Commit b3db87581213138e8a90862816051ca5f885e6d5
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
Showing
3 changed files
with
67 additions
and
12 deletions
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 |