]> git.ipfire.org Git - thirdparty/qemu.git/blame - include/exec/cpu_ldst_template.h
.travis.yml: don't run make check with multiple jobs
[thirdparty/qemu.git] / include / exec / cpu_ldst_template.h
CommitLineData
b92e5a22
FB
1/*
2 * Software MMU support
5fafdf24 3 *
efbf29b6
BS
4 * Generate inline load/store functions for one MMU mode and data
5 * size.
6 *
82f11917 7 * Generate a store function as well as signed and unsigned loads.
efbf29b6 8 *
c773828a 9 * Not used directly but included from cpu_ldst.h.
efbf29b6 10 *
b92e5a22
FB
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
8167ee88 24 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
b92e5a22 25 */
dcdaadb6
LV
26
27#if !defined(SOFTMMU_CODE_ACCESS)
0ab8ed18 28#include "trace-root.h"
dcdaadb6
LV
29#endif
30
e6d86bed 31#include "qemu/plugin.h"
dcdaadb6
LV
32#include "trace/mem.h"
33
b92e5a22
FB
34#if DATA_SIZE == 8
35#define SUFFIX q
61382a50 36#define USUFFIX q
b92e5a22 37#define DATA_TYPE uint64_t
282dffc8 38#define SHIFT 3
b92e5a22
FB
39#elif DATA_SIZE == 4
40#define SUFFIX l
61382a50 41#define USUFFIX l
b92e5a22 42#define DATA_TYPE uint32_t
282dffc8 43#define SHIFT 2
b92e5a22
FB
44#elif DATA_SIZE == 2
45#define SUFFIX w
61382a50 46#define USUFFIX uw
b92e5a22
FB
47#define DATA_TYPE uint16_t
48#define DATA_STYPE int16_t
282dffc8 49#define SHIFT 1
b92e5a22
FB
50#elif DATA_SIZE == 1
51#define SUFFIX b
61382a50 52#define USUFFIX ub
b92e5a22
FB
53#define DATA_TYPE uint8_t
54#define DATA_STYPE int8_t
282dffc8 55#define SHIFT 0
b92e5a22
FB
56#else
57#error unsupported data size
58#endif
59
b92e5a22
FB
60#if DATA_SIZE == 8
61#define RES_TYPE uint64_t
62#else
c086b783 63#define RES_TYPE uint32_t
b92e5a22
FB
64#endif
65
859d7612 66#ifdef SOFTMMU_CODE_ACCESS
84b7b8e7 67#define ADDR_READ addr_code
a6c9eac0 68#define MMUSUFFIX _cmmu
7dec71d5
AB
69#define URETSUFFIX USUFFIX
70#define SRETSUFFIX glue(s, SUFFIX)
84b7b8e7
FB
71#else
72#define ADDR_READ addr_read
a6c9eac0 73#define MMUSUFFIX _mmu
282dffc8
PD
74#define URETSUFFIX USUFFIX
75#define SRETSUFFIX glue(s, SUFFIX)
84b7b8e7 76#endif
b92e5a22 77
e16c53fa
FB
78/* generic load/store macros */
79
e141ab52 80static inline RES_TYPE
282dffc8
PD
81glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
82 target_ulong ptr,
83 uintptr_t retaddr)
b92e5a22 84{
383beda9 85 CPUTLBEntry *entry;
b92e5a22 86 RES_TYPE res;
c27004ec 87 target_ulong addr;
504f73f7 88 int mmu_idx = CPU_MMU_INDEX;
282dffc8 89 TCGMemOpIdx oi;
dcdaadb6 90#if !defined(SOFTMMU_CODE_ACCESS)
e6d86bed
EC
91 uint16_t meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false, mmu_idx);
92 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
dcdaadb6
LV
93#endif
94
c27004ec 95 addr = ptr;
383beda9
RH
96 entry = tlb_entry(env, mmu_idx, addr);
97 if (unlikely(entry->ADDR_READ !=
551bd27f 98 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
282dffc8
PD
99 oi = make_memop_idx(SHIFT, mmu_idx);
100 res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
101 oi, retaddr);
b92e5a22 102 } else {
383beda9 103 uintptr_t hostaddr = addr + entry->addend;
35539232 104 res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
b92e5a22 105 }
e6d86bed
EC
106#ifndef SOFTMMU_CODE_ACCESS
107 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
108#endif
b92e5a22
FB
109 return res;
110}
111
282dffc8
PD
112static inline RES_TYPE
113glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
114{
115 return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
116}
117
b92e5a22 118#if DATA_SIZE <= 2
e141ab52 119static inline int
282dffc8
PD
120glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
121 target_ulong ptr,
122 uintptr_t retaddr)
b92e5a22 123{
383beda9
RH
124 CPUTLBEntry *entry;
125 int res;
c27004ec 126 target_ulong addr;
504f73f7 127 int mmu_idx = CPU_MMU_INDEX;
282dffc8 128 TCGMemOpIdx oi;
dcdaadb6 129#if !defined(SOFTMMU_CODE_ACCESS)
e6d86bed
EC
130 uint16_t meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false, mmu_idx);
131 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
dcdaadb6
LV
132#endif
133
c27004ec 134 addr = ptr;
383beda9
RH
135 entry = tlb_entry(env, mmu_idx, addr);
136 if (unlikely(entry->ADDR_READ !=
551bd27f 137 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
282dffc8
PD
138 oi = make_memop_idx(SHIFT, mmu_idx);
139 res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
140 MMUSUFFIX)(env, addr, oi, retaddr);
b92e5a22 141 } else {
383beda9 142 uintptr_t hostaddr = addr + entry->addend;
35539232 143 res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
b92e5a22 144 }
e6d86bed
EC
145#ifndef SOFTMMU_CODE_ACCESS
146 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
147#endif
b92e5a22
FB
148 return res;
149}
282dffc8
PD
150
151static inline int
152glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
153{
154 return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
155}
b92e5a22
FB
156#endif
157
859d7612 158#ifndef SOFTMMU_CODE_ACCESS
84b7b8e7 159
e16c53fa
FB
160/* generic store macro */
161
e141ab52 162static inline void
282dffc8
PD
163glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
164 target_ulong ptr,
165 RES_TYPE v, uintptr_t retaddr)
b92e5a22 166{
383beda9 167 CPUTLBEntry *entry;
c27004ec 168 target_ulong addr;
504f73f7 169 int mmu_idx = CPU_MMU_INDEX;
282dffc8 170 TCGMemOpIdx oi;
dcdaadb6 171#if !defined(SOFTMMU_CODE_ACCESS)
e6d86bed
EC
172 uint16_t meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true, mmu_idx);
173 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
dcdaadb6
LV
174#endif
175
c27004ec 176 addr = ptr;
383beda9 177 entry = tlb_entry(env, mmu_idx, addr);
403f290c 178 if (unlikely(tlb_addr_write(entry) !=
551bd27f 179 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
282dffc8
PD
180 oi = make_memop_idx(SHIFT, mmu_idx);
181 glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
182 retaddr);
b92e5a22 183 } else {
383beda9 184 uintptr_t hostaddr = addr + entry->addend;
35539232 185 glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
b92e5a22 186 }
e6d86bed
EC
187#ifndef SOFTMMU_CODE_ACCESS
188 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
189#endif
b92e5a22
FB
190}
191
282dffc8
PD
192static inline void
193glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
194 RES_TYPE v)
195{
196 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
197}
198
859d7612 199#endif /* !SOFTMMU_CODE_ACCESS */
84b7b8e7 200
b92e5a22
FB
201#undef RES_TYPE
202#undef DATA_TYPE
203#undef DATA_STYPE
204#undef SUFFIX
61382a50 205#undef USUFFIX
b92e5a22 206#undef DATA_SIZE
61382a50 207#undef MMUSUFFIX
84b7b8e7 208#undef ADDR_READ
282dffc8
PD
209#undef URETSUFFIX
210#undef SRETSUFFIX
211#undef SHIFT