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
49IRExpr *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 */
56void 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*/
167Bool 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
200VexGuestLayout 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
231UInt 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
564void 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