target/openrisc: Invert the decoding in dec_calc

Decoding the opcodes in the right order reduces by 100+ lines.
Also, it happens to put the opcodes in the same order as Chapter 17.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2015-02-18 17:41:52 -08:00
parent 0c53d7342b
commit cf2ae4428f
1 changed files with 96 additions and 208 deletions

View File

@ -465,133 +465,95 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
rb = extract32(insn, 11, 5); rb = extract32(insn, 11, 5);
rd = extract32(insn, 21, 5); rd = extract32(insn, 21, 5);
switch (op0) {
case 0x0000:
switch (op1) { switch (op1) {
case 0x00: /* l.add */ case 0:
switch (op0) {
case 0x0: /* l.add */
LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; return;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x0001: /* l.addc */ case 0x1: /* l.addc */
switch (op1) {
case 0x00:
LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; return;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x0002: /* l.sub */ case 0x2: /* l.sub */
switch (op1) {
case 0x00:
LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; return;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x0003: /* l.and */ case 0x3: /* l.and */
switch (op1) {
case 0x00:
LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; return;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x0004: /* l.or */ case 0x4: /* l.or */
switch (op1) {
case 0x00:
LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; return;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x0005: case 0x5: /* l.xor */
switch (op1) {
case 0x00: /* l.xor */
LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; return;
default:
gen_illegal_exception(dc); case 0x8:
break; switch (op2) {
case 0: /* l.sll */
LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
case 1: /* l.srl */
LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
case 2: /* l.sra */
LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
case 3: /* l.ror */
LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
} }
break; break;
case 0x0006: case 0xc:
switch (op1) { switch (op2) {
case 0x03: /* l.mul */ case 0: /* l.exths */
LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.exths r%d, r%d\n", rd, ra);
gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
break; return;
default: case 1: /* l.extbs */
gen_illegal_exception(dc); LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
break; tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
return;
case 2: /* l.exthz */
LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
return;
case 3: /* l.extbz */
LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
return;
} }
break; break;
case 0x0009: case 0xd:
switch (op1) { switch (op2) {
case 0x03: /* l.div */ case 0: /* l.extws */
LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.extws r%d, r%d\n", rd, ra);
gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
break; return;
case 1: /* l.extwz */
default: LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
gen_illegal_exception(dc); tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
break; return;
} }
break; break;
case 0x000a: case 0xe: /* l.cmov */
switch (op1) {
case 0x03: /* l.divu */
LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x000b:
switch (op1) {
case 0x03: /* l.mulu */
LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x000e:
switch (op1) {
case 0x00: /* l.cmov */
LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
{ {
TCGLabel *lab = gen_new_label(); TCGLabel *lab = gen_new_label();
@ -606,128 +568,54 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
tcg_temp_free(sr_f); tcg_temp_free(sr_f);
tcg_temp_free(res); tcg_temp_free(res);
} }
break; return;
default: case 0xf: /* l.ff1 */
gen_illegal_exception(dc);
break;
}
break;
case 0x000f:
switch (op1) {
case 0x00: /* l.ff1 */
LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1); tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1);
tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1); tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1);
return;
}
break; break;
case 0x01: /* l.fl1 */
case 1:
switch (op0) {
case 0xf: /* l.fl1 */
LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS); tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS);
tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]); tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]);
break; return;
default:
gen_illegal_exception(dc);
break;
} }
break; break;
case 0x0008: case 2:
switch (op1) {
case 0x00:
switch (op2) {
case 0x00: /* l.sll */
LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break;
case 0x01: /* l.srl */
LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break;
case 0x02: /* l.sra */
LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break;
case 0x03: /* l.ror */
LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
break; break;
default: case 3:
gen_illegal_exception(dc); switch (op0) {
break; case 0x6: /* l.mul */
LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
case 0x9: /* l.div */
LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
case 0xa: /* l.divu */
LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
case 0xb: /* l.mulu */
LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
} }
break; break;
default:
gen_illegal_exception(dc);
break;
} }
break;
case 0x000c:
switch (op1) {
case 0x00:
switch (op2) {
case 0x00: /* l.exths */
LOG_DIS("l.exths r%d, r%d\n", rd, ra);
tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
break;
case 0x01: /* l.extbs */
LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
break;
case 0x02: /* l.exthz */
LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
break;
case 0x03: /* l.extbz */
LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
break;
default:
gen_illegal_exception(dc); gen_illegal_exception(dc);
break;
}
break;
default:
gen_illegal_exception(dc);
break;
}
break;
case 0x000d:
switch (op1) {
case 0x00:
switch (op2) {
case 0x00: /* l.extws */
LOG_DIS("l.extws r%d, r%d\n", rd, ra);
tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
break;
case 0x01: /* l.extwz */
LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
break;
default:
gen_illegal_exception(dc);
break;
}
break;
default:
gen_illegal_exception(dc);
break;
}
break;
default:
gen_illegal_exception(dc);
break;
}
} }
static void dec_misc(DisasContext *dc, uint32_t insn) static void dec_misc(DisasContext *dc, uint32_t insn)