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 |
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 } |