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
equal deleted inserted replaced
39436:f07320a4e634 39441:7464b1552bf7
    48     public SPARCTestAssembler(CodeCacheProvider codeCache, TestHotSpotVMConfig config) {
    48     public SPARCTestAssembler(CodeCacheProvider codeCache, TestHotSpotVMConfig config) {
    49         super(codeCache, config, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
    49         super(codeCache, config, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
    50     }
    50     }
    51 
    51 
    52     private void emitOp2(Register rd, int op2, int imm22) {
    52     private void emitOp2(Register rd, int op2, int imm22) {
       
    53         assert isSimm(imm22, 22);
    53         code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
    54         code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
    54     }
    55     }
    55 
    56 
    56     private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
    57     private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
    57         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
    58         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
    58     }
    59     }
    59 
    60 
    60     private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
    61     private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
       
    62         assert isSimm(simm13, 13);
    61         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
    63         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
    62     }
    64     }
    63 
    65 
    64     private void emitNop() {
    66     private void emitNop() {
    65         code.emitInt(1 << 24);
    67         code.emitInt(1 << 24);
       
    68     }
       
    69 
       
    70     /**
       
    71      * Minimum value for signed immediate ranges.
       
    72      */
       
    73     public static long minSimm(long nbits) {
       
    74         return -(1L << (nbits - 1));
       
    75     }
       
    76 
       
    77     /**
       
    78      * Maximum value for signed immediate ranges.
       
    79      */
       
    80     public static long maxSimm(long nbits) {
       
    81         return (1L << (nbits - 1)) - 1;
       
    82     }
       
    83 
       
    84     /**
       
    85      * Test if imm is within signed immediate range for nbits.
       
    86      */
       
    87     public static boolean isSimm(long imm, int nbits) {
       
    88         return minSimm(nbits) <= imm && imm <= maxSimm(nbits);
    66     }
    89     }
    67 
    90 
    68     @Override
    91     @Override
    69     public void emitPrologue() {
    92     public void emitPrologue() {
    70         // SAVE sp, -128, sp
    93         // SAVE sp, -128, sp
    85         return super.finish(method);
   108         return super.finish(method);
    86     }
   109     }
    87 
   110 
    88     @Override
   111     @Override
    89     public void emitGrowStack(int size) {
   112     public void emitGrowStack(int size) {
    90         emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
   113         frameSize += size;
       
   114         if (isSimm(size, 13)) {
       
   115             emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
       
   116         } else {
       
   117             Register r = emitLoadInt(size);
       
   118             emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, r); // SUB sp, size, sp
       
   119         }
    91     }
   120     }
    92 
   121 
    93     @Override
   122     @Override
    94     public Register emitIntArg0() {
   123     public Register emitIntArg0() {
    95         return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
   124         return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
   101     }
   130     }
   102 
   131 
   103     @Override
   132     @Override
   104     public Register emitLoadInt(int c) {
   133     public Register emitLoadInt(int c) {
   105         Register ret = newRegister();
   134         Register ret = newRegister();
       
   135         loadIntToRegister(c, ret);
       
   136         return ret;
       
   137     }
       
   138 
       
   139     private void loadIntToRegister(int c, Register ret) {
   106         int hi = c >>> 10;
   140         int hi = c >>> 10;
   107         int lo = c & ((1 << 10) - 1);
   141         int lo = c & ((1 << 10) - 1);
   108         if (hi == 0) {
   142         if (hi == 0) {
   109             emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret
   143             emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret
   110         } else {
   144         } else {
   111             emitOp2(ret, 0b100, hi);                    // SETHI hi, ret
   145             emitOp2(ret, 0b100, hi);                    // SETHI hi, ret
   112             if (lo != 0) {
   146             if (lo != 0) {
   113                 emitOp3(0b10, ret, 0b000010, ret, lo);  // OR ret, lo, ret
   147                 emitOp3(0b10, ret, 0b000010, ret, lo);  // OR ret, lo, ret
   114             }
   148             }
   115         }
   149         }
   116         return ret;
       
   117     }
   150     }
   118 
   151 
   119     @Override
   152     @Override
   120     public Register emitLoadLong(long c) {
   153     public Register emitLoadLong(long c) {
       
   154         Register ret = newRegister();
       
   155         emitLoadLongToRegister(c, ret);
       
   156         return ret;
       
   157     }
       
   158 
       
   159     private void loadLongToRegister(long c, Register ret) {
       
   160         DataSectionReference ref = new DataSectionReference();
       
   161         data.align(8);
       
   162         ref.setOffset(data.position());
       
   163         data.emitLong(c);
       
   164         emitLoadPointerToRegister(ref, ret);
       
   165     }
       
   166 
       
   167     public void emitLoadLongToRegister(long c, Register r) {
   121         if ((c & 0xFFFF_FFFFL) == c) {
   168         if ((c & 0xFFFF_FFFFL) == c) {
   122             return emitLoadInt((int) c);
   169             loadIntToRegister((int) c, r);
   123         } else {
   170         } else {
   124             DataSectionReference ref = new DataSectionReference();
   171             loadLongToRegister(c, r);
   125             data.align(8);
       
   126             ref.setOffset(data.position());
       
   127             data.emitLong(c);
       
   128             return emitLoadPointer(ref);
       
   129         }
   172         }
   130     }
   173     }
   131 
   174 
   132     private void emitPatchableSethi(Register ret, boolean wide) {
   175     private void emitPatchableSethi(Register ret, boolean wide) {
   133         int startPos = code.position();
   176         int startPos = code.position();
   166     }
   209     }
   167 
   210 
   168     @Override
   211     @Override
   169     public Register emitLoadPointer(DataSectionReference ref) {
   212     public Register emitLoadPointer(DataSectionReference ref) {
   170         Register ret = newRegister();
   213         Register ret = newRegister();
       
   214         emitLoadPointerToRegister(ref, ret);
       
   215         return ret;
       
   216     }
       
   217 
       
   218     private void emitLoadPointerToRegister(DataSectionReference ref, Register ret) {
   171         recordDataPatchInCode(ref);
   219         recordDataPatchInCode(ref);
   172         emitPatchableSethi(ret, true);
   220         emitPatchableSethi(ret, true);
   173         emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
   221         emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
   174         return ret;
       
   175     }
   222     }
   176 
   223 
   177     @Override
   224     @Override
   178     public Register emitLoadNarrowPointer(DataSectionReference ref) {
   225     public Register emitLoadNarrowPointer(DataSectionReference ref) {
   179         Register ret = newRegister();
   226         Register ret = newRegister();
   192 
   239 
   193     @Override
   240     @Override
   194     public StackSlot emitIntToStack(Register a) {
   241     public StackSlot emitIntToStack(Register a) {
   195         StackSlot ret = newStackSlot(SPARCKind.WORD);
   242         StackSlot ret = newStackSlot(SPARCKind.WORD);
   196         // STW a, [fp+offset]
   243         // STW a, [fp+offset]
   197         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
   244         emitStore(0b000100, a, ret);
   198         return ret;
   245         return ret;
   199     }
   246     }
   200 
   247 
   201     @Override
   248     @Override
   202     public StackSlot emitLongToStack(Register a) {
   249     public StackSlot emitLongToStack(Register a) {
   203         StackSlot ret = newStackSlot(SPARCKind.XWORD);
   250         StackSlot ret = newStackSlot(SPARCKind.XWORD);
   204         // STX a, [fp+offset]
   251         // STX a, [sp+offset]
   205         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
   252         emitStore(0b001110, a, ret);
   206         return ret;
   253         return ret;
   207     }
   254     }
   208 
   255 
   209     @Override
   256     @Override
   210     public StackSlot emitFloatToStack(Register a) {
   257     public StackSlot emitFloatToStack(Register a) {
   211         StackSlot ret = newStackSlot(SPARCKind.SINGLE);
   258         StackSlot ret = newStackSlot(SPARCKind.SINGLE);
   212         // STF a, [fp+offset]
   259         // STF a, [fp+offset]
   213         emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
   260         emitStore(0b100100, a, ret);
   214         return ret;
   261         return ret;
   215     }
   262     }
   216 
   263 
   217     @Override
   264     @Override
   218     public StackSlot emitPointerToStack(Register a) {
   265     public StackSlot emitPointerToStack(Register a) {
   219         StackSlot ret = newStackSlot(SPARCKind.XWORD);
   266         StackSlot ret = newStackSlot(SPARCKind.XWORD);
   220         // STX a, [fp+offset]
   267         // STX a, [fp+offset]
   221         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
   268         emitStore(0b001110, a, ret);
   222         return ret;
   269         return ret;
   223     }
   270     }
   224 
   271 
   225     @Override
   272     @Override
   226     public StackSlot emitNarrowPointerToStack(Register a) {
   273     public StackSlot emitNarrowPointerToStack(Register a) {
   227         StackSlot ret = newStackSlot(SPARCKind.WORD);
   274         StackSlot ret = newStackSlot(SPARCKind.WORD);
   228         // STW a, [fp+offset]
   275         // STW a, [fp+offset]
   229         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
   276         emitStore(0b000100, a, ret);
   230         return ret;
   277         return ret;
       
   278     }
       
   279 
       
   280     private void emitStore(int op3, Register a, StackSlot ret) {
       
   281         int offset = ret.getRawOffset() + SPARC.STACK_BIAS;
       
   282         if (isSimm(offset, 13)) {
       
   283             // op3 a, [sp+offset]
       
   284             emitOp3(0b11, a, op3, SPARC.fp, offset);
       
   285         } else {
       
   286             assert a != SPARC.g3;
       
   287             Register r = SPARC.g3;
       
   288             loadLongToRegister(offset, r);
       
   289             // op3 a, [sp+g3]
       
   290             emitOp3(0b11, a, op3, SPARC.fp, r);
       
   291         }
   231     }
   292     }
   232 
   293 
   233     @Override
   294     @Override
   234     public Register emitUncompressPointer(Register compressed, long base, int shift) {
   295     public Register emitUncompressPointer(Register compressed, long base, int shift) {
   235         Register ret;
   296         Register ret;