# HG changeset patch # User Stefan Anzinger # Date 1406582992 25200 # Node ID a38fea2b8e14550d47876ca679306ded04e9434d # Parent 8ca7e7e15342d64780f960db4dd91259ed68084b [SPARC] First implementation of TableSwitchOp diff -r 8ca7e7e15342 -r a38fea2b8e14 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Jul 28 10:38:18 2014 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Jul 28 14:29:52 2014 -0700 @@ -63,8 +63,8 @@ protected static final int OP2_SHIFT = 22; // @formatter:off - protected static final int OP_MASK = 0b11000000000000000000000000000000; - protected static final int OP2_MASK = 0b00000001110000000000000000000000; + protected static final int OP_MASK = 0b1100_0000_0000_0000_0000_0000_0000_0000; + protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000; // @formatter:off private int op2; @@ -3405,6 +3405,10 @@ public Jmpl(Register src, int simm13, Register dst) { super(Op3s.Jmpl, src, simm13, dst); } + + public Jmpl(Register src1, Register src2, Register dst) { + super(Op3s.Jmpl, src1, src2, dst); + } } public static class Lddf extends Fmt11 { diff -r 8ca7e7e15342 -r a38fea2b8e14 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Jul 28 10:38:18 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Jul 28 14:29:52 2014 -0700 @@ -24,8 +24,8 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.sparc.SPARC.*; -import com.oracle.graal.api.code.CompilationResult.JumpTable; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; @@ -252,10 +252,10 @@ Register scratchReg = asLongReg(scratch); // Compare index against jump table bounds - int highKey = lowKey + targets.length - 1; + // int highKey = lowKey + targets.length - 1; if (lowKey != 0) { // subtract the low value from the switch value - new Sub(value, lowKey, value).emit(masm); + new Subcc(value, lowKey, value).emit(masm); // masm.setp_gt_s32(value, highKey - lowKey); } else { // masm.setp_gt_s32(value, highKey); @@ -263,24 +263,33 @@ // Jump to default target if index is not within the jump table if (defaultTarget != null) { - new Bpgu(CC.Icc, defaultTarget.label()).emit(masm); + new Bpl(CC.Icc, defaultTarget.label()).emit(masm); new Nop().emit(masm); // delay slot } // Load jump table entry into scratch and jump to it - // masm.movslq(value, new AMD64Address(scratch, value, Scale.Times4, 0)); - // masm.addq(scratch, value); - new Jmp(new SPARCAddress(scratchReg, 0)).emit(masm); - new Nop().emit(masm); // delay slot + new Sll(value, 3, value).emit(masm); // Multiply by 8 + new Rdpc(scratchReg).emit(masm); + + // The jump table follows three instructions after rdpc + new Add(scratchReg, 4 * 4, scratchReg).emit(masm); + new Jmpl(value, scratchReg, g0).emit(masm); + new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8) - // address of jump table - int tablePos = masm.position(); - - JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4); - crb.compilationResult.addAnnotation(jt); - - // SPARC: unimp: tableswitch extract - throw GraalInternalError.unimplemented(); + // Emit jump table entries + for (LabelRef target : targets) { + Label label = target.label(); + if (label.isBound()) { + int disp19 = label.position() - masm.position(); + new Bpa(disp19).emit(masm); + new Nop().emit(masm); // delay slot + } else { + label.addPatchAt(masm.position()); + new Bpa(0).emit(masm); + new Nop().emit(masm); // delay slot + } + } + // crb.compilationResult.addAnnotation(jt); } }