# HG changeset patch # User Ao Qi # Date 1291196828 -28800 # Node ID 18922e417eb42594d7cd96aa25caed65747aafed # Parent dd1d79f9798b269fb310c63fc988d454250ff6f2 Fix bugs in reg2mem and mem2reg of T_LONG & needs_patching cases. diff -r dd1d79f9798b -r 18922e417eb4 hotspot/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp --- a/hotspot/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Wed Dec 01 17:39:16 2010 +0800 +++ b/hotspot/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Wed Dec 01 17:47:08 2010 +0800 @@ -432,7 +432,7 @@ #endif // ASSERT compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset()); - + __ call(SharedRuntime::deopt_blob()->unpack()); __ delayed()->nop(); @@ -811,156 +811,155 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info,bool pop_fpu_stack, bool/*unaliged*/) { LIR_Address* to_addr = dest->as_address_ptr(); Register dest_reg = to_addr->base()->as_register(); - PatchingStub* patch = NULL; - bool needs_patching = (patch_code != lir_patch_none); + PatchingStub* patch = NULL; + bool needs_patching = (patch_code != lir_patch_none); Register disp_reg = NOREG; - int disp_value = to_addr->disp(); - - if (type == T_ARRAY || type == T_OBJECT) { + int disp_value = to_addr->disp(); + + if (type == T_ARRAY || type == T_OBJECT) { __ verify_oop(src->as_register()); } - if (needs_patching) { - patch = new PatchingStub(_masm, PatchingStub::access_field_id); - assert(!src->is_double_cpu() || - patch_code == lir_patch_none || - patch_code == lir_patch_normal, - "patching doesn't match register"); - } - - if (info != NULL) { - add_debug_info_for_null_check_here(info); + if (needs_patching) { + patch = new PatchingStub(_masm, PatchingStub::access_field_id); + assert(!src->is_double_cpu() || + patch_code == lir_patch_none || + patch_code == lir_patch_normal, + "patching doesn't match register"); + } + + if (info != NULL) { + add_debug_info_for_null_check_here(info); + } + if (needs_patching) { + disp_reg = AT; + __ lui(AT, Assembler::split_high(disp_value)); + __ addiu(AT, AT, Assembler::split_low(disp_value)); + } else if (!Assembler::is_simm16(disp_value)) { + disp_reg = AT; + __ lui(AT, Assembler::split_high(disp_value)); } - if (needs_patching) { - disp_reg = AT; - __ lui(AT, Assembler::split_high(disp_value)); - __ addiu(AT, AT, Assembler::split_low(disp_value)); - } else if (!Assembler::is_simm16(disp_value)) { - disp_reg = AT; - __ lui(AT, Assembler::split_high(disp_value)); - } - int offset = code_offset(); - - switch(type) { - case T_DOUBLE: - assert(src->is_double_fpu(), "just check"); - if (disp_reg == noreg) { - __ swc1(src->as_double_reg(), dest_reg, disp_value); - __ swc1(src->as_double_reg()+1, dest_reg, disp_value+4); - } else if (needs_patching) { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ swc1(src->as_double_reg(), AT, 0); - __ swc1(src->as_double_reg()+1, AT, 4); - } else { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ swc1(src->as_double_reg(), AT, Assembler::split_low(disp_value)); - __ swc1(src->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4); - } - break; - - case T_FLOAT: - // assert(src->is_single_cpu(), "just check"); - - if (disp_reg == noreg) { - __ swc1(src->as_float_reg(), dest_reg, disp_value); - } else if(needs_patching) { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ swc1(src->as_float_reg(), AT, 0); - } else { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ swc1(src->as_float_reg(), AT, Assembler::split_low(disp_value)); - } - break; - - case T_LONG: { - Register from_lo = src->as_register_lo(); - Register from_hi = src->as_register_hi(); - Register base = to_addr->base()->as_register(); - Register index = noreg; - if (to_addr->index()->is_register()) { - index = to_addr->index()->as_register(); - } - if (base == from_lo || index == from_lo) { - assert(base != from_hi, "can't be"); - assert(index == noreg || (index != base && index != from_hi), "can't handle this"); - __ sw(from_hi,as_Address_hi(to_addr)); - if (patch != NULL) { - patching_epilog(patch, lir_patch_high, base, info); - patch = new PatchingStub(_masm, PatchingStub::access_field_id); - patch_code = lir_patch_low; + int offset = code_offset(); + + switch(type) { + case T_DOUBLE: + assert(src->is_double_fpu(), "just check"); + if (disp_reg == noreg) { + __ swc1(src->as_double_reg(), dest_reg, disp_value); + __ swc1(src->as_double_reg()+1, dest_reg, disp_value+4); + } else if (needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ swc1(src->as_double_reg(), AT, 0); + __ swc1(src->as_double_reg()+1, AT, 4); + } else { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ swc1(src->as_double_reg(), AT, Assembler::split_low(disp_value)); + __ swc1(src->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4); + } + break; + + case T_FLOAT: + if (disp_reg == noreg) { + __ swc1(src->as_float_reg(), dest_reg, disp_value); + } else if(needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ swc1(src->as_float_reg(), AT, 0); + } else { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ swc1(src->as_float_reg(), AT, Assembler::split_low(disp_value)); } - __ sw(from_lo,as_Address_lo(to_addr)); - } else { - assert(index == noreg || (index != base && index != from_lo), "can't handle this"); - __ sw(from_lo,as_Address_lo(to_addr)); - if (patch != NULL) { - patching_epilog(patch, lir_patch_low, base, info); - patch = new PatchingStub(_masm, PatchingStub::access_field_id); - patch_code = lir_patch_high; - } - __ sw(from_hi,as_Address_hi(to_addr)); - } - break; + break; + + case T_LONG: { + Register from_lo = src->as_register_lo(); + Register from_hi = src->as_register_hi(); + Register base = to_addr->base()->as_register(); + Register index = noreg; + if (to_addr->index()->is_register()) { + index = to_addr->index()->as_register(); + } + if (base == from_lo || index == from_lo) { + assert(base != from_hi, "can't be"); + assert(index == noreg || (index != base && index != from_hi), "can't handle this"); + if (needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sw(from_hi,AT, longSize/2); + __ sw(from_lo, AT, 0); + } else { + __ sw(from_hi,as_Address_hi(to_addr)); + __ sw(from_lo,as_Address_lo(to_addr)); + } + } else { + assert(index == noreg || (index != base && index != from_lo), "can't handle this"); + if (needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sw(from_lo,AT, 0); + __ sw(from_hi, AT, longSize/2); + } else { + __ sw(from_lo,as_Address_lo(to_addr)); + __ sw(from_hi,as_Address_hi(to_addr)); + } + } + break; + } + case T_ADDRESS: + case T_ARRAY: + case T_OBJECT: + case T_INT: + if (disp_reg == noreg) { + __ sw(src->as_register(), dest_reg, disp_value); + } else if (needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sw(src->as_register(), AT, 0); + } else { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sw(src->as_register(), AT, Assembler::split_low(disp_value)); + } + break; + + case T_CHAR: + case T_SHORT: + if (disp_reg == noreg) { + __ sh(src->as_register(), dest_reg, disp_value); + } else if (needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sh(src->as_register(), AT, 0); + } else { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sh(src->as_register(), AT, Assembler::split_low(disp_value)); + } + break; + + case T_BYTE: + case T_BOOLEAN: + assert(src->is_single_cpu(), "just check"); + + if (disp_reg == noreg) { + __ sb(src->as_register(), dest_reg, disp_value); + } else if (needs_patching) { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sb(src->as_register(), AT, 0); + } else { + __ add(AT, dest_reg, disp_reg); + offset = code_offset(); + __ sb(src->as_register(), AT, Assembler::split_low(disp_value)); + } + break; + + default: + ShouldNotReachHere(); } - case T_ADDRESS: - case T_ARRAY: - case T_OBJECT: - case T_INT: - //assert(from_reg.is_word(), "just check"); - if (disp_reg == noreg) { - __ sw(src->as_register(), dest_reg, disp_value); - } else if (needs_patching) { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ sw(src->as_register(), AT, 0); - } else { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ sw(src->as_register(), AT, Assembler::split_low(disp_value)); - } - break; - - case T_CHAR: - case T_SHORT: -// assert(from_reg.is_word(), "just check"); - - if (disp_reg == noreg) { - __ sh(src->as_register(), dest_reg, disp_value); - } else if (needs_patching) { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ sh(src->as_register(), AT, 0); - } else { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ sh(src->as_register(), AT, Assembler::split_low(disp_value)); - } - break; - - case T_BYTE: - case T_BOOLEAN: - assert(src->is_single_cpu(), "just check"); - - if (disp_reg == noreg) { - __ sb(src->as_register(), dest_reg, disp_value); - } else if (needs_patching) { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ sb(src->as_register(), AT, 0); - } else { - __ add(AT, dest_reg, disp_reg); - offset = code_offset(); - __ sb(src->as_register(), AT, Assembler::split_low(disp_value)); - } - break; - - default: - ShouldNotReachHere(); - } if (needs_patching) { patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); @@ -970,32 +969,32 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { - assert(src->is_stack(), "should not call otherwise"); + assert(src->is_stack(), "should not call otherwise"); assert(dest->is_register(), "should not call otherwise"); - if (dest->is_single_cpu()) { + if (dest->is_single_cpu()) { __ lw(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); if (type == T_ARRAY || type == T_OBJECT) { __ verify_oop(dest->as_register()); } - } else if (dest->is_double_cpu()) { - Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); - Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); - __ lw(dest->as_register_lo(), src_addr_LO); - __ lw(dest->as_register_hi(), src_addr_HI); - }else if (dest->is_single_fpu()) { - Address addr = frame_map()->address_for_slot(src->single_stack_ix()); - __ lwc1(dest->as_float_reg(), addr); - } else if (dest->is_double_fpu()) { - Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); - Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); - __ lwc1(dest->as_double_reg(), src_addr_LO); - __ lwc1(dest->as_double_reg()+1, src_addr_HI); - } else { - assert(dest->is_single_cpu(), "cannot be anything else but a single cpu"); - assert(type!= T_ILLEGAL, "Bad type in stack2reg") - Address addr = frame_map()->address_for_slot(src->single_stack_ix()); - __ lw(dest->as_register(), addr); - } + } else if (dest->is_double_cpu()) { + Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); + Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); + __ lw(dest->as_register_lo(), src_addr_LO); + __ lw(dest->as_register_hi(), src_addr_HI); + }else if (dest->is_single_fpu()) { + Address addr = frame_map()->address_for_slot(src->single_stack_ix()); + __ lwc1(dest->as_float_reg(), addr); + } else if (dest->is_double_fpu()) { + Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); + Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); + __ lwc1(dest->as_double_reg(), src_addr_LO); + __ lwc1(dest->as_double_reg()+1, src_addr_HI); + } else { + assert(dest->is_single_cpu(), "cannot be anything else but a single cpu"); + assert(type!= T_ILLEGAL, "Bad type in stack2reg") + Address addr = frame_map()->address_for_slot(src->single_stack_ix()); + __ lw(dest->as_register(), addr); + } } void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { @@ -1016,189 +1015,193 @@ // if patching needed, be sure the instruction at offset is a MoveMemReg void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool) { - assert(src->is_address(), "should not call otherwise"); + assert(src->is_address(), "should not call otherwise"); assert(dest->is_register(), "should not call otherwise"); LIR_Address* addr = src->as_address_ptr(); Address from_addr = as_Address(addr); - - Register src_reg = addr->base()->as_register(); - Register disp_reg = noreg; - int disp_value = addr->disp(); - bool needs_patching = (patch_code != lir_patch_none); - - PatchingStub* patch = NULL; - if (needs_patching) { - patch = new PatchingStub(_masm, PatchingStub::access_field_id); -// assert(!to_reg.is_long() || patch_code == LIR_Op1::patch_low || patch_code == LIR_Op1::patch_high, "patching doesn't match register"); - } - - // we must use lui&addiu, - if (needs_patching) { - disp_reg = AT; - __ lui(AT, Assembler::split_high(disp_value)); - __ addiu(AT, AT, Assembler::split_low(disp_value)); - } else if (!Assembler::is_simm16(disp_value)) { - disp_reg = AT; - __ lui(AT, Assembler::split_high(disp_value)); - } - - // remember the offset of the load. The patching_epilog must be done - // before the call to add_debug_info, otherwise the PcDescs don't get - // entered in increasing order. - int offset = code_offset(); - - switch(type) { + + Register src_reg = addr->base()->as_register(); + Register disp_reg = noreg; + int disp_value = addr->disp(); + bool needs_patching = (patch_code != lir_patch_none); + + PatchingStub* patch = NULL; + if (needs_patching) { + patch = new PatchingStub(_masm, PatchingStub::access_field_id); + } + + // we must use lui&addiu, + if (needs_patching) { + disp_reg = AT; + __ lui(AT, Assembler::split_high(disp_value)); + __ addiu(AT, AT, Assembler::split_low(disp_value)); + } else if (!Assembler::is_simm16(disp_value)) { + disp_reg = AT; + __ lui(AT, Assembler::split_high(disp_value)); + } + + // remember the offset of the load. The patching_epilog must be done + // before the call to add_debug_info, otherwise the PcDescs don't get + // entered in increasing order. + int offset = code_offset(); + + switch(type) { case T_BOOLEAN: case T_BYTE: { - //assert(to_reg.is_word(), "just check"); - if (disp_reg == noreg) { - __ lb(dest->as_register(), src_reg, disp_value); - } else if (needs_patching) { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lb(dest->as_register(), AT, 0); - } else { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lb(dest->as_register(), AT, Assembler::split_low(disp_value)); - } - } - break; - + //assert(to_reg.is_word(), "just check"); + if (disp_reg == noreg) { + __ lb(dest->as_register(), src_reg, disp_value); + } else if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lb(dest->as_register(), AT, 0); + } else { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lb(dest->as_register(), AT, Assembler::split_low(disp_value)); + } + } + break; + case T_CHAR: { - //assert(to_reg.is_word(), "just check"); - if (disp_reg == noreg) { - __ lhu(dest->as_register(), src_reg, disp_value); - } else if (needs_patching) { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lhu(dest->as_register(), AT, 0); - } else { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lhu(dest->as_register(), AT, Assembler::split_low(disp_value)); - } - } - break; - + //assert(to_reg.is_word(), "just check"); + if (disp_reg == noreg) { + __ lhu(dest->as_register(), src_reg, disp_value); + } else if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lhu(dest->as_register(), AT, 0); + } else { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lhu(dest->as_register(), AT, Assembler::split_low(disp_value)); + } + } + break; + case T_SHORT: { - // assert(to_reg.is_word(), "just check"); - if (disp_reg == noreg) { - __ lh(dest->as_register(), src_reg, disp_value); - } else if (needs_patching) { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lh(dest->as_register(), AT, 0); - } else { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lh(dest->as_register(), AT, Assembler::split_low(disp_value)); - } - } - break; - + // assert(to_reg.is_word(), "just check"); + if (disp_reg == noreg) { + __ lh(dest->as_register(), src_reg, disp_value); + } else if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lh(dest->as_register(), AT, 0); + } else { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lh(dest->as_register(), AT, Assembler::split_low(disp_value)); + } + } + break; + case T_INT: case T_OBJECT: case T_ARRAY: { - //assert(to_reg.is_word(), "just check"); - if (disp_reg == noreg) { - __ lw(dest->as_register(), src_reg, disp_value); - } else if (needs_patching) { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lw(dest->as_register(), AT, 0); - } else { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lw(dest->as_register(), AT, Assembler::split_low(disp_value)); - } - } - break; - + //assert(to_reg.is_word(), "just check"); + if (disp_reg == noreg) { + __ lw(dest->as_register(), src_reg, disp_value); + } else if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lw(dest->as_register(), AT, 0); + } else { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lw(dest->as_register(), AT, Assembler::split_low(disp_value)); + } + } + break; + case T_LONG: { - Register to_lo = dest->as_register_lo(); - Register to_hi = dest->as_register_hi(); - Register base = addr->base()->as_register(); - Register index = noreg; - if (addr->index()->is_register()) { - index = addr->index()->as_register(); - } - if ((base == to_lo && index == to_hi) ||(base == to_hi && index == to_lo)) { - // addresses with 2 registers are only formed as a result of - // array access so this code will never have to deal with - // patches or null checks. - assert(info == NULL && patch == NULL, "must be"); - __ lea(to_hi, as_Address(addr)); - __ lw(to_lo, Address(to_hi)); - __ lw(to_hi, Address(to_hi, BytesPerWord)); - } else if (base == to_lo || index == to_lo) { - assert(base != to_hi, "can't be"); - assert(index == noreg || (index != base && index != to_hi), "can't handle this"); - __ lw(to_hi, as_Address_hi(addr)); - if (patch != NULL) { - patching_epilog(patch, lir_patch_high, base, info); - patch = new PatchingStub(_masm, PatchingStub::access_field_id); - patch_code = lir_patch_low; - } - __ lw(to_lo, as_Address_lo(addr)); - } else { - assert(index == noreg || (index != base && index != to_lo), "can't handle this"); - __ lw(to_lo, as_Address_lo(addr)); - if (patch != NULL) { - patching_epilog(patch, lir_patch_low, base, info); - patch = new PatchingStub(_masm, PatchingStub::access_field_id); - patch_code = lir_patch_high; - } - __ lw(to_hi, as_Address_hi(addr)); - } - } - break; + Register to_lo = dest->as_register_lo(); + Register to_hi = dest->as_register_hi(); + Register base = addr->base()->as_register(); + Register index = noreg; + if (addr->index()->is_register()) { + index = addr->index()->as_register(); + } + if ((base == to_lo && index == to_hi) ||(base == to_hi && index == to_lo)) { + // addresses with 2 registers are only formed as a result of + // array access so this code will never have to deal with + // patches or null checks. + assert(info == NULL && patch == NULL, "must be"); + __ lea(to_hi, as_Address(addr)); + __ lw(to_lo, Address(to_hi)); + __ lw(to_hi, Address(to_hi, BytesPerWord)); + } else if (base == to_lo || index == to_lo) { + assert(base != to_hi, "can't be"); + assert(index == noreg || (index != base && index != to_hi), "can't handle this"); + if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lw(to_hi, AT, longSize/2); + __ lw(to_lo, AT, 0); + } else { + __ lw(to_hi, as_Address_hi(addr)); + __ lw(to_lo, as_Address_lo(addr)); + } + } else { + assert(index == noreg || (index != base && index != to_lo), "can't handle this"); + if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lw(to_lo, AT, 0); + } + __ lw(to_hi, AT, longSize/2); + } else { + __ lw(to_lo, as_Address_lo(addr)); + __ lw(to_hi, as_Address_hi(addr)); + } + } + } + break; case T_FLOAT: { - //assert(to_reg.is_float(), "just check"); - if (disp_reg == noreg) { - __ lwc1(dest->as_float_reg(), src_reg, disp_value); - } else if (needs_patching) { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lwc1(dest->as_float_reg(), AT, 0); - } else { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lwc1(dest->as_float_reg(), AT, Assembler::split_low(disp_value)); - } - } - break; - + //assert(to_reg.is_float(), "just check"); + if (disp_reg == noreg) { + __ lwc1(dest->as_float_reg(), src_reg, disp_value); + } else if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwc1(dest->as_float_reg(), AT, 0); + } else { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwc1(dest->as_float_reg(), AT, Assembler::split_low(disp_value)); + } + } + break; + case T_DOUBLE: { - //assert(to_reg.is_double(), "just check"); - - if (disp_reg == noreg) { - __ lwc1(dest->as_double_reg(), src_reg, disp_value); - __ lwc1(dest->as_double_reg()+1, src_reg, disp_value+4); - } else if (needs_patching) { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lwc1(dest->as_double_reg(), AT, 0); - __ lwc1(dest->as_double_reg()+1, AT, 4); - } else { - __ add(AT, src_reg, disp_reg); - offset = code_offset(); - __ lwc1(dest->as_double_reg(), AT, Assembler::split_low(disp_value)); - __ lwc1(dest->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4); - } - } - break; - + //assert(to_reg.is_double(), "just check"); + + if (disp_reg == noreg) { + __ lwc1(dest->as_double_reg(), src_reg, disp_value); + __ lwc1(dest->as_double_reg()+1, src_reg, disp_value+4); + } else if (needs_patching) { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwc1(dest->as_double_reg(), AT, 0); + __ lwc1(dest->as_double_reg()+1, AT, 4); + } else { + __ add(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwc1(dest->as_double_reg(), AT, Assembler::split_low(disp_value)); + __ lwc1(dest->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4); + } + } + break; + default: - ShouldNotReachHere(); - } - - if (needs_patching) { - patching_epilog(patch, patch_code, src_reg, info); - } - - if (info != NULL) add_debug_info_for_null_check(offset, info); + ShouldNotReachHere(); + } + + if (needs_patching) { + patching_epilog(patch, patch_code, src_reg, info); + } + + if (info != NULL) add_debug_info_for_null_check(offset, info); }