• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*---------------------------------------------------------------*/
3 /*--- begin                              guest_mips_helpers.c ---*/
4 /*---------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2010-2012 RT-RK
11       mips-valgrind@rt-rk.com
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 #include "libvex_basictypes.h"
32 #include "libvex_emwarn.h"
33 #include "libvex_guest_mips32.h"
34 #include "libvex_ir.h"
35 #include "libvex.h"
36 
37 #include "main_util.h"
38 #include "guest_generic_bb_to_IR.h"
39 #include "guest_mips_defs.h"
40 
41 /* This file contains helper functions for mips guest code.  Calls to
42    these functions are generated by the back end.
43 */
44 
45 #define ALWAYSDEFD32(field)                           \
46     { offsetof(VexGuestMIPS32State, field),            \
47       (sizeof ((VexGuestMIPS32State*)0)->field) }
48 
guest_mips32_spechelper(HChar * function_name,IRExpr ** args,IRStmt ** precedingStmts,Int n_precedingStmts)49 IRExpr *guest_mips32_spechelper(HChar * function_name, IRExpr ** args,
50                                 IRStmt ** precedingStmts, Int n_precedingStmts)
51 {
52    return NULL;
53 }
54 
55 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestMIPS32_initialise(VexGuestMIPS32State * vex_state)56 void LibVEX_GuestMIPS32_initialise( /*OUT*/ VexGuestMIPS32State * vex_state)
57 {
58    vex_state->guest_r0 = 0;   /* Hardwired to 0 */
59    vex_state->guest_r1 = 0;   /* Assembler temporary */
60    vex_state->guest_r2 = 0;   /* Values for function returns ... */
61    vex_state->guest_r3 = 0;   /* ...and expression evaluation */
62    vex_state->guest_r4 = 0;   /* Function arguments */
63    vex_state->guest_r5 = 0;
64    vex_state->guest_r6 = 0;
65    vex_state->guest_r7 = 0;
66    vex_state->guest_r8 = 0;   /* Temporaries */
67    vex_state->guest_r9 = 0;
68    vex_state->guest_r10 = 0;
69    vex_state->guest_r11 = 0;
70    vex_state->guest_r12 = 0;
71    vex_state->guest_r13 = 0;
72    vex_state->guest_r14 = 0;
73    vex_state->guest_r15 = 0;
74    vex_state->guest_r16 = 0;  /* Saved temporaries */
75    vex_state->guest_r17 = 0;
76    vex_state->guest_r18 = 0;
77    vex_state->guest_r19 = 0;
78    vex_state->guest_r20 = 0;
79    vex_state->guest_r21 = 0;
80    vex_state->guest_r22 = 0;
81    vex_state->guest_r23 = 0;
82    vex_state->guest_r24 = 0;  /* Temporaries */
83    vex_state->guest_r25 = 0;
84    vex_state->guest_r26 = 0;  /* Reserved for OS kernel */
85    vex_state->guest_r27 = 0;
86    vex_state->guest_r28 = 0;  /* Global pointer */
87    vex_state->guest_r29 = 0;  /* Stack pointer */
88    vex_state->guest_r30 = 0;  /* Frame pointer */
89    vex_state->guest_r31 = 0;  /* Return address */
90    vex_state->guest_PC = 0;   /* Program counter */
91    vex_state->guest_HI = 0;   /* Multiply and divide register higher result */
92    vex_state->guest_LO = 0;   /* Multiply and divide register lower result */
93 
94    /* FPU Registers */
95    vex_state->guest_f0 = 0x7ff80000;   /* Floting point general purpose registers */
96    vex_state->guest_f1 = 0x7ff80000;
97    vex_state->guest_f2 = 0x7ff80000;
98    vex_state->guest_f3 = 0x7ff80000;
99    vex_state->guest_f4 = 0x7ff80000;
100    vex_state->guest_f5 = 0x7ff80000;
101    vex_state->guest_f6 = 0x7ff80000;
102    vex_state->guest_f7 = 0x7ff80000;
103    vex_state->guest_f8 = 0x7ff80000;
104    vex_state->guest_f9 = 0x7ff80000;
105    vex_state->guest_f10 = 0x7ff80000;
106    vex_state->guest_f11 = 0x7ff80000;
107    vex_state->guest_f12 = 0x7ff80000;
108    vex_state->guest_f13 = 0x7ff80000;
109    vex_state->guest_f14 = 0x7ff80000;
110    vex_state->guest_f15 = 0x7ff80000;
111    vex_state->guest_f16 = 0x7ff80000;
112    vex_state->guest_f17 = 0x7ff80000;
113    vex_state->guest_f18 = 0x7ff80000;
114    vex_state->guest_f19 = 0x7ff80000;
115    vex_state->guest_f20 = 0x7ff80000;
116    vex_state->guest_f21 = 0x7ff80000;
117    vex_state->guest_f22 = 0x7ff80000;
118    vex_state->guest_f23 = 0x7ff80000;
119    vex_state->guest_f24 = 0x7ff80000;
120    vex_state->guest_f25 = 0x7ff80000;
121    vex_state->guest_f26 = 0x7ff80000;
122    vex_state->guest_f27 = 0x7ff80000;
123    vex_state->guest_f28 = 0x7ff80000;
124    vex_state->guest_f29 = 0x7ff80000;
125    vex_state->guest_f30 = 0x7ff80000;
126    vex_state->guest_f31 = 0x7ff80000;
127 
128    vex_state->guest_FIR = 0;  /* FP implementation and revision register */
129    vex_state->guest_FCCR = 0; /* FP condition codes register */
130    vex_state->guest_FEXR = 0; /* FP exceptions register */
131    vex_state->guest_FENR = 0; /* FP enables register */
132    vex_state->guest_FCSR = 0; /* FP control/status register */
133    vex_state->guest_ULR = 0; /* TLS */
134 
135    /* Various pseudo-regs mandated by Vex or Valgrind. */
136    /* Emulation warnings */
137    vex_state->guest_EMWARN = 0;
138 
139    /* For clflush: record start and length of area to invalidate */
140    vex_state->guest_TISTART = 0;
141    vex_state->guest_TILEN = 0;
142    vex_state->host_EvC_COUNTER = 0;
143    vex_state->host_EvC_FAILADDR = 0;
144 
145    /* Used to record the unredirected guest address at the start of
146       a translation whose start has been redirected.  By reading
147       this pseudo-register shortly afterwards, the translation can
148       find out what the corresponding no-redirection address was.
149       Note, this is only set for wrap-style redirects, not for
150       replace-style ones. */
151    vex_state->guest_NRADDR = 0;
152 
153    vex_state->guest_COND = 0;
154 }
155 
156 /*-----------------------------------------------------------*/
157 /*--- Describing the mips guest state, for the benefit    ---*/
158 /*--- of iropt and instrumenters.                         ---*/
159 /*-----------------------------------------------------------*/
160 
161 /* Figure out if any part of the guest state contained in minoff
162    .. maxoff requires precise memory exceptions.  If in doubt return
163    True (but this is generates significantly slower code).
164 
165    We enforce precise exns for guest SP, PC.
166 */
guest_mips32_state_requires_precise_mem_exns(Int minoff,Int maxoff)167 Bool guest_mips32_state_requires_precise_mem_exns(Int minoff, Int maxoff)
168 {
169    Int sp_min = offsetof(VexGuestMIPS32State, guest_r29);
170    Int sp_max = sp_min + 4 - 1;
171    Int pc_min = offsetof(VexGuestMIPS32State, guest_PC);
172    Int pc_max = pc_min + 4 - 1;
173 
174    if (maxoff < sp_min || minoff > sp_max) {
175       /* no overlap with sp */
176    } else {
177       return True;
178    }
179 
180    if (maxoff < pc_min || minoff > pc_max) {
181       /* no overlap with pc */
182    } else {
183       return True;
184    }
185 
186    /* We appear to need precise updates of R11 in order to get proper
187       stacktraces from non-optimised code. */
188    Int fp_min = offsetof(VexGuestMIPS32State, guest_r30);
189    Int fp_max = fp_min + 4 - 1;
190 
191    if (maxoff < fp_min || minoff > fp_max) {
192       /* no overlap with fp */
193    } else {
194       return True;
195    }
196 
197    return False;
198 }
199 
200 VexGuestLayout mips32Guest_layout = {
201    /* Total size of the guest state, in bytes. */
202    .total_sizeB = sizeof(VexGuestMIPS32State),
203    /* Describe the stack pointer. */
204    .offset_SP = offsetof(VexGuestMIPS32State, guest_r29),
205    .sizeof_SP = 4,
206    /* Describe the frame pointer. */
207    .offset_FP = offsetof(VexGuestMIPS32State, guest_r30),
208    .sizeof_FP = 4,
209    /* Describe the instruction pointer. */
210    .offset_IP = offsetof(VexGuestMIPS32State, guest_PC),
211    .sizeof_IP = 4,
212    /* Describe any sections to be regarded by Memcheck as
213       'always-defined'. */
214    .n_alwaysDefd = 8,
215    /* ? :(  */
216    .alwaysDefd = {
217              /* 0 */ ALWAYSDEFD32(guest_r0),
218              /* 1 */ ALWAYSDEFD32(guest_r1),
219              /* 2 */ ALWAYSDEFD32(guest_EMWARN),
220              /* 3 */ ALWAYSDEFD32(guest_TISTART),
221              /* 4 */ ALWAYSDEFD32(guest_TILEN),
222              /* 5 */ ALWAYSDEFD32(guest_r29),
223              /* 6 */ ALWAYSDEFD32(guest_r31),
224              /* 7 */ ALWAYSDEFD32(guest_ULR)
225              }
226 };
227 
228 #define ASM_VOLATILE_CASE(rd, sel) \
229          case rd: asm volatile ("mfc0 %0, $" #rd ", "#sel"\n\t" :"=r" (x) ); break;
230 
mips32_dirtyhelper_mfc0(UInt rd,UInt sel)231 UInt mips32_dirtyhelper_mfc0(UInt rd, UInt sel)
232 {
233    UInt x = 0;
234 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
235    switch (sel) {
236       case 0:
237          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
238          switch (rd) {
239             ASM_VOLATILE_CASE(0, 0);
240             ASM_VOLATILE_CASE(1, 0);
241             ASM_VOLATILE_CASE(2, 0);
242             ASM_VOLATILE_CASE(3, 0);
243             ASM_VOLATILE_CASE(4, 0);
244             ASM_VOLATILE_CASE(5, 0);
245             ASM_VOLATILE_CASE(6, 0);
246             ASM_VOLATILE_CASE(7, 0);
247             ASM_VOLATILE_CASE(8, 0);
248             ASM_VOLATILE_CASE(9, 0);
249             ASM_VOLATILE_CASE(10, 0);
250             ASM_VOLATILE_CASE(11, 0);
251             ASM_VOLATILE_CASE(12, 0);
252             ASM_VOLATILE_CASE(13, 0);
253             ASM_VOLATILE_CASE(14, 0);
254             ASM_VOLATILE_CASE(15, 0);
255             ASM_VOLATILE_CASE(16, 0);
256             ASM_VOLATILE_CASE(17, 0);
257             ASM_VOLATILE_CASE(18, 0);
258             ASM_VOLATILE_CASE(19, 0);
259             ASM_VOLATILE_CASE(20, 0);
260             ASM_VOLATILE_CASE(21, 0);
261             ASM_VOLATILE_CASE(22, 0);
262             ASM_VOLATILE_CASE(23, 0);
263             ASM_VOLATILE_CASE(24, 0);
264             ASM_VOLATILE_CASE(25, 0);
265             ASM_VOLATILE_CASE(26, 0);
266             ASM_VOLATILE_CASE(27, 0);
267             ASM_VOLATILE_CASE(28, 0);
268             ASM_VOLATILE_CASE(29, 0);
269             ASM_VOLATILE_CASE(30, 0);
270             ASM_VOLATILE_CASE(31, 0);
271          default:
272             break;
273          }
274          break;
275       case 1:
276          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
277          switch (rd) {
278             ASM_VOLATILE_CASE(0, 1);
279             ASM_VOLATILE_CASE(1, 1);
280             ASM_VOLATILE_CASE(2, 1);
281             ASM_VOLATILE_CASE(3, 1);
282             ASM_VOLATILE_CASE(4, 1);
283             ASM_VOLATILE_CASE(5, 1);
284             ASM_VOLATILE_CASE(6, 1);
285             ASM_VOLATILE_CASE(7, 1);
286             ASM_VOLATILE_CASE(8, 1);
287             ASM_VOLATILE_CASE(9, 1);
288             ASM_VOLATILE_CASE(10, 1);
289             ASM_VOLATILE_CASE(11, 1);
290             ASM_VOLATILE_CASE(12, 1);
291             ASM_VOLATILE_CASE(13, 1);
292             ASM_VOLATILE_CASE(14, 1);
293             ASM_VOLATILE_CASE(15, 1);
294             ASM_VOLATILE_CASE(16, 1);
295             ASM_VOLATILE_CASE(17, 1);
296             ASM_VOLATILE_CASE(18, 1);
297             ASM_VOLATILE_CASE(19, 1);
298             ASM_VOLATILE_CASE(20, 1);
299             ASM_VOLATILE_CASE(21, 1);
300             ASM_VOLATILE_CASE(22, 1);
301             ASM_VOLATILE_CASE(23, 1);
302             ASM_VOLATILE_CASE(24, 1);
303             ASM_VOLATILE_CASE(25, 1);
304             ASM_VOLATILE_CASE(26, 1);
305             ASM_VOLATILE_CASE(27, 1);
306             ASM_VOLATILE_CASE(28, 1);
307             ASM_VOLATILE_CASE(29, 1);
308             ASM_VOLATILE_CASE(30, 1);
309             ASM_VOLATILE_CASE(31, 1);
310          default:
311             break;
312          }
313          break;
314       case 2:
315          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
316          switch (rd) {
317             ASM_VOLATILE_CASE(0, 2);
318             ASM_VOLATILE_CASE(1, 2);
319             ASM_VOLATILE_CASE(2, 2);
320             ASM_VOLATILE_CASE(3, 1);
321             ASM_VOLATILE_CASE(4, 2);
322             ASM_VOLATILE_CASE(5, 2);
323             ASM_VOLATILE_CASE(6, 2);
324             ASM_VOLATILE_CASE(7, 2);
325             ASM_VOLATILE_CASE(8, 2);
326             ASM_VOLATILE_CASE(9, 2);
327             ASM_VOLATILE_CASE(10, 2);
328             ASM_VOLATILE_CASE(11, 2);
329             ASM_VOLATILE_CASE(12, 2);
330             ASM_VOLATILE_CASE(13, 2);
331             ASM_VOLATILE_CASE(14, 2);
332             ASM_VOLATILE_CASE(15, 2);
333             ASM_VOLATILE_CASE(16, 2);
334             ASM_VOLATILE_CASE(17, 2);
335             ASM_VOLATILE_CASE(18, 2);
336             ASM_VOLATILE_CASE(19, 2);
337             ASM_VOLATILE_CASE(20, 2);
338             ASM_VOLATILE_CASE(21, 2);
339             ASM_VOLATILE_CASE(22, 2);
340             ASM_VOLATILE_CASE(23, 2);
341             ASM_VOLATILE_CASE(24, 2);
342             ASM_VOLATILE_CASE(25, 2);
343             ASM_VOLATILE_CASE(26, 2);
344             ASM_VOLATILE_CASE(27, 2);
345             ASM_VOLATILE_CASE(28, 2);
346             ASM_VOLATILE_CASE(29, 2);
347             ASM_VOLATILE_CASE(30, 2);
348             ASM_VOLATILE_CASE(31, 2);
349          default:
350             break;
351          }
352          break;
353       case 3:
354          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
355          switch (rd) {
356             ASM_VOLATILE_CASE(0, 3);
357             ASM_VOLATILE_CASE(1, 3);
358             ASM_VOLATILE_CASE(2, 3);
359             ASM_VOLATILE_CASE(3, 3);
360             ASM_VOLATILE_CASE(4, 3);
361             ASM_VOLATILE_CASE(5, 3);
362             ASM_VOLATILE_CASE(6, 3);
363             ASM_VOLATILE_CASE(7, 3);
364             ASM_VOLATILE_CASE(8, 3);
365             ASM_VOLATILE_CASE(9, 3);
366             ASM_VOLATILE_CASE(10, 3);
367             ASM_VOLATILE_CASE(11, 3);
368             ASM_VOLATILE_CASE(12, 3);
369             ASM_VOLATILE_CASE(13, 3);
370             ASM_VOLATILE_CASE(14, 3);
371             ASM_VOLATILE_CASE(15, 3);
372             ASM_VOLATILE_CASE(16, 3);
373             ASM_VOLATILE_CASE(17, 3);
374             ASM_VOLATILE_CASE(18, 3);
375             ASM_VOLATILE_CASE(19, 3);
376             ASM_VOLATILE_CASE(20, 3);
377             ASM_VOLATILE_CASE(21, 3);
378             ASM_VOLATILE_CASE(22, 3);
379             ASM_VOLATILE_CASE(23, 3);
380             ASM_VOLATILE_CASE(24, 3);
381             ASM_VOLATILE_CASE(25, 3);
382             ASM_VOLATILE_CASE(26, 3);
383             ASM_VOLATILE_CASE(27, 3);
384             ASM_VOLATILE_CASE(28, 3);
385             ASM_VOLATILE_CASE(29, 3);
386             ASM_VOLATILE_CASE(30, 3);
387             ASM_VOLATILE_CASE(31, 3);
388          default:
389             break;
390          }
391          break;
392       case 4:
393          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
394          switch (rd) {
395             ASM_VOLATILE_CASE(0, 4);
396             ASM_VOLATILE_CASE(1, 4);
397             ASM_VOLATILE_CASE(2, 4);
398             ASM_VOLATILE_CASE(3, 4);
399             ASM_VOLATILE_CASE(4, 4);
400             ASM_VOLATILE_CASE(5, 4);
401             ASM_VOLATILE_CASE(6, 4);
402             ASM_VOLATILE_CASE(7, 4);
403             ASM_VOLATILE_CASE(8, 4);
404             ASM_VOLATILE_CASE(9, 4);
405             ASM_VOLATILE_CASE(10, 4);
406             ASM_VOLATILE_CASE(11, 4);
407             ASM_VOLATILE_CASE(12, 4);
408             ASM_VOLATILE_CASE(13, 4);
409             ASM_VOLATILE_CASE(14, 4);
410             ASM_VOLATILE_CASE(15, 4);
411             ASM_VOLATILE_CASE(16, 4);
412             ASM_VOLATILE_CASE(17, 4);
413             ASM_VOLATILE_CASE(18, 4);
414             ASM_VOLATILE_CASE(19, 4);
415             ASM_VOLATILE_CASE(20, 4);
416             ASM_VOLATILE_CASE(21, 4);
417             ASM_VOLATILE_CASE(22, 4);
418             ASM_VOLATILE_CASE(23, 4);
419             ASM_VOLATILE_CASE(24, 4);
420             ASM_VOLATILE_CASE(25, 4);
421             ASM_VOLATILE_CASE(26, 4);
422             ASM_VOLATILE_CASE(27, 4);
423             ASM_VOLATILE_CASE(28, 4);
424             ASM_VOLATILE_CASE(29, 4);
425             ASM_VOLATILE_CASE(30, 4);
426             ASM_VOLATILE_CASE(31, 4);
427          default:
428             break;
429          }
430          break;
431       case 5:
432          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
433          switch (rd) {
434             ASM_VOLATILE_CASE(0, 5);
435             ASM_VOLATILE_CASE(1, 5);
436             ASM_VOLATILE_CASE(2, 5);
437             ASM_VOLATILE_CASE(3, 5);
438             ASM_VOLATILE_CASE(4, 5);
439             ASM_VOLATILE_CASE(5, 5);
440             ASM_VOLATILE_CASE(6, 5);
441             ASM_VOLATILE_CASE(7, 5);
442             ASM_VOLATILE_CASE(8, 5);
443             ASM_VOLATILE_CASE(9, 5);
444             ASM_VOLATILE_CASE(10, 5);
445             ASM_VOLATILE_CASE(11, 5);
446             ASM_VOLATILE_CASE(12, 5);
447             ASM_VOLATILE_CASE(13, 5);
448             ASM_VOLATILE_CASE(14, 5);
449             ASM_VOLATILE_CASE(15, 5);
450             ASM_VOLATILE_CASE(16, 5);
451             ASM_VOLATILE_CASE(17, 5);
452             ASM_VOLATILE_CASE(18, 5);
453             ASM_VOLATILE_CASE(19, 5);
454             ASM_VOLATILE_CASE(20, 5);
455             ASM_VOLATILE_CASE(21, 5);
456             ASM_VOLATILE_CASE(22, 5);
457             ASM_VOLATILE_CASE(23, 5);
458             ASM_VOLATILE_CASE(24, 5);
459             ASM_VOLATILE_CASE(25, 5);
460             ASM_VOLATILE_CASE(26, 5);
461             ASM_VOLATILE_CASE(27, 5);
462             ASM_VOLATILE_CASE(28, 5);
463             ASM_VOLATILE_CASE(29, 5);
464             ASM_VOLATILE_CASE(30, 5);
465             ASM_VOLATILE_CASE(31, 5);
466          default:
467             break;
468          }
469          break;
470       case 6:
471          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
472          switch (rd) {
473             ASM_VOLATILE_CASE(0, 6);
474             ASM_VOLATILE_CASE(1, 6);
475             ASM_VOLATILE_CASE(2, 6);
476             ASM_VOLATILE_CASE(3, 6);
477             ASM_VOLATILE_CASE(4, 6);
478             ASM_VOLATILE_CASE(5, 6);
479             ASM_VOLATILE_CASE(6, 6);
480             ASM_VOLATILE_CASE(7, 6);
481             ASM_VOLATILE_CASE(8, 6);
482             ASM_VOLATILE_CASE(9, 6);
483             ASM_VOLATILE_CASE(10, 6);
484             ASM_VOLATILE_CASE(11, 6);
485             ASM_VOLATILE_CASE(12, 6);
486             ASM_VOLATILE_CASE(13, 6);
487             ASM_VOLATILE_CASE(14, 6);
488             ASM_VOLATILE_CASE(15, 6);
489             ASM_VOLATILE_CASE(16, 6);
490             ASM_VOLATILE_CASE(17, 6);
491             ASM_VOLATILE_CASE(18, 6);
492             ASM_VOLATILE_CASE(19, 6);
493             ASM_VOLATILE_CASE(20, 6);
494             ASM_VOLATILE_CASE(21, 6);
495             ASM_VOLATILE_CASE(22, 6);
496             ASM_VOLATILE_CASE(23, 6);
497             ASM_VOLATILE_CASE(24, 6);
498             ASM_VOLATILE_CASE(25, 6);
499             ASM_VOLATILE_CASE(26, 6);
500             ASM_VOLATILE_CASE(27, 6);
501             ASM_VOLATILE_CASE(28, 6);
502             ASM_VOLATILE_CASE(29, 6);
503             ASM_VOLATILE_CASE(30, 6);
504             ASM_VOLATILE_CASE(31, 6);
505          default:
506             break;
507          }
508          break;
509       case 7:
510          //__asm__("mfc0 %0, $1, 0" :"=r" (x));
511          switch (rd) {
512             ASM_VOLATILE_CASE(0, 7);
513             ASM_VOLATILE_CASE(1, 7);
514             ASM_VOLATILE_CASE(2, 7);
515             ASM_VOLATILE_CASE(3, 7);
516             ASM_VOLATILE_CASE(4, 7);
517             ASM_VOLATILE_CASE(5, 7);
518             ASM_VOLATILE_CASE(6, 7);
519             ASM_VOLATILE_CASE(7, 7);
520             ASM_VOLATILE_CASE(8, 7);
521             ASM_VOLATILE_CASE(9, 7);
522             ASM_VOLATILE_CASE(10, 7);
523             ASM_VOLATILE_CASE(11, 7);
524             ASM_VOLATILE_CASE(12, 7);
525             ASM_VOLATILE_CASE(13, 7);
526             ASM_VOLATILE_CASE(14, 7);
527             ASM_VOLATILE_CASE(15, 7);
528             ASM_VOLATILE_CASE(16, 7);
529             ASM_VOLATILE_CASE(17, 7);
530             ASM_VOLATILE_CASE(18, 7);
531             ASM_VOLATILE_CASE(19, 7);
532             ASM_VOLATILE_CASE(20, 7);
533             ASM_VOLATILE_CASE(21, 7);
534             ASM_VOLATILE_CASE(22, 7);
535             ASM_VOLATILE_CASE(23, 7);
536             ASM_VOLATILE_CASE(24, 7);
537             ASM_VOLATILE_CASE(25, 7);
538             ASM_VOLATILE_CASE(26, 7);
539             ASM_VOLATILE_CASE(27, 7);
540             ASM_VOLATILE_CASE(28, 7);
541             ASM_VOLATILE_CASE(29, 7);
542             ASM_VOLATILE_CASE(30, 7);
543             ASM_VOLATILE_CASE(31, 7);
544          default:
545             break;
546          }
547       break;
548 
549    default:
550       break;
551    }
552 #endif
553    return x;
554 }
555 
556 #undef ASM_VOLATILE_CASE
557 
558 #define ASM_VOLATILE_CASE(rd, sel) \
559    case rd: asm volatile ("dmfc0 %0, $" #rd ", "#sel"\n\t" :"=r" (x) ); break;
560 
561 #define ASM_VOLATILE_SYNC(stype) \
562         asm volatile ("sync \n\t");
563 
mips32_dirtyhelper_sync(UInt stype)564 void mips32_dirtyhelper_sync(UInt stype)
565 {
566 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
567    ASM_VOLATILE_SYNC(0);
568 #endif
569 }
570 
571 /*---------------------------------------------------------------*/
572 /*--- end                                guest_mips_helpers.c ---*/
573 /*---------------------------------------------------------------*/
574