# HG changeset patch # User twisti # Date 1375766580 25200 # Node ID 5a9d68c3a7d778aa503a21f1fea22991847ce85d # Parent 22d3ee2fcb97bac07e9091a29fd7f2b7541a7757 SPARC: a lot of fixes and more diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Mon Aug 05 22:23:00 2013 -0700 @@ -104,13 +104,20 @@ } /** + * @return true if this address has an index register + */ + public boolean hasIndex() { + return !getIndex().equals(Register.None); + } + + /** * This method adds the stack-bias to the displacement if the base register is either * {@link SPARC#sp} or {@link SPARC#fp}. * * @return Optional additive displacement. */ public int getDisplacement() { - if (!getIndex().equals(Register.None)) { + if (hasIndex()) { throw GraalInternalError.shouldNotReachHere("address has index register"); } // TODO Should we also hide the register save area size here? diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Aug 05 22:23:00 2013 -0700 @@ -458,9 +458,12 @@ /** * Instruction format for Arithmetic, Logical, Moves, Tcc, Prefetch, and Misc. * - * | 10 | rd | op3 | rs1 | i| imm_asi | rs2 | - * | 10 | rd | op3 | rs1 | i| simm13 | - * |31 30|29 25|24 19|18 14|13|12 5|4 0| + * | 10 | rd | op3 | rs1 | i| imm_asi | rs2 | + * | 10 | rd | op3 | rs1 | i| simm13 | + * | 10 | rd | op3 | rs1 | i| x| | rs2 | + * | 10 | rd | op3 | rs1 | i| x| | shcnt32 | + * | 10 | rd | op3 | rs1 | i| x| | shcnt64 | + * |31 30|29 25|24 19|18 14|13|12|11 5|4 0| */ // @formatter:on public static class Fmt10 { @@ -470,6 +473,7 @@ private static final int OP3_SHIFT = 19; private static final int RS1_SHIFT = 14; private static final int I_SHIFT = 13; + private static final int X_SHIFT = 12; private static final int IMM_ASI_SHIFT = 5; private static final int RS2_SHIFT = 0; private static final int SIMM13_SHIFT = 0; @@ -480,6 +484,7 @@ private static final int OP3_MASK = 0b00000001111110000000000000000000; private static final int RS1_MASK = 0b00000000000001111100000000000000; private static final int I_MASK = 0b00000000000000000010000000000000; + private static final int X_MASK = 0b00000000000000000001000000000000; private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000; private static final int RS2_MASK = 0b00000000000000000000000000011111; private static final int SIMM13_MASK = 0b00000000000000000001111111111111; @@ -489,15 +494,17 @@ private int op3; private int rs1; private int i; + private int x; private int immAsi; private int rs2; private int simm13; - private Fmt10(int rd, int op3, int rs1, int i, int immAsi, int rs2, int simm13) { + private Fmt10(int rd, int op3, int rs1, int i, int x, int immAsi, int rs2, int simm13) { this.rd = rd; this.op3 = op3; this.rs1 = rs1; this.i = i; + this.x = x; this.immAsi = immAsi; this.rs2 = rs2; this.simm13 = simm13; @@ -505,26 +512,40 @@ } public Fmt10(Op3s op3, Register rs1, Register rs2, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, rs2.encoding(), 0); + this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, getXBit(op3), 0, rs2.encoding(), 0); } public Fmt10(Op3s op3, Register rs1, int simm13, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, 0, 0, simm13); + this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, getXBit(op3), 0, 0, simm13); } public Fmt10(Op3s op3) { - this(0, op3.getValue(), 0, 0, 0, 0, 0); + this(0, op3.getValue(), 0, 0, getXBit(op3), 0, 0, 0); } public Fmt10(Op3s op3, Register rs1, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, 0, 0); + this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, getXBit(op3), 0, 0, 0); + } + + /** + * Helper method to determine if the instruction needs the X bit set. + */ + private static int getXBit(Op3s op3) { + switch (op3) { + case Sllx: + case Srax: + case Srlx: + return 1; + default: + return 0; + } } private int getInstructionBits() { if (i == 0) { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT; + return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | x << X_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT; } else { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK); + return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | x << X_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK); } } @@ -540,11 +561,12 @@ final int op3 = (inst & OP3_MASK) >> OP3_SHIFT; final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT; final int i = (inst & I_MASK) >> I_SHIFT; + final int x = (inst & X_MASK) >> X_SHIFT; final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT; final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT; final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT; - return new Fmt10(rd, op3, rs1, i, immAsi, rs2, simm13); + return new Fmt10(rd, op3, rs1, i, x, immAsi, rs2, simm13); } public void write(SPARCAssembler masm, int pos) { @@ -562,6 +584,7 @@ assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT); assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT); assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT); + assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT); assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT); assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT); assert isSimm13(simm13); @@ -711,6 +734,15 @@ } } + // @formatter:off + /** + * Instruction format for Movcc. + * + * | 10 | rd | op3 |cc2| cond | i|cc1|cc0| - | rs2 | + * | 10 | rd | op3 |cc2| cond | i|cc1|cc0| simm11 | + * |31 30|29 25|24 19| 18|17 14|13| 12| 11|10 5|4 0| + */ + // @formatter:on public static class Fmt10c { private static final int OP_SHIFT = 30; @@ -719,7 +751,8 @@ private static final int CC2_SHIFT = 18; private static final int COND_SHIFT = 14; private static final int I_SHIFT = 13; - private static final int CC_SHIFT = 11; + private static final int CC1_SHIFT = 12; + private static final int CC0_SHIFT = 11; private static final int RS2_SHIFT = 0; private static final int SIMM11_SHIFT = 0; @@ -730,7 +763,8 @@ private static final int CC2_MASK = 0b00000000000001000000000000000000; private static final int COND_MASK = 0b00000000000000111100000000000000; private static final int I_MASK = 0b00000000000000000010000000000000; - private static final int CC_MASK = 0b00000000000000000001100000000000; + private static final int CC1_MASK = 0b00000000000000000001000000000000; + private static final int CC0_MASK = 0b00000000000000000000100000000000; private static final int RS2_MASK = 0b00000000000000000000000000011111; private static final int SIMM11_MASK = 0b00000000000000000000011111111111; // @formatter:on @@ -755,20 +789,33 @@ } public Fmt10c(Op3s op3, ConditionFlag cond, CC cc, Register rs2, Register rd) { - this(rd.encoding(), op3.getValue(), cond.getValue(), 0, cc.getValue(), rs2.encoding(), 0); + this(rd.encoding(), op3.getValue(), cond.getValue(), 0, getCC(cc), rs2.encoding(), 0); } public Fmt10c(Op3s op3, ConditionFlag cond, CC cc, int simm11, Register rd) { - this(rd.encoding(), op3.getValue(), cond.getValue(), 1, cc.getValue(), 0, simm11); + this(rd.encoding(), op3.getValue(), cond.getValue(), 1, getCC(cc), 0, simm11); + } + + /** + * Converts regular CC codes to CC codes used by Movcc instructions. + */ + private static int getCC(CC cc) { + switch (cc) { + case Icc: + case Xcc: + return 0b100 + cc.getValue(); + default: + return cc.getValue(); + } } private int getInstructionBits() { if (i == 0) { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << CC2_SHIFT) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT | ((cc << CC_SHIFT) & CC_MASK) | - rs2 << RS2_SHIFT; + return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << (CC2_SHIFT - 2)) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT | + ((cc << (CC1_SHIFT - 1)) & CC1_MASK) | ((cc << CC0_SHIFT) & CC0_MASK) | rs2 << RS2_SHIFT; } else { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << CC2_SHIFT) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT | ((cc << CC_SHIFT) & CC_MASK) | - ((simm11 << SIMM11_SHIFT) & SIMM11_MASK); + return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << (CC2_SHIFT - 2)) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT | + ((cc << (CC1_SHIFT - 1)) & CC1_MASK) | ((cc << CC0_SHIFT) & CC0_MASK) | ((simm11 << SIMM11_SHIFT) & SIMM11_MASK); } } @@ -784,7 +831,7 @@ final int op3 = (inst & OP3_MASK) >> OP3_SHIFT; final int cond = (inst & COND_MASK) >> COND_SHIFT; final int i = (inst & I_MASK) >> I_SHIFT; - final int cc = (inst & CC2_MASK) >> CC2_SHIFT | (inst & CC_MASK) >> CC_SHIFT; + final int cc = (inst & CC2_MASK) >> CC2_SHIFT | (inst & CC1_MASK) >> CC1_SHIFT | (inst & CC0_MASK) >> CC0_SHIFT; final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT; final int simm11 = (inst & SIMM11_MASK) >> SIMM11_SHIFT; @@ -808,7 +855,7 @@ assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT); // assert cc >= 0 && cc < 0x8; assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT); - // assert isSimm11(simm11); + assert isSimm11(simm11); } } @@ -843,7 +890,14 @@ public static final int ImmedTrue = 0x00002000; public enum Ops { - BranchOp(0b00), CallOp(0b01), ArithOp(0b10), LdstOp(0b11); + // @formatter:off + + BranchOp(0b00), + CallOp(0b01), + ArithOp(0b10), + LdstOp(0b11); + + // @formatter:on private final int value; @@ -857,7 +911,18 @@ } public enum Op2s { - Bpr(3), Fb(6), Fbp(5), Br(2), Bp(1), Cb(7), Sethi(4); + // @formatter:off + + Illtrap(0b000), + Bpr(3), + Fb(6), + Fbp(5), + Br(2), + Bp(1), + Cb(7), + Sethi(0b100); + + // @formatter:on private final int value; @@ -871,6 +936,8 @@ } public enum Op3s { + // @formatter:off + Add(0x00, "add"), And(0x01, "and"), Or(0x02, "or"), @@ -943,17 +1010,15 @@ Casa(0b111100, "casa"), Casxa(0b111110, "casxa"), - Lduw(0x00, "lduw"), - Ldub(0x01, "ldub"), - Lduh(0x02, "lduh"), - Ldd(0x03, "ldd"), - Stw(0x04, "stw"), - Stb(0x05, "stb"), - Sth(0x06, "sth"), - Std(0x07, "std"), - Ldsw(0x08, "ldsw"), - Ldsb(0x09, "ldsb"), - Ldsh(0x0A, "ldsh"), + Lduw(0b00000, "lduw"), + Ldub(0b00001, "ldub"), + Lduh(0b00010, "lduh"), + Stw(0b000100, "stw"), + Stb(0b000101, "stb"), + Sth(0b000110, "sth"), + Ldsw(0b001000, "ldsw"), + Ldsb(0b001001, "ldsb"), + Ldsh(0b001010, "ldsh"), Ldx(0b001011, "ldx"), Stx(0b001110, "stx"), @@ -966,6 +1031,8 @@ Staf(0x26, "staf"), Stdf(0x27, "stdf"); + // @formatter:on + private final int value; private final String operator; @@ -984,7 +1051,18 @@ } public enum Op5s { - Fmadds(0x1), Fmaddd(0x2), Fmsubs(0x5), Fmsubd(0x6), Fnmsubs(0x9), Fnmsubd(0xA), Fnmadds(0xD), Fnmaddd(0xE); + // @formatter:off + + Fmadds(0x1), + Fmaddd(0x2), + Fmsubs(0x5), + Fmsubd(0x6), + Fnmsubs(0x9), + Fnmsubd(0xA), + Fnmadds(0xD), + Fnmaddd(0xE); + + // @formatter:on private final int value; @@ -998,9 +1076,17 @@ } public enum Opfs { - Fmovs(0x01, "fmovs"), Fmovd(0x02, "fmovd"), Fmovq(0x03, "fmovq"), Fnegs(0x05, "fnegs"), Fnegd(0x06, "fnegd"), Fnegq(0x07, "fnegq"), Fabss(0x09, "fabss"), Fabsd(0x0A, "fabsd"), Fabsq( - 0x0B, - "fabsq"), + // @formatter:off + + Fmovs(0x01, "fmovs"), + Fmovd(0x02, "fmovd"), + Fmovq(0x03, "fmovq"), + Fnegs(0x05, "fnegs"), + Fnegd(0x06, "fnegd"), + Fnegq(0x07, "fnegq"), + Fabss(0x09, "fabss"), + Fabsd(0x0A, "fabsd"), + Fabsq(0x0B, "fabsq"), // start VIS1 Edge8cc(0x0, "edge8cc"), @@ -1129,6 +1215,7 @@ Fstoi(0xD1, "fstoi"), Fdtoi(0xD2, "fdtoi"); + // @formatter:on private final int value; private final String operator; @@ -1148,9 +1235,17 @@ } public enum MembarMask { - StoreStore(1 << 3, "storestore"), LoadStore(1 << 2, "loadstore"), StoreLoad(1 << 1, "storeload"), LoadLoad(1 << 0, "loadload"), Sync(1 << 6, "sync"), MemIssue(1 << 5, "memissue"), LookAside( - 1 << 4, - "lookaside"); + // @formatter:off + + StoreStore(1 << 3, "storestore"), + LoadStore(1 << 2, "loadstore"), + StoreLoad(1 << 1, "storeload"), + LoadLoad(1 << 0, "loadload"), + Sync(1 << 6, "sync"), + MemIssue(1 << 5, "memissue"), + LookAside(1 << 4, "lookaside"); + + // @formatter:on private final int value; private final String operator; @@ -1170,7 +1265,17 @@ } public enum CC { - Icc(0, "icc"), Xcc(2, "xcc"), Ptrcc(HotSpotGraalRuntime.wordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"), Fcc0(0, "fcc0"), Fcc1(1, "fcc1"), Fcc2(2, "fcc2"), Fcc3(3, "fcc3"); + // @formatter:off + + Icc(0b00, "icc"), + Xcc(0b10, "xcc"), + Ptrcc(HotSpotGraalRuntime.wordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"), + Fcc0(0b00, "fcc0"), + Fcc1(0b01, "fcc1"), + Fcc2(0b10, "fcc2"), + Fcc3(0b11, "fcc3"); + + // @formatter:on private final int value; private final String operator; @@ -1190,8 +1295,9 @@ } public enum ConditionFlag { + // @formatter:off + // for FBfcc & FBPfcc instruction - F_Never(0, "f_never"), F_NotEqual(1, "f_notEqual"), F_NotZero(1, "f_notZero"), @@ -1233,6 +1339,8 @@ Positive(14, "positive"), OverflowClear(15, "overflowClear"); + // @formatter:on + private final int value; private final String operator; @@ -1251,7 +1359,17 @@ } public enum RCondition { - Rc_z(1, "rc_z"), Rc_lez(2, "rc_lez"), Rc_lz(3, "rc_lz"), Rc_nz(5, "rc_nz"), Rc_gz(6, "rc_gz"), Rc_gez(7, "rc_gez"), Rc_last(Rc_gez.getValue(), "rc_last"); + // @formatter:off + + Rc_z(1, "rc_z"), + Rc_lez(2, "rc_lez"), + Rc_lz(3, "rc_lz"), + Rc_nz(5, "rc_nz"), + Rc_gz(6, "rc_gz"), + Rc_gez(7, "rc_gez"), + Rc_last(Rc_gez.getValue(), "rc_last"); + + // @formatter:on private final int value; private final String operator; @@ -1271,12 +1389,19 @@ } public enum Asi { - INVALID(-1), ASI_PRIMARY(0x80), ASI_PRIMARY_NOFAULT(0x82), ASI_PRIMARY_LITTLE(0x88), + // @formatter:off + + 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); + // @formatter:on + private final int value; private Asi(int value) { @@ -1337,6 +1462,10 @@ return minSimm(nbits) <= imm && imm <= maxSimm(nbits); } + public static boolean isSimm11(int imm) { + return isSimm(imm, 11); + } + public static boolean isSimm13(int imm) { return isSimm(imm, 13); } @@ -2613,6 +2742,13 @@ } } + public static class Illtrap extends Fmt00a { + + public Illtrap(int const22) { + super(Op2s.Illtrap, const22, g0); + } + } + public static class Jmpl extends Fmt10 { public Jmpl(Register src, int simm13, Register dst) { @@ -2648,6 +2784,13 @@ } } + public static class Lduh extends Fmt11 { + + public Lduh(SPARCAddress src, Register dst) { + super(Op3s.Lduh, src, dst); + } + } + public static class Ldsw extends Fmt11 { public Ldsw(SPARCAddress src, Register dst) { @@ -2921,8 +3064,8 @@ public static class Sll extends Fmt10 { - public Sll(Register src1, int simm13, Register dst) { - super(Op3s.Sll, src1, simm13, dst); + public Sll(Register src1, int shcnt32, Register dst) { + super(Op3s.Sll, src1, shcnt32, dst); } public Sll(Register src1, Register src2, Register dst) { @@ -2932,8 +3075,8 @@ public static class Sllx extends Fmt10 { - public Sllx(Register src1, int simm13, Register dst) { - super(Op3s.Sllx, src1, simm13, dst); + public Sllx(Register src1, int shcnt64, Register dst) { + super(Op3s.Sllx, src1, shcnt64, dst); } public Sllx(Register src1, Register src2, Register dst) { @@ -2943,8 +3086,8 @@ public static class Sra extends Fmt10 { - public Sra(Register src1, int simm13, Register dst) { - super(Op3s.Sra, src1, simm13, dst); + public Sra(Register src1, int shcnt32, Register dst) { + super(Op3s.Sra, src1, shcnt32, dst); } public Sra(Register src1, Register src2, Register dst) { @@ -2954,8 +3097,8 @@ public static class Srax extends Fmt10 { - public Srax(Register src1, int simm13, Register dst) { - super(Op3s.Srax, src1, simm13, dst); + public Srax(Register src1, int shcnt64, Register dst) { + super(Op3s.Srax, src1, shcnt64, dst); } public Srax(Register src1, Register src2, Register dst) { @@ -2965,8 +3108,8 @@ public static class Srl extends Fmt10 { - public Srl(Register src1, int simm13, Register dst) { - super(Op3s.Srl, src1, simm13, dst); + public Srl(Register src1, int shcnt32, Register dst) { + super(Op3s.Srl, src1, shcnt32, dst); } public Srl(Register src1, Register src2, Register dst) { @@ -2976,8 +3119,8 @@ public static class Srlx extends Fmt10 { - public Srlx(Register src1, int simm13, Register dst) { - super(Op3s.Srlx, src1, simm13, dst); + public Srlx(Register src1, int shcnt64, Register dst) { + super(Op3s.Srlx, src1, shcnt64, dst); } public Srlx(Register src1, Register src2, Register dst) { diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Mon Aug 05 22:23:00 2013 -0700 @@ -53,7 +53,7 @@ @Override public void jmp(Label l) { new Bpa(l).emit(this); - new Nop().emit(this); + new Nop().emit(this); // delay slot } @Override @@ -74,6 +74,10 @@ return Placeholder; } + public final void ensureUniquePC() { + new Nop().emit(this); + } + public static class Bclr extends Andn { public Bclr(Register src, Register dst) { @@ -96,6 +100,17 @@ } } + public static class Bplu extends Bpcs { + + public Bplu(CC cc, int simm19) { + super(cc, simm19); + } + + public Bplu(CC cc, Label label) { + super(cc, label); + } + } + public static class Bset extends Or { public Bset(Register src, Register dst) { @@ -240,7 +255,6 @@ public Neg(Register src2, Register dst) { super(g0, src2, dst); - assert src2.encoding() != dst.encoding(); } public Neg(Register dst) { @@ -421,7 +435,6 @@ public Signx(Register src1, Register dst) { super(src1, g0, dst); - assert src1.encoding() != dst.encoding(); } public Signx(Register dst) { diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Aug 05 22:23:00 2013 -0700 @@ -24,7 +24,6 @@ package com.oracle.graal.compiler.sparc; import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.lir.LIRValueUtil.*; import static com.oracle.graal.lir.sparc.SPARCArithmetic.*; import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.*; import static com.oracle.graal.lir.sparc.SPARCCompare.*; @@ -32,6 +31,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; @@ -39,26 +39,8 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Reg; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack; -import com.oracle.graal.lir.sparc.SPARCArithmetic.ShiftOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op; -import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.BranchOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.CondMoveOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.FloatCondMoveOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.SequentialSwitchOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.SwitchRangesOp; -import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp; -import com.oracle.graal.lir.sparc.SPARCMove.MembarOp; -import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; -import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; -import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; -import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.*; +import com.oracle.graal.lir.sparc.SPARCMove.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.ConvertNode.Op; @@ -99,7 +81,7 @@ case Double: return false; default: - return c.isNull(); + return c.isDefaultForKind(); } } @@ -113,7 +95,7 @@ case Object: return c.isNull(); default: - return true; + return false; } } @@ -126,8 +108,7 @@ protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) { if (src instanceof SPARCAddressValue) { - // return new LeaOp(dst, (AMD64AddressValue) src); - throw new InternalError("NYI"); + return new LoadAddressOp(dst, (SPARCAddressValue) src); } else if (isRegister(src) || isStackSlot(dst)) { return new MoveFromRegOp(dst, src); } else { @@ -164,9 +145,13 @@ indexRegister = Value.ILLEGAL; } else { if (scale != 1) { - Variable longIndex = newVariable(Kind.Long); - emitMove(longIndex, index); - indexRegister = emitMul(longIndex, Constant.forLong(scale)); + // Variable longIndex = newVariable(Kind.Long); + Variable longIndex = emitConvert(Op.I2L, index); + if (CodeUtil.isPowerOf2(scale)) { + indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale))); + } else { + indexRegister = emitMul(longIndex, Constant.forLong(scale)); + } } else { indexRegister = asAllocatable(index); } @@ -193,13 +178,12 @@ displacementInt = (int) finalDisp; } else { displacementInt = 0; - AllocatableValue displacementRegister = load(Constant.forLong(finalDisp)); if (baseRegister.equals(Value.ILLEGAL)) { - baseRegister = displacementRegister; + baseRegister = load(Constant.forLong(finalDisp)); } else { - Variable longBase = newVariable(Kind.Long); - emitMove(longBase, baseRegister); - baseRegister = emitAdd(longBase, displacementRegister); + Variable longBaseRegister = newVariable(Kind.Long); + emitMove(longBaseRegister, baseRegister); // FIXME get rid of this move + baseRegister = emitAdd(longBaseRegister, Constant.forLong(finalDisp)); } } @@ -241,11 +225,12 @@ public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { boolean mirrored = emitCompare(left, right); Condition finalCondition = mirrored ? cond.mirror() : cond; - switch (left.getKind().getStackKind()) { + Kind kind = left.getKind().getStackKind(); + switch (kind) { case Int: case Long: case Object: - append(new BranchOp(finalCondition, label)); + append(new BranchOp(finalCondition, label, kind)); break; // case Float: // append(new CompareOp(FCMP, x, y)); @@ -263,13 +248,13 @@ @Override public void emitOverflowCheckBranch(LabelRef label, boolean negated) { // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label)); - throw GraalInternalError.shouldNotReachHere("emitOverflowCheckBranch: unimp"); + throw GraalInternalError.unimplemented(); } @Override public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { emitIntegerTest(left, right); - append(new BranchOp(negated ? Condition.NE : Condition.EQ, label)); + append(new BranchOp(negated ? Condition.NE : Condition.EQ, label, left.getKind().getStackKind())); } private void emitIntegerTest(Value a, Value b) { @@ -282,22 +267,6 @@ } @Override - public Variable load(Value value) { - if (!isVariable(value)) { - return emitMove(value); - } - return (Variable) value; - } - - @Override - public Value loadNonConst(Value value) { - if (isConstant(value) && !canInlineConstant((Constant) value)) { - return emitMove(value); - } - return value; - } - - @Override public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { boolean mirrored = emitCompare(left, right); Condition finalCondition = mirrored ? cond.mirror() : cond; @@ -384,12 +353,8 @@ protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { // Making a copy of the switch value is necessary because jump table destroys the input // value - if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { - append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL)); - } else { - assert key.getKind() == Kind.Object : key.getKind(); - append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object))); - } + assert key.getKind() == Kind.Int || key.getKind() == Kind.Long || key.getKind() == Kind.Object : key.getKind(); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(key.getKind()))); } @Override @@ -408,23 +373,23 @@ @Override public void emitBitCount(Variable result, Value operand) { if (operand.getKind().getStackKind() == Kind.Int) { - append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand))); + append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand), this)); } else { - append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand))); + append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand), this)); } } @Override public void emitBitScanForward(Variable result, Value operand) { - append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand))); + append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this)); } @Override public void emitBitScanReverse(Variable result, Value operand) { if (operand.getKind().getStackKind() == Kind.Int) { - append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand))); + append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this)); } else { - append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand))); + append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand), this)); } } @@ -466,7 +431,7 @@ @Override public Value emitNegate(Value input) { Variable result = newVariable(input.getKind()); - switch (input.getKind()) { + switch (input.getKind().getStackKind()) { case Int: append(new Op1Stack(INEG, result, input)); break; @@ -482,32 +447,71 @@ return result; } - @Override - public Variable emitAdd(Value a, Value b) { - Variable result = newVariable(a.getKind()); - switch (a.getKind()) { - case Int: - append(new Op2Stack(IADD, result, a, loadNonConst(b))); + private Variable emitBinary(SPARCArithmetic op, boolean commutative, Value a, Value b) { + if (isConstant(b)) { + return emitBinaryConst(op, commutative, asAllocatable(a), asConstant(b)); + } else if (commutative && isConstant(a)) { + return emitBinaryConst(op, commutative, asAllocatable(b), asConstant(a)); + } else { + return emitBinaryVar(op, commutative, asAllocatable(a), asAllocatable(b)); + } + } + + private Variable emitBinaryConst(SPARCArithmetic op, boolean commutative, AllocatableValue a, Constant b) { + switch (op) { + case IADD: + case LADD: + case ISUB: + case LSUB: + case IAND: + case LAND: + case IOR: + case LOR: + case IXOR: + case LXOR: + case IMUL: + case LMUL: + if (NumUtil.isInt(b.asLong())) { + Variable result = newVariable(a.getKind()); + append(new BinaryRegConst(op, result, a, b)); + return result; + } break; - case Long: - append(new Op2Stack(LADD, result, a, loadNonConst(b))); - break; - case Float: - append(new Op2Stack(FADD, result, a, loadNonConst(b))); - break; - case Double: - append(new Op2Stack(DADD, result, a, loadNonConst(b))); - break; - default: - throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind() + " prim: " + a.getKind().isPrimitive()); + } + + return emitBinaryVar(op, commutative, a, asAllocatable(b)); + } + + private Variable emitBinaryVar(SPARCArithmetic op, boolean commutative, AllocatableValue a, AllocatableValue b) { + Variable result = newVariable(a.getKind()); + if (commutative) { + append(new BinaryCommutative(op, result, a, b)); + } else { + append(new BinaryRegReg(op, result, a, b)); } return result; } @Override + public Variable emitAdd(Value a, Value b) { + switch (a.getKind().getStackKind()) { + case Int: + return emitBinary(IADD, true, a, b); + case Long: + return emitBinary(LADD, true, a, b); + case Float: + return emitBinary(FADD, true, a, b); + case Double: + return emitBinary(DADD, true, a, b); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override public Variable emitSub(Value a, Value b) { Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: append(new Op2Stack(ISUB, result, a, loadNonConst(b))); break; @@ -529,12 +533,12 @@ @Override public Variable emitMul(Value a, Value b) { Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: - append(new Op2Reg(IMUL, result, a, loadNonConst(b))); + append(new BinaryRegReg(IMUL, result, a, loadNonConst(b))); break; case Long: - append(new Op2Reg(LMUL, result, a, loadNonConst(b))); + append(new BinaryRegReg(LMUL, result, a, loadNonConst(b))); break; case Float: append(new Op2Stack(FMUL, result, a, loadNonConst(b))); @@ -551,12 +555,12 @@ @Override public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: - append(new Op2Reg(IDIV, result, a, loadNonConst(b))); + append(new BinaryRegReg(IDIV, result, a, loadNonConst(b))); break; case Long: - append(new Op2Reg(LDIV, result, a, loadNonConst(b))); + append(new BinaryRegReg(LDIV, result, a, loadNonConst(b))); break; case Float: append(new Op2Stack(FDIV, result, a, loadNonConst(b))); @@ -572,13 +576,14 @@ @Override public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { + LIRFrameState state = state(deopting); Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: - append(new Op2Reg(IREM, result, a, loadNonConst(b))); + append(new RemOp(IREM, result, a, loadNonConst(b), state, this)); break; case Long: - append(new Op2Reg(LREM, result, a, loadNonConst(b))); + append(new RemOp(LREM, result, a, loadNonConst(b), state, this)); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); @@ -588,9 +593,8 @@ @Override public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) { - @SuppressWarnings("unused") - LIRFrameState state = state(deopting); - switch (a.getKind()) { +// LIRFrameState state = state(deopting); + switch (a.getKind().getStackKind()) { case Int: // emitDivRem(IUDIV, a, b, state); // return emitMove(RAX_I); @@ -604,9 +608,8 @@ @Override public Value emitURem(Value a, Value b, DeoptimizingNode deopting) { - @SuppressWarnings("unused") - LIRFrameState state = state(deopting); - switch (a.getKind()) { +// LIRFrameState state = state(deopting); + switch (a.getKind().getStackKind()) { case Int: // emitDivRem(IUREM, a, b, state); // return emitMove(RDX_I); @@ -621,7 +624,7 @@ @Override public Variable emitAnd(Value a, Value b) { Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: append(new Op2Stack(IAND, result, a, loadNonConst(b))); break; @@ -638,7 +641,7 @@ @Override public Variable emitOr(Value a, Value b) { Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: append(new Op2Stack(IOR, result, a, loadNonConst(b))); break; @@ -654,7 +657,7 @@ @Override public Variable emitXor(Value a, Value b) { Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: append(new Op2Stack(IXOR, result, a, loadNonConst(b))); break; @@ -667,52 +670,51 @@ return result; } - @Override - public Variable emitShl(Value a, Value b) { - Variable result = newVariable(a.getKind()); - switch (a.getKind()) { - case Int: - append(new Op2Stack(ISHL, result, a, loadNonConst(b))); - break; - case Long: - append(new Op2Stack(LSHL, result, a, loadNonConst(b))); - break; - default: - throw GraalInternalError.shouldNotReachHere(); + private Variable emitShift(SPARCArithmetic op, Value a, Value b) { + Variable result = newVariable(a.getPlatformKind()); + AllocatableValue input = asAllocatable(a); + if (isConstant(b)) { + append(new BinaryRegConst(op, result, input, asConstant(b))); + } else { + append(new BinaryRegReg(op, result, input, b)); } return result; } @Override - public Variable emitShr(Value a, Value b) { - Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + public Variable emitShl(Value a, Value b) { + switch (a.getKind().getStackKind()) { case Int: - append(new Op2Stack(ISHR, result, a, loadNonConst(b))); - break; + return emitShift(ISHL, a, b); case Long: - append(new Op2Stack(LSHR, result, a, loadNonConst(b))); - break; + return emitShift(LSHL, a, b); default: throw GraalInternalError.shouldNotReachHere(); } - return result; + } + + @Override + public Variable emitShr(Value a, Value b) { + switch (a.getKind().getStackKind()) { + case Int: + return emitShift(ISHR, a, b); + case Long: + return emitShift(LSHR, a, b); + default: + throw GraalInternalError.shouldNotReachHere(); + } } @Override public Variable emitUShr(Value a, Value b) { - Variable result = newVariable(a.getKind()); - switch (a.getKind()) { + switch (a.getKind().getStackKind()) { case Int: - append(new ShiftOp(IUSHR, result, a, b)); - break; + return emitShift(IUSHR, a, b); case Long: - append(new ShiftOp(LUSHR, result, a, b)); - break; + return emitShift(LUSHR, a, b); default: throw GraalInternalError.shouldNotReachHere(); } - return result; } @Override @@ -724,13 +726,13 @@ append(new Unary2Op(I2L, result, input)); break; case L2I: - append(new Unary1Op(L2I, result, input)); + append(new Unary2Op(L2I, result, input)); break; case I2B: append(new Unary2Op(I2B, result, input)); break; case I2C: - append(new Unary1Op(I2C, result, input)); + append(new Unary2Op(I2C, result, input)); break; case I2S: append(new Unary2Op(I2S, result, input)); diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.asm.*; @@ -38,11 +39,14 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { Register thread = graalRuntime().getRuntime().threadRegister(); + HotSpotVMConfig config = graalRuntime().getConfig(); // Restore the thread register when coming back from the runtime. new Mov(l7, thread).emit(masm); - // Reset last Java frame. - new Stx(g0, new SPARCAddress(thread, graalRuntime().getConfig().threadLastJavaSpOffset)).emit(masm); + // Reset last Java frame, last Java PC and flags. + new Stx(g0, new SPARCAddress(thread, config.threadLastJavaSpOffset)).emit(masm); + new Stx(g0, new SPARCAddress(thread, config.threadLastJavaPcOffset)).emit(masm); + new Stw(g0, new SPARCAddress(thread, config.threadJavaFrameAnchorFlagsOffset)).emit(masm); } } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.*; @@ -39,12 +40,13 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { HotSpotRuntime runtime = graalRuntime().getRuntime(); + HotSpotVMConfig config = graalRuntime().getConfig(); Register thread = runtime.threadRegister(); Register stackPointer = runtime.stackPointerRegister(); // Save last Java frame. new Add(stackPointer, new SPARCAddress(stackPointer, 0).getDisplacement(), g4).emit(masm); - new Stx(g4, new SPARCAddress(thread, graalRuntime().getConfig().threadLastJavaSpOffset)).emit(masm); + new Stx(g4, new SPARCAddress(thread, config.threadLastJavaSpOffset)).emit(masm); // Save the thread register when calling out to the runtime. new Mov(thread, l7).emit(masm); diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Mon Aug 05 22:23:00 2013 -0700 @@ -53,7 +53,7 @@ protected TargetDescription createTarget() { final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = false; // TODO We might want to change this later. + final boolean inlineObjects = true; return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Mon Aug 05 22:23:00 2013 -0700 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.sparc.SPARC.*; import java.lang.reflect.*; @@ -157,14 +158,11 @@ @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { -// AllocatableValue metaspaceMethod = AMD64.rbx.asValue(); -// emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) -// callTarget).metaspaceMethod())); -// AllocatableValue targetAddress = AMD64.rax.asValue(); -// emitMove(targetAddress, operand(callTarget.computedAddress())); -// append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, -// targetAddress, callState)); - throw GraalInternalError.unimplemented(); + AllocatableValue metaspaceMethod = g5.asValue(); + emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); + AllocatableValue targetAddress = g3.asValue(); + emitMove(targetAddress, operand(callTarget.computedAddress())); + append(new SPARCIndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); } @Override diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Mon Aug 05 22:23:00 2013 -0700 @@ -33,6 +33,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.*; public class SPARCHotSpotRegisterConfig implements RegisterConfig { @@ -77,9 +78,12 @@ 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}; -// private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, -// i4, i5, i6, i7}; - private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7}; + + /** + * Registers saved by the callee. This lists all L and I registers which are saved in the + * register window. {@link FrameMap} uses this array to calculate the spill area size. + */ + private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7}; private final CalleeSaveLayout csl; @@ -100,7 +104,7 @@ // TODO this is not complete o0, o1, o2, o3, o4, o5, /*o6,*/ o7, l0, l1, l2, l3, l4, l5, l6, l7, - i0, i1, i2, i3, i4, i5, /*i6,*/ i7, + i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ f0, f1, f2, f3, f4, f5, f6, f7 }; } else { @@ -108,7 +112,7 @@ // TODO this is not complete o0, o1, o2, o3, o4, o5, /*o6,*/ o7, l0, l1, l2, l3, l4, l5, l6, l7, - i0, i1, i2, i3, i4, i5, /*i6,*/ i7, + i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ f0, f1, f2, f3, f4, f5, f6, f7 }; } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -32,6 +32,7 @@ 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; /** @@ -56,11 +57,7 @@ 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. -// 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); + SPARCMove.move(tasm, masm, g5.asValue(Kind.Long), metaspaceMethod); tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); // SPARCMove.move(tasm, masm, g3.asValue(Kind.Long), Constant.LONG_0); new Setx(nonOopBits, g3, true).emit(masm); diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -42,7 +42,6 @@ @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) { @@ -55,14 +54,8 @@ 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); + new Setx(HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits, g3, true).emit(masm); super.emitCode(tasm, masm); } } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -0,0 +1,72 @@ +/* + * 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.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.sparc.SPARC.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.sparc.SPARCCall.IndirectCallOp; +import com.oracle.graal.lir.asm.*; + +/** + * A register indirect call that complies with the extra conventions for such calls in HotSpot. In + * particular, the metaspace Method of the callee must be in g5 for the case where a vtable entry's + * _from_compiled_entry is the address of an C2I adapter. Such adapters expect the target method to + * be in g5. + */ +@Opcode("CALL_INDIRECT") +final class SPARCIndirectCallOp extends IndirectCallOp { + + /** + * Vtable stubs expect the metaspace Method in g5. + */ + public static final Register METHOD = g5; + + @Use({REG}) protected Value metaspaceMethod; + + SPARCIndirectCallOp(ResolvedJavaMethod targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state) { + super(targetMethod, result, parameters, temps, targetAddress, state); + this.metaspaceMethod = metaspaceMethod; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + tasm.recordMark(Marks.MARK_INLINE_INVOKE); + Register callReg = asRegister(targetAddress); + assert !callReg.equals(METHOD); + SPARCCall.indirectCall(tasm, masm, callReg, callTarget, state); + } + + @Override + protected void verify() { + super.verify(); + assert asRegister(metaspaceMethod).equals(METHOD); + } +} diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Mon Aug 05 22:23:00 2013 -0700 @@ -45,6 +45,7 @@ public SPARCAddressValue(PlatformKind kind, AllocatableValue base, AllocatableValue index, int displacement) { super(kind); + assert isIllegal(index) || displacement == 0; this.base = base; this.index = index; this.displacement = displacement; diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Mon Aug 05 22:23:00 2013 -0700 @@ -31,11 +31,12 @@ import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.spi.*; public enum SPARCArithmetic { // @formatter:off - IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, - LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, + IADD, ISUB, IMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, + LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, INEG, LNEG, FNEG, DNEG, @@ -47,36 +48,6 @@ // @formatter:on /** - * Binary operation with single source/destination operand and one constant. - */ - public static class BinaryRegConst extends SPARCLIRInstruction { - - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected AllocatableValue result; - @Use({REG, STACK}) protected AllocatableValue x; - protected Constant y; - - public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { - this.opcode = opcode; - this.result = result; - this.x = x; - this.y = y; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - SPARCMove.move(tasm, masm, result, x); - emit(tasm, masm, opcode, result, y, null); - } - - @Override - public void verify() { - super.verify(); - verifyKind(opcode, result, x, y); - } - } - - /** * Unary operation with separate source and destination operand. */ public static class Unary2Op extends SPARCLIRInstruction { @@ -93,32 +64,10 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - SPARCMove.move(tasm, masm, result, x); emit(tasm, masm, opcode, result, x, null); } } - /** - * Unary operation with single operand for source and destination. - */ - public static class Unary1Op extends SPARCLIRInstruction { - - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected AllocatableValue result; - @Use({REG, STACK}) protected AllocatableValue x; - - public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { - this.opcode = opcode; - this.result = result; - this.x = x; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - emit(masm, opcode, result); - } - } - public static class Op1Stack extends SPARCLIRInstruction { @Opcode private final SPARCArithmetic opcode; @@ -140,9 +89,9 @@ public static class Op2Stack extends SPARCLIRInstruction { @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; - @Alive({REG, STACK, CONST}) protected Value y; + @Def({REG}) protected Value result; + @Use({REG, CONST}) protected Value x; + @Alive({REG, CONST}) protected Value y; public Op2Stack(SPARCArithmetic opcode, Value result, Value x, Value y) { this.opcode = opcode; @@ -163,14 +112,47 @@ } } - public static class Op2Reg extends SPARCLIRInstruction { + /** + * Binary operation with two operands. The first source operand is combined with the + * destination. The second source operand must be a register. + */ + public static class BinaryRegReg extends SPARCLIRInstruction { @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; + @Def({REG}) protected Value result; + @Use({REG, CONST}) protected Value x; @Alive({REG, CONST}) protected Value y; - public Op2Reg(SPARCArithmetic opcode, Value result, Value x, Value y) { + public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } + + /** + * Binary operation with single source/destination operand and one constant. + */ + public static class BinaryRegConst extends SPARCLIRInstruction { + + @Opcode private final SPARCArithmetic opcode; + @Def({REG}) protected AllocatableValue result; + @Use({REG}) protected AllocatableValue x; + protected Constant y; + + public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { this.opcode = opcode; this.result = result; this.x = x; @@ -189,14 +171,17 @@ } } - public static class ShiftOp extends SPARCLIRInstruction { + /** + * Commutative binary operation with two operands. + */ + public static class BinaryCommutative extends SPARCLIRInstruction { @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; - @Alive({REG, CONST}) protected Value y; + @Def({REG, HINT}) protected AllocatableValue result; + @Use({REG}) protected AllocatableValue x; + @Use({REG}) protected AllocatableValue y; - public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) { + public BinaryCommutative(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { this.opcode = opcode; this.result = result; this.x = x; @@ -209,6 +194,33 @@ } @Override + protected void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } + + public static class ShiftOp extends SPARCLIRInstruction { + + @Opcode private final SPARCArithmetic opcode; + @Def({REG}) protected Value result; + @Use({REG, CONST}) protected Value x; + @Alive({REG, CONST}) protected Value y; + + public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + assert !(x instanceof SPARCAddressValue); + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override public void verify() { super.verify(); verifyKind(opcode, result, x, x); @@ -216,17 +228,35 @@ } } - protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode, Value result) { - switch (opcode) { - case L2I: - new And(asIntReg(result), -1, asIntReg(result)).emit(masm); - break; - case I2C: - new Sll(asIntReg(result), 16, asIntReg(result)).emit(masm); - new Srl(asIntReg(result), 16, asIntReg(result)).emit(masm); - break; - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + public static class RemOp extends SPARCLIRInstruction { + + @Opcode private final SPARCArithmetic opcode; + @Def({REG}) protected Value result; + @Use({REG, CONST}) protected Value x; + @Alive({REG, CONST}) protected Value y; + @Def({REG}) protected Value scratch1; + @Def({REG}) protected Value scratch2; + @State protected LIRFrameState state; + + public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + this.scratch1 = gen.newVariable(x.getKind()); + this.scratch2 = gen.newVariable(x.getKind()); + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + emit(tasm, masm, opcode, result, x, y, scratch1, scratch2, state); + } + + @Override + protected void verify() { + super.verify(); + verifyKind(opcode, result, x, y); } } @@ -266,6 +296,11 @@ assert isSimm13(tasm.asIntConst(src2)); new Mulx(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); break; + case IDIV: + assert isSimm13(tasm.asIntConst(src2)); + new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); + new Sdivx(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); + break; case IAND: assert isSimm13(tasm.asIntConst(src2)); new And(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); @@ -282,6 +317,10 @@ assert isSimm13(tasm.asIntConst(src2)); new Srl(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm); break; + case IOR: + assert isSimm13(tasm.asIntConst(src2)); + new Or(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); @@ -298,6 +337,10 @@ assert isSimm13(tasm.asIntConst(src2)); new Mulx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); break; + case LDIV: + throw GraalInternalError.unimplemented(); + case LUDIV: + throw GraalInternalError.unimplemented(); case LAND: assert isSimm13(tasm.asIntConst(src2)); new And(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); @@ -312,11 +355,15 @@ break; case LSHL: assert isSimm13(tasm.asIntConst(src2)); - new Sll(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); + new Sllx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); + break; + case LSHR: + assert isSimm13(tasm.asIntConst(src2)); + new Srax(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); break; case LUSHR: assert isSimm13(tasm.asIntConst(src2)); - new Srl(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); + new Srlx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm); break; case FADD: case FMUL: @@ -339,6 +386,8 @@ new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IDIV: + new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); + new Signx(asIntReg(src2), asIntReg(src2)).emit(masm); new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IAND: @@ -373,6 +422,8 @@ case LDIV: new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; + case LUDIV: + throw GraalInternalError.unimplemented(); case LAND: new And(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; @@ -383,19 +434,14 @@ new Xor(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LSHL: - new Sllx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + new Sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); break; case LSHR: - new Srlx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + new Srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); break; case LUSHR: - new Srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); + new Srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); break; - case LDIVREM: - case LUDIV: - case LUREM: - case LREM: - throw GraalInternalError.unimplemented(); case FADD: new Fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); break; @@ -425,7 +471,43 @@ case DREM: throw GraalInternalError.unimplemented(); default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + throw GraalInternalError.shouldNotReachHere(); + } + } + + if (info != null) { + assert exceptionOffset != -1; + tasm.recordImplicitException(exceptionOffset, info); + } + } + + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info) { + int exceptionOffset = -1; + if (isConstant(src1)) { + switch (opcode) { + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(src2)) { + switch (opcode) { + case LREM: + assert isSimm13(tasm.asIntConst(src2)); + new Sdivx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(scratch1)).emit(masm); + new Mulx(asLongReg(scratch1), tasm.asIntConst(src2), asLongReg(scratch2)).emit(masm); + new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); + break; + case LUREM: + throw GraalInternalError.unimplemented(); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (opcode) { + case LREM: + case LUREM: + throw GraalInternalError.unimplemented(); + default: + throw GraalInternalError.shouldNotReachHere(); } } @@ -444,12 +526,19 @@ new Neg(asIntReg(src), asIntReg(dst)).emit(masm); break; case I2L: - new Sra(asIntReg(src), 0, asLongReg(dst)).emit(masm); + new Signx(asIntReg(src), asLongReg(dst)).emit(masm); + break; + case L2I: + new Signx(asLongReg(src), asIntReg(dst)).emit(masm); break; case I2B: new Sll(asIntReg(src), 24, asIntReg(dst)).emit(masm); new Srl(asIntReg(dst), 24, asIntReg(dst)).emit(masm); break; + case I2C: + new Sll(asIntReg(src), 16, asIntReg(dst)).emit(masm); + new Srl(asIntReg(dst), 16, asIntReg(dst)).emit(masm); + break; case I2F: new Fstoi(masm, asIntReg(src), asFloatReg(dst)); break; diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -22,8 +22,10 @@ */ package com.oracle.graal.lir.sparc; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; @@ -32,7 +34,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -import com.oracle.graal.sparc.SPARC; +import com.oracle.graal.nodes.spi.*; public class SPARCBitManipulationOp extends SPARCLIRInstruction { @@ -42,37 +44,38 @@ @Opcode private final IntrinsicOpcode opcode; @Def protected AllocatableValue result; - @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input; + @Use({REG}) protected AllocatableValue input; + @Def({REG}) protected Value scratch; - public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) { + public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input, LIRGeneratorTool gen) { this.opcode = opcode; this.result = result; this.input = input; + if (opcode == IntrinsicOpcode.IBSR || opcode == IntrinsicOpcode.LBSR) { + scratch = gen.newVariable(input.getKind()); + } } @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - Register dst = ValueUtil.asIntReg(result); - Register tmp = null; // ?? - if (ValueUtil.isRegister(input)) { - Register src = ValueUtil.asRegister(input); + Register dst = asIntReg(result); + if (isRegister(input)) { + Register src = asRegister(input); switch (opcode) { case IPOPCNT: // clear upper word for 64 bit POPC - new Srl(src, SPARC.g0, dst).emit(masm); + new Srl(src, g0, dst).emit(masm); new Popc(src, dst).emit(masm); break; case LPOPCNT: new Popc(src, dst).emit(masm); break; case BSF: - // countTrailingZerosI - bsfl - // countTrailingZerosL - masm.bsfq(dst, src); Kind tkind = input.getKind(); if (tkind == Kind.Int) { new Sub(src, 1, dst).emit(masm); new Andn(dst, src, dst).emit(masm); - new Srl(dst, SPARC.g0, dst).emit(masm); + new Srl(dst, g0, dst).emit(masm); new Popc(dst, dst).emit(masm); } else if (tkind == Kind.Long) { new Sub(src, 1, dst).emit(masm); @@ -82,11 +85,10 @@ throw GraalInternalError.shouldNotReachHere("missing: " + tkind); } break; - case IBSR: - // countLeadingZerosI_bsr masm.bsrq(dst, src); - // masm.bsrl(dst, src); + case IBSR: { Kind ikind = input.getKind(); assert ikind == Kind.Int; + Register tmp = asRegister(scratch); new Srl(src, 1, tmp).emit(masm); new Srl(src, 0, dst).emit(masm); new Or(src, tmp, dst).emit(masm); @@ -102,11 +104,11 @@ new Mov(ikind.getBitCount(), tmp).emit(masm); new Sub(tmp, dst, dst).emit(masm); break; - case LBSR: - // countLeadingZerosL_bsr masm.bsrq(dst, src); - // masm.bsrq(dst, src); + } + case LBSR: { Kind lkind = input.getKind(); assert lkind == Kind.Int; + Register tmp = asRegister(scratch); new Srlx(src, 1, tmp).emit(masm); new Or(src, tmp, dst).emit(masm); new Srlx(dst, 2, tmp).emit(masm); @@ -123,11 +125,12 @@ new Mov(lkind.getBitCount(), tmp).emit(masm); new Sub(tmp, dst, dst).emit(masm); break; + } default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + throw GraalInternalError.shouldNotReachHere(); } - } else if (ValueUtil.isConstant(input) && isSimm13(tasm.asIntConst(input))) { + } else if (isConstant(input) && isSimm13(tasm.asIntConst(input))) { switch (opcode) { case IPOPCNT: new Popc(tasm.asIntConst(input), dst).emit(masm); @@ -136,48 +139,49 @@ new Popc(tasm.asIntConst(input), dst).emit(masm); break; default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + throw GraalInternalError.shouldNotReachHere(); } } else { - SPARCAddress src = (SPARCAddress) tasm.asAddress(input); - switch (opcode) { - case IPOPCNT: - new Ldsw(src, tmp).emit(masm); - // clear upper word for 64 bit POPC - new Srl(tmp, g0, dst).emit(masm); - new Popc(tmp, dst).emit(masm); - break; - case LPOPCNT: - new Ldx(src, tmp).emit(masm); - new Popc(tmp, dst).emit(masm); - break; - case BSF: - assert input.getKind() == Kind.Int; - new Ldsw(src, tmp).emit(masm); - new Srl(tmp, 1, tmp).emit(masm); - new Srl(tmp, 0, dst).emit(masm); - new Or(tmp, tmp, dst).emit(masm); - new Srl(dst, 2, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 4, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 8, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 16, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Popc(dst, dst).emit(masm); - new Mov(Kind.Int.getBitCount(), tmp).emit(masm); - new Sub(tmp, dst, dst).emit(masm); - break; - case IBSR: - // masm.bsrl(dst, src); - // countLeadingZerosI_bsr masm.bsrq(dst, src); - // masm.bsrl(dst, src); - case LBSR: - // masm.bsrq(dst, src); - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); - } + throw GraalInternalError.shouldNotReachHere(); +// SPARCAddress src = (SPARCAddress) tasm.asAddress(input); +// switch (opcode) { +// case IPOPCNT: +// new Ldsw(src, tmp).emit(masm); +// // clear upper word for 64 bit POPC +// new Srl(tmp, g0, dst).emit(masm); +// new Popc(tmp, dst).emit(masm); +// break; +// case LPOPCNT: +// new Ldx(src, tmp).emit(masm); +// new Popc(tmp, dst).emit(masm); +// break; +// case BSF: +// assert input.getKind() == Kind.Int; +// new Ldsw(src, tmp).emit(masm); +// new Srl(tmp, 1, tmp).emit(masm); +// new Srl(tmp, 0, dst).emit(masm); +// new Or(tmp, tmp, dst).emit(masm); +// new Srl(dst, 2, tmp).emit(masm); +// new Or(dst, tmp, dst).emit(masm); +// new Srl(dst, 4, tmp).emit(masm); +// new Or(dst, tmp, dst).emit(masm); +// new Srl(dst, 8, tmp).emit(masm); +// new Or(dst, tmp, dst).emit(masm); +// new Srl(dst, 16, tmp).emit(masm); +// new Or(dst, tmp, dst).emit(masm); +// new Popc(dst, dst).emit(masm); +// new Mov(Kind.Int.getBitCount(), tmp).emit(masm); +// new Sub(tmp, dst, dst).emit(masm); +// break; +// case IBSR: +// // masm.bsrl(dst, src); +// // countLeadingZerosI_bsr masm.bsrq(dst, src); +// // masm.bsrl(dst, src); +// case LBSR: +// // masm.bsrq(dst, src); +// default: +// throw GraalInternalError.shouldNotReachHere("missing: " + opcode); +// } } } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -42,10 +43,12 @@ public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { SPARCMove.move(tasm, masm, result, input); switch (input.getKind()) { - // case Int: - // masm.bswapl(ValueUtil.asIntReg(result)); - // case Long: - // masm.bswapq(ValueUtil.asLongReg(result)); + case Int: + // masm.bswapl(ValueUtil.asIntReg(result)); + case Long: + // masm.bswapq(ValueUtil.asLongReg(result)); + default: + throw GraalInternalError.shouldNotReachHere(); } } } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Mon Aug 05 22:23:00 2013 -0700 @@ -52,9 +52,7 @@ @Override public boolean destroysCallerSavedRegisters() { - // On SPARC we never destroy caller saved registers since they are automatically saved - // in the register window. - return false; + return true; } } @@ -115,9 +113,7 @@ @Override public boolean destroysCallerSavedRegisters() { - // On SPARC we never destroy caller saved registers since they are automatically saved - // in the register window. - return false; + return callTarget.destroysRegisters(); } } @@ -164,6 +160,7 @@ tasm.recordDirectCall(before, after, callTarget, info); tasm.recordExceptionHandlers(after, info); new Nop().emit(masm); // delay slot + masm.ensureUniquePC(); } public static void indirectJmp(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Register dst, InvokeTarget target) { @@ -173,6 +170,7 @@ int after = masm.codeBuffer.position(); tasm.recordIndirectCall(before, after, target, null); new Nop().emit(masm); // delay slot + masm.ensureUniquePC(); } public static void indirectCall(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) { @@ -182,5 +180,6 @@ tasm.recordIndirectCall(before, after, callTarget, info); tasm.recordExceptionHandlers(after, info); new Nop().emit(masm); // delay slot + masm.ensureUniquePC(); } } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Aug 05 22:23:00 2013 -0700 @@ -45,39 +45,48 @@ protected Condition condition; protected LabelRef destination; + protected final Kind kind; - public BranchOp(Condition condition, LabelRef destination) { + public BranchOp(Condition condition, LabelRef destination, Kind kind) { this.condition = condition; this.destination = destination; + this.kind = kind; } @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - // FIXME Using xcc is wrong! It depends on the compare. + assert kind == Kind.Int || kind == Kind.Long || kind == Kind.Object; + CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; switch (condition) { case EQ: - new Bpe(CC.Xcc, destination.label()).emit(masm); + new Bpe(cc, destination.label()).emit(masm); break; case NE: - new Bpne(CC.Xcc, destination.label()).emit(masm); + new Bpne(cc, destination.label()).emit(masm); + break; + case BT: + new Bplu(cc, destination.label()).emit(masm); break; case LT: - new Bpl(CC.Xcc, destination.label()).emit(masm); + new Bpl(cc, destination.label()).emit(masm); break; case BE: - new Bpleu(CC.Xcc, destination.label()).emit(masm); + new Bpleu(cc, destination.label()).emit(masm); break; case LE: - new Bple(CC.Xcc, destination.label()).emit(masm); + new Bple(cc, destination.label()).emit(masm); + break; + case GE: + new Bpge(cc, destination.label()).emit(masm); break; case AE: - new Bpgeu(CC.Xcc, destination.label()).emit(masm); + new Bpgeu(cc, destination.label()).emit(masm); break; case GT: - new Bpg(CC.Xcc, destination.label()).emit(masm); + new Bpg(cc, destination.label()).emit(masm); break; case AT: - new Bpgu(CC.Xcc, destination.label()).emit(masm); + new Bpgu(cc, destination.label()).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -152,8 +161,10 @@ if (isFloat) { if (unorderedIsTrue && !trueOnUnordered(condition)) { // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue); + throw GraalInternalError.unimplemented(); } else if (!unorderedIsTrue && trueOnUnordered(condition)) { // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue); + throw GraalInternalError.unimplemented(); } } } @@ -166,8 +177,9 @@ assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move"; switch (other.getKind()) { case Int: + // XXX CC depends on compare new Movcc(cond, CC.Icc, asRegister(other), asRegister(result)).emit(masm); - throw new InternalError("check instruction"); + break; case Long: default: throw GraalInternalError.shouldNotReachHere(); @@ -259,7 +271,6 @@ } @Override - @SuppressWarnings("unused") public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { if (key.getKind() == Kind.Int) { Register intKey = asIntReg(key); @@ -270,27 +281,26 @@ long lc = keyConstants[i].asLong(); assert NumUtil.isInt(lc); new Cmp(intKey, (int) lc).emit(masm); - Label l = keyTargets[i].label(); - l.addPatchAt(tasm.asm.codeBuffer.position()); - new Bpe(CC.Icc, l).emit(masm); + new Bpe(CC.Icc, keyTargets[i].label()).emit(masm); + new Nop().emit(masm); // delay slot } } else if (key.getKind() == Kind.Long) { Register longKey = asLongReg(key); + Register temp = asLongReg(scratch); for (int i = 0; i < keyConstants.length; i++) { - // masm.setp_eq_s64(tasm.asLongConst(keyConstants[i]), - // longKey); - // masm.at(); - Label l = keyTargets[i].label(); - l.addPatchAt(tasm.asm.codeBuffer.position()); - new Bpe(CC.Xcc, l).emit(masm); + SPARCMove.move(tasm, masm, temp.asValue(Kind.Long), keyConstants[i]); + new Cmp(longKey, temp).emit(masm); + new Bpe(CC.Xcc, keyTargets[i].label()).emit(masm); + new Nop().emit(masm); // delay slot } } else if (key.getKind() == Kind.Object) { - Register intKey = asObjectReg(key); + Register objectKey = asObjectReg(key); Register temp = asObjectReg(scratch); for (int i = 0; i < keyConstants.length; i++) { SPARCMove.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]); - new Cmp(intKey, temp).emit(masm); + new Cmp(objectKey, temp).emit(masm); new Bpe(CC.Ptrcc, keyTargets[i].label()).emit(masm); + new Nop().emit(masm); // delay slot } } else { throw new GraalInternalError("sequential switch only supported for int, long and object"); @@ -298,7 +308,7 @@ if (defaultTarget != null) { masm.jmp(defaultTarget.label()); } else { - // masm.hlt(); + new Illtrap(0).emit(masm); } } @@ -360,7 +370,7 @@ masm.bind(actualDefaultTarget); // masm.hlt(); } - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -444,6 +454,6 @@ tasm.compilationResult.addAnnotation(jt); // SPARC: unimp: tableswitch extract - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Mon Aug 05 22:23:00 2013 -0700 @@ -51,7 +51,7 @@ public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { switch (opcode) { case SQRT: - new Fsqrtd(asDoubleReg(result), asDoubleReg(input)).emit(masm); + new Fsqrtd(asDoubleReg(input), asDoubleReg(result)).emit(masm); break; case LOG: case LOG10: diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 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 Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Mon Aug 05 22:23:00 2013 -0700 @@ -135,7 +135,7 @@ new Ldsh(addr, asRegister(result)).emit(masm); break; case Char: - new Lduw(addr, asRegister(result)).emit(masm); + new Lduh(addr, asRegister(result)).emit(masm); break; case Int: new Ldsw(addr, asRegister(result)).emit(masm); @@ -158,6 +158,27 @@ } } + public static class LoadAddressOp extends SPARCLIRInstruction { + + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue address; + + public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) { + this.result = result; + this.address = address; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + SPARCAddress addr = address.toAddress(); + if (addr.hasIndex()) { + new Add(addr.getBase(), addr.getIndex(), asLongReg(result)).emit(masm); + } else { + new Add(addr.getBase(), addr.getDisplacement(), asLongReg(result)).emit(masm); + } + } + } + public static class MembarOp extends SPARCLIRInstruction { private final int barriers; @@ -183,10 +204,9 @@ } @Override - @SuppressWarnings("unused") public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { tasm.recordImplicitException(masm.codeBuffer.position(), state); - new Ldx(new SPARCAddress(asRegister(input), 0), r0); + new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm); } } @@ -222,7 +242,8 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - new Ldx((SPARCAddress) tasm.asAddress(slot), asLongReg(result)).emit(masm); + SPARCAddress address = (SPARCAddress) tasm.asAddress(slot); + new Add(address.getBase(), address.getDisplacement(), asLongReg(result)).emit(masm); } } @@ -245,6 +266,7 @@ new Stb(asRegister(input), addr).emit(masm); break; case Short: + case Char: new Sth(asRegister(input), addr).emit(masm); break; case Int: @@ -273,7 +295,7 @@ super(kind, address, state); this.input = input; this.compress = compress; - if (input.isNonNull()) { + if (!input.isDefaultForKind()) { throw GraalInternalError.shouldNotReachHere("Can only store null constants to memory"); } } @@ -285,8 +307,8 @@ case Byte: new Stb(g0, address.toAddress()).emit(masm); break; + case Short: case Char: - case Short: new Sth(g0, address.toAddress()).emit(masm); break; case Int: @@ -353,14 +375,15 @@ } private static void reg2stack(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) { - SPARCAddress dest = (SPARCAddress) tasm.asAddress(result); + SPARCAddress dst = (SPARCAddress) tasm.asAddress(result); + Register src = asRegister(input); switch (input.getKind()) { case Int: - new Stw(asRegister(input), dest).emit(masm); + new Stw(src, dst).emit(masm); break; case Long: case Object: - new Stx(asRegister(input), dest).emit(masm); + new Stx(src, dst).emit(masm); break; case Float: case Double: @@ -371,14 +394,17 @@ private static void stack2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) { SPARCAddress src = (SPARCAddress) tasm.asAddress(input); + Register dst = asRegister(result); switch (input.getKind()) { case Int: - new Ldsw(src, asRegister(result)).emit(masm); + new Ldsw(src, dst).emit(masm); break; case Long: + case Object: + new Ldx(src, dst).emit(masm); + break; case Float: case Double: - case Object: default: throw GraalInternalError.shouldNotReachHere(); } @@ -415,14 +441,14 @@ 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); - throw GraalInternalError.shouldNotReachHere(); + tasm.recordDataReferenceInCode(input, 0, true); + new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm); } else { Register dst = asRegister(result); new Rdpc(dst).emit(masm); tasm.asObjectConstRef(input); new Ldx(new SPARCAddress(dst, 0), dst).emit(masm); + throw GraalInternalError.shouldNotReachHere("the patched offset might be too big for the load"); } break; } diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java --- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Mon Aug 05 22:21:47 2013 -0700 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Mon Aug 05 22:23:00 2013 -0700 @@ -143,10 +143,7 @@ // @formatter:on public SPARC() { - // The return address doesn't have an extra slot in the frame so we pass 0 for the return - // address size. - // XXX think about the return address size again - super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + 1, 0); + super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + 1, 8); } @Override diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Mon Aug 05 22:21:47 2013 -0700 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Mon Aug 05 22:23:00 2013 -0700 @@ -31,6 +31,8 @@ inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { if (inst->is_call() || inst->is_jump()) { return pc_offset + NativeCall::instruction_size; + } else if (inst->is_call_reg()) { + return pc_offset + NativeCallReg::instruction_size; } else if (inst->is_sethi()) { return pc_offset + NativeFarCall::instruction_size; } else { @@ -83,23 +85,36 @@ break; } case 'a': { - 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); + if (inlined) { + NativeMovConstReg* move = nativeMovConstReg_at(pc); + Handle obj = Constant::object(constant); + jobject value = JNIHandles::make_local(obj()); + move->set_data((intptr_t) value); + + // We need two relocations: one on the sethi and one on the add. + int oop_index = _oop_recorder->find_index(value); + RelocationHolder rspec = oop_Relocation::spec(oop_index); + _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); + _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); + } else { + 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)); } - 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: diff -r 22d3ee2fcb97 -r 5a9d68c3a7d7 src/cpu/sparc/vm/nativeInst_sparc.hpp --- a/src/cpu/sparc/vm/nativeInst_sparc.hpp Mon Aug 05 22:21:47 2013 -0700 +++ b/src/cpu/sparc/vm/nativeInst_sparc.hpp Mon Aug 05 22:23:00 2013 -0700 @@ -55,6 +55,7 @@ bool is_dtrace_trap(); bool is_nop() { return long_at(0) == nop_instruction(); } bool is_call() { return is_op(long_at(0), Assembler::call_op); } + bool is_call_reg() { return is_op(long_at(0), Assembler::arith_op); } bool is_sethi() { return (is_op2(long_at(0), Assembler::sethi_op2) && inv_rd(long_at(0)) != G0); } @@ -417,6 +418,19 @@ return call; } +class NativeCallReg: public NativeInstruction { + public: + enum Sparc_specific_constants { + instruction_size = 8, + return_address_offset = 8, + instruction_offset = 0 + }; + + address next_instruction_address() const { + return addr_at(instruction_size); + } +}; + // The NativeFarCall is an abstraction for accessing/manipulating native call-anywhere // instructions in the sparcv9 vm. Used to call native methods which may be loaded // anywhere in the address space, possibly out of reach of a call instruction.