mirror of https://github.com/xemu-project/xemu.git
target-arm: A64: expand decoding skeleton for system instructions
Decode the various kinds of system instructions: hints (HINT), which include NOP, YIELD, WFE, WFI, SEV, SEL sync instructions, which include CLREX, DSB, DMB, ISB msr_i, which move immediate to processor state field sys, which include all SYS and SYSL instructions msr, which move from a gp register to a system register mrs, which move from a system register to a gp register Provide implementations where they are trivial nops. Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
ad7ee8a290
commit
87462e0f41
|
@ -190,12 +190,139 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
|
||||||
unsupported_encoding(s, insn);
|
unsupported_encoding(s, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* System */
|
/* C5.6.68 HINT */
|
||||||
static void disas_system(DisasContext *s, uint32_t insn)
|
static void handle_hint(DisasContext *s, uint32_t insn,
|
||||||
|
unsigned int op1, unsigned int op2, unsigned int crm)
|
||||||
|
{
|
||||||
|
unsigned int selector = crm << 3 | op2;
|
||||||
|
|
||||||
|
if (op1 != 3) {
|
||||||
|
unallocated_encoding(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (selector) {
|
||||||
|
case 0: /* NOP */
|
||||||
|
return;
|
||||||
|
case 1: /* YIELD */
|
||||||
|
case 2: /* WFE */
|
||||||
|
case 3: /* WFI */
|
||||||
|
case 4: /* SEV */
|
||||||
|
case 5: /* SEVL */
|
||||||
|
/* we treat all as NOP at least for now */
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
/* default specified as NOP equivalent */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CLREX, DSB, DMB, ISB */
|
||||||
|
static void handle_sync(DisasContext *s, uint32_t insn,
|
||||||
|
unsigned int op1, unsigned int op2, unsigned int crm)
|
||||||
|
{
|
||||||
|
if (op1 != 3) {
|
||||||
|
unallocated_encoding(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op2) {
|
||||||
|
case 2: /* CLREX */
|
||||||
|
unsupported_encoding(s, insn);
|
||||||
|
return;
|
||||||
|
case 4: /* DSB */
|
||||||
|
case 5: /* DMB */
|
||||||
|
case 6: /* ISB */
|
||||||
|
/* We don't emulate caches so barriers are no-ops */
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
unallocated_encoding(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* C5.6.130 MSR (immediate) - move immediate to processor state field */
|
||||||
|
static void handle_msr_i(DisasContext *s, uint32_t insn,
|
||||||
|
unsigned int op1, unsigned int op2, unsigned int crm)
|
||||||
{
|
{
|
||||||
unsupported_encoding(s, insn);
|
unsupported_encoding(s, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* C5.6.204 SYS */
|
||||||
|
static void handle_sys(DisasContext *s, uint32_t insn, unsigned int l,
|
||||||
|
unsigned int op1, unsigned int op2,
|
||||||
|
unsigned int crn, unsigned int crm, unsigned int rt)
|
||||||
|
{
|
||||||
|
unsupported_encoding(s, insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* C5.6.129 MRS - move from system register */
|
||||||
|
static void handle_mrs(DisasContext *s, uint32_t insn, unsigned int op0,
|
||||||
|
unsigned int op1, unsigned int op2,
|
||||||
|
unsigned int crn, unsigned int crm, unsigned int rt)
|
||||||
|
{
|
||||||
|
unsupported_encoding(s, insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* C5.6.131 MSR (register) - move to system register */
|
||||||
|
static void handle_msr(DisasContext *s, uint32_t insn, unsigned int op0,
|
||||||
|
unsigned int op1, unsigned int op2,
|
||||||
|
unsigned int crn, unsigned int crm, unsigned int rt)
|
||||||
|
{
|
||||||
|
unsupported_encoding(s, insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* C3.2.4 System
|
||||||
|
* 31 22 21 20 19 18 16 15 12 11 8 7 5 4 0
|
||||||
|
* +---------------------+---+-----+-----+-------+-------+-----+------+
|
||||||
|
* | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 | CRn | CRm | op2 | Rt |
|
||||||
|
* +---------------------+---+-----+-----+-------+-------+-----+------+
|
||||||
|
*/
|
||||||
|
static void disas_system(DisasContext *s, uint32_t insn)
|
||||||
|
{
|
||||||
|
unsigned int l, op0, op1, crn, crm, op2, rt;
|
||||||
|
l = extract32(insn, 21, 1);
|
||||||
|
op0 = extract32(insn, 19, 2);
|
||||||
|
op1 = extract32(insn, 16, 3);
|
||||||
|
crn = extract32(insn, 12, 4);
|
||||||
|
crm = extract32(insn, 8, 4);
|
||||||
|
op2 = extract32(insn, 5, 3);
|
||||||
|
rt = extract32(insn, 0, 5);
|
||||||
|
|
||||||
|
if (op0 == 0) {
|
||||||
|
if (l || rt != 31) {
|
||||||
|
unallocated_encoding(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (crn) {
|
||||||
|
case 2: /* C5.6.68 HINT */
|
||||||
|
handle_hint(s, insn, op1, op2, crm);
|
||||||
|
break;
|
||||||
|
case 3: /* CLREX, DSB, DMB, ISB */
|
||||||
|
handle_sync(s, insn, op1, op2, crm);
|
||||||
|
break;
|
||||||
|
case 4: /* C5.6.130 MSR (immediate) */
|
||||||
|
handle_msr_i(s, insn, op1, op2, crm);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unallocated_encoding(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op0 == 1) {
|
||||||
|
/* C5.6.204 SYS */
|
||||||
|
handle_sys(s, insn, l, op1, op2, crn, crm, rt);
|
||||||
|
} else if (l) { /* op0 > 1 */
|
||||||
|
/* C5.6.129 MRS - move from system register */
|
||||||
|
handle_mrs(s, insn, op0, op1, op2, crn, crm, rt);
|
||||||
|
} else {
|
||||||
|
/* C5.6.131 MSR (register) - move to system register */
|
||||||
|
handle_msr(s, insn, op0, op1, op2, crn, crm, rt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Exception generation */
|
/* Exception generation */
|
||||||
static void disas_exc(DisasContext *s, uint32_t insn)
|
static void disas_exc(DisasContext *s, uint32_t insn)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue