Revision 56f4927e tcg/sparc/tcg-target.c
b/tcg/sparc/tcg-target.c | ||
---|---|---|
479 | 479 |
[TCG_COND_GTU] = COND_GU, |
480 | 480 |
}; |
481 | 481 |
|
482 |
static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const) |
|
483 |
{ |
|
484 |
if (c2const) |
|
485 |
tcg_out_arithi(s, TCG_REG_G0, c1, c2, ARITH_SUBCC); |
|
486 |
else |
|
487 |
tcg_out_arith(s, TCG_REG_G0, c1, c2, ARITH_SUBCC); |
|
488 |
} |
|
489 |
|
|
482 | 490 |
static void tcg_out_brcond_i32(TCGContext *s, int cond, |
483 | 491 |
TCGArg arg1, TCGArg arg2, int const_arg2, |
484 | 492 |
int label_index) |
485 | 493 |
{ |
486 |
if (const_arg2 && arg2 == 0) |
|
487 |
/* orcc %g0, r, %g0 */ |
|
488 |
tcg_out_arith(s, TCG_REG_G0, TCG_REG_G0, arg1, ARITH_ORCC); |
|
489 |
else |
|
490 |
/* subcc r1, r2, %g0 */ |
|
491 |
tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC); |
|
494 |
tcg_out_cmp(s, arg1, arg2, const_arg2); |
|
492 | 495 |
tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index); |
493 | 496 |
tcg_out_nop(s); |
494 | 497 |
} |
... | ... | |
498 | 501 |
TCGArg arg1, TCGArg arg2, int const_arg2, |
499 | 502 |
int label_index) |
500 | 503 |
{ |
501 |
if (const_arg2 && arg2 == 0) |
|
502 |
/* orcc %g0, r, %g0 */ |
|
503 |
tcg_out_arith(s, TCG_REG_G0, TCG_REG_G0, arg1, ARITH_ORCC); |
|
504 |
else |
|
505 |
/* subcc r1, r2, %g0 */ |
|
506 |
tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC); |
|
504 |
tcg_out_cmp(s, arg1, arg2, const_arg2); |
|
507 | 505 |
tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index); |
508 | 506 |
tcg_out_nop(s); |
509 | 507 |
} |
508 |
#else |
|
509 |
static void tcg_out_brcond2_i32(TCGContext *s, int cond, |
|
510 |
TCGArg al, TCGArg ah, |
|
511 |
TCGArg bl, int blconst, |
|
512 |
TCGArg bh, int bhconst, int label_dest) |
|
513 |
{ |
|
514 |
int cc, label_next = gen_new_label(); |
|
515 |
|
|
516 |
tcg_out_cmp(s, ah, bh, bhconst); |
|
517 |
|
|
518 |
/* Note that we fill one of the delay slots with the second compare. */ |
|
519 |
switch (cond) { |
|
520 |
case TCG_COND_EQ: |
|
521 |
cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0); |
|
522 |
tcg_out_branch_i32(s, cc, label_next); |
|
523 |
tcg_out_cmp(s, al, bl, blconst); |
|
524 |
cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_EQ], 0); |
|
525 |
tcg_out_branch_i32(s, cc, label_dest); |
|
526 |
break; |
|
527 |
|
|
528 |
case TCG_COND_NE: |
|
529 |
cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0); |
|
530 |
tcg_out_branch_i32(s, cc, label_dest); |
|
531 |
tcg_out_cmp(s, al, bl, blconst); |
|
532 |
tcg_out_branch_i32(s, cc, label_dest); |
|
533 |
break; |
|
534 |
|
|
535 |
default: |
|
536 |
/* ??? One could fairly easily special-case 64-bit unsigned |
|
537 |
compares against 32-bit zero-extended constants. For instance, |
|
538 |
we know that (unsigned)AH < 0 is false and need not emit it. |
|
539 |
Similarly, (unsigned)AH > 0 being true implies AH != 0, so the |
|
540 |
second branch will never be taken. */ |
|
541 |
cc = INSN_COND(tcg_cond_to_bcond[cond], 0); |
|
542 |
tcg_out_branch_i32(s, cc, label_dest); |
|
543 |
tcg_out_nop(s); |
|
544 |
cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0); |
|
545 |
tcg_out_branch_i32(s, cc, label_next); |
|
546 |
tcg_out_cmp(s, al, bl, blconst); |
|
547 |
cc = INSN_COND(tcg_cond_to_bcond[tcg_unsigned_cond(cond)], 0); |
|
548 |
tcg_out_branch_i32(s, cc, label_dest); |
|
549 |
break; |
|
550 |
} |
|
551 |
tcg_out_nop(s); |
|
552 |
|
|
553 |
tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); |
|
554 |
} |
|
510 | 555 |
#endif |
511 | 556 |
|
512 | 557 |
/* Generate global QEMU prologue and epilogue code */ |
... | ... | |
1077 | 1122 |
tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1], |
1078 | 1123 |
args[3]); |
1079 | 1124 |
break; |
1125 |
#if TCG_TARGET_REG_BITS == 32 |
|
1126 |
case INDEX_op_brcond2_i32: |
|
1127 |
tcg_out_brcond2_i32(s, args[4], args[0], args[1], |
|
1128 |
args[2], const_args[2], |
|
1129 |
args[3], const_args[3], args[5]); |
|
1130 |
break; |
|
1131 |
#endif |
|
1080 | 1132 |
|
1081 | 1133 |
case INDEX_op_qemu_ld8u: |
1082 | 1134 |
tcg_out_qemu_ld(s, args, 0); |
... | ... | |
1195 | 1247 |
{ INDEX_op_shr_i32, { "r", "r", "rJ" } }, |
1196 | 1248 |
{ INDEX_op_sar_i32, { "r", "r", "rJ" } }, |
1197 | 1249 |
|
1198 |
{ INDEX_op_brcond_i32, { "r", "ri" } }, |
|
1250 |
{ INDEX_op_brcond_i32, { "r", "rJ" } }, |
|
1251 |
#if TCG_TARGET_REG_BITS == 32 |
|
1252 |
{ INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } }, |
|
1253 |
#endif |
|
1199 | 1254 |
|
1200 | 1255 |
{ INDEX_op_qemu_ld8u, { "r", "L" } }, |
1201 | 1256 |
{ INDEX_op_qemu_ld8s, { "r", "L" } }, |
... | ... | |
1238 | 1293 |
{ INDEX_op_shr_i64, { "r", "r", "rJ" } }, |
1239 | 1294 |
{ INDEX_op_sar_i64, { "r", "r", "rJ" } }, |
1240 | 1295 |
|
1241 |
{ INDEX_op_brcond_i64, { "r", "ri" } },
|
|
1296 |
{ INDEX_op_brcond_i64, { "r", "rJ" } },
|
|
1242 | 1297 |
#endif |
1243 | 1298 |
{ -1 }, |
1244 | 1299 |
}; |
Also available in: Unified diff