Use the shiny new clz helpers.
[qemu/qemu_0_9_1_stable.git] / target-cris / op.c
blob6e17719b6fd613e0d1011957d97a4a60f4a6505c
1 /*
2 * CRIS emulation micro-operations for qemu.
4 * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
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.
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.
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
20 #include "exec.h"
21 #include "host-utils.h"
23 #define REGNAME r0
24 #define REG (env->regs[0])
25 #include "op_template.h"
27 #define REGNAME r1
28 #define REG (env->regs[1])
29 #include "op_template.h"
31 #define REGNAME r2
32 #define REG (env->regs[2])
33 #include "op_template.h"
35 #define REGNAME r3
36 #define REG (env->regs[3])
37 #include "op_template.h"
39 #define REGNAME r4
40 #define REG (env->regs[4])
41 #include "op_template.h"
43 #define REGNAME r5
44 #define REG (env->regs[5])
45 #include "op_template.h"
47 #define REGNAME r6
48 #define REG (env->regs[6])
49 #include "op_template.h"
51 #define REGNAME r7
52 #define REG (env->regs[7])
53 #include "op_template.h"
55 #define REGNAME r8
56 #define REG (env->regs[8])
57 #include "op_template.h"
59 #define REGNAME r9
60 #define REG (env->regs[9])
61 #include "op_template.h"
63 #define REGNAME r10
64 #define REG (env->regs[10])
65 #include "op_template.h"
67 #define REGNAME r11
68 #define REG (env->regs[11])
69 #include "op_template.h"
71 #define REGNAME r12
72 #define REG (env->regs[12])
73 #include "op_template.h"
75 #define REGNAME r13
76 #define REG (env->regs[13])
77 #include "op_template.h"
79 #define REGNAME r14
80 #define REG (env->regs[14])
81 #include "op_template.h"
83 #define REGNAME r15
84 #define REG (env->regs[15])
85 #include "op_template.h"
88 #define REGNAME p0
89 #define REG (env->pregs[0])
90 #include "op_template.h"
92 #define REGNAME p1
93 #define REG (env->pregs[1])
94 #include "op_template.h"
96 #define REGNAME p2
97 #define REG (env->pregs[2])
98 #include "op_template.h"
100 #define REGNAME p3
101 #define REG (env->pregs[3])
102 #include "op_template.h"
104 #define REGNAME p4
105 #define REG (env->pregs[4])
106 #include "op_template.h"
108 #define REGNAME p5
109 #define REG (env->pregs[5])
110 #include "op_template.h"
112 #define REGNAME p6
113 #define REG (env->pregs[6])
114 #include "op_template.h"
116 #define REGNAME p7
117 #define REG (env->pregs[7])
118 #include "op_template.h"
120 #define REGNAME p8
121 #define REG (env->pregs[8])
122 #include "op_template.h"
124 #define REGNAME p9
125 #define REG (env->pregs[9])
126 #include "op_template.h"
128 #define REGNAME p10
129 #define REG (env->pregs[10])
130 #include "op_template.h"
132 #define REGNAME p11
133 #define REG (env->pregs[11])
134 #include "op_template.h"
136 #define REGNAME p12
137 #define REG (env->pregs[12])
138 #include "op_template.h"
140 #define REGNAME p13
141 #define REG (env->pregs[13])
142 #include "op_template.h"
144 #define REGNAME p14
145 #define REG (env->pregs[14])
146 #include "op_template.h"
148 #define REGNAME p15
149 #define REG (env->pregs[15])
150 #include "op_template.h"
152 /* Microcode. */
154 void OPPROTO op_exit_tb (void)
156 EXIT_TB();
159 void OPPROTO op_goto_tb0 (void)
161 GOTO_TB(op_goto_tb0, PARAM1, 0);
162 RETURN();
165 void OPPROTO op_goto_tb1 (void)
167 GOTO_TB(op_goto_tb1, PARAM1, 1);
168 RETURN();
171 void OPPROTO op_break_im(void)
173 env->trapnr = PARAM1;
174 env->exception_index = EXCP_BREAK;
175 cpu_loop_exit();
178 void OPPROTO op_debug(void)
180 env->exception_index = EXCP_DEBUG;
181 cpu_loop_exit();
184 void OPPROTO op_exec_insn(void)
186 env->stats.exec_insns++;
187 RETURN();
189 void OPPROTO op_exec_load(void)
191 env->stats.exec_loads++;
192 RETURN();
194 void OPPROTO op_exec_store(void)
196 env->stats.exec_stores++;
197 RETURN();
200 void OPPROTO op_ccs_lshift (void)
202 uint32_t ccs;
204 /* Apply the ccs shift. */
205 ccs = env->pregs[SR_CCS];
206 ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
207 env->pregs[SR_CCS] = ccs;
209 void OPPROTO op_ccs_rshift (void)
211 uint32_t ccs;
213 /* Apply the ccs shift. */
214 ccs = env->pregs[SR_CCS];
215 ccs = (ccs & 0xc0000000) | (ccs >> 10);
216 env->pregs[SR_CCS] = ccs;
219 void OPPROTO op_setf (void)
221 env->pregs[SR_CCS] |= PARAM1;
222 RETURN();
225 void OPPROTO op_clrf (void)
227 env->pregs[SR_CCS] &= ~PARAM1;
228 RETURN();
231 void OPPROTO op_movl_debug1_T0 (void)
233 env->debug1 = T0;
234 RETURN();
237 void OPPROTO op_movl_debug2_T0 (void)
239 env->debug2 = T0;
240 RETURN();
243 void OPPROTO op_movl_debug3_T0 (void)
245 env->debug3 = T0;
246 RETURN();
248 void OPPROTO op_movl_debug1_T1 (void)
250 env->debug1 = T1;
251 RETURN();
254 void OPPROTO op_movl_debug2_T1 (void)
256 env->debug2 = T1;
257 RETURN();
260 void OPPROTO op_movl_debug3_T1 (void)
262 env->debug3 = T1;
263 RETURN();
265 void OPPROTO op_movl_debug3_im (void)
267 env->debug3 = PARAM1;
268 RETURN();
270 void OPPROTO op_movl_T0_flags (void)
272 T0 = env->pregs[SR_CCS];
273 RETURN();
275 void OPPROTO op_movl_flags_T0 (void)
277 env->pregs[SR_CCS] = T0;
278 RETURN();
281 void OPPROTO op_movl_sreg_T0 (void)
283 env->sregs[env->pregs[SR_SRS]][PARAM1] = T0;
284 RETURN();
287 void OPPROTO op_movl_tlb_lo_T0 (void)
289 int srs;
290 srs = env->pregs[SR_SRS];
291 if (srs == 1 || srs == 2)
293 int set;
294 int idx;
295 uint32_t lo, hi;
297 idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
298 set >>= 4;
299 set &= 3;
301 idx &= 31;
302 /* We've just made a write to tlb_lo. */
303 lo = env->sregs[SFR_RW_MM_TLB_LO];
304 hi = env->sregs[SFR_RW_MM_TLB_HI];
305 env->tlbsets[srs - 1][set][idx].lo = lo;
306 env->tlbsets[srs - 1][set][idx].hi = hi;
309 RETURN();
312 void OPPROTO op_movl_T0_sreg (void)
314 T0 = env->sregs[env->pregs[SR_SRS]][PARAM1];
315 RETURN();
318 void OPPROTO op_update_cc (void)
320 env->cc_op = PARAM1;
321 env->cc_dest = PARAM2;
322 env->cc_src = PARAM3;
323 RETURN();
326 void OPPROTO op_update_cc_op (void)
328 env->cc_op = PARAM1;
329 RETURN();
332 void OPPROTO op_update_cc_mask (void)
334 env->cc_mask = PARAM1;
335 RETURN();
338 void OPPROTO op_update_cc_dest_T0 (void)
340 env->cc_dest = T0;
341 RETURN();
344 void OPPROTO op_update_cc_result_T0 (void)
346 env->cc_result = T0;
347 RETURN();
350 void OPPROTO op_update_cc_size_im (void)
352 env->cc_size = PARAM1;
353 RETURN();
356 void OPPROTO op_update_cc_src_T1 (void)
358 env->cc_src = T1;
359 RETURN();
361 void OPPROTO op_update_cc_x (void)
363 env->cc_x_live = PARAM1;
364 env->cc_x = PARAM2;
365 RETURN();
368 /* FIXME: is this allowed? */
369 extern inline void evaluate_flags_writeback(uint32_t flags)
371 int x;
373 /* Extended arithmetics, leave the z flag alone. */
374 env->debug3 = env->pregs[SR_CCS];
376 if (env->cc_x_live)
377 x = env->cc_x;
378 else
379 x = env->pregs[SR_CCS] & X_FLAG;
381 if ((x || env->cc_op == CC_OP_ADDC)
382 && flags & Z_FLAG)
383 env->cc_mask &= ~Z_FLAG;
385 /* all insn clear the x-flag except setf or clrf. */
386 env->pregs[SR_CCS] &= ~(env->cc_mask | X_FLAG);
387 flags &= env->cc_mask;
388 env->pregs[SR_CCS] |= flags;
389 RETURN();
392 void OPPROTO op_evaluate_flags_muls(void)
394 uint32_t src;
395 uint32_t dst;
396 uint32_t res;
397 uint32_t flags = 0;
398 /* were gonna have to redo the muls. */
399 int64_t tmp, t0 ,t1;
400 int32_t mof;
401 int dneg;
403 src = env->cc_src;
404 dst = env->cc_dest;
405 res = env->cc_result;
408 /* cast into signed values to make GCC sign extend. */
409 t0 = (int32_t)src;
410 t1 = (int32_t)dst;
411 dneg = ((int32_t)res) < 0;
413 tmp = t0 * t1;
414 mof = tmp >> 32;
415 if (tmp == 0)
416 flags |= Z_FLAG;
417 else if (tmp < 0)
418 flags |= N_FLAG;
419 if ((dneg && mof != -1)
420 || (!dneg && mof != 0))
421 flags |= V_FLAG;
422 evaluate_flags_writeback(flags);
423 RETURN();
426 void OPPROTO op_evaluate_flags_mulu(void)
428 uint32_t src;
429 uint32_t dst;
430 uint32_t res;
431 uint32_t flags = 0;
432 /* were gonna have to redo the muls. */
433 uint64_t tmp, t0 ,t1;
434 uint32_t mof;
436 src = env->cc_src;
437 dst = env->cc_dest;
438 res = env->cc_result;
441 /* cast into signed values to make GCC sign extend. */
442 t0 = src;
443 t1 = dst;
445 tmp = t0 * t1;
446 mof = tmp >> 32;
447 if (tmp == 0)
448 flags |= Z_FLAG;
449 else if (tmp >> 63)
450 flags |= N_FLAG;
451 if (mof)
452 flags |= V_FLAG;
454 evaluate_flags_writeback(flags);
455 RETURN();
458 void OPPROTO op_evaluate_flags_mcp(void)
460 uint32_t src;
461 uint32_t dst;
462 uint32_t res;
463 uint32_t flags = 0;
465 src = env->cc_src;
466 dst = env->cc_dest;
467 res = env->cc_result;
469 if ((res & 0x80000000L) != 0L)
471 flags |= N_FLAG;
472 if (((src & 0x80000000L) == 0L)
473 && ((dst & 0x80000000L) == 0L))
475 flags |= V_FLAG;
477 else if (((src & 0x80000000L) != 0L) &&
478 ((dst & 0x80000000L) != 0L))
480 flags |= R_FLAG;
483 else
485 if (res == 0L)
486 flags |= Z_FLAG;
487 if (((src & 0x80000000L) != 0L)
488 && ((dst & 0x80000000L) != 0L))
489 flags |= V_FLAG;
490 if ((dst & 0x80000000L) != 0L
491 || (src & 0x80000000L) != 0L)
492 flags |= R_FLAG;
495 evaluate_flags_writeback(flags);
496 RETURN();
499 void OPPROTO op_evaluate_flags_alu_4(void)
501 uint32_t src;
502 uint32_t dst;
503 uint32_t res;
504 uint32_t flags = 0;
506 src = env->cc_src;
507 dst = env->cc_dest;
508 res = env->cc_result;
510 if ((res & 0x80000000L) != 0L)
512 flags |= N_FLAG;
513 if (((src & 0x80000000L) == 0L)
514 && ((dst & 0x80000000L) == 0L))
516 flags |= V_FLAG;
518 else if (((src & 0x80000000L) != 0L) &&
519 ((dst & 0x80000000L) != 0L))
521 flags |= C_FLAG;
524 else
526 if (res == 0L)
527 flags |= Z_FLAG;
528 if (((src & 0x80000000L) != 0L)
529 && ((dst & 0x80000000L) != 0L))
530 flags |= V_FLAG;
531 if ((dst & 0x80000000L) != 0L
532 || (src & 0x80000000L) != 0L)
533 flags |= C_FLAG;
536 if (env->cc_op == CC_OP_SUB
537 || env->cc_op == CC_OP_CMP) {
538 flags ^= C_FLAG;
540 evaluate_flags_writeback(flags);
541 RETURN();
544 void OPPROTO op_evaluate_flags_move_4 (void)
546 uint32_t src;
547 uint32_t res;
548 uint32_t flags = 0;
550 src = env->cc_src;
551 res = env->cc_result;
553 if ((int32_t)res < 0)
554 flags |= N_FLAG;
555 else if (res == 0L)
556 flags |= Z_FLAG;
558 evaluate_flags_writeback(flags);
559 RETURN();
561 void OPPROTO op_evaluate_flags_move_2 (void)
563 uint32_t src;
564 uint32_t flags = 0;
565 uint16_t res;
567 src = env->cc_src;
568 res = env->cc_result;
570 if ((int16_t)res < 0L)
571 flags |= N_FLAG;
572 else if (res == 0)
573 flags |= Z_FLAG;
575 evaluate_flags_writeback(flags);
576 RETURN();
579 /* TODO: This is expensive. We could split things up and only evaluate part of
580 CCR on a need to know basis. For now, we simply re-evaluate everything. */
581 void OPPROTO op_evaluate_flags (void)
583 uint32_t src;
584 uint32_t dst;
585 uint32_t res;
586 uint32_t flags = 0;
588 src = env->cc_src;
589 dst = env->cc_dest;
590 res = env->cc_result;
593 /* Now, evaluate the flags. This stuff is based on
594 Per Zander's CRISv10 simulator. */
595 switch (env->cc_size)
597 case 1:
598 if ((res & 0x80L) != 0L)
600 flags |= N_FLAG;
601 if (((src & 0x80L) == 0L)
602 && ((dst & 0x80L) == 0L))
604 flags |= V_FLAG;
606 else if (((src & 0x80L) != 0L)
607 && ((dst & 0x80L) != 0L))
609 flags |= C_FLAG;
612 else
614 if ((res & 0xFFL) == 0L)
616 flags |= Z_FLAG;
618 if (((src & 0x80L) != 0L)
619 && ((dst & 0x80L) != 0L))
621 flags |= V_FLAG;
623 if ((dst & 0x80L) != 0L
624 || (src & 0x80L) != 0L)
626 flags |= C_FLAG;
629 break;
630 case 2:
631 if ((res & 0x8000L) != 0L)
633 flags |= N_FLAG;
634 if (((src & 0x8000L) == 0L)
635 && ((dst & 0x8000L) == 0L))
637 flags |= V_FLAG;
639 else if (((src & 0x8000L) != 0L)
640 && ((dst & 0x8000L) != 0L))
642 flags |= C_FLAG;
645 else
647 if ((res & 0xFFFFL) == 0L)
649 flags |= Z_FLAG;
651 if (((src & 0x8000L) != 0L)
652 && ((dst & 0x8000L) != 0L))
654 flags |= V_FLAG;
656 if ((dst & 0x8000L) != 0L
657 || (src & 0x8000L) != 0L)
659 flags |= C_FLAG;
662 break;
663 case 4:
664 if ((res & 0x80000000L) != 0L)
666 flags |= N_FLAG;
667 if (((src & 0x80000000L) == 0L)
668 && ((dst & 0x80000000L) == 0L))
670 flags |= V_FLAG;
672 else if (((src & 0x80000000L) != 0L) &&
673 ((dst & 0x80000000L) != 0L))
675 flags |= C_FLAG;
678 else
680 if (res == 0L)
681 flags |= Z_FLAG;
682 if (((src & 0x80000000L) != 0L)
683 && ((dst & 0x80000000L) != 0L))
684 flags |= V_FLAG;
685 if ((dst & 0x80000000L) != 0L
686 || (src & 0x80000000L) != 0L)
687 flags |= C_FLAG;
689 break;
690 default:
691 break;
694 if (env->cc_op == CC_OP_SUB
695 || env->cc_op == CC_OP_CMP) {
696 flags ^= C_FLAG;
698 evaluate_flags_writeback(flags);
699 RETURN();
702 void OPPROTO op_extb_T0_T0 (void)
704 T0 = ((int8_t)T0);
705 RETURN();
707 void OPPROTO op_extb_T1_T0 (void)
709 T1 = ((int8_t)T0);
710 RETURN();
712 void OPPROTO op_extb_T1_T1 (void)
714 T1 = ((int8_t)T1);
715 RETURN();
717 void OPPROTO op_zextb_T0_T0 (void)
719 T0 = ((uint8_t)T0);
720 RETURN();
722 void OPPROTO op_zextb_T1_T0 (void)
724 T1 = ((uint8_t)T0);
725 RETURN();
727 void OPPROTO op_zextb_T1_T1 (void)
729 T1 = ((uint8_t)T1);
730 RETURN();
732 void OPPROTO op_extw_T0_T0 (void)
734 T0 = ((int16_t)T0);
735 RETURN();
737 void OPPROTO op_extw_T1_T0 (void)
739 T1 = ((int16_t)T0);
740 RETURN();
742 void OPPROTO op_extw_T1_T1 (void)
744 T1 = ((int16_t)T1);
745 RETURN();
748 void OPPROTO op_zextw_T0_T0 (void)
750 T0 = ((uint16_t)T0);
751 RETURN();
753 void OPPROTO op_zextw_T1_T0 (void)
755 T1 = ((uint16_t)T0);
756 RETURN();
759 void OPPROTO op_zextw_T1_T1 (void)
761 T1 = ((uint16_t)T1);
762 RETURN();
765 void OPPROTO op_movl_T0_im (void)
767 T0 = PARAM1;
768 RETURN();
770 void OPPROTO op_movl_T1_im (void)
772 T1 = PARAM1;
773 RETURN();
776 void OPPROTO op_addl_T0_im (void)
778 T0 += PARAM1;
779 RETURN();
782 void OPPROTO op_addl_T1_im (void)
784 T1 += PARAM1;
785 RETURN();
788 void OPPROTO op_subl_T0_im (void)
790 T0 -= PARAM1;
791 RETURN();
794 void OPPROTO op_addxl_T0_C (void)
796 if (env->pregs[SR_CCS] & X_FLAG)
797 T0 += !!(env->pregs[SR_CCS] & C_FLAG);
798 RETURN();
800 void OPPROTO op_subxl_T0_C (void)
802 if (env->pregs[SR_CCS] & X_FLAG)
803 T0 -= !!(env->pregs[SR_CCS] & C_FLAG);
804 RETURN();
806 void OPPROTO op_addl_T0_C (void)
808 T0 += !!(env->pregs[SR_CCS] & C_FLAG);
809 RETURN();
811 void OPPROTO op_addl_T0_R (void)
813 T0 += !!(env->pregs[SR_CCS] & R_FLAG);
814 RETURN();
817 void OPPROTO op_clr_R (void)
819 env->pregs[SR_CCS] &= ~R_FLAG;
820 RETURN();
824 void OPPROTO op_andl_T0_im (void)
826 T0 &= PARAM1;
827 RETURN();
830 void OPPROTO op_andl_T1_im (void)
832 T1 &= PARAM1;
833 RETURN();
836 void OPPROTO op_movl_T0_T1 (void)
838 T0 = T1;
839 RETURN();
842 void OPPROTO op_swp_T0_T1 (void)
844 T0 ^= T1;
845 T1 ^= T0;
846 T0 ^= T1;
847 RETURN();
850 void OPPROTO op_movl_T1_T0 (void)
852 T1 = T0;
853 RETURN();
856 void OPPROTO op_movl_pc_T0 (void)
858 env->pc = T0;
859 RETURN();
862 void OPPROTO op_movl_T0_0 (void)
864 T0 = 0;
865 RETURN();
868 void OPPROTO op_addl_T0_T1 (void)
870 T0 += T1;
871 RETURN();
874 void OPPROTO op_subl_T0_T1 (void)
876 T0 -= T1;
877 RETURN();
880 void OPPROTO op_absl_T1_T1 (void)
882 int32_t st = T1;
884 T1 = st < 0 ? -st : st;
885 RETURN();
888 void OPPROTO op_muls_T0_T1 (void)
890 int64_t tmp, t0 ,t1;
892 /* cast into signed values to make GCC sign extend these babies. */
893 t0 = (int32_t)T0;
894 t1 = (int32_t)T1;
896 tmp = t0 * t1;
897 T0 = tmp & 0xffffffff;
898 env->pregs[REG_MOF] = tmp >> 32;
899 RETURN();
902 void OPPROTO op_mulu_T0_T1 (void)
904 uint64_t tmp, t0 ,t1;
905 t0 = T0;
906 t1 = T1;
908 tmp = t0 * t1;
909 T0 = tmp & 0xffffffff;
910 env->pregs[REG_MOF] = tmp >> 32;
911 RETURN();
914 void OPPROTO op_dstep_T0_T1 (void)
916 T0 <<= 1;
917 if (T0 >= T1)
918 T0 -= T1;
919 RETURN();
922 void OPPROTO op_orl_T0_T1 (void)
924 T0 |= T1;
925 RETURN();
928 void OPPROTO op_andl_T0_T1 (void)
930 T0 &= T1;
931 RETURN();
934 void OPPROTO op_xorl_T0_T1 (void)
936 T0 ^= T1;
937 RETURN();
940 void OPPROTO op_lsll_T0_T1 (void)
942 int s = T1;
943 if (s > 31)
944 T0 = 0;
945 else
946 T0 <<= s;
947 RETURN();
950 void OPPROTO op_lsll_T0_im (void)
952 T0 <<= PARAM1;
953 RETURN();
956 void OPPROTO op_lsrl_T0_T1 (void)
958 int s = T1;
959 if (s > 31)
960 T0 = 0;
961 else
962 T0 >>= s;
963 RETURN();
966 /* Rely on GCC emitting an arithmetic shift for signed right shifts. */
967 void OPPROTO op_asrl_T0_T1 (void)
969 int s = T1;
970 if (s > 31)
971 T0 = T0 & 0x80000000 ? -1 : 0;
972 else
973 T0 = (int32_t)T0 >> s;
974 RETURN();
977 void OPPROTO op_btst_T0_T1 (void)
979 /* FIXME: clean this up. */
981 /* des ref:
982 The N flag is set according to the selected bit in the dest reg.
983 The Z flag is set if the selected bit and all bits to the right are
984 zero.
985 The destination reg is not affected.*/
986 unsigned int fz, sbit, bset, mask, masked_t0;
988 sbit = T1 & 31;
989 bset = !!(T0 & (1 << sbit));
990 mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
991 masked_t0 = T0 & mask;
992 fz = !(masked_t0 | bset);
993 /* Set the N and Z flags accordingly. */
994 T0 = (bset << 3) | (fz << 2);
995 RETURN();
998 void OPPROTO op_bound_T0_T1 (void)
1000 if (T0 > T1)
1001 T0 = T1;
1002 RETURN();
1005 void OPPROTO op_lz_T0_T1 (void)
1007 T0 = clz32(T1);
1008 RETURN();
1011 void OPPROTO op_negl_T0_T1 (void)
1013 T0 = -T1;
1014 RETURN();
1017 void OPPROTO op_negl_T1_T1 (void)
1019 T1 = -T1;
1020 RETURN();
1023 void OPPROTO op_not_T0_T0 (void)
1025 T0 = ~(T0);
1026 RETURN();
1028 void OPPROTO op_not_T1_T1 (void)
1030 T1 = ~(T1);
1031 RETURN();
1034 void OPPROTO op_swapw_T0_T0 (void)
1036 T0 = (T0 << 16) | ((T0 >> 16));
1037 RETURN();
1040 void OPPROTO op_swapb_T0_T0 (void)
1042 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
1043 RETURN();
1046 void OPPROTO op_swapr_T0_T0 (void)
1048 T0 = (((T0 << 7) & 0x80808080) |
1049 ((T0 << 5) & 0x40404040) |
1050 ((T0 << 3) & 0x20202020) |
1051 ((T0 << 1) & 0x10101010) |
1052 ((T0 >> 1) & 0x08080808) |
1053 ((T0 >> 3) & 0x04040404) |
1054 ((T0 >> 5) & 0x02020202) |
1055 ((T0 >> 7) & 0x01010101));
1056 RETURN();
1059 void OPPROTO op_tst_cc_eq (void) {
1060 uint32_t flags = env->pregs[SR_CCS];
1061 int z_set;
1063 z_set = !!(flags & Z_FLAG);
1064 T0 = z_set;
1065 RETURN();
1068 void OPPROTO op_tst_cc_eq_fast (void) {
1069 T0 = !(env->cc_result);
1070 RETURN();
1073 void OPPROTO op_tst_cc_ne (void) {
1074 uint32_t flags = env->pregs[SR_CCS];
1075 int z_set;
1077 z_set = !!(flags & Z_FLAG);
1078 T0 = !z_set;
1079 RETURN();
1081 void OPPROTO op_tst_cc_ne_fast (void) {
1082 T0 = !!(env->cc_result);
1083 RETURN();
1086 void OPPROTO op_tst_cc_cc (void) {
1087 uint32_t flags = env->pregs[SR_CCS];
1088 int c_set;
1090 c_set = !!(flags & C_FLAG);
1091 T0 = !c_set;
1092 RETURN();
1094 void OPPROTO op_tst_cc_cs (void) {
1095 uint32_t flags = env->pregs[SR_CCS];
1096 int c_set;
1098 c_set = !!(flags & C_FLAG);
1099 T0 = c_set;
1100 RETURN();
1103 void OPPROTO op_tst_cc_vc (void) {
1104 uint32_t flags = env->pregs[SR_CCS];
1105 int v_set;
1107 v_set = !!(flags & V_FLAG);
1108 T0 = !v_set;
1109 RETURN();
1111 void OPPROTO op_tst_cc_vs (void) {
1112 uint32_t flags = env->pregs[SR_CCS];
1113 int v_set;
1115 v_set = !!(flags & V_FLAG);
1116 T0 = v_set;
1117 RETURN();
1119 void OPPROTO op_tst_cc_pl (void) {
1120 uint32_t flags = env->pregs[SR_CCS];
1121 int n_set;
1123 n_set = !!(flags & N_FLAG);
1124 T0 = !n_set;
1125 RETURN();
1127 void OPPROTO op_tst_cc_pl_fast (void) {
1128 T0 = ((int32_t)env->cc_result) >= 0;
1129 RETURN();
1132 void OPPROTO op_tst_cc_mi (void) {
1133 uint32_t flags = env->pregs[SR_CCS];
1134 int n_set;
1136 n_set = !!(flags & N_FLAG);
1137 T0 = n_set;
1138 RETURN();
1140 void OPPROTO op_tst_cc_mi_fast (void) {
1141 T0 = ((int32_t)env->cc_result) < 0;
1142 RETURN();
1145 void OPPROTO op_tst_cc_ls (void) {
1146 uint32_t flags = env->pregs[SR_CCS];
1147 int c_set;
1148 int z_set;
1150 c_set = !!(flags & C_FLAG);
1151 z_set = !!(flags & Z_FLAG);
1152 T0 = c_set || z_set;
1153 RETURN();
1155 void OPPROTO op_tst_cc_hi (void) {
1156 uint32_t flags = env->pregs[SR_CCS];
1157 int z_set;
1158 int c_set;
1160 z_set = !!(flags & Z_FLAG);
1161 c_set = !!(flags & C_FLAG);
1162 T0 = !c_set && !z_set;
1163 RETURN();
1167 void OPPROTO op_tst_cc_ge (void) {
1168 uint32_t flags = env->pregs[SR_CCS];
1169 int n_set;
1170 int v_set;
1172 n_set = !!(flags & N_FLAG);
1173 v_set = !!(flags & V_FLAG);
1174 T0 = (n_set && v_set) || (!n_set && !v_set);
1175 RETURN();
1178 void OPPROTO op_tst_cc_ge_fast (void) {
1179 T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
1180 RETURN();
1183 void OPPROTO op_tst_cc_lt (void) {
1184 uint32_t flags = env->pregs[SR_CCS];
1185 int n_set;
1186 int v_set;
1188 n_set = !!(flags & N_FLAG);
1189 v_set = !!(flags & V_FLAG);
1190 T0 = (n_set && !v_set) || (!n_set && v_set);
1191 RETURN();
1194 void OPPROTO op_tst_cc_gt (void) {
1195 uint32_t flags = env->pregs[SR_CCS];
1196 int n_set;
1197 int v_set;
1198 int z_set;
1200 n_set = !!(flags & N_FLAG);
1201 v_set = !!(flags & V_FLAG);
1202 z_set = !!(flags & Z_FLAG);
1203 T0 = (n_set && v_set && !z_set)
1204 || (!n_set && !v_set && !z_set);
1205 RETURN();
1208 void OPPROTO op_tst_cc_le (void) {
1209 uint32_t flags = env->pregs[SR_CCS];
1210 int n_set;
1211 int v_set;
1212 int z_set;
1214 n_set = !!(flags & N_FLAG);
1215 v_set = !!(flags & V_FLAG);
1216 z_set = !!(flags & Z_FLAG);
1217 T0 = z_set || (n_set && !v_set) || (!n_set && v_set);
1218 RETURN();
1221 void OPPROTO op_tst_cc_p (void) {
1222 uint32_t flags = env->pregs[SR_CCS];
1223 int p_set;
1225 p_set = !!(flags & P_FLAG);
1226 T0 = p_set;
1227 RETURN();
1230 /* Evaluate the if the branch should be taken or not. Needs to be done in
1231 the original sequence. The acutal branch is rescheduled to right after the
1232 delay-slot. */
1233 void OPPROTO op_evaluate_bcc (void)
1235 env->btaken = T0;
1236 RETURN();
1239 /* this one is used on every alu op, optimize it!. */
1240 void OPPROTO op_goto_if_not_x (void)
1242 if (env->pregs[SR_CCS] & X_FLAG)
1243 GOTO_LABEL_PARAM(1);
1244 RETURN();
1247 void OPPROTO op_cc_jmp (void)
1249 if (env->btaken)
1250 env->pc = PARAM1;
1251 else
1252 env->pc = PARAM2;
1253 RETURN();
1256 void OPPROTO op_cc_ngoto (void)
1258 if (!env->btaken)
1259 GOTO_LABEL_PARAM(1);
1260 RETURN();
1263 void OPPROTO op_movl_btarget_T0 (void)
1265 env->btarget = T0;
1266 RETURN();
1269 void OPPROTO op_jmp (void)
1271 env->pc = env->btarget;
1272 RETURN();
1275 /* Load and store */
1276 #define MEMSUFFIX _raw
1277 #include "op_mem.c"
1278 #undef MEMSUFFIX
1279 #if !defined(CONFIG_USER_ONLY)
1280 #define MEMSUFFIX _user
1281 #include "op_mem.c"
1282 #undef MEMSUFFIX
1284 #define MEMSUFFIX _kernel
1285 #include "op_mem.c"
1286 #undef MEMSUFFIX
1287 #endif