Revision b3db8758 tcg/sparc/tcg-target.c

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

Also available in: Unified diff