fixed ldq() macros
[qemu/qemu_0_9_1_stable.git] / target-sparc / op.c
blobd365661643771dd28812efe777255966e9632a87
1 /*
2 SPARC micro operations
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
21 #include "exec.h"
23 /*XXX*/
24 #define REGNAME g0
25 #define REG (env->gregs[0])
26 #include "op_template.h"
27 #define REGNAME g1
28 #define REG (env->gregs[1])
29 #include "op_template.h"
30 #define REGNAME g2
31 #define REG (env->gregs[2])
32 #include "op_template.h"
33 #define REGNAME g3
34 #define REG (env->gregs[3])
35 #include "op_template.h"
36 #define REGNAME g4
37 #define REG (env->gregs[4])
38 #include "op_template.h"
39 #define REGNAME g5
40 #define REG (env->gregs[5])
41 #include "op_template.h"
42 #define REGNAME g6
43 #define REG (env->gregs[6])
44 #include "op_template.h"
45 #define REGNAME g7
46 #define REG (env->gregs[7])
47 #include "op_template.h"
48 #define REGNAME i0
49 #define REG (env->regwptr[16])
50 #include "op_template.h"
51 #define REGNAME i1
52 #define REG (env->regwptr[17])
53 #include "op_template.h"
54 #define REGNAME i2
55 #define REG (env->regwptr[18])
56 #include "op_template.h"
57 #define REGNAME i3
58 #define REG (env->regwptr[19])
59 #include "op_template.h"
60 #define REGNAME i4
61 #define REG (env->regwptr[20])
62 #include "op_template.h"
63 #define REGNAME i5
64 #define REG (env->regwptr[21])
65 #include "op_template.h"
66 #define REGNAME i6
67 #define REG (env->regwptr[22])
68 #include "op_template.h"
69 #define REGNAME i7
70 #define REG (env->regwptr[23])
71 #include "op_template.h"
72 #define REGNAME l0
73 #define REG (env->regwptr[8])
74 #include "op_template.h"
75 #define REGNAME l1
76 #define REG (env->regwptr[9])
77 #include "op_template.h"
78 #define REGNAME l2
79 #define REG (env->regwptr[10])
80 #include "op_template.h"
81 #define REGNAME l3
82 #define REG (env->regwptr[11])
83 #include "op_template.h"
84 #define REGNAME l4
85 #define REG (env->regwptr[12])
86 #include "op_template.h"
87 #define REGNAME l5
88 #define REG (env->regwptr[13])
89 #include "op_template.h"
90 #define REGNAME l6
91 #define REG (env->regwptr[14])
92 #include "op_template.h"
93 #define REGNAME l7
94 #define REG (env->regwptr[15])
95 #include "op_template.h"
96 #define REGNAME o0
97 #define REG (env->regwptr[0])
98 #include "op_template.h"
99 #define REGNAME o1
100 #define REG (env->regwptr[1])
101 #include "op_template.h"
102 #define REGNAME o2
103 #define REG (env->regwptr[2])
104 #include "op_template.h"
105 #define REGNAME o3
106 #define REG (env->regwptr[3])
107 #include "op_template.h"
108 #define REGNAME o4
109 #define REG (env->regwptr[4])
110 #include "op_template.h"
111 #define REGNAME o5
112 #define REG (env->regwptr[5])
113 #include "op_template.h"
114 #define REGNAME o6
115 #define REG (env->regwptr[6])
116 #include "op_template.h"
117 #define REGNAME o7
118 #define REG (env->regwptr[7])
119 #include "op_template.h"
121 #define EIP (env->pc)
123 void OPPROTO op_movl_T0_0(void)
125 T0 = 0;
128 void OPPROTO op_movl_T0_1(void)
130 T0 = 1;
133 void OPPROTO op_movl_T0_im(void)
135 T0 = PARAM1;
138 void OPPROTO op_movl_T1_im(void)
140 T1 = PARAM1;
143 void OPPROTO op_movl_T2_im(void)
145 T2 = PARAM1;
148 void OPPROTO op_addl_T1_im(void)
150 T1 += PARAM1;
153 void OPPROTO op_addl_T1_T2(void)
155 T1 += T2;
158 void OPPROTO op_subl_T1_T2(void)
160 T1 -= T2;
163 void OPPROTO op_add_T1_T0 (void)
165 T0 += T1;
168 void OPPROTO op_and_T1_T0 (void)
170 T0 &= T1;
173 void OPPROTO op_or_T1_T0 (void)
175 T0 |= T1;
178 void OPPROTO op_xor_T1_T0 (void)
180 T0 ^= T1;
183 void OPPROTO op_sub_T1_T0 (void)
185 T0 -= T1;
188 void OPPROTO op_andn_T1_T0 (void)
190 T0 &= ~T1;
193 void OPPROTO op_orn_T1_T0 (void)
195 T0 |= ~T1;
198 void OPPROTO op_xnor_T1_T0 (void)
200 T0 ^= ~T1;
203 void OPPROTO op_addx_T1_T0 (void)
205 T0 += T1+((env->psr & PSR_CARRY)?1:0);
208 void OPPROTO op_umul_T1_T0 (void)
210 unsigned long long res = T0*T1;
211 T0 = res & 0xffffffff;
212 env->y = res >> 32;
215 void OPPROTO op_smul_T1_T0 (void)
217 long long res = T0*T1;
218 T0 = res & 0xffffffff;
219 env->y = res >> 32;
222 void OPPROTO op_udiv_T1_T0 (void)
224 unsigned long long x0 = T0 * env->y;
225 unsigned int x1 = T1;
226 T0 = x0 / x1;
229 void OPPROTO op_sdiv_T1_T0 (void)
231 long long x0 = T0 * env->y;
232 int x1 = T1;
233 T0 = x0 / x1;
236 void OPPROTO op_subx_T1_T0 (void)
238 T0 -= T1+((env->psr & PSR_CARRY)?1:0);
241 void OPPROTO op_set_flags (void)
243 env->psr = 0;
244 if (!T0) env->psr |= PSR_ZERO;
245 if ((unsigned int) T0 < (unsigned int) T1) env->psr |= PSR_CARRY;
246 if ((int) T0 < (int) T1) env->psr |= PSR_OVF;
247 if ((int) T0 < 0) env->psr |= PSR_NEG;
250 void OPPROTO op_sll (void)
252 T0 <<= T1;
255 void OPPROTO op_srl (void)
257 T0 >>= T1;
260 void OPPROTO op_sra (void)
262 int x = T0 >> T1;
263 T0 = x;
266 void OPPROTO op_st (void)
268 stl ((void *) T0, T1);
271 void OPPROTO op_stb (void)
273 stb ((void *) T0, T1);
276 void OPPROTO op_sth (void)
278 stw ((void *) T0, T1);
281 void OPPROTO op_ld (void)
283 T1 = ldl ((void *) T0);
286 void OPPROTO op_ldub (void)
288 T1 = ldub ((void *) T0);
291 void OPPROTO op_lduh (void)
293 T1 = lduw ((void *) T0);
296 void OPPROTO op_ldsb (void)
298 T1 = ldsb ((void *) T0);
301 void OPPROTO op_ldsh (void)
303 T1 = ldsw ((void *) T0);
306 void OPPROTO op_ldstub (void)
308 T1 = ldub ((void *) T0);
309 stb ((void *) T0, 0xff); /* XXX: Should be Atomically */
312 void OPPROTO op_swap (void)
314 unsigned int tmp = ldl ((void *) T0);
315 stl ((void *) T0, T1); /* XXX: Should be Atomically */
316 T1 = tmp;
319 void OPPROTO op_ldd (void)
321 T1 = ldl ((void *) T0);
322 T0 = ldl ((void *) T0+4);
325 void OPPROTO op_wry (void)
327 env->y = T0^T1;
330 void OPPROTO op_rdy (void)
332 T0 = env->y;
335 #define regwptr (env->regwptr)
337 void OPPROTO op_save (void)
339 regwptr -= 16;
342 void OPPROTO op_restore (void)
344 regwptr += 16;
347 void OPPROTO op_trap (void)
349 env->exception_index = PARAM1;
350 cpu_loop_exit ();
353 void OPPROTO op_exit_tb (void)
355 EXIT_TB ();
358 void OPPROTO op_eval_be (void)
360 T0 = (env->psr & PSR_ZERO);
363 #define FLAG_SET(x) (env->psr&x)?1:0
364 #define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY)
366 void OPPROTO op_eval_ble (void)
368 GET_FLAGS;
369 T0 = Z | (N^V);
372 void OPPROTO op_eval_bl (void)
374 GET_FLAGS;
375 T0 = N^V;
378 void OPPROTO op_eval_bleu (void)
380 GET_FLAGS;
381 T0 = C|Z;
384 void OPPROTO op_eval_bcs (void)
386 T0 = (env->psr & PSR_CARRY);
389 void OPPROTO op_eval_bvs (void)
391 T0 = (env->psr & PSR_OVF);
394 void OPPROTO op_eval_bneg (void)
396 T0 = (env->psr & PSR_NEG);
399 void OPPROTO op_eval_bne (void)
401 T0 = !(env->psr & PSR_ZERO);
404 void OPPROTO op_eval_bg (void)
406 GET_FLAGS;
407 T0 = !(Z | (N^V));
410 /*XXX: This seems to be documented wrong in the SPARC V8 Manual
411 The manual states: !(N^V)
412 but I assume Z | !(N^V) to be correct */
413 void OPPROTO op_eval_bge (void)
415 GET_FLAGS;
416 T0 = Z | !(N^V);
419 void OPPROTO op_eval_bgu (void)
421 GET_FLAGS;
422 T0 = !(C | Z);
425 void OPPROTO op_eval_bcc (void)
427 T0 = !(env->psr & PSR_CARRY);
430 void OPPROTO op_eval_bpos (void)
432 T0 = !(env->psr & PSR_NEG);
435 void OPPROTO op_eval_bvc (void)
437 T0 = !(env->psr & PSR_OVF);
440 void OPPROTO op_jmp_im (void)
442 env->pc = PARAM1;
445 void OPPROTO op_call (void)
447 regwptr[7] = PARAM1-4;
448 env->pc = PARAM1+PARAM2;
451 void OPPROTO op_jmpl (void)
453 env->npc = T0;
456 void OPPROTO op_generic_jmp_1 (void)
458 T1 = PARAM1;
459 env->pc = PARAM1+PARAM2;
462 void OPPROTO op_generic_jmp_2 (void)
464 T1 = PARAM1;
465 env->pc = env->npc;
468 unsigned long old_T0;
470 void OPPROTO op_save_T0 (void)
472 old_T0 = T0;
475 void OPPROTO op_restore_T0 (void)
477 T0 = old_T0;
480 void OPPROTO op_generic_branch (void)
482 if (T0)
483 JUMP_TB (__func__, PARAM1, 0, PARAM2);
484 else
485 JUMP_TB (__func__, PARAM1, 1, PARAM3);
486 FORCE_RET ();
489 void OPPROTO op_generic_branch_a (void)
491 if (T0)
492 env->npc = PARAM3;
493 else
494 JUMP_TB (__func__, PARAM1, 0, PARAM2);
495 FORCE_RET ();
498 void OPPROTO op_noop (void)