root / targetm68k / op.c @ 5fafdf24
History  View  Annotate  Download (20.6 kB)
1 
/*


2 
* m68k micro operations

3 
*

4 
* Copyright (c) 20062007 CodeSourcery

5 
* Written by Paul Brook

6 
*

7 
* This library is free software; you can redistribute it and/or

8 
* modify it under the terms of the GNU Lesser General Public

9 
* License as published by the Free Software Foundation; either

10 
* version 2 of the License, or (at your option) any later version.

11 
*

12 
* This library is distributed in the hope that it will be useful,

13 
* but WITHOUT ANY WARRANTY; without even the implied warranty of

14 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

15 
* General Public License for more details.

16 
*

17 
* You should have received a copy of the GNU Lesser General Public

18 
* License along with this library; if not, write to the Free Software

19 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021111307 USA

20 
*/

21  
22 
#include "exec.h" 
23 
#include "m68kqreg.h" 
24  
25 
#ifndef offsetof

26 
#define offsetof(type, field) ((size_t) &((type *)0)>field) 
27 
#endif

28  
29 
static long qreg_offsets[] = { 
30 
#define DEFO32(name, offset) offsetof(CPUState, offset),

31 
#define DEFR(name, reg, mode) 1, 
32 
#define DEFF64(name, offset) offsetof(CPUState, offset),

33 
0,

34 
#include "qregs.def" 
35 
}; 
36  
37 
#define CPU_FP_STATUS env>fp_status

38  
39 
#define RAISE_EXCEPTION(n) do { \ 
40 
env>exception_index = n; \ 
41 
cpu_loop_exit(); \ 
42 
} while(0) 
43  
44 
#define get_op helper_get_op

45 
#define set_op helper_set_op

46 
#define get_opf64 helper_get_opf64

47 
#define set_opf64 helper_set_opf64

48 
uint32_t 
49 
get_op(int qreg)

50 
{ 
51 
if (qreg >= TARGET_NUM_QREGS) {

52 
return env>qregs[qreg  TARGET_NUM_QREGS];

53 
} else if (qreg == QREG_T0) { 
54 
return T0;

55 
} else {

56 
return *(uint32_t *)(((long)env) + qreg_offsets[qreg]); 
57 
} 
58 
} 
59  
60 
void set_op(int qreg, uint32_t val) 
61 
{ 
62 
if (qreg >= TARGET_NUM_QREGS) {

63 
env>qregs[qreg  TARGET_NUM_QREGS] = val; 
64 
} else if (qreg == QREG_T0) { 
65 
T0 = val; 
66 
} else {

67 
*(uint32_t *)(((long)env) + qreg_offsets[qreg]) = val;

68 
} 
69 
} 
70  
71 
float64 get_opf64(int qreg)

72 
{ 
73 
if (qreg < TARGET_NUM_QREGS) {

74 
return *(float64 *)(((long)env) + qreg_offsets[qreg]); 
75 
} else {

76 
return *(float64 *)&env>qregs[qreg  TARGET_NUM_QREGS];

77 
} 
78 
} 
79  
80 
void set_opf64(int qreg, float64 val) 
81 
{ 
82 
if (qreg < TARGET_NUM_QREGS) {

83 
*(float64 *)(((long)env) + qreg_offsets[qreg]) = val;

84 
} else {

85 
*(float64 *)&env>qregs[qreg  TARGET_NUM_QREGS] = val; 
86 
} 
87 
} 
88  
89 
#define OP(name) void OPPROTO glue(op_,name) (void) 
90  
91 
OP(mov32) 
92 
{ 
93 
set_op(PARAM1, get_op(PARAM2)); 
94 
FORCE_RET(); 
95 
} 
96  
97 
OP(mov32_im) 
98 
{ 
99 
set_op(PARAM1, PARAM2); 
100 
FORCE_RET(); 
101 
} 
102  
103 
OP(movf64) 
104 
{ 
105 
set_opf64(PARAM1, get_opf64(PARAM2)); 
106 
FORCE_RET(); 
107 
} 
108  
109 
OP(zerof64) 
110 
{ 
111 
set_opf64(PARAM1, 0);

112 
FORCE_RET(); 
113 
} 
114  
115 
OP(add32) 
116 
{ 
117 
uint32_t op2 = get_op(PARAM2); 
118 
uint32_t op3 = get_op(PARAM3); 
119 
set_op(PARAM1, op2 + op3); 
120 
FORCE_RET(); 
121 
} 
122  
123 
OP(sub32) 
124 
{ 
125 
uint32_t op2 = get_op(PARAM2); 
126 
uint32_t op3 = get_op(PARAM3); 
127 
set_op(PARAM1, op2  op3); 
128 
FORCE_RET(); 
129 
} 
130  
131 
OP(mul32) 
132 
{ 
133 
uint32_t op2 = get_op(PARAM2); 
134 
uint32_t op3 = get_op(PARAM3); 
135 
set_op(PARAM1, op2 * op3); 
136 
FORCE_RET(); 
137 
} 
138  
139 
OP(not32) 
140 
{ 
141 
uint32_t arg = get_op(PARAM2); 
142 
set_op(PARAM1, ~arg); 
143 
FORCE_RET(); 
144 
} 
145  
146 
OP(neg32) 
147 
{ 
148 
uint32_t arg = get_op(PARAM2); 
149 
set_op(PARAM1, arg); 
150 
FORCE_RET(); 
151 
} 
152  
153 
OP(bswap32) 
154 
{ 
155 
uint32_t arg = get_op(PARAM2); 
156 
arg = (arg >> 24)  (arg << 24) 
157 
 ((arg >> 16) & 0xff00)  ((arg << 16) & 0xff0000); 
158 
set_op(PARAM1, arg); 
159 
FORCE_RET(); 
160 
} 
161  
162 
OP(btest) 
163 
{ 
164 
uint32_t op1 = get_op(PARAM1); 
165 
uint32_t op2 = get_op(PARAM2); 
166 
if (op1 & op2)

167 
env>cc_dest &= ~CCF_Z; 
168 
else

169 
env>cc_dest = CCF_Z; 
170 
FORCE_RET(); 
171 
} 
172  
173 
OP(ff1) 
174 
{ 
175 
uint32_t arg = get_op(PARAM2); 
176 
int n;

177 
for (n = 32; arg; n) 
178 
arg >>= 1;

179 
set_op(PARAM1, n); 
180 
FORCE_RET(); 
181 
} 
182  
183 
OP(subx_cc) 
184 
{ 
185 
uint32_t op1 = get_op(PARAM1); 
186 
uint32_t op2 = get_op(PARAM2); 
187 
uint32_t res; 
188 
if (env>cc_x) {

189 
env>cc_x = (op1 <= op2); 
190 
env>cc_op = CC_OP_SUBX; 
191 
res = op1  (op2 + 1);

192 
} else {

193 
env>cc_x = (op1 < op2); 
194 
env>cc_op = CC_OP_SUB; 
195 
res = op1  op2; 
196 
} 
197 
set_op(PARAM1, res); 
198 
FORCE_RET(); 
199 
} 
200  
201 
OP(addx_cc) 
202 
{ 
203 
uint32_t op1 = get_op(PARAM1); 
204 
uint32_t op2 = get_op(PARAM2); 
205 
uint32_t res; 
206 
if (env>cc_x) {

207 
res = op1 + op2 + 1;

208 
env>cc_x = (res <= op2); 
209 
env>cc_op = CC_OP_ADDX; 
210 
} else {

211 
res = op1 + op2; 
212 
env>cc_x = (res < op2); 
213 
env>cc_op = CC_OP_ADD; 
214 
} 
215 
set_op(PARAM1, res); 
216 
FORCE_RET(); 
217 
} 
218  
219 
/* Logic ops. */

220  
221 
OP(and32) 
222 
{ 
223 
uint32_t op2 = get_op(PARAM2); 
224 
uint32_t op3 = get_op(PARAM3); 
225 
set_op(PARAM1, op2 & op3); 
226 
FORCE_RET(); 
227 
} 
228  
229 
OP(or32) 
230 
{ 
231 
uint32_t op2 = get_op(PARAM2); 
232 
uint32_t op3 = get_op(PARAM3); 
233 
set_op(PARAM1, op2  op3); 
234 
FORCE_RET(); 
235 
} 
236  
237 
OP(xor32) 
238 
{ 
239 
uint32_t op2 = get_op(PARAM2); 
240 
uint32_t op3 = get_op(PARAM3); 
241 
set_op(PARAM1, op2 ^ op3); 
242 
FORCE_RET(); 
243 
} 
244  
245 
/* Shifts. */

246 
OP(shl32) 
247 
{ 
248 
uint32_t op2 = get_op(PARAM2); 
249 
uint32_t op3 = get_op(PARAM3); 
250 
uint32_t result; 
251 
result = op2 << op3; 
252 
set_op(PARAM1, result); 
253 
FORCE_RET(); 
254 
} 
255  
256 
OP(shl_cc) 
257 
{ 
258 
uint32_t op1 = get_op(PARAM1); 
259 
uint32_t op2 = get_op(PARAM2); 
260 
uint32_t result; 
261 
result = op1 << op2; 
262 
set_op(PARAM1, result); 
263 
env>cc_x = (op1 << (op2  1)) & 1; 
264 
FORCE_RET(); 
265 
} 
266  
267 
OP(shr32) 
268 
{ 
269 
uint32_t op2 = get_op(PARAM2); 
270 
uint32_t op3 = get_op(PARAM3); 
271 
uint32_t result; 
272 
result = op2 >> op3; 
273 
set_op(PARAM1, result); 
274 
FORCE_RET(); 
275 
} 
276  
277 
OP(shr_cc) 
278 
{ 
279 
uint32_t op1 = get_op(PARAM1); 
280 
uint32_t op2 = get_op(PARAM2); 
281 
uint32_t result; 
282 
result = op1 >> op2; 
283 
set_op(PARAM1, result); 
284 
env>cc_x = (op1 >> (op2  1)) & 1; 
285 
FORCE_RET(); 
286 
} 
287  
288 
OP(sar32) 
289 
{ 
290 
int32_t op2 = get_op(PARAM2); 
291 
uint32_t op3 = get_op(PARAM3); 
292 
uint32_t result; 
293 
result = op2 >> op3; 
294 
set_op(PARAM1, result); 
295 
FORCE_RET(); 
296 
} 
297  
298 
OP(sar_cc) 
299 
{ 
300 
int32_t op1 = get_op(PARAM1); 
301 
uint32_t op2 = get_op(PARAM2); 
302 
uint32_t result; 
303 
result = op1 >> op2; 
304 
set_op(PARAM1, result); 
305 
env>cc_x = (op1 >> (op2  1)) & 1; 
306 
FORCE_RET(); 
307 
} 
308  
309 
/* Value extend. */

310  
311 
OP(ext8u32) 
312 
{ 
313 
uint32_t op2 = get_op(PARAM2); 
314 
set_op(PARAM1, (uint8_t)op2); 
315 
FORCE_RET(); 
316 
} 
317  
318 
OP(ext8s32) 
319 
{ 
320 
uint32_t op2 = get_op(PARAM2); 
321 
set_op(PARAM1, (int8_t)op2); 
322 
FORCE_RET(); 
323 
} 
324  
325 
OP(ext16u32) 
326 
{ 
327 
uint32_t op2 = get_op(PARAM2); 
328 
set_op(PARAM1, (uint16_t)op2); 
329 
FORCE_RET(); 
330 
} 
331  
332 
OP(ext16s32) 
333 
{ 
334 
uint32_t op2 = get_op(PARAM2); 
335 
set_op(PARAM1, (int16_t)op2); 
336 
FORCE_RET(); 
337 
} 
338  
339 
OP(flush_flags) 
340 
{ 
341 
cpu_m68k_flush_flags(env, env>cc_op); 
342 
FORCE_RET(); 
343 
} 
344  
345 
OP(divu) 
346 
{ 
347 
uint32_t num; 
348 
uint32_t den; 
349 
uint32_t quot; 
350 
uint32_t rem; 
351 
uint32_t flags; 
352 

353 
num = env>div1; 
354 
den = env>div2; 
355 
/* ??? This needs to make sure the throwing location is accurate. */

356 
if (den == 0) 
357 
RAISE_EXCEPTION(EXCP_DIV0); 
358 
quot = num / den; 
359 
rem = num % den; 
360 
flags = 0;

361 
/* Avoid using a PARAM1 of zero. This breaks dyngen because it uses

362 
the address of a symbol, and gcc knows symbols can't have address

363 
zero. */

364 
if (PARAM1 == 2 && quot > 0xffff) 
365 
flags = CCF_V; 
366 
if (quot == 0) 
367 
flags = CCF_Z; 
368 
else if ((int32_t)quot < 0) 
369 
flags = CCF_N; 
370 
env>div1 = quot; 
371 
env>div2 = rem; 
372 
env>cc_dest = flags; 
373 
FORCE_RET(); 
374 
} 
375  
376 
OP(divs) 
377 
{ 
378 
int32_t num; 
379 
int32_t den; 
380 
int32_t quot; 
381 
int32_t rem; 
382 
int32_t flags; 
383 

384 
num = env>div1; 
385 
den = env>div2; 
386 
if (den == 0) 
387 
RAISE_EXCEPTION(EXCP_DIV0); 
388 
quot = num / den; 
389 
rem = num % den; 
390 
flags = 0;

391 
if (PARAM1 == 2 && quot != (int16_t)quot) 
392 
flags = CCF_V; 
393 
if (quot == 0) 
394 
flags = CCF_Z; 
395 
else if (quot < 0) 
396 
flags = CCF_N; 
397 
env>div1 = quot; 
398 
env>div2 = rem; 
399 
env>cc_dest = flags; 
400 
FORCE_RET(); 
401 
} 
402  
403 
/* Halt is special because it may be a semihosting call. */

404 
OP(halt) 
405 
{ 
406 
RAISE_EXCEPTION(EXCP_HALT_INSN); 
407 
FORCE_RET(); 
408 
} 
409  
410 
OP(stop) 
411 
{ 
412 
env>halted = 1;

413 
RAISE_EXCEPTION(EXCP_HLT); 
414 
FORCE_RET(); 
415 
} 
416  
417 
OP(raise_exception) 
418 
{ 
419 
RAISE_EXCEPTION(PARAM1); 
420 
FORCE_RET(); 
421 
} 
422  
423 
/* Floating point comparison sets flags differently to other instructions. */

424  
425 
OP(sub_cmpf64) 
426 
{ 
427 
float64 src0; 
428 
float64 src1; 
429 
src0 = get_opf64(PARAM2); 
430 
src1 = get_opf64(PARAM3); 
431 
set_opf64(PARAM1, helper_sub_cmpf64(env, src0, src1)); 
432 
FORCE_RET(); 
433 
} 
434  
435 
OP(update_xflag_tst) 
436 
{ 
437 
uint32_t op1 = get_op(PARAM1); 
438 
env>cc_x = op1; 
439 
FORCE_RET(); 
440 
} 
441  
442 
OP(update_xflag_lt) 
443 
{ 
444 
uint32_t op1 = get_op(PARAM1); 
445 
uint32_t op2 = get_op(PARAM2); 
446 
env>cc_x = (op1 < op2); 
447 
FORCE_RET(); 
448 
} 
449  
450 
OP(get_xflag) 
451 
{ 
452 
set_op(PARAM1, env>cc_x); 
453 
FORCE_RET(); 
454 
} 
455  
456 
OP(logic_cc) 
457 
{ 
458 
uint32_t op1 = get_op(PARAM1); 
459 
env>cc_dest = op1; 
460 
FORCE_RET(); 
461 
} 
462  
463 
OP(update_cc_add) 
464 
{ 
465 
uint32_t op1 = get_op(PARAM1); 
466 
uint32_t op2 = get_op(PARAM2); 
467 
env>cc_dest = op1; 
468 
env>cc_src = op2; 
469 
FORCE_RET(); 
470 
} 
471  
472 
OP(fp_result) 
473 
{ 
474 
env>fp_result = get_opf64(PARAM1); 
475 
FORCE_RET(); 
476 
} 
477  
478 
OP(set_sr) 
479 
{ 
480 
env>sr = get_op(PARAM1) & 0xffff;

481 
m68k_switch_sp(env); 
482 
FORCE_RET(); 
483 
} 
484  
485 
OP(jmp) 
486 
{ 
487 
GOTO_LABEL_PARAM(1);

488 
} 
489  
490 
OP(set_T0_z32) 
491 
{ 
492 
uint32_t arg = get_op(PARAM1); 
493 
T0 = (arg == 0);

494 
FORCE_RET(); 
495 
} 
496  
497 
OP(set_T0_nz32) 
498 
{ 
499 
uint32_t arg = get_op(PARAM1); 
500 
T0 = (arg != 0);

501 
FORCE_RET(); 
502 
} 
503  
504 
OP(set_T0_s32) 
505 
{ 
506 
int32_t arg = get_op(PARAM1); 
507 
T0 = (arg > 0);

508 
FORCE_RET(); 
509 
} 
510  
511 
OP(set_T0_ns32) 
512 
{ 
513 
int32_t arg = get_op(PARAM1); 
514 
T0 = (arg >= 0);

515 
FORCE_RET(); 
516 
} 
517  
518 
OP(jmp_T0) 
519 
{ 
520 
if (T0)

521 
GOTO_LABEL_PARAM(1);

522 
FORCE_RET(); 
523 
} 
524  
525 
void OPPROTO op_goto_tb0(void) 
526 
{ 
527 
GOTO_TB(op_goto_tb0, PARAM1, 0);

528 
} 
529  
530 
void OPPROTO op_goto_tb1(void) 
531 
{ 
532 
GOTO_TB(op_goto_tb1, PARAM1, 1);

533 
} 
534  
535 
OP(exit_tb) 
536 
{ 
537 
EXIT_TB(); 
538 
} 
539  
540  
541 
/* Floating point. */

542 
OP(f64_to_i32) 
543 
{ 
544 
set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS)); 
545 
FORCE_RET(); 
546 
} 
547  
548 
OP(f64_to_f32) 
549 
{ 
550 
union {

551 
float32 f; 
552 
uint32_t i; 
553 
} u; 
554 
u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS); 
555 
set_op(PARAM1, u.i); 
556 
FORCE_RET(); 
557 
} 
558  
559 
OP(i32_to_f64) 
560 
{ 
561 
set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS)); 
562 
FORCE_RET(); 
563 
} 
564  
565 
OP(f32_to_f64) 
566 
{ 
567 
union {

568 
float32 f; 
569 
uint32_t i; 
570 
} u; 
571 
u.i = get_op(PARAM2); 
572 
set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS)); 
573 
FORCE_RET(); 
574 
} 
575  
576 
OP(absf64) 
577 
{ 
578 
float64 op0 = get_opf64(PARAM2); 
579 
set_opf64(PARAM1, float64_abs(op0)); 
580 
FORCE_RET(); 
581 
} 
582  
583 
OP(chsf64) 
584 
{ 
585 
float64 op0 = get_opf64(PARAM2); 
586 
set_opf64(PARAM1, float64_chs(op0)); 
587 
FORCE_RET(); 
588 
} 
589  
590 
OP(sqrtf64) 
591 
{ 
592 
float64 op0 = get_opf64(PARAM2); 
593 
set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS)); 
594 
FORCE_RET(); 
595 
} 
596  
597 
OP(addf64) 
598 
{ 
599 
float64 op0 = get_opf64(PARAM2); 
600 
float64 op1 = get_opf64(PARAM3); 
601 
set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS)); 
602 
FORCE_RET(); 
603 
} 
604  
605 
OP(subf64) 
606 
{ 
607 
float64 op0 = get_opf64(PARAM2); 
608 
float64 op1 = get_opf64(PARAM3); 
609 
set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS)); 
610 
FORCE_RET(); 
611 
} 
612  
613 
OP(mulf64) 
614 
{ 
615 
float64 op0 = get_opf64(PARAM2); 
616 
float64 op1 = get_opf64(PARAM3); 
617 
set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS)); 
618 
FORCE_RET(); 
619 
} 
620  
621 
OP(divf64) 
622 
{ 
623 
float64 op0 = get_opf64(PARAM2); 
624 
float64 op1 = get_opf64(PARAM3); 
625 
set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS)); 
626 
FORCE_RET(); 
627 
} 
628  
629 
OP(iround_f64) 
630 
{ 
631 
float64 op0 = get_opf64(PARAM2); 
632 
set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS)); 
633 
FORCE_RET(); 
634 
} 
635  
636 
OP(itrunc_f64) 
637 
{ 
638 
float64 op0 = get_opf64(PARAM2); 
639 
set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS)); 
640 
FORCE_RET(); 
641 
} 
642  
643 
OP(compare_quietf64) 
644 
{ 
645 
float64 op0 = get_opf64(PARAM2); 
646 
float64 op1 = get_opf64(PARAM3); 
647 
set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS)); 
648 
FORCE_RET(); 
649 
} 
650  
651 
OP(movec) 
652 
{ 
653 
int op1 = get_op(PARAM1);

654 
uint32_t op2 = get_op(PARAM2); 
655 
helper_movec(env, op1, op2); 
656 
} 
657  
658 
/* Memory access. */

659  
660 
#define MEMSUFFIX _raw

661 
#include "op_mem.h" 
662  
663 
#if !defined(CONFIG_USER_ONLY)

664 
#define MEMSUFFIX _user

665 
#include "op_mem.h" 
666 
#define MEMSUFFIX _kernel

667 
#include "op_mem.h" 
668 
#endif

669  
670 
/* MAC unit. */

671 
/* TODO: The MAC instructions use 64bit arithmetic fairly extensively.

672 
This results in fairly large ops (and sometimes other issues) on 32bit

673 
hosts. Maybe move most of them into helpers. */

674 
OP(macmuls) 
675 
{ 
676 
uint32_t op1 = get_op(PARAM1); 
677 
uint32_t op2 = get_op(PARAM2); 
678 
int64_t product; 
679 
int64_t res; 
680  
681 
product = (uint64_t)op1 * op2; 
682 
res = (product << 24) >> 24; 
683 
if (res != product) {

684 
env>macsr = MACSR_V; 
685 
if (env>macsr & MACSR_OMC) {

686 
/* Make sure the accumulate operation overflows. */

687 
if (product < 0) 
688 
res = ~(1ll << 50); 
689 
else

690 
res = 1ll << 50; 
691 
} 
692 
} 
693 
env>mactmp = res; 
694 
FORCE_RET(); 
695 
} 
696  
697 
OP(macmulu) 
698 
{ 
699 
uint32_t op1 = get_op(PARAM1); 
700 
uint32_t op2 = get_op(PARAM2); 
701 
uint64_t product; 
702  
703 
product = (uint64_t)op1 * op2; 
704 
if (product & (0xffffffull << 40)) { 
705 
env>macsr = MACSR_V; 
706 
if (env>macsr & MACSR_OMC) {

707 
/* Make sure the accumulate operation overflows. */

708 
product = 1ll << 50; 
709 
} else {

710 
product &= ((1ull << 40)  1); 
711 
} 
712 
} 
713 
env>mactmp = product; 
714 
FORCE_RET(); 
715 
} 
716  
717 
OP(macmulf) 
718 
{ 
719 
int32_t op1 = get_op(PARAM1); 
720 
int32_t op2 = get_op(PARAM2); 
721 
uint64_t product; 
722 
uint32_t remainder; 
723  
724 
product = (uint64_t)op1 * op2; 
725 
if (env>macsr & MACSR_RT) {

726 
remainder = product & 0xffffff;

727 
product >>= 24;

728 
if (remainder > 0x800000) 
729 
product++; 
730 
else if (remainder == 0x800000) 
731 
product += (product & 1);

732 
} else {

733 
product >>= 24;

734 
} 
735 
env>mactmp = product; 
736 
FORCE_RET(); 
737 
} 
738  
739 
OP(macshl) 
740 
{ 
741 
env>mactmp <<= 1;

742 
} 
743  
744 
OP(macshr) 
745 
{ 
746 
env>mactmp >>= 1;

747 
} 
748  
749 
OP(macadd) 
750 
{ 
751 
int acc = PARAM1;

752 
env>macc[acc] += env>mactmp; 
753 
FORCE_RET(); 
754 
} 
755  
756 
OP(macsub) 
757 
{ 
758 
int acc = PARAM1;

759 
env>macc[acc] = env>mactmp; 
760 
FORCE_RET(); 
761 
} 
762  
763 
OP(macsats) 
764 
{ 
765 
int acc = PARAM1;

766 
int64_t sum; 
767 
int64_t result; 
768  
769 
sum = env>macc[acc]; 
770 
result = (sum << 16) >> 16; 
771 
if (result != sum) {

772 
env>macsr = MACSR_V; 
773 
} 
774 
if (env>macsr & MACSR_V) {

775 
env>macsr = MACSR_PAV0 << acc; 
776 
if (env>macsr & MACSR_OMC) {

777 
/* The result is saturated to 32 bits, despite overflow occuring

778 
at 48 bits. Seems weird, but that's what the hardware docs

779 
say. */

780 
result = (result >> 63) ^ 0x7fffffff; 
781 
} 
782 
} 
783 
env>macc[acc] = result; 
784 
FORCE_RET(); 
785 
} 
786  
787 
OP(macsatu) 
788 
{ 
789 
int acc = PARAM1;

790 
uint64_t sum; 
791  
792 
sum = env>macc[acc]; 
793 
if (sum & (0xffffull << 48)) { 
794 
env>macsr = MACSR_V; 
795 
} 
796 
if (env>macsr & MACSR_V) {

797 
env>macsr = MACSR_PAV0 << acc; 
798 
if (env>macsr & MACSR_OMC) {

799 
if (sum > (1ull << 53)) 
800 
sum = 0;

801 
else

802 
sum = (1ull << 48)  1; 
803 
} else {

804 
sum &= ((1ull << 48)  1); 
805 
} 
806 
} 
807 
FORCE_RET(); 
808 
} 
809  
810 
OP(macsatf) 
811 
{ 
812 
int acc = PARAM1;

813 
int64_t sum; 
814 
int64_t result; 
815  
816 
sum = env>macc[acc]; 
817 
result = (sum << 16) >> 16; 
818 
if (result != sum) {

819 
env>macsr = MACSR_V; 
820 
} 
821 
if (env>macsr & MACSR_V) {

822 
env>macsr = MACSR_PAV0 << acc; 
823 
if (env>macsr & MACSR_OMC) {

824 
result = (result >> 63) ^ 0x7fffffffffffll; 
825 
} 
826 
} 
827 
env>macc[acc] = result; 
828 
FORCE_RET(); 
829 
} 
830  
831 
OP(mac_clear_flags) 
832 
{ 
833 
env>macsr &= ~(MACSR_V  MACSR_Z  MACSR_N  MACSR_EV); 
834 
} 
835  
836 
OP(mac_set_flags) 
837 
{ 
838 
int acc = PARAM1;

839 
uint64_t val; 
840 
val = env>macc[acc]; 
841 
if (val == 0) 
842 
env>macsr = MACSR_Z; 
843 
else if (val & (1ull << 47)); 
844 
env>macsr = MACSR_N; 
845 
if (env>macsr & (MACSR_PAV0 << acc)) {

846 
env>macsr = MACSR_V; 
847 
} 
848 
if (env>macsr & MACSR_FI) {

849 
val = ((int64_t)val) >> 40;

850 
if (val != 0 && val != 1) 
851 
env>macsr = MACSR_EV; 
852 
} else if (env>macsr & MACSR_SU) { 
853 
val = ((int64_t)val) >> 32;

854 
if (val != 0 && val != 1) 
855 
env>macsr = MACSR_EV; 
856 
} else {

857 
if ((val >> 32) != 0) 
858 
env>macsr = MACSR_EV; 
859 
} 
860 
FORCE_RET(); 
861 
} 
862  
863 
OP(get_macf) 
864 
{ 
865 
int acc = PARAM2;

866 
int64_t val; 
867 
int rem;

868 
uint32_t result; 
869  
870 
val = env>macc[acc]; 
871 
if (env>macsr & MACSR_SU) {

872 
/* 16bit rounding. */

873 
rem = val & 0xffffff;

874 
val = (val >> 24) & 0xffffu; 
875 
if (rem > 0x800000) 
876 
val++; 
877 
else if (rem == 0x800000) 
878 
val += (val & 1);

879 
} else if (env>macsr & MACSR_RT) { 
880 
/* 32bit rounding. */

881 
rem = val & 0xff;

882 
val >>= 8;

883 
if (rem > 0x80) 
884 
val++; 
885 
else if (rem == 0x80) 
886 
val += (val & 1);

887 
} else {

888 
/* No rounding. */

889 
val >>= 8;

890 
} 
891 
if (env>macsr & MACSR_OMC) {

892 
/* Saturate. */

893 
if (env>macsr & MACSR_SU) {

894 
if (val != (uint16_t) val) {

895 
result = ((val >> 63) ^ 0x7fff) & 0xffff; 
896 
} else {

897 
result = val & 0xffff;

898 
} 
899 
} else {

900 
if (val != (uint32_t)val) {

901 
result = ((uint32_t)(val >> 63) & 0x7fffffff); 
902 
} else {

903 
result = (uint32_t)val; 
904 
} 
905 
} 
906 
} else {

907 
/* No saturation. */

908 
if (env>macsr & MACSR_SU) {

909 
result = val & 0xffff;

910 
} else {

911 
result = (uint32_t)val; 
912 
} 
913 
} 
914 
set_op(PARAM1, result); 
915 
FORCE_RET(); 
916 
} 
917  
918 
OP(get_maci) 
919 
{ 
920 
int acc = PARAM2;

921 
set_op(PARAM1, (uint32_t)env>macc[acc]); 
922 
FORCE_RET(); 
923 
} 
924  
925 
OP(get_macs) 
926 
{ 
927 
int acc = PARAM2;

928 
int64_t val = env>macc[acc]; 
929 
uint32_t result; 
930 
if (val == (int32_t)val) {

931 
result = (int32_t)val; 
932 
} else {

933 
result = (val >> 61) ^ 0x7fffffff; 
934 
} 
935 
set_op(PARAM1, result); 
936 
FORCE_RET(); 
937 
} 
938  
939 
OP(get_macu) 
940 
{ 
941 
int acc = PARAM2;

942 
uint64_t val = env>macc[acc]; 
943 
uint32_t result; 
944 
if ((val >> 32) == 0) { 
945 
result = (uint32_t)val; 
946 
} else {

947 
result = 0xffffffffu;

948 
} 
949 
set_op(PARAM1, result); 
950 
FORCE_RET(); 
951 
} 
952  
953 
OP(clear_mac) 
954 
{ 
955 
int acc = PARAM1;

956  
957 
env>macc[acc] = 0;

958 
env>macsr &= ~(MACSR_PAV0 << acc); 
959 
FORCE_RET(); 
960 
} 
961  
962 
OP(move_mac) 
963 
{ 
964 
int dest = PARAM1;

965 
int src = PARAM2;

966 
uint32_t mask; 
967 
env>macc[dest] = env>macc[src]; 
968 
mask = MACSR_PAV0 << dest; 
969 
if (env>macsr & (MACSR_PAV0 << src))

970 
env>macsr = mask; 
971 
else

972 
env>macsr &= ~mask; 
973 
FORCE_RET(); 
974 
} 
975  
976 
OP(get_mac_extf) 
977 
{ 
978 
uint32_t val; 
979 
int acc = PARAM2;

980 
val = env>macc[acc] & 0x00ff;

981 
val = (env>macc[acc] >> 32) & 0xff00; 
982 
val = (env>macc[acc + 1] << 16) & 0x00ff0000; 
983 
val = (env>macc[acc + 1] >> 16) & 0xff000000; 
984 
set_op(PARAM1, val); 
985 
FORCE_RET(); 
986 
} 
987  
988 
OP(get_mac_exti) 
989 
{ 
990 
uint32_t val; 
991 
int acc = PARAM2;

992 
val = (env>macc[acc] >> 32) & 0xffff; 
993 
val = (env>macc[acc + 1] >> 16) & 0xffff0000; 
994 
set_op(PARAM1, val); 
995 
FORCE_RET(); 
996 
} 
997  
998 
OP(set_macf) 
999 
{ 
1000 
int acc = PARAM2;

1001 
int32_t val = get_op(PARAM1); 
1002 
env>macc[acc] = ((int64_t)val) << 8;

1003 
env>macsr &= ~(MACSR_PAV0 << acc); 
1004 
FORCE_RET(); 
1005 
} 
1006  
1007 
OP(set_macs) 
1008 
{ 
1009 
int acc = PARAM2;

1010 
int32_t val = get_op(PARAM1); 
1011 
env>macc[acc] = val; 
1012 
env>macsr &= ~(MACSR_PAV0 << acc); 
1013 
FORCE_RET(); 
1014 
} 
1015  
1016 
OP(set_macu) 
1017 
{ 
1018 
int acc = PARAM2;

1019 
uint32_t val = get_op(PARAM1); 
1020 
env>macc[acc] = val; 
1021 
env>macsr &= ~(MACSR_PAV0 << acc); 
1022 
FORCE_RET(); 
1023 
} 
1024  
1025 
OP(set_mac_extf) 
1026 
{ 
1027 
int acc = PARAM2;

1028 
int32_t val = get_op(PARAM1); 
1029 
int64_t res; 
1030 
int32_t tmp; 
1031 
res = env>macc[acc] & 0xffffffff00ull;

1032 
tmp = (int16_t)(val & 0xff00);

1033 
res = ((int64_t)tmp) << 32;

1034 
res = val & 0xff;

1035 
env>macc[acc] = res; 
1036 
res = env>macc[acc + 1] & 0xffffffff00ull; 
1037 
tmp = (val & 0xff000000);

1038 
res = ((int64_t)tmp) << 16;

1039 
res = (val >> 16) & 0xff; 
1040 
env>macc[acc + 1] = res;

1041 
} 
1042  
1043 
OP(set_mac_exts) 
1044 
{ 
1045 
int acc = PARAM2;

1046 
int32_t val = get_op(PARAM1); 
1047 
int64_t res; 
1048 
int32_t tmp; 
1049 
res = (uint32_t)env>macc[acc]; 
1050 
tmp = (int16_t)val; 
1051 
res = ((int64_t)tmp) << 32;

1052 
env>macc[acc] = res; 
1053 
res = (uint32_t)env>macc[acc + 1];

1054 
tmp = val & 0xffff0000;

1055 
res = (int64_t)tmp << 16;

1056 
env>macc[acc + 1] = res;

1057 
} 
1058  
1059 
OP(set_mac_extu) 
1060 
{ 
1061 
int acc = PARAM2;

1062 
int32_t val = get_op(PARAM1); 
1063 
uint64_t res; 
1064 
res = (uint32_t)env>macc[acc]; 
1065 
res = ((uint64_t)(val & 0xffff)) << 32; 
1066 
env>macc[acc] = res; 
1067 
res = (uint32_t)env>macc[acc + 1];

1068 
res = (uint64_t)(val & 0xffff0000) << 16; 
1069 
env>macc[acc + 1] = res;

1070 
} 
1071  
1072 
OP(set_macsr) 
1073 
{ 
1074 
m68k_set_macsr(env, get_op(PARAM1)); 
1075 
} 