Commit 57e49b40745ceb6c198cc58274b705afb5f20493
1 parent
d4929d58
Fix constant checks on Sparc64 host
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4486 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
17 additions
and
12 deletions
tcg/sparc/tcg-target.c
| @@ -87,10 +87,15 @@ static const int tcg_target_call_oarg_regs[2] = { | @@ -87,10 +87,15 @@ static const int tcg_target_call_oarg_regs[2] = { | ||
| 87 | TCG_REG_O1, | 87 | TCG_REG_O1, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | -static inline int check_fit(tcg_target_long val, unsigned int bits) | 90 | +static inline int check_fit_tl(tcg_target_long val, unsigned int bits) |
| 91 | { | 91 | { |
| 92 | - return ((val << ((sizeof(tcg_target_long) * 8 - bits)) | ||
| 93 | - >> (sizeof(tcg_target_long) * 8 - bits)) == val); | 92 | + return (val << ((sizeof(tcg_target_long) * 8 - bits)) |
| 93 | + >> (sizeof(tcg_target_long) * 8 - bits)) == val; | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +static inline int check_fit_i32(uint32_t val, unsigned int bits) | ||
| 97 | +{ | ||
| 98 | + return ((val << (32 - bits)) >> (32 - bits)) == val; | ||
| 94 | } | 99 | } |
| 95 | 100 | ||
| 96 | static void patch_reloc(uint8_t *code_ptr, int type, | 101 | static void patch_reloc(uint8_t *code_ptr, int type, |
| @@ -106,7 +111,7 @@ static void patch_reloc(uint8_t *code_ptr, int type, | @@ -106,7 +111,7 @@ static void patch_reloc(uint8_t *code_ptr, int type, | ||
| 106 | case R_SPARC_WDISP22: | 111 | case R_SPARC_WDISP22: |
| 107 | value -= (long)code_ptr; | 112 | value -= (long)code_ptr; |
| 108 | value >>= 2; | 113 | value >>= 2; |
| 109 | - if (!check_fit(value, 22)) | 114 | + if (!check_fit_tl(value, 22)) |
| 110 | tcg_abort(); | 115 | tcg_abort(); |
| 111 | *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value; | 116 | *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value; |
| 112 | break; | 117 | break; |
| @@ -158,9 +163,9 @@ static inline int tcg_target_const_match(tcg_target_long val, | @@ -158,9 +163,9 @@ static inline int tcg_target_const_match(tcg_target_long val, | ||
| 158 | ct = arg_ct->ct; | 163 | ct = arg_ct->ct; |
| 159 | if (ct & TCG_CT_CONST) | 164 | if (ct & TCG_CT_CONST) |
| 160 | return 1; | 165 | return 1; |
| 161 | - else if ((ct & TCG_CT_CONST_S11) && check_fit(val, 11)) | 166 | + else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) |
| 162 | return 1; | 167 | return 1; |
| 163 | - else if ((ct & TCG_CT_CONST_S13) && check_fit(val, 13)) | 168 | + else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) |
| 164 | return 1; | 169 | return 1; |
| 165 | else | 170 | else |
| 166 | return 0; | 171 | return 0; |
| @@ -248,10 +253,10 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type, | @@ -248,10 +253,10 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type, | ||
| 248 | int ret, tcg_target_long arg) | 253 | int ret, tcg_target_long arg) |
| 249 | { | 254 | { |
| 250 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) | 255 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
| 251 | - if (!check_fit(arg, 32)) | 256 | + if (!check_fit_tl(arg, 32) && (arg & ~0xffffffff) != 0) |
| 252 | fprintf(stderr, "unimplemented %s with constant %ld\n", __func__, arg); | 257 | fprintf(stderr, "unimplemented %s with constant %ld\n", __func__, arg); |
| 253 | #endif | 258 | #endif |
| 254 | - if (check_fit(arg, 13)) | 259 | + if (check_fit_i32(arg, 13)) |
| 255 | tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) | | 260 | tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) | |
| 256 | INSN_IMM13(arg)); | 261 | INSN_IMM13(arg)); |
| 257 | else { | 262 | else { |
| @@ -274,9 +279,9 @@ static inline void tcg_out_ld_ptr(TCGContext *s, int ret, | @@ -274,9 +279,9 @@ static inline void tcg_out_ld_ptr(TCGContext *s, int ret, | ||
| 274 | tcg_target_long arg) | 279 | tcg_target_long arg) |
| 275 | { | 280 | { |
| 276 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) | 281 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
| 277 | - if (!check_fit(arg, 32)) | 282 | + if (!check_fit_tl(arg, 32) && (arg & ~0xffffffff) != 0) |
| 278 | fprintf(stderr, "unimplemented %s with offset %ld\n", __func__, arg); | 283 | fprintf(stderr, "unimplemented %s with offset %ld\n", __func__, arg); |
| 279 | - if (!check_fit(arg, 13)) | 284 | + if (!check_fit_i32(arg, 13)) |
| 280 | tcg_out32(s, SETHI | INSN_RD(ret) | (((uint32_t)arg & 0xfffffc00) >> 10)); | 285 | tcg_out32(s, SETHI | INSN_RD(ret) | (((uint32_t)arg & 0xfffffc00) >> 10)); |
| 281 | tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) | | 286 | tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) | |
| 282 | INSN_IMM13(arg & 0x3ff)); | 287 | INSN_IMM13(arg & 0x3ff)); |
| @@ -287,7 +292,7 @@ static inline void tcg_out_ld_ptr(TCGContext *s, int ret, | @@ -287,7 +292,7 @@ static inline void tcg_out_ld_ptr(TCGContext *s, int ret, | ||
| 287 | 292 | ||
| 288 | static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op) | 293 | static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op) |
| 289 | { | 294 | { |
| 290 | - if (check_fit(offset, 13)) | 295 | + if (check_fit_tl(offset, 13)) |
| 291 | tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) | | 296 | tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) | |
| 292 | INSN_IMM13(offset)); | 297 | INSN_IMM13(offset)); |
| 293 | else { | 298 | else { |
| @@ -340,7 +345,7 @@ static inline void tcg_out_sety(TCGContext *s, tcg_target_long val) | @@ -340,7 +345,7 @@ static inline void tcg_out_sety(TCGContext *s, tcg_target_long val) | ||
| 340 | static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) | 345 | static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) |
| 341 | { | 346 | { |
| 342 | if (val != 0) { | 347 | if (val != 0) { |
| 343 | - if (check_fit(val, 13)) | 348 | + if (check_fit_tl(val, 13)) |
| 344 | tcg_out_arithi(s, reg, reg, val, ARITH_ADD); | 349 | tcg_out_arithi(s, reg, reg, val, ARITH_ADD); |
| 345 | else { | 350 | else { |
| 346 | tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val); | 351 | tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val); |