Commit b3db87581213138e8a90862816051ca5f885e6d5

Authored by blueswir1
1 parent 53cd9273

Add function prologue, fix pointer load on Sparc64 host


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4027 c046a42c-6fe2-441c-8c8c-71466251a162
tcg/sparc/tcg-target.c
... ... @@ -71,7 +71,6 @@ static const int tcg_target_reg_alloc_order[TCG_TARGET_NB_REGS] = {
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,8 +160,11 @@ static inline int tcg_target_const_match(tcg_target_long val,
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,6 +215,10 @@ static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
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,6 +238,21 @@ static inline void tcg_out_ld_raw(TCGContext *s, int ret,
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,6 +311,12 @@ static inline void tcg_out_nop(TCGContext *s)
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,22 +324,31 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
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,7 +359,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
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,7 +550,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
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,13 +632,19 @@ void tcg_target_init(TCGContext *s)
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);
... ...
tcg/sparc/tcg-target.h
... ... @@ -75,10 +75,18 @@ enum {
75 75 #define TCG_REG_CALL_STACK TCG_REG_O6
76 76 #define TCG_TARGET_STACK_ALIGN 16
77 77  
  78 +#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
  79 +#define TCG_TARGET_STACK_MINFRAME 176
  80 +#else
  81 +#define TCG_TARGET_STACK_MINFRAME 92
  82 +#endif
  83 +
78 84 /* optional instructions */
79 85 //#define TCG_TARGET_HAS_bswap_i32
80 86 //#define TCG_TARGET_HAS_bswap_i64
81 87  
  88 +#define TCG_TARGET_NEEDS_PROLOGUE 1
  89 +
82 90 /* Note: must be synced with dyngen-exec.h */
83 91 #ifdef HOST_SOLARIS
84 92 #define TCG_AREG0 TCG_REG_G2
... ...
tcg/tcg.c
... ... @@ -1685,6 +1685,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1685 1685 macro_op_index = -1;
1686 1686 args = gen_opparam_buf;
1687 1687 op_index = 0;
  1688 +
  1689 +#ifdef TCG_TARGET_NEEDS_PROLOGUE
  1690 + tcg_target_prologue(s);
  1691 +#endif
  1692 +
1688 1693 for(;;) {
1689 1694 opc = gen_opc_buf[op_index];
1690 1695 #ifdef CONFIG_PROFILER
... ...