target/arm: Convert T16, Miscellaneous 16-bit instructions

Backports commit 43f7e42c7d515f41ff243034f51b28267ae69938 from qemu
This commit is contained in:
Richard Henderson 2019-11-20 12:38:59 -05:00 committed by Lioncash
parent dec55633dc
commit ee96ab9ea9
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 55 additions and 84 deletions

View file

@ -211,19 +211,30 @@ REVSH 1011 1010 11 ... ... @rdm
# Hints
{
YIELD 1011 1111 0001 0000
WFE 1011 1111 0010 0000
WFI 1011 1111 0011 0000
{
YIELD 1011 1111 0001 0000
WFE 1011 1111 0010 0000
WFI 1011 1111 0011 0000
# TODO: Implement SEV, SEVL; may help SMP performance.
# SEV 1011 1111 0100 0000
# SEVL 1011 1111 0101 0000
# TODO: Implement SEV, SEVL; may help SMP performance.
# SEV 1011 1111 0100 0000
# SEVL 1011 1111 0101 0000
# The canonical nop has the second nibble as 0000, but the whole of the
# rest of the space is a reserved hint, behaves as nop.
NOP 1011 1111 ---- 0000
# The canonical nop has the second nibble as 0000, but the whole of the
# rest of the space is a reserved hint, behaves as nop.
NOP 1011 1111 ---- 0000
}
IT 1011 1111 cond_mask:8
}
# Miscellaneous 16-bit instructions
%imm6_9_3 9:1 3:5 !function=times_2
HLT 1011 1010 10 imm:6 &i
BKPT 1011 1110 imm:8 &i
CBZ 1011 nz:1 0.1 ..... rn:3 imm=%imm6_9_3
# Push and Pop
%push_list 0:9 !function=t16_push_list

View file

@ -10533,6 +10533,19 @@ static bool trans_TBH(DisasContext *s, arg_tbranch *a)
return op_tbranch(s, a, true);
}
static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tmp = load_reg(s, a->rn);
arm_gen_condlabel(s);
tcg_gen_brcondi_i32(tcg_ctx, a->nz ? TCG_COND_EQ : TCG_COND_NE,
tmp, 0, s->condlabel);
tcg_temp_free_i32(tcg_ctx, tmp);
gen_jmp(s, read_pc(s) + a->imm);
return true;
}
/*
* Supervisor call
*/
@ -10759,6 +10772,27 @@ static bool trans_PLI(DisasContext *s, arg_PLD *a)
return ENABLE_ARCH_7;
}
/*
* If-then
*/
static bool trans_IT(DisasContext *s, arg_IT *a)
{
int cond_mask = a->cond_mask;
/*
* No actual code generated for this insn, just setup state.
*
* Combinations of firstcond and mask which set up an 0b1111
* condition are UNPREDICTABLE; we take the CONSTRAINED
* UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
* i.e. both meaning "execute always".
*/
s->condexec_cond = (cond_mask >> 4) & 0xe;
s->condexec_mask = cond_mask & 0x1f;
return true;
}
/*
* Legacy decoder.
*/
@ -11137,83 +11171,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
case 8: /* load/store halfword immediate offset, in decodetree */
case 9: /* load/store from stack, in decodetree */
case 10: /* add PC/SP (immediate), in decodetree */
case 11: /* misc, in decodetree */
case 12: /* load/store multiple, in decodetree */
goto illegal_op;
case 11:
/* misc */
op = (insn >> 8) & 0xf;
switch (op) {
case 0: /* add/sub (sp, immediate), in decodetree */
case 2: /* sign/zero extend, in decodetree */
goto illegal_op;
case 4: case 5: case 0xc: case 0xd:
/* push/pop, in decodetree */
goto illegal_op;
case 1: case 3: case 9: case 11: /* czb */
rm = insn & 7;
tmp = load_reg(s, rm);
arm_gen_condlabel(s);
if (insn & (1 << 11))
tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tmp, 0, s->condlabel);
else
tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tmp, 0, s->condlabel);
tcg_temp_free_i32(tcg_ctx, tmp);
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
gen_jmp(s, read_pc(s) + offset);
break;
case 15: /* IT, nop-hint. */
if ((insn & 0xf) == 0) {
goto illegal_op; /* nop hint, in decodetree */
}
/*
* IT (If-Then)
*
* Combinations of firstcond and mask which set up an 0b1111
* condition are UNPREDICTABLE; we take the CONSTRAINED
* UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
* i.e. both meaning "execute always".
*/
s->condexec_cond = (insn >> 4) & 0xe;
s->condexec_mask = insn & 0x1f;
/* No actual code generated for this insn, just setup state. */
break;
case 0xe: /* bkpt */
{
int imm8 = extract32(insn, 0, 8);
ARCH(5);
gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
break;
}
case 0xa: /* rev, and hlt */
{
int op1 = extract32(insn, 6, 2);
if (op1 == 2) {
/* HLT */
int imm6 = extract32(insn, 0, 6);
gen_hlt(s, imm6);
break;
}
/* Otherwise this is rev, in decodetree */
goto illegal_op;
}
case 6: /* setend, cps; in decodetree */
goto illegal_op;
default:
goto undef;
}
break;
case 13: /* conditional branch or swi, in decodetree */
goto illegal_op;
@ -11269,7 +11230,6 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
}
return;
illegal_op:
undef:
unallocated_encoding(s);
}