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 | #ifdef CODE_ACCESS |
68 | RES_TYPE ret; |
69 | set_helper_retaddr(1); |
70 | ret = glue(glue(ld, USUFFIX), _p)(g2h(ptr)); |
71 | clear_helper_retaddr(); |
72 | return ret; |
73 | #else |
74 | trace_guest_mem_before_exec( |
75 | env_cpu(env), ptr, |
76 | trace_mem_build_info(SHIFT, false, MO_TE, false)); |
77 | return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); |
78 | #endif |
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 | #ifdef CODE_ACCESS |
100 | int ret; |
101 | set_helper_retaddr(1); |
102 | ret = glue(glue(lds, SUFFIX), _p)(g2h(ptr)); |
103 | clear_helper_retaddr(); |
104 | return ret; |
105 | #else |
106 | trace_guest_mem_before_exec( |
107 | env_cpu(env), ptr, |
108 | trace_mem_build_info(SHIFT, true, MO_TE, false)); |
109 | return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); |
110 | #endif |
111 | } |
112 | |
113 | #ifndef CODE_ACCESS |
114 | static inline int |
115 | glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, |
116 | abi_ptr ptr, |
117 | uintptr_t retaddr) |
118 | { |
119 | int ret; |
120 | set_helper_retaddr(retaddr); |
121 | ret = glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(env, ptr); |
122 | clear_helper_retaddr(); |
123 | return ret; |
124 | } |
125 | #endif /* CODE_ACCESS */ |
126 | #endif /* DATA_SIZE <= 2 */ |
127 | |
128 | #ifndef CODE_ACCESS |
129 | static inline void |
130 | glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr, |
131 | RES_TYPE v) |
132 | { |
133 | trace_guest_mem_before_exec( |
134 | env_cpu(env), ptr, |
135 | trace_mem_build_info(SHIFT, false, MO_TE, true)); |
136 | glue(glue(st, SUFFIX), _p)(g2h(ptr), v); |
137 | } |
138 | |
139 | static inline void |
140 | glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, |
141 | abi_ptr ptr, |
142 | RES_TYPE v, |
143 | uintptr_t retaddr) |
144 | { |
145 | set_helper_retaddr(retaddr); |
146 | glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(env, ptr, v); |
147 | clear_helper_retaddr(); |
148 | } |
149 | #endif |
150 | |
151 | #undef RES_TYPE |
152 | #undef DATA_TYPE |
153 | #undef DATA_STYPE |
154 | #undef SUFFIX |
155 | #undef USUFFIX |
156 | #undef DATA_SIZE |
157 | #undef SHIFT |
158 | |