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 | 849 | 0, 8, CPU_TLB_SIZE - 1); |
850 | 850 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, |
851 | 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 | 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 | 859 | tcg_out_dat_reg(s, COND_AL, ARITH_CMP, |
855 | 860 | 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); |
856 | 861 | /* TODO: alignment check? |
... | ... | @@ -862,12 +867,12 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, |
862 | 867 | /* XXX: possibly we could use a block data load or writeback in |
863 | 868 | * the first access. */ |
864 | 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 | 871 | tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, |
867 | 872 | 0, 1, addr_reg2, SHIFT_IMM_LSL(0)); |
868 | 873 | # endif |
869 | 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 | 877 | switch (opc) { |
873 | 878 | case 0: |
... | ... | @@ -1015,8 +1020,12 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, |
1015 | 1020 | 0, 8, CPU_TLB_SIZE - 1); |
1016 | 1021 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, |
1017 | 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 | 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 | 1029 | tcg_out_dat_reg(s, COND_AL, ARITH_CMP, |
1021 | 1030 | 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); |
1022 | 1031 | /* TODO: alignment check? |
... | ... | @@ -1028,13 +1037,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, |
1028 | 1037 | /* XXX: possibly we could use a block data load or writeback in |
1029 | 1038 | * the first access. */ |
1030 | 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 | 1041 | + 4); |
1033 | 1042 | tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, |
1034 | 1043 | 0, 1, addr_reg2, SHIFT_IMM_LSL(0)); |
1035 | 1044 | # endif |
1036 | 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 | 1048 | switch (opc) { |
1040 | 1049 | case 0: | ... | ... |