diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2022-08-23 14:55:56 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-10-18 13:58:04 +0200 |
commit | 6ba13999be293c4183879b75a5343bc6a8c98c00 (patch) | |
tree | d2595744a25bf4e85a79e85647691c5614ed9789 /target/i386/tcg/decode-new.c.inc | |
parent | b3e22b2318afcaff6fe6e0e031dda11d324c8b4a (diff) |
target/i386: add ALU load/writeback core
Add generic code generation that takes care of preparing operands
around calls to decode.e.gen in a table-driven manner, so that ALU
operations need not take care of that.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386/tcg/decode-new.c.inc')
-rw-r--r-- | target/i386/tcg/decode-new.c.inc | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 65f9c1de40..37e76692ba 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -513,6 +513,20 @@ static bool decode_insn(DisasContext *s, CPUX86State *env, X86DecodeFunc decode_ return true; } +static void decode_temp_free(X86DecodedOp *op) +{ + if (op->v_ptr) { + tcg_temp_free_ptr(op->v_ptr); + } +} + +static void decode_temps_free(X86DecodedInsn *decode) +{ + decode_temp_free(&decode->op[0]); + decode_temp_free(&decode->op[1]); + decode_temp_free(&decode->op[2]); +} + /* * Convert one instruction. s->base.is_jmp is set if the translation must * be stopped. @@ -738,7 +752,24 @@ static void disas_insn_new(DisasContext *s, CPUState *cpu, int b) if (decode.op[0].has_ea || decode.op[1].has_ea || decode.op[2].has_ea) { gen_load_ea(s, &decode.mem); } - decode.e.gen(s, env, &decode); + if (s->prefix & PREFIX_LOCK) { + if (decode.op[0].unit != X86_OP_INT || !decode.op[0].has_ea) { + goto illegal_op; + } + gen_load(s, &decode, 2, s->T1); + decode.e.gen(s, env, &decode); + } else { + if (decode.op[0].unit == X86_OP_MMX) { + compute_mmx_offset(&decode.op[0]); + } else if (decode.op[0].unit == X86_OP_SSE) { + compute_xmm_offset(&decode.op[0]); + } + gen_load(s, &decode, 1, s->T0); + gen_load(s, &decode, 2, s->T1); + decode.e.gen(s, env, &decode); + gen_writeback(s, &decode, 0, s->T0); + } + decode_temps_free(&decode); return; illegal_op: gen_illegal_opcode(s); |