target-arm: a64: Add endianness support
Set the dc->mo_endianness flag for AA64 and use it in all ldst ops. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
dacf0a2ff7
commit
aa6489da4e
@ -723,7 +723,7 @@ static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
|
|||||||
TCGv_i64 tcg_addr, int size, int memidx)
|
TCGv_i64 tcg_addr, int size, int memidx)
|
||||||
{
|
{
|
||||||
g_assert(size <= 3);
|
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->be_data + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
|
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
|
||||||
@ -738,7 +738,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,
|
static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
|
||||||
int size, bool is_signed, bool extend, int memidx)
|
int size, bool is_signed, bool extend, int memidx)
|
||||||
{
|
{
|
||||||
TCGMemOp memop = MO_TE + size;
|
TCGMemOp memop = s->be_data + size;
|
||||||
|
|
||||||
g_assert(size <= 3);
|
g_assert(size <= 3);
|
||||||
|
|
||||||
@ -770,13 +770,18 @@ static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
|
|||||||
TCGv_i64 tmp = tcg_temp_new_i64();
|
TCGv_i64 tmp = tcg_temp_new_i64();
|
||||||
tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
|
tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
|
||||||
if (size < 4) {
|
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->be_data + size);
|
||||||
} else {
|
} else {
|
||||||
|
bool be = s->be_data == MO_BE;
|
||||||
TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
|
TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
|
||||||
tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
|
|
||||||
tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
|
|
||||||
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
|
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_hiaddr : tcg_addr, get_mem_index(s),
|
||||||
|
s->be_data | MO_Q);
|
||||||
|
tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
|
||||||
|
tcg_gen_qemu_st_i64(tmp, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
|
||||||
|
s->be_data | MO_Q);
|
||||||
tcg_temp_free_i64(tcg_hiaddr);
|
tcg_temp_free_i64(tcg_hiaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,17 +798,21 @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
|
|||||||
TCGv_i64 tmphi;
|
TCGv_i64 tmphi;
|
||||||
|
|
||||||
if (size < 4) {
|
if (size < 4) {
|
||||||
TCGMemOp memop = MO_TE + size;
|
TCGMemOp memop = s->be_data + size;
|
||||||
tmphi = tcg_const_i64(0);
|
tmphi = tcg_const_i64(0);
|
||||||
tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
|
tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
|
||||||
} else {
|
} else {
|
||||||
|
bool be = s->be_data == MO_BE;
|
||||||
TCGv_i64 tcg_hiaddr;
|
TCGv_i64 tcg_hiaddr;
|
||||||
|
|
||||||
tmphi = tcg_temp_new_i64();
|
tmphi = tcg_temp_new_i64();
|
||||||
tcg_hiaddr = 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_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->be_data | MO_Q);
|
||||||
|
tcg_gen_qemu_ld_i64(tmphi, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
|
||||||
|
s->be_data | MO_Q);
|
||||||
tcg_temp_free_i64(tcg_hiaddr);
|
tcg_temp_free_i64(tcg_hiaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,7 +951,7 @@ static void clear_vec_high(DisasContext *s, int rd)
|
|||||||
static void do_vec_st(DisasContext *s, int srcidx, int element,
|
static void do_vec_st(DisasContext *s, int srcidx, int element,
|
||||||
TCGv_i64 tcg_addr, int size)
|
TCGv_i64 tcg_addr, int size)
|
||||||
{
|
{
|
||||||
TCGMemOp memop = MO_TE + size;
|
TCGMemOp memop = s->be_data + size;
|
||||||
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
|
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
|
||||||
|
|
||||||
read_vec_element(s, tcg_tmp, srcidx, element, size);
|
read_vec_element(s, tcg_tmp, srcidx, element, size);
|
||||||
@ -955,7 +964,7 @@ static void do_vec_st(DisasContext *s, int srcidx, int element,
|
|||||||
static void do_vec_ld(DisasContext *s, int destidx, int element,
|
static void do_vec_ld(DisasContext *s, int destidx, int element,
|
||||||
TCGv_i64 tcg_addr, int size)
|
TCGv_i64 tcg_addr, int size)
|
||||||
{
|
{
|
||||||
TCGMemOp memop = MO_TE + size;
|
TCGMemOp memop = s->be_data + size;
|
||||||
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
|
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
|
||||||
|
|
||||||
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
|
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
|
||||||
@ -1702,7 +1711,7 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
|
|||||||
TCGv_i64 addr, int size, bool is_pair)
|
TCGv_i64 addr, int size, bool is_pair)
|
||||||
{
|
{
|
||||||
TCGv_i64 tmp = tcg_temp_new_i64();
|
TCGv_i64 tmp = tcg_temp_new_i64();
|
||||||
TCGMemOp memop = MO_TE + size;
|
TCGMemOp memop = s->be_data + size;
|
||||||
|
|
||||||
g_assert(size <= 3);
|
g_assert(size <= 3);
|
||||||
tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
|
tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
|
||||||
@ -1764,7 +1773,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);
|
tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
|
||||||
|
|
||||||
tmp = tcg_temp_new_i64();
|
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->be_data + size);
|
||||||
tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
|
tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
|
||||||
tcg_temp_free_i64(tmp);
|
tcg_temp_free_i64(tmp);
|
||||||
|
|
||||||
@ -1773,7 +1782,8 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
|
|||||||
TCGv_i64 tmphi = tcg_temp_new_i64();
|
TCGv_i64 tmphi = tcg_temp_new_i64();
|
||||||
|
|
||||||
tcg_gen_addi_i64(addrhi, addr, 1 << size);
|
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->be_data + size);
|
||||||
tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
|
tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
|
||||||
|
|
||||||
tcg_temp_free_i64(tmphi);
|
tcg_temp_free_i64(tmphi);
|
||||||
@ -1781,13 +1791,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 */
|
/* 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->be_data + size);
|
||||||
if (is_pair) {
|
if (is_pair) {
|
||||||
TCGv_i64 addrhi = tcg_temp_new_i64();
|
TCGv_i64 addrhi = tcg_temp_new_i64();
|
||||||
|
|
||||||
tcg_gen_addi_i64(addrhi, addr, 1 << size);
|
tcg_gen_addi_i64(addrhi, addr, 1 << size);
|
||||||
tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
|
tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
|
||||||
get_mem_index(s), MO_TE + size);
|
get_mem_index(s), s->be_data + size);
|
||||||
tcg_temp_free_i64(addrhi);
|
tcg_temp_free_i64(addrhi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2602,7 +2613,7 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
|
|||||||
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
|
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
|
||||||
|
|
||||||
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
|
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
|
||||||
get_mem_index(s), MO_TE + scale);
|
get_mem_index(s), s->be_data + scale);
|
||||||
switch (scale) {
|
switch (scale) {
|
||||||
case 0:
|
case 0:
|
||||||
mulconst = 0x0101010101010101ULL;
|
mulconst = 0x0101010101010101ULL;
|
||||||
@ -2632,9 +2643,9 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
|
|||||||
} else {
|
} else {
|
||||||
/* Load/store one element per register */
|
/* Load/store one element per register */
|
||||||
if (is_load) {
|
if (is_load) {
|
||||||
do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale);
|
do_vec_ld(s, rt, index, tcg_addr, s->be_data + scale);
|
||||||
} else {
|
} else {
|
||||||
do_vec_st(s, rt, index, tcg_addr, MO_TE + scale);
|
do_vec_st(s, rt, index, tcg_addr, s->be_data + scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
|
tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user