]> git.proxmox.com Git - qemu.git/blob - target-cris/op.c
3ce9888bc07e2d2b590191427f9313fbb40c855c
[qemu.git] / target-cris / op.c
1 /*
2 * CRIS emulation micro-operations for qemu.
3 *
4 * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include "exec.h"
21
22 #define REGNAME r0
23 #define REG (env->regs[0])
24 #include "op_template.h"
25
26 #define REGNAME r1
27 #define REG (env->regs[1])
28 #include "op_template.h"
29
30 #define REGNAME r2
31 #define REG (env->regs[2])
32 #include "op_template.h"
33
34 #define REGNAME r3
35 #define REG (env->regs[3])
36 #include "op_template.h"
37
38 #define REGNAME r4
39 #define REG (env->regs[4])
40 #include "op_template.h"
41
42 #define REGNAME r5
43 #define REG (env->regs[5])
44 #include "op_template.h"
45
46 #define REGNAME r6
47 #define REG (env->regs[6])
48 #include "op_template.h"
49
50 #define REGNAME r7
51 #define REG (env->regs[7])
52 #include "op_template.h"
53
54 #define REGNAME r8
55 #define REG (env->regs[8])
56 #include "op_template.h"
57
58 #define REGNAME r9
59 #define REG (env->regs[9])
60 #include "op_template.h"
61
62 #define REGNAME r10
63 #define REG (env->regs[10])
64 #include "op_template.h"
65
66 #define REGNAME r11
67 #define REG (env->regs[11])
68 #include "op_template.h"
69
70 #define REGNAME r12
71 #define REG (env->regs[12])
72 #include "op_template.h"
73
74 #define REGNAME r13
75 #define REG (env->regs[13])
76 #include "op_template.h"
77
78 #define REGNAME r14
79 #define REG (env->regs[14])
80 #include "op_template.h"
81
82 #define REGNAME r15
83 #define REG (env->regs[15])
84 #include "op_template.h"
85
86
87 #define REGNAME p0
88 #define REG (env->pregs[0])
89 #include "op_template.h"
90
91 #define REGNAME p1
92 #define REG (env->pregs[1])
93 #include "op_template.h"
94
95 #define REGNAME p2
96 #define REG (env->pregs[2])
97 #include "op_template.h"
98
99 #define REGNAME p3
100 #define REG (env->pregs[3])
101 #include "op_template.h"
102
103 #define REGNAME p4
104 #define REG (env->pregs[4])
105 #include "op_template.h"
106
107 #define REGNAME p5
108 #define REG (env->pregs[5])
109 #include "op_template.h"
110
111 #define REGNAME p6
112 #define REG (env->pregs[6])
113 #include "op_template.h"
114
115 #define REGNAME p7
116 #define REG (env->pregs[7])
117 #include "op_template.h"
118
119 #define REGNAME p8
120 #define REG (env->pregs[8])
121 #include "op_template.h"
122
123 #define REGNAME p9
124 #define REG (env->pregs[9])
125 #include "op_template.h"
126
127 #define REGNAME p10
128 #define REG (env->pregs[10])
129 #include "op_template.h"
130
131 #define REGNAME p11
132 #define REG (env->pregs[11])
133 #include "op_template.h"
134
135 #define REGNAME p12
136 #define REG (env->pregs[12])
137 #include "op_template.h"
138
139 #define REGNAME p13
140 #define REG (env->pregs[13])
141 #include "op_template.h"
142
143 #define REGNAME p14
144 #define REG (env->pregs[14])
145 #include "op_template.h"
146
147 #define REGNAME p15
148 #define REG (env->pregs[15])
149 #include "op_template.h"
150
151 /* Microcode. */
152
153 void OPPROTO op_exit_tb (void)
154 {
155 EXIT_TB();
156 }
157
158 void OPPROTO op_goto_tb0 (void)
159 {
160 GOTO_TB(op_goto_tb0, PARAM1, 0);
161 RETURN();
162 }
163
164 void OPPROTO op_goto_tb1 (void)
165 {
166 GOTO_TB(op_goto_tb1, PARAM1, 1);
167 RETURN();
168 }
169
170 void OPPROTO op_break_im(void)
171 {
172 env->trapnr = PARAM1;
173 env->exception_index = EXCP_BREAK;
174 cpu_loop_exit();
175 }
176
177 void OPPROTO op_debug(void)
178 {
179 env->exception_index = EXCP_DEBUG;
180 cpu_loop_exit();
181 }
182
183 void OPPROTO op_exec_insn(void)
184 {
185 env->stats.exec_insns++;
186 RETURN();
187 }
188 void OPPROTO op_exec_load(void)
189 {
190 env->stats.exec_loads++;
191 RETURN();
192 }
193 void OPPROTO op_exec_store(void)
194 {
195 env->stats.exec_stores++;
196 RETURN();
197 }
198
199 void OPPROTO op_ccs_lshift (void)
200 {
201 uint32_t ccs;
202
203 /* Apply the ccs shift. */
204 ccs = env->pregs[SR_CCS];
205 ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
206 env->pregs[SR_CCS] = ccs;
207 }
208 void OPPROTO op_ccs_rshift (void)
209 {
210 uint32_t ccs;
211
212 /* Apply the ccs shift. */
213 ccs = env->pregs[SR_CCS];
214 ccs = (ccs & 0xc0000000) | (ccs >> 10);
215 env->pregs[SR_CCS] = ccs;
216 }
217
218 void OPPROTO op_setf (void)
219 {
220 env->pregs[SR_CCS] |= PARAM1;
221 RETURN();
222 }
223
224 void OPPROTO op_clrf (void)
225 {
226 env->pregs[SR_CCS] &= ~PARAM1;
227 RETURN();
228 }
229
230 void OPPROTO op_movl_debug1_T0 (void)
231 {
232 env->debug1 = T0;
233 RETURN();
234 }
235
236 void OPPROTO op_movl_debug2_T0 (void)
237 {
238 env->debug2 = T0;
239 RETURN();
240 }
241
242 void OPPROTO op_movl_debug3_T0 (void)
243 {
244 env->debug3 = T0;
245 RETURN();
246 }
247 void OPPROTO op_movl_debug1_T1 (void)
248 {
249 env->debug1 = T1;
250 RETURN();
251 }
252
253 void OPPROTO op_movl_debug2_T1 (void)
254 {
255 env->debug2 = T1;
256 RETURN();
257 }
258
259 void OPPROTO op_movl_debug3_T1 (void)
260 {
261 env->debug3 = T1;
262 RETURN();
263 }
264 void OPPROTO op_movl_debug3_im (void)
265 {
266 env->debug3 = PARAM1;
267 RETURN();
268 }
269 void OPPROTO op_movl_T0_flags (void)
270 {
271 T0 = env->pregs[SR_CCS];
272 RETURN();
273 }
274 void OPPROTO op_movl_flags_T0 (void)
275 {
276 env->pregs[SR_CCS] = T0;
277 RETURN();
278 }
279
280 void OPPROTO op_movl_sreg_T0 (void)
281 {
282 env->sregs[env->pregs[SR_SRS]][PARAM1] = T0;
283 RETURN();
284 }
285
286 void OPPROTO op_movl_tlb_lo_T0 (void)
287 {
288 int srs;
289 srs = env->pregs[SR_SRS];
290 if (srs == 1 || srs == 2)
291 {
292 int set;
293 int idx;
294 uint32_t lo, hi;
295
296 idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
297 set >>= 4;
298 set &= 3;
299
300 idx &= 31;
301 /* We've just made a write to tlb_lo. */
302 lo = env->sregs[SFR_RW_MM_TLB_LO];
303 hi = env->sregs[SFR_RW_MM_TLB_HI];
304 env->tlbsets[srs - 1][set][idx].lo = lo;
305 env->tlbsets[srs - 1][set][idx].hi = hi;
306 }
307
308 RETURN();
309 }
310
311 void OPPROTO op_movl_T0_sreg (void)
312 {
313 T0 = env->sregs[env->pregs[SR_SRS]][PARAM1];
314 RETURN();
315 }
316
317 void OPPROTO op_update_cc (void)
318 {
319 env->cc_op = PARAM1;
320 env->cc_dest = PARAM2;
321 env->cc_src = PARAM3;
322 RETURN();
323 }
324
325 void OPPROTO op_update_cc_op (void)
326 {
327 env->cc_op = PARAM1;
328 RETURN();
329 }
330
331 void OPPROTO op_update_cc_mask (void)
332 {
333 env->cc_mask = PARAM1;
334 RETURN();
335 }
336
337 void OPPROTO op_update_cc_dest_T0 (void)
338 {
339 env->cc_dest = T0;
340 RETURN();
341 }
342
343 void OPPROTO op_update_cc_result_T0 (void)
344 {
345 env->cc_result = T0;
346 RETURN();
347 }
348
349 void OPPROTO op_update_cc_size_im (void)
350 {
351 env->cc_size = PARAM1;
352 RETURN();
353 }
354
355 void OPPROTO op_update_cc_src_T1 (void)
356 {
357 env->cc_src = T1;
358 RETURN();
359 }
360 void OPPROTO op_update_cc_x (void)
361 {
362 env->cc_x_live = PARAM1;
363 env->cc_x = PARAM2;
364 RETURN();
365 }
366
367 /* FIXME: is this allowed? */
368 extern inline void evaluate_flags_writeback(uint32_t flags)
369 {
370 int x;
371
372 /* Extended arithmetics, leave the z flag alone. */
373 env->debug3 = env->pregs[SR_CCS];
374
375 if (env->cc_x_live)
376 x = env->cc_x;
377 else
378 x = env->pregs[SR_CCS] & X_FLAG;
379
380 if ((x || env->cc_op == CC_OP_ADDC)
381 && flags & Z_FLAG)
382 env->cc_mask &= ~Z_FLAG;
383
384 /* all insn clear the x-flag except setf or clrf. */
385 env->pregs[SR_CCS] &= ~(env->cc_mask | X_FLAG);
386 flags &= env->cc_mask;
387 env->pregs[SR_CCS] |= flags;
388 RETURN();
389 }
390
391 void OPPROTO op_evaluate_flags_muls(void)
392 {
393 uint32_t src;
394 uint32_t dst;
395 uint32_t res;
396 uint32_t flags = 0;
397 /* were gonna have to redo the muls. */
398 int64_t tmp, t0 ,t1;
399 int32_t mof;
400 int dneg;
401
402 src = env->cc_src;
403 dst = env->cc_dest;
404 res = env->cc_result;
405
406
407 /* cast into signed values to make GCC sign extend. */
408 t0 = (int32_t)src;
409 t1 = (int32_t)dst;
410 dneg = ((int32_t)res) < 0;
411
412 tmp = t0 * t1;
413 mof = tmp >> 32;
414 if (tmp == 0)
415 flags |= Z_FLAG;
416 else if (tmp < 0)
417 flags |= N_FLAG;
418 if ((dneg && mof != -1)
419 || (!dneg && mof != 0))
420 flags |= V_FLAG;
421 evaluate_flags_writeback(flags);
422 RETURN();
423 }
424
425 void OPPROTO op_evaluate_flags_mulu(void)
426 {
427 uint32_t src;
428 uint32_t dst;
429 uint32_t res;
430 uint32_t flags = 0;
431 /* were gonna have to redo the muls. */
432 uint64_t tmp, t0 ,t1;
433 uint32_t mof;
434
435 src = env->cc_src;
436 dst = env->cc_dest;
437 res = env->cc_result;
438
439
440 /* cast into signed values to make GCC sign extend. */
441 t0 = src;
442 t1 = dst;
443
444 tmp = t0 * t1;
445 mof = tmp >> 32;
446 if (tmp == 0)
447 flags |= Z_FLAG;
448 else if (tmp >> 63)
449 flags |= N_FLAG;
450 if (mof)
451 flags |= V_FLAG;
452
453 evaluate_flags_writeback(flags);
454 RETURN();
455 }
456
457 void OPPROTO op_evaluate_flags_mcp(void)
458 {
459 uint32_t src;
460 uint32_t dst;
461 uint32_t res;
462 uint32_t flags = 0;
463
464 src = env->cc_src;
465 dst = env->cc_dest;
466 res = env->cc_result;
467
468 if ((res & 0x80000000L) != 0L)
469 {
470 flags |= N_FLAG;
471 if (((src & 0x80000000L) == 0L)
472 && ((dst & 0x80000000L) == 0L))
473 {
474 flags |= V_FLAG;
475 }
476 else if (((src & 0x80000000L) != 0L) &&
477 ((dst & 0x80000000L) != 0L))
478 {
479 flags |= R_FLAG;
480 }
481 }
482 else
483 {
484 if (res == 0L)
485 flags |= Z_FLAG;
486 if (((src & 0x80000000L) != 0L)
487 && ((dst & 0x80000000L) != 0L))
488 flags |= V_FLAG;
489 if ((dst & 0x80000000L) != 0L
490 || (src & 0x80000000L) != 0L)
491 flags |= R_FLAG;
492 }
493
494 evaluate_flags_writeback(flags);
495 RETURN();
496 }
497
498 void OPPROTO op_evaluate_flags_alu_4(void)
499 {
500 uint32_t src;
501 uint32_t dst;
502 uint32_t res;
503 uint32_t flags = 0;
504
505 src = env->cc_src;
506 dst = env->cc_dest;
507 res = env->cc_result;
508
509 if ((res & 0x80000000L) != 0L)
510 {
511 flags |= N_FLAG;
512 if (((src & 0x80000000L) == 0L)
513 && ((dst & 0x80000000L) == 0L))
514 {
515 flags |= V_FLAG;
516 }
517 else if (((src & 0x80000000L) != 0L) &&
518 ((dst & 0x80000000L) != 0L))
519 {
520 flags |= C_FLAG;
521 }
522 }
523 else
524 {
525 if (res == 0L)
526 flags |= Z_FLAG;
527 if (((src & 0x80000000L) != 0L)
528 && ((dst & 0x80000000L) != 0L))
529 flags |= V_FLAG;
530 if ((dst & 0x80000000L) != 0L
531 || (src & 0x80000000L) != 0L)
532 flags |= C_FLAG;
533 }
534
535 if (env->cc_op == CC_OP_SUB
536 || env->cc_op == CC_OP_CMP) {
537 flags ^= C_FLAG;
538 }
539 evaluate_flags_writeback(flags);
540 RETURN();
541 }
542
543 void OPPROTO op_evaluate_flags_move_4 (void)
544 {
545 uint32_t src;
546 uint32_t res;
547 uint32_t flags = 0;
548
549 src = env->cc_src;
550 res = env->cc_result;
551
552 if ((int32_t)res < 0)
553 flags |= N_FLAG;
554 else if (res == 0L)
555 flags |= Z_FLAG;
556
557 evaluate_flags_writeback(flags);
558 RETURN();
559 }
560 void OPPROTO op_evaluate_flags_move_2 (void)
561 {
562 uint32_t src;
563 uint32_t flags = 0;
564 uint16_t res;
565
566 src = env->cc_src;
567 res = env->cc_result;
568
569 if ((int16_t)res < 0L)
570 flags |= N_FLAG;
571 else if (res == 0)
572 flags |= Z_FLAG;
573
574 evaluate_flags_writeback(flags);
575 RETURN();
576 }
577
578 /* TODO: This is expensive. We could split things up and only evaluate part of
579 CCR on a need to know basis. For now, we simply re-evaluate everything. */
580 void OPPROTO op_evaluate_flags (void)
581 {
582 uint32_t src;
583 uint32_t dst;
584 uint32_t res;
585 uint32_t flags = 0;
586
587 src = env->cc_src;
588 dst = env->cc_dest;
589 res = env->cc_result;
590
591
592 /* Now, evaluate the flags. This stuff is based on
593 Per Zander's CRISv10 simulator. */
594 switch (env->cc_size)
595 {
596 case 1:
597 if ((res & 0x80L) != 0L)
598 {
599 flags |= N_FLAG;
600 if (((src & 0x80L) == 0L)
601 && ((dst & 0x80L) == 0L))
602 {
603 flags |= V_FLAG;
604 }
605 else if (((src & 0x80L) != 0L)
606 && ((dst & 0x80L) != 0L))
607 {
608 flags |= C_FLAG;
609 }
610 }
611 else
612 {
613 if ((res & 0xFFL) == 0L)
614 {
615 flags |= Z_FLAG;
616 }
617 if (((src & 0x80L) != 0L)
618 && ((dst & 0x80L) != 0L))
619 {
620 flags |= V_FLAG;
621 }
622 if ((dst & 0x80L) != 0L
623 || (src & 0x80L) != 0L)
624 {
625 flags |= C_FLAG;
626 }
627 }
628 break;
629 case 2:
630 if ((res & 0x8000L) != 0L)
631 {
632 flags |= N_FLAG;
633 if (((src & 0x8000L) == 0L)
634 && ((dst & 0x8000L) == 0L))
635 {
636 flags |= V_FLAG;
637 }
638 else if (((src & 0x8000L) != 0L)
639 && ((dst & 0x8000L) != 0L))
640 {
641 flags |= C_FLAG;
642 }
643 }
644 else
645 {
646 if ((res & 0xFFFFL) == 0L)
647 {
648 flags |= Z_FLAG;
649 }
650 if (((src & 0x8000L) != 0L)
651 && ((dst & 0x8000L) != 0L))
652 {
653 flags |= V_FLAG;
654 }
655 if ((dst & 0x8000L) != 0L
656 || (src & 0x8000L) != 0L)
657 {
658 flags |= C_FLAG;
659 }
660 }
661 break;
662 case 4:
663 if ((res & 0x80000000L) != 0L)
664 {
665 flags |= N_FLAG;
666 if (((src & 0x80000000L) == 0L)
667 && ((dst & 0x80000000L) == 0L))
668 {
669 flags |= V_FLAG;
670 }
671 else if (((src & 0x80000000L) != 0L) &&
672 ((dst & 0x80000000L) != 0L))
673 {
674 flags |= C_FLAG;
675 }
676 }
677 else
678 {
679 if (res == 0L)
680 flags |= Z_FLAG;
681 if (((src & 0x80000000L) != 0L)
682 && ((dst & 0x80000000L) != 0L))
683 flags |= V_FLAG;
684 if ((dst & 0x80000000L) != 0L
685 || (src & 0x80000000L) != 0L)
686 flags |= C_FLAG;
687 }
688 break;
689 default:
690 break;
691 }
692
693 if (env->cc_op == CC_OP_SUB
694 || env->cc_op == CC_OP_CMP) {
695 flags ^= C_FLAG;
696 }
697 evaluate_flags_writeback(flags);
698 RETURN();
699 }
700
701 void OPPROTO op_extb_T0_T0 (void)
702 {
703 T0 = ((int8_t)T0);
704 RETURN();
705 }
706 void OPPROTO op_extb_T1_T0 (void)
707 {
708 T1 = ((int8_t)T0);
709 RETURN();
710 }
711 void OPPROTO op_extb_T1_T1 (void)
712 {
713 T1 = ((int8_t)T1);
714 RETURN();
715 }
716 void OPPROTO op_zextb_T0_T0 (void)
717 {
718 T0 = ((uint8_t)T0);
719 RETURN();
720 }
721 void OPPROTO op_zextb_T1_T0 (void)
722 {
723 T1 = ((uint8_t)T0);
724 RETURN();
725 }
726 void OPPROTO op_zextb_T1_T1 (void)
727 {
728 T1 = ((uint8_t)T1);
729 RETURN();
730 }
731 void OPPROTO op_extw_T0_T0 (void)
732 {
733 T0 = ((int16_t)T0);
734 RETURN();
735 }
736 void OPPROTO op_extw_T1_T0 (void)
737 {
738 T1 = ((int16_t)T0);
739 RETURN();
740 }
741 void OPPROTO op_extw_T1_T1 (void)
742 {
743 T1 = ((int16_t)T1);
744 RETURN();
745 }
746
747 void OPPROTO op_zextw_T0_T0 (void)
748 {
749 T0 = ((uint16_t)T0);
750 RETURN();
751 }
752 void OPPROTO op_zextw_T1_T0 (void)
753 {
754 T1 = ((uint16_t)T0);
755 RETURN();
756 }
757
758 void OPPROTO op_zextw_T1_T1 (void)
759 {
760 T1 = ((uint16_t)T1);
761 RETURN();
762 }
763
764 void OPPROTO op_movl_T0_im (void)
765 {
766 T0 = PARAM1;
767 RETURN();
768 }
769 void OPPROTO op_movl_T1_im (void)
770 {
771 T1 = PARAM1;
772 RETURN();
773 }
774
775 void OPPROTO op_addl_T0_im (void)
776 {
777 T0 += PARAM1;
778 RETURN();
779 }
780
781 void OPPROTO op_addl_T1_im (void)
782 {
783 T1 += PARAM1;
784 RETURN();
785
786 }
787 void OPPROTO op_subl_T0_im (void)
788 {
789 T0 -= PARAM1;
790 RETURN();
791 }
792
793 void OPPROTO op_addxl_T0_C (void)
794 {
795 if (env->pregs[SR_CCS] & X_FLAG)
796 T0 += !!(env->pregs[SR_CCS] & C_FLAG);
797 RETURN();
798 }
799 void OPPROTO op_subxl_T0_C (void)
800 {
801 if (env->pregs[SR_CCS] & X_FLAG)
802 T0 -= !!(env->pregs[SR_CCS] & C_FLAG);
803 RETURN();
804 }
805 void OPPROTO op_addl_T0_C (void)
806 {
807 T0 += !!(env->pregs[SR_CCS] & C_FLAG);
808 RETURN();
809 }
810 void OPPROTO op_addl_T0_R (void)
811 {
812 T0 += !!(env->pregs[SR_CCS] & R_FLAG);
813 RETURN();
814 }
815
816 void OPPROTO op_clr_R (void)
817 {
818 env->pregs[SR_CCS] &= ~R_FLAG;
819 RETURN();
820 }
821
822
823 void OPPROTO op_andl_T0_im (void)
824 {
825 T0 &= PARAM1;
826 RETURN();
827 }
828
829 void OPPROTO op_andl_T1_im (void)
830 {
831 T1 &= PARAM1;
832 RETURN();
833 }
834
835 void OPPROTO op_movl_T0_T1 (void)
836 {
837 T0 = T1;
838 RETURN();
839 }
840
841 void OPPROTO op_swp_T0_T1 (void)
842 {
843 T0 ^= T1;
844 T1 ^= T0;
845 T0 ^= T1;
846 RETURN();
847 }
848
849 void OPPROTO op_movl_T1_T0 (void)
850 {
851 T1 = T0;
852 RETURN();
853 }
854
855 void OPPROTO op_movl_pc_T0 (void)
856 {
857 env->pc = T0;
858 RETURN();
859 }
860
861 void OPPROTO op_movl_T0_0 (void)
862 {
863 T0 = 0;
864 RETURN();
865 }
866
867 void OPPROTO op_addl_T0_T1 (void)
868 {
869 T0 += T1;
870 RETURN();
871 }
872
873 void OPPROTO op_subl_T0_T1 (void)
874 {
875 T0 -= T1;
876 RETURN();
877 }
878
879 void OPPROTO op_absl_T1_T1 (void)
880 {
881 int32_t st = T1;
882
883 T1 = st < 0 ? -st : st;
884 RETURN();
885 }
886
887 void OPPROTO op_muls_T0_T1 (void)
888 {
889 int64_t tmp, t0 ,t1;
890
891 /* cast into signed values to make GCC sign extend these babies. */
892 t0 = (int32_t)T0;
893 t1 = (int32_t)T1;
894
895 tmp = t0 * t1;
896 T0 = tmp & 0xffffffff;
897 env->pregs[REG_MOF] = tmp >> 32;
898 RETURN();
899 }
900
901 void OPPROTO op_mulu_T0_T1 (void)
902 {
903 uint64_t tmp, t0 ,t1;
904 t0 = T0;
905 t1 = T1;
906
907 tmp = t0 * t1;
908 T0 = tmp & 0xffffffff;
909 env->pregs[REG_MOF] = tmp >> 32;
910 RETURN();
911 }
912
913 void OPPROTO op_dstep_T0_T1 (void)
914 {
915 T0 <<= 1;
916 if (T0 >= T1)
917 T0 -= T1;
918 RETURN();
919 }
920
921 void OPPROTO op_orl_T0_T1 (void)
922 {
923 T0 |= T1;
924 RETURN();
925 }
926
927 void OPPROTO op_andl_T0_T1 (void)
928 {
929 T0 &= T1;
930 RETURN();
931 }
932
933 void OPPROTO op_xorl_T0_T1 (void)
934 {
935 T0 ^= T1;
936 RETURN();
937 }
938
939 void OPPROTO op_lsll_T0_T1 (void)
940 {
941 int s = T1;
942 if (s > 31)
943 T0 = 0;
944 else
945 T0 <<= s;
946 RETURN();
947 }
948
949 void OPPROTO op_lsll_T0_im (void)
950 {
951 T0 <<= PARAM1;
952 RETURN();
953 }
954
955 void OPPROTO op_lsrl_T0_T1 (void)
956 {
957 int s = T1;
958 if (s > 31)
959 T0 = 0;
960 else
961 T0 >>= s;
962 RETURN();
963 }
964
965 /* Rely on GCC emitting an arithmetic shift for signed right shifts. */
966 void OPPROTO op_asrl_T0_T1 (void)
967 {
968 int s = T1;
969 if (s > 31)
970 T0 = T0 & 0x80000000 ? -1 : 0;
971 else
972 T0 = (int32_t)T0 >> s;
973 RETURN();
974 }
975
976 void OPPROTO op_btst_T0_T1 (void)
977 {
978 /* FIXME: clean this up. */
979
980 /* des ref:
981 The N flag is set according to the selected bit in the dest reg.
982 The Z flag is set if the selected bit and all bits to the right are
983 zero.
984 The destination reg is not affected.*/
985 unsigned int fz, sbit, bset, mask, masked_t0;
986
987 sbit = T1 & 31;
988 bset = !!(T0 & (1 << sbit));
989 mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
990 masked_t0 = T0 & mask;
991 fz = !(masked_t0 | bset);
992 /* Set the N and Z flags accordingly. */
993 T0 = (bset << 3) | (fz << 2);
994 RETURN();
995 }
996
997 void OPPROTO op_bound_T0_T1 (void)
998 {
999 if (T0 > T1)
1000 T0 = T1;
1001 RETURN();
1002 }
1003
1004 void OPPROTO op_lz_T0_T1 (void)
1005 {
1006 if (T1 == 0)
1007 T0 = 32;
1008 else
1009 T0 = __builtin_clz(T1);
1010 RETURN();
1011 }
1012
1013 void OPPROTO op_negl_T0_T1 (void)
1014 {
1015 T0 = -T1;
1016 RETURN();
1017 }
1018
1019 void OPPROTO op_negl_T1_T1 (void)
1020 {
1021 T1 = -T1;
1022 RETURN();
1023 }
1024
1025 void OPPROTO op_not_T0_T0 (void)
1026 {
1027 T0 = ~(T0);
1028 RETURN();
1029 }
1030 void OPPROTO op_not_T1_T1 (void)
1031 {
1032 T1 = ~(T1);
1033 RETURN();
1034 }
1035
1036 void OPPROTO op_swapw_T0_T0 (void)
1037 {
1038 T0 = (T0 << 16) | ((T0 >> 16));
1039 RETURN();
1040 }
1041
1042 void OPPROTO op_swapb_T0_T0 (void)
1043 {
1044 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
1045 RETURN();
1046 }
1047
1048 void OPPROTO op_swapr_T0_T0 (void)
1049 {
1050 T0 = (((T0 << 7) & 0x80808080) |
1051 ((T0 << 5) & 0x40404040) |
1052 ((T0 << 3) & 0x20202020) |
1053 ((T0 << 1) & 0x10101010) |
1054 ((T0 >> 1) & 0x08080808) |
1055 ((T0 >> 3) & 0x04040404) |
1056 ((T0 >> 5) & 0x02020202) |
1057 ((T0 >> 7) & 0x01010101));
1058 RETURN();
1059 }
1060
1061 void OPPROTO op_tst_cc_eq (void) {
1062 uint32_t flags = env->pregs[SR_CCS];
1063 int z_set;
1064
1065 z_set = !!(flags & Z_FLAG);
1066 T0 = z_set;
1067 RETURN();
1068 }
1069
1070 void OPPROTO op_tst_cc_eq_fast (void) {
1071 T0 = !(env->cc_result);
1072 RETURN();
1073 }
1074
1075 void OPPROTO op_tst_cc_ne (void) {
1076 uint32_t flags = env->pregs[SR_CCS];
1077 int z_set;
1078
1079 z_set = !!(flags & Z_FLAG);
1080 T0 = !z_set;
1081 RETURN();
1082 }
1083 void OPPROTO op_tst_cc_ne_fast (void) {
1084 T0 = !!(env->cc_result);
1085 RETURN();
1086 }
1087
1088 void OPPROTO op_tst_cc_cc (void) {
1089 uint32_t flags = env->pregs[SR_CCS];
1090 int c_set;
1091
1092 c_set = !!(flags & C_FLAG);
1093 T0 = !c_set;
1094 RETURN();
1095 }
1096 void OPPROTO op_tst_cc_cs (void) {
1097 uint32_t flags = env->pregs[SR_CCS];
1098 int c_set;
1099
1100 c_set = !!(flags & C_FLAG);
1101 T0 = c_set;
1102 RETURN();
1103 }
1104
1105 void OPPROTO op_tst_cc_vc (void) {
1106 uint32_t flags = env->pregs[SR_CCS];
1107 int v_set;
1108
1109 v_set = !!(flags & V_FLAG);
1110 T0 = !v_set;
1111 RETURN();
1112 }
1113 void OPPROTO op_tst_cc_vs (void) {
1114 uint32_t flags = env->pregs[SR_CCS];
1115 int v_set;
1116
1117 v_set = !!(flags & V_FLAG);
1118 T0 = v_set;
1119 RETURN();
1120 }
1121 void OPPROTO op_tst_cc_pl (void) {
1122 uint32_t flags = env->pregs[SR_CCS];
1123 int n_set;
1124
1125 n_set = !!(flags & N_FLAG);
1126 T0 = !n_set;
1127 RETURN();
1128 }
1129 void OPPROTO op_tst_cc_pl_fast (void) {
1130 T0 = ((int32_t)env->cc_result) >= 0;
1131 RETURN();
1132 }
1133
1134 void OPPROTO op_tst_cc_mi (void) {
1135 uint32_t flags = env->pregs[SR_CCS];
1136 int n_set;
1137
1138 n_set = !!(flags & N_FLAG);
1139 T0 = n_set;
1140 RETURN();
1141 }
1142 void OPPROTO op_tst_cc_mi_fast (void) {
1143 T0 = ((int32_t)env->cc_result) < 0;
1144 RETURN();
1145 }
1146
1147 void OPPROTO op_tst_cc_ls (void) {
1148 uint32_t flags = env->pregs[SR_CCS];
1149 int c_set;
1150 int z_set;
1151
1152 c_set = !!(flags & C_FLAG);
1153 z_set = !!(flags & Z_FLAG);
1154 T0 = c_set || z_set;
1155 RETURN();
1156 }
1157 void OPPROTO op_tst_cc_hi (void) {
1158 uint32_t flags = env->pregs[SR_CCS];
1159 int z_set;
1160 int c_set;
1161
1162 z_set = !!(flags & Z_FLAG);
1163 c_set = !!(flags & C_FLAG);
1164 T0 = !c_set && !z_set;
1165 RETURN();
1166
1167 }
1168
1169 void OPPROTO op_tst_cc_ge (void) {
1170 uint32_t flags = env->pregs[SR_CCS];
1171 int n_set;
1172 int v_set;
1173
1174 n_set = !!(flags & N_FLAG);
1175 v_set = !!(flags & V_FLAG);
1176 T0 = (n_set && v_set) || (!n_set && !v_set);
1177 RETURN();
1178 }
1179
1180 void OPPROTO op_tst_cc_ge_fast (void) {
1181 T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
1182 RETURN();
1183 }
1184
1185 void OPPROTO op_tst_cc_lt (void) {
1186 uint32_t flags = env->pregs[SR_CCS];
1187 int n_set;
1188 int v_set;
1189
1190 n_set = !!(flags & N_FLAG);
1191 v_set = !!(flags & V_FLAG);
1192 T0 = (n_set && !v_set) || (!n_set && v_set);
1193 RETURN();
1194 }
1195
1196 void OPPROTO op_tst_cc_gt (void) {
1197 uint32_t flags = env->pregs[SR_CCS];
1198 int n_set;
1199 int v_set;
1200 int z_set;
1201
1202 n_set = !!(flags & N_FLAG);
1203 v_set = !!(flags & V_FLAG);
1204 z_set = !!(flags & Z_FLAG);
1205 T0 = (n_set && v_set && !z_set)
1206 || (!n_set && !v_set && !z_set);
1207 RETURN();
1208 }
1209
1210 void OPPROTO op_tst_cc_le (void) {
1211 uint32_t flags = env->pregs[SR_CCS];
1212 int n_set;
1213 int v_set;
1214 int z_set;
1215
1216 n_set = !!(flags & N_FLAG);
1217 v_set = !!(flags & V_FLAG);
1218 z_set = !!(flags & Z_FLAG);
1219 T0 = z_set || (n_set && !v_set) || (!n_set && v_set);
1220 RETURN();
1221 }
1222
1223 void OPPROTO op_tst_cc_p (void) {
1224 uint32_t flags = env->pregs[SR_CCS];
1225 int p_set;
1226
1227 p_set = !!(flags & P_FLAG);
1228 T0 = p_set;
1229 RETURN();
1230 }
1231
1232 /* Evaluate the if the branch should be taken or not. Needs to be done in
1233 the original sequence. The acutal branch is rescheduled to right after the
1234 delay-slot. */
1235 void OPPROTO op_evaluate_bcc (void)
1236 {
1237 env->btaken = T0;
1238 RETURN();
1239 }
1240
1241 /* this one is used on every alu op, optimize it!. */
1242 void OPPROTO op_goto_if_not_x (void)
1243 {
1244 if (env->pregs[SR_CCS] & X_FLAG)
1245 GOTO_LABEL_PARAM(1);
1246 RETURN();
1247 }
1248
1249 void OPPROTO op_cc_jmp (void)
1250 {
1251 if (env->btaken)
1252 env->pc = PARAM1;
1253 else
1254 env->pc = PARAM2;
1255 RETURN();
1256 }
1257
1258 void OPPROTO op_cc_ngoto (void)
1259 {
1260 if (!env->btaken)
1261 GOTO_LABEL_PARAM(1);
1262 RETURN();
1263 }
1264
1265 void OPPROTO op_movl_btarget_T0 (void)
1266 {
1267 env->btarget = T0;
1268 RETURN();
1269 }
1270
1271 void OPPROTO op_jmp (void)
1272 {
1273 env->pc = env->btarget;
1274 RETURN();
1275 }
1276
1277 /* Load and store */
1278 #define MEMSUFFIX _raw
1279 #include "op_mem.c"
1280 #undef MEMSUFFIX
1281 #if !defined(CONFIG_USER_ONLY)
1282 #define MEMSUFFIX _user
1283 #include "op_mem.c"
1284 #undef MEMSUFFIX
1285
1286 #define MEMSUFFIX _kernel
1287 #include "op_mem.c"
1288 #undef MEMSUFFIX
1289 #endif