Mercurial > hg > graal-compiler
changeset 22693:f04f2d2b2c42
[SPARC] Remove JavaKind dependency from SPARC backend, clearing up SPARCArithmetic
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Wed Sep 23 15:42:58 2015 +0200 @@ -83,7 +83,6 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fabss; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fandd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtoi; @@ -92,9 +91,7 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovd; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovdcc; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovs; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovscc; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd; @@ -140,9 +137,10 @@ import jdk.internal.jvmci.code.RegisterConfig; import jdk.internal.jvmci.code.TargetDescription; import jdk.internal.jvmci.meta.JavaConstant; -import jdk.internal.jvmci.meta.JavaKind; +import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.sparc.SPARC; import jdk.internal.jvmci.sparc.SPARC.CPUFeature; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.Assembler; import com.oracle.graal.asm.Label; @@ -251,60 +249,60 @@ } } + private static final int COMMUTATIVE = 1; + private static final int BINARY = 2; + private static final int UNARY = 4; + private static final int VOID_IN = 8; + public static enum Op3s { // @formatter:off - - Add(0x00, "add", ArithOp), - And(0x01, "and", ArithOp), - Or(0x02, "or", ArithOp), - Xor(0x03, "xor", ArithOp), - Sub(0x04, "sub", ArithOp), - Andn(0x05, "andn", ArithOp), - Orn(0x06, "orn", ArithOp), - Xnor(0x07, "xnor", ArithOp), - Addc(0x08, "addc", ArithOp), - Mulx(0x09, "mulx", ArithOp), - Umul(0x0A, "umul", ArithOp), - Smul(0x0B, "smul", ArithOp), - Subc(0x0C, "subc", ArithOp), - Udivx(0x0D, "udivx", ArithOp), - Udiv(0x0E, "udiv", ArithOp), - Sdiv(0x0F, "sdiv", ArithOp), - - Addcc(0x10, "addcc", ArithOp), - Andcc(0x11, "andcc", ArithOp), - Orcc(0x12, "orcc", ArithOp), - Xorcc(0x13, "xorcc", ArithOp), - Subcc(0x14, "subcc", ArithOp), - Andncc(0x15, "andncc", ArithOp), - Orncc(0x16, "orncc", ArithOp), - Xnorcc(0x17, "xnorcc", ArithOp), - Addccc(0x18, "addccc", ArithOp), - - Umulcc(0x1A, "umulcc", ArithOp), - Smulcc(0x1B, "smulcc", ArithOp), - Subccc(0x1C, "subccc", ArithOp), - Udivcc(0x1E, "udivcc", ArithOp), - Sdivcc(0x1F, "sdivcc", ArithOp), - - Taddcc(0x20, "taddcc", ArithOp), - Tsubcc(0x21, "tsubcc", ArithOp), - Taddcctv(0x22, "taddcctv", ArithOp), - Tsubcctv(0x23, "tsubcctv", ArithOp), - Mulscc(0x24, "mulscc", ArithOp), - Sll(0x25, "sll", ArithOp), - Sllx(0x25, "sllx", ArithOp), - Srl(0x26, "srl", ArithOp), - Srlx(0x26, "srlx", ArithOp), - Sra(0x27, "srax", ArithOp), - Srax(0x27, "srax", ArithOp), + Add(0x00, "add", ArithOp, BINARY | COMMUTATIVE), + And(0x01, "and", ArithOp, BINARY | COMMUTATIVE), + Or(0x02, "or", ArithOp, BINARY | COMMUTATIVE), + Xor(0x03, "xor", ArithOp, BINARY | COMMUTATIVE), + Sub(0x04, "sub", ArithOp, BINARY), + Andn(0x05, "andn", ArithOp, BINARY | COMMUTATIVE), + Orn(0x06, "orn", ArithOp, BINARY | COMMUTATIVE), + Xnor(0x07, "xnor", ArithOp, BINARY | COMMUTATIVE), + Addc(0x08, "addc", ArithOp, BINARY | COMMUTATIVE), + Mulx(0x09, "mulx", ArithOp, BINARY | COMMUTATIVE), + Umul(0x0A, "umul", ArithOp, BINARY | COMMUTATIVE), + Smul(0x0B, "smul", ArithOp, BINARY | COMMUTATIVE), + Subc(0x0C, "subc", ArithOp, BINARY), + Udivx(0x0D, "udivx", ArithOp, BINARY), + Udiv(0x0E, "udiv", ArithOp, BINARY), + Sdiv(0x0F, "sdiv", ArithOp, BINARY), + + Addcc(0x10, "addcc", ArithOp, BINARY | COMMUTATIVE), + Andcc(0x11, "andcc", ArithOp, BINARY | COMMUTATIVE), + Orcc(0x12, "orcc", ArithOp, BINARY | COMMUTATIVE), + Xorcc(0x13, "xorcc", ArithOp, BINARY | COMMUTATIVE), + Subcc(0x14, "subcc", ArithOp, BINARY | COMMUTATIVE), + Andncc(0x15, "andncc", ArithOp, BINARY | COMMUTATIVE), + Orncc(0x16, "orncc", ArithOp, BINARY | COMMUTATIVE), + Xnorcc(0x17, "xnorcc", ArithOp, BINARY | COMMUTATIVE), + Addccc(0x18, "addccc", ArithOp, BINARY | COMMUTATIVE), + + Umulcc(0x1A, "umulcc", ArithOp, BINARY | COMMUTATIVE), + Smulcc(0x1B, "smulcc", ArithOp, BINARY | COMMUTATIVE), + Subccc(0x1C, "subccc", ArithOp, BINARY), + Udivcc(0x1E, "udivcc", ArithOp, BINARY), + Sdivcc(0x1F, "sdivcc", ArithOp, BINARY), + + Mulscc(0x24, "mulscc", ArithOp, BINARY | COMMUTATIVE), + Sll(0x25, "sll", ArithOp, BINARY), + Sllx(0x25, "sllx", ArithOp, BINARY), + Srl(0x26, "srl", ArithOp, BINARY), + Srlx(0x26, "srlx", ArithOp, BINARY), + Sra(0x27, "srax", ArithOp, BINARY), + Srax(0x27, "srax", ArithOp, BINARY), Membar(0x28, "membar", ArithOp), Flushw(0x2B, "flushw", ArithOp), Movcc(0x2C, "movcc", ArithOp), - Sdivx(0x2D, "sdivx", ArithOp), - Popc(0x2E, "popc", ArithOp), - Movr(0x2F, "movr", ArithOp), + Sdivx(0x2D, "sdivx", ArithOp, BINARY), + Popc(0x2E, "popc", ArithOp, UNARY), + Movr(0x2F, "movr", ArithOp, BINARY), Fpop1(0b11_0100, "fpop1", ArithOp), Fpop2(0b11_0101, "fpop2", ArithOp), @@ -369,11 +367,17 @@ private final int value; private final String operator; private final Ops op; + private final int flags; private Op3s(int value, String name, Ops op) { + this(value, name, op, 0); + } + + private Op3s(int value, String name, Ops op, int flags) { this.value = value; this.operator = name; this.op = op; + this.flags = flags; } public int getValue() { @@ -400,82 +404,91 @@ return false; } } + + public boolean isBinary() { + return (flags & BINARY) != 0; + } + + public boolean isUnary() { + return (flags & UNARY) != 0; + } + + public boolean isCommutative() { + return (flags & COMMUTATIVE) != 0; + } } public static enum Opfs { // @formatter:off - Fmovs(0b0_0000_0001, "fmovs", Fpop1), - Fmovd(0b0_0000_0010, "fmovd", Fpop1), - Fmovq(0b0_0000_0011, "fmovq", Fpop1), - Fmovscc(0b00_0001, "fmovscc", Fpop2), - Fmovdcc(0b00_0010, "fmovdcc", Fpop2), - Fnegs(0x05, "fnegs", Fpop1), - Fnegd(0x06, "fnegd", Fpop1), - Fnegq(0x07, "fnegq", Fpop1), - Fabss(0x09, "fabss", Fpop1), - Fabsd(0x0A, "fabsd", Fpop1), - Fabsq(0x0B, "fabsq", Fpop1), + Fmovs(0b0_0000_0001, "fmovs", Fpop1, UNARY), + Fmovd(0b0_0000_0010, "fmovd", Fpop1, UNARY), + Fmovq(0b0_0000_0011, "fmovq", Fpop1, UNARY), + Fnegs(0x05, "fnegs", Fpop1, UNARY), + Fnegd(0x06, "fnegd", Fpop1, UNARY), + Fnegq(0x07, "fnegq", Fpop1, UNARY), + Fabss(0x09, "fabss", Fpop1, UNARY), + Fabsd(0x0A, "fabsd", Fpop1, UNARY), + Fabsq(0x0B, "fabsq", Fpop1, UNARY), // start VIS1 - Fpadd32(0x52, "fpadd32", Impdep1), - Fzerod(0x60, "fzerod", Impdep1), - Fzeros(0x61, "fzeros", Impdep1), - Fnot2d(0x66, "fnot1d", Impdep1), - Fsrc2d(0x78, "fsrc2d", Impdep1), - Fsrc2s(0x79, "fsrc2s", Impdep1), - Fandd(0b0_0111_0000, "fandd", Impdep1), - Fands(0b0_0111_0001, "fands", Impdep1), + Fpadd32(0x52, "fpadd32", Impdep1, BINARY | COMMUTATIVE), + Fzerod(0x60, "fzerod", Impdep1, VOID_IN), + Fzeros(0x61, "fzeros", Impdep1, VOID_IN), + Fsrc2d(0x78, "fsrc2d", Impdep1, UNARY), + Fsrc2s(0x79, "fsrc2s", Impdep1, UNARY), // end VIS1 // start VIS3 - Movdtox(0x110, "movdtox", Impdep1), - Movstouw(0x111, "movstouw", Impdep1), - Movstosw(0x113, "movstosw", Impdep1), - Movxtod(0x118, "movxtod", Impdep1), - Movwtos(0b1_0001_1001, "movwtos", Impdep1), - UMulxhi(0b0_0001_0110, "umulxhi", Impdep1), + Movdtox(0x110, "movdtox", Impdep1, UNARY), + Movstouw(0x111, "movstouw", Impdep1, UNARY), + Movstosw(0x113, "movstosw", Impdep1, UNARY), + Movxtod(0x118, "movxtod", Impdep1, UNARY), + Movwtos(0b1_0001_1001, "movwtos", Impdep1, UNARY), + UMulxhi(0b0_0001_0110, "umulxhi", Impdep1, BINARY | COMMUTATIVE), // end VIS3 - Fadds(0x41, "fadds", Fpop1), - Faddd(0x42, "faddd", Fpop1), - Fsubs(0x45, "fsubs", Fpop1), - Fsubd(0x46, "fsubd", Fpop1), - Fmuls(0x49, "fmuls", Fpop1), - Fmuld(0x4A, "fmuld", Fpop1), - Fdivs(0x4D, "fdivs", Fpop1), - Fdivd(0x4E, "fdivd", Fpop1), - - Fsqrts(0x29, "fsqrts", Fpop1), - Fsqrtd(0x2A, "fsqrtd", Fpop1), - - Fsmuld(0x69, "fsmuld", Fpop1), - - Fstoi(0xD1, "fstoi", Fpop1), - Fdtoi(0xD2, "fdtoi", Fpop1), - Fstox(0x81, "fstox", Fpop1), - Fdtox(0x82, "fdtox", Fpop1), - Fxtos(0x84, "fxtos", Fpop1), - Fxtod(0x88, "fxtod", Fpop1), - Fitos(0xC4, "fitos", Fpop1), - Fdtos(0xC6, "fdtos", Fpop1), - Fitod(0xC8, "fitod", Fpop1), - Fstod(0xC9, "fstod", Fpop1), - - - Fcmps(0x51, "fcmps", Fpop2), - Fcmpd(0x52, "fcmpd", Fpop2); + Fadds(0x41, "fadds", Fpop1, BINARY | COMMUTATIVE), + Faddd(0x42, "faddd", Fpop1, BINARY | COMMUTATIVE), + Fsubs(0x45, "fsubs", Fpop1, BINARY), + Fsubd(0x46, "fsubd", Fpop1, BINARY), + Fmuls(0x49, "fmuls", Fpop1, BINARY | COMMUTATIVE), + Fmuld(0x4A, "fmuld", Fpop1, BINARY | COMMUTATIVE), + Fdivs(0x4D, "fdivs", Fpop1, BINARY), + Fdivd(0x4E, "fdivd", Fpop1, BINARY), + + Fsqrts(0x29, "fsqrts", Fpop1, UNARY), + Fsqrtd(0x2A, "fsqrtd", Fpop1, UNARY), + + Fsmuld(0x69, "fsmuld", Fpop1, BINARY | COMMUTATIVE), + + Fstoi(0xD1, "fstoi", Fpop1, UNARY), + Fdtoi(0xD2, "fdtoi", Fpop1, UNARY), + Fstox(0x81, "fstox", Fpop1, UNARY), + Fdtox(0x82, "fdtox", Fpop1, UNARY), + Fxtos(0x84, "fxtos", Fpop1, UNARY), + Fxtod(0x88, "fxtod", Fpop1, UNARY), + Fitos(0xC4, "fitos", Fpop1, UNARY), + Fdtos(0xC6, "fdtos", Fpop1, UNARY), + Fitod(0xC8, "fitod", Fpop1, UNARY), + Fstod(0xC9, "fstod", Fpop1, UNARY), + + + Fcmps(0x51, "fcmps", Fpop2, BINARY), + Fcmpd(0x52, "fcmpd", Fpop2, BINARY); // @formatter:on private final int value; private final String operator; private final Op3s op3; - - private Opfs(int value, String op, Op3s op3) { + private final int flags; + + private Opfs(int value, String op, Op3s op3, int flags) { this.value = value; this.operator = op; this.op3 = op3; + this.flags = flags; } public int getValue() { @@ -485,6 +498,38 @@ public String getOperator() { return operator; } + + public boolean isBinary() { + return (flags & BINARY) != 0; + } + + public boolean isUnary() { + return (flags & UNARY) != 0; + } + + public boolean isCommutative() { + return (flags & COMMUTATIVE) != 0; + } + } + + public static enum OpfLow { + Fmovscc(0b00_0001, "fmovscc", Fpop2), + Fmovdcc(0b00_0010, "fmovdcc", Fpop2); + + private final int value; + private final String operator; + private final Op3s op3; + + private OpfLow(int value, String op, Op3s op3) { + this.value = value; + this.operator = op; + this.op3 = op3; + } + + @Override + public String toString() { + return operator; + } } public enum Annul { @@ -575,19 +620,15 @@ return operator; } - public static CC forKind(JavaKind kind) { - boolean isInt = kind == JavaKind.Boolean || kind == JavaKind.Byte || kind == JavaKind.Char || kind == JavaKind.Short || kind == JavaKind.Int; - boolean isFloat = kind == JavaKind.Float || kind == JavaKind.Double; - boolean isLong = kind == JavaKind.Long || kind == JavaKind.Object; - assert isInt || isFloat || isLong; - if (isLong) { + public static CC forKind(PlatformKind kind) { + if (kind.equals(SPARCKind.DWORD)) { return Xcc; - } else if (isInt) { + } else if (kind.equals(SPARCKind.WORD)) { return Icc; - } else if (isFloat) { + } else if (kind.equals(SPARCKind.SINGLE) || kind.equals(SPARCKind.DOUBLE)) { return Fcc0; } else { - throw new InternalError(); + throw new IllegalArgumentException("Unknown kind: " + kind); } } } @@ -829,10 +870,15 @@ private static final BitSpec op2 = new ContinousBitSpec(24, 22, "op2"); private static final BitSpec op3 = new ContinousBitSpec(24, 19, "op3"); private static final BitSpec opf = new ContinousBitSpec(13, 5, "opf"); + private static final BitSpec opfLow = new ContinousBitSpec(10, 5, "opfLow"); + private static final BitSpec opfCC = new ContinousBitSpec(13, 11, "opfCC"); + private static final BitSpec opfCond = new ContinousBitSpec(17, 14, "opfCond"); private static final BitSpec rd = new ContinousBitSpec(29, 25, "rd"); private static final BitSpec rs1 = new ContinousBitSpec(18, 14, "rs1"); private static final BitSpec rs2 = new ContinousBitSpec(4, 0, "rs2"); private static final BitSpec simm13 = new ContinousBitSpec(12, 0, true, "simm13"); + private static final BitSpec shcnt32 = new ContinousBitSpec(4, 0, "shcnt32"); + private static final BitSpec shcnt64 = new ContinousBitSpec(5, 0, "shcnt64"); private static final BitSpec imm22 = new ContinousBitSpec(21, 0, "imm22"); private static final BitSpec immAsi = new ContinousBitSpec(12, 5, "immASI"); private static final BitSpec i = new ContinousBitSpec(13, 13, "i"); @@ -841,6 +887,7 @@ private static final BitSpec disp30 = new ContinousBitSpec(29, 0, true, "disp30"); private static final BitSpec a = new ContinousBitSpec(29, 29, "a"); private static final BitSpec p = new ContinousBitSpec(19, 19, "p"); + private static final BitSpec x = new ContinousBitSpec(12, 12, "x"); private static final BitSpec cond = new ContinousBitSpec(28, 25, "cond"); private static final BitSpec rcond = new ContinousBitSpec(27, 25, "rcond"); private static final BitSpec cc = new ContinousBitSpec(21, 20, "cc"); @@ -848,6 +895,12 @@ private static final BitSpec d16hi = new ContinousBitSpec(21, 20, "d16hi"); private static final BitSpec d16lo = new ContinousBitSpec(13, 0, "d16lo"); private static final BitSpec d16 = new CompositeBitSpec(d16hi, d16lo); + // Movcc + private static final BitSpec movccLo = new ContinousBitSpec(12, 11, "cc_lo"); + private static final BitSpec movccHi = new ContinousBitSpec(18, 18, "cc_hi"); + private static final BitSpec movccCond = new ContinousBitSpec(17, 14, "cond"); + private static final BitSpec simm11 = new ContinousBitSpec(10, 0, true, "simm11"); + // CBCond private static final BitSpec cLo = new ContinousBitSpec(27, 25, "cLo"); private static final BitSpec cHi = new ContinousBitSpec(29, 29, "cHi"); @@ -868,7 +921,7 @@ public abstract boolean valueFits(int value); } - public static class ContinousBitSpec extends BitSpec { + public static final class ContinousBitSpec extends BitSpec { private final int hiBit; private final int lowBit; private final int width; @@ -925,7 +978,7 @@ } } - public static class CompositeBitSpec extends BitSpec { + public static final class CompositeBitSpec extends BitSpec { private final BitSpec left; private final int leftWidth; private final BitSpec right; @@ -996,7 +1049,7 @@ /** * Represents a prefix tree of {@link BitSpec} objects to find the most accurate SPARCOp. */ - public static class BitKeyIndex { + public static final class BitKeyIndex { private final BitSpec spec; private final Map<Integer, BitKeyIndex> nodes; private SPARCOp op; @@ -1083,6 +1136,9 @@ public static final Bpr BPR = new Bpr(); public static final Br BR = new Br(); public static final Sethi SETHI = new Sethi(); + public static final FMOVcc FMOVSCC = new FMOVcc(OpfLow.Fmovscc); + public static final FMOVcc FMOVDCC = new FMOVcc(OpfLow.Fmovdcc); + public static final MOVicc MOVicc = new MOVicc(); public static final OpfOp OPF = new OpfOp(); public static final Op3Op OP3 = new Op3Op(); public static final SPARCOp LDST = new SPARCOp(Ops.LdstOp); @@ -1216,7 +1272,7 @@ public abstract boolean isConditional(int inst); } - public static class Bpcc extends ControlTransferOp { + public static final class Bpcc extends ControlTransferOp { public Bpcc(Op2s op2) { super(Ops.BranchOp, op2, true, BitSpec.disp19); } @@ -1242,7 +1298,7 @@ } } - public static class Br extends ControlTransferOp { + public static final class Br extends ControlTransferOp { public Br() { super(Ops.BranchOp, Op2s.Br, true, BitSpec.disp22); } @@ -1259,7 +1315,7 @@ } } - public static class Bpr extends ControlTransferOp { + public static final class Bpr extends ControlTransferOp { private static final BitKey CBCOND_KEY = new BitKey(BitSpec.cbcond, 0); public Bpr() { @@ -1371,26 +1427,26 @@ } } - public static class Sethi extends Op2Op { + public static final class Sethi extends Op2Op { public Sethi() { super(Ops.BranchOp, Op2s.Sethi); } - public Register getRS1(int word) { + public static Register getRS1(int word) { int regNum = BitSpec.rs1.getBits(word); return SPARC.cpuRegisters[regNum]; } - public int getImm22(int word) { + public static int getImm22(int word) { return BitSpec.imm22.getBits(word); } - public boolean isNop(int inst) { + public static boolean isNop(int inst) { return getRS1(inst).equals(g0) && getImm22(inst) == 0; } } - public static class Op3Op extends SPARCOp { + public static final class Op3Op extends SPARCOp { public Op3Op() { super(ArithOp); } @@ -1400,42 +1456,157 @@ return OP3S[ArithOp.value & 1][BitSpec.op3.getBits(inst)]; } - public void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, Register rs2, Register rd) { + public static void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, Register rs2, Register rd) { int instruction = setBits(0, opcode, rs1, rd); instruction = BitSpec.rs2.setBits(instruction, rs2.encoding); instruction = BitSpec.i.setBits(instruction, 0); masm.emitInt(instruction); } - public void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, int simm13, Register rd) { + public static void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, int simm13, Register rd) { int instruction = setBits(0, opcode, rs1, rd); instruction = BitSpec.i.setBits(instruction, 1); - instruction = BitSpec.simm13.setBits(instruction, simm13); + BitSpec immediateSpec; + switch (opcode) { + case Sllx: + case Srlx: + case Srax: + immediateSpec = BitSpec.shcnt64; + break; + case Sll: + case Srl: + case Sra: + immediateSpec = BitSpec.shcnt32; + break; + default: + immediateSpec = BitSpec.simm13; + break; + } + instruction = immediateSpec.setBits(instruction, simm13); masm.emitInt(instruction); } private static int setBits(int instruction, Op3s op3, Register rs1, Register rd) { assert op3.op.equals(ArithOp); int tmp = BitSpec.op3.setBits(instruction, op3.value); + switch (op3) { + case Sllx: + case Srlx: + case Srax: + tmp = BitSpec.x.setBits(tmp, 1); + break; + } tmp = BitSpec.op.setBits(tmp, op3.op.value); tmp = BitSpec.rd.setBits(tmp, rd.encoding); return BitSpec.rs1.setBits(tmp, rs1.encoding); } } - public static class OpfOp extends SPARCOp { - public OpfOp() { + /** + * Used for interfacing FP and GP conditional move instructions. + */ + public interface CMOV { + void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd); + + void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd); + } + + public static final class MOVicc extends SPARCOp implements CMOV { + private static final Op3s op3 = Movcc; + + public MOVicc() { super(ArithOp); } - public void emit(SPARCMacroAssembler masm, Opfs opf, Register rs1, Register rs2, Register rd) { + public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd) { + int inst = setBits(0, condition, cc, rd); + inst = BitSpec.rs2.setBits(inst, rs2.encoding()); + masm.emitInt(inst); + } + + public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd) { + int inst = setBits(0, condition, cc, rd); + inst = BitSpec.i.setBits(inst, 1); + inst = BitSpec.simm11.setBits(inst, simm11); + masm.emitInt(inst); + } + + protected int setBits(int word, ConditionFlag condition, CC cc, Register rd) { + int inst = super.setBits(word); + inst = BitSpec.rd.setBits(inst, rd.encoding()); + inst = BitSpec.op3.setBits(inst, op3.value); + inst = BitSpec.movccCond.setBits(inst, condition.value); + inst = BitSpec.movccLo.setBits(inst, cc.value); + return BitSpec.movccHi.setBits(inst, cc.isFloat ? 0 : 1); + } + + @Override + protected List<BitKey[]> getKeys() { + List<BitKey[]> keys = super.getKeys(); + keys.add(new BitKey[]{new BitKey(BitSpec.op3, op3.value)}); + return keys; + } + } + + public static final class FMOVcc extends SPARCOp implements CMOV { + private OpfLow opfLow; + + public FMOVcc(OpfLow opfLow) { + super(ArithOp); + this.opfLow = opfLow; + } + + public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd) { + int inst = setBits(0); + inst = BitSpec.rd.setBits(inst, rd.encoding()); + inst = BitSpec.op3.setBits(inst, opfLow.op3.value); + inst = BitSpec.opfCond.setBits(inst, condition.value); + inst = BitSpec.opfCC.setBits(inst, cc.value); + inst = BitSpec.opfLow.setBits(inst, opfLow.value); + inst = BitSpec.rs2.setBits(inst, rs2.encoding()); + masm.emitInt(inst); + } + + public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd) { + throw new IllegalArgumentException("FMOVCC cannot be used with immediate value"); + } + + @Override + protected List<BitKey[]> getKeys() { + List<BitKey[]> keys = super.getKeys(); + keys.add(new BitKey[]{new BitKey(BitSpec.op3, opfLow.op3.value)}); + keys.add(new BitKey[]{new BitKey(BitSpec.opfLow, opfLow.value)}); + return keys; + } + } + + public static final class OpfOp extends SPARCOp { + + private BitKey[] op3Keys; + + public OpfOp(BitKey... op3Keys) { + super(ArithOp); + this.op3Keys = op3Keys; + } + + public OpfOp() { + // @formatter:off + this(new BitKey[]{ + new BitKey(BitSpec.op3, Op3s.Fpop1.value), + new BitKey(BitSpec.op3, Op3s.Fpop2.value), + new BitKey(BitSpec.op3, Op3s.Impdep1.value), + new BitKey(BitSpec.op3, Op3s.Impdep2.value)}); + // @formatter:on + } + + public static void emit(SPARCMacroAssembler masm, Opfs opf, Register rs1, Register rs2, Register rd) { int instruction = setBits(0, opf, rs1, rs2); instruction = BitSpec.rd.setBits(instruction, rd.encoding); instruction = BitSpec.i.setBits(instruction, 0); masm.emitInt(instruction); } - public void emitFcmp(SPARCMacroAssembler masm, Opfs opf, CC cc, Register rs1, Register rs2) { + public static void emitFcmp(SPARCMacroAssembler masm, Opfs opf, CC cc, Register rs1, Register rs2) { assert opf.equals(Opfs.Fcmpd) || opf.equals(Opfs.Fcmps) : opf; int instruction = setBits(0, opf, rs1, rs2); instruction = BitSpec.fcc.setBits(instruction, cc.value); @@ -1453,12 +1624,7 @@ @Override protected List<BitKey[]> getKeys() { List<BitKey[]> keys = super.getKeys(); - // @formatter:off - keys.add(new BitKey[]{ - new BitKey(BitSpec.op3, Op3s.Fpop1.value), - new BitKey(BitSpec.op3, Op3s.Fpop2.value), - new BitKey(BitSpec.op3, Op3s.Impdep1.value), - new BitKey(BitSpec.op3, Op3s.Impdep2.value)}); + keys.add(op3Keys); // @formatter:on return keys; } @@ -2072,11 +2238,11 @@ } public void fmovdcc(ConditionFlag cond, CC cc, Register rs2, Register rd) { - fmovcc(cond, cc, rs2, rd, Fmovdcc.value); + fmovcc(cond, cc, rs2, rd, OpfLow.Fmovdcc.value); } public void fmovscc(ConditionFlag cond, CC cc, Register rs2, Register rd) { - fmovcc(cond, cc, rs2, rd, Fmovscc.value); + fmovcc(cond, cc, rs2, rd, OpfLow.Fmovscc.value); } private void fmovcc(ConditionFlag cond, CC cc, Register rs2, Register rd, int opfLow) { @@ -2228,10 +2394,6 @@ op3(Srlx, rs1, shcnt64, rd); } - public void fandd(Register rs1, Register rs2, Register rd) { - op3(Impdep1, Fandd, rs1, rs2, rd); - } - public void sub(Register rs1, Register rs2, Register rd) { op3(Sub, rs1, rs2, rd); } @@ -2545,7 +2707,7 @@ int delaySlotAbsolute = i + INSTRUCTION_SIZE; int nextInst = getInt(delaySlotAbsolute); SPARCOp nextOp = getSPARCOp(nextInst); - if (nextOp instanceof Sethi && ((Sethi) nextOp).isNop(nextInst)) { + if (nextOp instanceof Sethi && Sethi.isNop(nextInst)) { int inst = getInt(i); SPARCOp op = getSPARCOp(inst); if (op instanceof ControlTransferOp && ((ControlTransferOp) op).hasDelaySlot() && ((ControlTransferOp) op).isAnnulable(inst)) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Sep 23 15:42:58 2015 +0200 @@ -23,86 +23,53 @@ package com.oracle.graal.compiler.sparc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.FMOVDCC; +import static com.oracle.graal.asm.sparc.SPARCAssembler.FMOVSCC; +import static com.oracle.graal.asm.sparc.SPARCAssembler.MOVicc; import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.Fcc0; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Add; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Addcc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.And; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Mulx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sdivx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sllx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sra; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srax; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sub; import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Subcc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Udivx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Xnor; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmpd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmps; -import static com.oracle.graal.lir.LIRValueUtil.asConstantValue; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtos; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fstod; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fxtod; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.UMulxhi; import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant; import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.B2I; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.B2L; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.D2F; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.D2I; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.D2L; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.DADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.DDIV; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.DMUL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.DNEG; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.DSUB; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.F2D; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.F2I; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.F2L; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.FADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.FDIV; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.FMUL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.FNEG; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.FSUB; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.I2D; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.I2F; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.I2L; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IADDCC; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IAND; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IDIV; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IMUL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IMULCC; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.INEG; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.INOT; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IOR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IREM; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISHL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISHR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISUB; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISUBCC; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IUMUL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IUREM; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IUSHR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IXOR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.L2D; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.L2F; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.L2I; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LADDCC; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LAND; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LDIV; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LMUL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LNEG; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LNOT; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LOR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LREM; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSHL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSHR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSUB; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSUBCC; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUDIV; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUMUL; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUREM; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUSHR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LXOR; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.S2I; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.S2L; import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.BSF; import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IBSR; -import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IPOPCNT; import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LBSR; -import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LPOPCNT; -import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.ABS; -import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.SQRT; +import static jdk.internal.jvmci.code.CodeUtil.mask; import static jdk.internal.jvmci.code.ValueUtil.isStackSlotValue; -import static jdk.internal.jvmci.meta.JavaKind.Char; +import static jdk.internal.jvmci.meta.JavaConstant.forLong; +import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import jdk.internal.jvmci.code.CallingConvention; -import jdk.internal.jvmci.code.CodeUtil; import jdk.internal.jvmci.code.StackSlotValue; import jdk.internal.jvmci.common.JVMCIError; import jdk.internal.jvmci.meta.AllocatableValue; @@ -114,9 +81,11 @@ import jdk.internal.jvmci.meta.Value; import jdk.internal.jvmci.sparc.SPARC; import jdk.internal.jvmci.sparc.SPARC.CPUFeature; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.sparc.SPARCAssembler; import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.CMOV; import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s; import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs; @@ -138,12 +107,13 @@ import com.oracle.graal.lir.gen.SpillMoveFactoryBase; import com.oracle.graal.lir.sparc.SPARCAddressValue; import com.oracle.graal.lir.sparc.SPARCArithmetic; -import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; -import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegReg; import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp.MulHigh; import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp.Rem; +import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp; import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op; +import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp; import com.oracle.graal.lir.sparc.SPARCArrayEqualsOp; import com.oracle.graal.lir.sparc.SPARCBitManipulationOp; import com.oracle.graal.lir.sparc.SPARCByteSwapOp; @@ -158,7 +128,6 @@ import com.oracle.graal.lir.sparc.SPARCImmediateAddressValue; import com.oracle.graal.lir.sparc.SPARCJumpOp; import com.oracle.graal.lir.sparc.SPARCLoadConstantTableBaseOp; -import com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp; import com.oracle.graal.lir.sparc.SPARCMove; import com.oracle.graal.lir.sparc.SPARCMove.LoadAddressOp; import com.oracle.graal.lir.sparc.SPARCMove.LoadDataAddressOp; @@ -169,6 +138,7 @@ import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; import com.oracle.graal.lir.sparc.SPARCOP3Op; +import com.oracle.graal.lir.sparc.SPARCOPFOp; import com.oracle.graal.phases.util.Providers; /** @@ -258,6 +228,22 @@ } } + /** + * The SPARC backend only uses WORD and DWORD values in registers because except to the ld/st + * instructions no instruction deals either with 32 or 64 bits. This function converts small + * integer kinds to WORD. + */ + @Override + public LIRKind toRegisterKind(LIRKind kind) { + switch ((SPARCKind) kind.getPlatformKind()) { + case BYTE: + case HWORD: + return kind.changeType(SPARCKind.WORD); + default: + return kind; + } + } + protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) { return new SPARCMove.Move(result, input); } @@ -329,25 +315,25 @@ right = loadNonConst(y); actualCondition = cond; } - JavaKind actualCmpKind = (JavaKind) cmpKind; - if (actualCmpKind.isNumericInteger()) { + SPARCKind actualCmpKind = (SPARCKind) cmpKind; + if (actualCmpKind.isInteger()) { actualCmpKind = toSPARCCmpKind(actualCmpKind); append(new SPARCControlFlow.CompareBranchOp(canonicalizeForCompare(left, cmpKind, actualCmpKind), canonicalizeForCompare(right, cmpKind, actualCmpKind), actualCondition, trueDestination, falseDestination, actualCmpKind, unorderedIsTrue, trueDestinationProbability)); - } else if (actualCmpKind.isNumericFloat()) { - emitFloatCompare(cmpKind, x, y, Fcc0); - ConditionFlag cf = SPARCControlFlow.fromCondition(Fcc0, cond, unorderedIsTrue); + } else if (actualCmpKind.isFloat()) { + emitFloatCompare(actualCmpKind, x, y, Fcc0); + ConditionFlag cf = SPARCControlFlow.fromCondition(false, cond, unorderedIsTrue); append(new SPARCControlFlow.BranchOp(cf, trueDestination, falseDestination, actualCmpKind, trueDestinationProbability)); + } else { + throw JVMCIError.shouldNotReachHere(); } } - private static JavaKind toSPARCCmpKind(JavaKind actualCmpKind) { - // TODO: Change to PlatformKind - assert actualCmpKind.isNumericInteger(); - if (actualCmpKind.getByteCount() <= 4) { - return JavaKind.Int; + private static SPARCKind toSPARCCmpKind(SPARCKind actualCmpKind) { + if (actualCmpKind.isInteger() && actualCmpKind.getSizeInBytes() <= 4) { + return SPARCKind.WORD; } else { - return JavaKind.Long; + return actualCmpKind; } } @@ -359,7 +345,7 @@ int fromBytes = from.getSizeInBytes() * 8; int toBytes = to.getSizeInBytes() * 8; assert from.getSizeInBytes() <= v.getPlatformKind().getSizeInBytes(); - if (from == to && !v.getPlatformKind().equals(JavaKind.Char)) { + if (from == to) { return v; } else { return emitSignExtend(v, fromBytes, toBytes); @@ -369,22 +355,22 @@ @Override public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { - JavaKind cmpKind = (JavaKind) cmpLIRKind.getPlatformKind(); + SPARCKind cmpKind = (SPARCKind) cmpLIRKind.getPlatformKind(); append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind, overflowProbability)); } @Override public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) { emitIntegerTest(left, right); - append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, ((JavaKind) left.getPlatformKind()).getStackKind(), trueDestinationProbability)); + append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, (SPARCKind) left.getPlatformKind(), trueDestinationProbability)); } private void emitIntegerTest(Value a, Value b) { - assert ((JavaKind) a.getPlatformKind()).isNumericInteger(); + assert ((SPARCKind) a.getPlatformKind()).isInteger(); if (LIRValueUtil.isVariable(b)) { - append(new SPARCOP3Op(Op3s.Andcc, load(b), loadNonConst(a))); + append(SPARCOP3Op.newBinaryVoid(Op3s.Andcc, load(b), loadNonConst(a))); } else { - append(new SPARCOP3Op(Op3s.Andcc, load(a), loadNonConst(b))); + append(SPARCOP3Op.newBinaryVoid(Op3s.Andcc, load(a), loadNonConst(b))); } } @@ -400,38 +386,30 @@ @Override public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { - boolean mirrored = emitCompare(cmpKind, left, right); - CC conditionFlags; + // Emit compare + SPARCKind cmpSPARCKind = (SPARCKind) cmpKind; + boolean mirrored = emitCompare(cmpSPARCKind, left, right); + + // Emit move Value actualTrueValue = trueValue; Value actualFalseValue = falseValue; - // TODO: (sa) Review this loadSimm11 if it is really necessary - switch ((JavaKind) left.getLIRKind().getPlatformKind()) { - case Byte: - case Short: - case Char: - case Int: - conditionFlags = CC.Icc; - actualTrueValue = loadSimm11(trueValue); - actualFalseValue = loadSimm11(falseValue); - break; - case Object: - case Long: - conditionFlags = CC.Xcc; - actualTrueValue = loadSimm11(trueValue); - actualFalseValue = loadSimm11(falseValue); - break; - case Float: - case Double: - conditionFlags = CC.Fcc0; - actualTrueValue = load(trueValue); // Floats cannot be immediate at all - actualFalseValue = load(falseValue); - break; - default: - throw JVMCIError.shouldNotReachHere(); + SPARCKind valueKind = (SPARCKind) trueValue.getPlatformKind(); + CMOV cmove; + if (valueKind.isFloat()) { + actualTrueValue = load(trueValue); // Floats cannot be immediate at all + actualFalseValue = load(falseValue); + cmove = valueKind.equals(SINGLE) ? FMOVSCC : FMOVDCC; + } else if (valueKind.isInteger()) { + actualTrueValue = loadSimm11(trueValue); + actualFalseValue = loadSimm11(falseValue); + cmove = MOVicc; + } else { + throw JVMCIError.shouldNotReachHere(); } Variable result = newVariable(trueValue.getLIRKind()); - ConditionFlag finalCondition = SPARCControlFlow.fromCondition(conditionFlags, mirrored ? cond.mirror() : cond, unorderedIsTrue); - append(new CondMoveOp(result, conditionFlags, finalCondition, actualTrueValue, actualFalseValue)); + ConditionFlag finalCondition = SPARCControlFlow.fromCondition(cmpSPARCKind.isInteger(), mirrored ? cond.mirror() : cond, unorderedIsTrue); + CC cc = CC.forKind(toSPARCCmpKind(cmpSPARCKind)); + append(new CondMoveOp(cmove, cc, finalCondition, actualTrueValue, actualFalseValue, result)); return result; } @@ -444,22 +422,22 @@ * @param b the right operand of the comparison * @return true if the left and right operands were switched, false otherwise */ - protected boolean emitCompare(PlatformKind cmpKind, Value a, Value b) { + protected boolean emitCompare(SPARCKind cmpKind, Value a, Value b) { boolean mirrored; - JavaKind cmpJavaKind = (JavaKind) cmpKind; - if (cmpJavaKind.isNumericInteger()) { // Integer case - mirrored = emitIntegerCompare(cmpJavaKind, a, b); - } else if (cmpJavaKind.isNumericFloat()) { // Float case + if (cmpKind.isInteger()) { // Integer case + mirrored = emitIntegerCompare(cmpKind, a, b); + } else if (cmpKind.isFloat()) { // Float case mirrored = false; // No mirroring done on floats - emitFloatCompare(cmpJavaKind, a, b, Fcc0); + emitFloatCompare(cmpKind, a, b, Fcc0); } else { throw JVMCIError.shouldNotReachHere(); } return mirrored; } - private boolean emitIntegerCompare(JavaKind cmpJavaKind, Value a, Value b) { + private boolean emitIntegerCompare(SPARCKind cmpKind, Value a, Value b) { boolean mirrored; + assert cmpKind.isInteger(); Value left; Value right; if (LIRValueUtil.isVariable(b)) { @@ -471,28 +449,26 @@ right = loadNonConst(b); mirrored = false; } - int compareBits = cmpJavaKind.getBitCount(); + int compareBytes = cmpKind.getSizeInBytes(); // SPARC compares 32 or 64 bits - if (compareBits < JavaKind.Int.getBitCount()) { - if (cmpJavaKind.equals(Char)) { // Char needs zero extend - left = emitZeroExtend(left, compareBits, 32); - right = emitZeroExtend(right, compareBits, 32); - } else { - left = emitSignExtend(left, compareBits, 32); - right = emitSignExtend(right, compareBits, 32); - } + if (compareBytes < left.getPlatformKind().getSizeInBytes()) { + left = emitSignExtend(left, compareBytes * 8, DWORD.getSizeInBytes() * 8); } - append(new SPARCOP3Op(Subcc, left, right)); + if (compareBytes < right.getPlatformKind().getSizeInBytes()) { + right = emitSignExtend(right, compareBytes * 8, DWORD.getSizeInBytes() * 8); + } + append(SPARCOP3Op.newBinaryVoid(Subcc, left, right)); return mirrored; } - private void emitFloatCompare(PlatformKind cmpJavaKind, Value a, Value b, CC cc) { + private void emitFloatCompare(SPARCKind cmpJavaKind, Value a, Value b, CC cc) { Opfs floatCompareOpcode; - switch ((JavaKind) cmpJavaKind) { - case Double: + assert cmpJavaKind.isFloat(); + switch (cmpJavaKind) { + case DOUBLE: floatCompareOpcode = Fcmpd; break; - case Float: + case SINGLE: floatCompareOpcode = Fcmps; break; default: @@ -505,25 +481,9 @@ public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { emitIntegerTest(left, right); Variable result = newVariable(trueValue.getLIRKind()); - JavaKind kind = ((JavaKind) left.getPlatformKind()).getStackKind(); - CC conditionCode; - switch (kind) { - case Object: - case Long: - conditionCode = CC.Xcc; - break; - case Int: - case Short: - case Char: - case Byte: - conditionCode = CC.Icc; - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - ConditionFlag flag = SPARCControlFlow.fromCondition(conditionCode, Condition.EQ, false); - // TODO: (sa) Review this loadSimm11 if it is really necessary - append(new CondMoveOp(result, conditionCode, flag, loadSimm11(trueValue), loadSimm11(falseValue))); + ConditionFlag flag = SPARCControlFlow.fromCondition(true, Condition.EQ, false); + CC cc = CC.forKind(left.getPlatformKind()); + append(new CondMoveOp(MOVicc, cc, flag, loadSimm11(trueValue), loadSimm11(falseValue), result)); return result; } @@ -565,26 +525,27 @@ @Override public Variable emitBitCount(Value operand) { - Variable result = newVariable(LIRKind.combine(operand).changeType(JavaKind.Int)); - if (operand.getPlatformKind() == JavaKind.Long) { - append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand), this)); - } else { - append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand), this)); + Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); + Value usedOperand = operand; + if (operand.getPlatformKind() == SPARCKind.WORD) { // Zero extend + usedOperand = newVariable(operand.getLIRKind()); + append(new SPARCOP3Op(Op3s.Srl, operand, SPARC.g0.asValue(), usedOperand)); } + append(new SPARCOP3Op(Op3s.Popc, SPARC.g0.asValue(), usedOperand, result)); return result; } @Override public Variable emitBitScanForward(Value operand) { - Variable result = newVariable(LIRKind.combine(operand).changeType(JavaKind.Int)); + Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this)); return result; } @Override public Variable emitBitScanReverse(Value operand) { - Variable result = newVariable(LIRKind.combine(operand).changeType(JavaKind.Int)); - if (operand.getPlatformKind() == JavaKind.Long) { + Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD)); + if (operand.getPlatformKind() == SPARCKind.DWORD) { append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand), this)); } else { append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this)); @@ -595,14 +556,38 @@ @Override public Value emitMathAbs(Value input) { Variable result = newVariable(LIRKind.combine(input)); - append(new SPARCMathIntrinsicOp(ABS, result, asAllocatable(input))); + SPARCKind kind = (SPARCKind) input.getPlatformKind(); + Opfs opf; + switch (kind) { + case SINGLE: + opf = Opfs.Fabss; + break; + case DOUBLE: + opf = Opfs.Fabsd; + break; + default: + throw JVMCIError.shouldNotReachHere("Input kind: " + kind); + } + append(new SPARCOPFOp(opf, g0.asValue(), input, result)); return result; } @Override public Value emitMathSqrt(Value input) { Variable result = newVariable(LIRKind.combine(input)); - append(new SPARCMathIntrinsicOp(SQRT, result, asAllocatable(input))); + SPARCKind kind = (SPARCKind) input.getPlatformKind(); + Opfs opf; + switch (kind) { + case SINGLE: + opf = Opfs.Fsqrts; + break; + case DOUBLE: + opf = Opfs.Fsqrtd; + break; + default: + throw JVMCIError.shouldNotReachHere("Input kind: " + kind); + } + append(new SPARCOPFOp(opf, g0.asValue(), input, result)); return result; } @@ -615,174 +600,151 @@ @Override public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) { - Variable result = newVariable(LIRKind.value(JavaKind.Int)); + Variable result = newVariable(LIRKind.value(SPARCKind.WORD)); append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length))); return result; } @Override public Value emitNegate(Value input) { - switch (((JavaKind) input.getPlatformKind()).getStackKind()) { - case Long: - return emitUnary(LNEG, input); - case Int: - return emitUnary(INEG, input); - case Float: - return emitUnary(FNEG, input); - case Double: - return emitUnary(DNEG, input); - default: - throw JVMCIError.shouldNotReachHere(); + PlatformKind inputKind = input.getPlatformKind(); + if (isNumericInteger(inputKind)) { + return emitUnary(Sub, input); + } else { + return emitUnary(inputKind.equals(DOUBLE) ? Fnegd : Fnegs, input); } } @Override public Value emitNot(Value input) { - switch (((JavaKind) input.getPlatformKind()).getStackKind()) { - case Int: - return emitUnary(INOT, input); - case Long: - return emitUnary(LNOT, input); - default: - throw JVMCIError.shouldNotReachHere(); - } + return emitUnary(Xnor, input); } - private Variable emitUnary(SPARCArithmetic op, Value input) { + private Variable emitUnary(Opfs opf, Value input) { Variable result = newVariable(LIRKind.combine(input)); - append(new Unary2Op(op, result, load(input))); + append(new SPARCOPFOp(opf, g0.asValue(), input, result)); + return result; + } + + private Variable emitUnary(Op3s op3, Value input) { + Variable result = newVariable(LIRKind.combine(input)); + append(SPARCOP3Op.newUnary(op3, input, result)); return result; } - private Variable emitBinary(LIRKind resultKind, SPARCArithmetic op, boolean commutative, Value a, Value b) { - return emitBinary(resultKind, op, commutative, a, b, null); + private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b) { + return emitBinary(resultKind, opf, a, b, null); } - private Variable emitBinary(LIRKind resultKind, SPARCArithmetic op, boolean commutative, Value a, Value b, LIRFrameState state) { - if (isJavaConstant(b) && canInlineConstant(asJavaConstant(b))) { - return emitBinaryConst(resultKind, op, load(a), asConstantValue(b), state); - } else if (commutative && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) { - return emitBinaryConst(resultKind, op, load(b), asConstantValue(a), state); + private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b, LIRFrameState state) { + Variable result = newVariable(resultKind); + if (opf.isCommutative() && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) { + append(new SPARCOPFOp(opf, b, a, result, state)); } else { - return emitBinaryVar(resultKind, op, load(a), load(b), state); + append(new SPARCOPFOp(opf, a, b, result, state)); } + return result; } - private Variable emitBinaryConst(LIRKind resultKind, SPARCArithmetic op, AllocatableValue a, ConstantValue b, LIRFrameState state) { - 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 (canInlineConstant(b.getJavaConstant())) { - Variable result = newVariable(resultKind); - append(new BinaryRegConst(op, result, a, b.getJavaConstant(), state)); - return result; - } - break; - } - return emitBinaryVar(resultKind, op, a, asAllocatable(b), state); + private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, int b) { + return emitBinary(resultKind, op3, a, new ConstantValue(LIRKind.value(WORD), JavaConstant.forInt(b))); + } + + private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b) { + return emitBinary(resultKind, op3, a, b, null); } - private Variable emitBinaryVar(LIRKind resultKind, SPARCArithmetic op, AllocatableValue a, AllocatableValue b, LIRFrameState state) { + private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b, LIRFrameState state) { Variable result = newVariable(resultKind); - append(new BinaryRegReg(op, result, a, b, state)); + if (op3.isCommutative() && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) { + append(new SPARCOP3Op(op3, load(b), a, result, state)); + } else { + append(new SPARCOP3Op(op3, load(a), b, result, state)); + } return result; } @Override protected boolean isNumericInteger(PlatformKind kind) { - return ((JavaKind) kind).isNumericInteger(); + return ((SPARCKind) kind).isInteger(); } @Override public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, setFlags ? IADDCC : IADD, true, a, b); - case Long: - return emitBinary(resultKind, setFlags ? LADDCC : LADD, true, a, b); - case Float: - return emitBinary(resultKind, FADD, true, a, b); - case Double: - return emitBinary(resultKind, DADD, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); + if (isNumericInteger(a.getPlatformKind())) { + return emitBinary(resultKind, setFlags ? Addcc : Add, a, b); + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Faddd : Fadds, a, b); } } @Override public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, setFlags ? ISUBCC : ISUB, false, a, b); - case Long: - return emitBinary(resultKind, setFlags ? LSUBCC : LSUB, false, a, b); - case Float: - return emitBinary(resultKind, FSUB, false, a, b); - case Double: - return emitBinary(resultKind, DSUB, false, a, b); - default: - throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); + if (isNumericInteger(a.getPlatformKind())) { + return emitBinary(resultKind, setFlags ? Subcc : Sub, a, b); + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Opfs.Fsubd : Opfs.Fsubs, a, b); } } @Override public Variable emitMul(Value a, Value b, boolean setFlags) { LIRKind resultKind = LIRKind.combine(a, b); - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, setFlags ? IMULCC : IMUL, true, a, b); - case Long: - if (setFlags) { - Variable result = newVariable(LIRKind.combine(a, b)); + PlatformKind aKind = a.getPlatformKind(); + if (isNumericInteger(aKind)) { + if (setFlags) { + Variable result = newVariable(LIRKind.combine(a, b)); + if (aKind == DWORD) { append(new SPARCLMulccOp(result, load(a), load(b), this)); - return result; + } else if (aKind == WORD) { + append(new SPARCIMulccOp(result, load(a), load(b))); } else { - return emitBinary(resultKind, LMUL, true, a, b); + throw JVMCIError.shouldNotReachHere(); } - case Float: - return emitBinary(resultKind, FMUL, true, a, b); - case Double: - return emitBinary(resultKind, DMUL, true, a, b); - default: - throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); + return result; + } else { + return emitBinary(resultKind, setFlags ? Op3s.Mulscc : Op3s.Mulx, a, b); + } + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Fmuld : Fmuls, a, b); } } @Override public Value emitMulHigh(Value a, Value b) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitMulHigh(IMUL, a, b); - case Long: - return emitMulHigh(LMUL, a, b); + MulHigh opcode; + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + opcode = MulHigh.IMUL; + break; + case DWORD: + opcode = MulHigh.LMUL; + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + return emitMulHigh(opcode, a, b); + } + + @Override + public Value emitUMulHigh(Value a, Value b) { + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + Value aExtended = emitBinary(LIRKind.combine(a), Srl, a, 0); + Value bExtended = emitBinary(LIRKind.combine(b), Srl, b, 0); + Value result = emitBinary(LIRKind.combine(a, b), Mulx, aExtended, bExtended); + return emitBinary(LIRKind.combine(a, b), Srax, result, WORD.getSizeInBits()); + case DWORD: + return emitBinary(LIRKind.combine(a, b), UMulxhi, a, b); default: throw JVMCIError.shouldNotReachHere(); } } - @Override - public Value emitUMulHigh(Value a, Value b) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitMulHigh(IUMUL, a, b); - case Long: - return emitMulHigh(LUMUL, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private Value emitMulHigh(SPARCArithmetic opcode, Value a, Value b) { + private Value emitMulHigh(MulHigh opcode, Value a, Value b) { Variable result = newVariable(LIRKind.combine(a, b)); MulHighOp mulHigh = new MulHighOp(opcode, load(a), load(b), result, newVariable(LIRKind.combine(a, b))); append(mulHigh); @@ -792,55 +754,63 @@ @Override public Value emitDiv(Value a, Value b, LIRFrameState state) { LIRKind resultKind = LIRKind.combine(a, b); - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, IDIV, false, a, b, state); - case Long: - return emitBinary(resultKind, LDIV, false, a, b, state); - case Float: - return emitBinary(resultKind, FDIV, false, a, b, state); - case Double: - return emitBinary(resultKind, DDIV, false, a, b, state); - default: - throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); + PlatformKind aKind = a.getPlatformKind(); + PlatformKind bKind = b.getPlatformKind(); + if (isJavaConstant(b) && asJavaConstant(b).isDefaultForKind()) { // Div by zero + Value zero = SPARC.g0.asValue(LIRKind.value(SPARCKind.WORD)); + return emitBinary(resultKind, Op3s.Sdivx, zero, zero, state); + } else if (isNumericInteger(aKind)) { + Value fixedA = emitSignExtend(a, aKind.getSizeInBytes() * 8, 64); + Value fixedB = emitSignExtend(b, bKind.getSizeInBytes() * 8, 64); + return emitBinary(resultKind, Op3s.Sdivx, fixedA, fixedB, state); + } else { + boolean isDouble = a.getPlatformKind().equals(DOUBLE); + return emitBinary(resultKind, isDouble ? Opfs.Fdivd : Opfs.Fdivs, a, b, state); } } @Override public Value emitRem(Value a, Value b, LIRFrameState state) { Variable result = newVariable(LIRKind.combine(a, b)); + Value aLoaded; + Value bLoaded; Variable q1; // Intermediate values Variable q2; Variable q3; Variable q4; - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - append(new RemOp(IREM, result, load(a), loadNonConst(b), state, this)); + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + switch (aKind) { + case WORD: + q1 = emitBinary(result.getLIRKind(), Sra, a, g0.asValue(LIRKind.value(WORD))); + q2 = emitBinary(q1.getLIRKind(), Sdivx, q1, b, state); + q3 = emitBinary(q2.getLIRKind(), Op3s.Mulx, q2, b); + result = emitSub(q1, q3, false); break; - case Long: - append(new RemOp(LREM, result, load(a), loadNonConst(b), state, this)); + case DWORD: + aLoaded = load(a); // Reuse the loaded value + q1 = emitBinary(result.getLIRKind(), Sdivx, aLoaded, b, state); + q2 = emitBinary(result.getLIRKind(), Mulx, q1, b); + result = emitSub(aLoaded, q2, false); break; - case Float: - q1 = newVariable(LIRKind.value(JavaKind.Float)); - append(new BinaryRegReg(FDIV, q1, a, b, state)); - q2 = newVariable(LIRKind.value(JavaKind.Float)); - append(new Unary2Op(F2I, q2, q1)); - q3 = newVariable(LIRKind.value(JavaKind.Float)); - append(new Unary2Op(I2F, q3, q2)); - q4 = newVariable(LIRKind.value(JavaKind.Float)); - append(new BinaryRegReg(FMUL, q4, q3, b)); - append(new BinaryRegReg(FSUB, result, a, q4)); + case SINGLE: + aLoaded = load(a); + bLoaded = load(b); + q1 = emitBinary(result.getLIRKind(), Fdivs, aLoaded, bLoaded, state); + q2 = newVariable(LIRKind.value(aKind)); + append(new FloatConvertOp(FloatConvertOp.FloatConvert.F2I, q1, q2)); + q3 = emitUnary(Fitos, q2); + q4 = emitBinary(LIRKind.value(aKind), Fmuls, q3, bLoaded); + result = emitSub(aLoaded, q4, false); break; - case Double: - q1 = newVariable(LIRKind.value(JavaKind.Double)); - append(new BinaryRegReg(DDIV, q1, a, b, state)); - q2 = newVariable(LIRKind.value(JavaKind.Double)); - append(new Unary2Op(D2L, q2, q1)); - q3 = newVariable(LIRKind.value(JavaKind.Double)); - append(new Unary2Op(L2D, q3, q2)); - q4 = newVariable(LIRKind.value(JavaKind.Double)); - append(new BinaryRegReg(DMUL, q4, q3, b)); - append(new BinaryRegReg(DSUB, result, a, q4)); + case DOUBLE: + aLoaded = load(a); + bLoaded = load(b); + q1 = emitBinary(result.getLIRKind(), Fdivd, aLoaded, bLoaded, state); + q2 = newVariable(LIRKind.value(aKind)); + append(new FloatConvertOp(FloatConvertOp.FloatConvert.D2L, q1, q2)); + q3 = emitUnary(Fxtod, q2); + q4 = emitBinary(result.getLIRKind(), Fmuld, q3, bLoaded); + result = emitSub(aLoaded, q4, false); break; default: throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); @@ -851,124 +821,111 @@ @Override public Value emitURem(Value a, Value b, LIRFrameState state) { Variable result = newVariable(LIRKind.combine(a, b)); - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - append(new RemOp(IUREM, result, load(a), load(b), state, this)); + Variable scratch1 = newVariable(LIRKind.combine(a, b)); + Variable scratch2 = newVariable(LIRKind.combine(a, b)); + Rem opcode; + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: + opcode = Rem.IUREM; break; - case Long: - append(new RemOp(LUREM, result, load(a), loadNonConst(b), state, this)); + case DWORD: + opcode = Rem.LUREM; break; default: throw JVMCIError.shouldNotReachHere(); } + append(new RemOp(opcode, result, load(a), load(b), scratch1, scratch2, state)); return result; } @Override public Value emitUDiv(Value a, Value b, LIRFrameState state) { - SPARCArithmetic op; Value actualA = a; Value actualB = b; - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - op = LUDIV; + switch (((SPARCKind) a.getPlatformKind())) { + case WORD: actualA = emitZeroExtend(actualA, 32, 64); actualB = emitZeroExtend(actualB, 32, 64); break; - case Long: - op = LUDIV; + case DWORD: break; default: throw JVMCIError.shouldNotReachHere(); } - return emitBinary(LIRKind.combine(actualA, actualB), op, false, actualA, actualB, state); + return emitBinary(LIRKind.combine(actualA, actualB), Udivx, actualA, actualB, state); } @Override public Variable emitAnd(Value a, Value b) { LIRKind resultKind = LIRKind.combine(a, b); - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, IAND, true, a, b); - case Long: - return emitBinary(resultKind, LAND, true, a, b); - - default: - throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); - } + return emitBinary(resultKind, Op3s.And, a, b); } @Override public Variable emitOr(Value a, Value b) { LIRKind resultKind = LIRKind.combine(a, b); - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, IOR, true, a, b); - case Long: - return emitBinary(resultKind, LOR, true, a, b); - default: - throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind()); - } + return emitBinary(resultKind, Op3s.Or, a, b); } @Override public Variable emitXor(Value a, Value b) { LIRKind resultKind = LIRKind.combine(a, b); - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitBinary(resultKind, IXOR, true, a, b); - case Long: - return emitBinary(resultKind, LXOR, true, a, b); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private Variable emitShift(SPARCArithmetic op, Value a, Value b) { - Variable result = newVariable(LIRKind.combine(a, b).changeType(a.getPlatformKind())); - if (isJavaConstant(b) && canInlineConstant(asJavaConstant(b))) { - append(new BinaryRegConst(op, result, load(a), asJavaConstant(b), null)); - } else { - append(new BinaryRegReg(op, result, load(a), load(b))); - } - return result; + return emitBinary(resultKind, Op3s.Xor, a, b); } @Override public Variable emitShl(Value a, Value b) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitShift(ISHL, a, b); - case Long: - return emitShift(LSHL, a, b); + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); + Op3s op; + switch (aKind) { + case WORD: + op = Op3s.Sll; + break; + case DWORD: + op = Op3s.Sllx; + break; default: throw JVMCIError.shouldNotReachHere(); } + return emitBinary(resultKind, op, a, b); } @Override public Variable emitShr(Value a, Value b) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitShift(ISHR, a, b); - case Long: - return emitShift(LSHR, a, b); + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); + Op3s op; + switch (aKind) { + case WORD: + op = Op3s.Sra; + break; + case DWORD: + op = Op3s.Srax; + break; default: throw JVMCIError.shouldNotReachHere(); } + return emitBinary(resultKind, op, a, b); } @Override public Variable emitUShr(Value a, Value b) { - switch (((JavaKind) a.getPlatformKind()).getStackKind()) { - case Int: - return emitShift(IUSHR, a, b); - case Long: - return emitShift(LUSHR, a, b); + SPARCKind aKind = (SPARCKind) a.getPlatformKind(); + LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind); + Op3s op; + switch (aKind) { + case WORD: + op = Op3s.Srl; + break; + case DWORD: + op = Op3s.Srlx; + break; default: throw JVMCIError.shouldNotReachHere(); } + return emitBinary(resultKind, op, a, b); } private AllocatableValue emitConvertMove(LIRKind kind, AllocatableValue input) { @@ -977,78 +934,86 @@ return result; } - private AllocatableValue emitConvert2Op(LIRKind kind, SPARCArithmetic op, AllocatableValue input) { - Variable result = newVariable(kind); - append(new Unary2Op(op, result, input)); - return result; - } - @Override public Value emitFloatConvert(FloatConvert op, Value inputVal) { AllocatableValue input = asAllocatable(inputVal); + Value result; switch (op) { case D2F: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Float), D2F, input); + result = newVariable(LIRKind.combine(inputVal).changeType(SINGLE)); + append(new SPARCOPFOp(Fdtos, inputVal, result)); + break; case F2D: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Double), F2D, input); + result = newVariable(LIRKind.combine(inputVal).changeType(DOUBLE)); + append(new SPARCOPFOp(Fstod, inputVal, result)); + break; case I2F: { - AllocatableValue intEncodedFloatReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Float)); + AllocatableValue intEncodedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); + result = newVariable(intEncodedFloatReg.getLIRKind()); moveBetweenFpGp(intEncodedFloatReg, input); - AllocatableValue convertedFloatReg = newVariable(intEncodedFloatReg.getLIRKind()); - append(new Unary2Op(I2F, convertedFloatReg, intEncodedFloatReg)); - return convertedFloatReg; + append(new SPARCOPFOp(Fitos, intEncodedFloatReg, result)); + break; } case I2D: { // Unfortunately we must do int -> float -> double because fitod has float // and double encoding in one instruction - AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Float)); + AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); + result = newVariable(LIRKind.combine(input).changeType(DOUBLE)); moveBetweenFpGp(convertedFloatReg, input); - AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Double)); - append(new Unary2Op(I2D, convertedDoubleReg, convertedFloatReg)); - return convertedDoubleReg; + append(new SPARCOPFOp(Fitod, convertedFloatReg, result)); + break; } case L2D: { - AllocatableValue longEncodedDoubleReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Double)); + AllocatableValue longEncodedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); moveBetweenFpGp(longEncodedDoubleReg, input); AllocatableValue convertedDoubleReg = newVariable(longEncodedDoubleReg.getLIRKind()); - append(new Unary2Op(L2D, convertedDoubleReg, longEncodedDoubleReg)); - return convertedDoubleReg; + append(new SPARCOPFOp(Fxtod, longEncodedDoubleReg, convertedDoubleReg)); + result = convertedDoubleReg; + break; } case D2I: { - AllocatableValue convertedFloatReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Float), D2I, input); - AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(JavaKind.Int)); + AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); + append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2I, input, convertedFloatReg)); + AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD)); moveBetweenFpGp(convertedIntReg, convertedFloatReg); - return convertedIntReg; + result = convertedIntReg; + break; } case F2L: { - AllocatableValue convertedDoubleReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Double), F2L, input); - AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(JavaKind.Long)); + AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); + append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2L, input, convertedDoubleReg)); + AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD)); moveBetweenFpGp(convertedLongReg, convertedDoubleReg); - return convertedLongReg; + result = convertedLongReg; + break; } case F2I: { - AllocatableValue convertedFloatReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Float), F2I, input); - AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(JavaKind.Int)); + AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE)); + append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2I, input, convertedFloatReg)); + AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD)); moveBetweenFpGp(convertedIntReg, convertedFloatReg); - return convertedIntReg; + result = convertedIntReg; + break; } case D2L: { - AllocatableValue convertedDoubleReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Double), D2L, input); - AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(JavaKind.Long)); + AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); + append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2L, input, convertedDoubleReg)); + AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD)); moveBetweenFpGp(convertedLongReg, convertedDoubleReg); - return convertedLongReg; + result = convertedLongReg; + break; } case L2F: { - // long -> double -> float see above - AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Double)); + AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE)); + result = newVariable(LIRKind.combine(input).changeType(SINGLE)); moveBetweenFpGp(convertedDoubleReg, input); - AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Float)); - append(new Unary2Op(L2F, convertedFloatReg, convertedDoubleReg)); - return convertedFloatReg; + append(new SPARCOPFOp(Opfs.Fxtos, convertedDoubleReg, result)); + break; } default: throw JVMCIError.shouldNotReachHere(); } + return result; } private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) { @@ -1056,7 +1021,7 @@ if (getArchitecture().getFeatures().contains(CPUFeature.VIS3)) { tempSlot = AllocatableValue.ILLEGAL; } else { - tempSlot = getTempSlot(LIRKind.value(JavaKind.Long)); + tempSlot = getTempSlot(LIRKind.value(DWORD)); } append(new MoveFpGp(dst, src, tempSlot)); } @@ -1074,8 +1039,11 @@ @Override public Value emitNarrow(Value inputVal, int bits) { - if (inputVal.getPlatformKind() == JavaKind.Long && bits <= 32) { - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Int), L2I, asAllocatable(inputVal)); + if (inputVal.getPlatformKind() == DWORD && bits <= 32) { + LIRKind resultKind = LIRKind.combine(inputVal).changeType(WORD); + Variable result = newVariable(resultKind); + emitMove(result, inputVal); + return result; } else { return inputVal; } @@ -1083,34 +1051,32 @@ @Override public Value emitSignExtend(Value inputVal, int fromBits, int toBits) { - assert fromBits <= toBits && toBits <= 64; + assert fromBits <= toBits && toBits <= DWORD.getSizeInBits(); + LIRKind shiftKind = LIRKind.value(WORD); + LIRKind resultKind = LIRKind.combine(inputVal).changeType(toBits > 32 ? DWORD : WORD); + Value result; + int shiftCount = DWORD.getSizeInBits() - fromBits; if (fromBits == toBits) { - return inputVal; - } else if (toBits > 32) { - // sign extend to 64 bits - switch (fromBits) { - case 8: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Long), B2L, asAllocatable(inputVal)); - case 16: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Long), S2L, asAllocatable(inputVal)); - case 32: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Long), I2L, asAllocatable(inputVal)); - default: - throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); + result = inputVal; + } else if (isJavaConstant(inputVal)) { + JavaConstant javaConstant = asJavaConstant(inputVal); + long constant; + if (javaConstant.isNull()) { + constant = 0; + } else { + constant = javaConstant.asLong(); } + return new ConstantValue(resultKind, JavaConstant.forLong((constant << shiftCount) >> shiftCount)); + } else if (fromBits == WORD.getSizeInBits() && toBits == DWORD.getSizeInBits()) { + result = newVariable(resultKind); + append(new SPARCOP3Op(Sra, inputVal, SPARC.g0.asValue(LIRKind.value(WORD)), result)); } else { - // sign extend to 32 bits (smaller values are internally represented as 32 bit values) - switch (fromBits) { - case 8: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Int), B2I, asAllocatable(inputVal)); - case 16: - return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Int), S2I, asAllocatable(inputVal)); - case 32: - return inputVal; - default: - throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); - } + Variable tmp = newVariable(resultKind.changeType(DWORD)); + result = newVariable(resultKind); + append(new SPARCOP3Op(Sllx, inputVal, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), tmp)); + append(new SPARCOP3Op(Srax, tmp, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), result)); } + return result; } @Override @@ -1118,83 +1084,34 @@ assert fromBits <= toBits && toBits <= 64; if (fromBits == toBits) { return inputVal; - } else if (fromBits > 32) { - assert inputVal.getPlatformKind() == JavaKind.Long; - Variable result = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Long)); - long mask = CodeUtil.mask(fromBits); - append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), JavaConstant.forLong(mask), null)); - return result; + } + Variable result = newVariable(LIRKind.combine(inputVal).changeType(toBits > WORD.getSizeInBits() ? DWORD : WORD)); + if (fromBits == 32) { + append(new SPARCOP3Op(Srl, inputVal, g0.asValue(), result)); } else { - assert inputVal.getPlatformKind() == JavaKind.Int || inputVal.getPlatformKind() == JavaKind.Short || inputVal.getPlatformKind() == JavaKind.Byte || - inputVal.getPlatformKind() == JavaKind.Char : inputVal.getPlatformKind(); - Variable result = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Int)); - long mask = CodeUtil.mask(fromBits); - JavaConstant constant = JavaConstant.forInt((int) mask); - if (fromBits == 32) { - append(new BinaryRegConst(IUSHR, result, inputVal, JavaConstant.forInt(0))); - } else if (canInlineConstant(constant)) { - append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant, null)); - } else { - Variable maskVar = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Int)); - emitMoveConstant(maskVar, constant); - append(new BinaryRegReg(IAND, result, maskVar, asAllocatable(inputVal))); - } - if (toBits > 32) { - Variable longResult = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Long)); - emitMove(longResult, result); - return longResult; - } else { - return result; - } + Value mask = emitConstant(LIRKind.value(DWORD), forLong(mask(fromBits))); + append(new SPARCOP3Op(And, inputVal, mask, result)); } + return result; } @Override public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) { - JavaKind from = (JavaKind) inputVal.getPlatformKind(); + SPARCKind fromKind = (SPARCKind) inputVal.getPlatformKind(); + SPARCKind toKind = (SPARCKind) to.getPlatformKind(); AllocatableValue input = asAllocatable(inputVal); Variable result = newVariable(to); // These cases require a move between CPU and FPU registers: - switch ((JavaKind) to.getPlatformKind()) { - case Int: - switch (from) { - case Float: - case Double: - moveBetweenFpGp(result, input); - return result; - } - break; - case Long: - switch (from) { - case Float: - case Double: - moveBetweenFpGp(result, input); - return result; - } - break; - case Float: - switch (from) { - case Int: - case Long: - moveBetweenFpGp(result, input); - return result; - } - break; - case Double: - switch (from) { - case Int: - case Long: - moveBetweenFpGp(result, input); - return result; - } - break; + if (fromKind.isFloat() != toKind.isFloat()) { + moveBetweenFpGp(result, input); + return result; + } else { + // Otherwise, just emit an ordinary move instruction. + // Instructions that move or generate 32-bit register values also set the upper 32 + // bits of the register to zero. + // Consequently, there is no need for a special zero-extension move. + return emitConvertMove(to, input); } - - // Otherwise, just emit an ordinary move instruction. - // Instructions that move or generate 32-bit register values also set the upper 32 - // bits of the register to zero. - // Consequently, there is no need for a special zero-extension move. - return emitConvertMove(to, input); } @Override @@ -1219,12 +1136,12 @@ public void emitNullCheck(Value address, LIRFrameState state) { PlatformKind kind = address.getPlatformKind(); - assert kind == JavaKind.Object || kind == JavaKind.Long : address + " - " + kind + " not an object!"; + assert kind == DWORD : address + " - " + kind + " not an object!"; append(new NullCheckOp(asAddressValue(address), state)); } public void emitLoadConstantTableBase() { - constantTableBase = newVariable(LIRKind.value(JavaKind.Long)); + constantTableBase = newVariable(LIRKind.value(DWORD)); int nextPosition = getResult().getLIR().getLIRforBlock(getCurrentBlock()).size(); NoOp placeHolder = append(new NoOp(getCurrentBlock(), nextPosition)); loadConstantTableBaseOp = new SPARCLoadConstantTableBaseOp(constantTableBase, placeHolder);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRKindTool.java Wed Sep 23 15:42:58 2015 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015, 2015, 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.compiler.sparc; + +import jdk.internal.jvmci.common.JVMCIError; +import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.sparc.SPARCKind; + +import com.oracle.graal.compiler.common.spi.LIRKindTool; + +public class SPARCLIRKindTool implements LIRKindTool { + + public LIRKind getIntegerKind(int bits) { + if (bits <= 8) { + return LIRKind.value(SPARCKind.BYTE); + } else if (bits <= 16) { + return LIRKind.value(SPARCKind.HWORD); + } else if (bits <= 32) { + return LIRKind.value(SPARCKind.WORD); + } else { + assert bits <= 64; + return LIRKind.value(SPARCKind.DWORD); + } + } + + public LIRKind getFloatingKind(int bits) { + switch (bits) { + case 32: + return LIRKind.value(SPARCKind.SINGLE); + case 64: + return LIRKind.value(SPARCKind.DOUBLE); + default: + throw JVMCIError.shouldNotReachHere(); + } + } + + public LIRKind getObjectKind() { + return LIRKind.reference(SPARCKind.DWORD); + } + + public LIRKind getWordKind() { + return LIRKind.value(SPARCKind.DWORD); + } +}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Wed Sep 23 15:42:58 2015 +0200 @@ -23,12 +23,16 @@ package com.oracle.graal.compiler.sparc; +import static jdk.internal.jvmci.sparc.SPARCKind.BYTE; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.HWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import jdk.internal.jvmci.code.CallingConvention; import jdk.internal.jvmci.common.JVMCIError; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.JavaType; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.compiler.gen.NodeLIRBuilder; import com.oracle.graal.compiler.match.ComplexMatchResult; @@ -88,33 +92,32 @@ private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) { assert fromBits <= toBits && toBits <= 64; - JavaKind toKind = null; - JavaKind fromKind = null; + SPARCKind toKind = null; + SPARCKind fromKind = null; if (fromBits == toBits) { return null; - } else if (toBits > 32) { - toKind = JavaKind.Long; - } else if (toBits > 16) { - toKind = JavaKind.Int; - } else { - toKind = JavaKind.Short; + } else if (toBits > WORD.getSizeInBits()) { + toKind = DWORD; + } else if (toBits > HWORD.getSizeInBits()) { + toKind = WORD; + } else if (toBits > BYTE.getSizeInBits()) { + toKind = HWORD; } switch (fromBits) { case 8: - fromKind = JavaKind.Byte; + fromKind = BYTE; break; case 16: - fromKind = JavaKind.Short; + fromKind = HWORD; break; case 32: - fromKind = JavaKind.Int; + fromKind = WORD; break; default: throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); } - - JavaKind localFromKind = fromKind; - JavaKind localToKind = toKind; + SPARCKind localFromKind = fromKind; + SPARCKind localToKind = toKind; return builder -> { Value v = getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access)); return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v); @@ -123,33 +126,32 @@ private ComplexMatchResult emitZeroExtendMemory(Access access, int fromBits, int toBits) { assert fromBits <= toBits && toBits <= 64; - JavaKind toKind = null; - JavaKind fromKind = null; + SPARCKind toKind = null; + SPARCKind fromKind = null; if (fromBits == toBits) { return null; - } else if (toBits > 32) { - toKind = JavaKind.Long; - } else if (toBits > 16) { - toKind = JavaKind.Int; - } else { - toKind = JavaKind.Short; + } else if (toBits > WORD.getSizeInBits()) { + toKind = DWORD; + } else if (toBits > HWORD.getSizeInBits()) { + toKind = WORD; + } else if (toBits > BYTE.getSizeInBits()) { + toKind = HWORD; } switch (fromBits) { case 8: - fromKind = JavaKind.Byte; + fromKind = BYTE; break; case 16: - fromKind = JavaKind.Short; + fromKind = HWORD; break; case 32: - fromKind = JavaKind.Int; + fromKind = WORD; break; default: throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); } - - JavaKind localFromKind = fromKind; - JavaKind localToKind = toKind; + SPARCKind localFromKind = fromKind; + SPARCKind localToKind = toKind; return builder -> { // Loads are always zero extending load Value v = getLIRGeneratorTool().emitLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access));
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Sep 23 15:42:58 2015 +0200 @@ -494,7 +494,7 @@ for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) { Value paramValue = params[param.index()]; - assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())); + assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp()); setResult(param, gen.emitMove(paramValue)); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -25,8 +25,8 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK; import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; import jdk.internal.jvmci.code.Register; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; @@ -63,7 +63,7 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Restore the thread register when coming back from the runtime. - SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(JavaKind.Long)), threadTemp, SPARCDelayedControlTransfer.DUMMY); + SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(DWORD)), threadTemp, SPARCDelayedControlTransfer.DUMMY); // Reset last Java frame, last Java PC and flags. masm.stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset));
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -26,9 +26,9 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK; import static jdk.internal.jvmci.code.ValueUtil.asRegister; import static jdk.internal.jvmci.sparc.SPARC.STACK_BIAS; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.meta.AllocatableValue; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; @@ -69,6 +69,6 @@ masm.stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset)); // Save the thread register when calling out to the runtime. - SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(JavaKind.Long)), getDelayedControlTransfer()); + SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(DWORD)), getDelayedControlTransfer()); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -26,7 +26,7 @@ import static jdk.internal.jvmci.code.ValueUtil.asRegister; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.meta.AllocatableValue; -import jdk.internal.jvmci.meta.JavaKind; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.sparc.SPARCMacroAssembler; import com.oracle.graal.lir.LIRInstructionClass; @@ -56,7 +56,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - Register addrRegister = asRegister(address, JavaKind.Long); + Register addrRegister = asRegister(address, SPARCKind.DWORD); masm.jmp(addrRegister); masm.restoreWindow(); }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Sep 23 15:42:58 2015 +0200 @@ -66,6 +66,8 @@ import static jdk.internal.jvmci.sparc.SPARC.g3; import static jdk.internal.jvmci.sparc.SPARC.g4; import static jdk.internal.jvmci.sparc.SPARC.g5; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import java.util.Map; @@ -91,6 +93,7 @@ import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; import jdk.internal.jvmci.sparc.SPARC; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.compiler.common.calc.Condition; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; @@ -103,7 +106,6 @@ import com.oracle.graal.hotspot.debug.BenchmarkCounters; import com.oracle.graal.hotspot.meta.HotSpotProviders; import com.oracle.graal.hotspot.meta.HotSpotRegistersProvider; -import com.oracle.graal.hotspot.nodes.type.DefaultHotSpotLIRKindTool; import com.oracle.graal.hotspot.stubs.Stub; import com.oracle.graal.lir.LIRFrameState; import com.oracle.graal.lir.LIRInstruction; @@ -131,7 +133,7 @@ private LIRFrameState currentRuntimeCallInfo; public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { - this(new DefaultHotSpotLIRKindTool(providers.getCodeCache().getTarget().arch.getWordKind()), providers, config, cc, lirGenRes); + this(new SPARCHotSpotLIRKindTool(), providers, config, cc, lirGenRes); } protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { @@ -210,7 +212,7 @@ if (linkage.destroysRegisters() || hotspotLinkage.needsJavaFrameAnchor()) { HotSpotRegistersProvider registers = getProviders().getRegisters(); Register thread = registers.getThreadRegister(); - Value threadTemp = newVariable(LIRKind.value(JavaKind.Long)); + Value threadTemp = newVariable(LIRKind.value(SPARCKind.DWORD)); Register stackPointer = registers.getStackPointerRegister(); Variable spScratch = newVariable(LIRKind.value(target().arch.getWordKind())); append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread, stackPointer, threadTemp, spScratch)); @@ -310,7 +312,7 @@ public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { LIRKind kind = newValue.getLIRKind(); assert kind.equals(expectedValue.getLIRKind()); - JavaKind memKind = (JavaKind) kind.getPlatformKind(); + SPARCKind memKind = (SPARCKind) kind.getPlatformKind(); Variable result = newVariable(newValue.getLIRKind()); append(new CompareAndSwapOp(result, asAllocatable(address), asAllocatable(expectedValue), asAllocatable(newValue))); return emitConditionalMove(memKind, expectedValue, result, Condition.EQ, true, trueValue, falseValue); @@ -355,13 +357,13 @@ } @Override - protected boolean emitCompare(PlatformKind cmpKind, Value a, Value b) { + protected boolean emitCompare(SPARCKind cmpKind, Value a, Value b) { Value localA = a; Value localB = b; if (isConstantValue(a)) { Constant c = asConstant(a); if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { - localA = SPARC.g0.asValue(LIRKind.value(JavaKind.Int)); + localA = SPARC.g0.asValue(LIRKind.value(WORD)); } else if (c instanceof HotSpotObjectConstant) { localA = load(localA); } @@ -369,7 +371,7 @@ if (isConstantValue(b)) { Constant c = asConstant(b); if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { - localB = SPARC.g0.asValue(LIRKind.value(JavaKind.Int)); + localB = SPARC.g0.asValue(LIRKind.value(WORD)); } else if (c instanceof HotSpotObjectConstant) { localB = load(localB); } @@ -380,18 +382,18 @@ @Override public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { LIRKind inputKind = pointer.getLIRKind(); - assert inputKind.getPlatformKind() == JavaKind.Long || inputKind.getPlatformKind() == JavaKind.Object; + assert inputKind.getPlatformKind() == DWORD : inputKind; if (inputKind.isReference(0)) { // oop - Variable result = newVariable(LIRKind.reference(JavaKind.Int)); + Variable result = newVariable(LIRKind.reference(WORD)); append(new SPARCHotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); return result; } else { // metaspace pointer - Variable result = newVariable(LIRKind.value(JavaKind.Int)); + Variable result = newVariable(LIRKind.value(WORD)); AllocatableValue base = Value.ILLEGAL; if (encoding.base != 0) { - base = emitLoadConstant(LIRKind.value(JavaKind.Long), JavaConstant.forLong(encoding.base)); + base = emitLoadConstant(LIRKind.value(DWORD), JavaConstant.forLong(encoding.base)); } append(new SPARCHotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); return result; @@ -401,18 +403,18 @@ @Override public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { LIRKind inputKind = pointer.getLIRKind(); - assert inputKind.getPlatformKind() == JavaKind.Int; + assert inputKind.getPlatformKind() == WORD; if (inputKind.isReference(0)) { // oop - Variable result = newVariable(LIRKind.reference(JavaKind.Long)); + Variable result = newVariable(LIRKind.reference(DWORD)); append(new SPARCHotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); return result; } else { // metaspace pointer - Variable result = newVariable(LIRKind.value(JavaKind.Long)); + Variable result = newVariable(LIRKind.value(DWORD)); AllocatableValue base = Value.ILLEGAL; if (encoding.base != 0) { - base = emitLoadConstant(LIRKind.value(JavaKind.Long), JavaConstant.forLong(encoding.base)); + base = emitLoadConstant(LIRKind.value(DWORD), JavaConstant.forLong(encoding.base)); } append(new SPARCHotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); return result; @@ -450,7 +452,6 @@ StackSlotValue[] savedRegisterLocations = new StackSlotValue[savedRegisters.length]; for (int i = 0; i < savedRegisters.length; i++) { PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory()); - assert kind != JavaKind.Illegal; VirtualStackSlot spillSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind)); savedRegisterLocations[i] = spillSlot; } @@ -529,7 +530,7 @@ @Override public void emitNullCheck(Value address, LIRFrameState state) { PlatformKind kind = address.getPlatformKind(); - if (kind == JavaKind.Int) { + if (kind == WORD) { CompressEncoding encoding = config.getOopEncoding(); Value uncompressed = emitUncompress(address, encoding, false); append(new NullCheckOp(asAddressValue(uncompressed), state));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRKindTool.java Wed Sep 23 15:42:58 2015 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, 2015, 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 jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.sparc.SPARCKind; + +import com.oracle.graal.compiler.sparc.SPARCLIRKindTool; +import com.oracle.graal.hotspot.nodes.type.HotSpotLIRKindTool; + +public class SPARCHotSpotLIRKindTool extends SPARCLIRKindTool implements HotSpotLIRKindTool { + + public LIRKind getNarrowOopKind() { + return LIRKind.reference(SPARCKind.WORD); + } + + public LIRKind getNarrowPointerKind() { + return LIRKind.value(SPARCKind.WORD); + } +}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Wed Sep 23 15:42:58 2015 +0200 @@ -32,9 +32,9 @@ import jdk.internal.jvmci.code.RegisterValue; import jdk.internal.jvmci.hotspot.HotSpotResolvedJavaMethod; import jdk.internal.jvmci.meta.AllocatableValue; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; import com.oracle.graal.compiler.gen.DebugInfoBuilder; @@ -70,7 +70,7 @@ @Override protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { - HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(JavaKind.Long)); + HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(SPARCKind.DWORD)); return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack); }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -25,9 +25,9 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; import static jdk.internal.jvmci.code.ValueUtil.asRegister; import static jdk.internal.jvmci.sparc.SPARC.i7; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.meta.AllocatableValue; -import jdk.internal.jvmci.meta.JavaKind; import com.oracle.graal.asm.sparc.SPARCAssembler; import com.oracle.graal.asm.sparc.SPARCMacroAssembler; @@ -53,7 +53,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - Register addrRegister = asRegister(address, JavaKind.Long); + Register addrRegister = asRegister(address, DWORD); masm.sub(addrRegister, SPARCAssembler.PC_RETURN_OFFSET, i7); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -66,7 +66,7 @@ if (keyConstants[index] instanceof HotSpotMetaspaceConstant) { HotSpotMetaspaceConstant constant = (HotSpotMetaspaceConstant) keyConstants[index]; CC conditionCode = constant.isCompressed() ? CC.Icc : CC.Xcc; - ConditionFlag conditionFlag = SPARCControlFlow.fromCondition(conditionCode, condition, false); + ConditionFlag conditionFlag = SPARCControlFlow.fromCondition(true, condition, false); LabelHint hint = requestHint(masm, target); // Load constant takes one instruction
--- a/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/ConstantStackCastTest.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/ConstantStackCastTest.java Wed Sep 23 15:42:58 2015 +0200 @@ -24,13 +24,15 @@ import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant; import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; -import jdk.internal.jvmci.amd64.AMD64Kind; import jdk.internal.jvmci.code.StackSlotValue; import jdk.internal.jvmci.common.JVMCIError; import jdk.internal.jvmci.meta.JavaConstant; +import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; +import org.junit.Before; import org.junit.Test; import com.oracle.graal.lir.ConstantValue; @@ -41,15 +43,20 @@ * Tests move from a constant to a wider stack slot (e.g. byte constant to integer stack slot). */ public class ConstantStackCastTest extends LIRTest { + private static PlatformKind byteKind; + private static final LoadConstantStackSpec stackCopyByte = new LoadConstantStackSpec(); + + @Before + public void setup() { + // Necessary to get the PlatformKind on which we're currently running on + byteKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Byte); + stackCopyByte.dstKind = getBackend().getTarget().getLIRKind(JavaKind.Int); + stackCopyByte.srcKind = getBackend().getTarget().getLIRKind(JavaKind.Byte); + } private static class LoadConstantStackSpec extends LIRTestSpecification { - protected final LIRKind dstKind; - protected final LIRKind srcKind; - - public LoadConstantStackSpec(LIRKind dstKind, LIRKind srcKind) { - this.dstKind = dstKind; - this.srcKind = srcKind; - } + LIRKind dstKind; + LIRKind srcKind; @Override public void generate(LIRGeneratorTool gen, Value value) { @@ -69,19 +76,16 @@ } private static ConstantValue getConstant(LIRKind srcKind, JavaConstant c) { - - switch ((AMD64Kind) srcKind.getPlatformKind()) { - case BYTE: - JavaConstant byteConst = JavaConstant.forByte((byte) c.asInt()); - return new ConstantValue(srcKind, byteConst); - default: - throw JVMCIError.shouldNotReachHere("Kind not supported: " + srcKind); + if (srcKind.getPlatformKind() == byteKind) { + JavaConstant byteConst = JavaConstant.forByte((byte) c.asInt()); + return new ConstantValue(srcKind, byteConst); + } else { + throw JVMCIError.shouldNotReachHere("Kind not supported: " + srcKind); } } + } - private static final LoadConstantStackSpec stackCopyByte = new LoadConstantStackSpec(LIRKind.value(AMD64Kind.DWORD), LIRKind.value(AMD64Kind.BYTE)); - @LIRIntrinsic public static byte testCopyByte(@SuppressWarnings("unused") LoadConstantStackSpec spec, byte value) { return value;
--- a/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/StackMoveTest.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/StackMoveTest.java Wed Sep 23 15:42:58 2015 +0200 @@ -22,11 +22,13 @@ */ package com.oracle.graal.lir.jtt; -import jdk.internal.jvmci.amd64.AMD64Kind; import jdk.internal.jvmci.code.StackSlotValue; +import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; +import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; +import org.junit.Before; import org.junit.Test; import com.oracle.graal.lir.Variable; @@ -34,6 +36,15 @@ import com.oracle.graal.lir.gen.LIRGeneratorTool; public class StackMoveTest extends LIRTest { + private static PlatformKind byteKind; + private static PlatformKind shortKind; + + @Before + public void setUp() { + byteKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Byte); + shortKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Short); + } + private static class StackCopySpec extends LIRTestSpecification { @Override public void generate(LIRGeneratorTool gen, Value a) { @@ -184,7 +195,7 @@ private static final LIRTestSpecification shortStackCopy = new StackCopySpec() { @Override protected LIRKind getLIRKind(Value value) { - return LIRKind.value(AMD64Kind.WORD); + return LIRKind.value(shortKind); } }; @@ -218,7 +229,7 @@ private static final LIRTestSpecification byteStackCopy = new StackCopySpec() { @Override protected LIRKind getLIRKind(Value value) { - return LIRKind.value(AMD64Kind.BYTE); + return LIRKind.value(byteKind); } };
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Wed Sep 23 15:42:58 2015 +0200 @@ -41,13 +41,14 @@ import static jdk.internal.jvmci.code.ValueUtil.asRegister; import static jdk.internal.jvmci.code.ValueUtil.isRegister; import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.common.JVMCIError; import jdk.internal.jvmci.meta.AllocatableValue; -import jdk.internal.jvmci.meta.JavaConstant; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; -import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; import jdk.internal.jvmci.sparc.SPARC; @@ -62,159 +63,79 @@ import com.oracle.graal.lir.asm.CompilationResultBuilder; import com.oracle.graal.lir.gen.LIRGeneratorTool; -public enum SPARCArithmetic { - // @formatter:off - IADD, ISUB, IMUL, IUMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, - LADD, LSUB, LMUL, LUMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, - IADDCC, ISUBCC, IMULCC, - LADDCC, LSUBCC, LMULCC, - FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, - DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, - INEG, LNEG, FNEG, DNEG, INOT, LNOT, - L2I, B2I, S2I, B2L, S2L, I2L, - F2D, D2F, - I2F, I2D, F2I, D2I, - L2F, L2D, F2L, D2L; - // @formatter:on +public class SPARCArithmetic { + public static final class FloatConvertOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<FloatConvertOp> TYPE = LIRInstructionClass.create(FloatConvertOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(5); - /** - * Unary operation with separate source and destination operand. - */ - public static final class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass<Unary2Op> TYPE = LIRInstructionClass.create(Unary2Op.class); - public static final SizeEstimate SIZE_1 = SizeEstimate.create(1); - public static final SizeEstimate SIZE_5 = SizeEstimate.create(5); + @Opcode private final FloatConvert opcode; + @Def({REG, HINT}) protected Value result; + @Use({REG}) protected Value x; - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue x; - - public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { - super(TYPE); - this.opcode = opcode; - this.result = result; - this.x = x; + public enum FloatConvert { + F2I, + D2I, + F2L, + D2L } - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitUnary(crb, masm, opcode, result, x, null, getDelayedControlTransfer()); + public FloatConvertOp(FloatConvert opcode, Value x, Value result) { + super(TYPE, SIZE); + this.opcode = opcode; + this.x = x; + this.result = result; } @Override - public SizeEstimate estimateSize() { + protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + Label notOrdered = new Label(); switch (opcode) { case F2L: + masm.fcmp(Fcc0, Fcmps, asRegister(x, SINGLE), asRegister(x, SINGLE)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fstox(asRegister(x, SINGLE), asRegister(result, DOUBLE)); + masm.fxtod(asRegister(result), asRegister(result)); + masm.fsubd(asRegister(result, DOUBLE), asRegister(result, DOUBLE), asRegister(result, DOUBLE)); + masm.bind(notOrdered); + break; case F2I: + masm.fcmp(Fcc0, Fcmps, asRegister(x, SINGLE), asRegister(x, SINGLE)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fstoi(asRegister(x, SINGLE), asRegister(result, SINGLE)); + masm.fitos(asRegister(result, SINGLE), asRegister(result, SINGLE)); + masm.fsubs(asRegister(result, SINGLE), asRegister(result, SINGLE), asRegister(result, SINGLE)); + masm.bind(notOrdered); + break; case D2L: + masm.fcmp(Fcc0, Fcmpd, asRegister(x, DOUBLE), asRegister(x, DOUBLE)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fdtox(asRegister(x, DOUBLE), asRegister(result, DOUBLE)); + masm.fxtod(asRegister(result, DOUBLE), asRegister(result, DOUBLE)); + masm.fsubd(asRegister(result, DOUBLE), asRegister(result, DOUBLE), asRegister(result, DOUBLE)); + masm.bind(notOrdered); + break; case D2I: - return SIZE_5; + masm.fcmp(Fcc0, Fcmpd, asRegister(x, DOUBLE), asRegister(x, DOUBLE)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fdtoi(asRegister(x, DOUBLE), asRegister(result, SINGLE)); + masm.fitos(asRegister(result, SINGLE), asRegister(result, SINGLE)); + masm.fsubs(asRegister(result, SINGLE), asRegister(result, SINGLE), asRegister(result, SINGLE)); + masm.bind(notOrdered); + break; default: - return SIZE_1; + throw JVMCIError.shouldNotReachHere("missing: " + opcode); } } } /** - * Binary operation with two operands. The first source operand is combined with the - * destination. The second source operand must be a register. - */ - public static final class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass<BinaryRegReg> TYPE = LIRInstructionClass.create(BinaryRegReg.class); - public static final SizeEstimate SIZE_1 = SizeEstimate.create(1); - public static final SizeEstimate SIZE_3 = SizeEstimate.create(3); - public static final SizeEstimate SIZE_7 = SizeEstimate.create(7); - - @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected Value result; - @Use({REG}) protected Value x; - @Alive({REG}) protected Value y; - @State LIRFrameState state; - - public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) { - this(opcode, result, x, y, null); - } - - public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) { - super(TYPE); - this.opcode = opcode; - this.result = result; - this.x = x; - this.y = y; - this.state = state; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitRegReg(crb, masm, opcode, result, x, y, state, getDelayedControlTransfer()); - } - - @Override - public void verify() { - super.verify(); - verifyKind(opcode, result.getPlatformKind(), x.getPlatformKind(), y.getPlatformKind()); - } - - @Override - public SizeEstimate estimateSize() { - switch (opcode) { - case IMULCC: - return SIZE_7; - case IUDIV: - case IDIV: - return SIZE_3; - default: - return SIZE_1; - } - } - } - - /** - * Binary operation with single source/destination operand and one constant. - */ - public static final class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass<BinaryRegConst> TYPE = LIRInstructionClass.create(BinaryRegConst.class); - public static final SizeEstimate SIZE = SizeEstimate.create(1); - - @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected AllocatableValue result; - @Use({REG}) protected Value x; - @State protected LIRFrameState state; - protected JavaConstant y; - - public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, JavaConstant y) { - this(opcode, result, x, y, null); - } - - public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, JavaConstant y, LIRFrameState state) { - super(TYPE, SIZE); - this.opcode = opcode; - this.result = result; - this.x = x; - this.y = y; - this.state = state; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitRegConstant(crb, masm, opcode, result, x, y, null, getDelayedControlTransfer()); - } - - @Override - public void verify() { - super.verify(); - verifyKind(opcode, result.getPlatformKind(), x.getPlatformKind(), y.getJavaKind()); - } - } - - /** * Special LIR instruction as it requires a bunch of scratch registers. */ public static final class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass<RemOp> TYPE = LIRInstructionClass.create(RemOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(4); - @Opcode private final SPARCArithmetic opcode; + @Opcode private final Rem opcode; @Def({REG}) protected Value result; @Alive({REG, CONST}) protected Value x; @Alive({REG, CONST}) protected Value y; @@ -222,26 +143,105 @@ @Temp({REG}) protected Value scratch2; @State protected LIRFrameState state; - public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) { + public enum Rem { + IUREM, + LUREM + } + + public RemOp(Rem opcode, Value result, Value x, Value y, Value scratch1, Value scratch2, LIRFrameState state) { super(TYPE, SIZE); this.opcode = opcode; this.result = result; this.x = x; this.y = y; - this.scratch1 = gen.newVariable(LIRKind.combine(x, y)); - this.scratch2 = gen.newVariable(LIRKind.combine(x, y)); + this.scratch1 = scratch1; + this.scratch2 = scratch2; this.state = state; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, getDelayedControlTransfer()); + if (!isJavaConstant(x) && isJavaConstant(y)) { + assert isSimm13(crb.asIntConst(y)); + assert !x.equals(scratch1); + assert !x.equals(scratch2); + assert !y.equals(scratch1); + switch (opcode) { + case LUREM: + crb.recordImplicitException(masm.position(), state); + masm.udivx(asRegister(x, DWORD), crb.asIntConst(y), asRegister(scratch1, DWORD)); + masm.mulx(asRegister(scratch1, DWORD), crb.asIntConst(y), asRegister(scratch2, DWORD)); + getDelayedControlTransfer().emitControlTransfer(crb, masm); + masm.sub(asRegister(x, DWORD), asRegister(scratch2, DWORD), asRegister(result, DWORD)); + break; + case IUREM: + JVMCIError.unimplemented(); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + } else if (isRegister(x) && isRegister(y)) { + Value xLeft = x; + switch (opcode) { + case LUREM: + if (isJavaConstant(x)) { + new Setx(crb.asLongConst(x), asRegister(scratch2, DWORD), false).emit(masm); + xLeft = scratch2; + } + assert !asRegister(xLeft, DWORD).equals(asRegister(scratch1, DWORD)); + assert !asRegister(y, DWORD).equals(asRegister(scratch1, DWORD)); + crb.recordImplicitException(masm.position(), state); + masm.udivx(asRegister(xLeft, DWORD), asRegister(y, DWORD), asRegister(scratch1, DWORD)); + masm.mulx(asRegister(scratch1, DWORD), asRegister(y, DWORD), asRegister(scratch1, DWORD)); + getDelayedControlTransfer().emitControlTransfer(crb, masm); + masm.sub(asRegister(xLeft, DWORD), asRegister(scratch1, DWORD), asRegister(result, DWORD)); + break; + case IUREM: + assert !asRegister(result, WORD).equals(asRegister(scratch1, WORD)); + assert !asRegister(result, WORD).equals(asRegister(scratch2, WORD)); + masm.srl(asRegister(x, WORD), 0, asRegister(scratch1, WORD)); + masm.srl(asRegister(y, WORD), 0, asRegister(result, WORD)); + crb.recordImplicitException(masm.position(), state); + masm.udivx(asRegister(scratch1, WORD), asRegister(result, WORD), asRegister(scratch2, WORD)); + masm.mulx(asRegister(scratch2, WORD), asRegister(result, WORD), asRegister(result, WORD)); + getDelayedControlTransfer().emitControlTransfer(crb, masm); + masm.sub(asRegister(scratch1, WORD), asRegister(result, WORD), asRegister(result, WORD)); + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + } else { + throw JVMCIError.shouldNotReachHere(); + } + } + } + + public static final class SPARCIMulccOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCIMulccOp> TYPE = LIRInstructionClass.create(SPARCIMulccOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(10); + @Def({REG}) protected Value result; + @Alive({REG}) protected Value x; + @Alive({REG}) protected Value y; + + public SPARCIMulccOp(Value result, Value x, Value y) { + super(TYPE, SIZE); + this.result = result; + this.x = x; + this.y = y; } @Override - public void verify() { - super.verify(); - verifyKind(opcode, result.getPlatformKind(), x.getPlatformKind(), y.getPlatformKind()); + protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + try (ScratchRegister tmpScratch = masm.getScratchRegister()) { + Register tmp = tmpScratch.getRegister(); + masm.mulx(asRegister(x, WORD), asRegister(y, WORD), asRegister(result, WORD)); + Label noOverflow = new Label(); + masm.sra(asRegister(result, WORD), 0, tmp); + masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0); + masm.compareBranch(tmp, asRegister(result), Equal, Xcc, noOverflow, PREDICT_TAKEN, null); + masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)); + masm.bind(noOverflow); + } } } @@ -270,21 +270,21 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Label noOverflow = new Label(); - masm.mulx(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(result, JavaKind.Long)); + masm.mulx(asRegister(x, DWORD), asRegister(y, DWORD), asRegister(result, DWORD)); // Calculate the upper 64 bit signed := (umulxhi product - (x{63}&y + y{63}&x)) - masm.umulxhi(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); - masm.srax(asRegister(x, JavaKind.Long), 63, asRegister(scratch2, JavaKind.Long)); - masm.and(asRegister(scratch2, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(scratch2, JavaKind.Long)); - masm.sub(asRegister(scratch1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); + masm.umulxhi(asRegister(x, DWORD), asRegister(y, DWORD), asRegister(scratch1, DWORD)); + masm.srax(asRegister(x, DWORD), 63, asRegister(scratch2, DWORD)); + masm.and(asRegister(scratch2, DWORD), asRegister(y, DWORD), asRegister(scratch2, DWORD)); + masm.sub(asRegister(scratch1, DWORD), asRegister(scratch2, DWORD), asRegister(scratch1, DWORD)); - masm.srax(asRegister(y, JavaKind.Long), 63, asRegister(scratch2, JavaKind.Long)); - masm.and(asRegister(scratch2, JavaKind.Long), asRegister(x, JavaKind.Long), asRegister(scratch2, JavaKind.Long)); - masm.sub(asRegister(scratch1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); + masm.srax(asRegister(y, DWORD), 63, asRegister(scratch2, DWORD)); + masm.and(asRegister(scratch2, DWORD), asRegister(x, DWORD), asRegister(scratch2, DWORD)); + masm.sub(asRegister(scratch1, DWORD), asRegister(scratch2, DWORD), asRegister(scratch1, DWORD)); // Now construct the lower half and compare - masm.srax(asRegister(result, JavaKind.Long), 63, asRegister(scratch2, JavaKind.Long)); - masm.cmp(asRegister(scratch1, JavaKind.Long), asRegister(scratch2, JavaKind.Long)); + masm.srax(asRegister(result, DWORD), 63, asRegister(scratch2, DWORD)); + masm.cmp(asRegister(scratch1, DWORD), asRegister(scratch2, DWORD)); masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN); masm.nop(); masm.wrccr(g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)); @@ -292,624 +292,22 @@ } } - private static void emitRegConstant(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, JavaConstant src2, LIRFrameState info, - SPARCDelayedControlTransfer delaySlotLir) { - assert isSimm13(src2.asLong()) : src2; - int constant = (int) src2.asLong(); - int exceptionOffset = -1; - delaySlotLir.emitControlTransfer(crb, masm); - switch (opcode) { - case IADD: - masm.add(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IADDCC: - masm.addcc(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case ISUB: - masm.sub(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case ISUBCC: - masm.subcc(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IMUL: - masm.mulx(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IMULCC: - throw JVMCIError.unimplemented(); - case IDIV: - masm.sra(asRegister(src1), 0, asRegister(src1)); - masm.sdivx(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IUDIV: - masm.srl(asRegister(src1), 0, asRegister(src1)); - masm.udivx(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IAND: - masm.and(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case ISHL: - masm.sll(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case ISHR: - masm.sra(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IUSHR: - masm.srl(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IOR: - masm.or(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case IXOR: - masm.xor(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int)); - break; - case LADD: - masm.add(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LADDCC: - masm.addcc(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LSUB: - masm.sub(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LSUBCC: - masm.subcc(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LMUL: - masm.mulx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LDIV: - exceptionOffset = masm.position(); - masm.sdivx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LUDIV: - exceptionOffset = masm.position(); - masm.udivx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LAND: - masm.and(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LOR: - masm.or(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LXOR: - masm.xor(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LSHL: - masm.sllx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LSHR: - masm.srax(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case LUSHR: - masm.srlx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long)); - break; - case DAND: // Has no constant implementation in SPARC - case FADD: - case FMUL: - case FDIV: - case DADD: - case DMUL: - case DDIV: - default: - throw JVMCIError.shouldNotReachHere(); - } - if (info != null) { - assert exceptionOffset != -1; - crb.recordImplicitException(exceptionOffset, info); - } - } - - public static void emitRegReg(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info, - SPARCDelayedControlTransfer delaySlotLir) { - int exceptionOffset = -1; - assert !isJavaConstant(src1) : src1; - assert !isJavaConstant(src2) : src2; - switch (opcode) { - case IADD: - delaySlotLir.emitControlTransfer(crb, masm); - masm.add(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IADDCC: - delaySlotLir.emitControlTransfer(crb, masm); - masm.addcc(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case ISUB: - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case ISUBCC: - delaySlotLir.emitControlTransfer(crb, masm); - masm.subcc(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IMUL: - delaySlotLir.emitControlTransfer(crb, masm); - masm.mulx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IMULCC: - try (ScratchRegister tmpScratch = masm.getScratchRegister()) { - Register tmp = tmpScratch.getRegister(); - masm.mulx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - Label noOverflow = new Label(); - masm.sra(asRegister(dst, JavaKind.Int), 0, tmp); - masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0); - masm.compareBranch(tmp, asRegister(dst), Equal, Xcc, noOverflow, PREDICT_TAKEN, null); - masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)); - masm.bind(noOverflow); - } - break; - case IDIV: - masm.signx(asRegister(src1, JavaKind.Int), asRegister(src1, JavaKind.Int)); - masm.signx(asRegister(src2, JavaKind.Int), asRegister(src2, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - exceptionOffset = masm.position(); - masm.sdivx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IUDIV: - masm.srl(asRegister(src1, JavaKind.Int), 0, asRegister(src1, JavaKind.Int)); - masm.srl(asRegister(src2, JavaKind.Int), 0, asRegister(src2, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - exceptionOffset = masm.position(); - masm.udivx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IAND: - delaySlotLir.emitControlTransfer(crb, masm); - masm.and(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IOR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.or(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IXOR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.xor(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case ISHL: - delaySlotLir.emitControlTransfer(crb, masm); - masm.sll(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case ISHR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.sra(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IUSHR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.srl(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IREM: - throw JVMCIError.unimplemented(); - case LADD: - delaySlotLir.emitControlTransfer(crb, masm); - masm.add(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LADDCC: - delaySlotLir.emitControlTransfer(crb, masm); - masm.addcc(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LSUB: - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LSUBCC: - delaySlotLir.emitControlTransfer(crb, masm); - masm.subcc(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LMUL: - delaySlotLir.emitControlTransfer(crb, masm); - masm.mulx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LMULCC: - throw JVMCIError.unimplemented(); - case LDIV: - delaySlotLir.emitControlTransfer(crb, masm); - exceptionOffset = masm.position(); - masm.sdivx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LUDIV: - delaySlotLir.emitControlTransfer(crb, masm); - exceptionOffset = masm.position(); - masm.udivx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LAND: - delaySlotLir.emitControlTransfer(crb, masm); - masm.and(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LOR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.or(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LXOR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.xor(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LSHL: - delaySlotLir.emitControlTransfer(crb, masm); - masm.sllx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Long)); - break; - case LSHR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.srax(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Long)); - break; - case LUSHR: - delaySlotLir.emitControlTransfer(crb, masm); - masm.srlx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Long)); - break; - case FADD: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fadds(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float)); - break; - case FSUB: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fsubs(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float)); - break; - case FMUL: - delaySlotLir.emitControlTransfer(crb, masm); - if (dst.getPlatformKind() == JavaKind.Double) { - masm.fsmuld(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Double)); - } else if (dst.getPlatformKind() == JavaKind.Float) { - masm.fmuls(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float)); - } - break; - case FDIV: - delaySlotLir.emitControlTransfer(crb, masm); - exceptionOffset = masm.position(); - masm.fdivs(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float)); - break; - case FREM: - throw JVMCIError.unimplemented(); - case DADD: - delaySlotLir.emitControlTransfer(crb, masm); - masm.faddd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - case DSUB: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fsubd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - case DMUL: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fmuld(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - case DDIV: - delaySlotLir.emitControlTransfer(crb, masm); - exceptionOffset = masm.position(); - masm.fdivd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - case DREM: - throw JVMCIError.unimplemented(); - case DAND: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fandd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - if (info != null) { - assert exceptionOffset != -1; - crb.recordImplicitException(exceptionOffset, info); - } - } - - public static void emitRem(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info, - SPARCDelayedControlTransfer delaySlotLir) { - int exceptionOffset = -1; - if (!isJavaConstant(src1) && isJavaConstant(src2)) { - assert isSimm13(crb.asIntConst(src2)); - assert !src1.equals(scratch1); - assert !src1.equals(scratch2); - assert !src2.equals(scratch1); - switch (opcode) { - case IREM: - masm.sra(asRegister(src1, JavaKind.Int), 0, asRegister(dst, JavaKind.Int)); - exceptionOffset = masm.position(); - masm.sdivx(asRegister(dst, JavaKind.Int), crb.asIntConst(src2), asRegister(scratch1, JavaKind.Int)); - masm.mulx(asRegister(scratch1, JavaKind.Int), crb.asIntConst(src2), asRegister(scratch2, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(dst, JavaKind.Int), asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case LREM: - exceptionOffset = masm.position(); - masm.sdivx(asRegister(src1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch1, JavaKind.Long)); - masm.mulx(asRegister(scratch1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch2, JavaKind.Long)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(src1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LUREM: - exceptionOffset = masm.position(); - masm.udivx(asRegister(src1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch1, JavaKind.Long)); - masm.mulx(asRegister(scratch1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch2, JavaKind.Long)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(src1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case IUREM: - JVMCIError.unimplemented(); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - } else if (isRegister(src1) && isRegister(src2)) { - Value srcLeft = src1; - switch (opcode) { - case LREM: - if (isJavaConstant(src1)) { - new Setx(crb.asLongConst(src1), asRegister(scratch2, JavaKind.Long), false).emit(masm); - srcLeft = scratch2; - } - assert !asRegister(srcLeft, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long)); - assert !asRegister(src2, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long)); - // But src2 can be scratch2 - exceptionOffset = masm.position(); - masm.sdivx(asRegister(srcLeft, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); - masm.mulx(asRegister(scratch1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(srcLeft, JavaKind.Long), asRegister(scratch1, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case LUREM: - if (isJavaConstant(src1)) { - new Setx(crb.asLongConst(src1), asRegister(scratch2, JavaKind.Long), false).emit(masm); - srcLeft = scratch2; - } - assert !asRegister(srcLeft, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long)); - assert !asRegister(src2, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long)); - exceptionOffset = masm.position(); - masm.udivx(asRegister(srcLeft, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); - masm.mulx(asRegister(scratch1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(srcLeft, JavaKind.Long), asRegister(scratch1, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case IREM: - if (isJavaConstant(src1)) { - new Setx(crb.asIntConst(src1), asRegister(scratch2, JavaKind.Int), false).emit(masm); - srcLeft = scratch2; - } - assert !asRegister(srcLeft, JavaKind.Int).equals(asRegister(scratch1, JavaKind.Int)); - assert !asRegister(src2, JavaKind.Int).equals(asRegister(scratch1, JavaKind.Int)); - masm.sra(asRegister(src1, JavaKind.Int), 0, asRegister(scratch1, JavaKind.Int)); - masm.sra(asRegister(src2, JavaKind.Int), 0, asRegister(scratch2, JavaKind.Int)); - exceptionOffset = masm.position(); - masm.sdivx(asRegister(scratch1, JavaKind.Int), asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - masm.mulx(asRegister(dst, JavaKind.Int), asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(scratch1, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case IUREM: - assert !asRegister(dst, JavaKind.Int).equals(asRegister(scratch1, JavaKind.Int)); - assert !asRegister(dst, JavaKind.Int).equals(asRegister(scratch2, JavaKind.Int)); - masm.srl(asRegister(src1, JavaKind.Int), 0, asRegister(scratch1, JavaKind.Int)); - masm.srl(asRegister(src2, JavaKind.Int), 0, asRegister(dst, JavaKind.Int)); - exceptionOffset = masm.position(); - masm.udivx(asRegister(scratch1, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(scratch2, JavaKind.Int)); - masm.mulx(asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(dst, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sub(asRegister(scratch1, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - } else { - throw JVMCIError.shouldNotReachHere(); - } - if (info != null) { - assert exceptionOffset != -1; - crb.recordImplicitException(exceptionOffset, info); - } - } - - public static void emitUnary(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) { - int exceptionOffset = -1; - Label notOrdered = new Label(); - switch (opcode) { - case INEG: - delaySlotLir.emitControlTransfer(crb, masm); - masm.neg(asRegister(src, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case LNEG: - delaySlotLir.emitControlTransfer(crb, masm); - masm.neg(asRegister(src, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case INOT: - delaySlotLir.emitControlTransfer(crb, masm); - masm.not(asRegister(src, JavaKind.Int), asRegister(dst, JavaKind.Int)); - break; - case LNOT: - delaySlotLir.emitControlTransfer(crb, masm); - masm.not(asRegister(src, JavaKind.Long), asRegister(dst, JavaKind.Long)); - break; - case D2F: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fdtos(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Float)); - break; - case L2D: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fxtod(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - case L2F: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fxtos(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Float)); - break; - case I2D: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fitod(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Double)); - break; - case I2L: - delaySlotLir.emitControlTransfer(crb, masm); - masm.signx(asRegister(src, JavaKind.Int), asRegister(dst, JavaKind.Long)); - break; - case L2I: - delaySlotLir.emitControlTransfer(crb, masm); - masm.signx(asRegister(src, JavaKind.Long), asRegister(dst, JavaKind.Int)); - break; - case B2L: - masm.sll(asRegister(src), 24, asRegister(dst, JavaKind.Long)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sra(asRegister(dst, JavaKind.Long), 24, asRegister(dst, JavaKind.Long)); - break; - case B2I: - masm.sll(asRegister(src), 24, asRegister(dst, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sra(asRegister(dst, JavaKind.Int), 24, asRegister(dst, JavaKind.Int)); - break; - case S2L: - masm.sll(asRegister(src), 16, asRegister(dst, JavaKind.Long)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sra(asRegister(dst, JavaKind.Long), 16, asRegister(dst, JavaKind.Long)); - break; - case S2I: - masm.sll(asRegister(src), 16, asRegister(dst, JavaKind.Int)); - delaySlotLir.emitControlTransfer(crb, masm); - masm.sra(asRegister(dst, JavaKind.Int), 16, asRegister(dst, JavaKind.Int)); - break; - case I2F: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fitos(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Float)); - break; - case F2D: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fstod(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Double)); - break; - case F2L: - masm.fcmp(Fcc0, Fcmps, asRegister(src, JavaKind.Float), asRegister(src, JavaKind.Float)); - masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); - masm.fstox(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Double)); - masm.fxtod(asRegister(dst), asRegister(dst)); - masm.fsubd(asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double)); - masm.bind(notOrdered); - break; - case F2I: - masm.fcmp(Fcc0, Fcmps, asRegister(src, JavaKind.Float), asRegister(src, JavaKind.Float)); - masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); - masm.fstoi(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Float)); - masm.fitos(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float)); - masm.fsubs(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float)); - masm.bind(notOrdered); - break; - case D2L: - masm.fcmp(Fcc0, Fcmpd, asRegister(src, JavaKind.Double), asRegister(src, JavaKind.Double)); - masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); - masm.fdtox(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Double)); - masm.fxtod(asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double)); - masm.fsubd(asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double)); - masm.bind(notOrdered); - break; - case D2I: - masm.fcmp(Fcc0, Fcmpd, asRegister(src, JavaKind.Double), asRegister(src, JavaKind.Double)); - masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); - masm.fdtoi(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Float)); - masm.fitos(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float)); - masm.fsubs(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float)); - masm.bind(notOrdered); - break; - case FNEG: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fnegs(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Float)); - break; - case DNEG: - delaySlotLir.emitControlTransfer(crb, masm); - masm.fnegd(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Double)); - break; - default: - throw JVMCIError.shouldNotReachHere("missing: " + opcode); - } - if (info != null) { - assert exceptionOffset != -1; - crb.recordImplicitException(exceptionOffset, info); - } - } - - private static void verifyKind(SPARCArithmetic opcode, PlatformKind result, PlatformKind x, PlatformKind y) { - JavaKind rk; - JavaKind xk; - JavaKind yk; - JavaKind xsk; - JavaKind ysk; - - switch (opcode) { - case IADD: - case IADDCC: - case ISUB: - case ISUBCC: - case IMUL: - case IMULCC: - case IDIV: - case IREM: - case IAND: - case IOR: - case IXOR: - case ISHL: - case ISHR: - case IUSHR: - case IUDIV: - case IUREM: - rk = ((JavaKind) result).getStackKind(); - xsk = ((JavaKind) x).getStackKind(); - ysk = ((JavaKind) y).getStackKind(); - boolean valid = false; - for (JavaKind k : new JavaKind[]{JavaKind.Int, JavaKind.Short, JavaKind.Byte, JavaKind.Char}) { - valid |= rk == k && xsk == k && ysk == k; - } - assert valid : "rk: " + rk + " xsk: " + xsk + " ysk: " + ysk; - break; - case LADD: - case LADDCC: - case LSUB: - case LSUBCC: - case LMUL: - case LMULCC: - case LDIV: - case LREM: - case LAND: - case LOR: - case LXOR: - case LUDIV: - case LUREM: - rk = (JavaKind) result; - xk = (JavaKind) x; - yk = (JavaKind) y; - assert rk == JavaKind.Long && xk == JavaKind.Long && yk == JavaKind.Long; - break; - case LSHL: - case LSHR: - case LUSHR: - rk = (JavaKind) result; - xk = (JavaKind) x; - yk = (JavaKind) y; - assert rk == JavaKind.Long && xk == JavaKind.Long && (yk == JavaKind.Int || yk == JavaKind.Long); - break; - case FADD: - case FSUB: - case FMUL: - case FDIV: - case FREM: - rk = (JavaKind) result; - xk = (JavaKind) x; - yk = (JavaKind) y; - assert (rk == JavaKind.Float || rk == JavaKind.Double) && xk == JavaKind.Float && yk == JavaKind.Float; - break; - case DAND: - case DADD: - case DSUB: - case DMUL: - case DDIV: - case DREM: - rk = (JavaKind) result; - xk = (JavaKind) x; - yk = (JavaKind) y; - assert rk == JavaKind.Double && xk == JavaKind.Double && yk == JavaKind.Double : "opcode=" + opcode + ", result kind=" + rk + ", x kind=" + xk + ", y kind=" + yk; - break; - default: - throw JVMCIError.shouldNotReachHere("missing: " + opcode); - } - } - public static final class MulHighOp extends SPARCLIRInstruction { public static final LIRInstructionClass<MulHighOp> TYPE = LIRInstructionClass.create(MulHighOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(4); - @Opcode private final SPARCArithmetic opcode; + @Opcode private final MulHigh opcode; @Def({REG}) public AllocatableValue result; @Alive({REG}) public AllocatableValue x; @Alive({REG}) public AllocatableValue y; @Temp({REG}) public AllocatableValue scratch; - public MulHighOp(SPARCArithmetic opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) { + public enum MulHigh { + IMUL, + LMUL + } + + public MulHighOp(MulHigh opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) { super(TYPE, SIZE); this.opcode = opcode; this.x = x; @@ -925,30 +323,20 @@ case IMUL: masm.sra(asRegister(x), 0, asRegister(x)); masm.sra(asRegister(y), 0, asRegister(y)); - masm.mulx(asRegister(x, JavaKind.Int), asRegister(y, JavaKind.Int), asRegister(result, JavaKind.Int)); - masm.srax(asRegister(result, JavaKind.Int), 32, asRegister(result, JavaKind.Int)); - break; - case IUMUL: - assert !asRegister(scratch, JavaKind.Int).equals(asRegister(result, JavaKind.Int)); - masm.srl(asRegister(x, JavaKind.Int), 0, asRegister(scratch, JavaKind.Int)); - masm.srl(asRegister(y, JavaKind.Int), 0, asRegister(result, JavaKind.Int)); - masm.mulx(asRegister(result, JavaKind.Int), asRegister(scratch, JavaKind.Int), asRegister(result, JavaKind.Int)); - masm.srlx(asRegister(result, JavaKind.Int), 32, asRegister(result, JavaKind.Int)); + masm.mulx(asRegister(x, WORD), asRegister(y, WORD), asRegister(result, WORD)); + masm.srax(asRegister(result, WORD), 32, asRegister(result, WORD)); break; case LMUL: - assert !asRegister(scratch, JavaKind.Long).equals(asRegister(result, JavaKind.Long)); - masm.umulxhi(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(result, JavaKind.Long)); - - masm.srlx(asRegister(x, JavaKind.Long), 63, asRegister(scratch, JavaKind.Long)); - masm.mulx(asRegister(scratch, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(scratch, JavaKind.Long)); - masm.sub(asRegister(result, JavaKind.Long), asRegister(scratch, JavaKind.Long), asRegister(result, JavaKind.Long)); + assert !asRegister(scratch, DWORD).equals(asRegister(result, DWORD)); + masm.umulxhi(asRegister(x, DWORD), asRegister(y, DWORD), asRegister(result, DWORD)); - masm.srlx(asRegister(y, JavaKind.Long), 63, asRegister(scratch, JavaKind.Long)); - masm.mulx(asRegister(scratch, JavaKind.Long), asRegister(x, JavaKind.Long), asRegister(scratch, JavaKind.Long)); - masm.sub(asRegister(result, JavaKind.Long), asRegister(scratch, JavaKind.Long), asRegister(result, JavaKind.Long)); - break; - case LUMUL: - masm.umulxhi(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(result, JavaKind.Long)); + masm.srlx(asRegister(x, DWORD), 63, asRegister(scratch, DWORD)); + masm.mulx(asRegister(scratch, DWORD), asRegister(y, DWORD), asRegister(scratch, DWORD)); + masm.sub(asRegister(result, DWORD), asRegister(scratch, DWORD), asRegister(result, DWORD)); + + masm.srlx(asRegister(y, DWORD), 63, asRegister(scratch, DWORD)); + masm.mulx(asRegister(scratch, DWORD), asRegister(x, DWORD), asRegister(scratch, DWORD)); + masm.sub(asRegister(result, DWORD), asRegister(scratch, DWORD), asRegister(result, DWORD)); break; default: throw JVMCIError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -34,6 +34,7 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; import static jdk.internal.jvmci.code.ValueUtil.asRegister; import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import java.lang.reflect.Array; import java.lang.reflect.Field; @@ -42,6 +43,7 @@ import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; +import jdk.internal.jvmci.sparc.SPARCKind; import sun.misc.Unsafe; import com.oracle.graal.asm.Label; @@ -113,7 +115,7 @@ masm.add(asRegister(array2Value), arrayBaseOffset, array2); // Get array length in bytes. - masm.mulx(asRegister(lengthValue, JavaKind.Int), arrayIndexScale, length); + masm.mulx(asRegister(lengthValue, WORD), arrayIndexScale, length); masm.mov(length, result); // copy emit8ByteCompare(masm, result, array1, array2, length, trueLabel, falseLabel); @@ -142,7 +144,7 @@ * Emits code that uses 8-byte vector compares. */ private void emit8ByteCompare(SPARCMacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) { - assert lengthValue.getPlatformKind().equals(JavaKind.Int); + assert lengthValue.getPlatformKind().equals(SPARCKind.WORD); Label loop = new Label(); Label compareTail = new Label(); Label compareTailCorrectVectorEnd = new Label();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -22,16 +22,15 @@ */ package com.oracle.graal.lir.sparc; -import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; -import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant; import static jdk.internal.jvmci.code.ValueUtil.asRegister; import static jdk.internal.jvmci.code.ValueUtil.isRegister; import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.common.JVMCIError; import jdk.internal.jvmci.meta.AllocatableValue; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; @@ -46,8 +45,6 @@ public static final LIRInstructionClass<SPARCBitManipulationOp> TYPE = LIRInstructionClass.create(SPARCBitManipulationOp.class); public enum IntrinsicOpcode { - IPOPCNT(SizeEstimate.create(2)), - LPOPCNT(SizeEstimate.create(1)), IBSR(SizeEstimate.create(13)), LBSR(SizeEstimate.create(14)), BSF(SizeEstimate.create(4)); @@ -74,26 +71,18 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - Register dst = asRegister(result, JavaKind.Int); + Register dst = asRegister(result, WORD); if (isRegister(input)) { Register src = asRegister(input); switch (opcode) { - case IPOPCNT: - // clear upper word for 64 bit POPC - masm.srl(src, g0, dst); - masm.popc(dst, dst); - break; - case LPOPCNT: - masm.popc(src, dst); - break; case BSF: PlatformKind tkind = input.getPlatformKind(); - if (tkind == JavaKind.Int) { + if (tkind == WORD) { masm.sub(src, 1, dst); masm.andn(dst, src, dst); masm.srl(dst, g0, dst); masm.popc(dst, dst); - } else if (tkind == JavaKind.Long) { + } else if (tkind == DWORD) { masm.sub(src, 1, dst); masm.andn(dst, src, dst); masm.popc(dst, dst); @@ -103,7 +92,7 @@ break; case IBSR: { PlatformKind ikind = input.getPlatformKind(); - assert ikind == JavaKind.Int; + assert ikind == WORD; Register tmp = asRegister(scratch); assert !tmp.equals(dst); masm.srl(src, 1, tmp); @@ -123,7 +112,7 @@ } case LBSR: { PlatformKind lkind = input.getPlatformKind(); - assert lkind == JavaKind.Long; + assert lkind == DWORD; Register tmp = asRegister(scratch); assert !tmp.equals(dst); masm.srlx(src, 1, tmp); @@ -146,17 +135,6 @@ throw JVMCIError.shouldNotReachHere(); } - } else if (isJavaConstant(input) && isSimm13(crb.asIntConst(input))) { - switch (opcode) { - case IPOPCNT: - masm.popc(crb.asIntConst(input), dst); - break; - case LPOPCNT: - masm.popc(crb.asIntConst(input), dst); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } } else { throw JVMCIError.shouldNotReachHere(); }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -27,13 +27,15 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.UNINITIALIZED; import static jdk.internal.jvmci.code.ValueUtil.asRegister; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import jdk.internal.jvmci.code.Register; import jdk.internal.jvmci.code.StackSlotValue; import jdk.internal.jvmci.code.ValueUtil; import jdk.internal.jvmci.common.JVMCIError; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.sparc.SPARCAddress; import com.oracle.graal.asm.sparc.SPARCAssembler.Asi; @@ -56,8 +58,8 @@ super(TYPE, SIZE); this.result = result; this.input = input; - this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(JavaKind.Long)); - this.tempIndex = tool.newVariable(LIRKind.value(JavaKind.Long)); + this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(DWORD)); + this.tempIndex = tool.newVariable(LIRKind.value(DWORD)); } @Override @@ -65,17 +67,17 @@ SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot); SPARCMove.emitStore(input, addr, result.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null, crb, masm); if (addr.getIndex().equals(Register.None)) { - Register tempReg = ValueUtil.asRegister(tempIndex, JavaKind.Long); + Register tempReg = ValueUtil.asRegister(tempIndex, DWORD); new SPARCMacroAssembler.Setx(addr.getDisplacement(), tempReg, false).emit(masm); addr = new SPARCAddress(addr.getBase(), tempReg); } getDelayedControlTransfer().emitControlTransfer(crb, masm); - switch ((JavaKind) input.getPlatformKind()) { - case Int: - masm.lduwa(addr.getBase(), addr.getIndex(), asRegister(result, JavaKind.Int), Asi.ASI_PRIMARY_LITTLE); + switch ((SPARCKind) input.getPlatformKind()) { + case WORD: + masm.lduwa(addr.getBase(), addr.getIndex(), asRegister(result, WORD), Asi.ASI_PRIMARY_LITTLE); break; - case Long: - masm.ldxa(addr.getBase(), addr.getIndex(), asRegister(result, JavaKind.Long), Asi.ASI_PRIMARY_LITTLE); + case DWORD: + masm.ldxa(addr.getBase(), addr.getIndex(), asRegister(result, DWORD), Asi.ASI_PRIMARY_LITTLE); break; default: throw JVMCIError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Wed Sep 23 15:42:58 2015 +0200 @@ -65,7 +65,10 @@ import static com.oracle.graal.lir.sparc.SPARCMove.const2reg; import static com.oracle.graal.lir.sparc.SPARCOP3Op.emitOp3; import static jdk.internal.jvmci.code.ValueUtil.asRegister; +import static jdk.internal.jvmci.sparc.SPARC.CPU; import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import java.util.ArrayList; import java.util.EnumSet; @@ -78,10 +81,11 @@ import jdk.internal.jvmci.meta.AllocatableValue; import jdk.internal.jvmci.meta.Constant; import jdk.internal.jvmci.meta.JavaConstant; -import jdk.internal.jvmci.meta.JavaKind; +import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; import jdk.internal.jvmci.sparc.SPARC; import jdk.internal.jvmci.sparc.SPARC.CPUFeature; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.Assembler; import com.oracle.graal.asm.Assembler.LabelHint; @@ -90,6 +94,7 @@ import com.oracle.graal.asm.sparc.SPARCAssembler; import com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict; import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.CMOV; import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; import com.oracle.graal.asm.sparc.SPARCMacroAssembler; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; @@ -135,7 +140,7 @@ public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer { public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(3); - static final EnumSet<JavaKind> SUPPORTED_KINDS = EnumSet.of(JavaKind.Long, JavaKind.Int, JavaKind.Short, JavaKind.Char, JavaKind.Byte); + static final EnumSet<SPARCKind> SUPPORTED_KINDS = EnumSet.of(DWORD, WORD); @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; @@ -144,13 +149,13 @@ protected LabelHint trueDestinationHint; protected final LabelRef falseDestination; protected LabelHint falseDestinationHint; - protected final JavaKind kind; + protected final SPARCKind kind; protected final boolean unorderedIsTrue; private boolean emitted = false; private int delaySlotPosition = -1; private double trueDestinationProbability; - public CompareBranchOp(Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, JavaKind kind, boolean unorderedIsTrue, double trueDestinationProbability) { + public CompareBranchOp(Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, SPARCKind kind, boolean unorderedIsTrue, double trueDestinationProbability) { super(TYPE, SIZE); this.x = x; this.y = y; @@ -159,8 +164,7 @@ this.kind = kind; this.unorderedIsTrue = unorderedIsTrue; this.trueDestinationProbability = trueDestinationProbability; - CC conditionCodeReg = CC.forKind(kind); - conditionFlag = fromCondition(conditionCodeReg, condition, unorderedIsTrue); + conditionFlag = fromCondition(kind.isInteger(), condition, unorderedIsTrue); } @Override @@ -276,29 +280,16 @@ return true; } - private static void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag conditionFlag) { - switch ((JavaKind) actualX.getLIRKind().getPlatformKind()) { - case Int: - if (isJavaConstant(actualY)) { - JavaConstant c = asJavaConstant(actualY); - int constantY = c.isNull() ? 0 : c.asInt(); - CBCOND.emit(masm, conditionFlag, false, asRegister(actualX, JavaKind.Int), constantY, actualTrueTarget); - } else { - CBCOND.emit(masm, conditionFlag, false, asRegister(actualX, JavaKind.Int), asRegister(actualY, JavaKind.Int), actualTrueTarget); - } - break; - case Long: - if (isJavaConstant(actualY)) { - JavaConstant c = asJavaConstant(actualY); - assert c.isNull() || NumUtil.is32bit(c.asLong()); - int constantY = c.isNull() ? 0 : (int) c.asLong(); - CBCOND.emit(masm, conditionFlag, true, asRegister(actualX, JavaKind.Long), constantY, actualTrueTarget); - } else { - CBCOND.emit(masm, conditionFlag, true, asRegister(actualX, JavaKind.Long), asRegister(actualY, JavaKind.Long), actualTrueTarget); - } - break; - default: - JVMCIError.shouldNotReachHere(); + private void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag cFlag) { + PlatformKind xKind = actualX.getPlatformKind(); + boolean isLong = kind == SPARCKind.DWORD; + if (isJavaConstant(actualY)) { + JavaConstant c = asJavaConstant(actualY); + long constantY = c.isNull() ? 0 : c.asLong(); + assert NumUtil.isInt(constantY); + CBCOND.emit(masm, cFlag, isLong, asRegister(actualX, xKind), (int) constantY, actualTrueTarget); + } else { + CBCOND.emit(masm, cFlag, isLong, asRegister(actualX, xKind), asRegister(actualY, xKind), actualTrueTarget); } } @@ -306,13 +297,8 @@ if (!asm.hasFeature(CPUFeature.CBCOND)) { return false; } - switch ((JavaKind) x.getPlatformKind()) { - case Int: - case Long: - case Object: - break; - default: - return false; + if (!((SPARCKind) x.getPlatformKind()).isInteger()) { + return false; } // Do not use short branch, if the y value is a constant and does not fit into simm5 but // fits into simm13; this means the code with CBcond would be longer as the code without @@ -373,10 +359,10 @@ protected final ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected final LabelRef falseDestination; - protected final JavaKind kind; + protected final SPARCKind kind; protected final double trueDestinationProbability; - public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, JavaKind kind, double trueDestinationProbability) { + public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, SPARCKind kind, double trueDestinationProbability) { super(TYPE, SIZE); this.trueDestination = trueDestination; this.falseDestination = falseDestination; @@ -391,7 +377,7 @@ } } - private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, JavaKind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, + private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, boolean withDelayedNop, double trueDestinationProbability) { Label actualTarget; ConditionFlag actualConditionFlag; @@ -412,10 +398,11 @@ // We cannot make use of the delay slot when we jump in true-case and false-case return false; } - if (kind == JavaKind.Double || kind == JavaKind.Float) { + if (kind.isFloat()) { masm.fbpcc(actualConditionFlag, NOT_ANNUL, actualTarget, CC.Fcc0, predictTaken); } else { - CC cc = kind == JavaKind.Int ? CC.Icc : CC.Xcc; + assert kind.isInteger(); + CC cc = kind.equals(SPARCKind.WORD) ? CC.Icc : CC.Xcc; masm.bpcc(actualConditionFlag, NOT_ANNUL, actualTarget, cc, predictTaken); } if (withDelayedNop) { @@ -506,29 +493,21 @@ protected void conditionalJump(int index, Condition condition, Label target) { JavaConstant constant = (JavaConstant) keyConstants[index]; CC conditionCode; - Long bits; + Long bits = constant.asLong(); switch (constant.getJavaKind()) { case Char: case Byte: case Short: case Int: conditionCode = CC.Icc; - bits = constant.asLong(); - break; - case Long: { - conditionCode = CC.Xcc; - bits = constant.asLong(); break; - } - case Object: { - conditionCode = crb.codeCache.getTarget().arch.getWordKind() == JavaKind.Long ? CC.Xcc : CC.Icc; - bits = constant.isDefaultForKind() ? 0L : null; + case Long: + conditionCode = CC.Xcc; break; - } default: throw new JVMCIError("switch only supported for int, long and object"); } - ConditionFlag conditionFlag = fromCondition(conditionCode, condition, false); + ConditionFlag conditionFlag = fromCondition(keyRegister.getRegisterCategory().equals(CPU), condition, false); LabelHint hint = requestHint(masm, target); boolean isShortConstant = isSimm5(constant); int cbCondPosition = masm.position(); @@ -606,8 +585,8 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - Register value = asRegister(index, JavaKind.Int); - Register scratchReg = asRegister(scratch, JavaKind.Long); + Register value = asRegister(index, SPARCKind.WORD); + Register scratchReg = asRegister(scratch, SPARCKind.DWORD); // Compare index against jump table bounds int highKey = lowKey + targets.length - 1; @@ -673,22 +652,24 @@ private final ConditionFlag condition; private final CC cc; + private final CMOV cmove; - public CondMoveOp(Variable result, CC cc, ConditionFlag condition, Value trueValue, Value falseValue) { + public CondMoveOp(CMOV cmove, CC cc, ConditionFlag condition, Value trueValue, Value falseValue, Value result) { super(TYPE); this.result = result; this.condition = condition; this.trueValue = trueValue; this.falseValue = falseValue; this.cc = cc; + this.cmove = cmove; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { if (result.equals(trueValue)) { // We have the true value in place, do he opposite - cmove(masm, cc, result, condition.negate(), falseValue); + cmove(masm, condition.negate(), falseValue); } else if (result.equals(falseValue)) { - cmove(masm, cc, result, condition, trueValue); + cmove(masm, condition, trueValue); } else { // We have to move one of the input values to the result ConditionFlag actualCondition = condition; Value actualTrueValue = trueValue; @@ -699,7 +680,15 @@ actualFalseValue = trueValue; } SPARCMove.move(crb, masm, result, actualFalseValue, SPARCDelayedControlTransfer.DUMMY); - cmove(masm, cc, result, actualCondition, actualTrueValue); + cmove(masm, actualCondition, actualTrueValue); + } + } + + private void cmove(SPARCMacroAssembler masm, ConditionFlag localCondition, Value value) { + if (isConstantValue(value)) { + cmove.emit(masm, localCondition, cc, asImmediate(asJavaConstant(value)), asRegister(result)); + } else { + cmove.emit(masm, localCondition, cc, asRegister(value), asRegister(result)); } } @@ -716,97 +705,47 @@ } } - private static void cmove(SPARCMacroAssembler masm, CC cc, Value result, ConditionFlag cond, Value other) { - switch ((JavaKind) other.getPlatformKind()) { - case Boolean: - case Byte: - case Short: - case Char: - case Int: - if (isJavaConstant(other)) { - int constant; - if (asJavaConstant(other).isNull()) { - constant = 0; - } else { - constant = asJavaConstant(other).asInt(); - } - masm.movcc(cond, cc, constant, asRegister(result)); - } else { - masm.movcc(cond, cc, asRegister(other), asRegister(result)); - } - break; - case Long: - case Object: - if (isJavaConstant(other)) { - long constant; - if (asJavaConstant(other).isNull()) { - constant = 0; - } else { - constant = asJavaConstant(other).asLong(); - } - masm.movcc(cond, cc, (int) constant, asRegister(result)); - } else { - masm.movcc(cond, cc, asRegister(other), asRegister(result)); - } - break; - case Float: - masm.fmovscc(cond, cc, asRegister(other, JavaKind.Float), asRegister(result, JavaKind.Float)); - break; - case Double: - masm.fmovdcc(cond, cc, asRegister(other, JavaKind.Double), asRegister(result, JavaKind.Double)); - break; - default: - throw JVMCIError.shouldNotReachHere(); + public static ConditionFlag fromCondition(boolean integer, Condition cond, boolean unorderedIsTrue) { + if (integer) { + switch (cond) { + case EQ: + return Equal; + case NE: + return NotEqual; + case BT: + return LessUnsigned; + case LT: + return Less; + case BE: + return LessEqualUnsigned; + case LE: + return LessEqual; + case AE: + return GreaterEqualUnsigned; + case GE: + return GreaterEqual; + case AT: + return GreaterUnsigned; + case GT: + return Greater; + } + throw JVMCIError.shouldNotReachHere("Unimplemented for: " + cond); + } else { + switch (cond) { + case EQ: + return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal; + case NE: + return ConditionFlag.F_NotEqual; + case LT: + return unorderedIsTrue ? F_UnorderedOrLess : F_Less; + case LE: + return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual; + case GE: + return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual; + case GT: + return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater; + } + throw JVMCIError.shouldNotReachHere("Unkown condition: " + cond); } } - - public static ConditionFlag fromCondition(CC conditionFlagsRegister, Condition cond, boolean unorderedIsTrue) { - switch (conditionFlagsRegister) { - case Xcc: - case Icc: - switch (cond) { - case EQ: - return Equal; - case NE: - return NotEqual; - case BT: - return LessUnsigned; - case LT: - return Less; - case BE: - return LessEqualUnsigned; - case LE: - return LessEqual; - case AE: - return GreaterEqualUnsigned; - case GE: - return GreaterEqual; - case AT: - return GreaterUnsigned; - case GT: - return Greater; - } - throw JVMCIError.shouldNotReachHere("Unimplemented for: " + cond); - case Fcc0: - case Fcc1: - case Fcc2: - case Fcc3: - switch (cond) { - case EQ: - return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal; - case NE: - return ConditionFlag.F_NotEqual; - case LT: - return unorderedIsTrue ? F_UnorderedOrLess : F_Less; - case LE: - return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual; - case GE: - return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual; - case GT: - return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater; - } - throw JVMCIError.shouldNotReachHere("Unkown condition: " + cond); - } - throw JVMCIError.shouldNotReachHere("Unknown condition flag register " + conditionFlagsRegister); - } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFloatCompareOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFloatCompareOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -53,7 +53,7 @@ @Override protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCAssembler.OPF.emitFcmp(masm, opf, cc, asRegister(a), asRegister(b)); + SPARCAssembler.OpfOp.emitFcmp(masm, opf, cc, asRegister(a), asRegister(b)); } @Override
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java Wed Sep 23 15:42:58 2015 +0200 @@ -25,9 +25,9 @@ import jdk.internal.jvmci.code.CodeCacheProvider; import jdk.internal.jvmci.code.RegisterConfig; import jdk.internal.jvmci.code.StackSlot; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.sparc.SPARC; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.NumUtil; import com.oracle.graal.lir.framemap.FrameMap; @@ -131,6 +131,6 @@ public StackSlot allocateDeoptimizationRescueSlot() { assert spillSize == initialSpillSize : "Deoptimization rescue slot must be the first stack slot"; - return allocateSpillSlot(LIRKind.value(JavaKind.Long)); + return allocateSpillSlot(LIRKind.value(SPARCKind.DWORD)); } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Wed Sep 23 15:42:58 2015 +0200 @@ -22,6 +22,9 @@ */ package com.oracle.graal.lir.sparc; +import jdk.internal.jvmci.meta.JavaConstant; + +import com.oracle.graal.asm.NumUtil; import com.oracle.graal.asm.sparc.SPARCMacroAssembler; import com.oracle.graal.lir.LIRInstruction; import com.oracle.graal.lir.LIRInstructionClass; @@ -53,4 +56,14 @@ public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() { return store; } + + protected static int asImmediate(JavaConstant value) { + if (value.isNull()) { + return 0; + } else { + long val = value.asLong(); + assert NumUtil.isInt(val); + return (int) val; + } + } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Mon Sep 21 14:35:30 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2011, 2015, 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.lir.sparc; - -import static jdk.internal.jvmci.code.ValueUtil.asRegister; -import jdk.internal.jvmci.common.JVMCIError; -import jdk.internal.jvmci.meta.JavaKind; -import jdk.internal.jvmci.meta.Value; - -import com.oracle.graal.asm.sparc.SPARCMacroAssembler; -import com.oracle.graal.lir.LIRInstructionClass; -import com.oracle.graal.lir.Opcode; -import com.oracle.graal.lir.asm.CompilationResultBuilder; - -public final class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass<SPARCMathIntrinsicOp> TYPE = LIRInstructionClass.create(SPARCMathIntrinsicOp.class); - public static final SizeEstimate SIZE = SizeEstimate.create(1); - - public enum IntrinsicOpcode { - SQRT, - ABS - } - - @Opcode private final IntrinsicOpcode opcode; - @Def protected Value result; - @Use protected Value input; - - public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { - super(TYPE, SIZE); - this.opcode = opcode; - this.result = result; - this.input = input; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - JavaKind inputKind = (JavaKind) input.getLIRKind().getPlatformKind(); - getDelayedControlTransfer().emitControlTransfer(crb, masm); - switch (opcode) { - case SQRT: - switch (inputKind) { - case Float: - masm.fsqrts(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Float)); - break; - case Double: - masm.fsqrtd(asRegister(input, JavaKind.Double), asRegister(result, JavaKind.Double)); - break; - default: - JVMCIError.shouldNotReachHere(); - } - break; - case ABS: - switch (inputKind) { - case Float: - masm.fabss(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Float)); - break; - case Double: - masm.fabsd(asRegister(input, JavaKind.Double), asRegister(result, JavaKind.Double)); - break; - default: - JVMCIError.shouldNotReachHere(); - } - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - } - -}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Wed Sep 23 15:42:58 2015 +0200 @@ -37,14 +37,11 @@ import static jdk.internal.jvmci.code.ValueUtil.asStackSlot; import static jdk.internal.jvmci.code.ValueUtil.isRegister; import static jdk.internal.jvmci.code.ValueUtil.isStackSlot; -import static jdk.internal.jvmci.meta.JavaKind.Byte; -import static jdk.internal.jvmci.meta.JavaKind.Char; -import static jdk.internal.jvmci.meta.JavaKind.Double; -import static jdk.internal.jvmci.meta.JavaKind.Float; -import static jdk.internal.jvmci.meta.JavaKind.Int; -import static jdk.internal.jvmci.meta.JavaKind.Long; -import static jdk.internal.jvmci.meta.JavaKind.Short; import static jdk.internal.jvmci.sparc.SPARC.g0; +import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE; +import static jdk.internal.jvmci.sparc.SPARCKind.DWORD; +import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE; +import static jdk.internal.jvmci.sparc.SPARCKind.WORD; import java.util.Set; @@ -55,12 +52,12 @@ import jdk.internal.jvmci.meta.AllocatableValue; import jdk.internal.jvmci.meta.Constant; import jdk.internal.jvmci.meta.JavaConstant; -import jdk.internal.jvmci.meta.JavaKind; import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.PlatformKind; import jdk.internal.jvmci.meta.Value; import jdk.internal.jvmci.sparc.SPARC; import jdk.internal.jvmci.sparc.SPARC.CPUFeature; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.sparc.SPARCAddress; import com.oracle.graal.asm.sparc.SPARCAssembler; @@ -204,8 +201,8 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - JavaKind inputKind = (JavaKind) input.getPlatformKind(); - JavaKind resultKind = (JavaKind) result.getPlatformKind(); + SPARCKind inputKind = (SPARCKind) input.getPlatformKind(); + SPARCKind resultKind = (SPARCKind) result.getPlatformKind(); if (AllocatableValue.ILLEGAL.equals(temp)) { moveDirect(crb, masm, inputKind, resultKind); } else { @@ -213,36 +210,36 @@ } } - private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, JavaKind inputKind, JavaKind resultKind) { + private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind inputKind, SPARCKind resultKind) { getDelayedControlTransfer().emitControlTransfer(crb, masm); - if (resultKind == Float) { - if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { - masm.movwtos(asRegister(input, JavaKind.Int), asRegister(result, JavaKind.Float)); + if (resultKind == SINGLE) { + if (inputKind == WORD) { + masm.movwtos(asRegister(input, WORD), asRegister(result, SINGLE)); } else { - throw JVMCIError.shouldNotReachHere(); + throw JVMCIError.shouldNotReachHere("inputKind: " + inputKind); } - } else if (resultKind == Double) { - if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { - masm.movxtod(asRegister(input, JavaKind.Int), asRegister(result, JavaKind.Double)); + } else if (resultKind == DOUBLE) { + if (inputKind == WORD) { + masm.movxtod(asRegister(input, WORD), asRegister(result, DOUBLE)); } else { - masm.movxtod(asRegister(input, JavaKind.Long), asRegister(result, JavaKind.Double)); + masm.movxtod(asRegister(input, DWORD), asRegister(result, DOUBLE)); } - } else if (inputKind == Float) { - if (resultKind == Int || resultKind == Short || resultKind == Byte) { - masm.movstosw(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Int)); + } else if (inputKind == SINGLE) { + if (resultKind == WORD) { + masm.movstosw(asRegister(input, SINGLE), asRegister(result, WORD)); } else { - masm.movstouw(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Int)); + masm.movstouw(asRegister(input, SINGLE), asRegister(result, WORD)); } - } else if (inputKind == Double) { - if (resultKind == Long) { - masm.movdtox(asRegister(input, JavaKind.Double), asRegister(result, JavaKind.Long)); + } else if (inputKind == DOUBLE) { + if (resultKind == DWORD) { + masm.movdtox(asRegister(input, DOUBLE), asRegister(result, DWORD)); } else { throw JVMCIError.shouldNotReachHere(); } } } - private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, JavaKind inputKind, JavaKind resultKind) { + private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind inputKind, SPARCKind resultKind) { int resultKindSize = resultKind.getSizeInBytes(); assert inputKind.getSizeInBytes() == resultKindSize; try (ScratchRegister sc = masm.getScratchRegister()) { @@ -324,7 +321,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { SPARCAddress address = addressValue.toAddress(); - loadEffectiveAddress(crb, masm, address, asRegister(result, JavaKind.Long), getDelayedControlTransfer()); + loadEffectiveAddress(crb, masm, address, asRegister(result, DWORD), getDelayedControlTransfer()); } } @@ -451,7 +448,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { SPARCAddress address = (SPARCAddress) crb.asAddress(slot); - loadEffectiveAddress(crb, masm, address, asRegister(result, JavaKind.Long), getDelayedControlTransfer()); + loadEffectiveAddress(crb, masm, address, asRegister(result, DWORD), getDelayedControlTransfer()); } } @@ -715,12 +712,11 @@ protected static void compareAndSwap(CompilationResultBuilder crb, SPARCMacroAssembler masm, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue, SPARCDelayedControlTransfer delay) { delay.emitControlTransfer(crb, masm); - switch ((JavaKind) cmpValue.getPlatformKind()) { - case Int: + switch ((SPARCKind) cmpValue.getPlatformKind()) { + case WORD: masm.cas(asRegister(address), asRegister(cmpValue), asRegister(newValue)); break; - case Long: - case Object: + case DWORD: masm.casx(asRegister(address), asRegister(cmpValue), asRegister(newValue)); break; default:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOP3Op.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOP3Op.java Wed Sep 23 15:42:58 2015 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.lir.sparc; -import static com.oracle.graal.asm.sparc.SPARCAssembler.OP3; import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.CONST; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; @@ -33,60 +32,85 @@ import static jdk.internal.jvmci.common.JVMCIError.shouldNotReachHere; import static jdk.internal.jvmci.sparc.SPARC.g0; import jdk.internal.jvmci.meta.JavaConstant; +import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; +import com.oracle.graal.asm.sparc.SPARCAssembler; import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s; import com.oracle.graal.asm.sparc.SPARCMacroAssembler; +import com.oracle.graal.lir.LIRFrameState; import com.oracle.graal.lir.LIRInstructionClass; import com.oracle.graal.lir.Opcode; import com.oracle.graal.lir.asm.CompilationResultBuilder; -public class SPARCOP3Op extends SPARCLIRInstruction { +public final class SPARCOP3Op extends SPARCLIRInstruction { public static final LIRInstructionClass<SPARCOP3Op> TYPE = LIRInstructionClass.create(SPARCOP3Op.class); public static final SizeEstimate SIZE = SizeEstimate.create(1); @Opcode private final Op3s op3; - @Use({REG}) protected Value a; - @Use({REG, CONST}) protected Value b; - @Use({REG}) protected Value result; + @Use({REG}) protected Value rs1; + @Use({REG, CONST}) protected Value rs2; + @Def({REG}) protected Value rd; + @State protected LIRFrameState state; - public SPARCOP3Op(Op3s op3, Value a, Value b) { - this(op3, a, b, g0.asValue()); + public static SPARCOP3Op newUnary(Op3s op3, Value rs2, Value rd) { + return newUnary(op3, rs2, rd, null); + } + + public static SPARCOP3Op newUnary(Op3s op3, Value rs2, Value rd, LIRFrameState state) { + return new SPARCOP3Op(op3, g0.asValue(LIRKind.value(rs2.getPlatformKind())), rs2, rd, state); } - public SPARCOP3Op(Op3s op3, Value a, Value b, Value result) { + public static SPARCOP3Op newBinaryVoid(Op3s op3, Value rs1, Value rs2) { + return newBinaryVoid(op3, rs1, rs2, null); + } + + public static SPARCOP3Op newBinaryVoid(Op3s op3, Value rs1, Value rs2, LIRFrameState state) { + return new SPARCOP3Op(op3, rs1, rs2, g0.asValue(LIRKind.value(rs2.getPlatformKind())), state); + } + + public SPARCOP3Op(Op3s op3, Value rs1, Value rs2, Value rd) { + this(op3, rs1, rs2, rd, null); + } + + public SPARCOP3Op(Op3s op3, Value rs1, Value rs2, Value rd, LIRFrameState state) { super(TYPE, SIZE); this.op3 = op3; - this.a = a; - this.b = b; - this.result = result; + this.rs1 = rs1; + this.rs2 = rs2; + this.rd = rd; + this.state = state; } @Override protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitOp3(masm, op3, a, b, result); + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + emitOp3(masm, op3, rs1, rs2, rd); } - public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value a, Value b) { - emitOp3(masm, op3, a, b, g0.asValue()); + public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value rs1, Value rs2) { + emitOp3(masm, op3, rs1, rs2, g0.asValue(LIRKind.value(rs2.getPlatformKind()))); } - public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value a, Value b, Value result) { - assert isRegister(a); - if (isJavaConstant(b)) { - JavaConstant constant = asJavaConstant(b); + public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value rs1, Value rs2, Value rd) { + assert isRegister(rs1) : rs1; + if (isJavaConstant(rs2)) { + JavaConstant constant = asJavaConstant(rs2); long simm13; if (constant.isNull()) { simm13 = 0; } else { - simm13 = constant.asLong(); // Cast is safe, as isSimm13 assertion is done + // Cast is safe, as isSimm13 assertion is done + simm13 = constant.asLong(); } assert isSimm13(constant); - OP3.emit(masm, op3, asRegister(a), (int) simm13, asRegister(result)); - } else if (isRegister(b)) { - OP3.emit(masm, op3, asRegister(a), asRegister(b), asRegister(result)); + SPARCAssembler.Op3Op.emit(masm, op3, asRegister(rs1), (int) simm13, asRegister(rd)); + } else if (isRegister(rs2)) { + SPARCAssembler.Op3Op.emit(masm, op3, asRegister(rs1), asRegister(rs2), asRegister(rd)); } else { - throw shouldNotReachHere(String.format("Got values a: %s b: %s", a, b)); + throw shouldNotReachHere(String.format("Got values a: %s b: %s", rs1, rs2)); } } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOPFOp.java Mon Sep 21 14:35:30 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOPFOp.java Wed Sep 23 15:42:58 2015 +0200 @@ -24,34 +24,51 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; import static jdk.internal.jvmci.code.ValueUtil.asRegister; +import jdk.internal.jvmci.meta.LIRKind; import jdk.internal.jvmci.meta.Value; +import jdk.internal.jvmci.sparc.SPARC; +import jdk.internal.jvmci.sparc.SPARCKind; import com.oracle.graal.asm.sparc.SPARCAssembler; import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs; import com.oracle.graal.asm.sparc.SPARCMacroAssembler; +import com.oracle.graal.lir.LIRFrameState; import com.oracle.graal.lir.LIRInstructionClass; import com.oracle.graal.lir.Opcode; import com.oracle.graal.lir.asm.CompilationResultBuilder; -public class SPARCOPFOp extends SPARCLIRInstruction { +public final class SPARCOPFOp extends SPARCLIRInstruction { public static final LIRInstructionClass<SPARCOPFOp> TYPE = LIRInstructionClass.create(SPARCOPFOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(1); @Opcode protected final Opfs opf; - @Use({REG}) protected Value a; - @Use({REG}) protected Value b; - @Use({REG}) protected Value result; + @Use({REG}) protected Value rs1; + @Use({REG}) protected Value rs2; + @Def({REG}) protected Value rd; + @State protected LIRFrameState state; - public SPARCOPFOp(Opfs opf, Value a, Value b, Value result) { + public SPARCOPFOp(Opfs opf, Value rs2, Value rd) { + this(opf, SPARC.g0.asValue(LIRKind.value(SPARCKind.SINGLE)), rs2, rd); + } + + public SPARCOPFOp(Opfs opf, Value rs1, Value rs2, Value rd) { + this(opf, rs1, rs2, rd, null); + } + + public SPARCOPFOp(Opfs opf, Value rs1, Value rs2, Value rd, LIRFrameState state) { super(TYPE, SIZE); this.opf = opf; - this.a = a; - this.b = b; - this.result = result; + this.rs1 = rs1; + this.rs2 = rs2; + this.rd = rd; + this.state = state; } @Override protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCAssembler.OPF.emit(masm, opf, asRegister(a), asRegister(b), asRegister(result)); + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + SPARCAssembler.OpfOp.emit(masm, opf, asRegister(rs1), asRegister(rs2), asRegister(rd)); } }