]>
Commit | Line | Data |
---|---|---|
9220fe54 PM |
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 | */ | |
dcdaadb6 LV |
25 | |
26 | #if !defined(CODE_ACCESS) | |
0ab8ed18 | 27 | #include "trace-root.h" |
dcdaadb6 LV |
28 | #endif |
29 | ||
30 | #include "trace/mem.h" | |
31 | ||
9220fe54 PM |
32 | #if DATA_SIZE == 8 |
33 | #define SUFFIX q | |
34 | #define USUFFIX q | |
35 | #define DATA_TYPE uint64_t | |
32c07234 | 36 | #define SHIFT 3 |
9220fe54 PM |
37 | #elif DATA_SIZE == 4 |
38 | #define SUFFIX l | |
39 | #define USUFFIX l | |
40 | #define DATA_TYPE uint32_t | |
32c07234 | 41 | #define SHIFT 2 |
9220fe54 PM |
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 | |
32c07234 | 47 | #define SHIFT 1 |
9220fe54 PM |
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 | |
32c07234 | 53 | #define SHIFT 0 |
9220fe54 PM |
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 | |
3e23de15 | 65 | glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr) |
9220fe54 | 66 | { |
52ba13f0 | 67 | RES_TYPE ret; |
e6d86bed | 68 | #ifdef CODE_ACCESS |
52ba13f0 RH |
69 | set_helper_retaddr(1); |
70 | ret = glue(glue(ld, USUFFIX), _p)(g2h(ptr)); | |
71 | clear_helper_retaddr(); | |
52ba13f0 | 72 | #else |
f3bee8d3 RH |
73 | MemOp op = MO_TE | SHIFT; |
74 | uint16_t meminfo = trace_mem_get_info(op, MMU_USER_IDX, false); | |
e6d86bed EC |
75 | trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); |
76 | ret = glue(glue(ld, USUFFIX), _p)(g2h(ptr)); | |
52ba13f0 | 77 | #endif |
e6d86bed | 78 | return ret; |
9220fe54 PM |
79 | } |
80 | ||
6ad8307b | 81 | #ifndef CODE_ACCESS |
282dffc8 PD |
82 | static inline RES_TYPE |
83 | glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | |
3e23de15 | 84 | abi_ptr ptr, |
282dffc8 PD |
85 | uintptr_t retaddr) |
86 | { | |
ec603b55 | 87 | RES_TYPE ret; |
08b97f7f | 88 | set_helper_retaddr(retaddr); |
ec603b55 | 89 | ret = glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(env, ptr); |
08b97f7f | 90 | clear_helper_retaddr(); |
ec603b55 | 91 | return ret; |
282dffc8 | 92 | } |
6ad8307b | 93 | #endif |
282dffc8 | 94 | |
9220fe54 PM |
95 | #if DATA_SIZE <= 2 |
96 | static inline int | |
3e23de15 | 97 | glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr) |
9220fe54 | 98 | { |
52ba13f0 | 99 | int ret; |
e6d86bed | 100 | #ifdef CODE_ACCESS |
52ba13f0 RH |
101 | set_helper_retaddr(1); |
102 | ret = glue(glue(lds, SUFFIX), _p)(g2h(ptr)); | |
103 | clear_helper_retaddr(); | |
52ba13f0 | 104 | #else |
f3bee8d3 RH |
105 | MemOp op = MO_TE | MO_SIGN | SHIFT; |
106 | uint16_t meminfo = trace_mem_get_info(op, MMU_USER_IDX, false); | |
e6d86bed EC |
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); | |
52ba13f0 | 110 | #endif |
e6d86bed | 111 | return ret; |
9220fe54 | 112 | } |
282dffc8 | 113 | |
6ad8307b | 114 | #ifndef CODE_ACCESS |
282dffc8 PD |
115 | static inline int |
116 | glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | |
3e23de15 | 117 | abi_ptr ptr, |
282dffc8 PD |
118 | uintptr_t retaddr) |
119 | { | |
ec603b55 | 120 | int ret; |
08b97f7f | 121 | set_helper_retaddr(retaddr); |
ec603b55 | 122 | ret = glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(env, ptr); |
08b97f7f | 123 | clear_helper_retaddr(); |
ec603b55 | 124 | return ret; |
282dffc8 | 125 | } |
6ad8307b RH |
126 | #endif /* CODE_ACCESS */ |
127 | #endif /* DATA_SIZE <= 2 */ | |
9220fe54 PM |
128 | |
129 | #ifndef CODE_ACCESS | |
130 | static inline void | |
3e23de15 | 131 | glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr, |
9220fe54 PM |
132 | RES_TYPE v) |
133 | { | |
f3bee8d3 RH |
134 | MemOp op = MO_TE | SHIFT; |
135 | uint16_t meminfo = trace_mem_get_info(op, MMU_USER_IDX, true); | |
e6d86bed | 136 | trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); |
9220fe54 | 137 | glue(glue(st, SUFFIX), _p)(g2h(ptr), v); |
e6d86bed | 138 | qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); |
9220fe54 | 139 | } |
282dffc8 PD |
140 | |
141 | static inline void | |
142 | glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | |
3e23de15 | 143 | abi_ptr ptr, |
282dffc8 PD |
144 | RES_TYPE v, |
145 | uintptr_t retaddr) | |
146 | { | |
08b97f7f | 147 | set_helper_retaddr(retaddr); |
282dffc8 | 148 | glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(env, ptr, v); |
08b97f7f | 149 | clear_helper_retaddr(); |
282dffc8 | 150 | } |
9220fe54 PM |
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 | |
32c07234 | 159 | #undef SHIFT |