]> git.proxmox.com Git - mirror_qemu.git/blob - include/exec/cpu_ldst_template.h
migration: use migration_in_postcopy() to check POSTCOPY_ACTIVE
[mirror_qemu.git] / include / exec / cpu_ldst_template.h
1 /*
2 * Software MMU support
3 *
4 * Generate inline load/store functions for one MMU mode and data
5 * size.
6 *
7 * Generate a store function as well as signed and unsigned loads.
8 *
9 * Not used directly but included from cpu_ldst.h.
10 *
11 * Copyright (c) 2003 Fabrice Bellard
12 *
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.
17 *
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.
22 *
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/>.
25 */
26
27 #if !defined(SOFTMMU_CODE_ACCESS)
28 #include "trace-root.h"
29 #endif
30
31 #include "trace/mem.h"
32
33 #if DATA_SIZE == 8
34 #define SUFFIX q
35 #define USUFFIX q
36 #define DATA_TYPE uint64_t
37 #define SHIFT 3
38 #elif DATA_SIZE == 4
39 #define SUFFIX l
40 #define USUFFIX l
41 #define DATA_TYPE uint32_t
42 #define SHIFT 2
43 #elif DATA_SIZE == 2
44 #define SUFFIX w
45 #define USUFFIX uw
46 #define DATA_TYPE uint16_t
47 #define DATA_STYPE int16_t
48 #define SHIFT 1
49 #elif DATA_SIZE == 1
50 #define SUFFIX b
51 #define USUFFIX ub
52 #define DATA_TYPE uint8_t
53 #define DATA_STYPE int8_t
54 #define SHIFT 0
55 #else
56 #error unsupported data size
57 #endif
58
59 #if DATA_SIZE == 8
60 #define RES_TYPE uint64_t
61 #else
62 #define RES_TYPE uint32_t
63 #endif
64
65 #ifdef SOFTMMU_CODE_ACCESS
66 #define ADDR_READ addr_code
67 #define MMUSUFFIX _cmmu
68 #define URETSUFFIX SUFFIX
69 #define SRETSUFFIX SUFFIX
70 #else
71 #define ADDR_READ addr_read
72 #define MMUSUFFIX _mmu
73 #define URETSUFFIX USUFFIX
74 #define SRETSUFFIX glue(s, SUFFIX)
75 #endif
76
77 /* generic load/store macros */
78
79 static inline RES_TYPE
80 glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
81 target_ulong ptr,
82 uintptr_t retaddr)
83 {
84 CPUTLBEntry *entry;
85 RES_TYPE res;
86 target_ulong addr;
87 int mmu_idx;
88 TCGMemOpIdx oi;
89
90 #if !defined(SOFTMMU_CODE_ACCESS)
91 trace_guest_mem_before_exec(
92 env_cpu(env), ptr,
93 trace_mem_build_info(SHIFT, false, MO_TE, false));
94 #endif
95
96 addr = ptr;
97 mmu_idx = CPU_MMU_INDEX;
98 entry = tlb_entry(env, mmu_idx, addr);
99 if (unlikely(entry->ADDR_READ !=
100 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
101 oi = make_memop_idx(SHIFT, mmu_idx);
102 res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
103 oi, retaddr);
104 } else {
105 uintptr_t hostaddr = addr + entry->addend;
106 res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
107 }
108 return res;
109 }
110
111 static inline RES_TYPE
112 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
113 {
114 return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
115 }
116
117 #if DATA_SIZE <= 2
118 static inline int
119 glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
120 target_ulong ptr,
121 uintptr_t retaddr)
122 {
123 CPUTLBEntry *entry;
124 int res;
125 target_ulong addr;
126 int mmu_idx;
127 TCGMemOpIdx oi;
128
129 #if !defined(SOFTMMU_CODE_ACCESS)
130 trace_guest_mem_before_exec(
131 env_cpu(env), ptr,
132 trace_mem_build_info(SHIFT, true, MO_TE, false));
133 #endif
134
135 addr = ptr;
136 mmu_idx = CPU_MMU_INDEX;
137 entry = tlb_entry(env, mmu_idx, addr);
138 if (unlikely(entry->ADDR_READ !=
139 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
140 oi = make_memop_idx(SHIFT, mmu_idx);
141 res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
142 MMUSUFFIX)(env, addr, oi, retaddr);
143 } else {
144 uintptr_t hostaddr = addr + entry->addend;
145 res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
146 }
147 return res;
148 }
149
150 static inline int
151 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
152 {
153 return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
154 }
155 #endif
156
157 #ifndef SOFTMMU_CODE_ACCESS
158
159 /* generic store macro */
160
161 static inline void
162 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
163 target_ulong ptr,
164 RES_TYPE v, uintptr_t retaddr)
165 {
166 CPUTLBEntry *entry;
167 target_ulong addr;
168 int mmu_idx;
169 TCGMemOpIdx oi;
170
171 #if !defined(SOFTMMU_CODE_ACCESS)
172 trace_guest_mem_before_exec(
173 env_cpu(env), ptr,
174 trace_mem_build_info(SHIFT, false, MO_TE, true));
175 #endif
176
177 addr = ptr;
178 mmu_idx = CPU_MMU_INDEX;
179 entry = tlb_entry(env, mmu_idx, addr);
180 if (unlikely(tlb_addr_write(entry) !=
181 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
182 oi = make_memop_idx(SHIFT, mmu_idx);
183 glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
184 retaddr);
185 } else {
186 uintptr_t hostaddr = addr + entry->addend;
187 glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
188 }
189 }
190
191 static inline void
192 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
193 RES_TYPE v)
194 {
195 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
196 }
197
198 #endif /* !SOFTMMU_CODE_ACCESS */
199
200 #undef RES_TYPE
201 #undef DATA_TYPE
202 #undef DATA_STYPE
203 #undef SUFFIX
204 #undef USUFFIX
205 #undef DATA_SIZE
206 #undef MMUSUFFIX
207 #undef ADDR_READ
208 #undef URETSUFFIX
209 #undef SRETSUFFIX
210 #undef SHIFT