Commit f02ca5cbeaf86038834c1953247a1579d7921927
1 parent
b8b6a50b
Fix bit fitting checks
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4460 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
15 additions
and
11 deletions
tcg/sparc/tcg-target.c
| ... | ... | @@ -134,7 +134,12 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) |
| 134 | 134 | return 0; |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | -#define ABS(x) ((x) < 0? -(x) : (x)) | |
| 137 | +static inline int check_fit(tcg_target_long val, unsigned int bits) | |
| 138 | +{ | |
| 139 | + return ((val << ((sizeof(tcg_target_long) * 8 - bits)) | |
| 140 | + >> (sizeof(tcg_target_long) * 8 - bits)) == val); | |
| 141 | +} | |
| 142 | + | |
| 138 | 143 | /* test if a constant matches the constraint */ |
| 139 | 144 | static inline int tcg_target_const_match(tcg_target_long val, |
| 140 | 145 | const TCGArgConstraint *arg_ct) |
| ... | ... | @@ -144,9 +149,9 @@ static inline int tcg_target_const_match(tcg_target_long val, |
| 144 | 149 | ct = arg_ct->ct; |
| 145 | 150 | if (ct & TCG_CT_CONST) |
| 146 | 151 | return 1; |
| 147 | - else if ((ct & TCG_CT_CONST_S11) && ABS(val) == (ABS(val) & 0x3ff)) | |
| 152 | + else if ((ct & TCG_CT_CONST_S11) && check_fit(val, 11)) | |
| 148 | 153 | return 1; |
| 149 | - else if ((ct & TCG_CT_CONST_S13) && ABS(val) == (ABS(val) & 0xfff)) | |
| 154 | + else if ((ct & TCG_CT_CONST_S13) && check_fit(val, 13)) | |
| 150 | 155 | return 1; |
| 151 | 156 | else |
| 152 | 157 | return 0; |
| ... | ... | @@ -217,10 +222,10 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type, |
| 217 | 222 | int ret, tcg_target_long arg) |
| 218 | 223 | { |
| 219 | 224 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
| 220 | - if (arg != (arg & 0xffffffff)) | |
| 225 | + if (!check_fit(arg, 32)) | |
| 221 | 226 | fprintf(stderr, "unimplemented %s with constant %ld\n", __func__, arg); |
| 222 | 227 | #endif |
| 223 | - if (arg == (arg & 0xfff)) | |
| 228 | + if (check_fit(arg, 13)) | |
| 224 | 229 | tcg_out32(s, ARITH_OR | INSN_RD(ret) | INSN_RS1(TCG_REG_G0) | |
| 225 | 230 | INSN_IMM13(arg)); |
| 226 | 231 | else { |
| ... | ... | @@ -243,9 +248,9 @@ static inline void tcg_out_ld_ptr(TCGContext *s, int ret, |
| 243 | 248 | tcg_target_long arg) |
| 244 | 249 | { |
| 245 | 250 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
| 246 | - if (arg != (arg & 0xffffffff)) | |
| 251 | + if (!check_fit(arg, 32)) | |
| 247 | 252 | fprintf(stderr, "unimplemented %s with offset %ld\n", __func__, arg); |
| 248 | - if (arg != (arg & 0xfff)) | |
| 253 | + if (!check_fit(arg, 13)) | |
| 249 | 254 | tcg_out32(s, SETHI | INSN_RD(ret) | (((uint32_t)arg & 0xfffffc00) >> 10)); |
| 250 | 255 | tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) | |
| 251 | 256 | INSN_IMM13(arg & 0x3ff)); |
| ... | ... | @@ -256,7 +261,7 @@ static inline void tcg_out_ld_ptr(TCGContext *s, int ret, |
| 256 | 261 | |
| 257 | 262 | static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op) |
| 258 | 263 | { |
| 259 | - if (offset == (offset & 0xfff)) | |
| 264 | + if (check_fit(offset, 13)) | |
| 260 | 265 | tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) | |
| 261 | 266 | INSN_IMM13(offset)); |
| 262 | 267 | else |
| ... | ... | @@ -306,7 +311,7 @@ static inline void tcg_out_sety(TCGContext *s, tcg_target_long val) |
| 306 | 311 | static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) |
| 307 | 312 | { |
| 308 | 313 | if (val != 0) { |
| 309 | - if (val == (val & 0xfff)) | |
| 314 | + if (check_fit(val, 13)) | |
| 310 | 315 | tcg_out_arithi(s, reg, reg, val, ARITH_ADD); |
| 311 | 316 | else |
| 312 | 317 | fprintf(stderr, "unimplemented addi %ld\n", (long)val); |
| ... | ... | @@ -344,8 +349,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
| 344 | 349 | case INDEX_op_goto_tb: |
| 345 | 350 | if (s->tb_jmp_offset) { |
| 346 | 351 | /* direct jump method */ |
| 347 | - if (ABS(args[0] - (unsigned long)s->code_ptr) == | |
| 348 | - (ABS(args[0] - (unsigned long)s->code_ptr) & 0x1fffff)) { | |
| 352 | + if (check_fit(args[0] - (unsigned long)s->code_ptr, 26)) { | |
| 349 | 353 | tcg_out32(s, BA | |
| 350 | 354 | INSN_OFF22(args[0] - (unsigned long)s->code_ptr)); |
| 351 | 355 | } else { | ... | ... |