< prev index next >

test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java

Print this page
rev 11569 : 8159368: [JVMCI] SPARCHotSpotRegisterConfig.callingConvention gives incorrect calling convention for native calls containing fp args

*** 21,51 **** --- 21,58 ---- * questions. */ package jdk.vm.ci.code.test.sparc; + import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.DebugInfo; import jdk.vm.ci.code.Register; + import jdk.vm.ci.code.Register.RegisterCategory; + import jdk.vm.ci.code.RegisterValue; import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.site.ConstantReference; import jdk.vm.ci.code.site.DataSectionReference; import jdk.vm.ci.code.test.TestAssembler; import jdk.vm.ci.code.test.TestHotSpotVMConfig; import jdk.vm.ci.hotspot.HotSpotCallingConventionType; import jdk.vm.ci.hotspot.HotSpotCompiledCode; import jdk.vm.ci.hotspot.HotSpotConstant; import jdk.vm.ci.hotspot.HotSpotForeignCallTarget; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; + import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.VMConstant; import jdk.vm.ci.sparc.SPARC; import jdk.vm.ci.sparc.SPARCKind; public class SPARCTestAssembler extends TestAssembler { private static final int MASK13 = (1 << 13) - 1; + private static final Register scratchRegister = SPARC.g5; + private static final Register floatScratch = SPARC.f30; + private static final Register doubleScratch = SPARC.d62; public SPARCTestAssembler(CodeCacheProvider codeCache, TestHotSpotVMConfig config) { super(codeCache, config, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7); }
*** 134,154 **** Register ret = newRegister(); loadIntToRegister(c, ret); return ret; } ! private void loadIntToRegister(int c, Register ret) { int hi = c >>> 10; int lo = c & ((1 << 10) - 1); if (hi == 0) { emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret } else { emitOp2(ret, 0b100, hi); // SETHI hi, ret if (lo != 0) { emitOp3(0b10, ret, 0b000010, ret, lo); // OR ret, lo, ret } } } @Override public Register emitLoadLong(long c) { Register ret = newRegister(); --- 141,162 ---- Register ret = newRegister(); loadIntToRegister(c, ret); return ret; } ! private Register loadIntToRegister(int c, Register ret) { int hi = c >>> 10; int lo = c & ((1 << 10) - 1); if (hi == 0) { emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret } else { emitOp2(ret, 0b100, hi); // SETHI hi, ret if (lo != 0) { emitOp3(0b10, ret, 0b000010, ret, lo); // OR ret, lo, ret } } + return ret; } @Override public Register emitLoadLong(long c) { Register ret = newRegister();
*** 162,177 **** ref.setOffset(data.position()); data.emitLong(c); emitLoadPointerToRegister(ref, ret); } ! public void emitLoadLongToRegister(long c, Register r) { if ((c & 0xFFFF_FFFFL) == c) { loadIntToRegister((int) c, r); } else { loadLongToRegister(c, r); } } private void emitPatchableSethi(Register ret, boolean wide) { int startPos = code.position(); emitOp2(ret, 0b100, 0); // SETHI 0, ret --- 170,186 ---- ref.setOffset(data.position()); data.emitLong(c); emitLoadPointerToRegister(ref, ret); } ! public Register emitLoadLongToRegister(long c, Register r) { if ((c & 0xFFFF_FFFFL) == c) { loadIntToRegister((int) c, r); } else { loadLongToRegister(c, r); } + return r; } private void emitPatchableSethi(Register ret, boolean wide) { int startPos = code.position(); emitOp2(ret, 0b100, 0); // SETHI 0, ret
*** 183,202 **** } } @Override public Register emitLoadFloat(float c) { DataSectionReference ref = new DataSectionReference(); data.align(4); ref.setOffset(data.position()); data.emitFloat(c); - Register ptr = newRegister(); recordDataPatchInCode(ref); ! emitPatchableSethi(ptr, true); ! emitOp3(0b11, SPARC.f0, 0b100000, ptr, 0); // LDF [ptr+0], f0 ! return SPARC.f0; } @Override public Register emitLoadPointer(HotSpotConstant c) { Register ret = newRegister(); --- 192,234 ---- } } @Override public Register emitLoadFloat(float c) { + return emitLoadFloat(SPARC.f0, c); + } + + public Register emitLoadFloat(Register reg, float c) { + return emitLoadFloat(reg, c, newRegister()); + } + + public Register emitLoadFloat(Register reg, float c, Register scratch) { DataSectionReference ref = new DataSectionReference(); data.align(4); ref.setOffset(data.position()); data.emitFloat(c); recordDataPatchInCode(ref); ! emitPatchableSethi(scratch, true); ! emitOp3(0b11, reg, 0b100000, scratch, 0); // LDF [scratch+0], f0 ! return reg; ! } ! ! public Register emitLoadDouble(Register reg, double c) { ! return emitLoadDouble(reg, c, newRegister()); ! } ! ! public Register emitLoadDouble(Register reg, double c, Register scratch) { ! DataSectionReference ref = new DataSectionReference(); ! data.align(8); ! ref.setOffset(data.position()); ! data.emitDouble(c); ! ! recordDataPatchInCode(ref); ! emitPatchableSethi(scratch, true); ! emitOp3(0b11, reg, 0b100011, scratch, 0); // LDDF [ptr+0], f0 ! return reg; } @Override public Register emitLoadPointer(HotSpotConstant c) { Register ret = newRegister();
*** 238,265 **** } @Override public StackSlot emitIntToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.WORD); ! // STW a, [fp+offset] ! emitStore(0b000100, a, ret); return ret; } @Override public StackSlot emitLongToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.XWORD); ! // STX a, [sp+offset] ! emitStore(0b001110, a, ret); return ret; } @Override public StackSlot emitFloatToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.SINGLE); // STF a, [fp+offset] emitStore(0b100100, a, ret); return ret; } @Override public StackSlot emitPointerToStack(Register a) { --- 270,321 ---- } @Override public StackSlot emitIntToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.WORD); ! intToStack(a, ret); return ret; } + public void intToStack(Register a, StackSlot ret) { + // STW a, [(s|f)p+offset] + emitStore(0b000100, a, ret); + } + @Override public StackSlot emitLongToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.XWORD); ! longToStack(a, ret); return ret; } + public void longToStack(Register a, StackSlot ret) { + // STX a, [(f|s)p+offset] + emitStore(0b001110, a, ret); + } + @Override public StackSlot emitFloatToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.SINGLE); + floatToStack(a, ret); + return ret; + } + + public void floatToStack(Register a, StackSlot ret) { // STF a, [fp+offset] emitStore(0b100100, a, ret); + } + + @Override + public StackSlot emitDoubleToStack(Register a) { + StackSlot ret = newStackSlot(SPARCKind.DOUBLE); + return doubleToStack(a, ret); + } + + public StackSlot doubleToStack(Register a, StackSlot ret) { + // STD a, [(s|f)p+offset] + emitStore(0b100111, a, ret); return ret; } @Override public StackSlot emitPointerToStack(Register a) {
*** 276,295 **** emitStore(0b000100, a, ret); return ret; } private void emitStore(int op3, Register a, StackSlot ret) { int offset = ret.getRawOffset() + SPARC.STACK_BIAS; if (isSimm(offset, 13)) { // op3 a, [sp+offset] ! emitOp3(0b11, a, op3, SPARC.fp, offset); } else { assert a != SPARC.g3; Register r = SPARC.g3; loadLongToRegister(offset, r); // op3 a, [sp+g3] ! emitOp3(0b11, a, op3, SPARC.fp, r); } } @Override public Register emitUncompressPointer(Register compressed, long base, int shift) { --- 332,357 ---- emitStore(0b000100, a, ret); return ret; } private void emitStore(int op3, Register a, StackSlot ret) { + Register base; + if (ret.getRawOffset() < 0) { + base = SPARC.fp; + } else { + base = SPARC.sp; + } int offset = ret.getRawOffset() + SPARC.STACK_BIAS; if (isSimm(offset, 13)) { // op3 a, [sp+offset] ! emitOp3(0b11, a, op3, base, offset); } else { assert a != SPARC.g3; Register r = SPARC.g3; loadLongToRegister(offset, r); // op3 a, [sp+g3] ! emitOp3(0b11, a, op3, base, r); } } @Override public Register emitUncompressPointer(Register compressed, long base, int shift) {
*** 326,335 **** --- 388,404 ---- public void emitIntRet(Register a) { emitPointerRet(a); } @Override + public void emitFloatRet(Register a) { + assert a == SPARC.f0 : "Unimplemented"; + emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8); // JMPL [i7+8], g0 + emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0 + } + + @Override public void emitPointerRet(Register a) { emitMove(SPARC.i0, a); emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8); // JMPL [i7+8], g0 emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0 }
*** 347,352 **** --- 416,474 ---- } else { data.align(8); } return super.emitDataItem(c); } + + @Override + public void emitCall(long addr) { + Register dst = emitLoadLong(addr); + emitOp3(0b10, SPARC.o7, 0b111000, dst, 0); // JMPL [dst+0], o7 + emitNop(); + } + + @Override + public void emitLoad(AllocatableValue av, Object prim) { + if (av instanceof RegisterValue) { + Register reg = ((RegisterValue) av).getRegister(); + RegisterCategory cat = reg.getRegisterCategory(); + if (cat.equals(SPARC.FPUs)) { + emitLoadFloat(reg, (Float) prim, scratchRegister); + } else if (cat.equals(SPARC.FPUd)) { + emitLoadDouble(reg, (Double) prim, scratchRegister); + } else if (prim instanceof Integer) { + loadIntToRegister((Integer) prim, reg); + } else if (prim instanceof Long) { + loadLongToRegister((Long) prim, reg); + } + } else if (av instanceof StackSlot) { + StackSlot slot = (StackSlot) av; + if (prim instanceof Float) { + floatToStack(emitLoadFloat(floatScratch, (Float) prim, scratchRegister), slot); + } else if (prim instanceof Double) { + doubleToStack(emitLoadDouble(doubleScratch, (Double) prim, scratchRegister), slot); + } else if (prim instanceof Integer) { + intToStack(loadIntToRegister((Integer) prim, scratchRegister), slot); + } else if (prim instanceof Long) { + longToStack(emitLoadLongToRegister((Long) prim, scratchRegister), slot); + } + } else { + throw new IllegalArgumentException("Unknown value " + av); + } + } + + @Override + public void emitCallEpilogue(CallingConvention cc) { + // Nothing to do here. + } + + @Override + public void emitCallPrologue(CallingConvention cc, Object... prim) { + emitGrowStack(cc.getStackSize()); + frameSize += cc.getStackSize(); + AllocatableValue[] args = cc.getArguments(); + for (int i = 0; i < args.length; i++) { + emitLoad(args[i], prim[i]); + } + } + }
< prev index next >