# HG changeset patch # User Stefan Anzinger # Date 1425025103 -3600 # Node ID 413ac504d74ebb9e0cca03cf7cdd67582530181a # Parent afe80ca4b0f02a213d67d2f037089f05b33c2db3 [SPARC] Simplify branch instructions (No more object allocations), Tidy up SPARCControlFlow and SPARCAssembler diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Feb 27 09:18:23 2015 +0100 @@ -60,6 +60,17 @@ public static final int CCR_Z_SHIFT = 2; public static final int CCR_N_SHIFT = 3; + protected static final int OP_SHIFT = 30; + protected static final int CBCOND_SHIFT = 28; + protected static final int OP2_SHIFT = 22; + protected static final int A_SHIFT = 29; + + // @formatter:off + protected static final int A_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; + protected static final int OP_MASK = 0b1100_0000_0000_0000_0000_0000_0000_0000; + protected static final int CBCOND_MASK = 0b0001_0000_0000_0000_0000_0000_0000_0000; // Used for distinguish CBcond and BPr instructions + protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000; + // @formatter:off /** * Instruction format for Fmt00 instructions. This abstraction is needed as it @@ -72,48 +83,12 @@ // @formatter:on public abstract static class Fmt00 implements AssemblerEmittable { - protected static final int OP_SHIFT = 30; - protected static final int CBCOND_SHIFT = 28; - protected static final int OP2_SHIFT = 22; - protected static final int A_SHIFT = 29; - - // @formatter:off - protected static final int A_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; - protected static final int OP_MASK = 0b1100_0000_0000_0000_0000_0000_0000_0000; - protected static final int CBCOND_MASK = 0b0001_0000_0000_0000_0000_0000_0000_0000; // Used for distinguish CBcond and BPr instructions - protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000; - // @formatter:off - private int op2; public Fmt00(int op2) { this.op2 = op2; } - public static Fmt00 read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - Op2s op2 = Op2s.byValue((inst & OP2_MASK) >> OP2_SHIFT); - switch(op2) { - case Br: - case Fb: - return Fmt00b.read(masm, op2, pos); - case Sethi: - case Illtrap: - return Fmt00a.read(masm, pos); - case Bp: - return Fmt00c.read(masm, pos); - case Bpr: - boolean isCBcond = (inst & CBCOND_MASK) != 0; - if (isCBcond) { - return Fmt00e.read(masm, pos); - } else { - return Fmt00d.read(masm, pos); - } - default: - throw GraalInternalError.shouldNotReachHere("Unknown op2 " + op2); - } - } - public void write(SPARCAssembler masm, int pos) { verify(); masm.emitInt(getInstructionBits(), pos); @@ -131,11 +106,13 @@ assert ((op2 << OP2_SHIFT) & OP2_MASK) == (op2 << OP2_SHIFT) : Integer.toHexString(op2); assert Op2s.byValue(op2) != null : op2; } + /** * Sets the immediate (displacement) value on this instruction. * * @see SPARCAssembler#patchJumpTarget(int, int) - * @param imm Displacement/imediate value. Can either be a 22 or 19 bit immediate (dependent on the instruction) + * @param imm Displacement/imediate value. Can either be a 22 or 19 bit immediate (dependent + * on the instruction) */ public abstract void setImm(int imm); @@ -148,6 +125,7 @@ public int getA() { throw GraalInternalError.shouldNotReachHere(); } + public void setA(@SuppressWarnings("unused") int a) { throw GraalInternalError.shouldNotReachHere(); } @@ -234,415 +212,16 @@ } } - // @formatter:off - /** - * Instruction format for branches. - *
-     * | 00  |a | cond | op2 |             disp22                      |
-     * |31 30|29|28  25|24 22|21                                      0|
-     * 
- */ - // @formatter:on - public static class Fmt00b extends Fmt00 { - private int a; - private int cond; - private int disp22; - private Label label; - - private static final int COND_SHIFT = 25; - private static final int DISP22_SHIFT = 0; - - // @formatter:off - private static final int COND_MASK = 0b00011110000000000000000000000000; - private static final int DISP22_MASK = 0b00000000001111111111111111111111; - // @formatter:on - - public Fmt00b(boolean annul, ConditionFlag cond, Op2s op2, Label label) { - this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label); - } - - public Fmt00b(boolean annul, FCond cond, Op2s op2, Label label) { - this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label); - } - - public Fmt00b(int annul, int cond, int op2, Label label) { - this(annul, cond, op2, 0, label); - } - - public Fmt00b(boolean annul, FCond cond, Op2s op2, int disp22) { - this(annul ? 1 : 0, cond.getValue(), op2.getValue(), disp22, null); - } - - public Fmt00b(int annul, int cond, int op2, int disp22) { - this(annul, cond, op2, disp22, null); - } - - public Fmt00b(int a, int cond, int op2, int disp22, Label label) { - super(op2); - setA(a); - setCond(cond); - setDisp22(disp22); - setLabel(label); - } - - @Override - public void emit(SPARCAssembler masm) { - if (label != null) { - final int pos = label.isBound() ? label.position() : patchUnbound(masm, label); - final int disp = pos - masm.position(); - setDisp22(disp); - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - protected int getInstructionBits() { - int inst = super.getInstructionBits() | a << A_SHIFT | cond << COND_SHIFT | (disp22 & DISP22_MASK) << DISP22_SHIFT; - return inst; - } - - protected static Fmt00b read(SPARCAssembler masm, Op2s op2, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.BranchOp.getValue(); - final int op2Read = (inst & OP2_MASK) >> OP2_SHIFT; - assert op2Read == op2.getValue() : "Op2 value read: " + op2Read + " Required op2: " + op2; - - // Get the instruction fields: - final int a = (inst & A_MASK) >> A_SHIFT; - final int cond = (inst & COND_MASK) >> COND_SHIFT; - final int disp22 = (inst & DISP22_MASK) >> DISP22_SHIFT << 2; - - Fmt00b fmt = new Fmt00b(a, cond, op2.getValue(), disp22); - fmt.verify(); - return fmt; - } - - @Override - public int getA() { - return a; - } - - @Override - public void setA(int a) { - this.a = a; - } - - public int getCond() { - return cond; - } - - public void setCond(int cond) { - this.cond = cond; - } - - public int getDisp22() { - return disp22 << 2; - } - - @Override - public void setImm(int imm) { - setDisp22(imm); - } - - public void setDisp22(int disp22) { - this.disp22 = disp22 >> 2; - } - - public Label getLabel() { - return label; - } - - public void setLabel(Label label) { - this.label = label; - } - - @Override - public void verify() { - super.verify(); - assert (getA() << A_SHIFT & ~A_MASK) == 0 : getA(); - assert (getCond() << COND_SHIFT & ~COND_MASK) == 0 : getCond(); - } - } - - // @formatter:off - /** - * Instruction format for conditional branches. - *
-     * | 00  |a | cond | op2 |cc1|cc0|p |             disp19           |
-     * |31 30|29|28  25|24 22|21 |20 |19|                             0|
-     * 
- */ - // @formatter:on - public static class Fmt00c extends Fmt00 { - - private static final int COND_SHIFT = 25; - private static final int CC_SHIFT = 20; - private static final int P_SHIFT = 19; - private static final int DISP19_SHIFT = 0; - - // @formatter:off - private static final int COND_MASK = 0b00011110000000000000000000000000; - private static final int CC_MASK = 0b00000000001100000000000000000000; - private static final int P_MASK = 0b00000000000010000000000000000000; - private static final int DISP19_MASK = 0b00000000000001111111111111111111; - // @formatter:on - - private int a; - private int cond; - private int cc; - private int p; - private int disp19; - private Label label; - - private Fmt00c(int a, int cond, int op2, int cc, int p, int disp19) { - super(op2); - setA(a); - setCond(cond); - setCc(cc); - setP(p); - setDisp19(disp19); - verify(); - } - - public Fmt00c(int a, ConditionFlag cond, Op2s op2, CC cc, int p, int disp19) { - this(a, cond.getValue(), op2.getValue(), cc.getValue(), p, disp19); - } - - public Fmt00c(int a, ConditionFlag cond, Op2s op2, CC cc, int p, Label label) { - this(a, cond.getValue(), op2.getValue(), cc.getValue(), p, 0); - this.label = label; - } - - @Override - public int getA() { - return a; - } - - @Override - public void setA(int a) { - this.a = a; - } - - public int getCond() { - return cond; - } - - public void setCond(int cond) { - this.cond = cond; - } - - public int getCc() { - return cc; - } - - public void setCc(int cc) { - this.cc = cc; - } - - public int getP() { - return p; - } - - public void setP(int p) { - this.p = p; - } - - /** - * Return the displacement in bytes. - */ - public int getDisp19() { - return disp19 << 2; - } - - /** - * The instructions requires displacements to be word-sized. - */ - public void setDisp19(int disp19) { - this.disp19 = disp19 >> 2; - } - - @Override - public void setImm(int imm) { - setDisp19(imm); - } - - @Override - protected int getInstructionBits() { - return super.getInstructionBits() | a << A_SHIFT | cond << COND_SHIFT | cc << CC_SHIFT | p << P_SHIFT | (disp19 & DISP19_MASK) << DISP19_SHIFT; - } - - public static Fmt00c read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.BranchOp.getValue(); - - // Get the instruction fields: - final int a = (inst & A_MASK) >> A_SHIFT; - final int cond = (inst & COND_MASK) >> COND_SHIFT; - final int op2 = (inst & OP2_MASK) >> OP2_SHIFT; - final int cc = (inst & CC_MASK) >> CC_SHIFT; - final int p = (inst & P_MASK) >> P_SHIFT; - final int disp19 = (inst & DISP19_MASK) >> DISP19_SHIFT << 2; - - Fmt00c fmt = new Fmt00c(a, cond, op2, cc, p, disp19); - fmt.verify(); - return fmt; - } - - @Override - public void emit(SPARCAssembler masm) { - if (label != null) { - final int pos = label.isBound() ? label.position() : patchUnbound(masm, label); - final int disp = pos - masm.position(); - setDisp19(disp); - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - public void verify() { - super.verify(); - assert p < 2; - assert cond < 0x10; - } - - @Override - public String toString() { - return "Fmt00c [a=" + a + ", cond=" + cond + ", cc=" + cc + ", p=" + p + ", disp19=" + disp19 + ", label=" + label + "]"; - } - } - - // @formatter:off - /** - * Instruction format for Branch on Integer Register with Prediction. - *
-     * |00   |a |- |rcond | 011 |d16hi|p | rs1 |          d16lo           |
-     * |31 30|29|28|27  25|24 22|21 20|19|18 14|                         0|
-     * 
- */ - // @formatter:on - public static class Fmt00d extends Fmt00 { - - private static final int RCOND_SHIFT = 25; - private static final int D16HI_SHIFT = 20; - private static final int P_SHIFT = 19; - private static final int RS1_SHIFT = 14; - private static final int D16LO_SHIFT = 0; - - // @formatter:off - private static final int RCOND_MASK = 0b0000_1110_0000_0000_0000_0000_0000_0000; - private static final int D16HI_MASK = 0b0000_0000_0011_0000_0000_0000_0000_0000; - private static final int P_MASK = 0b0000_0000_0000_1000_0000_0000_0000_0000; - private static final int RS1_MASK = 0b0000_0000_0000_0111_1100_0000_0000_0000; - private static final int D16LO_MASK = 0b0000_0000_0000_0000_0011_1111_1111_1111; - // @formatter:on - - private int annul; - private int rCondition; - private int disp16; - private int predictTaken; - private int rs1; - private Label label; - - public Fmt00d(int op2, int rCondition, int predictTaken, int annul, int d16, int rs1, Label label) { - super(op2); - this.annul = annul; - this.rCondition = rCondition; - setDisp16(d16); - this.predictTaken = predictTaken; - this.rs1 = rs1; - this.label = label; - } - - @Override - public void setImm(int imm) { - setDisp16(imm); - } - - public void setDisp16(int disp16) { - this.disp16 = disp16 >> 2; - } - - @Override - public int getA() { - return annul; - } - - @Override - public void emit(SPARCAssembler masm) { - if (label != null) { - final int pos = label.isBound() ? label.position() : patchUnbound(masm, label); - final int disp = pos - masm.position(); - setDisp16(disp); - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - protected int getInstructionBits() { - int d16Split = 0; - d16Split |= (disp16 & 0b1100_0000_0000_0000) << D16HI_SHIFT - 14; - d16Split |= (disp16 & 0b0011_1111_1111_1111) << D16LO_SHIFT; - return super.getInstructionBits() | annul << A_SHIFT | rCondition << RCOND_SHIFT | d16Split | predictTaken << P_SHIFT | rs1 << RS1_SHIFT; - } - - public static Fmt00d read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - final int op2 = (inst & OP2_MASK) >> OP2_SHIFT; - final int condFlag = (inst & CBCOND_MASK) >> CBCOND_SHIFT; - assert op2 == Op2s.Bpr.getValue() && op == Ops.BranchOp.getValue() && condFlag == 0 : "0x" + Integer.toHexString(inst); - - // Get the instruction fields: - final int a = (inst & A_MASK) >> A_SHIFT; - final int cond = (inst & RCOND_MASK) >> RCOND_SHIFT; - final int p = (inst & P_MASK) >> P_SHIFT; - final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT; - final int d16hi = (inst & D16HI_MASK) >> D16HI_SHIFT; - assert (d16hi & ~0b11) == 0; - final int d16lo = (inst & D16LO_MASK) >> D16LO_SHIFT; - assert (d16lo & ~((1 << 14) - 1)) == 0; - final int d16 = (short) (((d16hi << 14) | d16lo) << 2); // times 4 and sign extend - Fmt00d fmt = new Fmt00d(op2, cond, p, a, d16, rs1, null); - fmt.verify(); - return fmt; - } - - @Override - public void verify() { - super.verify(); - assert (annul & ~1) == 0 : annul; - assert (rCondition & ~0b111) == 0 : rCondition; - assert isSimm(disp16, 16) : disp16; - assert (predictTaken & ~1) == 0 : predictTaken; - assert (rs1 & ~((1 << 5) - 1)) == 0 : rs1; - } - } + protected static final int DISP22_SHIFT = 0; + protected static final int DISP22_MASK = 0b00000000001111111111111111111111; + + protected static final int DISP19_SHIFT = 0; + protected static final int DISP19_MASK = 0b00000000000001111111111111111111; + + protected static final int D16HI_SHIFT = 20; + protected static final int D16HI_MASK = 0b0000_0000_0011_0000_0000_0000_0000_0000; + protected static final int D16LO_SHIFT = 0; + protected static final int D16LO_MASK = 0b0000_0000_0000_0000_0011_1111_1111_1111; // @formatter:off /** @@ -654,24 +233,24 @@ */ // @formatter:on public static class Fmt00e extends Fmt00 { - private static final int CHI_SHIFT = 29; - private static final int CLO_SHIFT = 25; - private static final int CC2_SHIFT = 21; - private static final int D10HI_SHIFT = 19; - private static final int RS1_SHIFT = 14; - private static final int I_SHIFT = 13; - private static final int D10LO_SHIFT = 5; - private static final int RS2_SHIFT = 0; + protected static final int CHI_SHIFT = 29; + protected static final int CLO_SHIFT = 25; + protected static final int CC2_SHIFT = 21; + protected static final int D10HI_SHIFT = 19; + protected static final int RS1_SHIFT = 14; + protected static final int I_SHIFT = 13; + protected static final int D10LO_SHIFT = 5; + protected static final int RS2_SHIFT = 0; // @formatter:off - private static final int CHI_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; - private static final int CLO_MASK = 0b0000_1110_0000_0000_0000_0000_0000_0000; - private static final int CC2_MASK = 0b0000_0000_0010_0000_0000_0000_0000_0000; - private static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000; - private static final int RS1_MASK = 0b0000_0000_0000_0111_1100_0000_0000_0000; - private static final int I_MASK = 0b0000_0000_0000_0000_0010_0000_0000_0000; - private static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000; - private static final int RS2_MASK = 0b0000_0000_0000_0000_0000_0000_0001_1111; + protected static final int CHI_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; + protected static final int CLO_MASK = 0b0000_1110_0000_0000_0000_0000_0000_0000; + protected static final int CC2_MASK = 0b0000_0000_0010_0000_0000_0000_0000_0000; + protected static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000; + protected static final int RS1_MASK = 0b0000_0000_0000_0111_1100_0000_0000_0000; + protected static final int I_MASK = 0b0000_0000_0000_0000_0010_0000_0000_0000; + protected static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000; + protected static final int RS2_MASK = 0b0000_0000_0000_0000_0000_0000_0001_1111; // @formatter:on private int c; @@ -809,11 +388,9 @@ // @formatter:on public static class Fmt01 { - private static final int OP_SHIFT = 30; private static final int DISP30_SHIFT = 0; // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; private static final int DISP30_MASK = 0b00111111111111111111111111111111; // @formatter:on @@ -995,7 +572,6 @@ // @formatter:on public static class Fmt10 implements AssemblerEmittable { - private static final int OP_SHIFT = 30; private static final int RD_SHIFT = 25; private static final int OP3_SHIFT = 19; private static final int RS1_SHIFT = 14; @@ -1006,7 +582,6 @@ private static final int SIMM13_SHIFT = 0; // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; private static final int RD_MASK = 0b00111110000000000000000000000000; private static final int OP3_MASK = 0b00000001111110000000000000000000; private static final int RS1_MASK = 0b00000000000001111100000000000000; @@ -1147,7 +722,6 @@ // @formatter:on public static class Fmt11 { - private static final int OP_SHIFT = 30; private static final int RD_SHIFT = 25; private static final int OP3_SHIFT = 19; private static final int RS1_SHIFT = 14; @@ -1157,7 +731,6 @@ private static final int SIMM13_SHIFT = 0; // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; private static final int RD_MASK = 0b00111110000000000000000000000000; private static final int OP3_MASK = 0b00000001111110000000000000000000; private static final int RS1_MASK = 0b00000000000001111100000000000000; @@ -1292,7 +865,6 @@ // @formatter:on public static class Fmt10c { - private static final int OP_SHIFT = 30; private static final int RD_SHIFT = 25; private static final int OP3_SHIFT = 19; private static final int CC2_SHIFT = 18; @@ -1304,7 +876,6 @@ private static final int SIMM11_SHIFT = 0; // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; private static final int RD_MASK = 0b00111110000000000000000000000000; private static final int OP3_MASK = 0b00000001111110000000000000000000; private static final int CC2_MASK = 0b00000000000001000000000000000000; @@ -1417,7 +988,6 @@ // @formatter:on public static class Fmt10d implements AssemblerEmittable { - private static final int OP_SHIFT = 30; private static final int RD_SHIFT = 25; private static final int OP3_SHIFT = 19; private static final int COND_SHIFT = 14; @@ -1895,6 +1465,26 @@ } } + public enum Annul { + ANNUL(1), + NOT_ANNUL(0); + public final int flag; + + Annul(int flag) { + this.flag = flag; + } + } + + public enum BranchPredict { + PREDICT_TAKEN(1), + PREDICT_NOT_TAKEN(0); + public final int flag; + + BranchPredict(int flag) { + this.flag = flag; + } + } + public enum MembarMask { // @formatter:off @@ -1961,40 +1551,21 @@ public String getOperator() { return operator; } - } - - public enum FCond { - Fba(0x8, "fba"), - Fbn(0x0, "fbn"), - Fbu(0x7, "fbu"), - Fbg(0x6, "fbg"), - Fbug(0x5, "fbug"), - Fbl(0x4, "fbl"), - Fbul(0x3, "fbul"), - Fblg(0x2, "fblg"), - Fbne(0x1, "fbne"), - Fbe(0x9, "fbe"), - Fbue(0xA, "fbue"), - Fbge(0xB, "fbge"), - Fbuge(0xC, "fbuge"), - Fble(0xD, "fble"), - Fbule(0xE, "fbule"), - Fbo(0xF, "fbo"); - private final int value; - private final String operator; - - private FCond(int value, String op) { - assert value >= 0 && value < 1 << 5 : value; // 4 bits - this.value = value; - this.operator = op; - } - - public int getValue() { - return value; - } - - public String getOperator() { - return operator; + + public static CC forKind(Kind kind) { + boolean isInt = kind == Kind.Boolean || kind == Kind.Byte || kind == Kind.Char || kind == Kind.Short || kind == Kind.Int; + boolean isFloat = kind == Kind.Float || kind == Kind.Double; + boolean isLong = kind == Kind.Long || kind == Kind.Object; + assert isInt || isFloat || isLong; + if (isLong) { + return Xcc; + } else if (isInt) { + return Icc; + } else if (isFloat) { + return Fcc0; + } else { + throw GraalInternalError.shouldNotReachHere(); + } } } @@ -2115,31 +1686,56 @@ return null; } + public ConditionFlag mirror() { + switch (this) { + //@formatter:off + case F_Less : return F_Greater; + case F_Greater : return F_Less; + case F_LessOrEqual : return F_GreaterOrEqual; + case F_UnorderedGreaterOrEqual: return F_UnorderedOrLessOrEqual; + case F_UnorderedOrGreater : return F_UnorderedOrLess; + case F_UnorderedOrLessOrEqual : return F_UnorderedGreaterOrEqual; + case F_GreaterOrEqual : return F_LessOrEqual; + case F_UnorderedOrLess : return F_UnorderedOrGreater; + case LessEqual : return GreaterEqual; + case Greater : return Less; + case Less : return Greater; + case GreaterEqual : return LessEqual; + case LessEqualUnsigned : return GreaterEqualUnsigned; + case GreaterUnsigned : return LessUnsigned; + case LessUnsigned : return GreaterUnsigned; + case GreaterEqualUnsigned : return LessEqualUnsigned; + default: + return this; + //@formatter:on + } + } + public static ConditionFlag fromCondtition(CC conditionFlagsRegister, Condition cond, boolean unorderedIsTrue) { switch (conditionFlagsRegister) { case Xcc: case Icc: switch (cond) { case EQ: - return ConditionFlag.Equal; + return Equal; case NE: - return ConditionFlag.NotEqual; + return NotEqual; case BT: - return ConditionFlag.LessUnsigned; + return LessUnsigned; case LT: - return ConditionFlag.Less; + return Less; case BE: - return ConditionFlag.LessEqualUnsigned; + return LessEqualUnsigned; case LE: - return ConditionFlag.LessEqual; + return LessEqual; case AE: - return ConditionFlag.GreaterEqualUnsigned; + return GreaterEqualUnsigned; case GE: - return ConditionFlag.GreaterEqual; + return GreaterEqual; case AT: - return ConditionFlag.GreaterUnsigned; + return GreaterUnsigned; case GT: - return ConditionFlag.Greater; + return Greater; } throw GraalInternalError.shouldNotReachHere("Unimplemented for: " + cond); case Fcc0: @@ -2148,17 +1744,17 @@ case Fcc3: switch (cond) { case EQ: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrEqual : ConditionFlag.F_Equal; + return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal; case NE: return ConditionFlag.F_NotEqual; case LT: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrLess : ConditionFlag.F_Less; + return unorderedIsTrue ? F_UnorderedOrLess : F_Less; case LE: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrLessOrEqual : ConditionFlag.F_LessOrEqual; + return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual; case GE: - return unorderedIsTrue ? ConditionFlag.F_UnorderedGreaterOrEqual : ConditionFlag.F_GreaterOrEqual; + return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual; case GT: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrGreater : ConditionFlag.F_Greater; + return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater; } throw GraalInternalError.shouldNotReachHere("Unkown condition: " + cond); } @@ -2256,6 +1852,11 @@ return x & ((1 << nbits) - 1); } + public static final boolean isImm(int x, int nbits) { + // assert_signed_range(x, nbits); + return simm(x, nbits) == x; + } + /** * Minimum value for signed immediate ranges. */ @@ -2317,6 +1918,149 @@ return x & ((1 << 10) - 1); } + // @formatter:off + /** + * Instruction format for Fmt00 instructions. This abstraction is needed as it + * makes the patching easier later on. + *
+     * | 00  |    a   | op2 |               b                         |
+     * |31 30|29    25|24 22|21                                      0|
+     * 
+ */ + // @formatter:on + protected void fmt00(int a, int op2, int b) { + assert isImm(a, 5) && isImm(op2, 3) && isImm(b, 22) : String.format("a: 0x%x op2: 0x%x b: 0x%x", a, op2, b); + this.emitInt(a << 25 | op2 << 22 | b); + } + + // @formatter:off + /** + * Branch on Integer Condition Codes. + *
+     * | 00  |annul| cond| 010 |               disp22                 |
+     * |31 30|29   |28 25|24 22|21                                   0|
+     * 
+ */ + // @formatter:on + public void bicc(ConditionFlag cond, Annul annul, Label l) { + bcc(Op2s.Br, cond, annul, l); + } + + // @formatter:off + /** + * Branch on Floating-Point Condition Codes. + *
+     * | 00  |annul| cond| 110 |               disp22                 |
+     * |31 30|29   |28 25|24 22|21                                   0|
+     * 
+ */ + // @formatter:on + public void fbcc(ConditionFlag cond, Annul annul, Label l) { + bcc(Op2s.Fb, cond, annul, l); + } + + // @formatter:off + /** + * Branch on (Integer|Floatingpoint) Condition Codes + *
+     * | 00  |annul| cond| op2 |               disp22                 |
+     * |31 30|29   |28 25|24 22|21                                   0|
+     * 
+ */ + // @formatter:on + private void bcc(Op2s op2, ConditionFlag cond, Annul annul, Label l) { + int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + final int disp = 22; + assert isSimm(pos, disp); + pos &= (1 << disp) - 1; + int a = (annul.flag << 4) | cond.getValue(); + fmt00(a, op2.getValue(), pos); + } + + // @formatter:off + /** + * Branch on Integer Condition Codes with Prediction. + *
+     * | 00  |an|cond | 001 |cc1 2|p |           disp19               |
+     * |31 30|29|28 25|24 22|21 20|19|                               0|
+     * 
+ */ + // @formatter:on + public void bpcc(ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + bpcc(Op2s.Bp, cond, annul, l, cc, predictTaken); + } + + // @formatter:off + /** + * Branch on Integer Condition Codes with Prediction. + *
+     * | 00  |an|cond | 101 |cc1 2|p |           disp19               |
+     * |31 30|29|28 25|24 22|21 20|19|                               0|
+     * 
+ */ + // @formatter:on + public void fbpcc(ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + bpcc(Op2s.Fbp, cond, annul, l, cc, predictTaken); + } + + // @formatter:off + /** + * Used for fbpcc (Float) and bpcc (Integer) + *
+     * | 00  |an|cond | op2 |cc1 2|p |           disp19               |
+     * |31 30|29|28 25|24 22|21 20|19|                               0|
+     * 
+ */ + // @formatter:on + private void bpcc(Op2s op2, ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + final int disp = 19; + assert isSimm(pos, disp); + pos &= (1 << disp) - 1; + int a = (annul.flag << 4) | cond.getValue(); + int b = (cc.getValue() << 20) | ((predictTaken.flag) << 19) | pos; + fmt00(a, op2.getValue(), b); + } + + // @formatter:off + /** + * Branch on Integer Register with Prediction. + *
+     * | 00  |an| 0|rcond | 011 |d16hi|p | rs1 |    d16lo             |
+     * |31 30|29|28|27 25 |24 22|21 20|19|18 14|                     0|
+     * 
+ */ + // @formatter:on + public void bpr(RCondition cond, Annul annul, Label l, BranchPredict predictTaken, Register rs1) { + int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + final int disp = 16; + assert isSimm(pos, disp); + pos &= (1 << disp) - 1; + int a = (annul.flag << 4) | cond.getValue(); + int d16hi = (pos >> 13) << 13; + int d16lo = d16hi ^ pos; + int b = (d16hi << 20) | (predictTaken.flag << 19) | (rs1.encoding() << 14) | d16lo; + fmt00(a, Op2s.Bpr.getValue(), b); + } + + // @formatter:off + /** + * NOP. + *
+     * | 00  |00000| 100 |                0                    |
+     * |31 30|29 25|24 22|21                                  0|
+     * 
+ */ + // @formatter:on + public void nop() { + emitInt(1 << 24); + } + + private int patchUnbound(Label label) { + label.addPatchAt(position()); + return 0; + } + public static class Add extends Fmt10 { public Add(Register src1, int simm13, Register dst) { @@ -2592,232 +2336,6 @@ } } - public static class Bpr extends Fmt00d { - public Bpr(RCondition rcond, boolean annul, boolean predictTaken, Register rs1, Label label) { - super(Op2s.Bpr.getValue(), rcond.getValue(), predictTaken ? 1 : 0, annul ? 1 : 0, 0, rs1.encoding(), label); - } - } - - public static class Bpa extends Fmt00c { - - public Bpa(int simm19) { - super(0, ConditionFlag.Always, Op2s.Bp, CC.Icc, 1, simm19); - } - - public Bpa(Label label) { - super(0, ConditionFlag.Always, Op2s.Bp, CC.Icc, 1, label); - } - } - - public static class Bpcc extends Fmt00c { - - public Bpcc(CC cc, int simm19) { - super(0, ConditionFlag.CarryClear, Op2s.Bp, cc, 1, simm19); - } - - public Bpcc(CC cc, Label label) { - super(0, ConditionFlag.CarryClear, Op2s.Bp, cc, 1, label); - } - - public Bpcc(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.CarryClear, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpcs extends Fmt00c { - - public Bpcs(CC cc, int simm19) { - super(0, ConditionFlag.CarrySet, Op2s.Bp, cc, 1, simm19); - } - - public Bpcs(CC cc, Label label) { - super(0, ConditionFlag.CarrySet, Op2s.Bp, cc, 1, label); - } - - public Bpcs(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.CarrySet, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpe extends Fmt00c { - - public Bpe(CC cc, int simm19) { - super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, simm19); - } - - public Bpe(CC cc, Label label, boolean predictTaken) { - super(0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - - public Bpe(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - - public Bpe(CC cc, Label label) { - super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, label); - } - } - - public static class Bpg extends Fmt00c { - - public Bpg(CC cc, int simm19) { - super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, simm19); - } - - public Bpg(CC cc, Label label) { - super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, label); - } - - public Bpg(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.Greater, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpge extends Fmt00c { - - public Bpge(CC cc, int simm19) { - super(0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, 1, simm19); - } - - public Bpge(CC cc, Label label) { - super(0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, 1, label); - } - - public Bpge(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpgu extends Fmt00c { - - public Bpgu(CC cc, int simm19) { - super(0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, 1, simm19); - } - - public Bpgu(CC cc, Label label) { - super(0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, 1, label); - } - - public Bpgu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpl extends Fmt00c { - - public Bpl(CC cc, int simm19) { - super(0, ConditionFlag.Less, Op2s.Bp, cc, 1, simm19); - } - - public Bpl(CC cc, Label label) { - super(0, ConditionFlag.Less, Op2s.Bp, cc, 1, label); - } - - public Bpl(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.Less, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bple extends Fmt00c { - - public Bple(CC cc, int simm19) { - super(0, ConditionFlag.LessEqual, Op2s.Bp, cc, 1, simm19); - } - - public Bple(CC cc, Label label) { - super(0, ConditionFlag.LessEqual, Op2s.Bp, cc, 1, label); - } - - public Bple(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.LessEqual, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpleu extends Fmt00c { - - public Bpleu(CC cc, int simm19) { - super(0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, 1, simm19); - } - - public Bpleu(CC cc, Label label) { - super(0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, 1, label); - } - - public Bpleu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpn extends Fmt00c { - - public Bpn(CC cc, int simm19) { - super(0, ConditionFlag.Never, Op2s.Bp, cc, 1, simm19); - } - - public Bpn(CC cc, Label label) { - super(0, ConditionFlag.Never, Op2s.Bp, cc, 1, label); - } - } - - public static class Bpne extends Fmt00c { - - public Bpne(CC cc, int simm19) { - super(0, ConditionFlag.NotZero, Op2s.Bp, cc, 1, simm19); - } - - public Bpne(CC cc, Label label) { - super(0, ConditionFlag.NotZero, Op2s.Bp, cc, 1, label); - } - - public Bpne(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.NotZero, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpneg extends Fmt00c { - - public Bpneg(CC cc, int simm19) { - super(0, ConditionFlag.Negative, Op2s.Bp, cc, 1, simm19); - } - - public Bpneg(CC cc, Label label) { - super(0, ConditionFlag.Negative, Op2s.Bp, cc, 1, label); - } - } - - public static class Bppos extends Fmt00c { - - public Bppos(CC cc, int simm19) { - super(0, ConditionFlag.Positive, Op2s.Bp, cc, 1, simm19); - } - - public Bppos(CC cc, Label label) { - super(0, ConditionFlag.Positive, Op2s.Bp, cc, 1, label); - } - } - - public static class Bpvc extends Fmt00c { - - public Bpvc(CC cc, int simm19) { - super(0, ConditionFlag.OverflowClear, Op2s.Bp, cc, 1, simm19); - } - - public Bpvc(CC cc, Label label) { - super(0, ConditionFlag.OverflowClear, Op2s.Bp, cc, 1, label); - } - } - - public static class Bpvs extends Fmt00c { - - public Bpvs(CC cc, int simm19) { - super(0, ConditionFlag.OverflowSet, Op2s.Bp, cc, 1, simm19); - } - - public Bpvs(CC cc, Label label) { - super(0, ConditionFlag.OverflowSet, Op2s.Bp, cc, 1, label); - } - } - public static class Bshuffle extends Fmt3p { public Bshuffle(Register src1, Register src2, Register dst) { @@ -3664,166 +3182,6 @@ } } - public static class Fba extends Fmt00b { - public Fba(boolean annul, Label label) { - super(annul, FCond.Fba, Op2s.Fb, label); - } - - public Fba(boolean annul, int disp) { - super(annul, FCond.Fba, Op2s.Fb, disp); - } - } - - public static class Fbn extends Fmt00b { - public Fbn(boolean annul, Label label) { - super(annul, FCond.Fbn, Op2s.Fb, label); - } - - public Fbn(boolean annul, int disp) { - super(annul, FCond.Fbn, Op2s.Fb, disp); - } - } - - public static class Fbu extends Fmt00b { - public Fbu(boolean annul, Label label) { - super(annul, FCond.Fbu, Op2s.Fb, label); - } - - public Fbu(boolean annul, int disp) { - super(annul, FCond.Fbu, Op2s.Fb, disp); - } - } - - public static class Fbg extends Fmt00b { - public Fbg(boolean annul, Label label) { - super(annul, FCond.Fbg, Op2s.Fb, label); - } - - public Fbg(boolean annul, int disp) { - super(annul, FCond.Fbg, Op2s.Fb, disp); - } - } - - public static class Fbug extends Fmt00b { - public Fbug(boolean annul, Label label) { - super(annul, FCond.Fbug, Op2s.Fb, label); - } - - public Fbug(boolean annul, int disp) { - super(annul, FCond.Fbug, Op2s.Fb, disp); - } - } - - public static class Fbl extends Fmt00b { - public Fbl(boolean annul, Label label) { - super(annul, FCond.Fbl, Op2s.Fb, label); - } - - public Fbl(boolean annul, int disp) { - super(annul, FCond.Fbl, Op2s.Fb, disp); - } - } - - public static class Fbul extends Fmt00b { - public Fbul(boolean annul, Label label) { - super(annul, FCond.Fbul, Op2s.Fb, label); - } - - public Fbul(boolean annul, int disp) { - super(annul, FCond.Fbul, Op2s.Fb, disp); - } - } - - public static class Fblg extends Fmt00b { - public Fblg(boolean annul, Label label) { - super(annul, FCond.Fblg, Op2s.Fb, label); - } - - public Fblg(boolean annul, int disp) { - super(annul, FCond.Fblg, Op2s.Fb, disp); - } - } - - public static class Fbne extends Fmt00b { - public Fbne(boolean annul, Label label) { - super(annul, FCond.Fbne, Op2s.Fb, label); - } - - public Fbne(boolean annul, int disp) { - super(annul, FCond.Fbne, Op2s.Fb, disp); - } - } - - public static class Fbe extends Fmt00b { - public Fbe(boolean annul, Label label) { - super(annul, FCond.Fbe, Op2s.Fb, label); - } - - public Fbe(boolean annul, int disp) { - super(annul, FCond.Fbe, Op2s.Fb, disp); - } - } - - public static class Fbue extends Fmt00b { - public Fbue(boolean annul, Label label) { - super(annul, FCond.Fbue, Op2s.Fb, label); - } - - public Fbue(boolean annul, int disp) { - super(annul, FCond.Fbue, Op2s.Fb, disp); - } - } - - public static class Fbge extends Fmt00b { - public Fbge(boolean annul, Label label) { - super(annul, FCond.Fbge, Op2s.Fb, label); - } - - public Fbge(boolean annul, int disp) { - super(annul, FCond.Fbge, Op2s.Fb, disp); - } - } - - public static class Fbuge extends Fmt00b { - public Fbuge(boolean annul, Label label) { - super(annul, FCond.Fbuge, Op2s.Fb, label); - } - - public Fbuge(boolean annul, int disp) { - super(annul, FCond.Fbuge, Op2s.Fb, disp); - } - } - - public static class Fble extends Fmt00b { - public Fble(boolean annul, Label label) { - super(annul, FCond.Fble, Op2s.Fb, label); - } - - public Fble(boolean annul, int disp) { - super(annul, FCond.Fble, Op2s.Fb, disp); - } - } - - public static class Fbule extends Fmt00b { - public Fbule(boolean annul, Label label) { - super(annul, FCond.Fbule, Op2s.Fb, label); - } - - public Fbule(boolean annul, int disp) { - super(annul, FCond.Fbule, Op2s.Fb, disp); - } - } - - public static class Fbo extends Fmt00b { - public Fbo(boolean annul, Label label) { - super(annul, FCond.Fbo, Op2s.Fb, label); - } - - public Fbo(boolean annul, int disp) { - super(annul, FCond.Fbo, Op2s.Fb, disp); - } - } - public static class Illtrap extends Fmt00a { public Illtrap(int const22) { diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Fri Feb 27 09:18:23 2015 +0100 @@ -22,10 +22,13 @@ */ package com.oracle.graal.asm.sparc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; public class SPARCMacroAssembler extends SPARCAssembler { @@ -48,16 +51,58 @@ @Override public void jmp(Label l) { - new Bpa(l).emit(this); + bicc(Always, NOT_ANNUL, l); new Nop().emit(this); // delay slot } @Override protected final void patchJumpTarget(int branch, int branchTarget) { - final int disp = branchTarget - branch; - Fmt00 fmt = Fmt00.read(this, branch); - fmt.setImm(disp); - fmt.write(this, branch); + final int disp = (branchTarget - branch) / 4; + final int inst = getInt(branch); + Op2s op2 = Op2s.byValue((inst & OP2_MASK) >> OP2_SHIFT); + int maskBits; + int setBits; + switch (op2) { + case Br: + case Fb: + case Sethi: + case Illtrap: + // Disp 22 in the lower 22 bits + assert isSimm(disp, 22); + setBits = disp << DISP22_SHIFT; + maskBits = DISP22_MASK; + break; + case Fbp: + case Bp: + // Disp 19 in the lower 19 bits + assert isSimm(disp, 19); + setBits = disp << DISP19_SHIFT; + maskBits = DISP19_MASK; + break; + case Bpr: + boolean isCBcond = (inst & CBCOND_MASK) != 0; + if (isCBcond) { + assert isSimm10(disp); + int d10Split = 0; + d10Split |= (disp & 0b11_0000_0000) << Fmt00e.D10HI_SHIFT - 8; + d10Split |= (disp & 0b00_1111_1111) << Fmt00e.D10LO_SHIFT; + setBits = d10Split; + maskBits = Fmt00e.D10LO_MASK | Fmt00e.D10HI_MASK; + } else { + assert isSimm(disp, 16); + int d16Split = 0; + d16Split |= (disp & 0b1100_0000_0000_0000) << D16HI_SHIFT - 14; + d16Split |= (disp & 0b0011_1111_1111_1111) << D16LO_SHIFT; + setBits = d16Split; + maskBits = D16HI_MASK | D16LO_MASK; + } + break; + default: + throw GraalInternalError.shouldNotReachHere("Unknown op2 " + op2); + } + int newInst = ~maskBits & inst; + newInst |= setBits; + emitInt(newInst, branch); } @Override @@ -86,36 +131,6 @@ } } - public static class Bpgeu extends Bpcc { - - public Bpgeu(CC cc, int simm19) { - super(cc, simm19); - } - - public Bpgeu(CC cc, Label label) { - super(cc, label); - } - - public Bpgeu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(cc, annul, predictTaken, label); - } - } - - public static class Bplu extends Bpcs { - - public Bplu(CC cc, int simm19) { - super(cc, simm19); - } - - public Bplu(CC cc, Label label) { - super(cc, label); - } - - public Bplu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(cc, annul, predictTaken, label); - } - } - public static class Bset extends Or { public Bset(Register src, Register dst) { diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Feb 27 09:18:23 2015 +0100 @@ -215,7 +215,7 @@ double trueDestinationProbability) { Variable left; Value right; - Condition actualCondition = null; + Condition actualCondition; if (isConstant(x)) { left = load(y); right = loadNonConst(x); @@ -225,7 +225,7 @@ right = loadNonConst(y); actualCondition = cond; } - SPARCCompare opcode = null; + SPARCCompare opcode; Kind kind = left.getKind().getStackKind(); switch (kind) { case Object: @@ -247,7 +247,7 @@ opcode = DCMP; break; default: - GraalInternalError.shouldNotReachHere(kind.toString()); + throw GraalInternalError.shouldNotReachHere(kind.toString()); } append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, kind, unorderedIsTrue, trueDestinationProbability)); } @@ -255,13 +255,13 @@ @Override public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { Kind cmpKind = (Kind) cmpLIRKind.getPlatformKind(); - append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind)); + 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(Condition.EQ, trueDestination, falseDestination, left.getKind().getStackKind())); + append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, left.getKind().getStackKind(), trueDestinationProbability)); } private void emitIntegerTest(Value a, Value b) { diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Feb 27 09:18:23 2015 +0100 @@ -24,6 +24,10 @@ import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.sparc.SPARC.*; @@ -34,11 +38,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Bpne; -import com.oracle.graal.asm.sparc.SPARCAssembler.CC; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; -import com.oracle.graal.asm.sparc.SPARCAssembler.Save; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow; @@ -239,7 +239,7 @@ new Ldx(src, scratch).emit(masm); new Cmp(scratch, inlineCacheKlass).emit(masm); } - new Bpne(CC.Xcc, unverifiedStub).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, unverifiedStub, Xcc, PREDICT_NOT_TAKEN); new Nop().emit(masm); // delay slot } diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Feb 27 09:18:23 2015 +0100 @@ -24,7 +24,12 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -216,9 +221,9 @@ // Now construct the lower half and compare new Srax(asLongReg(result), 63, asLongReg(scratch2)).emit(masm); new Cmp(asLongReg(scratch1), asLongReg(scratch2)).emit(masm); - new Bpe(CC.Xcc, false, true, noOverflow).emit(masm); + masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN); new Nop().emit(masm); - new Wrccr(SPARC.g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm); + new Wrccr(g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm); masm.bind(noOverflow); } } @@ -367,7 +372,7 @@ new Nop().emit(masm); } else { new Cmp(tmp, asIntReg(dst)).emit(masm); - new Bpe(CC.Xcc, noOverflow).emit(masm); + masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN); new Nop().emit(masm); } new Wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)).emit(masm); @@ -704,14 +709,14 @@ break; case F2L: new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm); - new Fbo(true, notOrdered).emit(masm); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); new Fstox(asFloatReg(src), asDoubleReg(dst)).emit(masm); new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); masm.bind(notOrdered); break; case F2I: new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm); - new Fbo(true, notOrdered).emit(masm); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); new Fstoi(asFloatReg(src), asFloatReg(dst)).emit(masm); new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm); new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); @@ -719,7 +724,7 @@ break; case D2L: new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); - new Fbo(false, notOrdered).emit(masm); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); new Fdtox(asDoubleReg(src), asDoubleReg(dst)).emit(masm); new Fxtod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm); new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); @@ -727,7 +732,7 @@ break; case D2I: new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); - new Fbo(true, notOrdered).emit(masm); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); new Fdtoi(asDoubleReg(src), asFloatReg(dst)).emit(masm); new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); new Fstoi(asFloatReg(dst), asFloatReg(dst)).emit(masm); diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Fri Feb 27 09:18:23 2015 +0100 @@ -27,7 +27,11 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*; import java.lang.reflect.*; @@ -107,7 +111,7 @@ // Return true masm.bind(trueLabel); new Mov(1, result).emit(masm); - new Bpa(done).emit(masm); + masm.bicc(Always, ANNUL, done); new Nop().emit(masm); // Return false @@ -138,7 +142,7 @@ new And(result, VECTOR_SIZE - 1, result).emit(masm); // tail count (in bytes) new Andcc(length, ~(VECTOR_SIZE - 1), length).emit(masm); // vector count (in bytes) - new Bpe(CC.Xcc, compareTail).emit(masm); + masm.bpcc(ConditionFlag.Equal, NOT_ANNUL, compareTail, CC.Xcc, PREDICT_NOT_TAKEN); new Sub(length, VECTOR_SIZE, length).emit(masm); // Delay slot new Add(array1, length, array1).emit(masm); @@ -155,9 +159,9 @@ new Nop().emit(masm); // for optimal performance (see manual) } else { new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, true, false, falseLabel).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); new Nop().emit(masm); - new Bpr(RCondition.Rc_z, false, false, length, compareTailCorrectVectorEnd).emit(masm); + masm.bpr(Rc_z, NOT_ANNUL, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, length); new Nop().emit(masm); } @@ -166,17 +170,18 @@ masm.bind(loop); new Ldx(new SPARCAddress(array2, length), tempReg2).emit(masm); new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, false, false, falseLabel).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); // Delay slot, not annul, add for next iteration new Addcc(length, VECTOR_SIZE, length).emit(masm); - new Bpne(Xcc, true, true, loop).emit(masm); // Annul, to prevent access past the array + // Annul, to prevent access past the array + masm.bpcc(NotEqual, ANNUL, loop, Xcc, PREDICT_TAKEN); new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm); // Load in delay slot // Tail count zero, therefore we can go to the end if (hasCBcond) { new CBcondx(ConditionFlag.Equal, result, 0, trueLabel).emit(masm); } else { - new Bpr(RCondition.Rc_z, true, true, result, trueLabel).emit(masm); + masm.bpr(Rc_z, NOT_ANNUL, trueLabel, PREDICT_TAKEN, result); new Nop().emit(masm); } @@ -205,7 +210,7 @@ new CBcondx(ConditionFlag.Less, result, 4, compare2Bytes).emit(masm); } else { new Cmp(result, 4).emit(masm); - new Bpl(Xcc, false, false, compare2Bytes).emit(masm); + masm.bpcc(Less, NOT_ANNUL, compare2Bytes, Xcc, PREDICT_NOT_TAKEN); new Nop().emit(masm); } @@ -216,7 +221,7 @@ new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); } else { new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, false, false, falseLabel).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); new Nop().emit(masm); } @@ -233,7 +238,7 @@ new CBcondx(ConditionFlag.Less, result, 2, compare1Byte).emit(masm); } else { new Cmp(result, 2).emit(masm); - new Bpl(Xcc, false, true, compare1Byte).emit(masm); + masm.bpcc(Less, NOT_ANNUL, compare1Byte, Xcc, PREDICT_TAKEN); new Nop().emit(masm); } @@ -244,7 +249,7 @@ new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); } else { new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, false, true, falseLabel).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN); new Nop().emit(masm); } @@ -261,17 +266,16 @@ new CBcondx(ConditionFlag.NotEqual, result, 1, trueLabel).emit(masm); } else { new Cmp(result, 1).emit(masm); - new Bpne(Xcc, trueLabel).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, trueLabel, Xcc, PREDICT_TAKEN); new Nop().emit(masm); } new Ldub(new SPARCAddress(array1, 0), tempReg1).emit(masm); new Ldub(new SPARCAddress(array2, 0), tempReg2).emit(masm); if (hasCBcond) { - // new SPARCAssembler.Ldx(new SPARCAddress(o7, 1), g3).emit(masm); new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); } else { new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, falseLabel).emit(masm); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN); new Nop().emit(masm); } } else { diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Feb 27 09:18:23 2015 +0100 @@ -26,6 +26,10 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -67,7 +71,7 @@ private final SPARCCompare opcode; @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; - protected final Condition condition; + private ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected LabelHint trueDestinationHint; protected final LabelRef falseDestination; @@ -86,12 +90,13 @@ this.opcode = opcode; this.x = x; this.y = y; - this.condition = condition; this.trueDestination = trueDestination; this.falseDestination = falseDestination; this.kind = kind; this.unorderedIsTrue = unorderedIsTrue; this.trueDestinationProbability = trueDestinationProbability; + CC conditionCodeReg = CC.forKind(kind); + conditionFlag = ConditionFlag.fromCondtition(conditionCodeReg, condition, unorderedIsTrue); } @Override @@ -101,24 +106,32 @@ } if (!emitted) { requestHints(masm); - if (canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) { + int targetPosition = getTargetPosition(masm); + if (canUseShortBranch(crb, masm, targetPosition)) { emitted = emitShortCompareBranch(crb, masm); } - if (!emitted) { + if (!emitted) { // No short compare/branch was used, so we go into fallback SPARCCompare.emit(crb, masm, opcode, x, y); - emitted = emitBranch(crb, masm, true); + emitted = emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability); } } + assert emitted; + } - assert emitted; + private static int getTargetPosition(Assembler asm) { + return asm.position() + maximumSelfOffsetInstructions * asm.target.wordSize; } public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { requestHints(masm); // When we use short branches, no delay slot is available - if (!canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) { + int targetPosition = getTargetPosition(masm); + if (!canUseShortBranch(crb, masm, targetPosition)) { SPARCCompare.emit(crb, masm, opcode, x, y); - emitted = emitBranch(crb, masm, false); + emitted = emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, false, trueDestinationProbability); + if (emitted) { + delaySlotPosition = masm.position(); + } } } @@ -129,7 +142,6 @@ if (falseDestinationHint == null) { this.falseDestinationHint = masm.requestLabelHint(falseDestination.label()); } - } /** @@ -166,24 +178,25 @@ Value tmpValue; Value actualX = x; Value actualY = y; - Condition actualCondition = condition; + ConditionFlag actualConditionFlag = conditionFlag; Label actualTrueTarget = trueDestination.label(); Label actualFalseTarget = falseDestination.label(); Label tmpTarget; boolean needJump; if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = actualCondition.negate(); + actualConditionFlag = conditionFlag.negate(); tmpTarget = actualTrueTarget; actualTrueTarget = actualFalseTarget; actualFalseTarget = tmpTarget; needJump = false; } else { needJump = !crb.isSuccessorEdge(falseDestination); - if (needJump && !isShortBranch(masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize, trueDestinationHint, actualTrueTarget)) { + int targetPosition = getTargetPosition(masm); + if (needJump && !isShortBranch(masm, targetPosition, trueDestinationHint, actualTrueTarget)) { // we have to jump in either way, so we must put the shorter // branch into the actualTarget as only one of the two jump targets // is guaranteed to be simm10 - actualCondition = actualCondition.negate(); + actualConditionFlag = actualConditionFlag.negate(); tmpTarget = actualTrueTarget; actualTrueTarget = actualFalseTarget; actualFalseTarget = tmpTarget; @@ -194,9 +207,8 @@ tmpValue = actualX; actualX = actualY; actualY = tmpValue; - actualCondition = actualCondition.mirror(); + actualConditionFlag = actualConditionFlag.mirror(); } - ConditionFlag conditionFlag = ConditionFlag.fromCondtition(CC.Icc, actualCondition, false); boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY)); SPARCScratchRegister scratch = null; try { @@ -206,7 +218,7 @@ SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY); actualY = scratchValue; } - emitCBCond(masm, actualX, actualY, actualTrueTarget, conditionFlag); + emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag); new Nop().emit(masm); } finally { if (scratch != null) { @@ -256,46 +268,6 @@ } } - public boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, boolean withDelayedNop) { - Label actualTarget; - Condition actualCondition; - boolean branchOnUnordered; - boolean needJump; - boolean predictBranchTaken; - if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = condition != null ? condition.negate() : null; - actualTarget = falseDestination.label(); - predictBranchTaken = trueDestinationProbability < .5; // false branch needs jump - needJump = false; - branchOnUnordered = !unorderedIsTrue; - } else { - actualCondition = condition; - actualTarget = trueDestination.label(); - needJump = !crb.isSuccessorEdge(falseDestination); - predictBranchTaken = trueDestinationProbability >= .5; - branchOnUnordered = unorderedIsTrue; - } - if (!withDelayedNop && needJump) { - // We cannot make use of the delay slot when we jump in true-case and false-case - return false; - } - if (kind == Kind.Double || kind == Kind.Float) { - emitFloatBranch(masm, actualTarget, actualCondition, branchOnUnordered); - } else { - CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; - assert actualCondition != null; - SPARCControlFlow.emitBranch(masm, actualTarget, actualCondition, cc, predictBranchTaken); - } - delaySlotPosition = masm.position(); - if (withDelayedNop) { - new Nop().emit(masm); // delay slot - } - if (needJump) { - masm.jmp(falseDestination.label()); - } - return true; // emitted - } - private boolean canUseShortBranch(CompilationResultBuilder crb, SPARCAssembler asm, int position) { if (!asm.hasFeature(CPUFeature.CBCOND)) { return false; @@ -349,172 +321,61 @@ } public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { - // TODO: Condition code/flag handling needs to be improved; - protected final Condition condition; protected final ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected final LabelRef falseDestination; protected final Kind kind; - protected final boolean unorderedIsTrue; + protected final double trueDestinationProbability; - public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) { - this.conditionFlag = condition; + public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, Kind kind, double trueDestinationProbability) { this.trueDestination = trueDestination; this.falseDestination = falseDestination; this.kind = kind; - this.condition = null; - this.unorderedIsTrue = true; - } - - public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) { - this.condition = condition; - this.trueDestination = trueDestination; - this.falseDestination = falseDestination; - this.kind = kind; - this.conditionFlag = null; - this.unorderedIsTrue = true; - } - - public BranchOp(Condition finalCondition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue) { - this.trueDestination = trueDestination; - this.falseDestination = falseDestination; - this.kind = kind; - this.conditionFlag = null; - this.unorderedIsTrue = unorderedIsTrue; - this.condition = finalCondition; + this.conditionFlag = conditionFlag; + this.trueDestinationProbability = trueDestinationProbability; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - assert condition == null && conditionFlag != null || condition != null && conditionFlag == null; - Label actualTarget; - Condition actualCondition; - ConditionFlag actualConditionFlag; - boolean branchOnUnordered; - boolean needJump; - if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = condition != null ? condition.negate() : null; - actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null; - actualTarget = falseDestination.label(); - needJump = false; - branchOnUnordered = !unorderedIsTrue; - } else { - actualCondition = condition; - actualConditionFlag = conditionFlag; - actualTarget = trueDestination.label(); - needJump = !crb.isSuccessorEdge(falseDestination); - branchOnUnordered = unorderedIsTrue; - } - assert kind == Kind.Int || kind == Kind.Long || kind == Kind.Object || kind == Kind.Double || kind == Kind.Float : kind; - if (kind == Kind.Double || kind == Kind.Float) { - emitFloatBranch(masm, actualTarget, actualCondition, branchOnUnordered); - } else { - CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; - if (actualCondition != null) { - emitBranch(masm, actualTarget, actualCondition, cc, false); - } else if (actualConditionFlag != null) { - emitBranch(masm, actualTarget, actualConditionFlag, cc); - } else { - GraalInternalError.shouldNotReachHere(); - } - } - new Nop().emit(masm); // delay slot - if (needJump) { - masm.jmp(falseDestination.label()); - } + emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability); } } - private static void emitFloatBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, boolean branchOnUnordered) { - switch (actualCondition) { - case EQ: - if (branchOnUnordered) { - new Fbue(false, target).emit(masm); - } else { - new Fbe(false, target).emit(masm); - } - break; - case NE: - new Fbne(false, target).emit(masm); // Is also unordered - break; - case LT: - if (branchOnUnordered) { - new Fbul(false, target).emit(masm); - } else { - new Fbl(false, target).emit(masm); - } - break; - case LE: - if (branchOnUnordered) { - new Fbule(false, target).emit(masm); - } else { - new Fble(false, target).emit(masm); - } - break; - case GT: - if (branchOnUnordered) { - new Fbug(false, target).emit(masm); - } else { - new Fbg(false, target).emit(masm); - } - break; - case GE: - if (branchOnUnordered) { - new Fbuge(false, target).emit(masm); - } else { - new Fbge(false, target).emit(masm); - } - break; - case AE: - case AT: - case BT: - case BE: - throw GraalInternalError.unimplemented("Should not be required for float/dobule"); - default: - throw GraalInternalError.shouldNotReachHere(); + private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, + boolean withDelayedNop, double trueDestinationProbability) { + Label actualTarget; + ConditionFlag actualConditionFlag; + boolean needJump; + BranchPredict predictTaken; + if (falseDestination != null && crb.isSuccessorEdge(trueDestination)) { + actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null; + actualTarget = falseDestination.label(); + needJump = false; + predictTaken = trueDestinationProbability < .5d ? PREDICT_TAKEN : PREDICT_NOT_TAKEN; + } else { + actualConditionFlag = conditionFlag; + actualTarget = trueDestination.label(); + needJump = falseDestination != null && !crb.isSuccessorEdge(falseDestination); + predictTaken = trueDestinationProbability > .5d ? PREDICT_TAKEN : PREDICT_NOT_TAKEN; } - } - - private static void emitBranch(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition, CC cc) { - new Fmt00c(0, actualCondition, Op2s.Bp, cc, 0, target).emit(masm); - } - - private static void emitBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, CC cc, boolean predictTaken) { + if (!withDelayedNop && needJump) { + // We cannot make use of the delay slot when we jump in true-case and false-case + return false; + } - switch (actualCondition) { - case EQ: - new Bpe(cc, false, predictTaken, target).emit(masm); - break; - case NE: - new Bpne(cc, false, predictTaken, target).emit(masm); - break; - case BT: - new Bplu(cc, false, predictTaken, target).emit(masm); - break; - case LT: - new Bpl(cc, false, predictTaken, target).emit(masm); - break; - case BE: - new Bpleu(cc, false, predictTaken, target).emit(masm); - break; - case LE: - new Bple(cc, false, predictTaken, target).emit(masm); - break; - case GE: - new Bpge(cc, false, predictTaken, target).emit(masm); - break; - case AE: - new Bpgeu(cc, false, predictTaken, target).emit(masm); - break; - case GT: - new Bpg(cc, false, predictTaken, target).emit(masm); - break; - case AT: - new Bpgu(cc, false, predictTaken, target).emit(masm); - break; - default: - throw GraalInternalError.shouldNotReachHere(); + if (kind == Kind.Double || kind == Kind.Float) { + masm.fbpcc(actualConditionFlag, NOT_ANNUL, actualTarget, CC.Fcc0, predictTaken); + } else { + CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; + masm.bpcc(actualConditionFlag, NOT_ANNUL, actualTarget, cc, predictTaken); } + if (withDelayedNop) { + masm.nop(); // delay slot + } + if (needJump) { + masm.jmp(falseDestination.label()); + } + return true; } public static class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp { @@ -543,39 +404,33 @@ BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) { @Override protected void conditionalJump(int index, Condition condition, Label target) { + SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); + CC conditionCode; + Register scratchRegister; switch (key.getKind()) { case Char: case Byte: case Short: case Int: - if (crb.codeCache.needsDataPatch(keyConstants[index])) { - crb.recordInlineDataInCode(keyConstants[index]); - } - long lc = keyConstants[index].asLong(); - if (SPARCAssembler.isSimm13(lc)) { - assert NumUtil.isInt(lc); - new Cmp(keyRegister, (int) lc).emit(masm); - } else { - new Setx(lc, asIntReg(scratch)).emit(masm); - new Cmp(keyRegister, asIntReg(scratch)).emit(masm); - } - emitBranch(masm, target, condition, CC.Icc, false); + conditionCode = CC.Icc; + scratchRegister = asIntReg(scratch); break; case Long: { - SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); - new Cmp(keyRegister, asLongReg(scratch)).emit(masm); - emitBranch(masm, target, condition, CC.Xcc, false); + conditionCode = CC.Xcc; + scratchRegister = asLongReg(scratch); break; } case Object: { - SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); - new Cmp(keyRegister, asObjectReg(scratch)).emit(masm); - emitBranch(masm, target, condition, CC.Ptrcc, false); + conditionCode = CC.Ptrcc; + scratchRegister = asObjectReg(scratch); break; } default: throw new GraalInternalError("switch only supported for int, long and object"); } + ConditionFlag conditionFlag = ConditionFlag.fromCondtition(conditionCode, condition, false); + new Cmp(keyRegister, scratchRegister).emit(masm); + masm.bpcc(conditionFlag, NOT_ANNUL, target, conditionCode, PREDICT_TAKEN); new Nop().emit(masm); // delay slot } }; @@ -629,7 +484,7 @@ // Jump to default target if index is not within the jump table if (defaultTarget != null) { - new Bpgu(CC.Icc, defaultTarget.label()).emit(masm); + masm.bpcc(GreaterUnsigned, NOT_ANNUL, defaultTarget.label(), Icc, PREDICT_TAKEN); new Nop().emit(masm); // delay slot } @@ -644,11 +499,10 @@ new Jmpl(scratch2, scratchReg, g0).emit(masm); } new Nop().emit(masm); - // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8) // Emit jump table entries for (LabelRef target : targets) { - new Bpa(target.label()).emit(masm); + masm.bpcc(Always, NOT_ANNUL, target.label(), Xcc, PREDICT_TAKEN); new Nop().emit(masm); // delay slot } } @@ -677,8 +531,6 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - // check that we don't overwrite an input operand before it is used. - // assert !result.equals(trueValue); if (result.equals(trueValue)) { // We have the true value in place, do he opposite cmove(masm, cc, kind, result, condition.negate(), falseValue); } else if (result.equals(falseValue)) { diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Fri Feb 27 09:18:23 2015 +0100 @@ -22,7 +22,9 @@ */ package com.oracle.graal.lir.sparc; -import com.oracle.graal.asm.sparc.SPARCAssembler.Bpa; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; + +import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; import com.oracle.graal.lir.*; @@ -40,7 +42,7 @@ public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { assert !emitDone; if (!crb.isSuccessorEdge(destination())) { - new Bpa(destination().label()).emit(masm); + masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label()); delaySlotPosition = masm.position(); } emitDone = true; @@ -51,7 +53,7 @@ if (!crb.isSuccessorEdge(destination())) { if (!emitDone) { SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; - new Bpa(destination().label()).emit(masm); + masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label()); new Nop().emit(masm); } else { assert crb.asm.position() - delaySlotPosition == 4; diff -r afe80ca4b0f0 -r 413ac504d74e graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java --- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Fri Feb 13 17:42:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Fri Feb 27 09:18:23 2015 +0100 @@ -22,17 +22,18 @@ */ package com.oracle.graal.truffle.hotspot.sparc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; + import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe; -import com.oracle.graal.asm.sparc.SPARCAssembler.CBcondx; -import com.oracle.graal.asm.sparc.SPARCAssembler.CC; -import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; @@ -67,7 +68,7 @@ new CBcondx(ConditionFlag.Equal, spillRegister, 0, doProlog).emit(asm); } else { new Cmp(spillRegister, 0).emit(asm); - new Bpe(CC.Xcc, doProlog).emit(asm); + asm.bpcc(Equal, NOT_ANNUL, doProlog, Xcc, PREDICT_NOT_TAKEN); new Nop().emit(asm); } new Ldx(verifiedEntryPointAddress, spillRegister).emit(asm); // in delay slot