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