[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v1 07/17] target-arm: a64: Add endianness support
From: |
Peter Crosthwaite |
Subject: |
[Qemu-devel] [PATCH v1 07/17] target-arm: a64: Add endianness support |
Date: |
Sun, 17 Jan 2016 23:12:34 -0800 |
From: Peter Crosthwaite <address@hidden>
Set the dc->mo_endianness flag for AA64 and use it in all ldst ops.
Signed-off-by: Peter Crosthwaite <address@hidden>
---
target-arm/translate-a64.c | 49 ++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index d826b92..59026b6 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -726,7 +726,7 @@ static void do_gpr_st_memidx(DisasContext *s, TCGv_i64
source,
TCGv_i64 tcg_addr, int size, int memidx)
{
g_assert(size <= 3);
- tcg_gen_qemu_st_i64(source, tcg_addr, memidx, MO_TE + size);
+ tcg_gen_qemu_st_i64(source, tcg_addr, memidx, s->mo_endianness + size);
}
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
@@ -741,7 +741,7 @@ static void do_gpr_st(DisasContext *s, TCGv_i64 source,
static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
int size, bool is_signed, bool extend, int memidx)
{
- TCGMemOp memop = MO_TE + size;
+ TCGMemOp memop = s->mo_endianness + size;
g_assert(size <= 3);
@@ -773,13 +773,18 @@ static void do_fp_st(DisasContext *s, int srcidx,
TCGv_i64 tcg_addr, int size)
TCGv_i64 tmp = tcg_temp_new_i64();
tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
if (size < 4) {
- tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size);
+ tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s),
+ s->mo_endianness + size);
} else {
+ bool be = s->mo_endianness == MO_BE;
TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
- tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
+
+ tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
+ tcg_gen_qemu_st_i64(tmp, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
+ s->mo_endianness | MO_Q);
tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
- tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
- tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
+ tcg_gen_qemu_st_i64(tmp, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
+ s->mo_endianness | MO_Q);
tcg_temp_free_i64(tcg_hiaddr);
}
@@ -796,17 +801,21 @@ static void do_fp_ld(DisasContext *s, int destidx,
TCGv_i64 tcg_addr, int size)
TCGv_i64 tmphi;
if (size < 4) {
- TCGMemOp memop = MO_TE + size;
+ TCGMemOp memop = s->mo_endianness + size;
tmphi = tcg_const_i64(0);
tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
} else {
+ bool be = s->mo_endianness == MO_BE;
TCGv_i64 tcg_hiaddr;
+
tmphi = tcg_temp_new_i64();
tcg_hiaddr = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ);
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
- tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ);
+ tcg_gen_qemu_ld_i64(tmplo, be ? tcg_hiaddr : tcg_addr,
get_mem_index(s),
+ s->mo_endianness | MO_Q);
+ tcg_gen_qemu_ld_i64(tmphi, be ? tcg_addr : tcg_hiaddr,
get_mem_index(s),
+ s->mo_endianness | MO_Q);
tcg_temp_free_i64(tcg_hiaddr);
}
@@ -945,7 +954,7 @@ static void clear_vec_high(DisasContext *s, int rd)
static void do_vec_st(DisasContext *s, int srcidx, int element,
TCGv_i64 tcg_addr, int size)
{
- TCGMemOp memop = MO_TE + size;
+ TCGMemOp memop = s->mo_endianness + size;
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
read_vec_element(s, tcg_tmp, srcidx, element, size);
@@ -958,7 +967,7 @@ static void do_vec_st(DisasContext *s, int srcidx, int
element,
static void do_vec_ld(DisasContext *s, int destidx, int element,
TCGv_i64 tcg_addr, int size)
{
- TCGMemOp memop = MO_TE + size;
+ TCGMemOp memop = s->mo_endianness + size;
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
@@ -1703,7 +1712,7 @@ static void gen_load_exclusive(DisasContext *s, int rt,
int rt2,
TCGv_i64 addr, int size, bool is_pair)
{
TCGv_i64 tmp = tcg_temp_new_i64();
- TCGMemOp memop = MO_TE + size;
+ TCGMemOp memop = s->mo_endianness + size;
g_assert(size <= 3);
tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
@@ -1765,7 +1774,7 @@ static void gen_store_exclusive(DisasContext *s, int rd,
int rt, int rt2,
tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
tmp = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), MO_TE + size);
+ tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), s->mo_endianness + size);
tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
tcg_temp_free_i64(tmp);
@@ -1774,7 +1783,8 @@ static void gen_store_exclusive(DisasContext *s, int rd,
int rt, int rt2,
TCGv_i64 tmphi = tcg_temp_new_i64();
tcg_gen_addi_i64(addrhi, addr, 1 << size);
- tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s), MO_TE + size);
+ tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s),
+ s->mo_endianness + size);
tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
tcg_temp_free_i64(tmphi);
@@ -1782,13 +1792,14 @@ static void gen_store_exclusive(DisasContext *s, int
rd, int rt, int rt2,
}
/* We seem to still have the exclusive monitor, so do the store */
- tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s), MO_TE + size);
+ tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s),
+ s->mo_endianness + size);
if (is_pair) {
TCGv_i64 addrhi = tcg_temp_new_i64();
tcg_gen_addi_i64(addrhi, addr, 1 << size);
tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
- get_mem_index(s), MO_TE + size);
+ get_mem_index(s), s->mo_endianness + size);
tcg_temp_free_i64(addrhi);
}
@@ -2603,7 +2614,7 @@ static void disas_ldst_single_struct(DisasContext *s,
uint32_t insn)
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
- get_mem_index(s), MO_TE + scale);
+ get_mem_index(s), s->mo_endianness + scale);
switch (scale) {
case 0:
mulconst = 0x0101010101010101ULL;
@@ -2633,9 +2644,9 @@ static void disas_ldst_single_struct(DisasContext *s,
uint32_t insn)
} else {
/* Load/store one element per register */
if (is_load) {
- do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale);
+ do_vec_ld(s, rt, index, tcg_addr, s->mo_endianness + scale);
} else {
- do_vec_st(s, rt, index, tcg_addr, MO_TE + scale);
+ do_vec_st(s, rt, index, tcg_addr, s->mo_endianness + scale);
}
}
tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
--
1.9.1
- Re: [Qemu-devel] [PATCH v1 04/17] target-arm: implement SCTLR.EE, (continued)
- [Qemu-devel] [PATCH v1 03/17] linux-user: arm: handle CPSR.E correctly in strex emulation, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 06/17] target-arm: introduce disas flag for endianness, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 05/17] target-arm: pass DisasContext to gen_aa32_ld*/st*, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 09/17] target-arm: introduce tbflag for endianness, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 11/17] linux-user: arm: pass env to get_user_code_*, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 07/17] target-arm: a64: Add endianness support,
Peter Crosthwaite <=
- [Qemu-devel] [PATCH v1 08/17] target-arm: cpu: Move cpu_is_big_endian to header, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 10/17] target-arm: implement setend, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 13/17] arm: linux-user: don't set CPSR.E in BE32 mode, Peter Crosthwaite, 2016/01/18
- [Qemu-devel] [PATCH v1 14/17] target-arm: implement BE32 mode in system emulation, Peter Crosthwaite, 2016/01/18