changeset 16651:a38fea2b8e14

[SPARC] First implementation of TableSwitchOp
author Stefan Anzinger <stefan.anzinger@gmail.com>
date Mon, 28 Jul 2014 14:29:52 -0700
parents 8ca7e7e15342
children e878be37db4c
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/SPARCControlFlow.java
diffstat 2 files changed, 31 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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 {
--- 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);
         }
     }