Revision 88077742
b/target-arm/translate-a64.c | ||
---|---|---|
698 | 698 |
unsupported_encoding(s, insn); |
699 | 699 |
} |
700 | 700 |
|
701 |
/* Bitfield */ |
|
701 |
/* C3.4.2 Bitfield |
|
702 |
* 31 30 29 28 23 22 21 16 15 10 9 5 4 0 |
|
703 |
* +----+-----+-------------+---+------+------+------+------+ |
|
704 |
* | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd | |
|
705 |
* +----+-----+-------------+---+------+------+------+------+ |
|
706 |
*/ |
|
702 | 707 |
static void disas_bitfield(DisasContext *s, uint32_t insn) |
703 | 708 |
{ |
704 |
unsupported_encoding(s, insn); |
|
709 |
unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len; |
|
710 |
TCGv_i64 tcg_rd, tcg_tmp; |
|
711 |
|
|
712 |
sf = extract32(insn, 31, 1); |
|
713 |
opc = extract32(insn, 29, 2); |
|
714 |
n = extract32(insn, 22, 1); |
|
715 |
ri = extract32(insn, 16, 6); |
|
716 |
si = extract32(insn, 10, 6); |
|
717 |
rn = extract32(insn, 5, 5); |
|
718 |
rd = extract32(insn, 0, 5); |
|
719 |
bitsize = sf ? 64 : 32; |
|
720 |
|
|
721 |
if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) { |
|
722 |
unallocated_encoding(s); |
|
723 |
return; |
|
724 |
} |
|
725 |
|
|
726 |
tcg_rd = cpu_reg(s, rd); |
|
727 |
tcg_tmp = read_cpu_reg(s, rn, sf); |
|
728 |
|
|
729 |
/* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */ |
|
730 |
|
|
731 |
if (opc != 1) { /* SBFM or UBFM */ |
|
732 |
tcg_gen_movi_i64(tcg_rd, 0); |
|
733 |
} |
|
734 |
|
|
735 |
/* do the bit move operation */ |
|
736 |
if (si >= ri) { |
|
737 |
/* Wd<s-r:0> = Wn<s:r> */ |
|
738 |
tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri); |
|
739 |
pos = 0; |
|
740 |
len = (si - ri) + 1; |
|
741 |
} else { |
|
742 |
/* Wd<32+s-r,32-r> = Wn<s:0> */ |
|
743 |
pos = bitsize - ri; |
|
744 |
len = si + 1; |
|
745 |
} |
|
746 |
|
|
747 |
tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len); |
|
748 |
|
|
749 |
if (opc == 0) { /* SBFM - sign extend the destination field */ |
|
750 |
tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len)); |
|
751 |
tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len)); |
|
752 |
} |
|
753 |
|
|
754 |
if (!sf) { /* zero extend final result */ |
|
755 |
tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
|
756 |
} |
|
705 | 757 |
} |
706 | 758 |
|
707 | 759 |
/* C3.4.3 Extract |
Also available in: Unified diff