]> Git Repo - qemu.git/blob - target-sh4/op_helper.c
target-sh4: add ftrv instruction
[qemu.git] / target-sh4 / op_helper.c
1 /*
2  *  SH4 emulation
3  *
4  *  Copyright (c) 2005 Samuel Tardieu
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <assert.h>
20 #include <stdlib.h>
21 #include "exec.h"
22 #include "helper.h"
23
24 static void cpu_restore_state_from_retaddr(void *retaddr)
25 {
26     TranslationBlock *tb;
27     unsigned long pc;
28
29     if (retaddr) {
30         pc = (unsigned long) retaddr;
31         tb = tb_find_pc(pc);
32         if (tb) {
33             /* the PC is inside the translated code. It means that we have
34                a virtual CPU fault */
35             cpu_restore_state(tb, env, pc, NULL);
36         }
37     }
38 }
39
40 #ifndef CONFIG_USER_ONLY
41
42 #define MMUSUFFIX _mmu
43
44 #define SHIFT 0
45 #include "softmmu_template.h"
46
47 #define SHIFT 1
48 #include "softmmu_template.h"
49
50 #define SHIFT 2
51 #include "softmmu_template.h"
52
53 #define SHIFT 3
54 #include "softmmu_template.h"
55
56 void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
57 {
58     CPUState *saved_env;
59     int ret;
60
61     /* XXX: hack to restore env in all cases, even if not called from
62        generated code */
63     saved_env = env;
64     env = cpu_single_env;
65     ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
66     if (ret) {
67         /* now we have a real cpu fault */
68         cpu_restore_state_from_retaddr(retaddr);
69         cpu_loop_exit();
70     }
71     env = saved_env;
72 }
73
74 #endif
75
76 void helper_ldtlb(void)
77 {
78 #ifdef CONFIG_USER_ONLY
79     /* XXXXX */
80     cpu_abort(env, "Unhandled ldtlb");
81 #else
82     cpu_load_tlb(env);
83 #endif
84 }
85
86 void helper_raise_illegal_instruction(void)
87 {
88     env->exception_index = 0x180;
89     cpu_loop_exit();
90 }
91
92 void helper_raise_slot_illegal_instruction(void)
93 {
94     env->exception_index = 0x1a0;
95     cpu_loop_exit();
96 }
97
98 void helper_raise_fpu_disable(void)
99 {
100   env->exception_index = 0x800;
101   cpu_loop_exit();
102 }
103
104 void helper_raise_slot_fpu_disable(void)
105 {
106   env->exception_index = 0x820;
107   cpu_loop_exit();
108 }
109
110 void helper_debug(void)
111 {
112     env->exception_index = EXCP_DEBUG;
113     cpu_loop_exit();
114 }
115
116 void helper_sleep(uint32_t next_pc)
117 {
118     env->halted = 1;
119     env->exception_index = EXCP_HLT;
120     env->pc = next_pc;
121     cpu_loop_exit();
122 }
123
124 void helper_trapa(uint32_t tra)
125 {
126     env->tra = tra << 2;
127     env->exception_index = 0x160;
128     cpu_loop_exit();
129 }
130
131 void helper_movcal(uint32_t address, uint32_t value)
132 {
133     if (cpu_sh4_is_cached (env, address))
134     {
135         memory_content *r = malloc (sizeof(memory_content));
136         r->address = address;
137         r->value = value;
138         r->next = NULL;
139
140         *(env->movcal_backup_tail) = r;
141         env->movcal_backup_tail = &(r->next);
142     }
143 }
144
145 void helper_discard_movcal_backup(void)
146 {
147     memory_content *current = env->movcal_backup;
148
149     while(current)
150     {
151         memory_content *next = current->next;
152         free (current);
153         env->movcal_backup = current = next;
154         if (current == NULL)
155             env->movcal_backup_tail = &(env->movcal_backup);
156     } 
157 }
158
159 void helper_ocbi(uint32_t address)
160 {
161     memory_content **current = &(env->movcal_backup);
162     while (*current)
163     {
164         uint32_t a = (*current)->address;
165         if ((a & ~0x1F) == (address & ~0x1F))
166         {
167             memory_content *next = (*current)->next;
168             stl(a, (*current)->value);
169             
170             if (next == NULL)
171             {
172                 env->movcal_backup_tail = current;
173             }
174
175             free (*current);
176             *current = next;
177             break;
178         }
179     }
180 }
181
182 uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
183 {
184     uint32_t tmp0, tmp1;
185
186     tmp1 = arg0 + arg1;
187     tmp0 = arg1;
188     arg1 = tmp1 + (env->sr & 1);
189     if (tmp0 > tmp1)
190         env->sr |= SR_T;
191     else
192         env->sr &= ~SR_T;
193     if (tmp1 > arg1)
194         env->sr |= SR_T;
195     return arg1;
196 }
197
198 uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
199 {
200     uint32_t dest, src, ans;
201
202     if ((int32_t) arg1 >= 0)
203         dest = 0;
204     else
205         dest = 1;
206     if ((int32_t) arg0 >= 0)
207         src = 0;
208     else
209         src = 1;
210     src += dest;
211     arg1 += arg0;
212     if ((int32_t) arg1 >= 0)
213         ans = 0;
214     else
215         ans = 1;
216     ans += dest;
217     if (src == 0 || src == 2) {
218         if (ans == 1)
219             env->sr |= SR_T;
220         else
221             env->sr &= ~SR_T;
222     } else
223         env->sr &= ~SR_T;
224     return arg1;
225 }
226
227 #define T (env->sr & SR_T)
228 #define Q (env->sr & SR_Q ? 1 : 0)
229 #define M (env->sr & SR_M ? 1 : 0)
230 #define SETT env->sr |= SR_T
231 #define CLRT env->sr &= ~SR_T
232 #define SETQ env->sr |= SR_Q
233 #define CLRQ env->sr &= ~SR_Q
234 #define SETM env->sr |= SR_M
235 #define CLRM env->sr &= ~SR_M
236
237 uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
238 {
239     uint32_t tmp0, tmp2;
240     uint8_t old_q, tmp1 = 0xff;
241
242     //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
243     old_q = Q;
244     if ((0x80000000 & arg1) != 0)
245         SETQ;
246     else
247         CLRQ;
248     tmp2 = arg0;
249     arg1 <<= 1;
250     arg1 |= T;
251     switch (old_q) {
252     case 0:
253         switch (M) {
254         case 0:
255             tmp0 = arg1;
256             arg1 -= tmp2;
257             tmp1 = arg1 > tmp0;
258             switch (Q) {
259             case 0:
260                 if (tmp1)
261                     SETQ;
262                 else
263                     CLRQ;
264                 break;
265             case 1:
266                 if (tmp1 == 0)
267                     SETQ;
268                 else
269                     CLRQ;
270                 break;
271             }
272             break;
273         case 1:
274             tmp0 = arg1;
275             arg1 += tmp2;
276             tmp1 = arg1 < tmp0;
277             switch (Q) {
278             case 0:
279                 if (tmp1 == 0)
280                     SETQ;
281                 else
282                     CLRQ;
283                 break;
284             case 1:
285                 if (tmp1)
286                     SETQ;
287                 else
288                     CLRQ;
289                 break;
290             }
291             break;
292         }
293         break;
294     case 1:
295         switch (M) {
296         case 0:
297             tmp0 = arg1;
298             arg1 += tmp2;
299             tmp1 = arg1 < tmp0;
300             switch (Q) {
301             case 0:
302                 if (tmp1)
303                     SETQ;
304                 else
305                     CLRQ;
306                 break;
307             case 1:
308                 if (tmp1 == 0)
309                     SETQ;
310                 else
311                     CLRQ;
312                 break;
313             }
314             break;
315         case 1:
316             tmp0 = arg1;
317             arg1 -= tmp2;
318             tmp1 = arg1 > tmp0;
319             switch (Q) {
320             case 0:
321                 if (tmp1 == 0)
322                     SETQ;
323                 else
324                     CLRQ;
325                 break;
326             case 1:
327                 if (tmp1)
328                     SETQ;
329                 else
330                     CLRQ;
331                 break;
332             }
333             break;
334         }
335         break;
336     }
337     if (Q == M)
338         SETT;
339     else
340         CLRT;
341     //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
342     return arg1;
343 }
344
345 void helper_macl(uint32_t arg0, uint32_t arg1)
346 {
347     int64_t res;
348
349     res = ((uint64_t) env->mach << 32) | env->macl;
350     res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
351     env->mach = (res >> 32) & 0xffffffff;
352     env->macl = res & 0xffffffff;
353     if (env->sr & SR_S) {
354         if (res < 0)
355             env->mach |= 0xffff0000;
356         else
357             env->mach &= 0x00007fff;
358     }
359 }
360
361 void helper_macw(uint32_t arg0, uint32_t arg1)
362 {
363     int64_t res;
364
365     res = ((uint64_t) env->mach << 32) | env->macl;
366     res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
367     env->mach = (res >> 32) & 0xffffffff;
368     env->macl = res & 0xffffffff;
369     if (env->sr & SR_S) {
370         if (res < -0x80000000) {
371             env->mach = 1;
372             env->macl = 0x80000000;
373         } else if (res > 0x000000007fffffff) {
374             env->mach = 1;
375             env->macl = 0x7fffffff;
376         }
377     }
378 }
379
380 uint32_t helper_negc(uint32_t arg)
381 {
382     uint32_t temp;
383
384     temp = -arg;
385     arg = temp - (env->sr & SR_T);
386     if (0 < temp)
387         env->sr |= SR_T;
388     else
389         env->sr &= ~SR_T;
390     if (temp < arg)
391         env->sr |= SR_T;
392     return arg;
393 }
394
395 uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
396 {
397     uint32_t tmp0, tmp1;
398
399     tmp1 = arg1 - arg0;
400     tmp0 = arg1;
401     arg1 = tmp1 - (env->sr & SR_T);
402     if (tmp0 < tmp1)
403         env->sr |= SR_T;
404     else
405         env->sr &= ~SR_T;
406     if (tmp1 < arg1)
407         env->sr |= SR_T;
408     return arg1;
409 }
410
411 uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
412 {
413     int32_t dest, src, ans;
414
415     if ((int32_t) arg1 >= 0)
416         dest = 0;
417     else
418         dest = 1;
419     if ((int32_t) arg0 >= 0)
420         src = 0;
421     else
422         src = 1;
423     src += dest;
424     arg1 -= arg0;
425     if ((int32_t) arg1 >= 0)
426         ans = 0;
427     else
428         ans = 1;
429     ans += dest;
430     if (src == 1) {
431         if (ans == 1)
432             env->sr |= SR_T;
433         else
434             env->sr &= ~SR_T;
435     } else
436         env->sr &= ~SR_T;
437     return arg1;
438 }
439
440 static inline void set_t(void)
441 {
442     env->sr |= SR_T;
443 }
444
445 static inline void clr_t(void)
446 {
447     env->sr &= ~SR_T;
448 }
449
450 void helper_ld_fpscr(uint32_t val)
451 {
452     env->fpscr = val & FPSCR_MASK;
453     if ((val & FPSCR_RM_MASK) == FPSCR_RM_ZERO) {
454         set_float_rounding_mode(float_round_to_zero, &env->fp_status);
455     } else {
456         set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
457     }
458     set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
459 }
460
461 static void update_fpscr(void *retaddr)
462 {
463     int xcpt, cause, enable;
464
465     xcpt = get_float_exception_flags(&env->fp_status);
466
467     /* Clear the flag entries */
468     env->fpscr &= ~FPSCR_FLAG_MASK;
469
470     if (unlikely(xcpt)) {
471         if (xcpt & float_flag_invalid) {
472             env->fpscr |= FPSCR_FLAG_V;
473         }
474         if (xcpt & float_flag_divbyzero) {
475             env->fpscr |= FPSCR_FLAG_Z;
476         }
477         if (xcpt & float_flag_overflow) {
478             env->fpscr |= FPSCR_FLAG_O;
479         }
480         if (xcpt & float_flag_underflow) {
481             env->fpscr |= FPSCR_FLAG_U;
482         }
483         if (xcpt & float_flag_inexact) {
484             env->fpscr |= FPSCR_FLAG_I;
485         }
486
487         /* Accumulate in cause entries */
488         env->fpscr |= (env->fpscr & FPSCR_FLAG_MASK)
489                       << (FPSCR_CAUSE_SHIFT - FPSCR_FLAG_SHIFT);
490
491         /* Generate an exception if enabled */
492         cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT;
493         enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT;
494         if (cause & enable) {
495             cpu_restore_state_from_retaddr(retaddr);
496             env->exception_index = 0x120;
497             cpu_loop_exit();
498         }
499     }
500 }
501
502 uint32_t helper_fabs_FT(uint32_t t0)
503 {
504     CPU_FloatU f;
505     f.l = t0;
506     f.f = float32_abs(f.f);
507     return f.l;
508 }
509
510 uint64_t helper_fabs_DT(uint64_t t0)
511 {
512     CPU_DoubleU d;
513     d.ll = t0;
514     d.d = float64_abs(d.d);
515     return d.ll;
516 }
517
518 uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1)
519 {
520     CPU_FloatU f0, f1;
521     f0.l = t0;
522     f1.l = t1;
523     set_float_exception_flags(0, &env->fp_status);
524     f0.f = float32_add(f0.f, f1.f, &env->fp_status);
525     update_fpscr(GETPC());
526     return f0.l;
527 }
528
529 uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1)
530 {
531     CPU_DoubleU d0, d1;
532     d0.ll = t0;
533     d1.ll = t1;
534     set_float_exception_flags(0, &env->fp_status);
535     d0.d = float64_add(d0.d, d1.d, &env->fp_status);
536     update_fpscr(GETPC());
537     return d0.ll;
538 }
539
540 void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
541 {
542     CPU_FloatU f0, f1;
543     int relation;
544     f0.l = t0;
545     f1.l = t1;
546
547     set_float_exception_flags(0, &env->fp_status);
548     relation = float32_compare(f0.f, f1.f, &env->fp_status);
549     if (unlikely(relation == float_relation_unordered)) {
550         update_fpscr(GETPC());
551     } else if (relation == float_relation_equal) {
552         set_t();
553     } else {
554         clr_t();
555     }
556 }
557
558 void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
559 {
560     CPU_DoubleU d0, d1;
561     int relation;
562     d0.ll = t0;
563     d1.ll = t1;
564
565     set_float_exception_flags(0, &env->fp_status);
566     relation = float64_compare(d0.d, d1.d, &env->fp_status);
567     if (unlikely(relation == float_relation_unordered)) {
568         update_fpscr(GETPC());
569     } else if (relation == float_relation_equal) {
570         set_t();
571     } else {
572         clr_t();
573     }
574 }
575
576 void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
577 {
578     CPU_FloatU f0, f1;
579     int relation;
580     f0.l = t0;
581     f1.l = t1;
582
583     set_float_exception_flags(0, &env->fp_status);
584     relation = float32_compare(f0.f, f1.f, &env->fp_status);
585     if (unlikely(relation == float_relation_unordered)) {
586         update_fpscr(GETPC());
587     } else if (relation == float_relation_greater) {
588         set_t();
589     } else {
590         clr_t();
591     }
592 }
593
594 void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
595 {
596     CPU_DoubleU d0, d1;
597     int relation;
598     d0.ll = t0;
599     d1.ll = t1;
600
601     set_float_exception_flags(0, &env->fp_status);
602     relation = float64_compare(d0.d, d1.d, &env->fp_status);
603     if (unlikely(relation == float_relation_unordered)) {
604         update_fpscr(GETPC());
605     } else if (relation == float_relation_greater) {
606         set_t();
607     } else {
608         clr_t();
609     }
610 }
611
612 uint64_t helper_fcnvsd_FT_DT(uint32_t t0)
613 {
614     CPU_DoubleU d;
615     CPU_FloatU f;
616     f.l = t0;
617     set_float_exception_flags(0, &env->fp_status);
618     d.d = float32_to_float64(f.f, &env->fp_status);
619     update_fpscr(GETPC());
620     return d.ll;
621 }
622
623 uint32_t helper_fcnvds_DT_FT(uint64_t t0)
624 {
625     CPU_DoubleU d;
626     CPU_FloatU f;
627     d.ll = t0;
628     set_float_exception_flags(0, &env->fp_status);
629     f.f = float64_to_float32(d.d, &env->fp_status);
630     update_fpscr(GETPC());
631     return f.l;
632 }
633
634 uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
635 {
636     CPU_FloatU f0, f1;
637     f0.l = t0;
638     f1.l = t1;
639     set_float_exception_flags(0, &env->fp_status);
640     f0.f = float32_div(f0.f, f1.f, &env->fp_status);
641     update_fpscr(GETPC());
642     return f0.l;
643 }
644
645 uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1)
646 {
647     CPU_DoubleU d0, d1;
648     d0.ll = t0;
649     d1.ll = t1;
650     set_float_exception_flags(0, &env->fp_status);
651     d0.d = float64_div(d0.d, d1.d, &env->fp_status);
652     update_fpscr(GETPC());
653     return d0.ll;
654 }
655
656 uint32_t helper_float_FT(uint32_t t0)
657 {
658     CPU_FloatU f;
659
660     set_float_exception_flags(0, &env->fp_status);
661     f.f = int32_to_float32(t0, &env->fp_status);
662     update_fpscr(GETPC());
663
664     return f.l;
665 }
666
667 uint64_t helper_float_DT(uint32_t t0)
668 {
669     CPU_DoubleU d;
670     set_float_exception_flags(0, &env->fp_status);
671     d.d = int32_to_float64(t0, &env->fp_status);
672     update_fpscr(GETPC());
673     return d.ll;
674 }
675
676 uint32_t helper_fmac_FT(uint32_t t0, uint32_t t1, uint32_t t2)
677 {
678     CPU_FloatU f0, f1, f2;
679     f0.l = t0;
680     f1.l = t1;
681     f2.l = t2;
682     set_float_exception_flags(0, &env->fp_status);
683     f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
684     f0.f = float32_add(f0.f, f2.f, &env->fp_status);
685     update_fpscr(GETPC());
686
687     return f0.l;
688 }
689
690 uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1)
691 {
692     CPU_FloatU f0, f1;
693     f0.l = t0;
694     f1.l = t1;
695     set_float_exception_flags(0, &env->fp_status);
696     f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
697     update_fpscr(GETPC());
698     return f0.l;
699 }
700
701 uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1)
702 {
703     CPU_DoubleU d0, d1;
704     d0.ll = t0;
705     d1.ll = t1;
706     set_float_exception_flags(0, &env->fp_status);
707     d0.d = float64_mul(d0.d, d1.d, &env->fp_status);
708     update_fpscr(GETPC());
709
710     return d0.ll;
711 }
712
713 uint32_t helper_fneg_T(uint32_t t0)
714 {
715     CPU_FloatU f;
716     f.l = t0;
717     f.f = float32_chs(f.f);
718     return f.l;
719 }
720
721 uint32_t helper_fsqrt_FT(uint32_t t0)
722 {
723     CPU_FloatU f;
724     f.l = t0;
725     set_float_exception_flags(0, &env->fp_status);
726     f.f = float32_sqrt(f.f, &env->fp_status);
727     update_fpscr(GETPC());
728     return f.l;
729 }
730
731 uint64_t helper_fsqrt_DT(uint64_t t0)
732 {
733     CPU_DoubleU d;
734     d.ll = t0;
735     set_float_exception_flags(0, &env->fp_status);
736     d.d = float64_sqrt(d.d, &env->fp_status);
737     update_fpscr(GETPC());
738     return d.ll;
739 }
740
741 uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1)
742 {
743     CPU_FloatU f0, f1;
744     f0.l = t0;
745     f1.l = t1;
746     set_float_exception_flags(0, &env->fp_status);
747     f0.f = float32_sub(f0.f, f1.f, &env->fp_status);
748     update_fpscr(GETPC());
749     return f0.l;
750 }
751
752 uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1)
753 {
754     CPU_DoubleU d0, d1;
755
756     d0.ll = t0;
757     d1.ll = t1;
758     set_float_exception_flags(0, &env->fp_status);
759     d0.d = float64_sub(d0.d, d1.d, &env->fp_status);
760     update_fpscr(GETPC());
761     return d0.ll;
762 }
763
764 uint32_t helper_ftrc_FT(uint32_t t0)
765 {
766     CPU_FloatU f;
767     uint32_t ret;
768     f.l = t0;
769     set_float_exception_flags(0, &env->fp_status);
770     ret = float32_to_int32_round_to_zero(f.f, &env->fp_status);
771     update_fpscr(GETPC());
772     return ret;
773 }
774
775 uint32_t helper_ftrc_DT(uint64_t t0)
776 {
777     CPU_DoubleU d;
778     uint32_t ret;
779     d.ll = t0;
780     set_float_exception_flags(0, &env->fp_status);
781     ret = float64_to_int32_round_to_zero(d.d, &env->fp_status);
782     update_fpscr(GETPC());
783     return ret;
784 }
785
786 void helper_fipr(uint32_t m, uint32_t n)
787 {
788     int bank, i;
789     float32 r, p;
790
791     bank = (env->sr & FPSCR_FR) ? 16 : 0;
792     r = float32_zero;
793     set_float_exception_flags(0, &env->fp_status);
794
795     for (i = 0 ; i < 4 ; i++) {
796         p = float32_mul(env->fregs[bank + m + i],
797                         env->fregs[bank + n + i],
798                         &env->fp_status);
799         r = float32_add(r, p, &env->fp_status);
800     }
801     update_fpscr(GETPC());
802
803     env->fregs[bank + n + 3] = r;
804 }
805
806 void helper_ftrv(uint32_t n)
807 {
808     int bank_matrix, bank_vector;
809     int i, j;
810     float32 r[4];
811     float32 p;
812
813     bank_matrix = (env->sr & FPSCR_FR) ? 0 : 16;
814     bank_vector = (env->sr & FPSCR_FR) ? 16 : 0;
815     set_float_exception_flags(0, &env->fp_status);
816     for (i = 0 ; i < 4 ; i++) {
817         r[i] = float32_zero;
818         for (j = 0 ; j < 4 ; j++) {
819             p = float32_mul(env->fregs[bank_matrix + 4 * j + i],
820                             env->fregs[bank_vector + j],
821                             &env->fp_status);
822             r[i] = float32_add(r[i], p, &env->fp_status);
823         }
824     }
825     update_fpscr(GETPC());
826
827     for (i = 0 ; i < 4 ; i++) {
828         env->fregs[bank_vector + i] = r[i];
829     }
830 }
This page took 0.070127 seconds and 4 git commands to generate.