cpu_arm_instr_loadstore.cc Source File

Back to the index.

cpu_arm_instr_loadstore.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * TODO: Many things...
29  *
30  * o) Big-endian Double-Word loads/stores are likely INCORRECT.
31  *
32  * o) "Base Updated Abort Model", which updates the base register
33  * even if the memory access failed.
34  *
35  * o) Some ARM implementations use pc+8, some use pc+12 for stores?
36  *
37  * o) All load/store variants with the PC register are not really
38  * valid. (E.g. a byte load into the PC register. What should that
39  * accomplish?)
40  *
41  * o) Perhaps an optimization for the case when offset = 0, because
42  * that's quite common, and also when the Reg expression is just
43  * a simple, non-rotated register (0..14).
44  */
45 
46 
47 #if defined(A__SIGNED) && !defined(A__H) && !defined(A__L)
48 #define A__LDRD
49 #endif
50 #if defined(A__SIGNED) && defined(A__H) && !defined(A__L)
51 #define A__STRD
52 #endif
53 
54 
55 /*
56  * General load/store, by using memory_rw(). If at all possible, memory_rw()
57  * then inserts the page into the translation array, so that the fast
58  * load/store routine below can be used for further accesses.
59  */
60 void A__NAME__general(struct cpu *cpu, struct arm_instr_call *ic)
61 {
62 #if !defined(A__P) && defined(A__W)
63  const int memory_rw_flags = CACHE_DATA | MEMORY_USER_ACCESS;
64 #else
65  const int memory_rw_flags = CACHE_DATA;
66 #endif
67 
68 #ifdef A__REG
69  uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)
70  = (uint32_t (*)(struct cpu *, struct arm_instr_call *))
71  (void *)(size_t)ic->arg[1];
72 #endif
73 
74 #if defined(A__STRD) || defined(A__LDRD)
75  unsigned char data[8];
76  const int datalen = 8;
77 #else
78 #ifdef A__B
79  unsigned char data[1];
80  const int datalen = 1;
81 #else
82 #ifdef A__H
83  unsigned char data[2];
84  const int datalen = 2;
85 #else
86  const int datalen = 4;
87 #ifdef HOST_LITTLE_ENDIAN
88  unsigned char *data = (unsigned char *) ic->arg[2];
89 #else
90  unsigned char data[4];
91 #endif
92 #endif
93 #endif
94 #endif
95 
96  uint32_t addr, low_pc, offset =
97 #ifndef A__U
98  -
99 #endif
100 #ifdef A__REG
101  reg_func(cpu, ic);
102 #else
103  ic->arg[1];
104 #endif
105 
106  low_pc = ((size_t)ic - (size_t)cpu->cd.arm.
107  cur_ic_page) / sizeof(struct arm_instr_call);
108  cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1)
110  cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
111 
112  addr = reg(ic->arg[0])
113 #ifdef A__P
114  + offset
115 #endif
116  ;
117 
118  addr &= ~(datalen - 1);
119 
120 #if defined(A__L) || defined(A__LDRD)
121  /* Load: */
122  if (!cpu->memory_rw(cpu, cpu->mem, addr, data, datalen,
123  MEM_READ, memory_rw_flags)) {
124  /* load failed, an exception was generated */
125  return;
126  }
127 #if defined(A__B) && !defined(A__LDRD)
128  reg(ic->arg[2]) =
129 #ifdef A__SIGNED
130  (int32_t)(int8_t)
131 #endif
132  data[0];
133 #else
134 #if defined(A__H) && !defined(A__LDRD)
135  reg(ic->arg[2]) =
136 #ifdef A__SIGNED
137  (int32_t)(int16_t)
138 #endif
140  ? (data[0] + (data[1] << 8))
141  : (data[1] + (data[0] << 8)));
142 #else
143 #ifndef A__LDRD
144  reg(ic->arg[2]) =
146  ? data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)
147  : data[3] + (data[2] << 8) + (data[1] << 16) + (data[0] << 24);
148 #else
149  // TODO: Double-check if this is correct
150  reg(ic->arg[2]) =
152  ? data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)
153  : data[7] + (data[1] << 6) + (data[5] << 16) + (data[4] << 24);
154  reg(((uint32_t *)ic->arg[2]) + 1) =
156  ? data[4] + (data[5] << 8) + (data[6] << 16) + (data[7] << 24)
157  : data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
158 #endif
159 #endif
160 #endif
161 #else
162  /* Store: */
163 #if !defined(A__B) && !defined(A__H) && defined(HOST_LITTLE_ENDIAN)
164 #ifdef A__STRD
165  *(uint32_t *)data = reg(ic->arg[2]);
166  *(uint32_t *)(data + 4) = reg(ic->arg[2] + 4);
167 #endif
168 #else
169  int i = cpu->byte_order == EMUL_LITTLE_ENDIAN ? 0 : datalen - 1;
170  data[i] = reg(ic->arg[2]);
171  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
172 #ifndef A__B
173  data[i] = reg(ic->arg[2]) >> 8;
174  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
175 #if !defined(A__H) || defined(A__STRD)
176  data[i] = reg(ic->arg[2]) >> 16;
177  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
178  data[i] = reg(ic->arg[2]) >> 24;
179  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
180 #ifdef A__STRD
181  // TODO: Double-check if this is correct
182  data[i] = reg(ic->arg[2] + 4);
183  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
184  data[i] = reg(ic->arg[2] + 4) >> 8;
185  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
186  data[i] = reg(ic->arg[2] + 4) >> 16;
187  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
188  data[i] = reg(ic->arg[2] + 4) >> 24;
189  i += cpu->byte_order == EMUL_LITTLE_ENDIAN ? 1 : -1;
190 #endif
191 #endif
192 #endif
193 #endif
194  if (!cpu->memory_rw(cpu, cpu->mem, addr, data, datalen,
195  MEM_WRITE, memory_rw_flags)) {
196  /* store failed, an exception was generated */
197  return;
198  }
199 #endif
200 
201 #ifdef A__P
202 #ifdef A__W
203  reg(ic->arg[0]) = addr;
204 #endif
205 #else /* post-index writeback */
206  reg(ic->arg[0]) = addr + offset;
207 #endif
208 }
209 
210 
211 /*
212  * Fast load/store, if the page is in the translation array.
213  */
214 void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)
215 {
216 #if defined(A__LDRD) || defined(A__STRD)
217  /* Chicken out, let's do this unoptimized for now: */
219 #else
220 #ifdef A__REG
221  uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)
222  = (uint32_t (*)(struct cpu *, struct arm_instr_call *))
223  (void *)(size_t)ic->arg[1];
224 #endif
225  uint32_t offset =
226 #ifndef A__U
227  -
228 #endif
229 #ifdef A__REG
230  reg_func(cpu, ic);
231 #else
232  ic->arg[1];
233 #endif
234  uint32_t addr = reg(ic->arg[0])
235 #ifdef A__P
236  + offset
237 #endif
238  ;
239  unsigned char *page = cpu->cd.arm.
240 #ifdef A__L
241  host_load
242 #else
243  host_store
244 #endif
245  [addr >> 12];
246 
247 
248 #if !defined(A__P) && defined(A__W)
249  /*
250  * T-bit: userland access: check the corresponding bit in the
251  * is_userpage array. If it is set, then we're ok. Otherwise: use the
252  * generic function.
253  */
254  uint32_t x = cpu->cd.arm.is_userpage[addr >> 17];
255  if (!(x & (1 << ((addr >> 12) & 31))))
257  else
258 #endif
259 
260 
261  if (page == NULL) {
263  } else {
264 #ifdef A__L
265 #ifdef A__B
266  reg(ic->arg[2]) =
267 #ifdef A__SIGNED
268  (int32_t)(int8_t)
269 #endif
270  page[addr & 0xfff];
271 #else
272 #ifdef A__H
273  addr &= ~1;
274  reg(ic->arg[2]) =
275 #ifdef A__SIGNED
276  (int32_t)(int16_t)
277 #endif
279  ? (page[addr & 0xfff] + (page[(addr & 0xfff) + 1] << 8))
280  : ((page[addr & 0xfff] << 8) + page[(addr & 0xfff) + 1]));
281 #else
282  addr &= ~3;
284  reg(ic->arg[2]) = page[addr & 0xfff] +
285  (page[(addr & 0xfff) + 1] << 8) +
286  (page[(addr & 0xfff) + 2] << 16) +
287  (page[(addr & 0xfff) + 3] << 24);
288  else
289  reg(ic->arg[2]) = page[(addr & 0xfff) + 3] +
290  (page[(addr & 0xfff) + 2] << 8) +
291  (page[(addr & 0xfff) + 1] << 16) +
292  (page[(addr & 0xfff) + 0] << 24);
293 #endif
294 #endif
295 #else
296 #ifdef A__B
297  page[addr & 0xfff] = reg(ic->arg[2]);
298 #else
299 #ifdef A__H
300  addr &= ~1;
302  page[addr & 0xfff] = reg(ic->arg[2]);
303  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;
304  } else {
305  page[addr & 0xfff] = reg(ic->arg[2]) >> 8;
306  page[(addr & 0xfff)+1] = reg(ic->arg[2]);
307  }
308 #else
309  addr &= ~3;
311  page[addr & 0xfff] = reg(ic->arg[2]);
312  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;
313  page[(addr & 0xfff)+2] = reg(ic->arg[2]) >> 16;
314  page[(addr & 0xfff)+3] = reg(ic->arg[2]) >> 24;
315  } else {
316  page[addr & 0xfff] = reg(ic->arg[2]) >> 24;
317  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 16;
318  page[(addr & 0xfff)+2] = reg(ic->arg[2]) >> 8;
319  page[(addr & 0xfff)+3] = reg(ic->arg[2]);
320  }
321 #endif
322 #endif
323 #endif
324 
325  /* Index Write-back: */
326 #ifdef A__P
327 #ifdef A__W
328  reg(ic->arg[0]) = addr;
329 #endif
330 #else
331  /* post-index writeback */
332  reg(ic->arg[0]) = addr + offset;
333 #endif
334  }
335 #endif /* not STRD */
336 }
337 
338 
339 /*
340  * Special case when loading or storing the ARM's PC register, or when the PC
341  * register is used as the base address register.
342  *
343  * o) Loads into the PC register cause a branch. If an exception occured
344  * during the load, then the PC register should already point to the
345  * exception handler, in which case we simply recalculate the pointers a
346  * second time (no harm is done by doing that).
347  *
348  * TODO: A tiny performance optimization would be to separate the two
349  * cases: a load where arg[0] = PC, and the case where arg[2] = PC.
350  *
351  * o) Stores store "PC of the current instruction + 12". The solution I have
352  * choosen is to calculate this value and place it into a temporary
353  * variable (tmp_pc), which is then used for the store.
354  */
355 void A__NAME_PC(struct cpu *cpu, struct arm_instr_call *ic)
356 {
357 #ifdef A__L
358  /* Load: */
359  if (ic->arg[0] == (size_t)(&cpu->cd.arm.tmp_pc)) {
360  /* tmp_pc = current PC + 8: */
361  uint32_t low_pc, tmp;
362  low_pc = ((size_t)ic - (size_t) cpu->cd.arm.cur_ic_page) /
363  sizeof(struct arm_instr_call);
364  tmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<
366  tmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
367  cpu->cd.arm.tmp_pc = tmp + 8;
368  }
369  A__NAME(cpu, ic);
370  if (ic->arg[2] == (size_t)(&cpu->cd.arm.r[ARM_PC])) {
371  cpu->pc = cpu->cd.arm.r[ARM_PC];
375  }
376 #else
377  /* Store: */
378  uint32_t low_pc, tmp;
379  /* Calculate tmp from this instruction's PC + 12 */
380  low_pc = ((size_t)ic - (size_t) cpu->cd.arm.cur_ic_page) /
381  sizeof(struct arm_instr_call);
382  tmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<
384  tmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
385  cpu->cd.arm.tmp_pc = tmp + 12;
386  A__NAME(cpu, ic);
387 #endif
388 }
389 
390 
391 #ifndef A__NOCONDITIONS
392 /* Load/stores with all registers except the PC register: */
393 void A__NAME__eq(struct cpu *cpu, struct arm_instr_call *ic)
394 { if (cpu->cd.arm.flags & ARM_F_Z) A__NAME(cpu, ic); }
395 void A__NAME__ne(struct cpu *cpu, struct arm_instr_call *ic)
396 { if (!(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
397 void A__NAME__cs(struct cpu *cpu, struct arm_instr_call *ic)
398 { if (cpu->cd.arm.flags & ARM_F_C) A__NAME(cpu, ic); }
399 void A__NAME__cc(struct cpu *cpu, struct arm_instr_call *ic)
400 { if (!(cpu->cd.arm.flags & ARM_F_C)) A__NAME(cpu, ic); }
401 void A__NAME__mi(struct cpu *cpu, struct arm_instr_call *ic)
402 { if (cpu->cd.arm.flags & ARM_F_N) A__NAME(cpu, ic); }
403 void A__NAME__pl(struct cpu *cpu, struct arm_instr_call *ic)
404 { if (!(cpu->cd.arm.flags & ARM_F_N)) A__NAME(cpu, ic); }
405 void A__NAME__vs(struct cpu *cpu, struct arm_instr_call *ic)
406 { if (cpu->cd.arm.flags & ARM_F_V) A__NAME(cpu, ic); }
407 void A__NAME__vc(struct cpu *cpu, struct arm_instr_call *ic)
408 { if (!(cpu->cd.arm.flags & ARM_F_V)) A__NAME(cpu, ic); }
409 
410 void A__NAME__hi(struct cpu *cpu, struct arm_instr_call *ic)
411 { if (cpu->cd.arm.flags & ARM_F_C &&
412 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
413 void A__NAME__ls(struct cpu *cpu, struct arm_instr_call *ic)
414 { if (cpu->cd.arm.flags & ARM_F_Z ||
415 !(cpu->cd.arm.flags & ARM_F_C)) A__NAME(cpu, ic); }
416 void A__NAME__ge(struct cpu *cpu, struct arm_instr_call *ic)
417 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
418 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME(cpu, ic); }
419 void A__NAME__lt(struct cpu *cpu, struct arm_instr_call *ic)
420 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
421 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME(cpu, ic); }
422 void A__NAME__gt(struct cpu *cpu, struct arm_instr_call *ic)
423 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
424 ((cpu->cd.arm.flags & ARM_F_V)?1:0) &&
425 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
426 void A__NAME__le(struct cpu *cpu, struct arm_instr_call *ic)
427 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
428 ((cpu->cd.arm.flags & ARM_F_V)?1:0) ||
429 (cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
430 
431 
432 /* Load/stores with the PC register: */
433 void A__NAME_PC__eq(struct cpu *cpu, struct arm_instr_call *ic)
434 { if (cpu->cd.arm.flags & ARM_F_Z) A__NAME_PC(cpu, ic); }
435 void A__NAME_PC__ne(struct cpu *cpu, struct arm_instr_call *ic)
436 { if (!(cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
437 void A__NAME_PC__cs(struct cpu *cpu, struct arm_instr_call *ic)
438 { if (cpu->cd.arm.flags & ARM_F_C) A__NAME_PC(cpu, ic); }
439 void A__NAME_PC__cc(struct cpu *cpu, struct arm_instr_call *ic)
440 { if (!(cpu->cd.arm.flags & ARM_F_C)) A__NAME_PC(cpu, ic); }
441 void A__NAME_PC__mi(struct cpu *cpu, struct arm_instr_call *ic)
442 { if (cpu->cd.arm.flags & ARM_F_N) A__NAME_PC(cpu, ic); }
443 void A__NAME_PC__pl(struct cpu *cpu, struct arm_instr_call *ic)
444 { if (!(cpu->cd.arm.flags & ARM_F_N)) A__NAME_PC(cpu, ic); }
445 void A__NAME_PC__vs(struct cpu *cpu, struct arm_instr_call *ic)
446 { if (cpu->cd.arm.flags & ARM_F_V) A__NAME_PC(cpu, ic); }
447 void A__NAME_PC__vc(struct cpu *cpu, struct arm_instr_call *ic)
448 { if (!(cpu->cd.arm.flags & ARM_F_V)) A__NAME_PC(cpu, ic); }
449 
450 void A__NAME_PC__hi(struct cpu *cpu, struct arm_instr_call *ic)
451 { if (cpu->cd.arm.flags & ARM_F_C &&
452 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
453 void A__NAME_PC__ls(struct cpu *cpu, struct arm_instr_call *ic)
454 { if (cpu->cd.arm.flags & ARM_F_Z ||
455 !(cpu->cd.arm.flags & ARM_F_C)) A__NAME_PC(cpu, ic); }
456 void A__NAME_PC__ge(struct cpu *cpu, struct arm_instr_call *ic)
457 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
458 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME_PC(cpu, ic); }
459 void A__NAME_PC__lt(struct cpu *cpu, struct arm_instr_call *ic)
460 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
461 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME_PC(cpu, ic); }
462 void A__NAME_PC__gt(struct cpu *cpu, struct arm_instr_call *ic)
463 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
464 ((cpu->cd.arm.flags & ARM_F_V)?1:0) &&
465 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
466 void A__NAME_PC__le(struct cpu *cpu, struct arm_instr_call *ic)
467 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
468 ((cpu->cd.arm.flags & ARM_F_V)?1:0) ||
469 (cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
470 #endif
471 
472 
473 #ifdef A__LDRD
474 #undef A__LDRD
475 #endif
476 
477 #ifdef A__STRD
478 #undef A__STRD
479 #endif
480 
data
u_short data
Definition: siireg.h:79
A__NAME__hi
void A__NAME__hi(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:410
arm_cpu::tmp_pc
uint32_t tmp_pc
Definition: cpu_arm.h:164
A__NAME__cs
void A__NAME__cs(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:397
machine::show_trace_tree
int show_trace_tree
Definition: machine.h:164
ARM_IC_ENTRIES_PER_PAGE
#define ARM_IC_ENTRIES_PER_PAGE
Definition: cpu_arm.h:80
A__NAME_PC__gt
void A__NAME_PC__gt(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:462
MEM_READ
#define MEM_READ
Definition: memory.h:116
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
cpu_functioncall_trace
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:219
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
ARM_INSTR_ALIGNMENT_SHIFT
#define ARM_INSTR_ALIGNMENT_SHIFT
Definition: cpu_arm.h:79
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
A__NAME_PC__pl
void A__NAME_PC__pl(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:443
arm_cpu::flags
size_t flags
Definition: cpu_arm.h:174
A__NAME__gt
void A__NAME__gt(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:422
A__NAME__le
void A__NAME__le(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:426
A__NAME_PC__cc
void A__NAME_PC__cc(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:439
MEMORY_USER_ACCESS
#define MEMORY_USER_ACCESS
Definition: memory.h:127
A__NAME
void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:214
A__NAME_PC__ge
void A__NAME_PC__ge(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:456
cpu::cd
union cpu::@1 cd
page
page
Definition: tmp_arm_multi.cc:54
A__NAME__mi
void A__NAME__mi(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:401
ic
struct arm_instr_call * ic
Definition: tmp_arm_multi.cc:50
A__NAME_PC__cs
void A__NAME_PC__cs(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:437
CACHE_DATA
#define CACHE_DATA
Definition: memory.h:121
arm_cpu::r
uint32_t r[N_ARM_REGS]
Definition: cpu_arm.h:155
A__NAME__ls
void A__NAME__ls(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:413
A__U
#define A__U
Definition: tmp_arm_loadstore_p0_u1_w0.cc:1365
A__NAME__ge
void A__NAME__ge(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:416
A__L
#define A__L
Definition: tmp_arm_loadstore_p0_u0_w0.cc:1325
ARM_PC
#define ARM_PC
Definition: cpu_arm.h:56
cpu::mem
struct memory * mem
Definition: cpu.h:362
ARM_F_N
#define ARM_F_N
Definition: cpu_arm.h:86
A__NAME__ne
void A__NAME__ne(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:395
A__NAME_PC__lt
void A__NAME_PC__lt(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:459
EMUL_LITTLE_ENDIAN
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
A__NAME__vc
void A__NAME__vc(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:407
cpu::machine
struct machine * machine
Definition: cpu.h:328
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
A__NAME__vs
void A__NAME__vs(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:405
A__NAME_PC__vc
void A__NAME_PC__vc(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:447
ARM_F_Z
#define ARM_F_Z
Definition: cpu_arm.h:87
cpu::arm
struct arm_cpu arm
Definition: cpu.h:441
A__NAME__eq
void A__NAME__eq(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:393
A__NAME__cc
void A__NAME__cc(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:399
A__NAME__pl
void A__NAME__pl(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:403
A__NAME_PC__vs
void A__NAME_PC__vs(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:445
A__NAME_PC__mi
void A__NAME_PC__mi(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:441
A__REG
#define A__REG
Definition: tmp_arm_dpi.cc:4039
A__NAME__general
void A__NAME__general(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:60
quick_pc_to_pointers
#define quick_pc_to_pointers(cpu)
Definition: quick_pc_to_pointers.h:29
A__NAME_PC__hi
void A__NAME_PC__hi(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:450
A__NAME_PC__ls
void A__NAME_PC__ls(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:453
cpu
Definition: cpu.h:326
A__NAME_PC__le
void A__NAME_PC__le(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:466
ARM_F_V
#define ARM_F_V
Definition: cpu_arm.h:89
A__NAME_PC__eq
void A__NAME_PC__eq(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:433
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:365
A__NAME__lt
void A__NAME__lt(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:419
arm_cpu::is_userpage
uint32_t is_userpage[N_VPH32_ENTRIES/32]
Definition: cpu_arm.h:247
cpu::pc
uint64_t pc
Definition: cpu.h:383
ARM_F_C
#define ARM_F_C
Definition: cpu_arm.h:88
A__NAME_PC__ne
void A__NAME_PC__ne(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:435
A__NAME_PC
void A__NAME_PC(struct cpu *cpu, struct arm_instr_call *ic)
Definition: cpu_arm_instr_loadstore.cc:355

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17