Revision 637af30c tcg/ppc64/tcg-target.c
b/tcg/ppc64/tcg-target.c | ||
---|---|---|
527 | 527 |
} |
528 | 528 |
} |
529 | 529 |
|
530 |
static inline bool mask_operand(uint32_t c, int *mb, int *me)
|
|
530 |
static bool mask_operand(uint32_t c, int *mb, int *me) |
|
531 | 531 |
{ |
532 | 532 |
uint32_t lsb, test; |
533 | 533 |
|
... | ... | |
551 | 551 |
return true; |
552 | 552 |
} |
553 | 553 |
|
554 |
static bool mask64_operand(uint64_t c, int *mb, int *me) |
|
555 |
{ |
|
556 |
uint64_t lsb; |
|
557 |
|
|
558 |
if (c == 0) { |
|
559 |
return false; |
|
560 |
} |
|
561 |
|
|
562 |
lsb = c & -c; |
|
563 |
/* Accept 1..10..0. */ |
|
564 |
if (c == -lsb) { |
|
565 |
*mb = 0; |
|
566 |
*me = clz64(lsb); |
|
567 |
return true; |
|
568 |
} |
|
569 |
/* Accept 0..01..1. */ |
|
570 |
if (lsb == 1 && (c & (c + 1)) == 0) { |
|
571 |
*mb = clz64(c + 1) + 1; |
|
572 |
*me = 63; |
|
573 |
return true; |
|
574 |
} |
|
575 |
return false; |
|
576 |
} |
|
577 |
|
|
554 | 578 |
static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c) |
555 | 579 |
{ |
556 | 580 |
int mb, me; |
... | ... | |
569 | 593 |
} |
570 | 594 |
} |
571 | 595 |
|
596 |
static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c) |
|
597 |
{ |
|
598 |
int mb, me; |
|
599 |
|
|
600 |
if ((c & 0xffff) == c) { |
|
601 |
tcg_out32(s, ANDI | SAI(src, dst, c)); |
|
602 |
return; |
|
603 |
} else if ((c & 0xffff0000) == c) { |
|
604 |
tcg_out32(s, ANDIS | SAI(src, dst, c >> 16)); |
|
605 |
return; |
|
606 |
} else if (mask64_operand(c, &mb, &me)) { |
|
607 |
if (mb == 0) { |
|
608 |
tcg_out_rld(s, RLDICR, dst, src, 0, me); |
|
609 |
} else { |
|
610 |
tcg_out_rld(s, RLDICL, dst, src, 0, mb); |
|
611 |
} |
|
612 |
} else { |
|
613 |
tcg_out_movi(s, TCG_TYPE_I64, 0, c); |
|
614 |
tcg_out32(s, AND | SAB(src, dst, 0)); |
|
615 |
} |
|
616 |
} |
|
617 |
|
|
572 | 618 |
static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c, |
573 | 619 |
int op_lo, int op_hi) |
574 | 620 |
{ |
... | ... | |
1403 | 1449 |
break; |
1404 | 1450 |
case INDEX_op_and_i64: |
1405 | 1451 |
if (const_args[2]) { |
1406 |
if ((args[2] & 0xffff) == args[2]) { |
|
1407 |
tcg_out32(s, ANDI | SAI(args[1], args[0], args[2])); |
|
1408 |
} else if ((args[2] & 0xffff0000) == args[2]) { |
|
1409 |
tcg_out32(s, ANDIS | SAI(args[1], args[0], args[2] >> 16)); |
|
1410 |
} else { |
|
1411 |
tcg_out_movi (s, (opc == INDEX_op_and_i32 |
|
1412 |
? TCG_TYPE_I32 |
|
1413 |
: TCG_TYPE_I64), |
|
1414 |
0, args[2]); |
|
1415 |
tcg_out32 (s, AND | SAB (args[1], args[0], 0)); |
|
1416 |
} |
|
1452 |
tcg_out_andi64(s, args[0], args[1], args[2]); |
|
1453 |
} else { |
|
1454 |
tcg_out32(s, AND | SAB(args[1], args[0], args[2])); |
|
1417 | 1455 |
} |
1418 |
else |
|
1419 |
tcg_out32 (s, AND | SAB (args[1], args[0], args[2])); |
|
1420 | 1456 |
break; |
1421 | 1457 |
case INDEX_op_or_i64: |
1422 | 1458 |
case INDEX_op_or_i32: |
Also available in: Unified diff