Revision 0085bd51 tcg/hppa/tcg-target.c
b/tcg/hppa/tcg-target.c | ||
---|---|---|
97 | 97 |
Copied from gcc sources. */ |
98 | 98 |
static inline int or_mask_p(tcg_target_ulong mask) |
99 | 99 |
{ |
100 |
if (mask == 0 || mask == -1) { |
|
101 |
return 0; |
|
102 |
} |
|
100 | 103 |
mask += mask & -mask; |
101 | 104 |
return (mask & (mask - 1)) == 0; |
102 | 105 |
} |
... | ... | |
213 | 216 |
case 'K': |
214 | 217 |
ct->ct |= TCG_CT_CONST_MS11; |
215 | 218 |
break; |
219 |
case 'M': |
|
220 |
ct->ct |= TCG_CT_CONST_AND; |
|
221 |
break; |
|
222 |
case 'O': |
|
223 |
ct->ct |= TCG_CT_CONST_OR; |
|
224 |
break; |
|
216 | 225 |
default: |
217 | 226 |
return -1; |
218 | 227 |
} |
... | ... | |
236 | 245 |
return check_fit_tl(val, 11); |
237 | 246 |
} else if (ct & TCG_CT_CONST_MS11) { |
238 | 247 |
return check_fit_tl(-val, 11); |
248 |
} else if (ct & TCG_CT_CONST_AND) { |
|
249 |
return and_mask_p(val); |
|
250 |
} else if (ct & TCG_CT_CONST_OR) { |
|
251 |
return or_mask_p(val); |
|
239 | 252 |
} |
240 | 253 |
return 0; |
241 | 254 |
} |
... | ... | |
474 | 487 |
|
475 | 488 |
static void tcg_out_ori(TCGContext *s, int ret, int arg, tcg_target_ulong m) |
476 | 489 |
{ |
477 |
if (m == 0) { |
|
478 |
tcg_out_mov(s, ret, arg); |
|
479 |
} else if (m == -1) { |
|
480 |
tcg_out_movi(s, TCG_TYPE_I32, ret, -1); |
|
481 |
} else if (or_mask_p(m)) { |
|
482 |
int bs0, bs1; |
|
483 |
|
|
484 |
for (bs0 = 0; bs0 < 32; bs0++) { |
|
485 |
if ((m & (1u << bs0)) != 0) { |
|
486 |
break; |
|
487 |
} |
|
490 |
int bs0, bs1; |
|
491 |
|
|
492 |
/* Note that the argument is constrained to match or_mask_p. */ |
|
493 |
for (bs0 = 0; bs0 < 32; bs0++) { |
|
494 |
if ((m & (1u << bs0)) != 0) { |
|
495 |
break; |
|
488 | 496 |
} |
489 |
for (bs1 = bs0; bs1 < 32; bs1++) {
|
|
490 |
if ((m & (1u << bs1)) == 0) {
|
|
491 |
break;
|
|
492 |
}
|
|
497 |
}
|
|
498 |
for (bs1 = bs0; bs1 < 32; bs1++) {
|
|
499 |
if ((m & (1u << bs1)) == 0) {
|
|
500 |
break;
|
|
493 | 501 |
} |
494 |
assert(bs1 == 32 || (1ul << bs1) > m); |
|
495 |
|
|
496 |
tcg_out_mov(s, ret, arg); |
|
497 |
tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1) |
|
498 |
| INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0)); |
|
499 |
} else { |
|
500 |
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m); |
|
501 |
tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_OR); |
|
502 | 502 |
} |
503 |
assert(bs1 == 32 || (1ul << bs1) > m); |
|
504 |
|
|
505 |
tcg_out_mov(s, ret, arg); |
|
506 |
tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1) |
|
507 |
| INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0)); |
|
503 | 508 |
} |
504 | 509 |
|
505 | 510 |
static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m) |
506 | 511 |
{ |
507 |
if (m == 0) { |
|
508 |
tcg_out_mov(s, ret, TCG_REG_R0); |
|
509 |
} else if (m == -1) { |
|
510 |
tcg_out_mov(s, ret, arg); |
|
511 |
} else if (and_mask_p(m)) { |
|
512 |
int ls0, ls1, ms0; |
|
512 |
int ls0, ls1, ms0; |
|
513 | 513 |
|
514 |
for (ls0 = 0; ls0 < 32; ls0++) {
|
|
515 |
if ((m & (1u << ls0)) == 0) {
|
|
516 |
break;
|
|
517 |
}
|
|
514 |
/* Note that the argument is constrained to match and_mask_p. */
|
|
515 |
for (ls0 = 0; ls0 < 32; ls0++) {
|
|
516 |
if ((m & (1u << ls0)) == 0) {
|
|
517 |
break;
|
|
518 | 518 |
} |
519 |
for (ls1 = ls0; ls1 < 32; ls1++) {
|
|
520 |
if ((m & (1u << ls1)) != 0) {
|
|
521 |
break;
|
|
522 |
}
|
|
519 |
}
|
|
520 |
for (ls1 = ls0; ls1 < 32; ls1++) {
|
|
521 |
if ((m & (1u << ls1)) != 0) {
|
|
522 |
break;
|
|
523 | 523 |
} |
524 |
for (ms0 = ls1; ms0 < 32; ms0++) {
|
|
525 |
if ((m & (1u << ms0)) == 0) {
|
|
526 |
break;
|
|
527 |
}
|
|
524 |
}
|
|
525 |
for (ms0 = ls1; ms0 < 32; ms0++) {
|
|
526 |
if ((m & (1u << ms0)) == 0) {
|
|
527 |
break;
|
|
528 | 528 |
} |
529 |
assert (ms0 == 32); |
|
529 |
} |
|
530 |
assert (ms0 == 32); |
|
530 | 531 |
|
531 |
if (ls1 == 32) { |
|
532 |
tcg_out_extr(s, ret, arg, 0, ls0, 0); |
|
533 |
} else { |
|
534 |
tcg_out_mov(s, ret, arg); |
|
535 |
tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0) |
|
536 |
| INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0)); |
|
537 |
} |
|
532 |
if (ls1 == 32) { |
|
533 |
tcg_out_extr(s, ret, arg, 0, ls0, 0); |
|
538 | 534 |
} else { |
539 |
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m); |
|
540 |
tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_AND); |
|
535 |
tcg_out_mov(s, ret, arg); |
|
536 |
tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0) |
|
537 |
| INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0)); |
|
541 | 538 |
} |
542 | 539 |
} |
543 | 540 |
|
... | ... | |
1539 | 1536 |
|
1540 | 1537 |
{ INDEX_op_add_i32, { "r", "rZ", "ri" } }, |
1541 | 1538 |
{ INDEX_op_sub_i32, { "r", "rI", "ri" } }, |
1542 |
{ INDEX_op_and_i32, { "r", "rZ", "ri" } },
|
|
1543 |
{ INDEX_op_or_i32, { "r", "rZ", "ri" } },
|
|
1539 |
{ INDEX_op_and_i32, { "r", "rZ", "rM" } },
|
|
1540 |
{ INDEX_op_or_i32, { "r", "rZ", "rO" } },
|
|
1544 | 1541 |
{ INDEX_op_xor_i32, { "r", "rZ", "rZ" } }, |
1545 |
{ INDEX_op_andc_i32, { "r", "rZ", "ri" } }, |
|
1542 |
/* Note that the second argument will be inverted, which means |
|
1543 |
we want a constant whose inversion matches M, and that O = ~M. |
|
1544 |
See the implementation of and_mask_p. */ |
|
1545 |
{ INDEX_op_andc_i32, { "r", "rZ", "rO" } }, |
|
1546 | 1546 |
|
1547 | 1547 |
{ INDEX_op_mul_i32, { "r", "r", "r" } }, |
1548 | 1548 |
{ INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, |
Also available in: Unified diff