hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java
changeset 39441 7464b1552bf7
parent 39423 0f8dc3693499
child 39443 ca6dfb34e46c
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Wed Jun 22 21:13:52 2016 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Wed Jun 22 22:39:32 2016 +0000
@@ -50,6 +50,7 @@
     }
 
     private void emitOp2(Register rd, int op2, int imm22) {
+        assert isSimm(imm22, 22);
         code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
     }
 
@@ -58,6 +59,7 @@
     }
 
     private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
+        assert isSimm(simm13, 13);
         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
     }
 
@@ -65,6 +67,27 @@
         code.emitInt(1 << 24);
     }
 
+    /**
+     * Minimum value for signed immediate ranges.
+     */
+    public static long minSimm(long nbits) {
+        return -(1L << (nbits - 1));
+    }
+
+    /**
+     * Maximum value for signed immediate ranges.
+     */
+    public static long maxSimm(long nbits) {
+        return (1L << (nbits - 1)) - 1;
+    }
+
+    /**
+     * Test if imm is within signed immediate range for nbits.
+     */
+    public static boolean isSimm(long imm, int nbits) {
+        return minSimm(nbits) <= imm && imm <= maxSimm(nbits);
+    }
+
     @Override
     public void emitPrologue() {
         // SAVE sp, -128, sp
@@ -87,7 +110,13 @@
 
     @Override
     public void emitGrowStack(int size) {
-        emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
+        frameSize += size;
+        if (isSimm(size, 13)) {
+            emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
+        } else {
+            Register r = emitLoadInt(size);
+            emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, r); // SUB sp, size, sp
+        }
     }
 
     @Override
@@ -103,6 +132,11 @@
     @Override
     public Register emitLoadInt(int c) {
         Register ret = newRegister();
+        loadIntToRegister(c, ret);
+        return ret;
+    }
+
+    private void loadIntToRegister(int c, Register ret) {
         int hi = c >>> 10;
         int lo = c & ((1 << 10) - 1);
         if (hi == 0) {
@@ -113,19 +147,28 @@
                 emitOp3(0b10, ret, 0b000010, ret, lo);  // OR ret, lo, ret
             }
         }
-        return ret;
     }
 
     @Override
     public Register emitLoadLong(long c) {
+        Register ret = newRegister();
+        emitLoadLongToRegister(c, ret);
+        return ret;
+    }
+
+    private void loadLongToRegister(long c, Register ret) {
+        DataSectionReference ref = new DataSectionReference();
+        data.align(8);
+        ref.setOffset(data.position());
+        data.emitLong(c);
+        emitLoadPointerToRegister(ref, ret);
+    }
+
+    public void emitLoadLongToRegister(long c, Register r) {
         if ((c & 0xFFFF_FFFFL) == c) {
-            return emitLoadInt((int) c);
+            loadIntToRegister((int) c, r);
         } else {
-            DataSectionReference ref = new DataSectionReference();
-            data.align(8);
-            ref.setOffset(data.position());
-            data.emitLong(c);
-            return emitLoadPointer(ref);
+            loadLongToRegister(c, r);
         }
     }
 
@@ -168,10 +211,14 @@
     @Override
     public Register emitLoadPointer(DataSectionReference ref) {
         Register ret = newRegister();
+        emitLoadPointerToRegister(ref, ret);
+        return ret;
+    }
+
+    private void emitLoadPointerToRegister(DataSectionReference ref, Register ret) {
         recordDataPatchInCode(ref);
         emitPatchableSethi(ret, true);
         emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
-        return ret;
     }
 
     @Override
@@ -194,15 +241,15 @@
     public StackSlot emitIntToStack(Register a) {
         StackSlot ret = newStackSlot(SPARCKind.WORD);
         // STW a, [fp+offset]
-        emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        emitStore(0b000100, a, ret);
         return ret;
     }
 
     @Override
     public StackSlot emitLongToStack(Register a) {
         StackSlot ret = newStackSlot(SPARCKind.XWORD);
-        // STX a, [fp+offset]
-        emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        // STX a, [sp+offset]
+        emitStore(0b001110, a, ret);
         return ret;
     }
 
@@ -210,7 +257,7 @@
     public StackSlot emitFloatToStack(Register a) {
         StackSlot ret = newStackSlot(SPARCKind.SINGLE);
         // STF a, [fp+offset]
-        emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        emitStore(0b100100, a, ret);
         return ret;
     }
 
@@ -218,7 +265,7 @@
     public StackSlot emitPointerToStack(Register a) {
         StackSlot ret = newStackSlot(SPARCKind.XWORD);
         // STX a, [fp+offset]
-        emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        emitStore(0b001110, a, ret);
         return ret;
     }
 
@@ -226,10 +273,24 @@
     public StackSlot emitNarrowPointerToStack(Register a) {
         StackSlot ret = newStackSlot(SPARCKind.WORD);
         // STW a, [fp+offset]
-        emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        emitStore(0b000100, a, ret);
         return ret;
     }
 
+    private void emitStore(int op3, Register a, StackSlot ret) {
+        int offset = ret.getRawOffset() + SPARC.STACK_BIAS;
+        if (isSimm(offset, 13)) {
+            // op3 a, [sp+offset]
+            emitOp3(0b11, a, op3, SPARC.fp, offset);
+        } else {
+            assert a != SPARC.g3;
+            Register r = SPARC.g3;
+            loadLongToRegister(offset, r);
+            // op3 a, [sp+g3]
+            emitOp3(0b11, a, op3, SPARC.fp, r);
+        }
+    }
+
     @Override
     public Register emitUncompressPointer(Register compressed, long base, int shift) {
         Register ret;