exec.c: Convert subpage memory ops to _with_attrs
[qemu.git] / include / exec / cpu_ldst_template.h
blob95ab7504e28f7afae48fa974694ee99fc2afb377
1 /*
2 * Software MMU support
4 * Generate inline load/store functions for one MMU mode and data
5 * size.
7 * Generate a store function as well as signed and unsigned loads.
9 * Not used directly but included from cpu_ldst.h.
11 * Copyright (c) 2003 Fabrice Bellard
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #if DATA_SIZE == 8
27 #define SUFFIX q
28 #define USUFFIX q
29 #define DATA_TYPE uint64_t
30 #elif DATA_SIZE == 4
31 #define SUFFIX l
32 #define USUFFIX l
33 #define DATA_TYPE uint32_t
34 #elif DATA_SIZE == 2
35 #define SUFFIX w
36 #define USUFFIX uw
37 #define DATA_TYPE uint16_t
38 #define DATA_STYPE int16_t
39 #elif DATA_SIZE == 1
40 #define SUFFIX b
41 #define USUFFIX ub
42 #define DATA_TYPE uint8_t
43 #define DATA_STYPE int8_t
44 #else
45 #error unsupported data size
46 #endif
48 #if DATA_SIZE == 8
49 #define RES_TYPE uint64_t
50 #else
51 #define RES_TYPE uint32_t
52 #endif
54 #ifdef SOFTMMU_CODE_ACCESS
55 #define ADDR_READ addr_code
56 #define MMUSUFFIX _cmmu
57 #else
58 #define ADDR_READ addr_read
59 #define MMUSUFFIX _mmu
60 #endif
62 /* generic load/store macros */
64 static inline RES_TYPE
65 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
67 int page_index;
68 RES_TYPE res;
69 target_ulong addr;
70 int mmu_idx;
72 addr = ptr;
73 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
74 mmu_idx = CPU_MMU_INDEX;
75 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
76 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
77 res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
78 } else {
79 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
80 res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
82 return res;
85 #if DATA_SIZE <= 2
86 static inline int
87 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
89 int res, page_index;
90 target_ulong addr;
91 int mmu_idx;
93 addr = ptr;
94 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
95 mmu_idx = CPU_MMU_INDEX;
96 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
97 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
98 res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
99 MMUSUFFIX)(env, addr, mmu_idx);
100 } else {
101 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
102 res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
104 return res;
106 #endif
108 #ifndef SOFTMMU_CODE_ACCESS
110 /* generic store macro */
112 static inline void
113 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
114 RES_TYPE v)
116 int page_index;
117 target_ulong addr;
118 int mmu_idx;
120 addr = ptr;
121 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
122 mmu_idx = CPU_MMU_INDEX;
123 if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
124 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
125 glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
126 } else {
127 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
128 glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
132 #endif /* !SOFTMMU_CODE_ACCESS */
134 #undef RES_TYPE
135 #undef DATA_TYPE
136 #undef DATA_STYPE
137 #undef SUFFIX
138 #undef USUFFIX
139 #undef DATA_SIZE
140 #undef MMUSUFFIX
141 #undef ADDR_READ