target/mips: Add a placeholder for R5900 SQ, handle user mode RDHWR

Add placeholder for SQ instruction, handle RDHWR.

Backports commit bb41e74b66a8879ba5c23db145039faa27df5766 from qemu
This commit is contained in:
Fredrik Noring 2018-11-10 11:40:16 -05:00 committed by Lioncash
parent 32a644a4a1
commit cfc33249ce
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -24570,6 +24570,53 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
}
}
static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
{
generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
}
/*
* The TX79-specific instruction Store Quadword
*
* +--------+-------+-------+------------------------+
* | 011111 | base | rt | offset | SQ
* +--------+-------+-------+------------------------+
* 6 5 5 16
*
* has the same opcode as the Read Hardware Register instruction
*
* +--------+-------+-------+-------+-------+--------+
* | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
* +--------+-------+-------+-------+-------+--------+
* 6 5 5 5 5 6
*
* that is required, trapped and emulated by the Linux kernel. However, all
* RDHWR encodings yield address error exceptions on the TX79 since the SQ
* offset is odd. Therefore all valid SQ instructions can execute normally.
* In user mode, QEMU must verify the upper and lower 11 bits to distinguish
* between SQ and RDHWR, as the Linux kernel does.
*/
static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
{
int base = extract32(ctx->opcode, 21, 5);
int rt = extract32(ctx->opcode, 16, 5);
int offset = extract32(ctx->opcode, 0, 16);
#ifdef CONFIG_USER_ONLY
uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
uint32_t op2 = extract32(ctx->opcode, 6, 5);
if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
int rd = extract32(ctx->opcode, 11, 5);
gen_rdhwr(ctx, rt, rd, 0);
return;
}
#endif
gen_tx79_sq(ctx, base, rt, offset);
}
static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
{
TCGContext *tcg_ctx = env->uc->tcg_ctx;