# HG changeset patch # User fujie # Date 1508825049 -28800 # Node ID 76b73e112cb77826fd6f112a95c6c24bfdeca4ba # Parent 1510f9dcc0fa1007d43b3c8f54f41aef5f6ba579 [Assembler] Complex address modes support for Assembler::lea(Register rt, Address src), Assembler::sd(Register rt, Address dst) and Assembler::sw(Register rt, Address dst) diff -r 1510f9dcc0fa -r 76b73e112cb7 src/cpu/mips/vm/assembler_mips.cpp --- a/src/cpu/mips/vm/assembler_mips.cpp Mon Oct 23 17:07:19 2017 +0800 +++ b/src/cpu/mips/vm/assembler_mips.cpp Tue Oct 24 14:04:09 2017 +0800 @@ -319,11 +319,46 @@ lw(rt, src.base(), src.disp()); } void Assembler::lea(Register rt, Address src) { -#ifdef _LP64 - daddi(rt, src.base(), src.disp()); -#else - addi(rt, src.base(), src.disp()); -#endif + Register dst = rt; + Register base = src.base(); + Register index = src.index(); + + int scale = src.scale(); + int disp = src.disp(); + + if (index == noreg) { + if (is_simm16(disp)) { + daddiu(dst, base, disp); + } else { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + daddu(dst, base, AT); + } + } else { + if (scale == 0) { + if (is_simm16(disp)) { + daddu(AT, base, index); + daddiu(dst, AT, disp); + } else { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + daddu(AT, base, AT); + daddu(dst, AT, index); + } + } else { + if (is_simm16(disp)) { + dsll(AT, index, scale); + daddu(AT, AT, base); + daddiu(dst, AT, disp); + } else { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + daddu(AT, AT, base); + dsll(dst, index, scale); + daddu(dst, dst, AT); + } + } + } } void Assembler::lwl(Register rt, Address src){ @@ -351,7 +386,70 @@ } void Assembler::sd(Register rt, Address dst) { - sd(rt, dst.base(), dst.disp()); + Register src = rt; + Register base = dst.base(); + Register index = dst.index(); + + int scale = dst.scale(); + int disp = dst.disp(); + + if(index != noreg) { + if(is_simm16(disp)) { + if( UseLoongsonISA && is_simm(disp, 8)) { + if (scale == 0) { + gssdx(src, base, index, disp); + } else { + dsll(AT, index, scale); + gssdx(src, base, AT, disp); + } + } else { + if (scale == 0) { + daddu(AT, base, index); + } else { + dsll(AT, index, scale); + daddu(AT, base, AT); + } + sd(src, AT, disp); + } + } else { + if (scale == 0) { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + daddu(AT, AT, base); + if(UseLoongsonISA) { + gssdx(src, AT, index, 0); + } else { + daddu(AT, AT, index); + sd(src, AT, 0); + } + } else { + dsll(AT, index, scale); + daddu(AT, base, AT); + lui(T9, split_low(disp >> 16)); + if (split_low(disp)) ori(T9, T9, split_low(disp)); + if(UseLoongsonISA) { + gssdx(src, AT, T9, 0); + } else { + daddu(AT, AT, T9); + sd(src, AT, 0); + } + } + } + } else { + if(is_simm16(disp)) { + sd(src, base, disp); + } else { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + + if(UseLoongsonISA) { + gssdx(src, base, AT, 0); + } else { + daddu(AT, base, AT); + sd(src, AT, 0); + } + } + } } void Assembler::sdl(Register rt, Address dst) { @@ -367,7 +465,70 @@ } void Assembler::sw(Register rt, Address dst) { - sw(rt, dst.base(), dst.disp()); + Register src = rt; + Register base = dst.base(); + Register index = dst.index(); + + int scale = dst.scale(); + int disp = dst.disp(); + + if(index != noreg) { + if( Assembler::is_simm16(disp) ) { + if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) { + if (scale == 0) { + gsswx(src, base, index, disp); + } else { + dsll(AT, index, scale); + gsswx(src, base, AT, disp); + } + } else { + if (scale == 0) { + daddu(AT, base, index); + } else { + dsll(AT, index, scale); + daddu(AT, base, AT); + } + sw(src, AT, disp); + } + } else { + if (scale == 0) { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + daddu(AT, AT, base); + if( UseLoongsonISA ) { + gsswx(src, AT, index, 0); + } else { + daddu(AT, AT, index); + sw(src, AT, 0); + } + } else { + dsll(AT, index, scale); + daddu(AT, base, AT); + lui(T9, split_low(disp >> 16)); + if (split_low(disp)) ori(T9, T9, split_low(disp)); + if( UseLoongsonISA ) { + gsswx(src, AT, T9, 0); + } else { + daddu(AT, AT, T9); + sw(src, AT, 0); + } + } + } + } else { + if( Assembler::is_simm16(disp) ) { + sw(src, base, disp); + } else { + lui(AT, split_low(disp >> 16)); + if (split_low(disp)) ori(AT, AT, split_low(disp)); + + if( UseLoongsonISA ) { + gsswx(src, base, AT, 0); + } else { + daddu(AT, base, AT); + sw(src, AT, 0); + } + } + } } void Assembler::swl(Register rt, Address dst) { diff -r 1510f9dcc0fa -r 76b73e112cb7 src/cpu/mips/vm/macroAssembler_mips.cpp --- a/src/cpu/mips/vm/macroAssembler_mips.cpp Mon Oct 23 17:07:19 2017 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.cpp Tue Oct 24 14:04:09 2017 +0800 @@ -3323,6 +3323,14 @@ } } +void MacroAssembler::store_heap_oop_null(Address dst){ + if(UseCompressedOops){ + sw(R0, dst); + } else{ + sd(R0, dst); + } +} + #ifdef ASSERT void MacroAssembler::verify_heapbase(const char* msg) { assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed"); diff -r 1510f9dcc0fa -r 76b73e112cb7 src/cpu/mips/vm/macroAssembler_mips.hpp --- a/src/cpu/mips/vm/macroAssembler_mips.hpp Mon Oct 23 17:07:19 2017 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.hpp Tue Oct 24 14:04:09 2017 +0800 @@ -249,6 +249,7 @@ void load_heap_oop(Register dst, Address src); void store_heap_oop(Address dst, Register src); + void store_heap_oop_null(Address dst); void encode_heap_oop(Register r); void encode_heap_oop(Register dst, Register src); void decode_heap_oop(Register r); diff -r 1510f9dcc0fa -r 76b73e112cb7 src/cpu/mips/vm/templateTable_mips_64.cpp --- a/src/cpu/mips/vm/templateTable_mips_64.cpp Mon Oct 23 17:07:19 2017 +0800 +++ b/src/cpu/mips/vm/templateTable_mips_64.cpp Tue Oct 24 14:04:09 2017 +0800 @@ -101,6 +101,85 @@ return Address(BCP, offset); } +// Miscelaneous helper routines +// Store an oop (or NULL) at the address described by obj. +// If val == noreg this means store a NULL + +static void do_oop_store(InterpreterMacroAssembler* _masm, + Address obj, + Register val, + BarrierSet::Name barrier, + bool precise) { + assert(val == noreg || val == V0, "parameter is just for looks"); + switch (barrier) { +#if INCLUDE_ALL_GCS +// case BarrierSet::G1SATBCT: +// case BarrierSet::G1SATBCTLogging: +// { +// // flatten object address if needed +// if (obj.index() == noreg && obj.disp() == 0) { +// if (obj.base() != rdx) { +// __ movq(rdx, obj.base()); +// } +// } else { +// __ leaq(rdx, obj); +// } +// __ g1_write_barrier_pre(rdx /* obj */, +// rbx /* pre_val */, +// r15_thread /* thread */, +// r8 /* tmp */, +// val != noreg /* tosca_live */, +// false /* expand_call */); +// if (val == noreg) { +// __ store_heap_oop_null(Address(rdx, 0)); +// } else { +// // G1 barrier needs uncompressed oop for region cross check. +// Register new_val = val; +// if (UseCompressedOops) { +// new_val = rbx; +// __ movptr(new_val, val); +// } +// __ store_heap_oop(Address(rdx, 0), val); +// __ g1_write_barrier_post(rdx /* store_adr */, +// new_val /* new_val */, +// r15_thread /* thread */, +// r8 /* tmp */, +// rbx /* tmp2 */); +// } +// } + break; +#endif // INCLUDE_ALL_GCS + case BarrierSet::CardTableModRef: + case BarrierSet::CardTableExtension: + { + if (val == noreg) { + __ store_heap_oop_null(obj); + } else { + __ store_heap_oop(obj, val); + // flatten object address if needed + if (!precise || (obj.index() == noreg && obj.disp() == 0)) { + __ store_check(obj.base()); + } else { + //__ leaq(rdx, obj); + //__ store_check(rdx); + } + } + } + break; + case BarrierSet::ModRef: + case BarrierSet::Other: + if (val == noreg) { + __ store_heap_oop_null(obj); + } else { + __ store_heap_oop(obj, val); + } + break; + default : + ShouldNotReachHere(); + + } +} + // bytecode folding void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, Register tmp_reg, bool load_bc_into_bc_reg/*=true*/,