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,7 +71,6 @@ static const int tcg_target_reg_alloc_order[TCG_TARGET_NB_REGS] = {
71 TCG_REG_I2, 71 TCG_REG_I2,
72 TCG_REG_I3, 72 TCG_REG_I3,
73 TCG_REG_I4, 73 TCG_REG_I4,
74 - TCG_REG_I5,  
75 }; 74 };
76 75
77 static const int tcg_target_call_iarg_regs[6] = { 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,8 +160,11 @@ static inline int tcg_target_const_match(tcg_target_long val,
161 #define INSN_RS2(x) (x) 160 #define INSN_RS2(x) (x)
162 161
163 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) 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 #define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00)) 169 #define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00))
168 #define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01)) 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,6 +215,10 @@ static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
213 static inline void tcg_out_movi(TCGContext *s, TCGType type, 215 static inline void tcg_out_movi(TCGContext *s, TCGType type,
214 int ret, tcg_target_long arg) 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 if (arg == (arg & 0xfff)) 222 if (arg == (arg & 0xfff))
217 tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) | 223 tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) |
218 INSN_IMM13(arg)); 224 INSN_IMM13(arg));
@@ -232,6 +238,21 @@ static inline void tcg_out_ld_raw(TCGContext *s, int ret, @@ -232,6 +238,21 @@ static inline void tcg_out_ld_raw(TCGContext *s, int ret,
232 INSN_IMM13(arg & 0x3ff)); 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 static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op) 256 static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
236 { 257 {
237 if (offset == (offset & 0xfff)) 258 if (offset == (offset & 0xfff))
@@ -290,6 +311,12 @@ static inline void tcg_out_nop(TCGContext *s) @@ -290,6 +311,12 @@ static inline void tcg_out_nop(TCGContext *s)
290 tcg_out32(s, SETHI | INSN_RD(TCG_REG_G0) | 0); 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 static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, 320 static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
294 const int *const_args) 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,22 +324,31 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
297 324
298 switch (opc) { 325 switch (opc) {
299 case INDEX_op_exit_tb: 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 INSN_IMM13(8)); 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 break; 332 break;
305 case INDEX_op_goto_tb: 333 case INDEX_op_goto_tb:
306 if (s->tb_jmp_offset) { 334 if (s->tb_jmp_offset) {
307 /* direct jump method */ 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 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; 345 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
310 } else { 346 } else {
311 /* indirect jump method */ 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 tcg_out_nop(s); 352 tcg_out_nop(s);
317 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; 353 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
318 break; 354 break;
@@ -323,7 +359,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, @@ -323,7 +359,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
323 & 0x3fffffff)); 359 & 0x3fffffff));
324 tcg_out_nop(s); 360 tcg_out_nop(s);
325 } else { 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 tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_O7) | 363 tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_O7) |
328 INSN_RS2(TCG_REG_G0)); 364 INSN_RS2(TCG_REG_G0));
329 tcg_out_nop(s); 365 tcg_out_nop(s);
@@ -514,7 +550,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, @@ -514,7 +550,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
514 550
515 static const TCGTargetOpDef sparc_op_defs[] = { 551 static const TCGTargetOpDef sparc_op_defs[] = {
516 { INDEX_op_exit_tb, { } }, 552 { INDEX_op_exit_tb, { } },
517 - { INDEX_op_goto_tb, { "r" } }, 553 + { INDEX_op_goto_tb, { } },
518 { INDEX_op_call, { "ri" } }, 554 { INDEX_op_call, { "ri" } },
519 { INDEX_op_jmp, { "ri" } }, 555 { INDEX_op_jmp, { "ri" } },
520 { INDEX_op_br, { } }, 556 { INDEX_op_br, { } },
@@ -596,13 +632,19 @@ void tcg_target_init(TCGContext *s) @@ -596,13 +632,19 @@ void tcg_target_init(TCGContext *s)
596 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); 632 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
597 #endif 633 #endif
598 tcg_regset_set32(tcg_target_call_clobber_regs, 0, 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 (1 << TCG_REG_O0) | 642 (1 << TCG_REG_O0) |
600 (1 << TCG_REG_O1) | 643 (1 << TCG_REG_O1) |
601 (1 << TCG_REG_O2) | 644 (1 << TCG_REG_O2) |
602 (1 << TCG_REG_O3) | 645 (1 << TCG_REG_O3) |
603 (1 << TCG_REG_O4) | 646 (1 << TCG_REG_O4) |
604 (1 << TCG_REG_O5) | 647 (1 << TCG_REG_O5) |
605 - (1 << TCG_REG_O6) |  
606 (1 << TCG_REG_O7)); 648 (1 << TCG_REG_O7));
607 649
608 tcg_regset_clear(s->reserved_regs); 650 tcg_regset_clear(s->reserved_regs);
tcg/sparc/tcg-target.h
@@ -75,10 +75,18 @@ enum { @@ -75,10 +75,18 @@ enum {
75 #define TCG_REG_CALL_STACK TCG_REG_O6 75 #define TCG_REG_CALL_STACK TCG_REG_O6
76 #define TCG_TARGET_STACK_ALIGN 16 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 /* optional instructions */ 84 /* optional instructions */
79 //#define TCG_TARGET_HAS_bswap_i32 85 //#define TCG_TARGET_HAS_bswap_i32
80 //#define TCG_TARGET_HAS_bswap_i64 86 //#define TCG_TARGET_HAS_bswap_i64
81 87
  88 +#define TCG_TARGET_NEEDS_PROLOGUE 1
  89 +
82 /* Note: must be synced with dyngen-exec.h */ 90 /* Note: must be synced with dyngen-exec.h */
83 #ifdef HOST_SOLARIS 91 #ifdef HOST_SOLARIS
84 #define TCG_AREG0 TCG_REG_G2 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,6 +1685,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1685 macro_op_index = -1; 1685 macro_op_index = -1;
1686 args = gen_opparam_buf; 1686 args = gen_opparam_buf;
1687 op_index = 0; 1687 op_index = 0;
  1688 +
  1689 +#ifdef TCG_TARGET_NEEDS_PROLOGUE
  1690 + tcg_target_prologue(s);
  1691 +#endif
  1692 +
1688 for(;;) { 1693 for(;;) {
1689 opc = gen_opc_buf[op_index]; 1694 opc = gen_opc_buf[op_index];
1690 #ifdef CONFIG_PROFILER 1695 #ifdef CONFIG_PROFILER