Revision cf7c2ca5

b/tcg/sparc/tcg-target.c
169 169
#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
170 170

  
171 171
#define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
172
#define COND_N     0x0
173
#define COND_E     0x1
174
#define COND_LE    0x2
175
#define COND_L     0x3
176
#define COND_LEU   0x4
177
#define COND_CS    0x5
178
#define COND_NEG   0x6
179
#define COND_VS    0x7
172 180
#define COND_A     0x8
181
#define COND_NE    0x9
182
#define COND_G     0xa
183
#define COND_GE    0xb
184
#define COND_GU    0xc
185
#define COND_CC    0xd
186
#define COND_POS   0xe
187
#define COND_VC    0xf
173 188
#define BA         (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
174 189

  
175 190
#define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
176 191
#define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
192
#define ARITH_ANDCC (INSN_OP(2) | INSN_OP3(0x11))
177 193
#define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
178 194
#define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
179 195
#define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x08))
196
#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x18))
180 197
#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
181 198
#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
182 199
#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
......
264 281
    if (check_fit(offset, 13))
265 282
        tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
266 283
                  INSN_IMM13(offset));
267
    else
268
        fprintf(stderr, "unimplemented %s with offset %d\n", __func__, offset);
284
    else {
285
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
286
        tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
287
                  INSN_RS2(addr));
288
    }
269 289
}
270 290

  
271 291
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
......
323 343
    tcg_out32(s, SETHI | INSN_RD(TCG_REG_G0) | 0);
324 344
}
325 345

  
346
static void tcg_out_branch(TCGContext *s, int opc, int label_index)
347
{
348
    int32_t val;
349
    TCGLabel *l = &s->labels[label_index];
350

  
351
    if (l->has_value) {
352
        val = l->u.value - (tcg_target_long)s->code_ptr;
353
        tcg_out32(s, (INSN_OP(0) | opc | INSN_OP2(0x2)
354
                      | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
355
    } else
356
        fprintf(stderr, "unimplemented branch\n");
357
}
358

  
359
static const uint8_t tcg_cond_to_bcond[10] = {
360
    [TCG_COND_EQ] = COND_E,
361
    [TCG_COND_NE] = COND_NE,
362
    [TCG_COND_LT] = COND_L,
363
    [TCG_COND_GE] = COND_GE,
364
    [TCG_COND_LE] = COND_LE,
365
    [TCG_COND_GT] = COND_G,
366
    [TCG_COND_LTU] = COND_CS,
367
    [TCG_COND_GEU] = COND_CC,
368
    [TCG_COND_LEU] = COND_LEU,
369
    [TCG_COND_GTU] = COND_GU,
370
};
371

  
372
static void tcg_out_brcond(TCGContext *s, int cond,
373
                           TCGArg arg1, TCGArg arg2, int const_arg2,
374
                           int label_index)
375
{
376
    if (const_arg2 && arg2 == 0)
377
        /* andcc r, r, %g0 */
378
        tcg_out_arithi(s, TCG_REG_G0, arg1, arg1, ARITH_ANDCC);
379
    else
380
        /* subcc r1, r2, %g0 */
381
        tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC);
382
    tcg_out_branch(s, tcg_cond_to_bcond[cond], label_index);
383
    tcg_out_nop(s);
384
}
385

  
326 386
/* Generate global QEMU prologue and epilogue code */
327 387
void tcg_target_qemu_prologue(TCGContext *s)
328 388
{
329 389
    tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
330 390
              INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
331
    tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_O0) |
391
    tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
332 392
              INSN_RS2(TCG_REG_G0));
333 393
    tcg_out_nop(s);
334 394
}
......
349 409
    case INDEX_op_goto_tb:
350 410
        if (s->tb_jmp_offset) {
351 411
            /* direct jump method */
352
            if (check_fit(args[0] - (unsigned long)s->code_ptr, 26)) {
353
                tcg_out32(s, BA |
354
                          INSN_OFF22(args[0] - (unsigned long)s->code_ptr));
355
            } else {
356
                tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, args[0]);
357
                tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
358
                          INSN_RS2(TCG_REG_G0));
359
            }
412
            tcg_out32(s, SETHI | INSN_RD(TCG_REG_I5) |
413
                      ((args[0] & 0xffffe000) >> 10));
414
            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
415
                      INSN_IMM13((args[0] & 0x1fff)));
360 416
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
361 417
        } else {
362 418
            /* indirect jump method */
......
374 430
                                 & 0x3fffffff));
375 431
            tcg_out_nop(s);
376 432
        } else {
377
            tcg_out_ld_ptr(s, TCG_REG_O7, (tcg_target_long)(s->tb_next + args[0]));
378
            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_O7) |
433
            tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
434
            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
379 435
                      INSN_RS2(TCG_REG_G0));
380 436
            tcg_out_nop(s);
381 437
        }
......
475 531
#endif
476 532

  
477 533
    case INDEX_op_brcond_i32:
478
        fprintf(stderr, "unimplemented brcond\n");
534
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
535
                       args[3]);
479 536
        break;
480 537

  
481 538
    case INDEX_op_qemu_ld8u:

Also available in: Unified diff