Revision dbfe80e1
b/tcg/sparc/tcg-target.c | ||
---|---|---|
194 | 194 |
#define INSN_RS2(x) (x) |
195 | 195 |
#define INSN_ASI(x) ((x) << 5) |
196 | 196 |
|
197 |
#define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff)) |
|
197 | 198 |
#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) |
198 | 199 |
#define INSN_OFF19(x) (((x) >> 2) & 0x07ffff) |
199 | 200 |
#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff) |
... | ... | |
217 | 218 |
#define COND_VC 0xf |
218 | 219 |
#define BA (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2)) |
219 | 220 |
|
221 |
#define MOVCC_ICC (1 << 18) |
|
222 |
#define MOVCC_XCC (1 << 18 | 1 << 12) |
|
223 |
|
|
220 | 224 |
#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00)) |
221 | 225 |
#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10)) |
222 | 226 |
#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01)) |
... | ... | |
233 | 237 |
#define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09)) |
234 | 238 |
#define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d)) |
235 | 239 |
#define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d)) |
240 |
#define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c)) |
|
236 | 241 |
|
237 | 242 |
#define SHIFT_SLL (INSN_OP(2) | INSN_OP3(0x25)) |
238 | 243 |
#define SHIFT_SRL (INSN_OP(2) | INSN_OP3(0x26)) |
... | ... | |
580 | 585 |
} |
581 | 586 |
#endif |
582 | 587 |
|
588 |
static void tcg_out_setcond_i32(TCGContext *s, int cond, TCGArg ret, |
|
589 |
TCGArg c1, TCGArg c2, int c2const) |
|
590 |
{ |
|
591 |
TCGArg t; |
|
592 |
|
|
593 |
/* For 32-bit comparisons, we can play games with ADDX/SUBX. */ |
|
594 |
switch (cond) { |
|
595 |
case TCG_COND_EQ: |
|
596 |
case TCG_COND_NE: |
|
597 |
if (c2 != 0) { |
|
598 |
tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR); |
|
599 |
} |
|
600 |
c1 = TCG_REG_G0, c2 = ret, c2const = 0; |
|
601 |
cond = (cond == TCG_COND_EQ ? TCG_COND_LEU : TCG_COND_LTU); |
|
602 |
break; |
|
603 |
|
|
604 |
case TCG_COND_GTU: |
|
605 |
case TCG_COND_GEU: |
|
606 |
if (c2const && c2 != 0) { |
|
607 |
tcg_out_movi_imm13(s, TCG_REG_I5, c2); |
|
608 |
c2 = TCG_REG_I5; |
|
609 |
} |
|
610 |
t = c1, c1 = c2, c2 = t, c2const = 0; |
|
611 |
cond = tcg_swap_cond(cond); |
|
612 |
break; |
|
613 |
|
|
614 |
case TCG_COND_LTU: |
|
615 |
case TCG_COND_LEU: |
|
616 |
break; |
|
617 |
|
|
618 |
default: |
|
619 |
tcg_out_cmp(s, c1, c2, c2const); |
|
620 |
#if defined(__sparc_v9__) || defined(__sparc_v8plus__) |
|
621 |
tcg_out_movi_imm13(s, ret, 0); |
|
622 |
tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret) |
|
623 |
| INSN_RS1(tcg_cond_to_bcond[cond]) |
|
624 |
| MOVCC_ICC | INSN_IMM11(1)); |
|
625 |
#else |
|
626 |
t = gen_new_label(); |
|
627 |
tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), t); |
|
628 |
tcg_out_movi_imm13(s, ret, 1); |
|
629 |
tcg_out_movi_imm13(s, ret, 0); |
|
630 |
tcg_out_label(s, t, (tcg_target_long)s->code_ptr); |
|
631 |
#endif |
|
632 |
return; |
|
633 |
} |
|
634 |
|
|
635 |
tcg_out_cmp(s, c1, c2, c2const); |
|
636 |
if (cond == TCG_COND_LTU) { |
|
637 |
tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX); |
|
638 |
} else { |
|
639 |
tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX); |
|
640 |
} |
|
641 |
} |
|
642 |
|
|
643 |
#if TCG_TARGET_REG_BITS == 64 |
|
644 |
static void tcg_out_setcond_i64(TCGContext *s, int cond, TCGArg ret, |
|
645 |
TCGArg c1, TCGArg c2, int c2const) |
|
646 |
{ |
|
647 |
tcg_out_cmp(s, c1, c2, c2const); |
|
648 |
tcg_out_movi_imm13(s, ret, 0); |
|
649 |
tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret) |
|
650 |
| INSN_RS1(tcg_cond_to_bcond[cond]) |
|
651 |
| MOVCC_XCC | INSN_IMM11(1)); |
|
652 |
} |
|
653 |
#else |
|
654 |
static void tcg_out_setcond2_i32(TCGContext *s, int cond, TCGArg ret, |
|
655 |
TCGArg al, TCGArg ah, |
|
656 |
TCGArg bl, int blconst, |
|
657 |
TCGArg bh, int bhconst) |
|
658 |
{ |
|
659 |
int lab; |
|
660 |
|
|
661 |
switch (cond) { |
|
662 |
case TCG_COND_EQ: |
|
663 |
tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_I5, al, bl, blconst); |
|
664 |
tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst); |
|
665 |
tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_AND); |
|
666 |
break; |
|
667 |
|
|
668 |
case TCG_COND_NE: |
|
669 |
tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_I5, al, al, blconst); |
|
670 |
tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst); |
|
671 |
tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR); |
|
672 |
break; |
|
673 |
|
|
674 |
default: |
|
675 |
lab = gen_new_label(); |
|
676 |
|
|
677 |
tcg_out_cmp(s, ah, bh, bhconst); |
|
678 |
tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), lab); |
|
679 |
tcg_out_movi_imm13(s, ret, 1); |
|
680 |
tcg_out_branch_i32(s, INSN_COND(COND_NE, 1), lab); |
|
681 |
tcg_out_movi_imm13(s, ret, 0); |
|
682 |
|
|
683 |
tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), ret, al, bl, blconst); |
|
684 |
|
|
685 |
tcg_out_label(s, lab, (tcg_target_long)s->code_ptr); |
|
686 |
break; |
|
687 |
} |
|
688 |
} |
|
689 |
#endif |
|
690 |
|
|
583 | 691 |
/* Generate global QEMU prologue and epilogue code */ |
584 | 692 |
void tcg_target_qemu_prologue(TCGContext *s) |
585 | 693 |
{ |
... | ... | |
1146 | 1254 |
tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1], |
1147 | 1255 |
args[3]); |
1148 | 1256 |
break; |
1257 |
case INDEX_op_setcond_i32: |
|
1258 |
tcg_out_setcond_i32(s, args[3], args[0], args[1], |
|
1259 |
args[2], const_args[2]); |
|
1260 |
break; |
|
1261 |
|
|
1149 | 1262 |
#if TCG_TARGET_REG_BITS == 32 |
1150 | 1263 |
case INDEX_op_brcond2_i32: |
1151 | 1264 |
tcg_out_brcond2_i32(s, args[4], args[0], args[1], |
1152 | 1265 |
args[2], const_args[2], |
1153 | 1266 |
args[3], const_args[3], args[5]); |
1154 | 1267 |
break; |
1268 |
case INDEX_op_setcond2_i32: |
|
1269 |
tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2], |
|
1270 |
args[3], const_args[3], |
|
1271 |
args[4], const_args[4]); |
|
1272 |
break; |
|
1155 | 1273 |
case INDEX_op_add2_i32: |
1156 | 1274 |
tcg_out_arithc(s, args[0], args[2], args[4], const_args[4], |
1157 | 1275 |
ARITH_ADDCC); |
... | ... | |
1257 | 1375 |
tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1], |
1258 | 1376 |
args[3]); |
1259 | 1377 |
break; |
1378 |
case INDEX_op_setcond_i64: |
|
1379 |
tcg_out_setcond_i64(s, args[3], args[0], args[1], |
|
1380 |
args[2], const_args[2]); |
|
1381 |
break; |
|
1382 |
|
|
1260 | 1383 |
case INDEX_op_qemu_ld64: |
1261 | 1384 |
tcg_out_qemu_ld(s, args, 3); |
1262 | 1385 |
break; |
... | ... | |
1309 | 1432 |
{ INDEX_op_sar_i32, { "r", "r", "rJ" } }, |
1310 | 1433 |
|
1311 | 1434 |
{ INDEX_op_brcond_i32, { "r", "rJ" } }, |
1435 |
{ INDEX_op_setcond_i32, { "r", "r", "rJ" } }, |
|
1436 |
|
|
1312 | 1437 |
#if TCG_TARGET_REG_BITS == 32 |
1313 | 1438 |
{ INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } }, |
1439 |
{ INDEX_op_setcond2_i32, { "r", "r", "r", "rJ", "rJ" } }, |
|
1314 | 1440 |
{ INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } }, |
1315 | 1441 |
{ INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } }, |
1316 | 1442 |
{ INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } }, |
... | ... | |
1362 | 1488 |
{ INDEX_op_ext32u_i64, { "r", "ri" } }, |
1363 | 1489 |
|
1364 | 1490 |
{ INDEX_op_brcond_i64, { "r", "rJ" } }, |
1491 |
{ INDEX_op_setcond_i64, { "r", "r", "rJ" } }, |
|
1365 | 1492 |
#endif |
1366 | 1493 |
{ -1 }, |
1367 | 1494 |
}; |
Also available in: Unified diff