Mercurial > hg > graal-jvmci-8
changeset 22126:5f622eadfa5b
[SPARC] Put nop after cbcond only for following branch/call instructions
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Tue, 30 Jun 2015 10:41:03 +0200 |
parents | 9f58c0d2bd5a |
children | a27d4ef9b3a3 |
files | graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java |
diffstat | 3 files changed, 66 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Jun 29 11:51:57 2015 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Jun 30 10:41:03 2015 +0200 @@ -87,6 +87,21 @@ protected static final int D10LO_SHIFT = 5; protected static final int D10HI_SHIFT = 19; + private static final Ops[] OPS; + private static final Op2s[] OP2S; + static { + Ops[] ops = Ops.values(); + OPS = new Ops[ops.length]; + for (Ops op : ops) { + OPS[op.value] = op; + } + Op2s[] op2s = Op2s.values(); + OP2S = new Op2s[op2s.length]; + for (Op2s op2 : op2s) { + OP2S[op2.value] = op2; + } + } + public enum Ops { // @formatter:off @@ -967,6 +982,7 @@ */ // @formatter:on private void bcc(Op2s op2, ConditionFlag cond, Annul annul, Label l) { + insertNopAfterCBCond(); int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; final int disp = 22; assert isSimm(pos, disp); @@ -975,6 +991,33 @@ fmt00(a, op2.getValue(), pos); } + public void insertNopAfterCBCond() { + int pos = position(); + if (pos == 0) { + return; + } + int inst = getInt(pos); + if (isCBCond(inst)) { + nop(); + } + } + + private static boolean isCBCond(int inst) { + return getOp(inst).equals(Ops.BranchOp) && getOp2(inst).equals(Op2s.Bpr) && getBits(inst, 28, 28) == 1; + } + + private static Ops getOp(int inst) { + return OPS[getBits(inst, 31, 30)]; + } + + private static Op2s getOp2(int inst) { + return OP2S[getBits(inst, 24, 22)]; + } + + private static int getBits(int inst, int hiBit, int lowBit) { + return (inst >> lowBit) & ((1 << (hiBit - lowBit + 1)) - 1); + } + // @formatter:off /** * Branch on Integer Condition Codes with Prediction. @@ -1011,6 +1054,7 @@ */ // @formatter:on private void bpcc(Op2s op2, ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + insertNopAfterCBCond(); int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; final int disp = 19; assert isSimm(pos, disp); @@ -1030,6 +1074,7 @@ */ // @formatter:on public void bpr(RCondition cond, Annul annul, Label l, BranchPredict predictTaken, Register rs1) { + insertNopAfterCBCond(); int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; final int disp = 16; assert isSimm(pos, disp); @@ -1065,6 +1110,7 @@ } private void cbcond(int cc2, int i, ConditionFlag cf, Register rs1, int rs2, Label l) { + insertNopAfterCBCond(); int disp10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; assert isSimm(disp10, 10) && isImm(rs2, 5); disp10 &= (1 << 10) - 1; @@ -1101,13 +1147,18 @@ * | 01 | disp30 | * |31 30|29 0| * </pre> + * + * @return Position of the call instruction */ // @formatter:on - public void call(int disp30) { + public int call(int disp30) { assert isImm(disp30, 30); + insertNopAfterCBCond(); + int before = position(); int instr = 1 << 30; instr |= disp30; emitInt(instr); + return before; } public void add(Register rs1, Register rs2, Register rd) { @@ -1382,11 +1433,18 @@ } public void jmpl(Register rs1, Register rs2, Register rd) { + insertNopAfterCBCond(); op3(Jmpl, rs1, rs2, rd); } - public void jmpl(Register rs1, int simm13, Register rd) { + /** + * @return Position of the jmpl instruction + */ + public int jmpl(Register rs1, int simm13, Register rd) { + insertNopAfterCBCond(); + int before = position(); op3(Jmpl, rs1, simm13, rd); + return before; } public void fmovdcc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Mon Jun 29 11:51:57 2015 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Tue Jun 30 10:41:03 2015 +0200 @@ -106,8 +106,7 @@ public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { assert !emitted; emitCallPrefixCode(crb, masm); - before = masm.position(); - masm.call(0); + before = masm.call(0); emitted = true; } @@ -189,14 +188,16 @@ if (align) { // We don't need alignment on SPARC. } - int before = masm.position(); + + int before; if (scratch != null) { // offset might not fit a 30-bit displacement, generate an // indirect call with a 64-bit immediate + before = masm.position(); new Sethix(0L, scratch, true).emit(masm); masm.jmpl(scratch, 0, o7); } else { - masm.call(0); + before = masm.call(0); } masm.nop(); // delay slot int after = masm.position(); @@ -216,8 +217,7 @@ } public static void indirectCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) { - int before = masm.position(); - masm.jmpl(dst, 0, o7); + int before = masm.jmpl(dst, 0, o7); masm.nop(); // delay slot int after = masm.position(); crb.recordIndirectCall(before, after, callTarget, info);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Jun 29 11:51:57 2015 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Jun 30 10:41:03 2015 +0200 @@ -227,7 +227,6 @@ } try (ScratchRegister scratch = masm.getScratchRegister()) { emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag); - masm.nop(); } if (needJump) { masm.jmp(actualFalseTarget);