Commit 48d38ca52b6d9c33066e139226eba2966d0c88d3

Authored by ths
1 parent 8c99506c

Switch most MIPS logical and arithmetic instructions to TCG.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4496 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/exec.h
... ... @@ -118,8 +118,6 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
118 118 void cpu_loop_exit(void);
119 119 void do_raise_exception_err (uint32_t exception, int error_code);
120 120 void do_raise_exception (uint32_t exception);
121   -void do_raise_exception_direct_err (uint32_t exception, int error_code);
122   -void do_raise_exception_direct (uint32_t exception);
123 121  
124 122 void cpu_dump_state(CPUState *env, FILE *f,
125 123 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
... ...
target-mips/op.c
... ... @@ -167,251 +167,7 @@
167 167 #undef MEMSUFFIX
168 168 #endif
169 169  
170   -/* Addresses computation */
171   -void op_addr_add (void)
172   -{
173   -/* For compatibility with 32-bit code, data reference in user mode
174   - with Status_UX = 0 should be casted to 32-bit and sign extended.
175   - See the MIPS64 PRA manual, section 4.10. */
176   -#if defined(TARGET_MIPS64)
177   - if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
178   - !(env->CP0_Status & (1 << CP0St_UX)))
179   - T0 = (int64_t)(int32_t)(T0 + T1);
180   - else
181   -#endif
182   - T0 += T1;
183   - FORCE_RET();
184   -}
185   -
186   -/* Arithmetic */
187   -void op_add (void)
188   -{
189   - T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
190   - FORCE_RET();
191   -}
192   -
193   -void op_addo (void)
194   -{
195   - target_ulong tmp;
196   -
197   - tmp = (int32_t)T0;
198   - T0 = (int32_t)T0 + (int32_t)T1;
199   - if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
200   - /* operands of same sign, result different sign */
201   - CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
202   - }
203   - T0 = (int32_t)T0;
204   - FORCE_RET();
205   -}
206   -
207   -void op_sub (void)
208   -{
209   - T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
210   - FORCE_RET();
211   -}
212   -
213   -void op_subo (void)
214   -{
215   - target_ulong tmp;
216   -
217   - tmp = (int32_t)T0;
218   - T0 = (int32_t)T0 - (int32_t)T1;
219   - if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
220   - /* operands of different sign, first operand and result different sign */
221   - CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
222   - }
223   - T0 = (int32_t)T0;
224   - FORCE_RET();
225   -}
226   -
227   -void op_mul (void)
228   -{
229   - T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
230   - FORCE_RET();
231   -}
232   -
233   -#if HOST_LONG_BITS < 64
234   -void op_div (void)
235   -{
236   - CALL_FROM_TB0(do_div);
237   - FORCE_RET();
238   -}
239   -#else
240   -void op_div (void)
241   -{
242   - if (T1 != 0) {
243   - env->LO[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
244   - env->HI[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
245   - }
246   - FORCE_RET();
247   -}
248   -#endif
249   -
250   -void op_divu (void)
251   -{
252   - if (T1 != 0) {
253   - env->LO[env->current_tc][0] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
254   - env->HI[env->current_tc][0] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
255   - }
256   - FORCE_RET();
257   -}
258   -
259   -#if defined(TARGET_MIPS64)
260   -/* Arithmetic */
261   -void op_dadd (void)
262   -{
263   - T0 += T1;
264   - FORCE_RET();
265   -}
266   -
267   -void op_daddo (void)
268   -{
269   - target_long tmp;
270   -
271   - tmp = T0;
272   - T0 += T1;
273   - if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
274   - /* operands of same sign, result different sign */
275   - CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
276   - }
277   - FORCE_RET();
278   -}
279   -
280   -void op_dsub (void)
281   -{
282   - T0 -= T1;
283   - FORCE_RET();
284   -}
285   -
286   -void op_dsubo (void)
287   -{
288   - target_long tmp;
289   -
290   - tmp = T0;
291   - T0 = (int64_t)T0 - (int64_t)T1;
292   - if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
293   - /* operands of different sign, first operand and result different sign */
294   - CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
295   - }
296   - FORCE_RET();
297   -}
298   -
299   -void op_dmul (void)
300   -{
301   - T0 = (int64_t)T0 * (int64_t)T1;
302   - FORCE_RET();
303   -}
304   -
305   -/* Those might call libgcc functions. */
306   -void op_ddiv (void)
307   -{
308   - do_ddiv();
309   - FORCE_RET();
310   -}
311   -
312   -#if TARGET_LONG_BITS > HOST_LONG_BITS
313   -void op_ddivu (void)
314   -{
315   - do_ddivu();
316   - FORCE_RET();
317   -}
318   -#else
319   -void op_ddivu (void)
320   -{
321   - if (T1 != 0) {
322   - env->LO[env->current_tc][0] = T0 / T1;
323   - env->HI[env->current_tc][0] = T0 % T1;
324   - }
325   - FORCE_RET();
326   -}
327   -#endif
328   -#endif /* TARGET_MIPS64 */
329   -
330 170 /* Logical */
331   -void op_and (void)
332   -{
333   - T0 &= T1;
334   - FORCE_RET();
335   -}
336   -
337   -void op_nor (void)
338   -{
339   - T0 = ~(T0 | T1);
340   - FORCE_RET();
341   -}
342   -
343   -void op_or (void)
344   -{
345   - T0 |= T1;
346   - FORCE_RET();
347   -}
348   -
349   -void op_xor (void)
350   -{
351   - T0 ^= T1;
352   - FORCE_RET();
353   -}
354   -
355   -void op_sll (void)
356   -{
357   - T0 = (int32_t)((uint32_t)T0 << T1);
358   - FORCE_RET();
359   -}
360   -
361   -void op_sra (void)
362   -{
363   - T0 = (int32_t)((int32_t)T0 >> T1);
364   - FORCE_RET();
365   -}
366   -
367   -void op_srl (void)
368   -{
369   - T0 = (int32_t)((uint32_t)T0 >> T1);
370   - FORCE_RET();
371   -}
372   -
373   -void op_rotr (void)
374   -{
375   - target_ulong tmp;
376   -
377   - if (T1) {
378   - tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
379   - T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
380   - }
381   - FORCE_RET();
382   -}
383   -
384   -void op_sllv (void)
385   -{
386   - T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
387   - FORCE_RET();
388   -}
389   -
390   -void op_srav (void)
391   -{
392   - T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
393   - FORCE_RET();
394   -}
395   -
396   -void op_srlv (void)
397   -{
398   - T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
399   - FORCE_RET();
400   -}
401   -
402   -void op_rotrv (void)
403   -{
404   - target_ulong tmp;
405   -
406   - T0 &= 0x1F;
407   - if (T0) {
408   - tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
409   - T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
410   - } else
411   - T0 = T1;
412   - FORCE_RET();
413   -}
414   -
415 171 void op_clo (void)
416 172 {
417 173 T0 = clo32(T0);
... ... @@ -428,78 +184,6 @@ void op_clz (void)
428 184  
429 185 #if TARGET_LONG_BITS > HOST_LONG_BITS
430 186 /* Those might call libgcc functions. */
431   -void op_dsll (void)
432   -{
433   - CALL_FROM_TB0(do_dsll);
434   - FORCE_RET();
435   -}
436   -
437   -void op_dsll32 (void)
438   -{
439   - CALL_FROM_TB0(do_dsll32);
440   - FORCE_RET();
441   -}
442   -
443   -void op_dsra (void)
444   -{
445   - CALL_FROM_TB0(do_dsra);
446   - FORCE_RET();
447   -}
448   -
449   -void op_dsra32 (void)
450   -{
451   - CALL_FROM_TB0(do_dsra32);
452   - FORCE_RET();
453   -}
454   -
455   -void op_dsrl (void)
456   -{
457   - CALL_FROM_TB0(do_dsrl);
458   - FORCE_RET();
459   -}
460   -
461   -void op_dsrl32 (void)
462   -{
463   - CALL_FROM_TB0(do_dsrl32);
464   - FORCE_RET();
465   -}
466   -
467   -void op_drotr (void)
468   -{
469   - CALL_FROM_TB0(do_drotr);
470   - FORCE_RET();
471   -}
472   -
473   -void op_drotr32 (void)
474   -{
475   - CALL_FROM_TB0(do_drotr32);
476   - FORCE_RET();
477   -}
478   -
479   -void op_dsllv (void)
480   -{
481   - CALL_FROM_TB0(do_dsllv);
482   - FORCE_RET();
483   -}
484   -
485   -void op_dsrav (void)
486   -{
487   - CALL_FROM_TB0(do_dsrav);
488   - FORCE_RET();
489   -}
490   -
491   -void op_dsrlv (void)
492   -{
493   - CALL_FROM_TB0(do_dsrlv);
494   - FORCE_RET();
495   -}
496   -
497   -void op_drotrv (void)
498   -{
499   - CALL_FROM_TB0(do_drotrv);
500   - FORCE_RET();
501   -}
502   -
503 187 void op_dclo (void)
504 188 {
505 189 CALL_FROM_TB0(do_dclo);
... ... @@ -514,93 +198,6 @@ void op_dclz (void)
514 198  
515 199 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
516 200  
517   -void op_dsll (void)
518   -{
519   - T0 = T0 << T1;
520   - FORCE_RET();
521   -}
522   -
523   -void op_dsll32 (void)
524   -{
525   - T0 = T0 << (T1 + 32);
526   - FORCE_RET();
527   -}
528   -
529   -void op_dsra (void)
530   -{
531   - T0 = (int64_t)T0 >> T1;
532   - FORCE_RET();
533   -}
534   -
535   -void op_dsra32 (void)
536   -{
537   - T0 = (int64_t)T0 >> (T1 + 32);
538   - FORCE_RET();
539   -}
540   -
541   -void op_dsrl (void)
542   -{
543   - T0 = T0 >> T1;
544   - FORCE_RET();
545   -}
546   -
547   -void op_dsrl32 (void)
548   -{
549   - T0 = T0 >> (T1 + 32);
550   - FORCE_RET();
551   -}
552   -
553   -void op_drotr (void)
554   -{
555   - target_ulong tmp;
556   -
557   - if (T1) {
558   - tmp = T0 << (0x40 - T1);
559   - T0 = (T0 >> T1) | tmp;
560   - }
561   - FORCE_RET();
562   -}
563   -
564   -void op_drotr32 (void)
565   -{
566   - target_ulong tmp;
567   -
568   - tmp = T0 << (0x40 - (32 + T1));
569   - T0 = (T0 >> (32 + T1)) | tmp;
570   - FORCE_RET();
571   -}
572   -
573   -void op_dsllv (void)
574   -{
575   - T0 = T1 << (T0 & 0x3F);
576   - FORCE_RET();
577   -}
578   -
579   -void op_dsrav (void)
580   -{
581   - T0 = (int64_t)T1 >> (T0 & 0x3F);
582   - FORCE_RET();
583   -}
584   -
585   -void op_dsrlv (void)
586   -{
587   - T0 = T1 >> (T0 & 0x3F);
588   - FORCE_RET();
589   -}
590   -
591   -void op_drotrv (void)
592   -{
593   - target_ulong tmp;
594   -
595   - T0 &= 0x3F;
596   - if (T0) {
597   - tmp = T1 << (0x40 - T0);
598   - T0 = (T1 >> T0) | tmp;
599   - } else
600   - T0 = T1;
601   - FORCE_RET();
602   -}
603   -
604 201 void op_dclo (void)
605 202 {
606 203 T0 = clo64(T0);
... ... @@ -3063,31 +2660,6 @@ void op_save_pc64 (void)
3063 2660 }
3064 2661 #endif
3065 2662  
3066   -void op_interrupt_restart (void)
3067   -{
3068   - if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
3069   - !(env->CP0_Status & (1 << CP0St_ERL)) &&
3070   - !(env->hflags & MIPS_HFLAG_DM) &&
3071   - (env->CP0_Status & (1 << CP0St_IE)) &&
3072   - (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
3073   - env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
3074   - CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
3075   - }
3076   - FORCE_RET();
3077   -}
3078   -
3079   -void op_raise_exception (void)
3080   -{
3081   - CALL_FROM_TB1(do_raise_exception, PARAM1);
3082   - FORCE_RET();
3083   -}
3084   -
3085   -void op_raise_exception_err (void)
3086   -{
3087   - CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
3088   - FORCE_RET();
3089   -}
3090   -
3091 2663 void op_wait (void)
3092 2664 {
3093 2665 env->halted = 1;
... ... @@ -3154,15 +2726,3 @@ void op_dshd(void)
3154 2726 FORCE_RET();
3155 2727 }
3156 2728 #endif
3157   -
3158   -void op_seb(void)
3159   -{
3160   - T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
3161   - FORCE_RET();
3162   -}
3163   -
3164   -void op_seh(void)
3165   -{
3166   - T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
3167   - FORCE_RET();
3168   -}
... ...
target-mips/op_helper.c
... ... @@ -48,6 +48,18 @@ void do_raise_exception (uint32_t exception)
48 48 do_raise_exception_err(exception, 0);
49 49 }
50 50  
  51 +void do_interrupt_restart (void)
  52 +{
  53 + if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
  54 + !(env->CP0_Status & (1 << CP0St_ERL)) &&
  55 + !(env->hflags & MIPS_HFLAG_DM) &&
  56 + (env->CP0_Status & (1 << CP0St_IE)) &&
  57 + (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
  58 + env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
  59 + do_raise_exception(EXCP_EXT_INTERRUPT);
  60 + }
  61 +}
  62 +
51 63 void do_restore_state (void *pc_ptr)
52 64 {
53 65 TranslationBlock *tb;
... ... @@ -59,17 +71,6 @@ void do_restore_state (void *pc_ptr)
59 71 }
60 72 }
61 73  
62   -void do_raise_exception_direct_err (uint32_t exception, int error_code)
63   -{
64   - do_restore_state (GETPC ());
65   - do_raise_exception_err (exception, error_code);
66   -}
67   -
68   -void do_raise_exception_direct (uint32_t exception)
69   -{
70   - do_raise_exception_direct_err (exception, 0);
71   -}
72   -
73 74 #if defined(TARGET_MIPS64)
74 75 #if TARGET_LONG_BITS > HOST_LONG_BITS
75 76 /* Those might call libgcc functions. */
... ... @@ -300,45 +301,6 @@ void do_mulshiu (void)
300 301 }
301 302 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
302 303  
303   -#if HOST_LONG_BITS < 64
304   -void do_div (void)
305   -{
306   - /* 64bit datatypes because we may see overflow/underflow. */
307   - if (T1 != 0) {
308   - env->LO[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
309   - env->HI[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
310   - }
311   -}
312   -#endif
313   -
314   -#if defined(TARGET_MIPS64)
315   -void do_ddiv (void)
316   -{
317   - if (T1 != 0) {
318   - int64_t arg0 = (int64_t)T0;
319   - int64_t arg1 = (int64_t)T1;
320   - if (arg0 == ((int64_t)-1 << 63) && arg1 == (int64_t)-1) {
321   - env->LO[env->current_tc][0] = arg0;
322   - env->HI[env->current_tc][0] = 0;
323   - } else {
324   - lldiv_t res = lldiv(arg0, arg1);
325   - env->LO[env->current_tc][0] = res.quot;
326   - env->HI[env->current_tc][0] = res.rem;
327   - }
328   - }
329   -}
330   -
331   -#if TARGET_LONG_BITS > HOST_LONG_BITS
332   -void do_ddivu (void)
333   -{
334   - if (T1 != 0) {
335   - env->LO[env->current_tc][0] = T0 / T1;
336   - env->HI[env->current_tc][0] = T0 % T1;
337   - }
338   -}
339   -#endif
340   -#endif /* TARGET_MIPS64 */
341   -
342 304 #if defined(CONFIG_USER_ONLY)
343 305 void do_mfc0_random (void)
344 306 {
... ...
target-mips/translate.c
... ... @@ -29,6 +29,7 @@
29 29 #include "cpu.h"
30 30 #include "exec-all.h"
31 31 #include "disas.h"
  32 +#include "helper.h"
32 33 #include "tcg-op.h"
33 34 #include "qemu-common.h"
34 35  
... ... @@ -833,40 +834,47 @@ static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
833 834 }
834 835  
835 836 static always_inline void
836   -generate_tcg_exception_err (DisasContext *ctx, int excp, int err)
  837 +generate_exception_err (DisasContext *ctx, int excp, int err)
837 838 {
838 839 save_cpu_state(ctx, 1);
839   - if (err == 0)
840   - gen_op_raise_exception(excp);
841   - else
842   - gen_op_raise_exception_err(excp, err);
843   - gen_op_interrupt_restart();
  840 + tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
  841 + tcg_gen_helper_0_0(do_interrupt_restart);
844 842 tcg_gen_exit_tb(0);
845 843 }
846 844  
847 845 static always_inline void
848   -generate_tcg_exception (DisasContext *ctx, int excp)
  846 +generate_exception (DisasContext *ctx, int excp)
849 847 {
850   - generate_tcg_exception_err (ctx, excp, 0);
851   -}
852   -
853   -static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
854   -{
855   -#if defined MIPS_DEBUG_DISAS
856   - if (loglevel & CPU_LOG_TB_IN_ASM)
857   - fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
858   -#endif
859 848 save_cpu_state(ctx, 1);
860   - if (err == 0)
861   - gen_op_raise_exception(excp);
862   - else
863   - gen_op_raise_exception_err(excp, err);
864   - ctx->bstate = BS_EXCP;
  849 + tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
  850 + tcg_gen_helper_0_0(do_interrupt_restart);
  851 + tcg_gen_exit_tb(0);
865 852 }
866 853  
867   -static always_inline void generate_exception (DisasContext *ctx, int excp)
  854 +/* Addresses computation */
  855 +static inline void gen_op_addr_add (void)
868 856 {
869   - generate_exception_err (ctx, excp, 0);
  857 + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  858 +
  859 +#if defined(TARGET_MIPS64)
  860 + /* For compatibility with 32-bit code, data reference in user mode
  861 + with Status_UX = 0 should be casted to 32-bit and sign extended.
  862 + See the MIPS64 PRA manual, section 4.10. */
  863 + {
  864 + TCGv r_tmp = new_tmp();
  865 + int l1 = gen_new_label();
  866 +
  867 + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
  868 + tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
  869 + tcg_gen_brcond_i32(TCG_COND_NE, r_tmp, tcg_const_i32(MIPS_HFLAG_UM), l1);
  870 + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
  871 + tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
  872 + tcg_gen_brcond_i32(TCG_COND_NE, r_tmp, tcg_const_i32(0), l1);
  873 + tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
  874 + gen_set_label(l1);
  875 + dead_tmp(r_tmp);
  876 + }
  877 +#endif
870 878 }
871 879  
872 880 static always_inline void check_cp0_enabled(DisasContext *ctx)
... ... @@ -1024,7 +1032,7 @@ void inline op_ldst_##insn(DisasContext *ctx) \
1024 1032 tcg_gen_andi_tl(r_tmp, cpu_T[0], almask); \
1025 1033 tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1); \
1026 1034 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1027   - generate_tcg_exception(ctx, EXCP_AdES); \
  1035 + generate_exception(ctx, EXCP_AdES); \
1028 1036 gen_set_label(l1); \
1029 1037 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \
1030 1038 tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2); \
... ... @@ -1282,12 +1290,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1282 1290 case OPC_SLTI:
1283 1291 case OPC_SLTIU:
1284 1292 uimm = (target_long)imm; /* Sign extend to 32/64 bits */
  1293 + GEN_LOAD_IMM_TN(T1, uimm);
1285 1294 /* Fall through. */
1286 1295 case OPC_ANDI:
1287 1296 case OPC_ORI:
1288 1297 case OPC_XORI:
1289 1298 GEN_LOAD_REG_T0(rs);
1290   - GEN_LOAD_IMM_TN(T1, uimm);
1291 1299 break;
1292 1300 case OPC_LUI:
1293 1301 GEN_LOAD_IMM_TN(T0, imm << 16);
... ... @@ -1305,27 +1313,64 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1305 1313 #endif
1306 1314 uimm &= 0x1f;
1307 1315 GEN_LOAD_REG_T0(rs);
1308   - GEN_LOAD_IMM_TN(T1, uimm);
1309 1316 break;
1310 1317 }
1311 1318 switch (opc) {
1312 1319 case OPC_ADDI:
1313   - save_cpu_state(ctx, 1);
1314   - gen_op_addo();
  1320 + {
  1321 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1322 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1323 + int l1 = gen_new_label();
  1324 +
  1325 + save_cpu_state(ctx, 1);
  1326 + tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
  1327 + tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
  1328 +
  1329 + tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
  1330 + tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
  1331 + tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
  1332 + tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
  1333 + tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
  1334 + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
  1335 + /* operands of same sign, result different sign */
  1336 + generate_exception(ctx, EXCP_OVERFLOW);
  1337 + gen_set_label(l1);
  1338 +
  1339 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1340 + }
1315 1341 opn = "addi";
1316 1342 break;
1317 1343 case OPC_ADDIU:
1318   - gen_op_add();
  1344 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1345 + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
  1346 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1319 1347 opn = "addiu";
1320 1348 break;
1321 1349 #if defined(TARGET_MIPS64)
1322 1350 case OPC_DADDI:
1323   - save_cpu_state(ctx, 1);
1324   - gen_op_daddo();
  1351 + {
  1352 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1353 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1354 + int l1 = gen_new_label();
  1355 +
  1356 + save_cpu_state(ctx, 1);
  1357 + tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
  1358 + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
  1359 +
  1360 + tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
  1361 + tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
  1362 + tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
  1363 + tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
  1364 + tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
  1365 + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
  1366 + /* operands of same sign, result different sign */
  1367 + generate_exception(ctx, EXCP_OVERFLOW);
  1368 + gen_set_label(l1);
  1369 + }
1325 1370 opn = "daddi";
1326 1371 break;
1327 1372 case OPC_DADDIU:
1328   - gen_op_dadd();
  1373 + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1329 1374 opn = "daddiu";
1330 1375 break;
1331 1376 #endif
... ... @@ -1338,41 +1383,62 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1338 1383 opn = "sltiu";
1339 1384 break;
1340 1385 case OPC_ANDI:
1341   - gen_op_and();
  1386 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1342 1387 opn = "andi";
1343 1388 break;
1344 1389 case OPC_ORI:
1345   - gen_op_or();
  1390 + tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1346 1391 opn = "ori";
1347 1392 break;
1348 1393 case OPC_XORI:
1349   - gen_op_xor();
  1394 + tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1350 1395 opn = "xori";
1351 1396 break;
1352 1397 case OPC_LUI:
1353 1398 opn = "lui";
1354 1399 break;
1355 1400 case OPC_SLL:
1356   - gen_op_sll();
  1401 + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
  1402 + tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
  1403 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1357 1404 opn = "sll";
1358 1405 break;
1359 1406 case OPC_SRA:
1360   - gen_op_sra();
  1407 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1408 + tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
  1409 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1361 1410 opn = "sra";
1362 1411 break;
1363 1412 case OPC_SRL:
1364 1413 switch ((ctx->opcode >> 21) & 0x1f) {
1365 1414 case 0:
1366   - gen_op_srl();
  1415 + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
  1416 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
  1417 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1367 1418 opn = "srl";
1368 1419 break;
1369 1420 case 1:
1370 1421 /* rotr is decoded as srl on non-R2 CPUs */
1371 1422 if (env->insn_flags & ISA_MIPS32R2) {
1372   - gen_op_rotr();
  1423 + if (uimm != 0) {
  1424 + TCGv r_tmp1 = new_tmp();
  1425 + TCGv r_tmp2 = new_tmp();
  1426 +
  1427 + tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
  1428 + tcg_gen_movi_i32(r_tmp2, 0x20);
  1429 + tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
  1430 + tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
  1431 + tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
  1432 + tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
  1433 + tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
  1434 + dead_tmp(r_tmp1);
  1435 + dead_tmp(r_tmp2);
  1436 + }
1373 1437 opn = "rotr";
1374 1438 } else {
1375   - gen_op_srl();
  1439 + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
  1440 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
  1441 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1376 1442 opn = "srl";
1377 1443 }
1378 1444 break;
... ... @@ -1384,26 +1450,34 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1384 1450 break;
1385 1451 #if defined(TARGET_MIPS64)
1386 1452 case OPC_DSLL:
1387   - gen_op_dsll();
  1453 + tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1388 1454 opn = "dsll";
1389 1455 break;
1390 1456 case OPC_DSRA:
1391   - gen_op_dsra();
  1457 + tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1392 1458 opn = "dsra";
1393 1459 break;
1394 1460 case OPC_DSRL:
1395 1461 switch ((ctx->opcode >> 21) & 0x1f) {
1396 1462 case 0:
1397   - gen_op_dsrl();
  1463 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1398 1464 opn = "dsrl";
1399 1465 break;
1400 1466 case 1:
1401 1467 /* drotr is decoded as dsrl on non-R2 CPUs */
1402 1468 if (env->insn_flags & ISA_MIPS32R2) {
1403   - gen_op_drotr();
  1469 + if (uimm != 0) {
  1470 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1471 +
  1472 + tcg_gen_movi_tl(r_tmp1, 0x40);
  1473 + tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
  1474 + tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
  1475 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
  1476 + tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
  1477 + }
1404 1478 opn = "drotr";
1405 1479 } else {
1406   - gen_op_dsrl();
  1480 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1407 1481 opn = "dsrl";
1408 1482 }
1409 1483 break;
... ... @@ -1414,26 +1488,35 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1414 1488 }
1415 1489 break;
1416 1490 case OPC_DSLL32:
1417   - gen_op_dsll32();
  1491 + tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1418 1492 opn = "dsll32";
1419 1493 break;
1420 1494 case OPC_DSRA32:
1421   - gen_op_dsra32();
  1495 + tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1422 1496 opn = "dsra32";
1423 1497 break;
1424 1498 case OPC_DSRL32:
1425 1499 switch ((ctx->opcode >> 21) & 0x1f) {
1426 1500 case 0:
1427   - gen_op_dsrl32();
  1501 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1428 1502 opn = "dsrl32";
1429 1503 break;
1430 1504 case 1:
1431 1505 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1432 1506 if (env->insn_flags & ISA_MIPS32R2) {
1433   - gen_op_drotr32();
  1507 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1508 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1509 +
  1510 + tcg_gen_movi_tl(r_tmp1, 0x40);
  1511 + tcg_gen_movi_tl(r_tmp2, 32);
  1512 + tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
  1513 + tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
  1514 + tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
  1515 + tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
  1516 + tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1434 1517 opn = "drotr32";
1435 1518 } else {
1436   - gen_op_dsrl32();
  1519 + tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1437 1520 opn = "dsrl32";
1438 1521 }
1439 1522 break;
... ... @@ -1476,40 +1559,118 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1476 1559 GEN_LOAD_REG_T1(rt);
1477 1560 switch (opc) {
1478 1561 case OPC_ADD:
1479   - save_cpu_state(ctx, 1);
1480   - gen_op_addo();
  1562 + {
  1563 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1564 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1565 + int l1 = gen_new_label();
  1566 +
  1567 + save_cpu_state(ctx, 1);
  1568 + tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
  1569 + tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
  1570 + tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
  1571 +
  1572 + tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
  1573 + tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
  1574 + tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
  1575 + tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
  1576 + tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
  1577 + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
  1578 + /* operands of same sign, result different sign */
  1579 + generate_exception(ctx, EXCP_OVERFLOW);
  1580 + gen_set_label(l1);
  1581 +
  1582 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1583 + }
1481 1584 opn = "add";
1482 1585 break;
1483 1586 case OPC_ADDU:
1484   - gen_op_add();
  1587 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1588 + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
  1589 + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  1590 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1485 1591 opn = "addu";
1486 1592 break;
1487 1593 case OPC_SUB:
1488   - save_cpu_state(ctx, 1);
1489   - gen_op_subo();
  1594 + {
  1595 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1596 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1597 + int l1 = gen_new_label();
  1598 +
  1599 + save_cpu_state(ctx, 1);
  1600 + tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
  1601 + tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
  1602 + tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
  1603 +
  1604 + tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
  1605 + tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
  1606 + tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
  1607 + tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
  1608 + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
  1609 + /* operands of different sign, first operand and result different sign */
  1610 + generate_exception(ctx, EXCP_OVERFLOW);
  1611 + gen_set_label(l1);
  1612 +
  1613 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1614 + }
1490 1615 opn = "sub";
1491 1616 break;
1492 1617 case OPC_SUBU:
1493   - gen_op_sub();
  1618 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1619 + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
  1620 + tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  1621 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1494 1622 opn = "subu";
1495 1623 break;
1496 1624 #if defined(TARGET_MIPS64)
1497 1625 case OPC_DADD:
1498   - save_cpu_state(ctx, 1);
1499   - gen_op_daddo();
  1626 + {
  1627 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1628 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1629 + int l1 = gen_new_label();
  1630 +
  1631 + save_cpu_state(ctx, 1);
  1632 + tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
  1633 + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  1634 +
  1635 + tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
  1636 + tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
  1637 + tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
  1638 + tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
  1639 + tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
  1640 + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
  1641 + /* operands of same sign, result different sign */
  1642 + generate_exception(ctx, EXCP_OVERFLOW);
  1643 + gen_set_label(l1);
  1644 + }
1500 1645 opn = "dadd";
1501 1646 break;
1502 1647 case OPC_DADDU:
1503   - gen_op_dadd();
  1648 + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1504 1649 opn = "daddu";
1505 1650 break;
1506 1651 case OPC_DSUB:
1507   - save_cpu_state(ctx, 1);
1508   - gen_op_dsubo();
  1652 + {
  1653 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1654 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
  1655 + int l1 = gen_new_label();
  1656 +
  1657 + save_cpu_state(ctx, 1);
  1658 + tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
  1659 + tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  1660 +
  1661 + tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
  1662 + tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
  1663 + tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
  1664 + tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
  1665 + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
  1666 + /* operands of different sign, first operand and result different sign */
  1667 + generate_exception(ctx, EXCP_OVERFLOW);
  1668 + gen_set_label(l1);
  1669 + }
1509 1670 opn = "dsub";
1510 1671 break;
1511 1672 case OPC_DSUBU:
1512   - gen_op_dsub();
  1673 + tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1513 1674 opn = "dsubu";
1514 1675 break;
1515 1676 #endif
... ... @@ -1522,23 +1683,27 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1522 1683 opn = "sltu";
1523 1684 break;
1524 1685 case OPC_AND:
1525   - gen_op_and();
  1686 + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1526 1687 opn = "and";
1527 1688 break;
1528 1689 case OPC_NOR:
1529   - gen_op_nor();
  1690 + tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  1691 + tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1530 1692 opn = "nor";
1531 1693 break;
1532 1694 case OPC_OR:
1533   - gen_op_or();
  1695 + tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1534 1696 opn = "or";
1535 1697 break;
1536 1698 case OPC_XOR:
1537   - gen_op_xor();
  1699 + tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1538 1700 opn = "xor";
1539 1701 break;
1540 1702 case OPC_MUL:
1541   - gen_op_mul();
  1703 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
  1704 + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
  1705 + tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  1706 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1542 1707 opn = "mul";
1543 1708 break;
1544 1709 case OPC_MOVN:
... ... @@ -1550,26 +1715,64 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1550 1715 opn = "movz";
1551 1716 goto print;
1552 1717 case OPC_SLLV:
1553   - gen_op_sllv();
  1718 + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
  1719 + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
  1720 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
  1721 + tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
  1722 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1554 1723 opn = "sllv";
1555 1724 break;
1556 1725 case OPC_SRAV:
1557   - gen_op_srav();
  1726 + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
  1727 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
  1728 + tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
  1729 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1558 1730 opn = "srav";
1559 1731 break;
1560 1732 case OPC_SRLV:
1561 1733 switch ((ctx->opcode >> 6) & 0x1f) {
1562 1734 case 0:
1563   - gen_op_srlv();
  1735 + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
  1736 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
  1737 + tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
  1738 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1564 1739 opn = "srlv";
1565 1740 break;
1566 1741 case 1:
1567 1742 /* rotrv is decoded as srlv on non-R2 CPUs */
1568 1743 if (env->insn_flags & ISA_MIPS32R2) {
1569   - gen_op_rotrv();
  1744 + int l1 = gen_new_label();
  1745 + int l2 = gen_new_label();
  1746 +
  1747 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
  1748 + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
  1749 + {
  1750 + TCGv r_tmp1 = new_tmp();
  1751 + TCGv r_tmp2 = new_tmp();
  1752 + TCGv r_tmp3 = new_tmp();
  1753 +
  1754 + tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
  1755 + tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
  1756 + tcg_gen_movi_i32(r_tmp3, 0x20);
  1757 + tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
  1758 + tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
  1759 + tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
  1760 + tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
  1761 + tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
  1762 + dead_tmp(r_tmp1);
  1763 + dead_tmp(r_tmp2);
  1764 + dead_tmp(r_tmp3);
  1765 + tcg_gen_br(l2);
  1766 + }
  1767 + gen_set_label(l1);
  1768 + tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
  1769 + gen_set_label(l2);
1570 1770 opn = "rotrv";
1571 1771 } else {
1572   - gen_op_srlv();
  1772 + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
  1773 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
  1774 + tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
  1775 + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1573 1776 opn = "srlv";
1574 1777 }
1575 1778 break;
... ... @@ -1581,26 +1784,47 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1581 1784 break;
1582 1785 #if defined(TARGET_MIPS64)
1583 1786 case OPC_DSLLV:
1584   - gen_op_dsllv();
  1787 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
  1788 + tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1585 1789 opn = "dsllv";
1586 1790 break;
1587 1791 case OPC_DSRAV:
1588   - gen_op_dsrav();
  1792 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
  1793 + tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1589 1794 opn = "dsrav";
1590 1795 break;
1591 1796 case OPC_DSRLV:
1592 1797 switch ((ctx->opcode >> 6) & 0x1f) {
1593 1798 case 0:
1594   - gen_op_dsrlv();
  1799 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
  1800 + tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1595 1801 opn = "dsrlv";
1596 1802 break;
1597 1803 case 1:
1598 1804 /* drotrv is decoded as dsrlv on non-R2 CPUs */
1599 1805 if (env->insn_flags & ISA_MIPS32R2) {
1600   - gen_op_drotrv();
  1806 + int l1 = gen_new_label();
  1807 + int l2 = gen_new_label();
  1808 +
  1809 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
  1810 + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
  1811 + {
  1812 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
  1813 +
  1814 + tcg_gen_movi_tl(r_tmp1, 0x40);
  1815 + tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
  1816 + tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
  1817 + tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
  1818 + tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
  1819 + tcg_gen_br(l2);
  1820 + }
  1821 + gen_set_label(l1);
  1822 + tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
  1823 + gen_set_label(l2);
1601 1824 opn = "drotrv";
1602 1825 } else {
1603   - gen_op_dsrlv();
  1826 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
  1827 + tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1604 1828 opn = "dsrlv";
1605 1829 }
1606 1830 break;
... ... @@ -1669,11 +1893,71 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1669 1893 GEN_LOAD_REG_T1(rt);
1670 1894 switch (opc) {
1671 1895 case OPC_DIV:
1672   - gen_op_div();
  1896 + {
  1897 + int l1 = gen_new_label();
  1898 +
  1899 + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
  1900 + {
  1901 + TCGv r_tmp1 = new_tmp();
  1902 + TCGv r_tmp2 = new_tmp();
  1903 + TCGv r_tmp3 = new_tmp();
  1904 + TCGv r_tc_off = new_tmp();
  1905 + TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
  1906 + TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
  1907 +
  1908 + tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
  1909 + tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
  1910 + tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
  1911 + tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2);
  1912 + tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
  1913 + tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
  1914 + dead_tmp(r_tmp1);
  1915 + dead_tmp(r_tmp2);
  1916 + dead_tmp(r_tmp3);
  1917 + tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
  1918 + tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
  1919 + tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
  1920 + tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
  1921 + tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
  1922 + tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
  1923 + dead_tmp(r_tc_off);
  1924 + }
  1925 + gen_set_label(l1);
  1926 + }
1673 1927 opn = "div";
1674 1928 break;
1675 1929 case OPC_DIVU:
1676   - gen_op_divu();
  1930 + {
  1931 + int l1 = gen_new_label();
  1932 +
  1933 + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
  1934 + {
  1935 + TCGv r_tmp1 = new_tmp();
  1936 + TCGv r_tmp2 = new_tmp();
  1937 + TCGv r_tmp3 = new_tmp();
  1938 + TCGv r_tc_off = new_tmp();
  1939 + TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
  1940 + TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
  1941 +
  1942 + tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
  1943 + tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
  1944 + tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
  1945 + tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
  1946 + tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
  1947 + tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
  1948 + dead_tmp(r_tmp1);
  1949 + dead_tmp(r_tmp2);
  1950 + dead_tmp(r_tmp3);
  1951 + tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
  1952 + tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
  1953 + tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
  1954 + tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
  1955 + tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
  1956 + tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
  1957 + dead_tmp(r_tc_off);
  1958 + }
  1959 + gen_set_label(l1);
  1960 + }
1677 1961 opn = "divu";
1678 1962 break;
1679 1963 case OPC_MULT:
... ... @@ -1686,11 +1970,63 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1686 1970 break;
1687 1971 #if defined(TARGET_MIPS64)
1688 1972 case OPC_DDIV:
1689   - gen_op_ddiv();
  1973 + {
  1974 + int l1 = gen_new_label();
  1975 +
  1976 + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
  1977 + {
  1978 + TCGv r_tc_off = new_tmp();
  1979 + TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
  1980 + TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
  1981 + int l2 = gen_new_label();
  1982 + int l3 = gen_new_label();
  1983 +
  1984 + tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], tcg_const_tl(1ULL << 63), l2);
  1985 + tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[1], tcg_const_tl(-1ULL), l2);
  1986 + tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
  1987 + tcg_gen_movi_tl(cpu_T[1], 0);
  1988 + tcg_gen_br(l3);
  1989 + gen_set_label(l2);
  1990 + tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
  1991 + tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]);
  1992 + gen_set_label(l3);
  1993 +
  1994 + tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
  1995 + tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
  1996 + tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
  1997 + tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
  1998 + tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
  1999 + tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
  2000 + dead_tmp(r_tc_off);
  2001 + }
  2002 + gen_set_label(l1);
  2003 + }
1690 2004 opn = "ddiv";
1691 2005 break;
1692 2006 case OPC_DDIVU:
1693   - gen_op_ddivu();
  2007 + {
  2008 + int l1 = gen_new_label();
  2009 +
  2010 + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
  2011 + {
  2012 + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
  2013 + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
  2014 + TCGv r_tc_off = new_tmp();
  2015 + TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
  2016 + TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
  2017 +
  2018 + tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
  2019 + tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
  2020 + tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
  2021 + tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
  2022 + tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
  2023 + tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
  2024 + tcg_gen_st_tl(r_tmp1, r_ptr, offsetof(CPUState, LO));
  2025 + tcg_gen_st_tl(r_tmp2, r_ptr, offsetof(CPUState, HI));
  2026 + dead_tmp(r_tc_off);
  2027 + }
  2028 + gen_set_label(l1);
  2029 + }
1694 2030 opn = "ddivu";
1695 2031 break;
1696 2032 case OPC_DMULT:
... ... @@ -6424,11 +6760,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6424 6760 break;
6425 6761 case OPC_SEB:
6426 6762 GEN_LOAD_REG_T1(rt);
6427   - gen_op_seb();
  6763 + tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6428 6764 break;
6429 6765 case OPC_SEH:
6430 6766 GEN_LOAD_REG_T1(rt);
6431   - gen_op_seh();
  6767 + tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6432 6768 break;
6433 6769 default: /* Invalid */
6434 6770 MIPS_INVAL("bshfl");
... ... @@ -6837,6 +7173,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6837 7173 num_temps = 0;
6838 7174 memset(temps, 0, sizeof(temps));
6839 7175  
  7176 + num_temps = 0;
  7177 + memset(temps, 0, sizeof(temps));
  7178 +
6840 7179 pc_start = tb->pc;
6841 7180 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6842 7181 ctx.pc = pc_start;
... ... @@ -6915,7 +7254,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6915 7254 } else {
6916 7255 switch (ctx.bstate) {
6917 7256 case BS_STOP:
6918   - gen_op_interrupt_restart();
  7257 + tcg_gen_helper_0_0(do_interrupt_restart);
6919 7258 gen_goto_tb(&ctx, 0, ctx.pc);
6920 7259 break;
6921 7260 case BS_NONE:
... ... @@ -6923,7 +7262,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6923 7262 gen_goto_tb(&ctx, 0, ctx.pc);
6924 7263 break;
6925 7264 case BS_EXCP:
6926   - gen_op_interrupt_restart();
  7265 + tcg_gen_helper_0_0(do_interrupt_restart);
6927 7266 tcg_gen_exit_tb(0);
6928 7267 break;
6929 7268 case BS_BRANCH:
... ...
tcg/tcg-op.h
... ... @@ -1553,8 +1553,12 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
1553 1553 #endif
1554 1554  
1555 1555 #if TCG_TARGET_REG_BITS == 32
  1556 +#define tcg_gen_add_ptr tcg_gen_add_i32
1556 1557 #define tcg_gen_addi_ptr tcg_gen_addi_i32
  1558 +#define tcg_gen_ext_i32_ptr tcg_gen_mov_i32
1557 1559 #else /* TCG_TARGET_REG_BITS == 32 */
  1560 +#define tcg_gen_add_ptr tcg_gen_add_i64
1558 1561 #define tcg_gen_addi_ptr tcg_gen_addi_i64
  1562 +#define tcg_gen_ext_i32_ptr tcg_gen_ext_i32_i64
1559 1563 #endif /* TCG_TARGET_REG_BITS != 32 */
1560 1564  
... ...