6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 package jdk.vm.ci.code.test.sparc;
25
26 import jdk.vm.ci.code.CodeCacheProvider;
27 import jdk.vm.ci.code.DebugInfo;
28 import jdk.vm.ci.code.Register;
29 import jdk.vm.ci.code.StackSlot;
30 import jdk.vm.ci.code.site.ConstantReference;
31 import jdk.vm.ci.code.site.DataSectionReference;
32 import jdk.vm.ci.code.test.TestAssembler;
33 import jdk.vm.ci.code.test.TestHotSpotVMConfig;
34 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
35 import jdk.vm.ci.hotspot.HotSpotCompiledCode;
36 import jdk.vm.ci.hotspot.HotSpotConstant;
37 import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
38 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
39 import jdk.vm.ci.meta.JavaKind;
40 import jdk.vm.ci.meta.VMConstant;
41 import jdk.vm.ci.sparc.SPARC;
42 import jdk.vm.ci.sparc.SPARCKind;
43
44 public class SPARCTestAssembler extends TestAssembler {
45
46 private static final int MASK13 = (1 << 13) - 1;
47
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);
50 }
51
52 private void emitOp2(Register rd, int op2, int imm22) {
53 code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
54 }
55
56 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 }
59
60 private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
61 code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
62 }
63
64 private void emitNop() {
65 code.emitInt(1 << 24);
66 }
85 return super.finish(method);
86 }
87
88 @Override
89 public void emitGrowStack(int size) {
90 emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
91 }
92
93 @Override
94 public Register emitIntArg0() {
95 return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
96 }
97
98 @Override
99 public Register emitIntArg1() {
100 return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1];
101 }
102
103 @Override
104 public Register emitLoadInt(int c) {
105 Register ret = newRegister();
106 int hi = c >>> 10;
107 int lo = c & ((1 << 10) - 1);
108 if (hi == 0) {
109 emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret
110 } else {
111 emitOp2(ret, 0b100, hi); // SETHI hi, ret
112 if (lo != 0) {
113 emitOp3(0b10, ret, 0b000010, ret, lo); // OR ret, lo, ret
114 }
115 }
116 return ret;
117 }
118
119 @Override
120 public Register emitLoadLong(long c) {
121 if ((c & 0xFFFF_FFFFL) == c) {
122 return emitLoadInt((int) c);
123 } else {
124 DataSectionReference ref = new DataSectionReference();
125 data.align(8);
126 ref.setOffset(data.position());
127 data.emitLong(c);
128 return emitLoadPointer(ref);
129 }
130 }
131
132 private void emitPatchableSethi(Register ret, boolean wide) {
133 int startPos = code.position();
134 emitOp2(ret, 0b100, 0); // SETHI 0, ret
135 if (wide) {
136 // pad for later patching
137 while (code.position() < (startPos + 28)) {
138 emitNop();
139 }
140 }
141 }
142
143 @Override
144 public Register emitLoadFloat(float c) {
145 DataSectionReference ref = new DataSectionReference();
146 data.align(4);
147 ref.setOffset(data.position());
148 data.emitFloat(c);
149
150 Register ptr = newRegister();
151 recordDataPatchInCode(ref);
152 emitPatchableSethi(ptr, true);
153 emitOp3(0b11, SPARC.f0, 0b100000, ptr, 0); // LDF [ptr+0], f0
154 return SPARC.f0;
155 }
156
157 @Override
158 public Register emitLoadPointer(HotSpotConstant c) {
159 Register ret = newRegister();
160 recordDataPatchInCode(new ConstantReference((VMConstant) c));
161
162 emitPatchableSethi(ret, !c.isCompressed());
163 emitOp3(0b10, ret, 0b000010, ret, 0); // OR ret, 0, ret
164
165 return ret;
166 }
167
168 @Override
169 public Register emitLoadPointer(DataSectionReference ref) {
170 Register ret = newRegister();
171 recordDataPatchInCode(ref);
172 emitPatchableSethi(ret, true);
173 emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
174 return ret;
175 }
176
177 @Override
178 public Register emitLoadNarrowPointer(DataSectionReference ref) {
179 Register ret = newRegister();
180 recordDataPatchInCode(ref);
181 emitPatchableSethi(ret, true);
182 emitOp3(0b11, ret, 0b000000, ret, 0); // LDUW [ret+0], ret
183 return ret;
184 }
185
186 @Override
187 public Register emitLoadPointer(Register b, int offset) {
188 Register ret = newRegister();
189 emitOp3(0b11, ret, 0b001011, b, offset); // LDX [b+offset], ret
190 return ret;
191 }
192
193 @Override
194 public StackSlot emitIntToStack(Register a) {
195 StackSlot ret = newStackSlot(SPARCKind.WORD);
196 // STW a, [fp+offset]
197 emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
198 return ret;
199 }
200
201 @Override
202 public StackSlot emitLongToStack(Register a) {
203 StackSlot ret = newStackSlot(SPARCKind.XWORD);
204 // STX a, [fp+offset]
205 emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
206 return ret;
207 }
208
209 @Override
210 public StackSlot emitFloatToStack(Register a) {
211 StackSlot ret = newStackSlot(SPARCKind.SINGLE);
212 // STF a, [fp+offset]
213 emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
214 return ret;
215 }
216
217 @Override
218 public StackSlot emitPointerToStack(Register a) {
219 StackSlot ret = newStackSlot(SPARCKind.XWORD);
220 // STX a, [fp+offset]
221 emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
222 return ret;
223 }
224
225 @Override
226 public StackSlot emitNarrowPointerToStack(Register a) {
227 StackSlot ret = newStackSlot(SPARCKind.WORD);
228 // STW a, [fp+offset]
229 emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
230 return ret;
231 }
232
233 @Override
250
251 @Override
252 public Register emitIntAdd(Register a, Register b) {
253 Register ret = newRegister();
254 emitOp3(0b10, ret, 0b00000, a, b); // ADD a, b, ret
255 return ret;
256 }
257
258 private void emitMove(Register to, Register from) {
259 if (to != from) {
260 emitOp3(0b10, to, 0b000010, from, SPARC.g0); // OR from, g0, to
261 }
262 }
263
264 @Override
265 public void emitIntRet(Register a) {
266 emitPointerRet(a);
267 }
268
269 @Override
270 public void emitPointerRet(Register a) {
271 emitMove(SPARC.i0, a);
272 emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8); // JMPL [i7+8], g0
273 emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
274 }
275
276 @Override
277 public void emitTrap(DebugInfo info) {
278 recordImplicitException(info);
279 emitOp3(0b11, SPARC.g0, 0b001011, SPARC.g0, 0); // LDX [g0+0], g0
280 }
281
282 @Override
283 public DataSectionReference emitDataItem(HotSpotConstant c) {
284 if (c.isCompressed()) {
285 data.align(4);
286 } else {
287 data.align(8);
288 }
289 return super.emitDataItem(c);
290 }
291 }
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 package jdk.vm.ci.code.test.sparc;
25
26 import jdk.vm.ci.code.CallingConvention;
27 import jdk.vm.ci.code.CodeCacheProvider;
28 import jdk.vm.ci.code.DebugInfo;
29 import jdk.vm.ci.code.Register;
30 import jdk.vm.ci.code.Register.RegisterCategory;
31 import jdk.vm.ci.code.RegisterValue;
32 import jdk.vm.ci.code.StackSlot;
33 import jdk.vm.ci.code.site.ConstantReference;
34 import jdk.vm.ci.code.site.DataSectionReference;
35 import jdk.vm.ci.code.test.TestAssembler;
36 import jdk.vm.ci.code.test.TestHotSpotVMConfig;
37 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
38 import jdk.vm.ci.hotspot.HotSpotCompiledCode;
39 import jdk.vm.ci.hotspot.HotSpotConstant;
40 import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
41 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
42 import jdk.vm.ci.meta.AllocatableValue;
43 import jdk.vm.ci.meta.JavaKind;
44 import jdk.vm.ci.meta.VMConstant;
45 import jdk.vm.ci.sparc.SPARC;
46 import jdk.vm.ci.sparc.SPARCKind;
47
48 public class SPARCTestAssembler extends TestAssembler {
49
50 private static final int MASK13 = (1 << 13) - 1;
51 private static final Register scratchRegister = SPARC.g5;
52 private static final Register floatScratch = SPARC.f30;
53 private static final Register doubleScratch = SPARC.d62;
54
55 public SPARCTestAssembler(CodeCacheProvider codeCache, TestHotSpotVMConfig config) {
56 super(codeCache, config, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
57 }
58
59 private void emitOp2(Register rd, int op2, int imm22) {
60 code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
61 }
62
63 private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
64 code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
65 }
66
67 private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
68 code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
69 }
70
71 private void emitNop() {
72 code.emitInt(1 << 24);
73 }
92 return super.finish(method);
93 }
94
95 @Override
96 public void emitGrowStack(int size) {
97 emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
98 }
99
100 @Override
101 public Register emitIntArg0() {
102 return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
103 }
104
105 @Override
106 public Register emitIntArg1() {
107 return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1];
108 }
109
110 @Override
111 public Register emitLoadInt(int c) {
112 return emitLoadInt(newRegister(), c);
113 }
114
115 public Register emitLoadInt(Register ret, int c) {
116 int hi = c >>> 10;
117 int lo = c & ((1 << 10) - 1);
118 if (hi == 0) {
119 emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret
120 } else {
121 emitOp2(ret, 0b100, hi); // SETHI hi, ret
122 if (lo != 0) {
123 emitOp3(0b10, ret, 0b000010, ret, lo); // OR ret, lo, ret
124 }
125 }
126 return ret;
127 }
128
129 @Override
130 public Register emitLoadLong(long c) {
131 return emitLoadLong(newRegister(), c);
132 }
133
134 public Register emitLoadLong(Register reg, long c) {
135 if ((c & 0xFFFF_FFFFL) == c) {
136 return emitLoadInt(reg, (int) c);
137 } else {
138 DataSectionReference ref = new DataSectionReference();
139 data.align(8);
140 ref.setOffset(data.position());
141 data.emitLong(c);
142 return emitLoadPointer(reg, ref);
143 }
144 }
145
146 private void emitPatchableSethi(Register ret, boolean wide) {
147 int startPos = code.position();
148 emitOp2(ret, 0b100, 0); // SETHI 0, ret
149 if (wide) {
150 // pad for later patching
151 while (code.position() < (startPos + 28)) {
152 emitNop();
153 }
154 }
155 }
156
157 @Override
158 public Register emitLoadFloat(float c) {
159 return emitLoadFloat(SPARC.f0, c);
160 }
161
162 public Register emitLoadFloat(Register reg, float c) {
163 return emitLoadFloat(reg, c, newRegister());
164 }
165
166 public Register emitLoadFloat(Register reg, float c, Register scratch) {
167 DataSectionReference ref = new DataSectionReference();
168 data.align(4);
169 ref.setOffset(data.position());
170 data.emitFloat(c);
171
172 recordDataPatchInCode(ref);
173 emitPatchableSethi(scratch, true);
174 emitOp3(0b11, reg, 0b100000, scratch, 0); // LDF [scratch+0], f0
175 return reg;
176 }
177
178 public Register emitLoadDouble(Register reg, double c) {
179 return emitLoadDouble(reg, c, newRegister());
180 }
181
182 public Register emitLoadDouble(Register reg, double c, Register scratch) {
183 DataSectionReference ref = new DataSectionReference();
184 data.align(8);
185 ref.setOffset(data.position());
186 data.emitDouble(c);
187
188 recordDataPatchInCode(ref);
189 emitPatchableSethi(scratch, true);
190 emitOp3(0b11, reg, 0b100011, scratch, 0); // LDDF [ptr+0], f0
191 return reg;
192 }
193
194 @Override
195 public Register emitLoadPointer(HotSpotConstant c) {
196 Register ret = newRegister();
197 recordDataPatchInCode(new ConstantReference((VMConstant) c));
198
199 emitPatchableSethi(ret, !c.isCompressed());
200 emitOp3(0b10, ret, 0b000010, ret, 0); // OR ret, 0, ret
201
202 return ret;
203 }
204
205 @Override
206 public Register emitLoadPointer(DataSectionReference ref) {
207 return emitLoadPointer(newRegister(), ref);
208 }
209
210 public Register emitLoadPointer(Register ret, DataSectionReference ref) {
211 recordDataPatchInCode(ref);
212 emitPatchableSethi(ret, true);
213 emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
214 return ret;
215 }
216
217 @Override
218 public Register emitLoadNarrowPointer(DataSectionReference ref) {
219 Register ret = newRegister();
220 recordDataPatchInCode(ref);
221 emitPatchableSethi(ret, true);
222 emitOp3(0b11, ret, 0b000000, ret, 0); // LDUW [ret+0], ret
223 return ret;
224 }
225
226 @Override
227 public Register emitLoadPointer(Register b, int offset) {
228 Register ret = newRegister();
229 emitOp3(0b11, ret, 0b001011, b, offset); // LDX [b+offset], ret
230 return ret;
231 }
232
233 @Override
234 public StackSlot emitIntToStack(Register a) {
235 StackSlot ret = newStackSlot(SPARCKind.WORD);
236 return emitIntToStack(ret, a);
237 }
238
239 public StackSlot emitIntToStack(StackSlot ret, Register a) {
240 int offset = ret.getRawOffset();
241 if (offset < 0) {
242 // STW a, [fp+offset]
243 emitOp3(0b11, a, 0b000100, SPARC.fp, offset + SPARC.STACK_BIAS);
244 } else {
245 // STW a, [sp+offset]
246 emitOp3(0b11, a, 0b000100, SPARC.sp, offset + SPARC.STACK_BIAS);
247 }
248 return ret;
249 }
250
251 @Override
252 public StackSlot emitLongToStack(Register a) {
253 StackSlot ret = newStackSlot(SPARCKind.XWORD);
254 return emitLongToStack(ret, a);
255 }
256
257 public StackSlot emitLongToStack(StackSlot ret, Register a) {
258 int offset = ret.getRawOffset();
259 if (ret.getRawAddFrameSize()) {
260 // STX a, [fp+offset]
261 emitOp3(0b11, a, 0b001110, SPARC.fp, offset + SPARC.STACK_BIAS);
262 } else {
263 // STX a, [sp+offset]
264 emitOp3(0b11, a, 0b001110, SPARC.sp, offset + SPARC.STACK_BIAS);
265 }
266 return ret;
267 }
268
269 @Override
270 public StackSlot emitFloatToStack(Register a) {
271 StackSlot ret = newStackSlot(SPARCKind.SINGLE);
272 return emitFloatToStack(ret, a);
273 }
274
275 public StackSlot emitFloatToStack(StackSlot ret, Register a) {
276 int offset = ret.getRawOffset();
277 if (offset < 0) {
278 // STF a, [fp+offset]
279 emitOp3(0b11, a, 0b100100, SPARC.fp, offset + SPARC.STACK_BIAS);
280 } else {
281 // STF a, [sp+offset]
282 emitOp3(0b11, a, 0b100100, SPARC.sp, offset + SPARC.STACK_BIAS);
283 }
284 return ret;
285 }
286
287 public StackSlot emitDoubleToStack(Register a) {
288 StackSlot ret = newStackSlot(SPARCKind.DOUBLE);
289 return emitDoubleToStack(ret, a);
290 }
291
292 public StackSlot emitDoubleToStack(StackSlot ret, Register a) {
293 int offset = ret.getRawOffset();
294 if (offset < 0) {
295 // STDF a, [fp+offset]
296 emitOp3(0b11, a, 0b100111, SPARC.fp, offset + SPARC.STACK_BIAS);
297 } else {
298 // STDF a, [sp+offset]
299 emitOp3(0b11, a, 0b100111, SPARC.sp, offset + SPARC.STACK_BIAS);
300 }
301 return ret;
302 }
303
304 @Override
305 public StackSlot emitPointerToStack(Register a) {
306 StackSlot ret = newStackSlot(SPARCKind.XWORD);
307 // STX a, [fp+offset]
308 emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
309 return ret;
310 }
311
312 @Override
313 public StackSlot emitNarrowPointerToStack(Register a) {
314 StackSlot ret = newStackSlot(SPARCKind.WORD);
315 // STW a, [fp+offset]
316 emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
317 return ret;
318 }
319
320 @Override
337
338 @Override
339 public Register emitIntAdd(Register a, Register b) {
340 Register ret = newRegister();
341 emitOp3(0b10, ret, 0b00000, a, b); // ADD a, b, ret
342 return ret;
343 }
344
345 private void emitMove(Register to, Register from) {
346 if (to != from) {
347 emitOp3(0b10, to, 0b000010, from, SPARC.g0); // OR from, g0, to
348 }
349 }
350
351 @Override
352 public void emitIntRet(Register a) {
353 emitPointerRet(a);
354 }
355
356 @Override
357 public void emitFloatRet(Register a) {
358 assert a == SPARC.f0 : "Unimplemented";
359 emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8); // JMPL [i7+8], g0
360 emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
361 }
362
363 @Override
364 public void emitPointerRet(Register a) {
365 emitMove(SPARC.i0, a);
366 emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8); // JMPL [i7+8], g0
367 emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
368 }
369
370 @Override
371 public void emitTrap(DebugInfo info) {
372 recordImplicitException(info);
373 emitOp3(0b11, SPARC.g0, 0b001011, SPARC.g0, 0); // LDX [g0+0], g0
374 }
375
376 @Override
377 public DataSectionReference emitDataItem(HotSpotConstant c) {
378 if (c.isCompressed()) {
379 data.align(4);
380 } else {
381 data.align(8);
382 }
383 return super.emitDataItem(c);
384 }
385
386 @Override
387 public void emitCall(long addr) {
388 Register dst = emitLoadLong(addr);
389 emitOp3(0b10, SPARC.o7, 0b111000, dst, 0); // JMPL [dst+0], o7
390 emitNop();
391 }
392
393 @Override
394 public void emitLoad(AllocatableValue av, Object prim) {
395 if (av instanceof RegisterValue) {
396 Register reg = ((RegisterValue) av).getRegister();
397 RegisterCategory cat = reg.getRegisterCategory();
398 if (cat.equals(SPARC.FPUs)) {
399 emitLoadFloat(reg, (Float) prim, scratchRegister);
400 } else if (cat.equals(SPARC.FPUd)) {
401 emitLoadDouble(reg, (Double) prim, scratchRegister);
402 } else if (prim instanceof Integer) {
403 emitLoadInt(reg, (Integer) prim);
404 } else if (prim instanceof Long) {
405 emitLoadLong(reg, (Long) prim);
406 }
407 } else if (av instanceof StackSlot) {
408 StackSlot slot = (StackSlot) av;
409 if (prim instanceof Float) {
410 emitFloatToStack(slot, emitLoadFloat(floatScratch, (Float) prim, scratchRegister));
411 } else if (prim instanceof Double) {
412 emitDoubleToStack(slot, emitLoadDouble(doubleScratch, (Double) prim, scratchRegister));
413 } else if (prim instanceof Integer) {
414 emitIntToStack(slot, emitLoadInt(scratchRegister, (Integer) prim));
415 } else if (prim instanceof Long) {
416 emitLongToStack(slot, emitLoadLong(scratchRegister, (Long) prim));
417 }
418 } else {
419 throw new IllegalArgumentException("Unknown value " + av);
420 }
421 }
422
423 @Override
424 public void emitCallEpilogue(CallingConvention cc) {
425 // Nothing to do here.
426 }
427
428 @Override
429 public void emitCallPrologue(CallingConvention cc, Object... prim) {
430 emitGrowStack(cc.getStackSize());
431 frameSize += cc.getStackSize();
432 AllocatableValue[] args = cc.getArguments();
433 for (int i = 0; i < args.length; i++) {
434 emitLoad(args[i], prim[i]);
435 }
436 }
437
438 }
|