< prev index next >

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

Print this page
rev 28792 : 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); }
*** 100,110 **** return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1]; } @Override public Register emitLoadInt(int c) { ! Register ret = newRegister(); 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 { --- 107,120 ---- return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1]; } @Override public Register emitLoadInt(int c) { ! return emitLoadInt(newRegister(), c); ! } ! ! public Register emitLoadInt(Register ret, int c) { 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 {
*** 116,133 **** return ret; } @Override public Register emitLoadLong(long c) { if ((c & 0xFFFF_FFFFL) == c) { ! return emitLoadInt((int) c); } else { DataSectionReference ref = new DataSectionReference(); data.align(8); ref.setOffset(data.position()); data.emitLong(c); ! return emitLoadPointer(ref); } } private void emitPatchableSethi(Register ret, boolean wide) { int startPos = code.position(); --- 126,147 ---- return ret; } @Override public Register emitLoadLong(long c) { + return emitLoadLong(newRegister(), c); + } + + public Register emitLoadLong(Register reg, long c) { if ((c & 0xFFFF_FFFFL) == c) { ! return emitLoadInt(reg, (int) c); } else { DataSectionReference ref = new DataSectionReference(); data.align(8); ref.setOffset(data.position()); data.emitLong(c); ! return emitLoadPointer(reg, ref); } } private void emitPatchableSethi(Register ret, boolean wide) { int startPos = code.position();
*** 140,159 **** } } @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(); --- 154,196 ---- } } @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();
*** 165,175 **** return ret; } @Override public Register emitLoadPointer(DataSectionReference ref) { ! Register ret = newRegister(); recordDataPatchInCode(ref); emitPatchableSethi(ret, true); emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret return ret; } --- 202,215 ---- return ret; } @Override public Register emitLoadPointer(DataSectionReference ref) { ! return emitLoadPointer(newRegister(), ref); ! } ! ! public Register emitLoadPointer(Register ret, DataSectionReference ref) { recordDataPatchInCode(ref); emitPatchableSethi(ret, true); emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret return ret; }
*** 191,218 **** } @Override public StackSlot emitIntToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.WORD); // STW a, [fp+offset] ! emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); return ret; } @Override public StackSlot emitLongToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.XWORD); // STX a, [fp+offset] ! emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); return ret; } @Override public StackSlot emitFloatToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.SINGLE); // STF a, [fp+offset] ! emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); return ret; } @Override public StackSlot emitPointerToStack(Register a) { --- 231,305 ---- } @Override public StackSlot emitIntToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.WORD); + return emitIntToStack(ret, a); + } + + public StackSlot emitIntToStack(StackSlot ret, Register a) { + int offset = ret.getRawOffset(); + if (offset < 0) { // STW a, [fp+offset] ! emitOp3(0b11, a, 0b000100, SPARC.fp, offset + SPARC.STACK_BIAS); ! } else { ! // STW a, [sp+offset] ! emitOp3(0b11, a, 0b000100, SPARC.sp, offset + SPARC.STACK_BIAS); ! } return ret; } @Override public StackSlot emitLongToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.XWORD); + return emitLongToStack(ret, a); + } + + public StackSlot emitLongToStack(StackSlot ret, Register a) { + int offset = ret.getRawOffset(); + if (ret.getRawAddFrameSize()) { // STX a, [fp+offset] ! emitOp3(0b11, a, 0b001110, SPARC.fp, offset + SPARC.STACK_BIAS); ! } else { ! // STX a, [sp+offset] ! emitOp3(0b11, a, 0b001110, SPARC.sp, offset + SPARC.STACK_BIAS); ! } return ret; } @Override public StackSlot emitFloatToStack(Register a) { StackSlot ret = newStackSlot(SPARCKind.SINGLE); + return emitFloatToStack(ret, a); + } + + public StackSlot emitFloatToStack(StackSlot ret, Register a) { + int offset = ret.getRawOffset(); + if (offset < 0) { // STF a, [fp+offset] ! emitOp3(0b11, a, 0b100100, SPARC.fp, offset + SPARC.STACK_BIAS); ! } else { ! // STF a, [sp+offset] ! emitOp3(0b11, a, 0b100100, SPARC.sp, offset + SPARC.STACK_BIAS); ! } ! return ret; ! } ! ! public StackSlot emitDoubleToStack(Register a) { ! StackSlot ret = newStackSlot(SPARCKind.DOUBLE); ! return emitDoubleToStack(ret, a); ! } ! ! public StackSlot emitDoubleToStack(StackSlot ret, Register a) { ! int offset = ret.getRawOffset(); ! if (offset < 0) { ! // STDF a, [fp+offset] ! emitOp3(0b11, a, 0b100111, SPARC.fp, offset + SPARC.STACK_BIAS); ! } else { ! // STDF a, [sp+offset] ! emitOp3(0b11, a, 0b100111, SPARC.sp, offset + SPARC.STACK_BIAS); ! } return ret; } @Override public StackSlot emitPointerToStack(Register a) {
*** 265,274 **** --- 352,368 ---- 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 }
*** 286,291 **** --- 380,438 ---- } 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) { + emitLoadInt(reg, (Integer) prim); + } else if (prim instanceof Long) { + emitLoadLong(reg, (Long) prim); + } + } else if (av instanceof StackSlot) { + StackSlot slot = (StackSlot) av; + if (prim instanceof Float) { + emitFloatToStack(slot, emitLoadFloat(floatScratch, (Float) prim, scratchRegister)); + } else if (prim instanceof Double) { + emitDoubleToStack(slot, emitLoadDouble(doubleScratch, (Double) prim, scratchRegister)); + } else if (prim instanceof Integer) { + emitIntToStack(slot, emitLoadInt(scratchRegister, (Integer) prim)); + } else if (prim instanceof Long) { + emitLongToStack(slot, emitLoadLong(scratchRegister, (Long) prim)); + } + } 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 >