From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] [PATCH v3 15/20] tcg-arm: Cleanup most primitive load store subroutines
Date: Thu, 28 Mar 2013 08:32:56 -0700 [thread overview]
Message-ID: <1364484781-15561-16-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1364484781-15561-1-git-send-email-rth@twiddle.net>
Use even more primitive helper functions to avoid lots of duplicated code.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/arm/tcg-target.c | 235 ++++++++++++++++++++++++---------------------------
1 file changed, 111 insertions(+), 124 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 6de5e90..fb8c96d 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -306,7 +306,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define TO_CPSR (1 << 20)
-enum arm_data_opc_e {
+typedef enum {
ARITH_AND = 0x0 << 21,
ARITH_EOR = 0x1 << 21,
ARITH_SUB = 0x2 << 21,
@@ -322,7 +322,26 @@ enum arm_data_opc_e {
ARITH_MOV = 0xd << 21,
ARITH_BIC = 0xe << 21,
ARITH_MVN = 0xf << 21,
-};
+
+ INSN_LDR_IMM = 0x04100000,
+ INSN_LDR_REG = 0x06100000,
+ INSN_STR_IMM = 0x04000000,
+ INSN_STR_REG = 0x06000000,
+
+ INSN_LDRH_IMM = 0x005000b0,
+ INSN_LDRH_REG = 0x001000b0,
+ INSN_LDRSH_IMM = 0x005000f0,
+ INSN_LDRSH_REG = 0x001000f0,
+ INSN_STRH_IMM = 0x004000b0,
+ INSN_STRH_REG = 0x000000b0,
+
+ INSN_LDRB_IMM = 0x04500000,
+ INSN_LDRB_REG = 0x06500000,
+ INSN_LDRSB_IMM = 0x005000d0,
+ INSN_LDRSB_REG = 0x001000d0,
+ INSN_STRB_IMM = 0x04400000,
+ INSN_STRB_REG = 0x06400000,
+} ARMInsn;
#define SHIFT_IMM_LSL(im) (((im) << 7) | 0x00)
#define SHIFT_IMM_LSR(im) (((im) << 7) | 0x20)
@@ -748,187 +767,155 @@ static inline void tcg_out_deposit(TCGContext *s, int cond, TCGReg rd,
| (ofs << 7) | ((ofs + len - 1) << 16));
}
-static inline void tcg_out_ld32_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+/* Note that this routine is used for both LDR and LDRH formats, so we do
+ not wish to include an immediate shift at this point. */
+static void tcg_out_memop_r(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
+ TCGReg rn, TCGReg rm, bool u, bool p, bool w)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05900000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05100000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
+ tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24)
+ | (w << 21) | (rn << 16) | (rt << 12) | rm);
+}
+
+static void tcg_out_memop_8(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
+ TCGReg rn, int imm8, bool p, bool w)
+{
+ bool u = 1;
+ if (imm8 < 0) {
+ imm8 = -imm8;
+ u = 0;
+ }
+ tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
+ (rn << 16) | (rt << 12) | ((imm8 & 0xf0) << 4) | (imm8 & 0xf));
+}
+
+static void tcg_out_memop_12(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
+ TCGReg rn, int imm12, bool p, bool w)
+{
+ bool u = 1;
+ if (imm12 < 0) {
+ imm12 = -imm12;
+ u = 0;
+ }
+ tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
+ (rn << 16) | (rt << 12) | imm12);
+}
+
+static inline void tcg_out_ld32_12(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm12)
+{
+ tcg_out_memop_12(s, cond, INSN_LDR_IMM, rt, rn, imm12, 1, 0);
}
/* Offset pre-increment with base writeback. */
-static inline void tcg_out_ld32_12wb(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_ld32_12wb(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm12)
{
/* ldr with writeback and both register equals is UNPREDICTABLE */
assert(rd != rn);
-
- if (im >= 0) {
- tcg_out32(s, (cond << 28) | 0x05b00000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- } else {
- tcg_out32(s, (cond << 28) | 0x05300000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
- }
+ tcg_out_memop_12(s, cond, INSN_LDR_IMM, rt, rn, imm12, 1, 1);
}
-static inline void tcg_out_st32_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_st32_12(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm12)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05800000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05000000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
+ tcg_out_memop_12(s, cond, INSN_STR_IMM, rt, rn, imm12, 1, 0);
}
-static inline void tcg_out_ld32_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_ld32_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x07900000 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 0);
}
-static inline void tcg_out_st32_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_st32_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x07800000 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 0);
}
/* Register pre-increment with base writeback. */
-static inline void tcg_out_ld32_rwb(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_ld32_rwb(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x07b00000 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 1);
}
-static inline void tcg_out_st32_rwb(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_st32_rwb(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x07a00000 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 1);
}
-static inline void tcg_out_ld16u_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_ld16u_8(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm8)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01d000b0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x015000b0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
+ tcg_out_memop_8(s, cond, INSN_LDRH_IMM, rt, rn, imm8, 1, 0);
}
-static inline void tcg_out_st16_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_st16_8(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm8)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01c000b0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x014000b0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
+ tcg_out_memop_8(s, cond, INSN_STRH_IMM, rt, rn, imm8, 1, 0);
}
-static inline void tcg_out_ld16u_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_ld16u_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x019000b0 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_LDRH_REG, rt, rn, rm, 1, 1, 0);
}
-static inline void tcg_out_st16_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_st16_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x018000b0 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_STRH_REG, rt, rn, rm, 1, 1, 0);
}
-static inline void tcg_out_ld16s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_ld16s_8(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm8)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01d000f0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x015000f0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
+ tcg_out_memop_8(s, cond, INSN_LDRSH_IMM, rt, rn, imm8, 1, 0);
}
-static inline void tcg_out_ld16s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_ld16s_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x019000f0 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_LDRSH_REG, rt, rn, rm, 1, 1, 0);
}
-static inline void tcg_out_ld8_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_ld8_12(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm12)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05d00000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05500000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
+ tcg_out_memop_12(s, cond, INSN_LDRB_IMM, rt, rn, imm12, 1, 0);
}
-static inline void tcg_out_st8_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_st8_12(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm12)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05c00000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05400000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
+ tcg_out_memop_12(s, cond, INSN_STRB_IMM, rt, rn, imm12, 1, 0);
}
-static inline void tcg_out_ld8_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_ld8_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x07d00000 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_LDRB_REG, rt, rn, rm, 1, 1, 0);
}
-static inline void tcg_out_st8_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_st8_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x07c00000 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_STRB_REG, rt, rn, rm, 1, 1, 0);
}
-static inline void tcg_out_ld8s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
+static inline void tcg_out_ld8s_8(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, int imm8)
{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01d000d0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x015000d0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
+ tcg_out_memop_8(s, cond, INSN_LDRSB_IMM, rt, rn, imm8, 1, 0);
}
-static inline void tcg_out_ld8s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
+static inline void tcg_out_ld8s_r(TCGContext *s, int cond, TCGReg rt,
+ TCGReg rn, TCGReg rm)
{
- tcg_out32(s, (cond << 28) | 0x019000d0 |
- (rn << 16) | (rd << 12) | rm);
+ tcg_out_memop_r(s, cond, INSN_LDRSB_REG, rt, rn, rm, 1, 1, 0);
}
static inline void tcg_out_ld32u(TCGContext *s, int cond,
--
1.8.1.4
next prev parent reply other threads:[~2013-03-28 15:33 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-28 15:32 [Qemu-devel] [PATCH v3 00/20] tcg-arm improvements Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 01/20] tcg-arm: Use bic to implement and with constant Richard Henderson
2013-03-29 16:53 ` Aurelien Jarno
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 02/20] tcg-arm: Handle negated constant arguments to and/sub Richard Henderson
2013-03-29 16:53 ` Aurelien Jarno
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 03/20] tcg-arm: Allow constant first argument to sub Richard Henderson
2013-03-29 16:58 ` Aurelien Jarno
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 04/20] tcg-arm: Use tcg_out_dat_rIN for compares Richard Henderson
2013-03-29 16:58 ` Aurelien Jarno
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 05/20] tcg-arm: Handle constant arguments to add2/sub2 Richard Henderson
2013-03-28 15:56 ` Peter Maydell
2013-03-28 16:04 ` Richard Henderson
2013-03-28 16:09 ` Laurent Desnogues
2013-03-28 16:16 ` Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 06/20] tcg-arm: Improve constant generation Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 07/20] tcg-arm: Fold epilogue into INDEX_op_exit_tb Richard Henderson
2013-03-28 16:05 ` Peter Maydell
2013-03-28 16:12 ` Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 08/20] tcg-arm: Implement deposit for armv7 Richard Henderson
2013-03-28 16:15 ` Peter Maydell
2013-03-28 16:22 ` Richard Henderson
2013-03-28 16:59 ` Peter Maydell
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 09/20] tcg-arm: Implement division instructions Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 10/20] tcg-arm: Use TCG_REG_TMP name for the tcg temporary Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 11/20] tcg-arm: Use R12 " Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 12/20] tcg-arm: Cleanup multiply subroutines Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 13/20] tcg-arm: Cleanup tcg_out_goto_label Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 14/20] tcg-arm: Cleanup goto_tb handling Richard Henderson
2013-03-28 20:09 ` Aurelien Jarno
2013-03-28 20:48 ` Richard Henderson
2013-03-29 6:50 ` Aurelien Jarno
2013-03-29 15:06 ` Richard Henderson
2013-03-28 15:32 ` Richard Henderson [this message]
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 16/20] tcg-arm: Fix local stack frame Richard Henderson
2013-03-29 16:50 ` Aurelien Jarno
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 17/20] tcg-arm: Split out tcg_out_tlb_read Richard Henderson
2013-03-28 15:32 ` [Qemu-devel] [PATCH v3 18/20] tcg-arm: Improve scheduling of tcg_out_tlb_read Richard Henderson
2013-03-28 15:33 ` [Qemu-devel] [PATCH v3 19/20] tcg-arm: Use movi32 + blx for calls on v7 Richard Henderson
2013-03-28 15:33 ` [Qemu-devel] [PATCH v3 20/20] tcg-arm: Convert to CONFIG_QEMU_LDST_OPTIMIZATION Richard Henderson
2013-03-28 16:44 ` Peter Maydell
2013-03-28 17:46 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1364484781-15561-16-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=aurelien@aurel32.net \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).