From cfc33249cea2572c79fe910c46a9e19691f65bc3 Mon Sep 17 00:00:00 2001 From: Fredrik Noring Date: Sat, 10 Nov 2018 11:40:16 -0500 Subject: [PATCH] target/mips: Add a placeholder for R5900 SQ, handle user mode RDHWR Add placeholder for SQ instruction, handle RDHWR. Backports commit bb41e74b66a8879ba5c23db145039faa27df5766 from qemu --- qemu/target/mips/translate.c | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index a7a7c440..4ff6f67f 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -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;