Revision b3db8758 tcg/sparc/tcg-target.c
b/tcg/sparc/tcg-target.c | ||
---|---|---|
71 | 71 |
TCG_REG_I2, |
72 | 72 |
TCG_REG_I3, |
73 | 73 |
TCG_REG_I4, |
74 |
TCG_REG_I5, |
|
75 | 74 |
}; |
76 | 75 |
|
77 | 76 |
static const int tcg_target_call_iarg_regs[6] = { |
... | ... | |
161 | 160 |
#define INSN_RS2(x) (x) |
162 | 161 |
|
163 | 162 |
#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) |
163 |
#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff) |
|
164 | 164 |
|
165 |
#define INSN_COND(x, a) (((x) << 25) | ((a) << 29) |
|
165 |
#define INSN_COND(x, a) (((x) << 25) | ((a) << 29)) |
|
166 |
#define COND_A 0x8 |
|
167 |
#define BA (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2)) |
|
166 | 168 |
|
167 | 169 |
#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00)) |
168 | 170 |
#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01)) |
... | ... | |
213 | 215 |
static inline void tcg_out_movi(TCGContext *s, TCGType type, |
214 | 216 |
int ret, tcg_target_long arg) |
215 | 217 |
{ |
218 |
#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
|
219 |
if (arg != (arg & 0xffffffff)) |
|
220 |
fprintf(stderr, "unimplemented %s with constant %ld\n", __func__, arg); |
|
221 |
#endif |
|
216 | 222 |
if (arg == (arg & 0xfff)) |
217 | 223 |
tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) | |
218 | 224 |
INSN_IMM13(arg)); |
... | ... | |
232 | 238 |
INSN_IMM13(arg & 0x3ff)); |
233 | 239 |
} |
234 | 240 |
|
241 |
static inline void tcg_out_ld_ptr(TCGContext *s, int ret, |
|
242 |
tcg_target_long arg) |
|
243 |
{ |
|
244 |
#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
|
245 |
if (arg != (arg & 0xffffffff)) |
|
246 |
fprintf(stderr, "unimplemented %s with offset %ld\n", __func__, arg); |
|
247 |
if (arg != (arg & 0xfff)) |
|
248 |
tcg_out32(s, SETHI | INSN_RD(ret) | (((uint32_t)arg & 0xfffffc00) >> 10)); |
|
249 |
tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) | |
|
250 |
INSN_IMM13(arg & 0x3ff)); |
|
251 |
#else |
|
252 |
tcg_out_ld_raw(s, ret, arg); |
|
253 |
#endif |
|
254 |
} |
|
255 |
|
|
235 | 256 |
static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op) |
236 | 257 |
{ |
237 | 258 |
if (offset == (offset & 0xfff)) |
... | ... | |
290 | 311 |
tcg_out32(s, SETHI | INSN_RD(TCG_REG_G0) | 0); |
291 | 312 |
} |
292 | 313 |
|
314 |
static inline void tcg_target_prologue(TCGContext *s) |
|
315 |
{ |
|
316 |
tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) | |
|
317 |
INSN_IMM13(-TCG_TARGET_STACK_MINFRAME)); |
|
318 |
} |
|
319 |
|
|
293 | 320 |
static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
294 | 321 |
const int *const_args) |
295 | 322 |
{ |
... | ... | |
297 | 324 |
|
298 | 325 |
switch (opc) { |
299 | 326 |
case INDEX_op_exit_tb: |
300 |
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_O0, args[0]);
|
|
301 |
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_O7) |
|
|
327 |
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
|
|
328 |
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
|
|
302 | 329 |
INSN_IMM13(8)); |
303 |
tcg_out_nop(s); |
|
330 |
tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) | |
|
331 |
INSN_RS2(TCG_REG_G0)); |
|
304 | 332 |
break; |
305 | 333 |
case INDEX_op_goto_tb: |
306 | 334 |
if (s->tb_jmp_offset) { |
307 | 335 |
/* direct jump method */ |
308 |
tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_I5, args[0]); |
|
336 |
if (ABS(args[0] - (unsigned long)s->code_ptr) == |
|
337 |
(ABS(args[0] - (unsigned long)s->code_ptr) & 0x1fffff)) { |
|
338 |
tcg_out32(s, BA | |
|
339 |
INSN_OFF22(args[0] - (unsigned long)s->code_ptr)); |
|
340 |
} else { |
|
341 |
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, args[0]); |
|
342 |
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) | |
|
343 |
INSN_RS2(TCG_REG_G0)); |
|
344 |
} |
|
309 | 345 |
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; |
310 | 346 |
} else { |
311 | 347 |
/* indirect jump method */ |
312 |
tcg_out_ld_raw(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0])); |
|
348 |
tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0])); |
|
349 |
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) | |
|
350 |
INSN_RS2(TCG_REG_G0)); |
|
313 | 351 |
} |
314 |
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) | |
|
315 |
INSN_RS2(TCG_REG_G0)); |
|
316 | 352 |
tcg_out_nop(s); |
317 | 353 |
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; |
318 | 354 |
break; |
... | ... | |
323 | 359 |
& 0x3fffffff)); |
324 | 360 |
tcg_out_nop(s); |
325 | 361 |
} else { |
326 |
tcg_out_ld_raw(s, TCG_REG_O7, (tcg_target_long)(s->tb_next + args[0]));
|
|
362 |
tcg_out_ld_ptr(s, TCG_REG_O7, (tcg_target_long)(s->tb_next + args[0]));
|
|
327 | 363 |
tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_O7) | |
328 | 364 |
INSN_RS2(TCG_REG_G0)); |
329 | 365 |
tcg_out_nop(s); |
... | ... | |
514 | 550 |
|
515 | 551 |
static const TCGTargetOpDef sparc_op_defs[] = { |
516 | 552 |
{ INDEX_op_exit_tb, { } }, |
517 |
{ INDEX_op_goto_tb, { "r" } },
|
|
553 |
{ INDEX_op_goto_tb, { } }, |
|
518 | 554 |
{ INDEX_op_call, { "ri" } }, |
519 | 555 |
{ INDEX_op_jmp, { "ri" } }, |
520 | 556 |
{ INDEX_op_br, { } }, |
... | ... | |
596 | 632 |
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); |
597 | 633 |
#endif |
598 | 634 |
tcg_regset_set32(tcg_target_call_clobber_regs, 0, |
635 |
(1 << TCG_REG_G1) | |
|
636 |
(1 << TCG_REG_G2) | |
|
637 |
(1 << TCG_REG_G3) | |
|
638 |
(1 << TCG_REG_G4) | |
|
639 |
(1 << TCG_REG_G5) | |
|
640 |
(1 << TCG_REG_G6) | |
|
641 |
(1 << TCG_REG_G7) | |
|
599 | 642 |
(1 << TCG_REG_O0) | |
600 | 643 |
(1 << TCG_REG_O1) | |
601 | 644 |
(1 << TCG_REG_O2) | |
602 | 645 |
(1 << TCG_REG_O3) | |
603 | 646 |
(1 << TCG_REG_O4) | |
604 | 647 |
(1 << TCG_REG_O5) | |
605 |
(1 << TCG_REG_O6) | |
|
606 | 648 |
(1 << TCG_REG_O7)); |
607 | 649 |
|
608 | 650 |
tcg_regset_clear(s->reserved_regs); |
Also available in: Unified diff