< 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 >