target/arm: Rearrange disas_data_proc_reg

This decoding more closely matches the ARMv8.4 Table C4-6,
Encoding table for Data Processing - Register Group.

In particular, op2 == 0 is now more than just Add/sub (with carry).

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190301200501.16533-7-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2019-03-01 12:04:57 -08:00 committed by Peter Maydell
parent 22ac3c4964
commit 2fba34f70d

View File

@ -4494,11 +4494,10 @@ static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
} }
/* Add/subtract (with carry) /* Add/subtract (with carry)
* 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0 * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
* +--+--+--+------------------------+------+---------+------+-----+ * +--+--+--+------------------------+------+-------------+------+-----+
* |sf|op| S| 1 1 0 1 0 0 0 0 | rm | opcode2 | Rn | Rd | * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | 0 0 0 0 0 0 | Rn | Rd |
* +--+--+--+------------------------+------+---------+------+-----+ * +--+--+--+------------------------+------+-------------+------+-----+
* [000000]
*/ */
static void disas_adc_sbc(DisasContext *s, uint32_t insn) static void disas_adc_sbc(DisasContext *s, uint32_t insn)
@ -4506,11 +4505,6 @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
unsigned int sf, op, setflags, rm, rn, rd; unsigned int sf, op, setflags, rm, rn, rd;
TCGv_i64 tcg_y, tcg_rn, tcg_rd; TCGv_i64 tcg_y, tcg_rn, tcg_rd;
if (extract32(insn, 10, 6) != 0) {
unallocated_encoding(s);
return;
}
sf = extract32(insn, 31, 1); sf = extract32(insn, 31, 1);
op = extract32(insn, 30, 1); op = extract32(insn, 30, 1);
setflags = extract32(insn, 29, 1); setflags = extract32(insn, 29, 1);
@ -5164,47 +5158,69 @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
} }
} }
/* Data processing - register */ /*
* Data processing - register
* 31 30 29 28 25 21 20 16 10 0
* +--+---+--+---+-------+-----+-------+-------+---------+
* | |op0| |op1| 1 0 1 | op2 | | op3 | |
* +--+---+--+---+-------+-----+-------+-------+---------+
*/
static void disas_data_proc_reg(DisasContext *s, uint32_t insn) static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
{ {
switch (extract32(insn, 24, 5)) { int op0 = extract32(insn, 30, 1);
case 0x0a: /* Logical (shifted register) */ int op1 = extract32(insn, 28, 1);
disas_logic_reg(s, insn); int op2 = extract32(insn, 21, 4);
break; int op3 = extract32(insn, 10, 6);
case 0x0b: /* Add/subtract */
if (insn & (1 << 21)) { /* (extended register) */ if (!op1) {
disas_add_sub_ext_reg(s, insn); if (op2 & 8) {
if (op2 & 1) {
/* Add/sub (extended register) */
disas_add_sub_ext_reg(s, insn);
} else {
/* Add/sub (shifted register) */
disas_add_sub_reg(s, insn);
}
} else { } else {
disas_add_sub_reg(s, insn); /* Logical (shifted register) */
disas_logic_reg(s, insn);
} }
break; return;
case 0x1b: /* Data-processing (3 source) */ }
disas_data_proc_3src(s, insn);
break; switch (op2) {
case 0x1a: case 0x0:
switch (extract32(insn, 21, 3)) { switch (op3) {
case 0x0: /* Add/subtract (with carry) */ case 0x00: /* Add/subtract (with carry) */
disas_adc_sbc(s, insn); disas_adc_sbc(s, insn);
break; break;
case 0x2: /* Conditional compare */
disas_cc(s, insn); /* both imm and reg forms */
break;
case 0x4: /* Conditional select */
disas_cond_select(s, insn);
break;
case 0x6: /* Data-processing */
if (insn & (1 << 30)) { /* (1 source) */
disas_data_proc_1src(s, insn);
} else { /* (2 source) */
disas_data_proc_2src(s, insn);
}
break;
default: default:
unallocated_encoding(s); goto do_unallocated;
break;
} }
break; break;
case 0x2: /* Conditional compare */
disas_cc(s, insn); /* both imm and reg forms */
break;
case 0x4: /* Conditional select */
disas_cond_select(s, insn);
break;
case 0x6: /* Data-processing */
if (op0) { /* (1 source) */
disas_data_proc_1src(s, insn);
} else { /* (2 source) */
disas_data_proc_2src(s, insn);
}
break;
case 0x8 ... 0xf: /* (3 source) */
disas_data_proc_3src(s, insn);
break;
default: default:
do_unallocated:
unallocated_encoding(s); unallocated_encoding(s);
break; break;
} }