# HG changeset patch # User twisti # Date 1374021681 25200 # Node ID 7a8d6ba83a04fcc6536207a2680798a6765bf611 # Parent e2786e2c491a348a18cd0e2ccc907ec779212c2c SPARC: fixes and more stuff works diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Jul 16 17:41:21 2013 -0700 @@ -116,7 +116,7 @@ public void verify() { assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT); assert ((op2 << OP2_SHIFT) & OP2_MASK) == (op2 << OP2_SHIFT); - assert ((imm22 << IMM22_SHIFT) & IMM22_MASK) == (imm22 << IMM22_SHIFT); + assert ((imm22 << IMM22_SHIFT) & IMM22_MASK) == (imm22 << IMM22_SHIFT) : String.format("imm22: %d (%x)", imm22, imm22); } } @@ -287,6 +287,11 @@ masm.emitInt(getInstructionBits()); } + private static int patchUnbound(SPARCAssembler masm, Label label) { + label.addPatchAt(masm.codeBuffer.position()); + return 0; + } + public void verify() { assert p < 2; assert cond < 0x10; @@ -625,6 +630,28 @@ this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, 0, 0); } + /** + * Special constructor for Casa and Casxa. + */ + public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd, Asi asi) { + this(rd.encoding(), op3.getValue(), rs1.encoding(), asi.isValid() ? 0 : 1, asi.isValid() ? asi.getValue() : 0, rs2.encoding(), 0); + assert asi.isValid() : "default asi is not supported yet"; + } + + /** + * Special constructor for loads and stores. + */ + public Fmt11(Op3s op3, SPARCAddress addr, Register rd) { + this(rd.encoding(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0); + if (!addr.getIndex().equals(Register.None)) { + this.rs2 = addr.getIndex().encoding(); + } else { + this.simm13 = addr.getDisplacement(); + this.i = 1; + } + verify(); + } + private int getInstructionBits() { if (i == 0) { return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT; @@ -913,6 +940,8 @@ Restore(0x3d, "restore"), Done(0x3e, "done"), Retry(0x3e, "retry"), + Casa(0b111100, "casa"), + Casxa(0b111110, "casxa"), Lduw(0x00, "lduw"), Ldub(0x01, "ldub"), @@ -1241,6 +1270,28 @@ } } + public enum Asi { + INVALID(-1), ASI_PRIMARY(0x80), ASI_PRIMARY_NOFAULT(0x82), ASI_PRIMARY_LITTLE(0x88), + // Block initializing store + ASI_ST_BLKINIT_PRIMARY(0xE2), + // Most-Recently-Used (MRU) BIS variant + ASI_ST_BLKINIT_MRU_PRIMARY(0xF2); + + private final int value; + + private Asi(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public boolean isValid() { + return value != INVALID.getValue(); + } + } + public static int getFloatEncoding(int reg) { assert reg < 32; return reg; @@ -1277,7 +1328,7 @@ } public static final int hi22(int x) { - return x >> 10; + return x >>> 10; } public static final int lo10(int x) { @@ -1643,9 +1694,18 @@ } } - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.codeBuffer.position()); - return 0; + public static class Casa extends Fmt11 { + + public Casa(Register src1, Register src2, Register dst, Asi asi) { + super(Op3s.Casa, src1, src2, dst, asi); + } + } + + public static class Casxa extends Fmt11 { + + public Casxa(Register src1, Register src2, Register dst, Asi asi) { + super(Op3s.Casxa, src1, src2, dst, asi); + } } public static class Cmask8 extends Fmt3n { @@ -2536,51 +2596,50 @@ public static class Lddf extends Fmt11 { - // TODO remove address public Lddf(SPARCAddress src, Register dst) { - super(Op3s.Lddf, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Lddf, src, dst); } } public static class Ldf extends Fmt11 { public Ldf(SPARCAddress src, Register dst) { - super(Op3s.Ldf, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Ldf, src, dst); } } public static class Ldsb extends Fmt11 { public Ldsb(SPARCAddress src, Register dst) { - super(Op3s.Ldsb, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Ldsb, src, dst); } } public static class Ldsh extends Fmt11 { public Ldsh(SPARCAddress src, Register dst) { - super(Op3s.Ldsh, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Ldsh, src, dst); } } public static class Ldsw extends Fmt11 { public Ldsw(SPARCAddress src, Register dst) { - super(Op3s.Ldsw, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Ldsw, src, dst); } } public static class Lduw extends Fmt11 { public Lduw(SPARCAddress src, Register dst) { - super(Op3s.Lduw, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Lduw, src, dst); } } public static class Ldx extends Fmt11 { public Ldx(SPARCAddress src, Register dst) { - super(Op3s.Ldx, src.getBase(), src.getDisplacement(), dst); + super(Op3s.Ldx, src, dst); } } @@ -2822,8 +2881,8 @@ public static class Sethi extends Fmt00a { - public Sethi(int simm22, Register dst) { - super(Op2s.Sethi, simm22, dst); + public Sethi(int imm22, Register dst) { + super(Op2s.Sethi, imm22, dst); } } @@ -2903,44 +2962,28 @@ public static class Stb extends Fmt11 { public Stb(Register dst, SPARCAddress addr) { - super(Op3s.Stb, addr.getBase(), addr.getDisplacement(), dst); + super(Op3s.Stb, addr, dst); } } public static class Sth extends Fmt11 { public Sth(Register dst, SPARCAddress addr) { - super(Op3s.Sth, addr.getBase(), addr.getDisplacement(), dst); + super(Op3s.Sth, addr, dst); } } public static class Stw extends Fmt11 { - public Stw(Register dst, Register src1, Register src2) { - super(Op3s.Stw, src1, src2, dst); - } - - public Stw(Register dst, Register src1, int simm13) { - super(Op3s.Stw, src1, simm13, dst); - } - public Stw(Register dst, SPARCAddress addr) { - this(dst, addr.getBase(), addr.getDisplacement()); + super(Op3s.Stw, addr, dst); } } public static class Stx extends Fmt11 { - public Stx(Register dst, Register src1, Register src2) { - super(Op3s.Stx, src1, src2, dst); - } - - public Stx(Register dst, Register src1, int simm13) { - super(Op3s.Stx, src1, simm13, dst); - } - public Stx(Register dst, SPARCAddress addr) { - this(dst, addr.getBase(), addr.getDisplacement()); + super(Op3s.Stx, addr, dst); } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Tue Jul 16 17:41:21 2013 -0700 @@ -85,6 +85,17 @@ } } + public static class Bpgeu extends Bpcc { + + public Bpgeu(CC cc, int simm19) { + super(cc, simm19); + } + + public Bpgeu(CC cc, Label label) { + super(cc, label); + } + } + public static class Bset extends Or { public Bset(Register src, Register dst) { @@ -107,6 +118,20 @@ } } + public static class Cas extends Casa { + + public Cas(Register src1, Register src2, Register dst) { + super(src1, src2, dst, Asi.ASI_PRIMARY); + } + } + + public static class Casx extends Casxa { + + public Casx(Register src1, Register src2, Register dst) { + super(src1, src2, dst, Asi.ASI_PRIMARY); + } + } + public static class Clr extends Or { public Clr(Register dst) { @@ -302,53 +327,87 @@ public static class Setx { private long value; - private Register tmp; private Register dst; + private boolean forceRelocatable; - public Setx(long value, Register tmp, Register dst) { + public Setx(long value, Register dst, boolean forceRelocatable) { this.value = value; - this.tmp = tmp; this.dst = dst; + this.forceRelocatable = forceRelocatable; + } + + public Setx(long value, Register dst) { + this(value, dst, false); } public void emit(SPARCMacroAssembler masm) { int hi = (int) (value >> 32); int lo = (int) (value & ~0); - if (isSimm13(lo) && value == lo) { - new Or(g0, lo, dst).emit(masm); - } else if (hi == 0) { - new Sethi(lo, dst).emit(masm); // hardware version zero-extends to upper 32 - if (lo10(lo) != 0) { - new Or(dst, lo10(lo), dst).emit(masm); +// if (isSimm13(lo) && value == lo) { +// new Or(g0, lo, dst).emit(masm); +// } else if (hi == 0) { +// new Sethi(lo, dst).emit(masm); // hardware version zero-extends to upper 32 +// if (lo10(lo) != 0) { +// new Or(dst, lo10(lo), dst).emit(masm); +// } +// } else if (hi == -1) { +// new Sethi(~lo, dst).emit(masm); // hardware version zero-extends to upper 32 +// new Xor(dst, ~lo10(~0), dst).emit(masm); +// new Add(dst, lo10(lo), dst).emit(masm); +// } else if (lo == 0) { +// if (isSimm13(hi)) { +// new Or(g0, hi, dst).emit(masm); +// } else { +// new Sethi(hi, dst).emit(masm); // hardware version zero-extends to upper 32 +// if (lo10(hi) != 0) { +// new Or(dst, lo10(hi), dst).emit(masm); +// } +// } +// new Sllx(dst, 32, dst).emit(masm); + + // This is the same logic as MacroAssembler::internal_set. + final int startPc = masm.codeBuffer.position(); + + if (hi == 0 && lo >= 0) { + new Sethi(lo, dst).emit(masm); + } else if (hi == -1) { + new Sethi(~lo, dst).emit(masm); + new Xor(dst, ~lo10(~0), dst).emit(masm); + } else { + int shiftcnt = 0; + new Sethi(hi, dst).emit(masm); + if ((hi & 0x3ff) != 0) { // Any bits? + new Or(dst, hi & 0x3ff, dst).emit(masm); // msb 32-bits are now in lsb 32 } - } else if (hi == -1) { - new Sethi(~lo, dst).emit(masm); // hardware version zero-extends to upper 32 - new Xor(dst, ~lo10(~0), dst).emit(masm); - new Add(dst, lo10(lo), dst).emit(masm); - } else if (lo == 0) { - if (isSimm13(hi)) { - new Or(g0, hi, dst).emit(masm); + if ((lo & 0xFFFFFC00) != 0) { // done? + if (((lo >> 20) & 0xfff) != 0) { // Any bits set? + new Sllx(dst, 12, dst).emit(masm); // Make room for next 12 bits + new Or(dst, (lo >> 20) & 0xfff, dst).emit(masm); // Or in next 12 + shiftcnt = 0; // We already shifted + } else { + shiftcnt = 12; + } + if (((lo >> 10) & 0x3ff) != 0) { + new Sllx(dst, shiftcnt + 10, dst).emit(masm); // Make room for last 10 bits + new Or(dst, (lo >> 10) & 0x3ff, dst).emit(masm); // Or in next 10 + shiftcnt = 0; + } else { + shiftcnt = 10; + } + new Sllx(dst, shiftcnt + 10, dst).emit(masm); // Shift leaving disp field 0'd } else { - new Sethi(hi, dst).emit(masm); // hardware version zero-extends to upper 32 - if (lo10(hi) != 0) { - new Or(dst, lo10(hi), dst).emit(masm); - } + new Sllx(dst, 32, dst).emit(masm); } - new Sllx(dst, 32, dst).emit(masm); - } else { - // TODO Use the same logic as in MacroAssembler::internal_sethi, which doesn't need -// a scratch register. - new Sethi(hi, tmp).emit(masm); - new Sethi(lo, dst).emit(masm); // macro assembler version sign-extends - if (lo10(hi) != 0) { - new Or(tmp, lo10(hi), tmp).emit(masm); + } + // Pad out the instruction sequence so it can be patched later. + if (forceRelocatable) { + while (masm.codeBuffer.position() < (startPc + (7 * 4))) { + new Nop().emit(masm); } - if (lo10(lo) != 0) { - new Or(dst, lo10(lo), dst).emit(masm); - } - new Sllx(tmp, 32, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); + } + if (lo10(lo) != 0 || forceRelocatable) { + new Add(dst, lo10(lo), dst).emit(masm); } } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Jul 16 17:41:21 2013 -0700 @@ -389,31 +389,53 @@ baseRegister = asAllocatable(base); } + AllocatableValue indexRegister; if (!index.equals(Value.ILLEGAL) && scale != 0) { if (isConstant(index)) { finalDisp += asConstant(index).asLong() * scale; + indexRegister = Value.ILLEGAL; } else { - Value indexRegister; if (scale != 1) { Variable longIndex = newVariable(Kind.Long); emitMove(longIndex, index); indexRegister = emitMul(longIndex, Constant.forLong(scale)); } else { - indexRegister = index; + indexRegister = asAllocatable(index); } - if (baseRegister.equals(Value.ILLEGAL)) { - baseRegister = asAllocatable(indexRegister); - } else { - Variable newBase = newVariable(Kind.Long); - emitMove(newBase, baseRegister); - baseRegister = newBase; - baseRegister = emitAdd(baseRegister, indexRegister); - } +// if (baseRegister.equals(Value.ILLEGAL)) { +// baseRegister = asAllocatable(indexRegister); +// } else { +// Variable newBase = newVariable(Kind.Long); +// emitMove(newBase, baseRegister); +// baseRegister = newBase; +// baseRegister = emitAdd(baseRegister, indexRegister); +// } + } + } else { + indexRegister = Value.ILLEGAL; + } + + int displacementInt; + + // If we don't have an index register we can use a displacement, otherwise load the + // displacement into a register and add it to the base. + if (indexRegister.equals(Value.ILLEGAL)) { + // TODO What if displacement if too big? + displacementInt = (int) finalDisp; + } else { + displacementInt = 0; + AllocatableValue displacementRegister = load(Constant.forLong(finalDisp)); + if (baseRegister.equals(Value.ILLEGAL)) { + baseRegister = displacementRegister; + } else { + Variable longBase = newVariable(Kind.Long); + emitMove(longBase, baseRegister); + baseRegister = emitAdd(longBase, displacementRegister); } } - return new SPARCAddressValue(target().wordKind, baseRegister, (int) finalDisp); + return new SPARCAddressValue(target().wordKind, baseRegister, indexRegister, displacementInt); } private SPARCAddressValue asAddress(Value address) { @@ -488,7 +510,7 @@ } @Override - public Value emitSub(Value a, Value b) { + public Variable emitSub(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -510,7 +532,7 @@ } @Override - public Value emitMul(Value a, Value b) { + public Variable emitMul(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -602,7 +624,7 @@ } @Override - public Value emitAnd(Value a, Value b) { + public Variable emitAnd(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -619,7 +641,7 @@ } @Override - public Value emitOr(Value a, Value b) { + public Variable emitOr(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -635,7 +657,7 @@ } @Override - public Value emitXor(Value a, Value b) { + public Variable emitXor(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -651,7 +673,7 @@ } @Override - public Value emitShl(Value a, Value b) { + public Variable emitShl(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -667,7 +689,7 @@ } @Override - public Value emitShr(Value a, Value b) { + public Variable emitShr(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -683,7 +705,7 @@ } @Override - public Value emitUShr(Value a, Value b) { + public Variable emitUShr(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -699,7 +721,7 @@ } @Override - public Value emitConvert(Op opcode, Value inputVal) { + public Variable emitConvert(Op opcode, Value inputVal) { Variable input = load(inputVal); Variable result = newVariable(opcode.to); switch (opcode) { diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Jul 16 17:41:21 2013 -0700 @@ -85,9 +85,8 @@ if (SPARCAssembler.isSimm13(address.getDisplacement())) { new Stx(g0, address).emit(masm); } else { - // TODO Can't use g3 as scratch here. - new Setx(address.getDisplacement(), g3, g3).emit(masm); - new Stx(g0, sp, g3).emit(masm); + new Setx(address.getDisplacement(), g3).emit(masm); + new Stx(g0, new SPARCAddress(sp, g3)).emit(masm); } } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Tue Jul 16 17:41:21 2013 -0700 @@ -53,7 +53,8 @@ protected TargetDescription createTarget() { final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; - return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, true); + final boolean inlineObjects = false; // TODO We might want to change this later. + return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); } @Override diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Jul 16 17:41:21 2013 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.sparc; +import static com.oracle.graal.api.code.ValueUtil.*; + import java.lang.reflect.*; import com.oracle.graal.api.code.*; @@ -32,6 +34,7 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.sparc.SPARCMove.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; @@ -60,16 +63,14 @@ @Override public void emitTailcall(Value[] args, Value address) { - // TODO Auto-generated method stub + throw new InternalError("NYI"); } @Override protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { -// append(new SPARCHotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, -// callState, invokeKind)); - throw new InternalError("NYI"); + append(new SPARCHotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind)); } else { assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target(); @@ -93,33 +94,52 @@ @Override public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { - // TODO Auto-generated method stub + throw new InternalError("NYI"); } @Override public void emitPatchReturnAddress(ValueNode address) { - // TODO Auto-generated method stub + throw new InternalError("NYI"); } @Override public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { - // TODO Auto-generated method stub + throw new InternalError("NYI"); } @Override public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { - // TODO Auto-generated method stub + Kind kind = x.newValue().kind(); + assert kind == x.expectedValue().kind(); + + Variable address = load(operand(x.object())); + Value offset = operand(x.offset()); + Variable cmpValue = (Variable) loadNonConst(operand(x.expectedValue())); + Variable newValue = load(operand(x.newValue())); + + if (ValueUtil.isConstant(offset)) { + assert !runtime.needsDataPatch(asConstant(offset)); + address = emitAdd(address, asConstant(offset)); + } else { + if (isLegal(offset)) { + address = emitAdd(address, offset); + } + } + + append(new CompareAndSwapOp(address, cmpValue, newValue)); + + Variable result = newVariable(x.kind()); + emitMove(result, newValue); + setResult(x, result); } @Override public StackSlot getLockSlot(int lockDepth) { - // TODO Auto-generated method stub - return null; + throw new InternalError("NYI"); } public Stub getStub() { - // TODO Auto-generated method stub - return null; + throw new InternalError("NYI"); } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Jul 16 17:41:21 2013 -0700 @@ -71,8 +71,9 @@ return attributesMap.clone(); } - private final Register[] javaGeneralParameterRegisters; - private final Register[] nativeGeneralParameterRegisters; + private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; + private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; + private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7}; @@ -124,9 +125,6 @@ public SPARCHotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) { this.architecture = architecture; - javaGeneralParameterRegisters = new Register[]{i0, i1, i2, i3, i4, i5}; - nativeGeneralParameterRegisters = new Register[]{i0, i1, i2, i3, i4, i5}; - csl = new CalleeSaveLayout(architecture, -1, -1, architecture.getWordSize(), calleeSaveRegisters); allocatable = initAllocatable(config.useCompressedOops); attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); @@ -144,12 +142,13 @@ @Override public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { - if (type == Type.NativeCall) { - return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + if (type == Type.JavaCall || type == Type.NativeCall) { + return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly); } - // On x64, parameter locations are the same whether viewed - // from the caller or callee perspective - return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + if (type == Type.JavaCallee) { + return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + throw GraalInternalError.shouldNotReachHere(); } public Register[] getCallingConventionRegisters(Type type, Kind kind) { @@ -157,7 +156,7 @@ return fpuParameterRegisters; } assert architecture.canStoreValue(CPU, kind); - return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; + return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; } private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Tue Jul 16 17:41:21 2013 -0700 @@ -27,23 +27,21 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.SPARCCall.DirectCallOp; -import com.oracle.graal.lir.sparc.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** * A direct call that complies with the conventions for such calls in HotSpot. In particular, for * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call. - * This instruction (which moves 0L in G3) is patched by the C++ Graal code to replace the 0L - * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the - * Klass in an inline cache. It puts the called method into G5 before calling. */ @Opcode("CALL_DIRECT") final class SPARCHotspotDirectStaticCallOp extends DirectCallOp { + private static final long nonOopBits = HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits; private final Constant metaspaceMethod; private final InvokeKind invokeKind; @@ -57,22 +55,15 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { // The mark for an invocation that uses an inline cache must be placed at the - // instruction that loads the Klass from the inline cache so that the C++ code can find it - // and replace the inline 0L value with Universe::non_oop_word() + // instruction that loads the Klass from the inline cache. // SPARCMove.move(tasm, masm, g5.asValue(Kind.Long), tasm.asLongConstRef(metaspaceMethod)); new Rdpc(g5).emit(masm); tasm.asLongConstRef(metaspaceMethod); new Ldx(new SPARCAddress(g5, 0), g5).emit(masm); tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); - // XXX move must be patchable! - SPARCMove.move(tasm, masm, g3.asValue(Kind.Long), Constant.LONG_0); - new Nop().emit(masm); - new Nop().emit(masm); - new Nop().emit(masm); - new Nop().emit(masm); - new Nop().emit(masm); - new Nop().emit(masm); + // SPARCMove.move(tasm, masm, g3.asValue(Kind.Long), Constant.LONG_0); + new Setx(nonOopBits, g3, true).emit(masm); super.emitCode(tasm, masm); } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Tue Jul 16 17:41:21 2013 -0700 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.sparc; + +import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*; +import static com.oracle.graal.sparc.SPARC.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.sparc.SPARCCall.DirectCallOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; + +/** + * A direct call that complies with the conventions for such calls in HotSpot. In particular, for + * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call. + */ +@Opcode("CALL_DIRECT") +final class SPARCHotspotDirectVirtualCallOp extends DirectCallOp { + + private static final long nonOopBits = HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits; + private final InvokeKind invokeKind; + + SPARCHotspotDirectVirtualCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) { + super(target, result, parameters, temps, state); + this.invokeKind = invokeKind; + assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + // The mark for an invocation that uses an inline cache must be placed at the + // instruction that loads the Klass from the inline cache. +// new Rdpc(g3).emit(masm); +// tasm.asLongConstRef(nonOopBitsConstant); +// tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); +// new Ldx(new SPARCAddress(g3, 0), g3).emit(masm); + + tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); + // SPARCMove.move(tasm, masm, g3.asValue(Kind.Long), nonOopBitsConstant); + new Setx(nonOopBits, g3, true).emit(masm); + super.emitCode(tasm, masm); + } +} diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java Tue Jul 16 17:41:21 2013 -0700 @@ -61,7 +61,7 @@ final int pos = masm.codeBuffer.position(); final int offset = SafepointPollOffset.getValue() % unsafe.pageSize(); Register scratch = ((RegisterValue) temp).getRegister(); - new Setx(config.safepointPollingAddress + offset, scratch, scratch).emit(masm); + new Setx(config.safepointPollingAddress + offset, scratch).emit(masm); tasm.recordMark(config.isPollingPageFar ? Marks.MARK_POLL_FAR : Marks.MARK_POLL_NEAR); tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm); diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Tue Jul 16 17:41:21 2013 -0700 @@ -22,6 +22,7 @@ */ package com.oracle.graal.lir.sparc; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.code.*; @@ -35,16 +36,22 @@ private static final long serialVersionUID = -3583286416638228207L; @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base; + @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index; protected final int displacement; - public SPARCAddressValue(PlatformKind kind, AllocatableValue baseRegister, int finalDisp) { + public SPARCAddressValue(PlatformKind kind, AllocatableValue base, int displacement) { + this(kind, base, Value.ILLEGAL, displacement); + } + + public SPARCAddressValue(PlatformKind kind, AllocatableValue base, AllocatableValue index, int displacement) { super(kind); - this.base = baseRegister; - this.displacement = finalDisp; + this.base = base; + this.index = index; + this.displacement = displacement; } private static Register toRegister(AllocatableValue value) { - if (value.equals(Value.ILLEGAL)) { + if (isIllegal(value)) { return Register.None; } else { RegisterValue reg = (RegisterValue) value; @@ -53,7 +60,46 @@ } public SPARCAddress toAddress() { - return new SPARCAddress(toRegister(base), displacement); + if (isLegal(index)) { + return new SPARCAddress(toRegister(base), toRegister(index)); + } else { + return new SPARCAddress(toRegister(base), displacement); + } } + @Override + public String toString() { + StringBuilder s = new StringBuilder("["); + String sep = ""; + if (isLegal(base)) { + s.append(base); + sep = " + "; + } + if (isLegal(index)) { + s.append(sep).append(index); + sep = " + "; + } else { + if (displacement < 0) { + s.append(" - ").append(-displacement); + } else if (displacement > 0) { + s.append(sep).append(displacement); + } + } + s.append("]"); + return s.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SPARCAddressValue) { + SPARCAddressValue addr = (SPARCAddressValue) obj; + return getPlatformKind() == addr.getPlatformKind() && displacement == addr.displacement && base.equals(addr.base) && index.equals(addr.index); + } + return false; + } + + @Override + public int hashCode() { + return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ getPlatformKind().hashCode(); + } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Jul 16 17:41:21 2013 -0700 @@ -271,13 +271,9 @@ // new Sdivx(masm, asIntReg(src1), asIntReg(src2), // asIntReg(dst)); case FSUB: - throw new InternalError("NYI"); case FDIV: - throw new InternalError("NYI"); case DSUB: - throw new InternalError("NYI"); case DDIV: - throw new InternalError("NYI"); default: throw GraalInternalError.shouldNotReachHere(); } @@ -305,34 +301,34 @@ break; case ISHR: assert isSimm13(tasm.asIntConst(src2)); - new Srl(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); + new Sra(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); break; case IUSHR: assert isSimm13(tasm.asIntConst(src2)); - new Sra(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); + new Srl(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); break; case IXOR: assert isSimm13(tasm.asIntConst(src2)); new Xor(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); break; + case LMUL: + assert isSimm13(tasm.asIntConst(src2)); + new Mulx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); + break; case LXOR: assert isSimm13(tasm.asIntConst(src2)); new Add(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); break; case LUSHR: - throw new InternalError("NYI"); + assert isSimm13(tasm.asIntConst(src2)); + new Srl(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); + break; case FADD: - throw new InternalError("NYI"); case FMUL: - throw new InternalError("NYI"); case FDIV: - throw new InternalError("NYI"); case DADD: - throw new InternalError("NYI"); case DMUL: - throw new InternalError("NYI"); case DDIV: - throw new InternalError("NYI"); default: throw GraalInternalError.shouldNotReachHere(); } @@ -453,8 +449,8 @@ new Sra(asIntReg(src), 0, asLongReg(dst)).emit(masm); break; case I2B: - new Sll(asIntReg(src), 24, asIntReg(src)).emit(masm); - new Srl(asIntReg(dst), 24, asIntReg(src)).emit(masm); + new Sll(asIntReg(src), 24, asIntReg(dst)).emit(masm); + new Srl(asIntReg(dst), 24, asIntReg(dst)).emit(masm); break; case I2F: new Fstoi(masm, asIntReg(src), asFloatReg(dst)); @@ -468,12 +464,6 @@ case DNEG: new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst)); break; - case LSHL: - new Sllx(asLongReg(dst), asIntReg(src), asLongReg(dst)).emit(masm); - break; - case LSHR: - new Srlx(asLongReg(dst), asIntReg(src), asLongReg(dst)).emit(masm); - break; default: throw GraalInternalError.shouldNotReachHere("missing: " + opcode); } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Tue Jul 16 17:41:21 2013 -0700 @@ -72,8 +72,8 @@ new Cmp(asLongReg(x), asLongReg(y)).emit(masm); break; case ACMP: -// new Cmp(asObjectReg(x), asObjectReg(y)).emit(masm); -// break; + new Cmp(asObjectReg(x), asObjectReg(y)).emit(masm); + break; case FCMP: // masm.ucomiss(asFloatReg(x), asFloatReg(y)); // break; diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Jul 16 17:41:21 2013 -0700 @@ -58,6 +58,18 @@ case EQ: new Bpe(CC.Xcc, destination.label()).emit(masm); break; + case NE: + new Bpne(CC.Xcc, destination.label()).emit(masm); + break; + case BE: + new Bpleu(CC.Xcc, destination.label()).emit(masm); + break; + case LE: + new Bple(CC.Xcc, destination.label()).emit(masm); + break; + case AE: + new Bpgeu(CC.Xcc, destination.label()).emit(masm); + break; case GT: new Bpg(CC.Xcc, destination.label()).emit(masm); break; diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Jul 16 17:41:21 2013 -0700 @@ -127,6 +127,7 @@ public void emitMemAccess(SPARCMacroAssembler masm) { SPARCAddress addr = address.toAddress(); switch (kind) { + case Boolean: case Byte: new Ldsb(addr, asRegister(result)).emit(masm); break; @@ -189,6 +190,26 @@ } } + @Opcode("CAS") + public static class CompareAndSwapOp extends SPARCLIRInstruction { + +// @Def protected AllocatableValue result; + @Use protected AllocatableValue address; + @Use protected AllocatableValue cmpValue; + @Use protected AllocatableValue newValue; + + public CompareAndSwapOp(AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + this.address = address; + this.cmpValue = cmpValue; + this.newValue = newValue; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + compareAndSwap(masm, address, cmpValue, newValue); + } + } + public static class StackLoadAddressOp extends SPARCLIRInstruction { @Def({REG}) protected AllocatableValue result; @@ -219,6 +240,7 @@ assert isRegister(input); SPARCAddress addr = address.toAddress(); switch (kind) { + case Boolean: case Byte: new Stb(asRegister(input), addr).emit(masm); break; @@ -274,14 +296,12 @@ } switch (input.getKind()) { case Int: - new Mov(asRegister(input), asRegister(result)).emit(masm); - break; case Long: + case Object: new Mov(asRegister(input), asRegister(result)).emit(masm); break; case Float: case Double: - case Object: default: throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind()); } @@ -325,24 +345,52 @@ } new Setuw(input.asInt(), asRegister(result)).emit(masm); break; - case Long: + case Long: { if (tasm.runtime.needsDataPatch(input)) { + new Nop().emit(masm); tasm.recordDataReferenceInCode(input, 0, true); + new Setx(input.asLong(), asRegister(result), true).emit(masm); + new Nop().emit(masm); + } else { + new Nop().emit(masm); + new Nop().emit(masm); + new Setx(input.asLong(), asRegister(result)).emit(masm); + new Nop().emit(masm); + new Nop().emit(masm); } - new Setx(input.asLong(), null, asRegister(result)).emit(masm); break; - case Object: + } + case Object: { if (input.isNull()) { new Clr(asRegister(result)).emit(masm); } else if (tasm.target.inlineObjects) { - tasm.recordDataReferenceInCode(input, 0, true); - new Setx(0xDEADDEADDEADDEADL, null, asRegister(result)).emit(masm); +// tasm.recordDataReferenceInCode(input, 0, true); +// new Setx(0xDEADDEADDEADDEADL, null, asRegister(result)).emit(masm); + throw GraalInternalError.shouldNotReachHere(); } else { - throw new InternalError("NYI"); + Register dst = asRegister(result); + new Rdpc(dst).emit(masm); + tasm.asObjectConstRef(input); + new Ldx(new SPARCAddress(dst, 0), dst).emit(masm); } break; + } default: throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind()); } } + + protected static void compareAndSwap(SPARCMacroAssembler masm, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + switch (cmpValue.getKind()) { + case Int: + new Cas(asRegister(address), asRegister(cmpValue), asRegister(newValue)).emit(masm); + break; + case Long: + case Object: + new Casx(asRegister(address), asRegister(cmpValue), asRegister(newValue)).emit(masm); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } } diff -r e2786e2c491a -r 7a8d6ba83a04 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Tue Jul 16 18:30:45 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Tue Jul 16 17:41:21 2013 -0700 @@ -211,7 +211,7 @@ } /** - * Returns the address of a float constant that is embedded as a data references into the code. + * Returns the address of a float constant that is embedded as a data reference into the code. */ public AbstractAddress asFloatConstRef(Value value) { return asFloatConstRef(value, 4); @@ -223,7 +223,7 @@ } /** - * Returns the address of a double constant that is embedded as a data references into the code. + * Returns the address of a double constant that is embedded as a data reference into the code. */ public AbstractAddress asDoubleConstRef(Value value) { return asDoubleConstRef(value, 8); @@ -235,13 +235,21 @@ } /** - * Returns the address of a long constant that is embedded as a data references into the code. + * Returns the address of a long constant that is embedded as a data reference into the code. */ public AbstractAddress asLongConstRef(Value value) { assert value.getKind() == Kind.Long && isConstant(value); return recordDataReferenceInCode((Constant) value, 8, false); } + /** + * Returns the address of an object constant that is embedded as a data reference into the code. + */ + public AbstractAddress asObjectConstRef(Value value) { + assert value.getKind() == Kind.Object && isConstant(value); + return recordDataReferenceInCode((Constant) value, 8, false); + } + public AbstractAddress asIntAddr(Value value) { assert value.getKind() == Kind.Int; return asAddress(value); diff -r e2786e2c491a -r 7a8d6ba83a04 src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Tue Jul 16 18:30:45 2013 +0200 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Tue Jul 16 17:41:21 2013 -0700 @@ -43,8 +43,6 @@ address pc = _instructions->start() + pc_offset; - tty->print_cr("CodeInstaller::pd_site_DataPatch: typeChar=%c, inlined=%d", typeChar, inlined); - switch (typeChar) { case 'z': case 'b': @@ -57,7 +55,9 @@ case 'j': case 'd': { if (inlined) { - fatal(err_msg("inlined: type=%c, constant=%lx", inlined, Constant::primitive(constant))); + NativeMovConstReg* move = nativeMovConstReg_at(pc); + uint64_t value = Constant::primitive(constant); + move->set_data(value); } else { int size = _constants->size(); if (alignment > 0) { @@ -73,23 +73,27 @@ NativeMovRegMem* load = nativeMovRegMem_at(pc); int disp = _constants_size + pc_offset - size - BytesPerInstWord; load->set_offset(-disp); - -// assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); -// *((jint*) operand) = (jint) disp; - -// _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS) /*, Assembler::disp32_operand*/); -// TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); } break; } case 'a': { -// address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); -// Handle obj = Constant::object(constant); -// -// jobject value = JNIHandles::make_local(obj()); -// *((jobject*) operand) = value; -// _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); -// TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); + int size = _constants->size(); + if (alignment > 0) { + guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + size = align_size_up(size, alignment); + } + address dest = _constants->start() + size; + _constants->set_end(dest); + Handle obj = Constant::object(constant); + jobject value = JNIHandles::make_local(obj()); + _constants->emit_address((address) value); + + NativeMovRegMem* load = nativeMovRegMem_at(pc); + int disp = _constants_size + pc_offset - size - BytesPerInstWord; + load->set_offset(-disp); + + int oop_index = _oop_recorder->find_index(value); + _constants->relocate(dest, oop_Relocation::spec(oop_index)); break; } default: @@ -122,18 +126,16 @@ assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); -// _instructions->relocate(call->instruction_address(), -// virtual_call_Relocation::spec(_invoke_mark_pc), -// Assembler::call32_operand); - fatal("NYI"); + _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc)); + /*, Assembler::call32_operand); */ break; } case MARK_INVOKESTATIC: { assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_static_call_stub()); - _instructions->relocate(call->instruction_address(), - relocInfo::static_call_type /*, Assembler::call32_operand*/); + _instructions->relocate(call->instruction_address(), relocInfo::static_call_type); + /*, Assembler::call32_operand); */ break; } case MARK_INVOKESPECIAL: {