]>
git.proxmox.com Git - qemu.git/blob - target-sparc/op.c
e2ef7ae7cd7b9b8a659ad06c7ef93c56515600d7
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
, N
, V
, b2
, src1
;
263 N
= FLAG_SET(PSR_NEG
);
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)
686 void OPPROTO
op_flush_T0(void)