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 | 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 | ... | ... |