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-2009 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 ARM loads/stores.
31  *
32  * o) Alignment checks!
33  *
34  * o) Native load/store if the endianness is the same as the host's
35  * (only implemented for little endian, so far, and it assumes that
36  * alignment is correct!)
37  *
38  * o) "Base Updated Abort Model", which updates the base register
39  * even if the memory access failed.
40  *
41  * o) Some ARM implementations use pc+8, some use pc+12 for stores?
42  *
43  * o) All load/store variants with the PC register are not really
44  * valid. (E.g. a byte load into the PC register. What should that
45  * accomplish?)
46  *
47  * o) Perhaps an optimization for the case when offset = 0, because
48  * that's quite common, and also when the Reg expression is just
49  * a simple, non-rotated register (0..14).
50  */
51 
52 
53 #if defined(A__SIGNED) && !defined(A__H) && !defined(A__L)
54 #define A__LDRD
55 #endif
56 #if defined(A__SIGNED) && defined(A__H) && !defined(A__L)
57 #define A__STRD
58 #endif
59 
60 
61 /*
62  * General load/store, by using memory_rw(). If at all possible, memory_rw()
63  * then inserts the page into the translation array, so that the fast
64  * load/store routine below can be used for further accesses.
65  */
66 void A__NAME__general(struct cpu *cpu, struct arm_instr_call *ic)
67 {
68 #if !defined(A__P) && defined(A__W)
69  const int memory_rw_flags = CACHE_DATA | MEMORY_USER_ACCESS;
70 #else
71  const int memory_rw_flags = CACHE_DATA;
72 #endif
73 
74 #ifdef A__REG
75  uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)
76  = (uint32_t (*)(struct cpu *, struct arm_instr_call *))
77  (void *)(size_t)ic->arg[1];
78 #endif
79 
80 #if defined(A__STRD) || defined(A__LDRD)
81  unsigned char data[8];
82  const int datalen = 8;
83 #else
84 #ifdef A__B
85  unsigned char data[1];
86  const int datalen = 1;
87 #else
88 #ifdef A__H
89  unsigned char data[2];
90  const int datalen = 2;
91 #else
92  const int datalen = 4;
93 #ifdef HOST_LITTLE_ENDIAN
94  unsigned char *data = (unsigned char *) ic->arg[2];
95 #else
96  unsigned char data[4];
97 #endif
98 #endif
99 #endif
100 #endif
101 
102  uint32_t addr, low_pc, offset =
103 #ifndef A__U
104  -
105 #endif
106 #ifdef A__REG
107  reg_func(cpu, ic);
108 #else
109  ic->arg[1];
110 #endif
111 
112  low_pc = ((size_t)ic - (size_t)cpu->cd.arm.
113  cur_ic_page) / sizeof(struct arm_instr_call);
114  cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1)
116  cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
117 
118  addr = reg(ic->arg[0])
119 #ifdef A__P
120  + offset
121 #endif
122  ;
123 
124 
125 #if defined(A__L) || defined(A__LDRD)
126  /* Load: */
127  if (!cpu->memory_rw(cpu, cpu->mem, addr, data, datalen,
128  MEM_READ, memory_rw_flags)) {
129  /* load failed, an exception was generated */
130  return;
131  }
132 #if defined(A__B) && !defined(A__LDRD)
133  reg(ic->arg[2]) =
134 #ifdef A__SIGNED
135  (int32_t)(int8_t)
136 #endif
137  data[0];
138 #else
139 #if defined(A__H) && !defined(A__LDRD)
140  reg(ic->arg[2]) =
141 #ifdef A__SIGNED
142  (int32_t)(int16_t)
143 #endif
144  (data[0] + (data[1] << 8));
145 #else
146 #ifndef A__LDRD
147 #ifdef HOST_LITTLE_ENDIAN
148  /* Nothing. */
149 #else
150  reg(ic->arg[2]) = data[0] + (data[1] << 8) +
151  (data[2] << 16) + (data[3] << 24);
152 #endif
153 #else
154  reg(ic->arg[2]) = data[0] + (data[1] << 8) +
155  (data[2] << 16) + (data[3] << 24);
156  reg(((uint32_t *)ic->arg[2]) + 1) = data[4] + (data[5] << 8) +
157  (data[6] << 16) + (data[7] << 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  data[0] = reg(ic->arg[2]);
170 #ifndef A__B
171  data[1] = reg(ic->arg[2]) >> 8;
172 #if !defined(A__H) || defined(A__STRD)
173  data[1] = reg(ic->arg[2]) >> 8;
174  data[2] = reg(ic->arg[2]) >> 16;
175  data[3] = reg(ic->arg[2]) >> 24;
176 #ifdef A__STRD
177  data[4] = reg(ic->arg[2] + 4);
178  data[5] = reg(ic->arg[2] + 4) >> 8;
179  data[6] = reg(ic->arg[2] + 4) >> 16;
180  data[7] = reg(ic->arg[2] + 4) >> 24;
181 #endif
182 #endif
183 #endif
184 #endif
185  if (!cpu->memory_rw(cpu, cpu->mem, addr, data, datalen,
186  MEM_WRITE, memory_rw_flags)) {
187  /* store failed, an exception was generated */
188  return;
189  }
190 #endif
191 
192 #ifdef A__P
193 #ifdef A__W
194  reg(ic->arg[0]) = addr;
195 #endif
196 #else /* post-index writeback */
197  reg(ic->arg[0]) = addr + offset;
198 #endif
199 }
200 
201 
202 /*
203  * Fast load/store, if the page is in the translation array.
204  */
205 void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)
206 {
207 #if defined(A__LDRD) || defined(A__STRD)
208  /* Chicken out, let's do this unoptimized for now: */
209  A__NAME__general(cpu, ic);
210 #else
211 #ifdef A__REG
212  uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)
213  = (uint32_t (*)(struct cpu *, struct arm_instr_call *))
214  (void *)(size_t)ic->arg[1];
215 #endif
216  uint32_t offset =
217 #ifndef A__U
218  -
219 #endif
220 #ifdef A__REG
221  reg_func(cpu, ic);
222 #else
223  ic->arg[1];
224 #endif
225  uint32_t addr = reg(ic->arg[0])
226 #ifdef A__P
227  + offset
228 #endif
229  ;
230  unsigned char *page = cpu->cd.arm.
231 #ifdef A__L
232  host_load
233 #else
234  host_store
235 #endif
236  [addr >> 12];
237 
238 
239 #if !defined(A__P) && defined(A__W)
240  /*
241  * T-bit: userland access: check the corresponding bit in the
242  * is_userpage array. If it is set, then we're ok. Otherwise: use the
243  * generic function.
244  */
245  uint32_t x = cpu->cd.arm.is_userpage[addr >> 17];
246  if (!(x & (1 << ((addr >> 12) & 31))))
247  A__NAME__general(cpu, ic);
248  else
249 #endif
250 
251 
252  if (page == NULL) {
253  A__NAME__general(cpu, ic);
254  } else {
255 #ifdef A__L
256 #ifdef A__B
257  reg(ic->arg[2]) =
258 #ifdef A__SIGNED
259  (int32_t)(int8_t)
260 #endif
261  page[addr & 0xfff];
262 #else
263 #ifdef A__H
264  reg(ic->arg[2]) =
265 #ifdef A__SIGNED
266  (int32_t)(int16_t)
267 #endif
268  (page[addr & 0xfff] + (page[(addr & 0xfff) + 1] << 8));
269 #else
270 #ifdef HOST_LITTLE_ENDIAN
271  reg(ic->arg[2]) = *(uint32_t *)(page + (addr & 0xffc));
272 #else
273  reg(ic->arg[2]) = page[addr & 0xfff] +
274  (page[(addr & 0xfff) + 1] << 8) +
275  (page[(addr & 0xfff) + 2] << 16) +
276  (page[(addr & 0xfff) + 3] << 24);
277 #endif
278 #endif
279 #endif
280 #else
281 #ifdef A__B
282  page[addr & 0xfff] = reg(ic->arg[2]);
283 #else
284 #ifdef A__H
285  page[addr & 0xfff] = reg(ic->arg[2]);
286  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;
287 #else
288 #ifdef HOST_LITTLE_ENDIAN
289  *(uint32_t *)(page + (addr & 0xffc)) = reg(ic->arg[2]);
290 #else
291  page[addr & 0xfff] = reg(ic->arg[2]);
292  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;
293  page[(addr & 0xfff)+2] = reg(ic->arg[2]) >> 16;
294  page[(addr & 0xfff)+3] = reg(ic->arg[2]) >> 24;
295 #endif
296 #endif
297 #endif
298 #endif
299 
300  /* Index Write-back: */
301 #ifdef A__P
302 #ifdef A__W
303  reg(ic->arg[0]) = addr;
304 #endif
305 #else
306  /* post-index writeback */
307  reg(ic->arg[0]) = addr + offset;
308 #endif
309  }
310 #endif /* not STRD */
311 }
312 
313 
314 /*
315  * Special case when loading or storing the ARM's PC register, or when the PC
316  * register is used as the base address register.
317  *
318  * o) Loads into the PC register cause a branch. If an exception occured
319  * during the load, then the PC register should already point to the
320  * exception handler, in which case we simply recalculate the pointers a
321  * second time (no harm is done by doing that).
322  *
323  * TODO: A tiny performance optimization would be to separate the two
324  * cases: a load where arg[0] = PC, and the case where arg[2] = PC.
325  *
326  * o) Stores store "PC of the current instruction + 12". The solution I have
327  * choosen is to calculate this value and place it into a temporary
328  * variable (tmp_pc), which is then used for the store.
329  */
330 void A__NAME_PC(struct cpu *cpu, struct arm_instr_call *ic)
331 {
332 #ifdef A__L
333  /* Load: */
334  if (ic->arg[0] == (size_t)(&cpu->cd.arm.tmp_pc)) {
335  /* tmp_pc = current PC + 8: */
336  uint32_t low_pc, tmp;
337  low_pc = ((size_t)ic - (size_t) cpu->cd.arm.cur_ic_page) /
338  sizeof(struct arm_instr_call);
339  tmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<
341  tmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
342  cpu->cd.arm.tmp_pc = tmp + 8;
343  }
344  A__NAME(cpu, ic);
345  if (ic->arg[2] == (size_t)(&cpu->cd.arm.r[ARM_PC])) {
346  cpu->pc = cpu->cd.arm.r[ARM_PC];
348  if (cpu->machine->show_trace_tree)
349  cpu_functioncall_trace(cpu, cpu->pc);
350  }
351 #else
352  /* Store: */
353  uint32_t low_pc, tmp;
354  /* Calculate tmp from this instruction's PC + 12 */
355  low_pc = ((size_t)ic - (size_t) cpu->cd.arm.cur_ic_page) /
356  sizeof(struct arm_instr_call);
357  tmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<
359  tmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
360  cpu->cd.arm.tmp_pc = tmp + 12;
361  A__NAME(cpu, ic);
362 #endif
363 }
364 
365 
366 #ifndef A__NOCONDITIONS
367 /* Load/stores with all registers except the PC register: */
368 void A__NAME__eq(struct cpu *cpu, struct arm_instr_call *ic)
369 { if (cpu->cd.arm.flags & ARM_F_Z) A__NAME(cpu, ic); }
370 void A__NAME__ne(struct cpu *cpu, struct arm_instr_call *ic)
371 { if (!(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
372 void A__NAME__cs(struct cpu *cpu, struct arm_instr_call *ic)
373 { if (cpu->cd.arm.flags & ARM_F_C) A__NAME(cpu, ic); }
374 void A__NAME__cc(struct cpu *cpu, struct arm_instr_call *ic)
375 { if (!(cpu->cd.arm.flags & ARM_F_C)) A__NAME(cpu, ic); }
376 void A__NAME__mi(struct cpu *cpu, struct arm_instr_call *ic)
377 { if (cpu->cd.arm.flags & ARM_F_N) A__NAME(cpu, ic); }
378 void A__NAME__pl(struct cpu *cpu, struct arm_instr_call *ic)
379 { if (!(cpu->cd.arm.flags & ARM_F_N)) A__NAME(cpu, ic); }
380 void A__NAME__vs(struct cpu *cpu, struct arm_instr_call *ic)
381 { if (cpu->cd.arm.flags & ARM_F_V) A__NAME(cpu, ic); }
382 void A__NAME__vc(struct cpu *cpu, struct arm_instr_call *ic)
383 { if (!(cpu->cd.arm.flags & ARM_F_V)) A__NAME(cpu, ic); }
384 
385 void A__NAME__hi(struct cpu *cpu, struct arm_instr_call *ic)
386 { if (cpu->cd.arm.flags & ARM_F_C &&
387 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
388 void A__NAME__ls(struct cpu *cpu, struct arm_instr_call *ic)
389 { if (cpu->cd.arm.flags & ARM_F_Z ||
390 !(cpu->cd.arm.flags & ARM_F_C)) A__NAME(cpu, ic); }
391 void A__NAME__ge(struct cpu *cpu, struct arm_instr_call *ic)
392 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
393 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME(cpu, ic); }
394 void A__NAME__lt(struct cpu *cpu, struct arm_instr_call *ic)
395 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
396 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME(cpu, ic); }
397 void A__NAME__gt(struct cpu *cpu, struct arm_instr_call *ic)
398 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
399 ((cpu->cd.arm.flags & ARM_F_V)?1:0) &&
400 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
401 void A__NAME__le(struct cpu *cpu, struct arm_instr_call *ic)
402 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
403 ((cpu->cd.arm.flags & ARM_F_V)?1:0) ||
404 (cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
405 
406 
407 /* Load/stores with the PC register: */
408 void A__NAME_PC__eq(struct cpu *cpu, struct arm_instr_call *ic)
409 { if (cpu->cd.arm.flags & ARM_F_Z) A__NAME_PC(cpu, ic); }
410 void A__NAME_PC__ne(struct cpu *cpu, struct arm_instr_call *ic)
411 { if (!(cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
412 void A__NAME_PC__cs(struct cpu *cpu, struct arm_instr_call *ic)
413 { if (cpu->cd.arm.flags & ARM_F_C) A__NAME_PC(cpu, ic); }
414 void A__NAME_PC__cc(struct cpu *cpu, struct arm_instr_call *ic)
415 { if (!(cpu->cd.arm.flags & ARM_F_C)) A__NAME_PC(cpu, ic); }
416 void A__NAME_PC__mi(struct cpu *cpu, struct arm_instr_call *ic)
417 { if (cpu->cd.arm.flags & ARM_F_N) A__NAME_PC(cpu, ic); }
418 void A__NAME_PC__pl(struct cpu *cpu, struct arm_instr_call *ic)
419 { if (!(cpu->cd.arm.flags & ARM_F_N)) A__NAME_PC(cpu, ic); }
420 void A__NAME_PC__vs(struct cpu *cpu, struct arm_instr_call *ic)
421 { if (cpu->cd.arm.flags & ARM_F_V) A__NAME_PC(cpu, ic); }
422 void A__NAME_PC__vc(struct cpu *cpu, struct arm_instr_call *ic)
423 { if (!(cpu->cd.arm.flags & ARM_F_V)) A__NAME_PC(cpu, ic); }
424 
425 void A__NAME_PC__hi(struct cpu *cpu, struct arm_instr_call *ic)
426 { if (cpu->cd.arm.flags & ARM_F_C &&
427 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
428 void A__NAME_PC__ls(struct cpu *cpu, struct arm_instr_call *ic)
429 { if (cpu->cd.arm.flags & ARM_F_Z ||
430 !(cpu->cd.arm.flags & ARM_F_C)) A__NAME_PC(cpu, ic); }
431 void A__NAME_PC__ge(struct cpu *cpu, struct arm_instr_call *ic)
432 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
433 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME_PC(cpu, ic); }
434 void A__NAME_PC__lt(struct cpu *cpu, struct arm_instr_call *ic)
435 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
436 ((cpu->cd.arm.flags & ARM_F_V)?1:0)) A__NAME_PC(cpu, ic); }
437 void A__NAME_PC__gt(struct cpu *cpu, struct arm_instr_call *ic)
438 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) ==
439 ((cpu->cd.arm.flags & ARM_F_V)?1:0) &&
440 !(cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
441 void A__NAME_PC__le(struct cpu *cpu, struct arm_instr_call *ic)
442 { if (((cpu->cd.arm.flags & ARM_F_N)?1:0) !=
443 ((cpu->cd.arm.flags & ARM_F_V)?1:0) ||
444 (cpu->cd.arm.flags & ARM_F_Z)) A__NAME_PC(cpu, ic); }
445 #endif
446 
447 
448 #ifdef A__LDRD
449 #undef A__LDRD
450 #endif
451 
452 #ifdef A__STRD
453 #undef A__STRD
454 #endif
455 
void A__NAME_PC__ge(struct cpu *cpu, struct arm_instr_call *ic)
#define CACHE_DATA
Definition: memory.h:121
#define ARM_PC
Definition: cpu_arm.h:56
void A__NAME__cs(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC__vc(struct cpu *cpu, struct arm_instr_call *ic)
page
void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__general(struct cpu *cpu, struct arm_instr_call *ic)
struct arm_instr_call * ic
void A__NAME__pl(struct cpu *cpu, struct arm_instr_call *ic)
union cpu::@1 cd
struct memory * mem
Definition: cpu.h:362
void A__NAME_PC__mi(struct cpu *cpu, struct arm_instr_call *ic)
struct machine * machine
Definition: cpu.h:328
#define MEM_READ
Definition: memory.h:116
struct arm_cpu arm
Definition: cpu.h:441
#define reg(x)
void A__NAME__eq(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC__cc(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__cc(struct cpu *cpu, struct arm_instr_call *ic)
uint32_t is_userpage[N_VPH32_ENTRIES/32]
Definition: cpu_arm.h:239
uint64_t pc
Definition: cpu.h:383
#define ARM_IC_ENTRIES_PER_PAGE
Definition: cpu_arm.h:76
void A__NAME_PC__ne(struct cpu *cpu, struct arm_instr_call *ic)
#define ARM_F_V
Definition: cpu_arm.h:85
void A__NAME_PC__hi(struct cpu *cpu, struct arm_instr_call *ic)
#define quick_pc_to_pointers(cpu)
#define A__REG
#define ARM_INSTR_ALIGNMENT_SHIFT
Definition: cpu_arm.h:75
void A__NAME_PC__ls(struct cpu *cpu, struct arm_instr_call *ic)
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
void A__NAME_PC__le(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC__eq(struct cpu *cpu, struct arm_instr_call *ic)
u_short data
Definition: siireg.h:79
void A__NAME__vc(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__ne(struct cpu *cpu, struct arm_instr_call *ic)
uint32_t tmp_pc
Definition: cpu_arm.h:157
void A__NAME__lt(struct cpu *cpu, struct arm_instr_call *ic)
#define ARM_F_Z
Definition: cpu_arm.h:83
#define MEM_WRITE
Definition: memory.h:117
void A__NAME_PC__pl(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC__gt(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__ls(struct cpu *cpu, struct arm_instr_call *ic)
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:219
uint32_t addr
Definition: cpu.h:326
void A__NAME_PC__vs(struct cpu *cpu, struct arm_instr_call *ic)
#define MEMORY_USER_ACCESS
Definition: memory.h:127
void A__NAME__gt(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__ge(struct cpu *cpu, struct arm_instr_call *ic)
size_t flags
Definition: cpu_arm.h:166
void A__NAME__vs(struct cpu *cpu, struct arm_instr_call *ic)
#define ARM_F_N
Definition: cpu_arm.h:82
#define ARM_F_C
Definition: cpu_arm.h:84
void A__NAME__le(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__hi(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC__lt(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME__mi(struct cpu *cpu, struct arm_instr_call *ic)
void A__NAME_PC__cs(struct cpu *cpu, struct arm_instr_call *ic)
uint32_t r[N_ARM_REGS]
Definition: cpu_arm.h:148
int show_trace_tree
Definition: machine.h:164

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13