* [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements
@ 2010-04-07 17:51 Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 01/18] tcg/arm: remove SAVE_LR code Aurelien Jarno
` (17 more replies)
0 siblings, 18 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski
This patch series clean-up and improves the tcg/arm code. The first
patches are just a clean-up and should not change the resulting
binaries, while the other ones use new ARM instructions, and fix
64-bit and/or big-endian targets.
With this patch series I am able to successfully:
- boot debian-installer on qemu-system-mips/mipsel
- run libc.so on qemu-i386, qemu-mips, qemu-mipsel, qemu-ppc,
qemu-ppc64, qemu-sh4, qemu-x86_64
With this patch series I am able to partially:
- boot debian-installer on qemu-system-i386 and qemu-system-x86_64,
but ld.so segfaults while coming to userland.
- boot the kernel on qemu-ppc. It deadlocks in the middle of the
kernel boot. Strangely openbios crashes in initialize-forth on
some machines (Feroceon 88FR131), but not on some others (Cortex-A9,
qemu-system-arm emulating a versatilepb board).
With this patch series I am not able to:
- run libc.so on qemu-alpha. ld.so works though.
I have verified that all the problem above are not regressions (when
possible, as without this series, it is not possible to emulate a big
endian CPU).
^ permalink raw reply [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 01/18] tcg/arm: remove SAVE_LR code
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 02/18] tcg/arm: explicitely list clobbered/reserved regs Aurelien Jarno
` (16 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
There is no need to save the LR register (r14) before a call to a
subroutine. According to the "Procedure Call Standard for the ARM
Architecture", it is the job of the callee to save this register.
Moreover, this register is already saved in the prologue/epilogue.
This patch removes the disabled SAVE_LR code, as there is no need to
reenable later.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 43 -------------------------------------------
1 files changed, 0 insertions(+), 43 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index f0f669d..e86ed9a 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -748,10 +748,6 @@ static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
{
int32_t val;
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R8, 0, 14, SHIFT_IMM_LSL(0));
-#endif
-
val = addr - (tcg_target_long) s->code_ptr;
if (val < 0x01fffffd && val > -0x01fffffd)
tcg_out_bl(s, cond, val);
@@ -770,23 +766,13 @@ static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
}
#endif
}
-
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
-#endif
}
static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
{
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R8, 0, 14, SHIFT_IMM_LSL(0));
-#endif
/* TODO: on ARMv5 and ARMv6 replace with tcg_out_blx(s, cond, arg); */
tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 15, SHIFT_IMM_LSL(0));
tcg_out_bx(s, cond, arg);
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
-#endif
}
static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
@@ -922,10 +908,6 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
label_ptr = (void *) s->code_ptr;
tcg_out_b(s, COND_EQ, 8);
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0));
-# endif
-
/* TODO: move this code to where the constants pool will be */
if (addr_reg)
tcg_out_dat_reg(s, cond, ARITH_MOV,
@@ -972,10 +954,6 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
break;
}
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 8, SHIFT_IMM_LSL(0));
-# endif
-
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
#else /* !CONFIG_SOFTMMU */
if (GUEST_BASE) {
@@ -1186,10 +1164,6 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
}
# endif
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0));
-# endif
-
tcg_out_bl(s, cond, (tcg_target_long) qemu_st_helpers[s_bits] -
(tcg_target_long) s->code_ptr);
# if TARGET_LONG_BITS == 64
@@ -1197,10 +1171,6 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 0x10);
# endif
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 8, SHIFT_IMM_LSL(0));
-# endif
-
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
#else /* !CONFIG_SOFTMMU */
if (GUEST_BASE) {
@@ -1254,15 +1224,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
switch (opc) {
case INDEX_op_exit_tb:
-#ifdef SAVE_LR
- if (args[0] >> 8)
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, 15, 0);
- else
- tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, 15, 0, 14, SHIFT_IMM_LSL(0));
- if (args[0] >> 8)
- tcg_out32(s, args[0]);
-#else
{
uint8_t *ld_ptr = s->code_ptr;
if (args[0] >> 8)
@@ -1275,7 +1236,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out32(s, args[0]);
}
}
-#endif
break;
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
@@ -1627,9 +1587,6 @@ void tcg_target_init(TCGContext *s)
(1 << TCG_REG_R12) | (1 << TCG_REG_R14));
tcg_regset_clear(s->reserved_regs);
-#ifdef SAVE_LR
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R14);
-#endif
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R8);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 02/18] tcg/arm: explicitely list clobbered/reserved regs
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 01/18] tcg/arm: remove SAVE_LR code Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 03/18] tcg/arm: remove store signed functions Aurelien Jarno
` (15 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Instead of writing very compact code, declare all registers that are
clobbered or reserved one by one. This makes the code easier to read.
Also declare all the 16 registers to TCG, and mark pc as reserved.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 13 +++++++++----
tcg/arm/tcg-target.h | 3 ++-
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index e86ed9a..35f6c47 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -39,6 +39,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"%r12",
"%r13",
"%r14",
+ "%pc",
};
#endif
@@ -1580,15 +1581,19 @@ void tcg_target_init(TCGContext *s)
tcg_abort();
#endif
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0,
- ((2 << TCG_REG_R14) - 1) & ~(1 << TCG_REG_R8));
+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- ((2 << TCG_REG_R3) - 1) |
- (1 << TCG_REG_R12) | (1 << TCG_REG_R14));
+ (1 << TCG_REG_R0) |
+ (1 << TCG_REG_R1) |
+ (1 << TCG_REG_R2) |
+ (1 << TCG_REG_R3) |
+ (1 << TCG_REG_R12) |
+ (1 << TCG_REG_R14));
tcg_regset_clear(s->reserved_regs);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R8);
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
tcg_add_target_add_op_defs(arm_op_defs);
}
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 6d58de8..a0027b5 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -44,9 +44,10 @@ enum {
TCG_REG_R12,
TCG_REG_R13,
TCG_REG_R14,
+ TCG_REG_PC,
};
-#define TCG_TARGET_NB_REGS 15
+#define TCG_TARGET_NB_REGS 16
#define TCG_CT_CONST_ARM 0x100
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 03/18] tcg/arm: remove store signed functions
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 01/18] tcg/arm: remove SAVE_LR code Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 02/18] tcg/arm: explicitely list clobbered/reserved regs Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 04/18] tcg/arm: replace integer values by registers enum Aurelien Jarno
` (14 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Store signed functions doesn't make sense, and are not used. Remove
them.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 72 +++++++-------------------------------------------
1 files changed, 10 insertions(+), 62 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 35f6c47..e923330 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -499,7 +499,7 @@ static inline void tcg_out_ld16u_8(TCGContext *s, int cond,
(((-im) & 0xf0) << 4) | ((-im) & 0xf));
}
-static inline void tcg_out_st16u_8(TCGContext *s, int cond,
+static inline void tcg_out_st16_8(TCGContext *s, int cond,
int rd, int rn, tcg_target_long im)
{
if (im >= 0)
@@ -519,7 +519,7 @@ static inline void tcg_out_ld16u_r(TCGContext *s, int cond,
(rn << 16) | (rd << 12) | rm);
}
-static inline void tcg_out_st16u_r(TCGContext *s, int cond,
+static inline void tcg_out_st16_r(TCGContext *s, int cond,
int rd, int rn, int rm)
{
tcg_out32(s, (cond << 28) | 0x018000b0 |
@@ -539,19 +539,6 @@ static inline void tcg_out_ld16s_8(TCGContext *s, int cond,
(((-im) & 0xf0) << 4) | ((-im) & 0xf));
}
-static inline void tcg_out_st16s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01c000f0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x014000f0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
static inline void tcg_out_ld16s_r(TCGContext *s, int cond,
int rd, int rn, int rm)
{
@@ -559,13 +546,6 @@ static inline void tcg_out_ld16s_r(TCGContext *s, int cond,
(rn << 16) | (rd << 12) | rm);
}
-static inline void tcg_out_st16s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x018000f0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
static inline void tcg_out_ld8_12(TCGContext *s, int cond,
int rd, int rn, tcg_target_long im)
{
@@ -615,19 +595,6 @@ static inline void tcg_out_ld8s_8(TCGContext *s, int cond,
(((-im) & 0xf0) << 4) | ((-im) & 0xf));
}
-static inline void tcg_out_st8s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01c000d0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x014000d0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
static inline void tcg_out_ld8s_r(TCGContext *s, int cond,
int rd, int rn, int rm)
{
@@ -635,13 +602,6 @@ static inline void tcg_out_ld8s_r(TCGContext *s, int cond,
(rn << 16) | (rd << 12) | rm);
}
-static inline void tcg_out_st8s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x018000d0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
static inline void tcg_out_ld32u(TCGContext *s, int cond,
int rd, int rn, int32_t offset)
{
@@ -682,14 +642,14 @@ static inline void tcg_out_ld16s(TCGContext *s, int cond,
tcg_out_ld16s_8(s, cond, rd, rn, offset);
}
-static inline void tcg_out_st16u(TCGContext *s, int cond,
+static inline void tcg_out_st16(TCGContext *s, int cond,
int rd, int rn, int32_t offset)
{
if (offset > 0xff || offset < -0xff) {
tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_st16u_r(s, cond, rd, rn, TCG_REG_R8);
+ tcg_out_st16_r(s, cond, rd, rn, TCG_REG_R8);
} else
- tcg_out_st16u_8(s, cond, rd, rn, offset);
+ tcg_out_st16_8(s, cond, rd, rn, offset);
}
static inline void tcg_out_ld8u(TCGContext *s, int cond,
@@ -712,7 +672,7 @@ static inline void tcg_out_ld8s(TCGContext *s, int cond,
tcg_out_ld8s_8(s, cond, rd, rn, offset);
}
-static inline void tcg_out_st8u(TCGContext *s, int cond,
+static inline void tcg_out_st8(TCGContext *s, int cond,
int rd, int rn, int32_t offset)
{
if (offset > 0xfff || offset < -0xfff) {
@@ -1075,14 +1035,8 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
case 0:
tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, 1);
break;
- case 0 | 4:
- tcg_out_st8s_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
case 1:
- tcg_out_st16u_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 1 | 4:
- tcg_out_st16s_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, 1);
break;
case 2:
default:
@@ -1193,14 +1147,8 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
case 0:
tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
break;
- case 0 | 4:
- tcg_out_st8s_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
case 1:
- tcg_out_st16u_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 1 | 4:
- tcg_out_st16s_8(s, COND_AL, data_reg, addr_reg, 0);
+ tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
break;
case 2:
default:
@@ -1299,10 +1247,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
break;
case INDEX_op_st8_i32:
- tcg_out_st8u(s, COND_AL, args[0], args[1], args[2]);
+ tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
break;
case INDEX_op_st16_i32:
- tcg_out_st16u(s, COND_AL, args[0], args[1], args[2]);
+ tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
break;
case INDEX_op_st_i32:
tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 04/18] tcg/arm: replace integer values by registers enum
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (2 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 03/18] tcg/arm: remove store signed functions Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 05/18] tcg/arm: align 64-bit arguments in function calls Aurelien Jarno
` (13 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
The TCG ARM backends uses integer values to refer to both immediate
values and register number. This makes the code difficult to read.
The patch below replaces all (if I haven't miss any ;-) integer values
representing register number by TCG_REG_* enum values.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 233 ++++++++++++++++++++++++++-----------------------
1 files changed, 124 insertions(+), 109 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index e923330..ee5f723 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -397,7 +397,7 @@ static inline void tcg_out_mul32(TCGContext *s,
tcg_out32(s, (cond << 28) | ( 8 << 16) | (0 << 12) |
(rs << 8) | 0x90 | rm);
tcg_out_dat_reg(s, cond, ARITH_MOV,
- rd, 0, 8, SHIFT_IMM_LSL(0));
+ rd, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
}
}
@@ -694,12 +694,13 @@ static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
tcg_abort();
#else
if (cond == COND_AL) {
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
tcg_out32(s, addr); /* XXX: This is l->u.value, can we use it? */
} else {
tcg_out_movi32(s, cond, TCG_REG_R8, val - 8);
tcg_out_dat_reg(s, cond, ARITH_ADD,
- 15, 15, TCG_REG_R8, SHIFT_IMM_LSL(0));
+ TCG_REG_PC, TCG_REG_PC,
+ TCG_REG_R8, SHIFT_IMM_LSL(0));
}
#endif
}
@@ -717,12 +718,13 @@ static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
tcg_abort();
#else
if (cond == COND_AL) {
- tcg_out_dat_imm(s, cond, ARITH_ADD, 14, 15, 4);
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
+ tcg_out_dat_imm(s, cond, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
tcg_out32(s, addr); /* XXX: This is l->u.value, can we use it? */
} else {
tcg_out_movi32(s, cond, TCG_REG_R9, addr);
- tcg_out_dat_imm(s, cond, ARITH_MOV, 14, 0, 15);
+ tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
+ TCG_REG_PC, SHIFT_IMM_LSL(0));
tcg_out_bx(s, cond, TCG_REG_R9);
}
#endif
@@ -732,7 +734,8 @@ static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
{
/* TODO: on ARMv5 and ARMv6 replace with tcg_out_blx(s, cond, arg); */
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 15, SHIFT_IMM_LSL(0));
+ tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
+ TCG_REG_PC, SHIFT_IMM_LSL(0));
tcg_out_bx(s, cond, arg);
}
@@ -743,7 +746,7 @@ static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
if (l->has_value)
tcg_out_goto(s, cond, l->u.value);
else if (cond == COND_AL) {
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
tcg_out_reloc(s, s->code_ptr, R_ARM_ABS32, label_index, 31337);
s->code_ptr += 4;
} else {
@@ -807,12 +810,12 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
# if CPU_TLB_BITS > 8
# error
# endif
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- 8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_R8,
+ 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
tcg_out_dat_imm(s, COND_AL, ARITH_AND,
- 0, 8, CPU_TLB_SIZE - 1);
- tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
- 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
+ TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
+ tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_AREG0,
+ TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
/* In the
* ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_read))]
* below, the offset is likely to exceed 12 bits if mem_index != 0 and
@@ -821,13 +824,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
* before.
*/
if (mem_index)
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0,
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
(mem_index << (TLB_SHIFT & 1)) |
((16 - (TLB_SHIFT >> 1)) << 8));
- tcg_out_ld32_12(s, COND_AL, 1, 0,
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0,
offsetof(CPUState, tlb_table[0][0].addr_read));
- tcg_out_dat_reg(s, COND_AL, ARITH_CMP,
- 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
+ tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
+ TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
/* Check alignment. */
if (s_bits)
tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
@@ -835,34 +838,34 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
# if TARGET_LONG_BITS == 64
/* XXX: possibly we could use a block data load or writeback in
* the first access. */
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
+ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
offsetof(CPUState, tlb_table[0][0].addr_read) + 4);
- tcg_out_dat_reg(s, COND_EQ, ARITH_CMP,
- 0, 1, addr_reg2, SHIFT_IMM_LSL(0));
+ tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
+ TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
# endif
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
+ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
offsetof(CPUState, tlb_table[0][0].addend));
switch (opc) {
case 0:
- tcg_out_ld8_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_ld8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 0 | 4:
- tcg_out_ld8s_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_ld8s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 1:
- tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 1 | 4:
- tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 2:
default:
- tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 3:
- tcg_out_ld32_rwb(s, COND_EQ, data_reg, 1, addr_reg);
- tcg_out_ld32_12(s, COND_EQ, data_reg2, 1, 4);
+ tcg_out_ld32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
+ tcg_out_ld32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
break;
}
@@ -870,16 +873,18 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
tcg_out_b(s, COND_EQ, 8);
/* TODO: move this code to where the constants pool will be */
- if (addr_reg)
+ if (addr_reg != TCG_REG_R0) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, addr_reg, SHIFT_IMM_LSL(0));
+ TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
+ }
# if TARGET_LONG_BITS == 32
- tcg_out_dat_imm(s, cond, ARITH_MOV, 1, 0, mem_index);
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R1, 0, mem_index);
# else
- if (addr_reg2 != 1)
+ if (addr_reg2 != TCG_REG_R1) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, addr_reg2, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
+ TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
+ }
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
# endif
tcg_out_bl(s, cond, (tcg_target_long) qemu_ld_helpers[s_bits] -
(tcg_target_long) s->code_ptr);
@@ -887,31 +892,34 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
switch (opc) {
case 0 | 4:
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, 0, SHIFT_IMM_LSL(24));
+ TCG_REG_R0, 0, TCG_REG_R0, SHIFT_IMM_LSL(24));
tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_ASR(24));
+ data_reg, 0, TCG_REG_R0, SHIFT_IMM_ASR(24));
break;
case 1 | 4:
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, 0, SHIFT_IMM_LSL(16));
+ TCG_REG_R0, 0, TCG_REG_R0, SHIFT_IMM_LSL(16));
tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_ASR(16));
+ data_reg, 0, TCG_REG_R0, SHIFT_IMM_ASR(16));
break;
case 0:
case 1:
case 2:
default:
- if (data_reg)
+ if (data_reg != TCG_REG_R0) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_LSL(0));
+ data_reg, 0, TCG_REG_R0, SHIFT_IMM_LSL(0));
+ }
break;
case 3:
- if (data_reg != 0)
+ if (data_reg != TCG_REG_R0) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_LSL(0));
- if (data_reg2 != 1)
+ data_reg, 0, TCG_REG_R0, SHIFT_IMM_LSL(0));
+ }
+ if (data_reg2 != TCG_REG_R1) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg2, 0, 1, SHIFT_IMM_LSL(0));
+ data_reg2, 0, TCG_REG_R1, SHIFT_IMM_LSL(0));
+ }
break;
}
@@ -926,9 +934,9 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
i = ctz32(offset) & ~1;
rot = ((32 - i) << 7) & 0xf00;
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R8, addr_reg,
((offset >> i) & 0xff) | rot);
- addr_reg = 8;
+ addr_reg = TCG_REG_R8;
offset &= ~(0xff << i);
}
}
@@ -995,11 +1003,11 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
* add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
*/
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- 8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
+ TCG_REG_R8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
tcg_out_dat_imm(s, COND_AL, ARITH_AND,
- 0, 8, CPU_TLB_SIZE - 1);
- tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
- 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
+ TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
+ tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0,
+ TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
/* In the
* ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_write))]
* below, the offset is likely to exceed 12 bits if mem_index != 0 and
@@ -1008,13 +1016,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
* before.
*/
if (mem_index)
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0,
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
(mem_index << (TLB_SHIFT & 1)) |
((16 - (TLB_SHIFT >> 1)) << 8));
- tcg_out_ld32_12(s, COND_AL, 1, 0,
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0,
offsetof(CPUState, tlb_table[0][0].addr_write));
- tcg_out_dat_reg(s, COND_AL, ARITH_CMP,
- 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
+ tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
+ TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
/* Check alignment. */
if (s_bits)
tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
@@ -1022,29 +1030,28 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
# if TARGET_LONG_BITS == 64
/* XXX: possibly we could use a block data load or writeback in
* the first access. */
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addr_write)
- + 4);
- tcg_out_dat_reg(s, COND_EQ, ARITH_CMP,
- 0, 1, addr_reg2, SHIFT_IMM_LSL(0));
+ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
+ offsetof(CPUState, tlb_table[0][0].addr_write) + 4);
+ tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
+ TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
# endif
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
+ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
offsetof(CPUState, tlb_table[0][0].addend));
switch (opc) {
case 0:
- tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 1:
- tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 2:
default:
- tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, 1);
+ tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 3:
- tcg_out_st32_rwb(s, COND_EQ, data_reg, 1, addr_reg);
- tcg_out_st32_12(s, COND_EQ, data_reg2, 1, 4);
+ tcg_out_st32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
+ tcg_out_st32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
break;
}
@@ -1052,69 +1059,77 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
tcg_out_b(s, COND_EQ, 8);
/* TODO: move this code to where the constants pool will be */
- if (addr_reg)
+ if (addr_reg != TCG_REG_R0) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, addr_reg, SHIFT_IMM_LSL(0));
+ TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
+ }
# if TARGET_LONG_BITS == 32
switch (opc) {
case 0:
- tcg_out_dat_imm(s, cond, ARITH_AND, 1, data_reg, 0xff);
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
+ tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R1, data_reg, 0xff);
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 1:
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, data_reg, SHIFT_IMM_LSL(16));
+ TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(16));
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, 1, SHIFT_IMM_LSR(16));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
+ TCG_REG_R1, 0, TCG_REG_R1, SHIFT_IMM_LSR(16));
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 2:
- if (data_reg != 1)
+ if (data_reg != TCG_REG_R1) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, data_reg, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
+ TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
+ }
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 3:
- if (data_reg != 1)
+ if (data_reg != TCG_REG_R1) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, data_reg, SHIFT_IMM_LSL(0));
- if (data_reg2 != 2)
+ TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
+ }
+ if (data_reg2 != TCG_REG_R2) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg2, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
+ TCG_REG_R2, 0, data_reg2, SHIFT_IMM_LSL(0));
+ }
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
}
# else
- if (addr_reg2 != 1)
+ if (addr_reg2 != TCG_REG_R1) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, addr_reg2, SHIFT_IMM_LSL(0));
+ TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
+ }
switch (opc) {
case 0:
- tcg_out_dat_imm(s, cond, ARITH_AND, 2, data_reg, 0xff);
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
+ tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R2, data_reg, 0xff);
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 1:
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg, SHIFT_IMM_LSL(16));
+ TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(16));
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, 2, SHIFT_IMM_LSR(16));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
+ TCG_REG_R2, 0, TCG_REG_R2, SHIFT_IMM_LSR(16));
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 2:
- if (data_reg != 2)
+ if (data_reg != TCG_REG_R2) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
+ TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
+ }
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 3:
- tcg_out_dat_imm(s, cond, ARITH_MOV, 8, 0, mem_index);
+ tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R8, 0, mem_index);
tcg_out32(s, (cond << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
- if (data_reg != 2)
+ if (data_reg != TCG_REG_R2) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg, SHIFT_IMM_LSL(0));
- if (data_reg2 != 3)
+ TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
+ }
+ if (data_reg2 != TCG_REG_R3) {
tcg_out_dat_reg(s, cond, ARITH_MOV,
- 3, 0, data_reg2, SHIFT_IMM_LSL(0));
+ TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
+ }
break;
}
# endif
@@ -1123,7 +1138,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
(tcg_target_long) s->code_ptr);
# if TARGET_LONG_BITS == 64
if (opc == 3)
- tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 0x10);
+ tcg_out_dat_imm(s, cond, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
@@ -1137,9 +1152,9 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
i = ctz32(offset) & ~1;
rot = ((32 - i) << 7) & 0xf00;
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R8, addr_reg,
((offset >> i) & 0xff) | rot);
- addr_reg = 8;
+ addr_reg = TCG_REG_R8;
offset &= ~(0xff << i);
}
}
@@ -1176,9 +1191,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
{
uint8_t *ld_ptr = s->code_ptr;
if (args[0] >> 8)
- tcg_out_ld32_12(s, COND_AL, 0, 15, 0);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
else
- tcg_out_dat_imm(s, COND_AL, ARITH_MOV, 0, 0, args[0]);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);
tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
if (args[0] >> 8) {
*ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;
@@ -1193,7 +1208,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
tcg_out_b(s, COND_AL, 8);
#else
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
tcg_out32(s, 0);
#endif
@@ -1204,12 +1219,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
if (c > 0xfff || c < -0xfff) {
tcg_out_movi32(s, COND_AL, TCG_REG_R0,
(tcg_target_long) (s->tb_next + args[0]));
- tcg_out_ld32_12(s, COND_AL, 15, TCG_REG_R0, 0);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
} else
- tcg_out_ld32_12(s, COND_AL, 15, 15, c);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);
#else
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, 15, 0);
- tcg_out_ld32_12(s, COND_AL, 15, TCG_REG_R0, 0);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
#endif
}
@@ -1335,8 +1350,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
if (const_args[1]) {
int rot;
rot = encode_imm(args[1]);
- tcg_out_dat_imm(s, COND_AL, ARITH_CMP,
- 0, args[0], rotl(args[1], rot) | (rot << 7));
+ tcg_out_dat_imm(s, COND_AL, ARITH_CMP, 0,
+ args[0], rotl(args[1], rot) | (rot << 7));
} else {
tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
args[0], args[1], SHIFT_IMM_LSL(0));
@@ -1362,8 +1377,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
if (const_args[2]) {
int rot;
rot = encode_imm(args[2]);
- tcg_out_dat_imm(s, COND_AL, ARITH_CMP,
- 0, args[1], rotl(args[2], rot) | (rot << 7));
+ tcg_out_dat_imm(s, COND_AL, ARITH_CMP, 0,
+ args[1], rotl(args[2], rot) | (rot << 7));
} else {
tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
args[1], args[2], SHIFT_IMM_LSL(0));
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 05/18] tcg/arm: align 64-bit arguments in function calls
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (3 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 04/18] tcg/arm: replace integer values by registers enum Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set Aurelien Jarno
` (12 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
As specified by the "Procedure Call Standard for the ARM Architecture".
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index a0027b5..334edfa 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -54,6 +54,7 @@ enum {
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_R13
#define TCG_TARGET_STACK_ALIGN 8
+#define TCG_TARGET_CALL_ALIGN_ARGS 1
#define TCG_TARGET_CALL_STACK_OFFSET 0
/* optional instructions */
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (4 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 05/18] tcg/arm: align 64-bit arguments in function calls Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-08 13:46 ` Paul Brook
2010-04-08 16:46 ` Richard Henderson
2010-04-07 17:51 ` [Qemu-devel] [PATCH 07/18] tcg/arm: sxtb and sxth are available starting with ARMv6 Aurelien Jarno
` (11 subsequent siblings)
17 siblings, 2 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Use a set of #define to define the allowed ARM instructions, depending
on the __ARM_ARCH_*__ GCC defines.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 27 ++++++++++++++++++++++++---
1 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index ee5f723..cae6385 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -22,6 +22,27 @@
* THE SOFTWARE.
*/
+#if defined(__ARM_ARCH_5T__) || \
+ defined(__ARM_ARCH_5TE__) || \
+ defined(__ARM_ARCH_5TEJ__) || \
+ defined(__ARM_ARCH_6__) || \
+ defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7__)
+# define USE_ARMV5_INSTRUCTIONS 1
+#endif
+
+#if defined(__ARM_ARCH_6__) || \
+ defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7__)
+# define USE_ARMV6_INSTRUCTIONS 1
+#endif
+
+#if defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7__)
+# define USE_ARMV7_INSTRUCTIONS 1
+#endif
+
+
#ifndef NDEBUG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"%r0",
@@ -361,7 +382,7 @@ static inline void tcg_out_movi32(TCGContext *s,
tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) :
tcg_out_dat_imm(s, cond, ARITH_SUB, rd, 15, -offset);
-#ifdef __ARM_ARCH_7A__
+#ifdef USE_ARMV7_INSTRUCTIONS
/* use movw/movt */
/* movw */
tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
@@ -1433,7 +1454,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_ext8s_i32:
-#ifdef __ARM_ARCH_7A__
+#ifdef USE_ARMV7_INSTRUCTIONS
/* sxtb */
tcg_out32(s, 0xe6af0070 | (args[0] << 12) | args[1]);
#else
@@ -1444,7 +1465,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
#endif
break;
case INDEX_op_ext16s_i32:
-#ifdef __ARM_ARCH_7A__
+#ifdef USE_ARMV7_INSTRUCTIONS
/* sxth */
tcg_out32(s, 0xe6bf0070 | (args[0] << 12) | args[1]);
#else
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 07/18] tcg/arm: sxtb and sxth are available starting with ARMv6
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (5 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 08/18] tcg/arm: use the blx instruction when possible Aurelien Jarno
` (10 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index cae6385..777c4ac 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1454,7 +1454,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_ext8s_i32:
-#ifdef USE_ARMV7_INSTRUCTIONS
+#ifdef USE_ARMV6_INSTRUCTIONS
/* sxtb */
tcg_out32(s, 0xe6af0070 | (args[0] << 12) | args[1]);
#else
@@ -1465,7 +1465,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
#endif
break;
case INDEX_op_ext16s_i32:
-#ifdef USE_ARMV7_INSTRUCTIONS
+#ifdef USE_ARMV6_INSTRUCTIONS
/* sxth */
tcg_out32(s, 0xe6bf0070 | (args[0] << 12) | args[1]);
#else
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 08/18] tcg/arm: use the blx instruction when possible
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (6 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 07/18] tcg/arm: sxtb and sxth are available starting with ARMv6 Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 09/18] tcg/arm: add rotation ops Aurelien Jarno
` (9 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 777c4ac..3360c23 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -333,6 +333,11 @@ static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
(((offset - 8) >> 2) & 0x00ffffff));
}
+static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
+{
+ tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
+}
+
static inline void tcg_out_dat_reg(TCGContext *s,
int cond, int opc, int rd, int rn, int rm, int shift)
{
@@ -754,10 +759,13 @@ static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
{
- /* TODO: on ARMv5 and ARMv6 replace with tcg_out_blx(s, cond, arg); */
+#ifdef USE_ARMV5_INSTRUCTIONS
+ tcg_out_blx(s, cond, arg);
+#else
tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
TCG_REG_PC, SHIFT_IMM_LSL(0));
tcg_out_bx(s, cond, arg);
+#endif
}
static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 09/18] tcg/arm: add rotation ops
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (7 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 08/18] tcg/arm: use the blx instruction when possible Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 10/18] tcg/arm: add ext16u op Aurelien Jarno
` (8 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 19 +++++++++++++++++++
tcg/arm/tcg-target.h | 2 +-
2 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 3360c23..4290c4f 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1370,11 +1370,28 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_sar_i32:
c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
+ goto gen_shift32;
+ case INDEX_op_rotr_i32:
+ c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
+ SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
/* Fall through. */
gen_shift32:
tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
break;
+ case INDEX_op_rotl_i32:
+ if (const_args[2]) {
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
+ ((0x20 - args[2]) & 0x1f) ?
+ SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
+ SHIFT_IMM_LSL(0));
+ } else {
+ tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_R8, args[1], 0x20);
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
+ SHIFT_REG_ROR(TCG_REG_R8));
+ }
+ break;
+
case INDEX_op_brcond_i32:
if (const_args[1]) {
int rot;
@@ -1523,6 +1540,8 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_shl_i32, { "r", "r", "ri" } },
{ INDEX_op_shr_i32, { "r", "r", "ri" } },
{ INDEX_op_sar_i32, { "r", "r", "ri" } },
+ { INDEX_op_rotl_i32, { "r", "r", "ri" } },
+ { INDEX_op_rotr_i32, { "r", "r", "ri" } },
{ INDEX_op_brcond_i32, { "r", "rI" } },
{ INDEX_op_setcond_i32, { "r", "r", "rI" } },
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 334edfa..bc08f91 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -66,7 +66,7 @@ enum {
// #define TCG_TARGET_HAS_bswap32_i32
#define TCG_TARGET_HAS_not_i32
#define TCG_TARGET_HAS_neg_i32
-// #define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_rot_i32
#define TCG_TARGET_HAS_andc_i32
// #define TCG_TARGET_HAS_orc_i32
// #define TCG_TARGET_HAS_eqv_i32
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 10/18] tcg/arm: add ext16u op
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (8 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 09/18] tcg/arm: add rotation ops Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops Aurelien Jarno
` (7 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Add an ext16u op, either using the uxth instruction on ARMv6+ or two
shifts on previous ARM versions. In both cases the result use the same
number or less instructions than the pure TCG version.
Also move all sign extension code to separate functions, so that it can
be reused in other parts of the code.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 66 ++++++++++++++++++++++++++++++++++++-------------
tcg/arm/tcg-target.h | 4 +-
2 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 4290c4f..d8ba5f1 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -461,6 +461,48 @@ static inline void tcg_out_smull32(TCGContext *s,
}
}
+static inline void tcg_out_ext8s(TCGContext *s, int cond,
+ int rd, int rn)
+{
+#ifdef USE_ARMV6_INSTRUCTIONS
+ /* sxtb */
+ tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
+#else
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ rd, 0, rn, SHIFT_IMM_LSL(24));
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ rd, 0, rd, SHIFT_IMM_ASR(24));
+#endif
+}
+
+static inline void tcg_out_ext16s(TCGContext *s, int cond,
+ int rd, int rn)
+{
+#ifdef USE_ARMV6_INSTRUCTIONS
+ /* sxth */
+ tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
+#else
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ rd, 0, rn, SHIFT_IMM_LSL(16));
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ rd, 0, rd, SHIFT_IMM_ASR(16));
+#endif
+}
+
+static inline void tcg_out_ext16u(TCGContext *s, int cond,
+ int rd, int rn)
+{
+#ifdef USE_ARMV6_INSTRUCTIONS
+ /* uxth */
+ tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
+#else
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ rd, 0, rn, SHIFT_IMM_LSL(16));
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ rd, 0, rd, SHIFT_IMM_LSR(16));
+#endif
+}
+
static inline void tcg_out_ld32_12(TCGContext *s, int cond,
int rd, int rn, tcg_target_long im)
{
@@ -1479,26 +1521,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_ext8s_i32:
-#ifdef USE_ARMV6_INSTRUCTIONS
- /* sxtb */
- tcg_out32(s, 0xe6af0070 | (args[0] << 12) | args[1]);
-#else
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[1], SHIFT_IMM_LSL(24));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[0], SHIFT_IMM_ASR(24));
-#endif
+ tcg_out_ext8s(s, COND_AL, args[0], args[1]);
break;
case INDEX_op_ext16s_i32:
-#ifdef USE_ARMV6_INSTRUCTIONS
- /* sxth */
- tcg_out32(s, 0xe6bf0070 | (args[0] << 12) | args[1]);
-#else
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[1], SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[0], SHIFT_IMM_ASR(16));
-#endif
+ tcg_out_ext16s(s, COND_AL, args[0], args[1]);
+ break;
+ case INDEX_op_ext16u_i32:
+ tcg_out_ext16u(s, COND_AL, args[0], args[1]);
break;
default:
@@ -1580,6 +1609,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_ext8s_i32, { "r", "r" } },
{ INDEX_op_ext16s_i32, { "r", "r" } },
+ { INDEX_op_ext16u_i32, { "r", "r" } },
{ -1 },
};
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index bc08f91..1f6d665 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -60,8 +60,8 @@ enum {
/* optional instructions */
#define TCG_TARGET_HAS_ext8s_i32
#define TCG_TARGET_HAS_ext16s_i32
-// #define TCG_TARGET_HAS_ext8u_i32
-// #define TCG_TARGET_HAS_ext16u_i32
+#undef TCG_TARGET_HAS_ext8u_i32 /* and r0, r1, #0xff */
+#define TCG_TARGET_HAS_ext16u_i32
// #define TCG_TARGET_HAS_bswap16_i32
// #define TCG_TARGET_HAS_bswap32_i32
#define TCG_TARGET_HAS_not_i32
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (9 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 10/18] tcg/arm: add ext16u op Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-08 23:32 ` Paul Brook
2010-04-07 17:51 ` [Qemu-devel] [PATCH 12/18] tcg/arm: remove conditional argument for qemu_ld/st Aurelien Jarno
` (6 subsequent siblings)
17 siblings, 1 reply; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Add an bswap16 and bswap32 ops, either using the rev and rev16
instructions on ARMv6+ or shifts and logical operations on previous
ARM versions. In both cases the result use less instructions than
the pure TCG version.
These ops are also needed by the qemu_ld/st functions.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
tcg/arm/tcg-target.h | 4 ++--
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index d8ba5f1..aec1183 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -503,6 +503,44 @@ static inline void tcg_out_ext16u(TCGContext *s, int cond,
#endif
}
+static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
+{
+#ifdef USE_ARMV6_INSTRUCTIONS
+ /* rev16 */
+ tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
+#else
+ tcg_out_dat_reg(s, cond, ARITH_MOV,
+ TCG_REG_R8, 0, rn, SHIFT_IMM_LSL(24));
+ tcg_out_dat_reg(s, cond, ARITH_MOV,
+ TCG_REG_R8, 0, TCG_REG_R8, SHIFT_IMM_LSR(16));
+ tcg_out_dat_reg(s, cond, ARITH_ORR,
+ rd, TCG_REG_R8, rn, SHIFT_IMM_LSR(8));
+#endif
+}
+
+static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
+{
+#ifdef USE_ARMV6_INSTRUCTIONS
+ /* rev */
+ tcg_out32(s, 0x06bf0f30 | (cond << 28) | (rd << 12) | rn);
+#else
+ /* This code only uses one temporary register. There is probably
+ a faster way to do that with more temporary registers. */
+ tcg_out_dat_reg(s, cond, ARITH_MOV,
+ TCG_REG_R8, 0, rn, SHIFT_IMM_ROR(8));
+ tcg_out_dat_imm(s, cond, ARITH_BIC,
+ rd, TCG_REG_R8, 0xff);
+ tcg_out_dat_imm(s, cond, ARITH_BIC,
+ rd, rd, 0xff | 0x800);
+ tcg_out_dat_imm(s, cond, ARITH_BIC,
+ TCG_REG_R8, TCG_REG_R8, 0xff | 0x400);
+ tcg_out_dat_imm(s, cond, ARITH_BIC,
+ TCG_REG_R8, TCG_REG_R8, 0xff | 0xc00);
+ tcg_out_dat_reg(s, cond, ARITH_ORR,
+ rd, rd, TCG_REG_R8, SHIFT_IMM_ROR(16));
+#endif
+}
+
static inline void tcg_out_ld32_12(TCGContext *s, int cond,
int rd, int rn, tcg_target_long im)
{
@@ -1520,6 +1558,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_qemu_st(s, COND_AL, args, 3);
break;
+ case INDEX_op_bswap16_i32:
+ tcg_out_bswap16(s, COND_AL, args[0], args[1]);
+ break;
+ case INDEX_op_bswap32_i32:
+ tcg_out_bswap32(s, COND_AL, args[0], args[1]);
+ break;
+
case INDEX_op_ext8s_i32:
tcg_out_ext8s(s, COND_AL, args[0], args[1]);
break;
@@ -1607,6 +1652,9 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_qemu_st64, { "x", "D", "x", "X" } },
#endif
+ { INDEX_op_bswap16_i32, { "r", "r" } },
+ { INDEX_op_bswap32_i32, { "r", "r" } },
+
{ INDEX_op_ext8s_i32, { "r", "r" } },
{ INDEX_op_ext16s_i32, { "r", "r" } },
{ INDEX_op_ext16u_i32, { "r", "r" } },
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 1f6d665..d8d7d94 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -62,8 +62,8 @@ enum {
#define TCG_TARGET_HAS_ext16s_i32
#undef TCG_TARGET_HAS_ext8u_i32 /* and r0, r1, #0xff */
#define TCG_TARGET_HAS_ext16u_i32
-// #define TCG_TARGET_HAS_bswap16_i32
-// #define TCG_TARGET_HAS_bswap32_i32
+#define TCG_TARGET_HAS_bswap16_i32
+#define TCG_TARGET_HAS_bswap32_i32
#define TCG_TARGET_HAS_not_i32
#define TCG_TARGET_HAS_neg_i32
#define TCG_TARGET_HAS_rot_i32
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 12/18] tcg/arm: remove conditional argument for qemu_ld/st
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (10 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 13/18] tcg/arm: use ext* ops in qemu_ld Aurelien Jarno
` (5 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
While it make sense to pass a conditional argument to tcg_out_*()
functions as the ARM architecture allows that, it doesn't make sense
for qemu_ld/st functions. These functions use comparison instructions
and conditional execution already, so it is not possible to use a
second level of conditional execution.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 100 ++++++++++++++++++++++++-------------------------
1 files changed, 49 insertions(+), 51 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index aec1183..d24a245 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -886,8 +886,7 @@ static void *qemu_st_helpers[4] = {
#define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
-static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
- const TCGArg *args, int opc)
+static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
{
int addr_reg, data_reg, data_reg2;
#ifdef CONFIG_SOFTMMU
@@ -983,32 +982,32 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
/* TODO: move this code to where the constants pool will be */
if (addr_reg != TCG_REG_R0) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
}
# if TARGET_LONG_BITS == 32
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R1, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R1, 0, mem_index);
# else
if (addr_reg2 != TCG_REG_R1) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
}
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
# endif
- tcg_out_bl(s, cond, (tcg_target_long) qemu_ld_helpers[s_bits] -
+ tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_ld_helpers[s_bits] -
(tcg_target_long) s->code_ptr);
switch (opc) {
case 0 | 4:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R0, 0, TCG_REG_R0, SHIFT_IMM_LSL(24));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
data_reg, 0, TCG_REG_R0, SHIFT_IMM_ASR(24));
break;
case 1 | 4:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R0, 0, TCG_REG_R0, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
data_reg, 0, TCG_REG_R0, SHIFT_IMM_ASR(16));
break;
case 0:
@@ -1016,17 +1015,17 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
case 2:
default:
if (data_reg != TCG_REG_R0) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
data_reg, 0, TCG_REG_R0, SHIFT_IMM_LSL(0));
}
break;
case 3:
if (data_reg != TCG_REG_R0) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
data_reg, 0, TCG_REG_R0, SHIFT_IMM_LSL(0));
}
if (data_reg2 != TCG_REG_R1) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
data_reg2, 0, TCG_REG_R1, SHIFT_IMM_LSL(0));
}
break;
@@ -1081,8 +1080,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
#endif
}
-static inline void tcg_out_qemu_st(TCGContext *s, int cond,
- const TCGArg *args, int opc)
+static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
{
int addr_reg, data_reg, data_reg2;
#ifdef CONFIG_SOFTMMU
@@ -1169,85 +1167,85 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
/* TODO: move this code to where the constants pool will be */
if (addr_reg != TCG_REG_R0) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
}
# if TARGET_LONG_BITS == 32
switch (opc) {
case 0:
- tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R1, data_reg, 0xff);
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_AND, TCG_REG_R1, data_reg, 0xff);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 1:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, TCG_REG_R1, SHIFT_IMM_LSR(16));
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 2:
if (data_reg != TCG_REG_R1) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
}
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R2, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 3:
if (data_reg != TCG_REG_R1) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
}
if (data_reg2 != TCG_REG_R2) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg2, SHIFT_IMM_LSL(0));
}
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
}
# else
if (addr_reg2 != TCG_REG_R1) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
}
switch (opc) {
case 0:
- tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R2, data_reg, 0xff);
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_AND, TCG_REG_R2, data_reg, 0xff);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 1:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, TCG_REG_R2, SHIFT_IMM_LSR(16));
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 2:
if (data_reg != TCG_REG_R2) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
}
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R3, 0, mem_index);
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 3:
- tcg_out_dat_imm(s, cond, ARITH_MOV, TCG_REG_R8, 0, mem_index);
- tcg_out32(s, (cond << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index);
+ tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
if (data_reg != TCG_REG_R2) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
}
if (data_reg2 != TCG_REG_R3) {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
}
break;
}
# endif
- tcg_out_bl(s, cond, (tcg_target_long) qemu_st_helpers[s_bits] -
+ tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_st_helpers[s_bits] -
(tcg_target_long) s->code_ptr);
# if TARGET_LONG_BITS == 64
if (opc == 3)
- tcg_out_dat_imm(s, cond, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
@@ -1527,35 +1525,35 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, COND_AL, args, 0);
+ tcg_out_qemu_ld(s, args, 0);
break;
case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, COND_AL, args, 0 | 4);
+ tcg_out_qemu_ld(s, args, 0 | 4);
break;
case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, COND_AL, args, 1);
+ tcg_out_qemu_ld(s, args, 1);
break;
case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, COND_AL, args, 1 | 4);
+ tcg_out_qemu_ld(s, args, 1 | 4);
break;
case INDEX_op_qemu_ld32:
- tcg_out_qemu_ld(s, COND_AL, args, 2);
+ tcg_out_qemu_ld(s, args, 2);
break;
case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, COND_AL, args, 3);
+ tcg_out_qemu_ld(s, args, 3);
break;
case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, COND_AL, args, 0);
+ tcg_out_qemu_st(s, args, 0);
break;
case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, COND_AL, args, 1);
+ tcg_out_qemu_st(s, args, 1);
break;
case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, COND_AL, args, 2);
+ tcg_out_qemu_st(s, args, 2);
break;
case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, COND_AL, args, 3);
+ tcg_out_qemu_st(s, args, 3);
break;
case INDEX_op_bswap16_i32:
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 13/18] tcg/arm: use ext* ops in qemu_ld
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (11 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 12/18] tcg/arm: remove conditional argument for qemu_ld/st Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 14/18] tcg/arm: bswap arguments in qemu_ld/st if needed Aurelien Jarno
` (4 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 30 ++++++++++++------------------
1 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index d24a245..33ca2ca 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -475,6 +475,12 @@ static inline void tcg_out_ext8s(TCGContext *s, int cond,
#endif
}
+static inline void tcg_out_ext8u(TCGContext *s, int cond,
+ int rd, int rn)
+{
+ tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
+}
+
static inline void tcg_out_ext16s(TCGContext *s, int cond,
int rd, int rn)
{
@@ -999,16 +1005,10 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
switch (opc) {
case 0 | 4:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R0, 0, TCG_REG_R0, SHIFT_IMM_LSL(24));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- data_reg, 0, TCG_REG_R0, SHIFT_IMM_ASR(24));
+ tcg_out_ext8s(s, COND_AL, data_reg, TCG_REG_R0);
break;
case 1 | 4:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R0, 0, TCG_REG_R0, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- data_reg, 0, TCG_REG_R0, SHIFT_IMM_ASR(16));
+ tcg_out_ext16s(s, COND_AL, data_reg, TCG_REG_R0);
break;
case 0:
case 1:
@@ -1173,14 +1173,11 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
# if TARGET_LONG_BITS == 32
switch (opc) {
case 0:
- tcg_out_dat_imm(s, COND_AL, ARITH_AND, TCG_REG_R1, data_reg, 0xff);
+ tcg_out_ext8u(s, COND_AL, TCG_REG_R1, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 1:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, TCG_REG_R1, SHIFT_IMM_LSR(16));
+ tcg_out_ext16u(s, COND_AL, TCG_REG_R1, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 2:
@@ -1209,14 +1206,11 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
}
switch (opc) {
case 0:
- tcg_out_dat_imm(s, COND_AL, ARITH_AND, TCG_REG_R2, data_reg, 0xff);
+ tcg_out_ext8u(s, COND_AL, TCG_REG_R2, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 1:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R2, 0, TCG_REG_R2, SHIFT_IMM_LSR(16));
+ tcg_out_ext16u(s, COND_AL, TCG_REG_R2, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 2:
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 14/18] tcg/arm: bswap arguments in qemu_ld/st if needed
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (12 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 13/18] tcg/arm: use ext* ops in qemu_ld Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 15/18] tcg/arm: remove useless register tests in qemu_ld/st Aurelien Jarno
` (3 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
On big endian targets, data arguments of qemu_ld/st ops have to be
byte swapped. Two temporary registers are needed for qemu_st to do
the bswap. r0 and r1 are used in system mode, do the same in user
mode, which implies reworking the constraints.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 228 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 159 insertions(+), 69 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 33ca2ca..4b414ff 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -127,57 +127,55 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
break;
case 'r':
-#ifndef CONFIG_SOFTMMU
- case 'd':
- case 'D':
- case 'x':
- case 'X':
-#endif
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
break;
-#ifdef CONFIG_SOFTMMU
- /* qemu_ld/st inputs (unless 'X', 'd' or 'D') */
- case 'x':
+ /* qemu_ld address */
+ case 'l':
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
+#ifdef CONFIG_SOFTMMU
+ /* r0 and r1 will be overwritten when reading the tlb entry,
+ so don't use these. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
+#endif
break;
-
- /* qemu_ld64 data_reg */
- case 'd':
+ case 'L':
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- /* r1 is still needed to load data_reg2, so don't use it. */
+#ifdef CONFIG_SOFTMMU
+ /* r1 is still needed to load data_reg or data_reg2,
+ so don't use it. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
+#endif
break;
- /* qemu_ld/st64 data_reg2 */
- case 'D':
+ /* qemu_st address & data_reg */
+ case 's':
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- /* r0, r1 and optionally r2 will be overwritten by the address
- * and the low word of data, so don't use these. */
+ /* r0 and r1 will be overwritten when reading the tlb entry
+ (softmmu only) and doing the byte swapping, so don't
+ use these. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-# if TARGET_LONG_BITS == 64
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
-# endif
break;
-
-# if TARGET_LONG_BITS == 64
- /* qemu_ld/st addr_reg2 */
- case 'X':
+ /* qemu_st64 data_reg2 */
+ case 'S':
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- /* r0 will be overwritten by the low word of base, so don't use it. */
+ /* r0 and r1 will be overwritten when reading the tlb entry
+ (softmmu only) and doing the byte swapping, so don't
+ use these. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
- break;
-# endif
+#ifdef CONFIG_SOFTMMU
+ /* r2 is still needed to load data_reg, so don't use it. */
+ tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
#endif
+ break;
default:
return -1;
@@ -509,6 +507,21 @@ static inline void tcg_out_ext16u(TCGContext *s, int cond,
#endif
}
+static inline void tcg_out_bswap16s(TCGContext *s, int cond, int rd, int rn)
+{
+#ifdef USE_ARMV6_INSTRUCTIONS
+ /* rev16 */
+ tcg_out32(s, 0x06ff0fb0 | (cond << 28) | (rd << 12) | rn);
+#else
+ tcg_out_dat_reg(s, cond, ARITH_MOV,
+ TCG_REG_R8, 0, rn, SHIFT_IMM_LSL(24));
+ tcg_out_dat_reg(s, cond, ARITH_MOV,
+ TCG_REG_R8, 0, TCG_REG_R8, SHIFT_IMM_ASR(16));
+ tcg_out_dat_reg(s, cond, ARITH_ORR,
+ rd, TCG_REG_R8, rn, SHIFT_IMM_LSR(8));
+#endif
+}
+
static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
{
#ifdef USE_ARMV6_INSTRUCTIONS
@@ -894,7 +907,7 @@ static void *qemu_st_helpers[4] = {
static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
{
- int addr_reg, data_reg, data_reg2;
+ int addr_reg, data_reg, data_reg2, bswap;
#ifdef CONFIG_SOFTMMU
int mem_index, s_bits;
# if TARGET_LONG_BITS == 64
@@ -903,6 +916,11 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
uint32_t *label_ptr;
#endif
+#ifdef TARGET_WORDS_BIGENDIAN
+ bswap = 1;
+#else
+ bswap = 0;
+#endif
data_reg = *args++;
if (opc == 3)
data_reg2 = *args++;
@@ -969,17 +987,35 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
break;
case 1:
tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ if (bswap) {
+ tcg_out_bswap16(s, COND_EQ, data_reg, data_reg);
+ }
break;
case 1 | 4:
- tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ if (bswap) {
+ tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ tcg_out_bswap16s(s, COND_EQ, data_reg, data_reg);
+ } else {
+ tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ }
break;
case 2:
default:
tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ if (bswap) {
+ tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
+ }
break;
case 3:
- tcg_out_ld32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
- tcg_out_ld32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
+ if (bswap) {
+ tcg_out_ld32_rwb(s, COND_EQ, data_reg2, TCG_REG_R1, addr_reg);
+ tcg_out_ld32_12(s, COND_EQ, data_reg, TCG_REG_R1, 4);
+ tcg_out_bswap32(s, COND_EQ, data_reg2, data_reg2);
+ tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
+ } else {
+ tcg_out_ld32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
+ tcg_out_ld32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
+ }
break;
}
@@ -1057,23 +1093,38 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
break;
case 1:
tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
+ if (bswap) {
+ tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
+ }
break;
case 1 | 4:
- tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
+ if (bswap) {
+ tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
+ tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
+ } else {
+ tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
+ }
break;
case 2:
default:
tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
+ if (bswap) {
+ tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
+ }
break;
case 3:
/* TODO: use block load -
* check that data_reg2 > data_reg or the other way */
if (data_reg == addr_reg) {
- tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, 4);
- tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
+ tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
+ tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
} else {
- tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
- tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, 4);
+ tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
+ tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
+ }
+ if (bswap) {
+ tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
+ tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
}
break;
}
@@ -1082,7 +1133,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
{
- int addr_reg, data_reg, data_reg2;
+ int addr_reg, data_reg, data_reg2, bswap;
#ifdef CONFIG_SOFTMMU
int mem_index, s_bits;
# if TARGET_LONG_BITS == 64
@@ -1091,6 +1142,11 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
uint32_t *label_ptr;
#endif
+#ifdef TARGET_WORDS_BIGENDIAN
+ bswap = 1;
+#else
+ bswap = 0;
+#endif
data_reg = *args++;
if (opc == 3)
data_reg2 = *args++;
@@ -1150,15 +1206,32 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
break;
case 1:
- tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ if (bswap) {
+ tcg_out_bswap16(s, COND_EQ, TCG_REG_R0, data_reg);
+ tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
+ } else {
+ tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ }
break;
case 2:
default:
- tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ if (bswap) {
+ tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
+ tcg_out_st32_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
+ } else {
+ tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
+ }
break;
case 3:
- tcg_out_st32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
- tcg_out_st32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
+ if (bswap) {
+ tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg2);
+ tcg_out_st32_rwb(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, addr_reg);
+ tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
+ tcg_out_st32_12(s, COND_EQ, data_reg, TCG_REG_R1, 4);
+ } else {
+ tcg_out_st32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
+ tcg_out_st32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
+ }
break;
}
@@ -1253,9 +1326,9 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
i = ctz32(offset) & ~1;
rot = ((32 - i) << 7) & 0xf00;
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R8, addr_reg,
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R1, addr_reg,
((offset >> i) & 0xff) | rot);
- addr_reg = TCG_REG_R8;
+ addr_reg = TCG_REG_R1;
offset &= ~(0xff << i);
}
}
@@ -1264,17 +1337,34 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
break;
case 1:
- tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
+ if (bswap) {
+ tcg_out_bswap16(s, COND_AL, TCG_REG_R0, data_reg);
+ tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0);
+ } else {
+ tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
+ }
break;
case 2:
default:
- tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
+ if (bswap) {
+ tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
+ tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
+ } else {
+ tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
+ }
break;
case 3:
/* TODO: use block store -
* check that data_reg2 > data_reg or the other way */
- tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
- tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
+ if (bswap) {
+ tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg2);
+ tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
+ tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
+ tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 4);
+ } else {
+ tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
+ tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
+ }
break;
}
#endif
@@ -1619,29 +1709,29 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_setcond2_i32, { "r", "r", "r", "r", "r" } },
#if TARGET_LONG_BITS == 32
- { INDEX_op_qemu_ld8u, { "r", "x" } },
- { INDEX_op_qemu_ld8s, { "r", "x" } },
- { INDEX_op_qemu_ld16u, { "r", "x" } },
- { INDEX_op_qemu_ld16s, { "r", "x" } },
- { INDEX_op_qemu_ld32, { "r", "x" } },
- { INDEX_op_qemu_ld64, { "d", "r", "x" } },
-
- { INDEX_op_qemu_st8, { "x", "x" } },
- { INDEX_op_qemu_st16, { "x", "x" } },
- { INDEX_op_qemu_st32, { "x", "x" } },
- { INDEX_op_qemu_st64, { "x", "D", "x" } },
+ { INDEX_op_qemu_ld8u, { "r", "l" } },
+ { INDEX_op_qemu_ld8s, { "r", "l" } },
+ { INDEX_op_qemu_ld16u, { "r", "l" } },
+ { INDEX_op_qemu_ld16s, { "r", "l" } },
+ { INDEX_op_qemu_ld32, { "r", "l" } },
+ { INDEX_op_qemu_ld64, { "L", "L", "l" } },
+
+ { INDEX_op_qemu_st8, { "s", "s" } },
+ { INDEX_op_qemu_st16, { "s", "s" } },
+ { INDEX_op_qemu_st32, { "s", "s" } },
+ { INDEX_op_qemu_st64, { "s", "S", "s" } },
#else
- { INDEX_op_qemu_ld8u, { "r", "x", "X" } },
- { INDEX_op_qemu_ld8s, { "r", "x", "X" } },
- { INDEX_op_qemu_ld16u, { "r", "x", "X" } },
- { INDEX_op_qemu_ld16s, { "r", "x", "X" } },
- { INDEX_op_qemu_ld32, { "r", "x", "X" } },
- { INDEX_op_qemu_ld64, { "d", "r", "x", "X" } },
-
- { INDEX_op_qemu_st8, { "x", "x", "X" } },
- { INDEX_op_qemu_st16, { "x", "x", "X" } },
- { INDEX_op_qemu_st32, { "x", "x", "X" } },
- { INDEX_op_qemu_st64, { "x", "D", "x", "X" } },
+ { INDEX_op_qemu_ld8u, { "r", "l", "l" } },
+ { INDEX_op_qemu_ld8s, { "r", "l", "l" } },
+ { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
+ { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
+ { INDEX_op_qemu_ld32, { "r", "l", "l" } },
+ { INDEX_op_qemu_ld64, { "L", "L", "l", "l" } },
+
+ { INDEX_op_qemu_st8, { "s", "s", "s" } },
+ { INDEX_op_qemu_st16, { "s", "s", "s" } },
+ { INDEX_op_qemu_st32, { "s", "s", "s" } },
+ { INDEX_op_qemu_st64, { "s", "S", "s", "s" } },
#endif
{ INDEX_op_bswap16_i32, { "r", "r" } },
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 15/18] tcg/arm: remove useless register tests in qemu_ld/st
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (13 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 14/18] tcg/arm: bswap arguments in qemu_ld/st if needed Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 16/18] tcg/arm: fix argument alignment in qemu_st64 Aurelien Jarno
` (2 subsequent siblings)
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
addr_reg, data_reg and data_reg2 can't be register r0 or r1 du to the
constraints. Don't check if they equals these registers.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 30 ++++++++++--------------------
1 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 4b414ff..a4419f8 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1030,10 +1030,8 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
# if TARGET_LONG_BITS == 32
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R1, 0, mem_index);
# else
- if (addr_reg2 != TCG_REG_R1) {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
- }
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
# endif
tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_ld_helpers[s_bits] -
@@ -1239,10 +1237,8 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_b(s, COND_EQ, 8);
/* TODO: move this code to where the constants pool will be */
- if (addr_reg != TCG_REG_R0) {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
- }
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
# if TARGET_LONG_BITS == 32
switch (opc) {
case 0:
@@ -1254,17 +1250,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 2:
- if (data_reg != TCG_REG_R1) {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
- }
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 3:
- if (data_reg != TCG_REG_R1) {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
- }
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
if (data_reg2 != TCG_REG_R2) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg2, SHIFT_IMM_LSL(0));
@@ -1273,10 +1265,8 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
break;
}
# else
- if (addr_reg2 != TCG_REG_R1) {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
- }
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
switch (opc) {
case 0:
tcg_out_ext8u(s, COND_AL, TCG_REG_R2, data_reg);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 16/18] tcg/arm: fix argument alignment in qemu_st64
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (14 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 15/18] tcg/arm: remove useless register tests in qemu_ld/st Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 17/18] tcg/arm: optimize register allocation order Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 18/18] tcg/arm: don't try to load constants using pc Aurelien Jarno
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
64-bit arguments should be aligned on an even register as specified
by the "Procedure Call Standard for the ARM Architecture".
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index a4419f8..91542bd 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1255,13 +1255,16 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 3:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
- if (data_reg2 != TCG_REG_R2) {
+ tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index);
+ tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
+ if (data_reg != TCG_REG_R2) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- TCG_REG_R2, 0, data_reg2, SHIFT_IMM_LSL(0));
+ TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
+ }
+ if (data_reg2 != TCG_REG_R3) {
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+ TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
}
- tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
}
# else
@@ -1300,10 +1303,8 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_st_helpers[s_bits] -
(tcg_target_long) s->code_ptr);
-# if TARGET_LONG_BITS == 64
if (opc == 3)
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
-# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
#else /* !CONFIG_SOFTMMU */
@@ -1709,7 +1710,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_qemu_st8, { "s", "s" } },
{ INDEX_op_qemu_st16, { "s", "s" } },
{ INDEX_op_qemu_st32, { "s", "s" } },
- { INDEX_op_qemu_st64, { "s", "S", "s" } },
+ { INDEX_op_qemu_st64, { "S", "S", "s" } },
#else
{ INDEX_op_qemu_ld8u, { "r", "l", "l" } },
{ INDEX_op_qemu_ld8s, { "r", "l", "l" } },
@@ -1721,7 +1722,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_qemu_st8, { "s", "s", "s" } },
{ INDEX_op_qemu_st16, { "s", "s", "s" } },
{ INDEX_op_qemu_st32, { "s", "s", "s" } },
- { INDEX_op_qemu_st64, { "s", "S", "s", "s" } },
+ { INDEX_op_qemu_st64, { "S", "S", "s", "s" } },
#endif
{ INDEX_op_bswap16_i32, { "r", "r" } },
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 17/18] tcg/arm: optimize register allocation order
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (15 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 16/18] tcg/arm: fix argument alignment in qemu_st64 Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 18/18] tcg/arm: don't try to load constants using pc Aurelien Jarno
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
The beginning of the register allocation order list on the TCG arm
target matches the list of clobbered registers. This means that when an
helper is called, there is almost always clobbered registers that have
to be spilled.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 91542bd..03fe11c 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -65,10 +65,6 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
#endif
static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_R0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R3,
TCG_REG_R4,
TCG_REG_R5,
TCG_REG_R6,
@@ -77,8 +73,12 @@ static const int tcg_target_reg_alloc_order[] = {
TCG_REG_R9,
TCG_REG_R10,
TCG_REG_R11,
- TCG_REG_R12,
TCG_REG_R13,
+ TCG_REG_R0,
+ TCG_REG_R1,
+ TCG_REG_R2,
+ TCG_REG_R3,
+ TCG_REG_R12,
TCG_REG_R14,
};
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 18/18] tcg/arm: don't try to load constants using pc
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
` (16 preceding siblings ...)
2010-04-07 17:51 ` [Qemu-devel] [PATCH 17/18] tcg/arm: optimize register allocation order Aurelien Jarno
@ 2010-04-07 17:51 ` Aurelien Jarno
17 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-07 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
This code is never used, neither in user mode nor in system mode.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/arm/tcg-target.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 03fe11c..1d1e28a 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -372,19 +372,12 @@ static inline void tcg_out_dat_imm(TCGContext *s,
static inline void tcg_out_movi32(TCGContext *s,
int cond, int rd, int32_t arg)
{
- int offset = (uint32_t) arg - ((uint32_t) s->code_ptr + 8);
-
/* TODO: This is very suboptimal, we can easily have a constant
* pool somewhere after all the instructions. */
if (arg < 0 && arg > -0x100)
return tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0, (~arg) & 0xff);
- if (offset < 0x100 && offset > -0x100)
- return offset >= 0 ?
- tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) :
- tcg_out_dat_imm(s, cond, ARITH_SUB, rd, 15, -offset);
-
#ifdef USE_ARMV7_INSTRUCTIONS
/* use movw/movt */
/* movw */
--
1.7.0.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set
2010-04-07 17:51 ` [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set Aurelien Jarno
@ 2010-04-08 13:46 ` Paul Brook
2010-04-08 16:46 ` Richard Henderson
1 sibling, 0 replies; 23+ messages in thread
From: Paul Brook @ 2010-04-08 13:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
> Use a set of #define to define the allowed ARM instructions, depending
> on the __ARM_ARCH_*__ GCC defines.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
> tcg/arm/tcg-target.c | 27 ++++++++++++++++++++++++---
> 1 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
> index ee5f723..cae6385 100644
> --- a/tcg/arm/tcg-target.c
> +++ b/tcg/arm/tcg-target.c
> @@ -22,6 +22,27 @@
> * THE SOFTWARE.
> */
>
> +#if defined(__ARM_ARCH_5T__) || \
> + defined(__ARM_ARCH_5TE__) || \
> + defined(__ARM_ARCH_5TEJ__) || \
> + defined(__ARM_ARCH_6__) || \
> + defined(__ARM_ARCH_7A__) || \
> + defined(__ARM_ARCH_7__)
> +# define USE_ARMV5_INSTRUCTIONS 1
> +#endif
Would be better to avoid redundancy by reordering a bit and doing:
#if defined(__ARM_ARCH_5T__) || \
defined(__ARM_ARCH_5TE__) || \
defined(__ARM_ARCH_5TEJ__) || \
defined(USE_ARMV6_INSTRUCTIONS)
> +#if defined(__ARM_ARCH_6__) || \
> + defined(__ARM_ARCH_7A__) || \
> + defined(__ARM_ARCH_7__)
> +# define USE_ARMV6_INSTRUCTIONS 1
> +#endif
Likewise.
> +#if defined(__ARM_ARCH_7A__) || \
> + defined(__ARM_ARCH_7__)
> +# define USE_ARMV7_INSTRUCTIONS 1
> +#endif
Missing check for __ARM_ARCH_7R__. Should probably also check 7M and 7EM, even
though we don't currently generate Thumb code.
Paul
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set
2010-04-07 17:51 ` [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set Aurelien Jarno
2010-04-08 13:46 ` Paul Brook
@ 2010-04-08 16:46 ` Richard Henderson
1 sibling, 0 replies; 23+ messages in thread
From: Richard Henderson @ 2010-04-08 16:46 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: Andrzej Zaborowski, qemu-devel
On 04/07/2010 10:51 AM, Aurelien Jarno wrote:
> +#if defined(__ARM_ARCH_5T__) || \
> + defined(__ARM_ARCH_5TE__) || \
> + defined(__ARM_ARCH_5TEJ__) || \
> + defined(__ARM_ARCH_6__) || \
> + defined(__ARM_ARCH_7A__) || \
> + defined(__ARM_ARCH_7__)
> +# define USE_ARMV5_INSTRUCTIONS 1
> +#endif
Wouldn't it be better to add a zero definition here
so that you can use C if's and not ifdefs, so as to
make sure that all code paths are semantically correct.
It's very easy to introduce a typo in a code path that
isn't used by a particular host's build.
r~
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops
2010-04-07 17:51 ` [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops Aurelien Jarno
@ 2010-04-08 23:32 ` Paul Brook
2010-04-09 17:11 ` Aurelien Jarno
0 siblings, 1 reply; 23+ messages in thread
From: Paul Brook @ 2010-04-08 23:32 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrzej Zaborowski, Aurelien Jarno
> +static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
> +#else
> + /* This code only uses one temporary register. There is probably
> + a faster way to do that with more temporary registers. */
You can do better even without a temporary:
eor r8, rn, rn, ror #16
bic r8, r8, #0x00ff0000
mov rd, rn, ror #8
eor rd, rd, r8, lsr #8
Paul
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops
2010-04-08 23:32 ` Paul Brook
@ 2010-04-09 17:11 ` Aurelien Jarno
0 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2010-04-09 17:11 UTC (permalink / raw)
To: Paul Brook; +Cc: Andrzej Zaborowski, qemu-devel
On Fri, Apr 09, 2010 at 12:32:04AM +0100, Paul Brook wrote:
> > +static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
> > +#else
> > + /* This code only uses one temporary register. There is probably
> > + a faster way to do that with more temporary registers. */
>
> You can do better even without a temporary:
>
> eor r8, rn, rn, ror #16
> bic r8, r8, #0x00ff0000
> mov rd, rn, ror #8
> eor rd, rd, r8, lsr #8
>
That's indeed much better, though it's still use one temporary (r8).
I'll use that in the next version. Thanks.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2010-04-09 17:11 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-07 17:51 [Qemu-devel] [PATCH 0/18] tcg/arm: cleanup and improvements Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 01/18] tcg/arm: remove SAVE_LR code Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 02/18] tcg/arm: explicitely list clobbered/reserved regs Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 03/18] tcg/arm: remove store signed functions Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 04/18] tcg/arm: replace integer values by registers enum Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 05/18] tcg/arm: align 64-bit arguments in function calls Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 06/18] tcg/arm: add defines for the allowed instructions set Aurelien Jarno
2010-04-08 13:46 ` Paul Brook
2010-04-08 16:46 ` Richard Henderson
2010-04-07 17:51 ` [Qemu-devel] [PATCH 07/18] tcg/arm: sxtb and sxth are available starting with ARMv6 Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 08/18] tcg/arm: use the blx instruction when possible Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 09/18] tcg/arm: add rotation ops Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 10/18] tcg/arm: add ext16u op Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 11/18] tcg/arm: add bswap ops Aurelien Jarno
2010-04-08 23:32 ` Paul Brook
2010-04-09 17:11 ` Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 12/18] tcg/arm: remove conditional argument for qemu_ld/st Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 13/18] tcg/arm: use ext* ops in qemu_ld Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 14/18] tcg/arm: bswap arguments in qemu_ld/st if needed Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 15/18] tcg/arm: remove useless register tests in qemu_ld/st Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 16/18] tcg/arm: fix argument alignment in qemu_st64 Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 17/18] tcg/arm: optimize register allocation order Aurelien Jarno
2010-04-07 17:51 ` [Qemu-devel] [PATCH 18/18] tcg/arm: don't try to load constants using pc Aurelien Jarno
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).