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: | ... | ... |