Commit 225b437649f6c883a10c295b9b93285e8dfef571
1 parent
bedba0cd
Fix qemu_ld/st for mem_index > 0 on arm host.
offsetof(CPUState, tlb_table[mem_index][0].addr_read) with mem_index > 0 was larger than max immediate offset for ldr and str (12-bit) so insert an additional insn to add the mem_index offset. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4542 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
15 additions
and
6 deletions
tcg/arm/tcg-target.c
@@ -849,8 +849,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, | @@ -849,8 +849,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, | ||
849 | 0, 8, CPU_TLB_SIZE - 1); | 849 | 0, 8, CPU_TLB_SIZE - 1); |
850 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, | 850 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, |
851 | 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); | 851 | 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); |
852 | +# define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS) | ||
853 | + if (mem_index) | ||
854 | + tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0, | ||
855 | + (mem_index << (TLB_SHIFT & 1)) | | ||
856 | + ((16 - (TLB_SHIFT >> 1)) << 8)); | ||
852 | tcg_out_ld32_12(s, COND_AL, 1, 0, | 857 | tcg_out_ld32_12(s, COND_AL, 1, 0, |
853 | - offsetof(CPUState, tlb_table[mem_index][0].addr_read)); | 858 | + offsetof(CPUState, tlb_table[0][0].addr_read)); |
854 | tcg_out_dat_reg(s, COND_AL, ARITH_CMP, | 859 | tcg_out_dat_reg(s, COND_AL, ARITH_CMP, |
855 | 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); | 860 | 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); |
856 | /* TODO: alignment check? | 861 | /* TODO: alignment check? |
@@ -862,12 +867,12 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, | @@ -862,12 +867,12 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, | ||
862 | /* XXX: possibly we could use a block data load or writeback in | 867 | /* XXX: possibly we could use a block data load or writeback in |
863 | * the first access. */ | 868 | * the first access. */ |
864 | tcg_out_ld32_12(s, COND_EQ, 1, 0, | 869 | tcg_out_ld32_12(s, COND_EQ, 1, 0, |
865 | - offsetof(CPUState, tlb_table[mem_index][0].addr_read) + 4); | 870 | + offsetof(CPUState, tlb_table[0][0].addr_read) + 4); |
866 | tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, | 871 | tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, |
867 | 0, 1, addr_reg2, SHIFT_IMM_LSL(0)); | 872 | 0, 1, addr_reg2, SHIFT_IMM_LSL(0)); |
868 | # endif | 873 | # endif |
869 | tcg_out_ld32_12(s, COND_EQ, 1, 0, | 874 | tcg_out_ld32_12(s, COND_EQ, 1, 0, |
870 | - offsetof(CPUState, tlb_table[mem_index][0].addend)); | 875 | + offsetof(CPUState, tlb_table[0][0].addend)); |
871 | 876 | ||
872 | switch (opc) { | 877 | switch (opc) { |
873 | case 0: | 878 | case 0: |
@@ -1015,8 +1020,12 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, | @@ -1015,8 +1020,12 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, | ||
1015 | 0, 8, CPU_TLB_SIZE - 1); | 1020 | 0, 8, CPU_TLB_SIZE - 1); |
1016 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, | 1021 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, |
1017 | 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); | 1022 | 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); |
1023 | + if (mem_index) | ||
1024 | + tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0, | ||
1025 | + (mem_index << (TLB_SHIFT & 1)) | | ||
1026 | + ((16 - (TLB_SHIFT >> 1)) << 8)); | ||
1018 | tcg_out_ld32_12(s, COND_AL, 1, 0, | 1027 | tcg_out_ld32_12(s, COND_AL, 1, 0, |
1019 | - offsetof(CPUState, tlb_table[mem_index][0].addr_write)); | 1028 | + offsetof(CPUState, tlb_table[0][0].addr_write)); |
1020 | tcg_out_dat_reg(s, COND_AL, ARITH_CMP, | 1029 | tcg_out_dat_reg(s, COND_AL, ARITH_CMP, |
1021 | 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); | 1030 | 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); |
1022 | /* TODO: alignment check? | 1031 | /* TODO: alignment check? |
@@ -1028,13 +1037,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, | @@ -1028,13 +1037,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, | ||
1028 | /* XXX: possibly we could use a block data load or writeback in | 1037 | /* XXX: possibly we could use a block data load or writeback in |
1029 | * the first access. */ | 1038 | * the first access. */ |
1030 | tcg_out_ld32_12(s, COND_EQ, 1, 0, | 1039 | tcg_out_ld32_12(s, COND_EQ, 1, 0, |
1031 | - offsetof(CPUState, tlb_table[mem_index][0].addr_write) | 1040 | + offsetof(CPUState, tlb_table[0][0].addr_write) |
1032 | + 4); | 1041 | + 4); |
1033 | tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, | 1042 | tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, |
1034 | 0, 1, addr_reg2, SHIFT_IMM_LSL(0)); | 1043 | 0, 1, addr_reg2, SHIFT_IMM_LSL(0)); |
1035 | # endif | 1044 | # endif |
1036 | tcg_out_ld32_12(s, COND_EQ, 1, 0, | 1045 | tcg_out_ld32_12(s, COND_EQ, 1, 0, |
1037 | - offsetof(CPUState, tlb_table[mem_index][0].addend)); | 1046 | + offsetof(CPUState, tlb_table[0][0].addend)); |
1038 | 1047 | ||
1039 | switch (opc) { | 1048 | switch (opc) { |
1040 | case 0: | 1049 | case 0: |