Revision ab1339b9 tcg/sparc/tcg-target.c
b/tcg/sparc/tcg-target.c | ||
---|---|---|
126 | 126 |
|
127 | 127 |
#define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff)) |
128 | 128 |
#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) |
129 |
#define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20)) |
|
129 | 130 |
#define INSN_OFF19(x) (((x) >> 2) & 0x07ffff) |
130 | 131 |
#define INSN_COND(x) ((x) << 25) |
131 | 132 |
|
... | ... | |
147 | 148 |
#define COND_VC 0xf |
148 | 149 |
#define BA (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2)) |
149 | 150 |
|
151 |
#define RCOND_Z 1 |
|
152 |
#define RCOND_LEZ 2 |
|
153 |
#define RCOND_LZ 3 |
|
154 |
#define RCOND_NZ 5 |
|
155 |
#define RCOND_GZ 6 |
|
156 |
#define RCOND_GEZ 7 |
|
157 |
|
|
150 | 158 |
#define MOVCC_ICC (1 << 18) |
151 | 159 |
#define MOVCC_XCC (1 << 18 | 1 << 12) |
152 | 160 |
|
... | ... | |
156 | 164 |
#define BPCC_PN 0 |
157 | 165 |
#define BPCC_A (1 << 29) |
158 | 166 |
|
167 |
#define BPR_PT BPCC_PT |
|
168 |
|
|
159 | 169 |
#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00)) |
160 | 170 |
#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10)) |
161 | 171 |
#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01)) |
... | ... | |
251 | 261 |
} |
252 | 262 |
*(uint32_t *)code_ptr = value; |
253 | 263 |
break; |
264 |
case R_SPARC_WDISP16: |
|
265 |
value -= (long)code_ptr; |
|
266 |
if (!check_fit_tl(value >> 2, 16)) { |
|
267 |
tcg_abort(); |
|
268 |
} |
|
269 |
insn = *(uint32_t *)code_ptr; |
|
270 |
insn &= ~INSN_OFF16(-1); |
|
271 |
insn |= INSN_OFF16(value); |
|
272 |
*(uint32_t *)code_ptr = insn; |
|
273 |
break; |
|
254 | 274 |
case R_SPARC_WDISP19: |
255 | 275 |
value -= (long)code_ptr; |
256 | 276 |
if (!check_fit_tl(value >> 2, 19)) { |
... | ... | |
502 | 522 |
[TCG_COND_GTU] = COND_GU, |
503 | 523 |
}; |
504 | 524 |
|
525 |
static const uint8_t tcg_cond_to_rcond[] = { |
|
526 |
[TCG_COND_EQ] = RCOND_Z, |
|
527 |
[TCG_COND_NE] = RCOND_NZ, |
|
528 |
[TCG_COND_LT] = RCOND_LZ, |
|
529 |
[TCG_COND_GT] = RCOND_GZ, |
|
530 |
[TCG_COND_LE] = RCOND_LEZ, |
|
531 |
[TCG_COND_GE] = RCOND_GEZ |
|
532 |
}; |
|
533 |
|
|
505 | 534 |
static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19) |
506 | 535 |
{ |
507 | 536 |
tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19); |
... | ... | |
555 | 584 |
static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1, |
556 | 585 |
TCGArg arg2, int const_arg2, int label) |
557 | 586 |
{ |
558 |
tcg_out_cmp(s, arg1, arg2, const_arg2); |
|
559 |
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label); |
|
587 |
/* For 64-bit signed comparisons vs zero, we can avoid the compare. */ |
|
588 |
if (arg2 == 0 && !is_unsigned_cond(cond)) { |
|
589 |
TCGLabel *l = &s->labels[label]; |
|
590 |
int off16; |
|
591 |
|
|
592 |
if (l->has_value) { |
|
593 |
off16 = INSN_OFF16(l->u.value - (unsigned long)s->code_ptr); |
|
594 |
} else { |
|
595 |
/* Make sure to preserve destinations during retranslation. */ |
|
596 |
off16 = *(uint32_t *)s->code_ptr & INSN_OFF16(-1); |
|
597 |
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0); |
|
598 |
} |
|
599 |
tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1) |
|
600 |
| INSN_COND(tcg_cond_to_rcond[cond]) | off16); |
|
601 |
} else { |
|
602 |
tcg_out_cmp(s, arg1, arg2, const_arg2); |
|
603 |
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label); |
|
604 |
} |
|
560 | 605 |
tcg_out_nop(s); |
561 | 606 |
} |
562 | 607 |
|
Also available in: Unified diff