[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-st
From: |
Jan Bobek |
Subject: |
[Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-store operand |
Date: |
Sat, 10 Aug 2019 00:12:36 -0400 |
This operand attempts to capture the "indirect" or "memory" operand in
a generic way. It significatly reduces the amount code that needs to
be written in order to read operands from memory to temporary storage
and write them back.
Signed-off-by: Jan Bobek <address@hidden>
---
target/i386/translate.c | 78 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/target/i386/translate.c b/target/i386/translate.c
index cd2467e6a5..ebb68fef0b 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4619,6 +4619,84 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s,
int ck_cpuid_feat)
insnop_prepare(opT2)(env, s, modrm, op), \
insnop_finalize(opT2)(env, s, modrm, op))
+/*
+ * "Load-store" operand helper
+ */
+#define INSNOP_LDST(opT, opTr, opTm, scratch_op, ld_stmt, st_stmt) \
+ INSNOP( \
+ opT, \
+ struct { \
+ bool is_mem; \
+ insnop_t(opTr) op_reg; \
+ }, \
+ do { \
+ insnop_t(opTr) reg; \
+ insnop_t(opTm) ptr; \
+ if (!insnop_init(opTr)(env, s, modrm, ®)) { \
+ op->is_mem = 0; \
+ op->op_reg = reg; \
+ INSNOP_INIT_OK(*op); \
+ } else if (!insnop_init(opTm)(env, s, modrm, &ptr)) { \
+ op->is_mem = 1; \
+ op->op_reg = (scratch_op); \
+ INSNOP_INIT_OK(*op); \
+ } \
+ INSNOP_INIT_FAIL; \
+ } while (0), \
+ do { \
+ insnop_t(opTr) reg = op->op_reg; \
+ if (op->is_mem) { \
+ insnop_t(opTm) ptr; \
+ const int ret = insnop_init(opTm)(env, s, modrm, &ptr); \
+ assert(!ret); \
+ \
+ insnop_prepare(opTm)(env, s, modrm, &ptr); \
+ ld_stmt; \
+ } else { \
+ insnop_prepare(opTr)(env, s, modrm, ®); \
+ } \
+ } while (0), \
+ do { \
+ insnop_t(opTr) reg = op->op_reg; \
+ if (op->is_mem) { \
+ insnop_t(opTm) ptr; \
+ const int ret = insnop_init(opTm)(env, s, modrm, &ptr); \
+ assert(!ret); \
+ \
+ insnop_prepare(opTm)(env, s, modrm, &ptr); \
+ st_stmt; \
+ } else { \
+ insnop_finalize(opTr)(env, s, modrm, ®); \
+ } \
+ } while (0))
+
+#define INSNOP_LDST_UNIFY(opT, opTr, opTrm) \
+ INSNOP( \
+ opT, insnop_t(opTr), \
+ do { \
+ insnop_t(opTrm) rm; \
+ if (!insnop_init(opTrm)(env, s, modrm, &rm)) { \
+ INSNOP_INIT_OK(rm.op_reg); \
+ } \
+ INSNOP_INIT_FAIL; \
+ } while (0), \
+ do { \
+ insnop_t(opTrm) rm; \
+ const int ret = insnop_init(opTrm)(env, s, modrm, &rm); \
+ assert(!ret); \
+ \
+ rm.op_reg = *op; \
+ insnop_prepare(opTrm)(env, s, modrm, &rm); \
+ } while (0), \
+ do { \
+ insnop_t(opTrm) rm; \
+ const int ret = insnop_init(opTrm)(env, s, modrm, &rm); \
+ assert(!ret); \
+ \
+ rm.op_reg = *op; \
+ insnop_finalize(opTrm)(env, s, modrm, &rm); \
+ } while (0))
+
static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
{
enum {
--
2.20.1
- [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng, (continued)
- [Qemu-devel] [RFC PATCH v2 17/39] target/i386: introduce helpers for decoding modrm fields, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 18/39] target/i386: introduce modifier for direct-only operand decoding, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-store operand,
Jan Bobek <=
- [Qemu-devel] [RFC PATCH v2 22/39] target/i386: introduce code generators, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 19/39] target/i386: introduce generic operand alias, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 24/39] target/i386: introduce Ib (immediate) operand, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 25/39] target/i386: introduce M* (memptr) operands, Jan Bobek, 2019/08/10
- [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros, Jan Bobek, 2019/08/10