Revision f02ca5cb

b/tcg/sparc/tcg-target.c
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 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 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 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 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 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 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 {

Also available in: Unified diff