4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
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
25 #define REG (env->gregs[0])
26 #include "op_template.h"
28 #define REG (env->gregs[1])
29 #include "op_template.h"
31 #define REG (env->gregs[2])
32 #include "op_template.h"
34 #define REG (env->gregs[3])
35 #include "op_template.h"
37 #define REG (env->gregs[4])
38 #include "op_template.h"
40 #define REG (env->gregs[5])
41 #include "op_template.h"
43 #define REG (env->gregs[6])
44 #include "op_template.h"
46 #define REG (env->gregs[7])
47 #include "op_template.h"
49 #define REG (env->regwptr[16])
50 #include "op_template.h"
52 #define REG (env->regwptr[17])
53 #include "op_template.h"
55 #define REG (env->regwptr[18])
56 #include "op_template.h"
58 #define REG (env->regwptr[19])
59 #include "op_template.h"
61 #define REG (env->regwptr[20])
62 #include "op_template.h"
64 #define REG (env->regwptr[21])
65 #include "op_template.h"
67 #define REG (env->regwptr[22])
68 #include "op_template.h"
70 #define REG (env->regwptr[23])
71 #include "op_template.h"
73 #define REG (env->regwptr[8])
74 #include "op_template.h"
76 #define REG (env->regwptr[9])
77 #include "op_template.h"
79 #define REG (env->regwptr[10])
80 #include "op_template.h"
82 #define REG (env->regwptr[11])
83 #include "op_template.h"
85 #define REG (env->regwptr[12])
86 #include "op_template.h"
88 #define REG (env->regwptr[13])
89 #include "op_template.h"
91 #define REG (env->regwptr[14])
92 #include "op_template.h"
94 #define REG (env->regwptr[15])
95 #include "op_template.h"
97 #define REG (env->regwptr[0])
98 #include "op_template.h"
100 #define REG (env->regwptr[1])
101 #include "op_template.h"
103 #define REG (env->regwptr[2])
104 #include "op_template.h"
106 #define REG (env->regwptr[3])
107 #include "op_template.h"
109 #define REG (env->regwptr[4])
110 #include "op_template.h"
112 #define REG (env->regwptr[5])
113 #include "op_template.h"
115 #define REG (env->regwptr[6])
116 #include "op_template.h"
118 #define REG (env->regwptr[7])
119 #include "op_template.h"
120 #define EIP (env->pc)
122 #define FLAG_SET(x) (env->psr&x)?1:0
124 void OPPROTO op_movl_T0_0(void)
129 void OPPROTO op_movl_T0_1(void)
134 void OPPROTO op_movl_T0_im(void)
139 void OPPROTO op_movl_T1_im(void)
144 void OPPROTO op_movl_T2_im(void)
149 void OPPROTO op_addl_T1_im(void)
154 void OPPROTO op_addl_T1_T2(void)
159 void OPPROTO op_subl_T1_T2(void)
164 void OPPROTO op_add_T1_T0(void)
169 void OPPROTO op_add_T1_T0_cc(void)
176 env->psr |= PSR_ZERO;
180 env->psr |= PSR_CARRY;
181 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
186 void OPPROTO op_sub_T1_T0(void)
191 void OPPROTO op_sub_T1_T0_cc(void)
199 env->psr |= PSR_ZERO;
203 env->psr |= PSR_CARRY;
204 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
209 void OPPROTO op_and_T1_T0(void)
214 void OPPROTO op_or_T1_T0(void)
219 void OPPROTO op_xor_T1_T0(void)
224 void OPPROTO op_andn_T1_T0(void)
229 void OPPROTO op_orn_T1_T0(void)
234 void OPPROTO op_xnor_T1_T0(void)
239 void OPPROTO op_addx_T1_T0(void)
241 T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
244 void OPPROTO op_umul_T1_T0(void)
247 res = (uint64_t) T0 *(uint64_t) T1;
248 T0 = res & 0xffffffff;
252 void OPPROTO op_smul_T1_T0(void)
255 res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
256 T0 = res & 0xffffffff;
260 void OPPROTO op_mulscc_T1_T0(void)
262 unsigned int b1, C, V, b2, src1;
263 C = FLAG_SET(PSR_CARRY);
264 V = FLAG_SET(PSR_OVF);
267 T0 = (b1 << 31) | (T0 >> 1);
270 /* do addition and update flags */
275 env->psr |= PSR_ZERO;
279 env->psr |= PSR_CARRY;
280 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
282 env->y = (b2 << 31) | (env->y >> 1);
286 void OPPROTO op_udiv_T1_T0(void)
291 x0 = T0 | ((uint64_t) (env->y) << 32);
294 if (x0 > 0xffffffff) {
304 void OPPROTO op_sdiv_T1_T0(void)
309 x0 = T0 | ((uint64_t) (env->y) << 32);
312 if ((int32_t) x0 != x0) {
322 void OPPROTO op_div_cc(void)
326 env->psr |= PSR_ZERO;
334 void OPPROTO op_subx_T1_T0(void)
336 T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
339 void OPPROTO op_logic_T0_cc(void)
343 env->psr |= PSR_ZERO;
349 void OPPROTO op_set_flags(void)
353 env->psr |= PSR_ZERO;
354 if ((unsigned int) T0 < (unsigned int) T1)
355 env->psr |= PSR_CARRY;
356 if ((int) T0 < (int) T1)
363 void OPPROTO op_sll(void)
368 void OPPROTO op_srl(void)
373 void OPPROTO op_sra(void)
375 T0 = ((int32_t) T0) >> T1;
378 void OPPROTO op_st(void)
380 stl((void *) T0, T1);
383 void OPPROTO op_stb(void)
385 stb((void *) T0, T1);
388 void OPPROTO op_sth(void)
390 stw((void *) T0, T1);
393 void OPPROTO op_std(void)
395 stl((void *) T0, T1);
396 stl((void *) (T0 + 4), T2);
399 void OPPROTO op_ld(void)
401 T1 = ldl((void *) T0);
404 void OPPROTO op_ldub(void)
406 T1 = ldub((void *) T0);
409 void OPPROTO op_lduh(void)
411 T1 = lduw((void *) T0);
414 void OPPROTO op_ldsb(void)
416 T1 = ldsb((void *) T0);
419 void OPPROTO op_ldsh(void)
421 T1 = ldsw((void *) T0);
424 void OPPROTO op_ldstub(void)
426 T1 = ldub((void *) T0);
427 stb((void *) T0, 0xff); /* XXX: Should be Atomically */
430 void OPPROTO op_swap(void)
432 unsigned int tmp = ldl((void *) T0);
433 stl((void *) T0, T1); /* XXX: Should be Atomically */
437 void OPPROTO op_ldd(void)
439 T1 = ldl((void *) T0);
440 T0 = ldl((void *) (T0 + 4));
443 void OPPROTO op_wry(void)
448 void OPPROTO op_rdy(void)
453 void raise_exception(int tt)
455 env->exception_index = tt;
459 void memcpy32(uint32_t *dst, const uint32_t *src)
471 static inline void set_cwp(int new_cwp)
473 /* put the modified wrap registers at their proper location */
474 if (env->cwp == (NWINDOWS - 1))
475 memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
477 /* put the wrap registers at their temporary location */
478 if (new_cwp == (NWINDOWS - 1))
479 memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
480 env->regwptr = env->regbase + (new_cwp * 16);
483 /* XXX: use another pointer for %iN registers to avoid slow wrapping
485 void OPPROTO op_save(void)
488 cwp = (env->cwp - 1) & (NWINDOWS - 1);
489 if (env->wim & (1 << cwp)) {
490 raise_exception(TT_WIN_OVF);
496 void OPPROTO op_restore(void)
499 cwp = (env->cwp + 1) & (NWINDOWS - 1);
500 if (env->wim & (1 << cwp)) {
501 raise_exception(TT_WIN_UNF);
507 void OPPROTO op_exception(void)
509 env->exception_index = PARAM1;
513 void OPPROTO op_trap_T0(void)
515 env->exception_index = TT_TRAP + (T0 & 0x7f);
519 void OPPROTO op_trapcc_T0(void)
522 env->exception_index = TT_TRAP + (T0 & 0x7f);
528 void OPPROTO op_exit_tb(void)
533 void OPPROTO op_eval_be(void)
535 T2 = (env->psr & PSR_ZERO);
538 void OPPROTO op_eval_ble(void)
540 unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
545 void OPPROTO op_eval_bl(void)
547 unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
552 void OPPROTO op_eval_bleu(void)
554 unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
559 void OPPROTO op_eval_bcs(void)
561 T2 = (env->psr & PSR_CARRY);
564 void OPPROTO op_eval_bvs(void)
566 T2 = (env->psr & PSR_OVF);
569 void OPPROTO op_eval_bneg(void)
571 T2 = (env->psr & PSR_NEG);
574 void OPPROTO op_eval_bne(void)
576 T2 = !(env->psr & PSR_ZERO);
579 void OPPROTO op_eval_bg(void)
581 unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
586 void OPPROTO op_eval_bge(void)
588 unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
593 void OPPROTO op_eval_bgu(void)
595 unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
600 void OPPROTO op_eval_bcc(void)
602 T2 = !(env->psr & PSR_CARRY);
605 void OPPROTO op_eval_bpos(void)
607 T2 = !(env->psr & PSR_NEG);
610 void OPPROTO op_eval_bvc(void)
612 T2 = !(env->psr & PSR_OVF);
615 void OPPROTO op_movl_T2_0(void)
620 void OPPROTO op_movl_T2_1(void)
625 void OPPROTO op_jmp_im(void)
630 void OPPROTO op_movl_npc_im(void)
635 void OPPROTO op_movl_npc_T0(void)
640 void OPPROTO op_next_insn(void)
643 env->npc = env->npc + 4;
646 void OPPROTO op_branch(void)
648 env->npc = PARAM3; /* XXX: optimize */
649 JUMP_TB(op_branch, PARAM1, 0, PARAM2);
652 void OPPROTO op_branch2(void)
655 env->npc = PARAM2 + 4;
656 JUMP_TB(op_branch2, PARAM1, 0, PARAM2);
658 env->npc = PARAM3 + 4;
659 JUMP_TB(op_branch2, PARAM1, 1, PARAM3);
664 void OPPROTO op_branch_a(void)
667 env->npc = PARAM2; /* XXX: optimize */
668 JUMP_TB(op_generic_branch_a, PARAM1, 0, PARAM3);
670 env->npc = PARAM3 + 8; /* XXX: optimize */
671 JUMP_TB(op_generic_branch_a, PARAM1, 1, PARAM3 + 4);
676 void OPPROTO op_generic_branch(void)