hotspot/test/compiler/jvmci/code/sparc/SPARCTestAssembler.java
changeset 35582 c32a0cc19877
parent 35144 f2381983e98e
child 35591 35ab7c6816e9
equal deleted inserted replaced
35581:dd47cf4734f2 35582:c32a0cc19877
     1 /*
     1 /*
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 package compiler.jvmci.code.sparc;
    24 package compiler.jvmci.code.sparc;
    25 
    25 
       
    26 import jdk.vm.ci.code.CallingConvention.Type;
    26 import jdk.vm.ci.code.CodeCacheProvider;
    27 import jdk.vm.ci.code.CodeCacheProvider;
    27 import jdk.vm.ci.code.CompilationResult;
       
    28 import jdk.vm.ci.code.CompilationResult.ConstantReference;
       
    29 import jdk.vm.ci.code.CompilationResult.DataSectionReference;
       
    30 import jdk.vm.ci.code.DataSection.Data;
       
    31 import jdk.vm.ci.code.DebugInfo;
    28 import jdk.vm.ci.code.DebugInfo;
    32 import jdk.vm.ci.code.InfopointReason;
       
    33 import jdk.vm.ci.code.Register;
    29 import jdk.vm.ci.code.Register;
    34 import jdk.vm.ci.code.StackSlot;
    30 import jdk.vm.ci.code.StackSlot;
    35 import jdk.vm.ci.code.CallingConvention.Type;
    31 import jdk.vm.ci.code.site.ConstantReference;
       
    32 import jdk.vm.ci.code.site.DataSectionReference;
       
    33 import jdk.vm.ci.hotspot.HotSpotCompiledCode;
    36 import jdk.vm.ci.hotspot.HotSpotConstant;
    34 import jdk.vm.ci.hotspot.HotSpotConstant;
    37 import jdk.vm.ci.meta.JavaConstant;
    35 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
    38 import jdk.vm.ci.meta.JavaKind;
    36 import jdk.vm.ci.meta.JavaKind;
    39 import jdk.vm.ci.meta.LIRKind;
    37 import jdk.vm.ci.meta.LIRKind;
    40 import jdk.vm.ci.meta.VMConstant;
    38 import jdk.vm.ci.meta.VMConstant;
    41 import jdk.vm.ci.sparc.SPARC;
    39 import jdk.vm.ci.sparc.SPARC;
    42 import jdk.vm.ci.sparc.SPARCKind;
    40 import jdk.vm.ci.sparc.SPARCKind;
    45 
    43 
    46 public class SPARCTestAssembler extends TestAssembler {
    44 public class SPARCTestAssembler extends TestAssembler {
    47 
    45 
    48     private static final int MASK13 = (1 << 13) - 1;
    46     private static final int MASK13 = (1 << 13) - 1;
    49 
    47 
    50     public SPARCTestAssembler(CompilationResult result, CodeCacheProvider codeCache) {
    48     public SPARCTestAssembler(CodeCacheProvider codeCache) {
    51         super(result, codeCache, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
    49         super(codeCache, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
    52     }
    50     }
    53 
    51 
    54     private void emitOp2(Register rd, int op2, int imm22) {
    52     private void emitOp2(Register rd, int op2, int imm22) {
    55         emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
    53         code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
    56     }
    54     }
    57 
    55 
    58     private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
    56     private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
    59         emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
    57         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
    60     }
    58     }
    61 
    59 
    62     private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
    60     private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
    63         emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
    61         code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
    64     }
    62     }
    65 
    63 
    66     private void emitNop() {
    64     private void emitNop() {
    67         emitInt(1 << 24);
    65         code.emitInt(1 << 24);
    68     }
    66     }
    69 
    67 
       
    68     @Override
    70     public void emitPrologue() {
    69     public void emitPrologue() {
    71         emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE); // SAVE sp, -128, sp
    70         emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE); // SAVE sp, -128, sp
    72     }
    71     }
    73 
    72 
    74     @Override
    73     @Override
    75     public void finish() {
    74     public HotSpotCompiledCode finish(HotSpotResolvedJavaMethod method) {
    76         frameSize += SPARC.REGISTER_SAFE_AREA_SIZE;
    75         frameSize += SPARC.REGISTER_SAFE_AREA_SIZE;
    77         super.finish();
    76         return super.finish(method);
    78     }
    77     }
    79 
    78 
       
    79     @Override
    80     public void emitGrowStack(int size) {
    80     public void emitGrowStack(int size) {
    81         emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
    81         emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
    82     }
    82     }
    83 
    83 
       
    84     @Override
    84     public Register emitIntArg0() {
    85     public Register emitIntArg0() {
    85         return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCallee, JavaKind.Int)[0];
    86         return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCallee, JavaKind.Int)[0];
    86     }
    87     }
    87 
    88 
       
    89     @Override
    88     public Register emitIntArg1() {
    90     public Register emitIntArg1() {
    89         return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCallee, JavaKind.Int)[1];
    91         return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCallee, JavaKind.Int)[1];
    90     }
    92     }
    91 
    93 
       
    94     @Override
    92     public Register emitLoadInt(int c) {
    95     public Register emitLoadInt(int c) {
    93         Register ret = newRegister();
    96         Register ret = newRegister();
    94         int hi = c >>> 10;
    97         int hi = c >>> 10;
    95         int lo = c & ((1 << 10) - 1);
    98         int lo = c & ((1 << 10) - 1);
    96         if (hi == 0) {
    99         if (hi == 0) {
   102             }
   105             }
   103         }
   106         }
   104         return ret;
   107         return ret;
   105     }
   108     }
   106 
   109 
       
   110     @Override
   107     public Register emitLoadLong(long c) {
   111     public Register emitLoadLong(long c) {
   108         if ((c & 0xFFFFFFFF) == c) {
   112         if ((c & 0xFFFFFFFF) == c) {
   109             return emitLoadInt((int) c);
   113             return emitLoadInt((int) c);
   110         } else {
   114         } else {
   111             Data data = codeCache.createDataItem(JavaConstant.forLong(c));
   115             DataSectionReference ref = new DataSectionReference();
   112             DataSectionReference ref = result.getDataSection().insertData(data);
   116             ref.setOffset(data.position());
       
   117             data.emitLong(c);
   113             return emitLoadPointer(ref);
   118             return emitLoadPointer(ref);
   114         }
   119         }
   115     }
   120     }
   116 
   121 
   117     private void emitPatchableSethi(Register ret, boolean wide) {
   122     private void emitPatchableSethi(Register ret, boolean wide) {
   118         int startPos = position();
   123         int startPos = code.position();
   119         emitOp2(ret, 0b100, 0);              // SETHI 0, ret
   124         emitOp2(ret, 0b100, 0);              // SETHI 0, ret
   120         if (wide) {
   125         if (wide) {
   121             // pad for later patching
   126             // pad for later patching
   122             while (position() < (startPos + 28)) {
   127             while (code.position() < (startPos + 28)) {
   123                 emitNop();
   128                 emitNop();
   124             }
   129             }
   125         }
   130         }
   126     }
   131     }
   127 
   132 
       
   133     @Override
   128     public Register emitLoadFloat(float c) {
   134     public Register emitLoadFloat(float c) {
   129         Data data = codeCache.createDataItem(JavaConstant.forFloat(c));
   135         DataSectionReference ref = new DataSectionReference();
   130         DataSectionReference ref = result.getDataSection().insertData(data);
   136         ref.setOffset(data.position());
       
   137         data.emitFloat(c);
   131 
   138 
   132         Register ptr = newRegister();
   139         Register ptr = newRegister();
   133         result.recordDataPatch(position(), ref);
   140         recordDataPatchInCode(ref);
   134         emitPatchableSethi(ptr, true);
   141         emitPatchableSethi(ptr, true);
   135         emitOp3(0b11, SPARC.f0, 0b100000, ptr, 0); // LDF [ptr+0], f0
   142         emitOp3(0b11, SPARC.f0, 0b100000, ptr, 0); // LDF [ptr+0], f0
   136         return SPARC.f0;
   143         return SPARC.f0;
   137     }
   144     }
   138 
   145 
       
   146     @Override
   139     public Register emitLoadPointer(HotSpotConstant c) {
   147     public Register emitLoadPointer(HotSpotConstant c) {
   140         Register ret = newRegister();
   148         Register ret = newRegister();
   141         result.recordDataPatch(position(), new ConstantReference((VMConstant) c));
   149         recordDataPatchInCode(new ConstantReference((VMConstant) c));
   142 
   150 
   143         emitPatchableSethi(ret, !c.isCompressed());
   151         emitPatchableSethi(ret, !c.isCompressed());
   144         emitOp3(0b10, ret, 0b000010, ret, 0); // OR ret, 0, ret
   152         emitOp3(0b10, ret, 0b000010, ret, 0); // OR ret, 0, ret
   145 
   153 
   146         return ret;
   154         return ret;
   147     }
   155     }
   148 
   156 
       
   157     @Override
   149     public Register emitLoadPointer(DataSectionReference ref) {
   158     public Register emitLoadPointer(DataSectionReference ref) {
   150         Register ret = newRegister();
   159         Register ret = newRegister();
   151         result.recordDataPatch(position(), ref);
   160         recordDataPatchInCode(ref);
   152         emitPatchableSethi(ret, true);
   161         emitPatchableSethi(ret, true);
   153         emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
   162         emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
   154         return ret;
   163         return ret;
   155     }
   164     }
   156 
   165 
       
   166     @Override
   157     public Register emitLoadNarrowPointer(DataSectionReference ref) {
   167     public Register emitLoadNarrowPointer(DataSectionReference ref) {
   158         Register ret = newRegister();
   168         Register ret = newRegister();
   159         result.recordDataPatch(position(), ref);
   169         recordDataPatchInCode(ref);
   160         emitPatchableSethi(ret, true);
   170         emitPatchableSethi(ret, true);
   161         emitOp3(0b11, ret, 0b000000, ret, 0); // LDUW [ret+0], ret
   171         emitOp3(0b11, ret, 0b000000, ret, 0); // LDUW [ret+0], ret
   162         return ret;
   172         return ret;
   163     }
   173     }
   164 
   174 
       
   175     @Override
   165     public Register emitLoadPointer(Register b, int offset) {
   176     public Register emitLoadPointer(Register b, int offset) {
   166         Register ret = newRegister();
   177         Register ret = newRegister();
   167         emitOp3(0b11, ret, 0b001011, b, offset); // LDX [b+offset], ret
   178         emitOp3(0b11, ret, 0b001011, b, offset); // LDX [b+offset], ret
   168         return ret;
   179         return ret;
   169     }
   180     }
   170 
   181 
       
   182     @Override
   171     public StackSlot emitIntToStack(Register a) {
   183     public StackSlot emitIntToStack(Register a) {
   172         StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.WORD));
   184         StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.WORD));
   173         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STW a, [fp+offset]
   185         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STW a, [fp+offset]
   174         return ret;
   186         return ret;
   175     }
   187     }
   176 
   188 
       
   189     @Override
   177     public StackSlot emitLongToStack(Register a) {
   190     public StackSlot emitLongToStack(Register a) {
   178         StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.XWORD));
   191         StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.XWORD));
   179         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STX a, [fp+offset]
   192         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STX a, [fp+offset]
   180         return ret;
   193         return ret;
   181     }
   194     }
   182 
   195 
       
   196     @Override
   183     public StackSlot emitFloatToStack(Register a) {
   197     public StackSlot emitFloatToStack(Register a) {
   184         StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.SINGLE));
   198         StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.SINGLE));
   185         emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STF a, [fp+offset]
   199         emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STF a, [fp+offset]
   186         return ret;
   200         return ret;
   187     }
   201     }
   188 
   202 
       
   203     @Override
   189     public StackSlot emitPointerToStack(Register a) {
   204     public StackSlot emitPointerToStack(Register a) {
   190         StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.XWORD));
   205         StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.XWORD));
   191         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STX a, [fp+offset]
   206         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STX a, [fp+offset]
   192         return ret;
   207         return ret;
   193     }
   208     }
   194 
   209 
       
   210     @Override
   195     public StackSlot emitNarrowPointerToStack(Register a) {
   211     public StackSlot emitNarrowPointerToStack(Register a) {
   196         StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.WORD));
   212         StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.WORD));
   197         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STW a, [fp+offset]
   213         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STW a, [fp+offset]
   198         return ret;
   214         return ret;
   199     }
   215     }
   200 
   216 
       
   217     @Override
   201     public Register emitUncompressPointer(Register compressed, long base, int shift) {
   218     public Register emitUncompressPointer(Register compressed, long base, int shift) {
   202         Register ret;
   219         Register ret;
   203         if (shift > 0) {
   220         if (shift > 0) {
   204             ret = newRegister();
   221             ret = newRegister();
   205             emitOp3(0b10, ret, 0b100101, compressed, shift); // SLL compressed, shift, ret
   222             emitOp3(0b10, ret, 0b100101, compressed, shift); // SLL compressed, shift, ret
   213             emitOp3(0b10, b, 0b00000, ret, b); // ADD b, ret, b
   230             emitOp3(0b10, b, 0b00000, ret, b); // ADD b, ret, b
   214             return b;
   231             return b;
   215         }
   232         }
   216     }
   233     }
   217 
   234 
       
   235     @Override
   218     public Register emitIntAdd(Register a, Register b) {
   236     public Register emitIntAdd(Register a, Register b) {
   219         Register ret = newRegister();
   237         Register ret = newRegister();
   220         emitOp3(0b10, ret, 0b00000, a, b); // ADD a, b, ret
   238         emitOp3(0b10, ret, 0b00000, a, b); // ADD a, b, ret
   221         return ret;
   239         return ret;
   222     }
   240     }
   225         if (to != from) {
   243         if (to != from) {
   226             emitOp3(0b10, to, 0b000010, from, SPARC.g0); // OR from, g0, to
   244             emitOp3(0b10, to, 0b000010, from, SPARC.g0); // OR from, g0, to
   227         }
   245         }
   228     }
   246     }
   229 
   247 
       
   248     @Override
   230     public void emitIntRet(Register a) {
   249     public void emitIntRet(Register a) {
   231         emitPointerRet(a);
   250         emitPointerRet(a);
   232     }
   251     }
   233 
   252 
       
   253     @Override
   234     public void emitPointerRet(Register a) {
   254     public void emitPointerRet(Register a) {
   235         emitMove(SPARC.i0, a);
   255         emitMove(SPARC.i0, a);
   236         emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8);        // JMPL [i7+8], g0
   256         emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8);        // JMPL [i7+8], g0
   237         emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
   257         emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
   238     }
   258     }
   239 
   259 
       
   260     @Override
   240     public void emitTrap(DebugInfo info) {
   261     public void emitTrap(DebugInfo info) {
   241         result.recordInfopoint(position(), info, InfopointReason.IMPLICIT_EXCEPTION);
   262         recordImplicitException(info);
   242         emitOp3(0b11, SPARC.g0, 0b001011, SPARC.g0, 0); // LDX [g0+0], g0
   263         emitOp3(0b11, SPARC.g0, 0b001011, SPARC.g0, 0); // LDX [g0+0], g0
   243     }
   264     }
   244 }
   265 }