]> git.proxmox.com Git - mirror_qemu.git/blob - include/exec/cpu_ldst_useronly_template.h
e5a3d1983a635876626e380c42b849e57371cc4a
[mirror_qemu.git] / include / exec / cpu_ldst_useronly_template.h
1 /*
2 * User-only accessor function support
3 *
4 * Generate inline load/store functions for one data size.
5 *
6 * Generate a store function as well as signed and unsigned loads.
7 *
8 * Not used directly but included from cpu_ldst.h.
9 *
10 * Copyright (c) 2015 Linaro Limited
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #if !defined(CODE_ACCESS)
27 #include "trace-root.h"
28 #endif
29
30 #include "trace/mem.h"
31
32 #if DATA_SIZE == 8
33 #define SUFFIX q
34 #define USUFFIX q
35 #define DATA_TYPE uint64_t
36 #define SHIFT 3
37 #elif DATA_SIZE == 4
38 #define SUFFIX l
39 #define USUFFIX l
40 #define DATA_TYPE uint32_t
41 #define SHIFT 2
42 #elif DATA_SIZE == 2
43 #define SUFFIX w
44 #define USUFFIX uw
45 #define DATA_TYPE uint16_t
46 #define DATA_STYPE int16_t
47 #define SHIFT 1
48 #elif DATA_SIZE == 1
49 #define SUFFIX b
50 #define USUFFIX ub
51 #define DATA_TYPE uint8_t
52 #define DATA_STYPE int8_t
53 #define SHIFT 0
54 #else
55 #error unsupported data size
56 #endif
57
58 #if DATA_SIZE == 8
59 #define RES_TYPE uint64_t
60 #else
61 #define RES_TYPE uint32_t
62 #endif
63
64 static inline RES_TYPE
65 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr)
66 {
67 RES_TYPE ret;
68 #ifdef CODE_ACCESS
69 set_helper_retaddr(1);
70 ret = glue(glue(ld, USUFFIX), _p)(g2h(ptr));
71 clear_helper_retaddr();
72 #else
73 MemOp op = MO_TE | SHIFT;
74 uint16_t meminfo = trace_mem_get_info(op, MMU_USER_IDX, false);
75 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
76 ret = glue(glue(ld, USUFFIX), _p)(g2h(ptr));
77 #endif
78 return ret;
79 }
80
81 #ifndef CODE_ACCESS
82 static inline RES_TYPE
83 glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
84 abi_ptr ptr,
85 uintptr_t retaddr)
86 {
87 RES_TYPE ret;
88 set_helper_retaddr(retaddr);
89 ret = glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(env, ptr);
90 clear_helper_retaddr();
91 return ret;
92 }
93 #endif
94
95 #if DATA_SIZE <= 2
96 static inline int
97 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr)
98 {
99 int ret;
100 #ifdef CODE_ACCESS
101 set_helper_retaddr(1);
102 ret = glue(glue(lds, SUFFIX), _p)(g2h(ptr));
103 clear_helper_retaddr();
104 #else
105 MemOp op = MO_TE | MO_SIGN | SHIFT;
106 uint16_t meminfo = trace_mem_get_info(op, MMU_USER_IDX, false);
107 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
108 ret = glue(glue(lds, SUFFIX), _p)(g2h(ptr));
109 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
110 #endif
111 return ret;
112 }
113
114 #ifndef CODE_ACCESS
115 static inline int
116 glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
117 abi_ptr ptr,
118 uintptr_t retaddr)
119 {
120 int ret;
121 set_helper_retaddr(retaddr);
122 ret = glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(env, ptr);
123 clear_helper_retaddr();
124 return ret;
125 }
126 #endif /* CODE_ACCESS */
127 #endif /* DATA_SIZE <= 2 */
128
129 #ifndef CODE_ACCESS
130 static inline void
131 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr,
132 RES_TYPE v)
133 {
134 MemOp op = MO_TE | SHIFT;
135 uint16_t meminfo = trace_mem_get_info(op, MMU_USER_IDX, true);
136 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
137 glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
138 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
139 }
140
141 static inline void
142 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
143 abi_ptr ptr,
144 RES_TYPE v,
145 uintptr_t retaddr)
146 {
147 set_helper_retaddr(retaddr);
148 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(env, ptr, v);
149 clear_helper_retaddr();
150 }
151 #endif
152
153 #undef RES_TYPE
154 #undef DATA_TYPE
155 #undef DATA_STYPE
156 #undef SUFFIX
157 #undef USUFFIX
158 #undef DATA_SIZE
159 #undef SHIFT