1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#ifndef TARGET_ARM_SVE_LDST_INTERNAL_H
21#define TARGET_ARM_SVE_LDST_INTERNAL_H
22
23#include "exec/cpu_ldst.h"
24
25
26
27
28
29typedef void sve_ldst1_host_fn(void *vd, intptr_t reg_off, void *host);
30
31
32
33
34
35typedef void sve_ldst1_tlb_fn(CPUARMState *env, void *vd, intptr_t reg_off,
36 target_ulong vaddr, uintptr_t retaddr);
37
38
39
40
41
42#define DO_LD_HOST(NAME, H, TYPEE, TYPEM, HOST) \
43static inline void sve_##NAME##_host(void *vd, intptr_t reg_off, void *host) \
44{ TYPEM val = HOST(host); *(TYPEE *)(vd + H(reg_off)) = val; }
45
46#define DO_ST_HOST(NAME, H, TYPEE, TYPEM, HOST) \
47static inline void sve_##NAME##_host(void *vd, intptr_t reg_off, void *host) \
48{ TYPEM val = *(TYPEE *)(vd + H(reg_off)); HOST(host, val); }
49
50#define DO_LD_TLB(NAME, H, TYPEE, TYPEM, TLB) \
51static inline void sve_##NAME##_tlb(CPUARMState *env, void *vd, \
52 intptr_t reg_off, target_ulong addr, uintptr_t ra) \
53{ \
54 TYPEM val = TLB(env, useronly_clean_ptr(addr), ra); \
55 *(TYPEE *)(vd + H(reg_off)) = val; \
56}
57
58#define DO_ST_TLB(NAME, H, TYPEE, TYPEM, TLB) \
59static inline void sve_##NAME##_tlb(CPUARMState *env, void *vd, \
60 intptr_t reg_off, target_ulong addr, uintptr_t ra) \
61{ \
62 TYPEM val = *(TYPEE *)(vd + H(reg_off)); \
63 TLB(env, useronly_clean_ptr(addr), val, ra); \
64}
65
66#define DO_LD_PRIM_1(NAME, H, TE, TM) \
67 DO_LD_HOST(NAME, H, TE, TM, ldub_p) \
68 DO_LD_TLB(NAME, H, TE, TM, cpu_ldub_data_ra)
69
70DO_LD_PRIM_1(ld1bb, H1, uint8_t, uint8_t)
71DO_LD_PRIM_1(ld1bhu, H1_2, uint16_t, uint8_t)
72DO_LD_PRIM_1(ld1bhs, H1_2, uint16_t, int8_t)
73DO_LD_PRIM_1(ld1bsu, H1_4, uint32_t, uint8_t)
74DO_LD_PRIM_1(ld1bss, H1_4, uint32_t, int8_t)
75DO_LD_PRIM_1(ld1bdu, H1_8, uint64_t, uint8_t)
76DO_LD_PRIM_1(ld1bds, H1_8, uint64_t, int8_t)
77
78#define DO_ST_PRIM_1(NAME, H, TE, TM) \
79 DO_ST_HOST(st1##NAME, H, TE, TM, stb_p) \
80 DO_ST_TLB(st1##NAME, H, TE, TM, cpu_stb_data_ra)
81
82DO_ST_PRIM_1(bb, H1, uint8_t, uint8_t)
83DO_ST_PRIM_1(bh, H1_2, uint16_t, uint8_t)
84DO_ST_PRIM_1(bs, H1_4, uint32_t, uint8_t)
85DO_ST_PRIM_1(bd, H1_8, uint64_t, uint8_t)
86
87#define DO_LD_PRIM_2(NAME, H, TE, TM, LD) \
88 DO_LD_HOST(ld1##NAME##_be, H, TE, TM, LD##_be_p) \
89 DO_LD_HOST(ld1##NAME##_le, H, TE, TM, LD##_le_p) \
90 DO_LD_TLB(ld1##NAME##_be, H, TE, TM, cpu_##LD##_be_data_ra) \
91 DO_LD_TLB(ld1##NAME##_le, H, TE, TM, cpu_##LD##_le_data_ra)
92
93#define DO_ST_PRIM_2(NAME, H, TE, TM, ST) \
94 DO_ST_HOST(st1##NAME##_be, H, TE, TM, ST##_be_p) \
95 DO_ST_HOST(st1##NAME##_le, H, TE, TM, ST##_le_p) \
96 DO_ST_TLB(st1##NAME##_be, H, TE, TM, cpu_##ST##_be_data_ra) \
97 DO_ST_TLB(st1##NAME##_le, H, TE, TM, cpu_##ST##_le_data_ra)
98
99DO_LD_PRIM_2(hh, H1_2, uint16_t, uint16_t, lduw)
100DO_LD_PRIM_2(hsu, H1_4, uint32_t, uint16_t, lduw)
101DO_LD_PRIM_2(hss, H1_4, uint32_t, int16_t, lduw)
102DO_LD_PRIM_2(hdu, H1_8, uint64_t, uint16_t, lduw)
103DO_LD_PRIM_2(hds, H1_8, uint64_t, int16_t, lduw)
104
105DO_ST_PRIM_2(hh, H1_2, uint16_t, uint16_t, stw)
106DO_ST_PRIM_2(hs, H1_4, uint32_t, uint16_t, stw)
107DO_ST_PRIM_2(hd, H1_8, uint64_t, uint16_t, stw)
108
109DO_LD_PRIM_2(ss, H1_4, uint32_t, uint32_t, ldl)
110DO_LD_PRIM_2(sdu, H1_8, uint64_t, uint32_t, ldl)
111DO_LD_PRIM_2(sds, H1_8, uint64_t, int32_t, ldl)
112
113DO_ST_PRIM_2(ss, H1_4, uint32_t, uint32_t, stl)
114DO_ST_PRIM_2(sd, H1_8, uint64_t, uint32_t, stl)
115
116DO_LD_PRIM_2(dd, H1_8, uint64_t, uint64_t, ldq)
117DO_ST_PRIM_2(dd, H1_8, uint64_t, uint64_t, stq)
118
119#undef DO_LD_TLB
120#undef DO_ST_TLB
121#undef DO_LD_HOST
122#undef DO_LD_PRIM_1
123#undef DO_ST_PRIM_1
124#undef DO_LD_PRIM_2
125#undef DO_ST_PRIM_2
126
127
128
129
130
131
132
133typedef struct {
134 void *host;
135 int flags;
136 MemTxAttrs attrs;
137} SVEHostPage;
138
139bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
140 target_ulong addr, int mem_off, MMUAccessType access_type,
141 int mmu_idx, uintptr_t retaddr);
142
143
144
145
146
147typedef enum {
148 FAULT_NO,
149 FAULT_FIRST,
150 FAULT_ALL,
151} SVEContFault;
152
153typedef struct {
154
155
156
157
158
159
160
161
162
163
164
165
166 int16_t mem_off_first[2];
167 int16_t reg_off_first[2];
168 int16_t reg_off_last[2];
169
170
171
172
173
174 int16_t mem_off_split;
175 int16_t reg_off_split;
176
177
178
179
180
181 int16_t page_split;
182
183
184 SVEHostPage page[2];
185} SVEContLdSt;
186
187
188
189
190
191
192bool sve_cont_ldst_elements(SVEContLdSt *info, target_ulong addr, uint64_t *vg,
193 intptr_t reg_max, int esz, int msize);
194
195
196
197
198
199
200bool sve_cont_ldst_pages(SVEContLdSt *info, SVEContFault fault,
201 CPUARMState *env, target_ulong addr,
202 MMUAccessType access_type, uintptr_t retaddr);
203
204#ifdef CONFIG_USER_ONLY
205static inline void
206sve_cont_ldst_watchpoints(SVEContLdSt *info, CPUARMState *env, uint64_t *vg,
207 target_ulong addr, int esize, int msize,
208 int wp_access, uintptr_t retaddr)
209{ }
210#else
211void sve_cont_ldst_watchpoints(SVEContLdSt *info, CPUARMState *env,
212 uint64_t *vg, target_ulong addr,
213 int esize, int msize, int wp_access,
214 uintptr_t retaddr);
215#endif
216
217void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env, uint64_t *vg,
218 target_ulong addr, int esize, int msize,
219 uint32_t mtedesc, uintptr_t ra);
220
221#endif
222