[sim/rx]
[binutils-gdb.git] / sim / rx / rx.c
1 /* rx.c --- opcode semantics for stand-alone RX simulator.
2
3 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
5
6 This file is part of the GNU simulators.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <signal.h>
26
27 #include "opcode/rx.h"
28 #include "cpu.h"
29 #include "mem.h"
30 #include "syscalls.h"
31 #include "fpu.h"
32 #include "err.h"
33 #include "misc.h"
34
35 #ifdef CYCLE_STATS
36 static const char * id_names[] = {
37 "RXO_unknown",
38 "RXO_mov", /* d = s (signed) */
39 "RXO_movbi", /* d = [s,s2] (signed) */
40 "RXO_movbir", /* [s,s2] = d (signed) */
41 "RXO_pushm", /* s..s2 */
42 "RXO_popm", /* s..s2 */
43 "RXO_xchg", /* s <-> d */
44 "RXO_stcc", /* d = s if cond(s2) */
45 "RXO_rtsd", /* rtsd, 1=imm, 2-0 = reg if reg type */
46
47 /* These are all either d OP= s or, if s2 is set, d = s OP s2. Note
48 that d may be "None". */
49 "RXO_and",
50 "RXO_or",
51 "RXO_xor",
52 "RXO_add",
53 "RXO_sub",
54 "RXO_mul",
55 "RXO_div",
56 "RXO_divu",
57 "RXO_shll",
58 "RXO_shar",
59 "RXO_shlr",
60
61 "RXO_adc", /* d = d + s + carry */
62 "RXO_sbb", /* d = d - s - ~carry */
63 "RXO_abs", /* d = |s| */
64 "RXO_max", /* d = max(d,s) */
65 "RXO_min", /* d = min(d,s) */
66 "RXO_emul", /* d:64 = d:32 * s */
67 "RXO_emulu", /* d:64 = d:32 * s (unsigned) */
68 "RXO_ediv", /* d:64 / s; d = quot, d+1 = rem */
69 "RXO_edivu", /* d:64 / s; d = quot, d+1 = rem */
70
71 "RXO_rolc", /* d <<= 1 through carry */
72 "RXO_rorc", /* d >>= 1 through carry*/
73 "RXO_rotl", /* d <<= #s without carry */
74 "RXO_rotr", /* d >>= #s without carry*/
75 "RXO_revw", /* d = revw(s) */
76 "RXO_revl", /* d = revl(s) */
77 "RXO_branch", /* pc = d if cond(s) */
78 "RXO_branchrel",/* pc += d if cond(s) */
79 "RXO_jsr", /* pc = d */
80 "RXO_jsrrel", /* pc += d */
81 "RXO_rts",
82 "RXO_nop",
83 "RXO_nop2",
84 "RXO_nop3",
85
86 "RXO_scmpu",
87 "RXO_smovu",
88 "RXO_smovb",
89 "RXO_suntil",
90 "RXO_swhile",
91 "RXO_smovf",
92 "RXO_sstr",
93
94 "RXO_rmpa",
95 "RXO_mulhi",
96 "RXO_mullo",
97 "RXO_machi",
98 "RXO_maclo",
99 "RXO_mvtachi",
100 "RXO_mvtaclo",
101 "RXO_mvfachi",
102 "RXO_mvfacmi",
103 "RXO_mvfaclo",
104 "RXO_racw",
105
106 "RXO_sat", /* sat(d) */
107 "RXO_satr",
108
109 "RXO_fadd", /* d op= s */
110 "RXO_fcmp",
111 "RXO_fsub",
112 "RXO_ftoi",
113 "RXO_fmul",
114 "RXO_fdiv",
115 "RXO_round",
116 "RXO_itof",
117
118 "RXO_bset", /* d |= (1<<s) */
119 "RXO_bclr", /* d &= ~(1<<s) */
120 "RXO_btst", /* s & (1<<s2) */
121 "RXO_bnot", /* d ^= (1<<s) */
122 "RXO_bmcc", /* d<s> = cond(s2) */
123
124 "RXO_clrpsw", /* flag index in d */
125 "RXO_setpsw", /* flag index in d */
126 "RXO_mvtipl", /* new IPL in s */
127
128 "RXO_rtfi",
129 "RXO_rte",
130 "RXO_rtd", /* undocumented */
131 "RXO_brk",
132 "RXO_dbt", /* undocumented */
133 "RXO_int", /* vector id in s */
134 "RXO_stop",
135 "RXO_wait",
136
137 "RXO_sccnd", /* d = cond(s) ? 1 : 0 */
138 };
139
140 static const char * optype_names[] = {
141 " ",
142 "#Imm", /* #addend */
143 " Rn ", /* Rn */
144 "[Rn]", /* [Rn + addend] */
145 "Ps++", /* [Rn+] */
146 "--Pr", /* [-Rn] */
147 " cc ", /* eq, gtu, etc */
148 "Flag" /* [UIOSZC] */
149 };
150
151 #define N_RXO (sizeof(id_names)/sizeof(id_names[0]))
152 #define N_RXT (sizeof(optype_names)/sizeof(optype_names[0]))
153 #define N_MAP 30
154
155 static unsigned long long benchmark_start_cycle;
156 static unsigned long long benchmark_end_cycle;
157
158 static int op_cache[N_RXT][N_RXT][N_RXT];
159 static int op_cache_rev[N_MAP];
160 static int op_cache_idx = 0;
161
162 static int
163 op_lookup (int a, int b, int c)
164 {
165 if (op_cache[a][b][c])
166 return op_cache[a][b][c];
167 op_cache_idx ++;
168 if (op_cache_idx >= N_MAP)
169 {
170 printf("op_cache_idx exceeds %d\n", N_MAP);
171 exit(1);
172 }
173 op_cache[a][b][c] = op_cache_idx;
174 op_cache_rev[op_cache_idx] = (a<<8) | (b<<4) | c;
175 return op_cache_idx;
176 }
177
178 static char *
179 op_cache_string (int map)
180 {
181 static int ci;
182 static char cb[5][20];
183 int a, b, c;
184
185 map = op_cache_rev[map];
186 a = (map >> 8) & 15;
187 b = (map >> 4) & 15;
188 c = (map >> 0) & 15;
189 ci = (ci + 1) % 5;
190 sprintf(cb[ci], "%s %s %s", optype_names[a], optype_names[b], optype_names[c]);
191 return cb[ci];
192 }
193
194 static unsigned long long cycles_per_id[N_RXO][N_MAP];
195 static unsigned long long times_per_id[N_RXO][N_MAP];
196 static unsigned long long memory_stalls;
197 static unsigned long long register_stalls;
198 static unsigned long long branch_stalls;
199 static unsigned long long branch_alignment_stalls;
200 static unsigned long long fast_returns;
201
202 static unsigned long times_per_pair[N_RXO][N_MAP][N_RXO][N_MAP];
203 static int prev_opcode_id = RXO_unknown;
204 static int po0;
205
206 #define STATS(x) x
207
208 #else
209 #define STATS(x)
210 #endif /* CYCLE_STATS */
211
212
213 #ifdef CYCLE_ACCURATE
214
215 static int new_rt = -1;
216
217 /* Number of cycles to add if an insn spans an 8-byte boundary. */
218 static int branch_alignment_penalty = 0;
219
220 #endif
221
222 static int running_benchmark = 1;
223
224 #define tprintf if (trace && running_benchmark) printf
225
226 jmp_buf decode_jmp_buf;
227 unsigned int rx_cycles = 0;
228
229 #ifdef CYCLE_ACCURATE
230 /* If nonzero, memory was read at some point and cycle latency might
231 take effect. */
232 static int memory_source = 0;
233 /* If nonzero, memory was written and extra cycles might be
234 needed. */
235 static int memory_dest = 0;
236
237 static void
238 cycles (int throughput)
239 {
240 tprintf("%d cycles\n", throughput);
241 regs.cycle_count += throughput;
242 }
243
244 /* Number of execution (E) cycles the op uses. For memory sources, we
245 include the load micro-op stall as two extra E cycles. */
246 #define E(c) cycles (memory_source ? c + 2 : c)
247 #define E1 cycles (1)
248 #define E2 cycles (2)
249 #define EBIT cycles (memory_source ? 2 : 1)
250
251 /* Check to see if a read latency must be applied for a given register. */
252 #define RL(r) \
253 if (regs.rt == r ) \
254 { \
255 tprintf("register %d load stall\n", r); \
256 regs.cycle_count ++; \
257 STATS(register_stalls ++); \
258 regs.rt = -1; \
259 }
260
261 #define RLD(r) \
262 if (memory_source) \
263 { \
264 tprintf ("Rt now %d\n", r); \
265 new_rt = r; \
266 }
267
268 #else /* !CYCLE_ACCURATE */
269
270 #define cycles(t)
271 #define E(c)
272 #define E1
273 #define E2
274 #define EBIT
275 #define RL(r)
276 #define RLD(r)
277
278 #endif /* else CYCLE_ACCURATE */
279
280 static int size2bytes[] = {
281 4, 1, 1, 1, 2, 2, 2, 3, 4
282 };
283
284 typedef struct {
285 unsigned long dpc;
286 } RX_Data;
287
288 #define rx_abort() _rx_abort(__FILE__, __LINE__)
289 static void
290 _rx_abort (const char *file, int line)
291 {
292 if (strrchr (file, '/'))
293 file = strrchr (file, '/') + 1;
294 fprintf(stderr, "abort at %s:%d\n", file, line);
295 abort();
296 }
297
298 static unsigned char *get_byte_base;
299 static SI get_byte_page;
300
301 /* This gets called a *lot* so optimize it. */
302 static int
303 rx_get_byte (void *vdata)
304 {
305 RX_Data *rx_data = (RX_Data *)vdata;
306 SI tpc = rx_data->dpc;
307
308 /* See load.c for an explanation of this. */
309 if (rx_big_endian)
310 tpc ^= 3;
311
312 if (((tpc ^ get_byte_page) & NONPAGE_MASK) || enable_counting)
313 {
314 get_byte_page = tpc & NONPAGE_MASK;
315 get_byte_base = rx_mem_ptr (get_byte_page, MPA_READING) - get_byte_page;
316 }
317
318 rx_data->dpc ++;
319 return get_byte_base [tpc];
320 }
321
322 static int
323 get_op (RX_Opcode_Decoded *rd, int i)
324 {
325 RX_Opcode_Operand *o = rd->op + i;
326 int addr, rv = 0;
327
328 switch (o->type)
329 {
330 case RX_Operand_None:
331 rx_abort ();
332
333 case RX_Operand_Immediate: /* #addend */
334 return o->addend;
335
336 case RX_Operand_Register: /* Rn */
337 RL (o->reg);
338 rv = get_reg (o->reg);
339 break;
340
341 case RX_Operand_Predec: /* [-Rn] */
342 put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]);
343 /* fall through */
344 case RX_Operand_Postinc: /* [Rn+] */
345 case RX_Operand_Indirect: /* [Rn + addend] */
346 #ifdef CYCLE_ACCURATE
347 RL (o->reg);
348 regs.rt = -1;
349 if (regs.m2m == M2M_BOTH)
350 {
351 tprintf("src memory stall\n");
352 #ifdef CYCLE_STATS
353 memory_stalls ++;
354 #endif
355 regs.cycle_count ++;
356 regs.m2m = 0;
357 }
358
359 memory_source = 1;
360 #endif
361
362 addr = get_reg (o->reg) + o->addend;
363 switch (o->size)
364 {
365 case RX_AnySize:
366 rx_abort ();
367
368 case RX_Byte: /* undefined extension */
369 case RX_UByte:
370 case RX_SByte:
371 rv = mem_get_qi (addr);
372 break;
373
374 case RX_Word: /* undefined extension */
375 case RX_UWord:
376 case RX_SWord:
377 rv = mem_get_hi (addr);
378 break;
379
380 case RX_3Byte:
381 rv = mem_get_psi (addr);
382 break;
383
384 case RX_Long:
385 rv = mem_get_si (addr);
386 break;
387 }
388
389 if (o->type == RX_Operand_Postinc)
390 put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]);
391
392 break;
393
394 case RX_Operand_Condition: /* eq, gtu, etc */
395 return condition_true (o->reg);
396
397 case RX_Operand_Flag: /* [UIOSZC] */
398 return (regs.r_psw & (1 << o->reg)) ? 1 : 0;
399 }
400
401 /* if we've gotten here, we need to clip/extend the value according
402 to the size. */
403 switch (o->size)
404 {
405 case RX_AnySize:
406 rx_abort ();
407
408 case RX_Byte: /* undefined extension */
409 rv |= 0xdeadbe00; /* keep them honest */
410 break;
411
412 case RX_UByte:
413 rv &= 0xff;
414 break;
415
416 case RX_SByte:
417 rv = sign_ext (rv, 8);
418 break;
419
420 case RX_Word: /* undefined extension */
421 rv |= 0xdead0000; /* keep them honest */
422 break;
423
424 case RX_UWord:
425 rv &= 0xffff;
426 break;
427
428 case RX_SWord:
429 rv = sign_ext (rv, 16);
430 break;
431
432 case RX_3Byte:
433 rv &= 0xffffff;
434 break;
435
436 case RX_Long:
437 break;
438 }
439 return rv;
440 }
441
442 static void
443 put_op (RX_Opcode_Decoded *rd, int i, int v)
444 {
445 RX_Opcode_Operand *o = rd->op + i;
446 int addr;
447
448 switch (o->size)
449 {
450 case RX_AnySize:
451 if (o->type != RX_Operand_Register)
452 rx_abort ();
453 break;
454
455 case RX_Byte: /* undefined extension */
456 v |= 0xdeadbe00; /* keep them honest */
457 break;
458
459 case RX_UByte:
460 v &= 0xff;
461 break;
462
463 case RX_SByte:
464 v = sign_ext (v, 8);
465 break;
466
467 case RX_Word: /* undefined extension */
468 v |= 0xdead0000; /* keep them honest */
469 break;
470
471 case RX_UWord:
472 v &= 0xffff;
473 break;
474
475 case RX_SWord:
476 v = sign_ext (v, 16);
477 break;
478
479 case RX_3Byte:
480 v &= 0xffffff;
481 break;
482
483 case RX_Long:
484 break;
485 }
486
487 switch (o->type)
488 {
489 case RX_Operand_None:
490 /* Opcodes like TST and CMP use this. */
491 break;
492
493 case RX_Operand_Immediate: /* #addend */
494 case RX_Operand_Condition: /* eq, gtu, etc */
495 rx_abort ();
496
497 case RX_Operand_Register: /* Rn */
498 put_reg (o->reg, v);
499 RLD (o->reg);
500 break;
501
502 case RX_Operand_Predec: /* [-Rn] */
503 put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]);
504 /* fall through */
505 case RX_Operand_Postinc: /* [Rn+] */
506 case RX_Operand_Indirect: /* [Rn + addend] */
507
508 #ifdef CYCLE_ACCURATE
509 if (regs.m2m == M2M_BOTH)
510 {
511 tprintf("dst memory stall\n");
512 regs.cycle_count ++;
513 #ifdef CYCLE_STATS
514 memory_stalls ++;
515 #endif
516 regs.m2m = 0;
517 }
518 memory_dest = 1;
519 #endif
520
521 addr = get_reg (o->reg) + o->addend;
522 switch (o->size)
523 {
524 case RX_AnySize:
525 rx_abort ();
526
527 case RX_Byte: /* undefined extension */
528 case RX_UByte:
529 case RX_SByte:
530 mem_put_qi (addr, v);
531 break;
532
533 case RX_Word: /* undefined extension */
534 case RX_UWord:
535 case RX_SWord:
536 mem_put_hi (addr, v);
537 break;
538
539 case RX_3Byte:
540 mem_put_psi (addr, v);
541 break;
542
543 case RX_Long:
544 mem_put_si (addr, v);
545 break;
546 }
547
548 if (o->type == RX_Operand_Postinc)
549 put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]);
550
551 break;
552
553 case RX_Operand_Flag: /* [UIOSZC] */
554 if (v)
555 regs.r_psw |= (1 << o->reg);
556 else
557 regs.r_psw &= ~(1 << o->reg);
558 break;
559 }
560 }
561
562 #define PD(x) put_op (&opcode, 0, x)
563 #define PS(x) put_op (&opcode, 1, x)
564 #define PS2(x) put_op (&opcode, 2, x)
565 #define GD() get_op (&opcode, 0)
566 #define GS() get_op (&opcode, 1)
567 #define GS2() get_op (&opcode, 2)
568 #define DSZ() size2bytes[opcode.op[0].size]
569 #define SSZ() size2bytes[opcode.op[0].size]
570 #define S2SZ() size2bytes[opcode.op[0].size]
571
572 /* "Universal" sources. */
573 #define US1() ((opcode.op[2].type == RX_Operand_None) ? GD() : GS())
574 #define US2() ((opcode.op[2].type == RX_Operand_None) ? GS() : GS2())
575
576 static void
577 push(int val)
578 {
579 int rsp = get_reg (sp);
580 rsp -= 4;
581 put_reg (sp, rsp);
582 mem_put_si (rsp, val);
583 }
584
585 /* Just like the above, but tag the memory as "pushed pc" so if anyone
586 tries to write to it, it will cause an error. */
587 static void
588 pushpc(int val)
589 {
590 int rsp = get_reg (sp);
591 rsp -= 4;
592 put_reg (sp, rsp);
593 mem_put_si (rsp, val);
594 mem_set_content_range (rsp, rsp+3, MC_PUSHED_PC);
595 }
596
597 static int
598 pop()
599 {
600 int rv;
601 int rsp = get_reg (sp);
602 rv = mem_get_si (rsp);
603 rsp += 4;
604 put_reg (sp, rsp);
605 return rv;
606 }
607
608 static int
609 poppc()
610 {
611 int rv;
612 int rsp = get_reg (sp);
613 if (mem_get_content_type (rsp) != MC_PUSHED_PC)
614 execution_error (SIM_ERR_CORRUPT_STACK, rsp);
615 rv = mem_get_si (rsp);
616 mem_set_content_range (rsp, rsp+3, MC_UNINIT);
617 rsp += 4;
618 put_reg (sp, rsp);
619 return rv;
620 }
621
622 #define MATH_OP(vop,c) \
623 { \
624 umb = US2(); \
625 uma = US1(); \
626 ll = (unsigned long long) uma vop (unsigned long long) umb vop c; \
627 tprintf ("0x%x " #vop " 0x%x " #vop " 0x%x = 0x%llx\n", uma, umb, c, ll); \
628 ma = sign_ext (uma, DSZ() * 8); \
629 mb = sign_ext (umb, DSZ() * 8); \
630 sll = (long long) ma vop (long long) mb vop c; \
631 tprintf ("%d " #vop " %d " #vop " %d = %lld\n", ma, mb, c, sll); \
632 set_oszc (sll, DSZ(), (long long) ll > ((1 vop 1) ? (long long) b2mask[DSZ()] : (long long) -1)); \
633 PD (sll); \
634 E (1); \
635 }
636
637 #define LOGIC_OP(vop) \
638 { \
639 mb = US2(); \
640 ma = US1(); \
641 v = ma vop mb; \
642 tprintf("0x%x " #vop " 0x%x = 0x%x\n", ma, mb, v); \
643 set_sz (v, DSZ()); \
644 PD(v); \
645 E (1); \
646 }
647
648 #define SHIFT_OP(val, type, count, OP, carry_mask) \
649 { \
650 int i, c=0; \
651 count = US2(); \
652 val = (type)US1(); \
653 tprintf("%lld " #OP " %d\n", val, count); \
654 for (i = 0; i < count; i ++) \
655 { \
656 c = val & carry_mask; \
657 val OP 1; \
658 } \
659 if (count) \
660 set_oszc (val, 4, c); \
661 PD (val); \
662 }
663
664 typedef union {
665 int i;
666 float f;
667 } FloatInt;
668
669 static inline int
670 float2int (float f)
671 {
672 FloatInt fi;
673 fi.f = f;
674 return fi.i;
675 }
676
677 static inline float
678 int2float (int i)
679 {
680 FloatInt fi;
681 fi.i = i;
682 return fi.f;
683 }
684
685 static int
686 fop_fadd (fp_t s1, fp_t s2, fp_t *d)
687 {
688 *d = rxfp_add (s1, s2);
689 return 1;
690 }
691
692 static int
693 fop_fmul (fp_t s1, fp_t s2, fp_t *d)
694 {
695 *d = rxfp_mul (s1, s2);
696 return 1;
697 }
698
699 static int
700 fop_fdiv (fp_t s1, fp_t s2, fp_t *d)
701 {
702 *d = rxfp_div (s1, s2);
703 return 1;
704 }
705
706 static int
707 fop_fsub (fp_t s1, fp_t s2, fp_t *d)
708 {
709 *d = rxfp_sub (s1, s2);
710 return 1;
711 }
712
713 #define FPPENDING() (regs.r_fpsw & (FPSWBITS_CE | (FPSWBITS_FMASK & (regs.r_fpsw << FPSW_EFSH))))
714 #define FPCLEAR() regs.r_fpsw &= FPSWBITS_CLEAR
715 #define FPCHECK() \
716 if (FPPENDING()) \
717 return do_fp_exception (opcode_pc)
718
719 #define FLOAT_OP(func) \
720 { \
721 int do_store; \
722 fp_t fa, fb, fc; \
723 FPCLEAR(); \
724 fb = GS (); \
725 fa = GD (); \
726 do_store = fop_##func (fa, fb, &fc); \
727 tprintf("%g " #func " %g = %g %08x\n", int2float(fa), int2float(fb), int2float(fc), fc); \
728 FPCHECK(); \
729 if (do_store) \
730 PD (fc); \
731 mb = 0; \
732 if ((fc & 0x80000000UL) != 0) \
733 mb |= FLAGBIT_S; \
734 if ((fc & 0x7fffffffUL) == 0) \
735 mb |= FLAGBIT_Z; \
736 set_flags (FLAGBIT_S | FLAGBIT_Z, mb); \
737 }
738
739 #define carry (FLAG_C ? 1 : 0)
740
741 static struct {
742 unsigned long vaddr;
743 const char *str;
744 int signal;
745 } exception_info[] = {
746 { 0xFFFFFFD0UL, "priviledged opcode", SIGILL },
747 { 0xFFFFFFD4UL, "access violation", SIGSEGV },
748 { 0xFFFFFFDCUL, "undefined opcode", SIGILL },
749 { 0xFFFFFFE4UL, "floating point", SIGFPE }
750 };
751 #define EX_PRIVILEDGED 0
752 #define EX_ACCESS 1
753 #define EX_UNDEFINED 2
754 #define EX_FLOATING 3
755 #define EXCEPTION(n) \
756 return generate_exception (n, opcode_pc)
757
758 #define PRIVILEDGED() \
759 if (FLAG_PM) \
760 EXCEPTION (EX_PRIVILEDGED)
761
762 static int
763 generate_exception (unsigned long type, SI opcode_pc)
764 {
765 SI old_psw, old_pc, new_pc;
766
767 new_pc = mem_get_si (exception_info[type].vaddr);
768 /* 0x00020000 is the value used to initialise the known
769 exception vectors (see rx.ld), but it is a reserved
770 area of memory so do not try to access it, and if the
771 value has not been changed by the program then the
772 vector has not been installed. */
773 if (new_pc == 0 || new_pc == 0x00020000)
774 {
775 if (rx_in_gdb)
776 return RX_MAKE_STOPPED (exception_info[type].signal);
777
778 fprintf(stderr, "Unhandled %s exception at pc = %#lx\n",
779 exception_info[type].str, (unsigned long) opcode_pc);
780 if (type == EX_FLOATING)
781 {
782 int mask = FPPENDING ();
783 fprintf (stderr, "Pending FP exceptions:");
784 if (mask & FPSWBITS_FV)
785 fprintf(stderr, " Invalid");
786 if (mask & FPSWBITS_FO)
787 fprintf(stderr, " Overflow");
788 if (mask & FPSWBITS_FZ)
789 fprintf(stderr, " Division-by-zero");
790 if (mask & FPSWBITS_FU)
791 fprintf(stderr, " Underflow");
792 if (mask & FPSWBITS_FX)
793 fprintf(stderr, " Inexact");
794 if (mask & FPSWBITS_CE)
795 fprintf(stderr, " Unimplemented");
796 fprintf(stderr, "\n");
797 }
798 return RX_MAKE_EXITED (1);
799 }
800
801 tprintf ("Triggering %s exception\n", exception_info[type].str);
802
803 old_psw = regs.r_psw;
804 regs.r_psw &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
805 old_pc = opcode_pc;
806 regs.r_pc = new_pc;
807 pushpc (old_psw);
808 pushpc (old_pc);
809 return RX_MAKE_STEPPED ();
810 }
811
812 void
813 generate_access_exception (void)
814 {
815 int rv;
816
817 rv = generate_exception (EX_ACCESS, regs.r_pc);
818 if (RX_EXITED (rv))
819 longjmp (decode_jmp_buf, rv);
820 }
821
822 static int
823 do_fp_exception (unsigned long opcode_pc)
824 {
825 while (FPPENDING())
826 EXCEPTION (EX_FLOATING);
827 return RX_MAKE_STEPPED ();
828 }
829
830 static int
831 op_is_memory (RX_Opcode_Decoded *rd, int i)
832 {
833 switch (rd->op[i].type)
834 {
835 case RX_Operand_Predec:
836 case RX_Operand_Postinc:
837 case RX_Operand_Indirect:
838 return 1;
839 default:
840 return 0;
841 }
842 }
843 #define OM(i) op_is_memory (&opcode, i)
844
845 int
846 decode_opcode ()
847 {
848 unsigned int uma=0, umb=0;
849 int ma=0, mb=0;
850 int opcode_size, v;
851 unsigned long long ll;
852 long long sll;
853 unsigned long opcode_pc;
854 RX_Data rx_data;
855 RX_Opcode_Decoded opcode;
856 int rv;
857 #ifdef CYCLE_STATS
858 unsigned long long prev_cycle_count;
859 #endif
860 #ifdef CYCLE_ACCURATE
861 int tx;
862 #endif
863
864 if ((rv = setjmp (decode_jmp_buf)))
865 return rv;
866
867 #ifdef CYCLE_STATS
868 prev_cycle_count = regs.cycle_count;
869 #endif
870
871 #ifdef CYCLE_ACCURATE
872 memory_source = 0;
873 memory_dest = 0;
874 #endif
875
876 rx_cycles ++;
877
878 rx_data.dpc = opcode_pc = regs.r_pc;
879 memset (&opcode, 0, sizeof(opcode));
880 opcode_size = rx_decode_opcode (opcode_pc, &opcode, rx_get_byte, &rx_data);
881
882 #ifdef CYCLE_ACCURATE
883 if (branch_alignment_penalty)
884 {
885 if ((regs.r_pc ^ (regs.r_pc + opcode_size - 1)) & ~7)
886 {
887 tprintf("1 cycle branch alignment penalty\n");
888 cycles (branch_alignment_penalty);
889 #ifdef CYCLE_STATS
890 branch_alignment_stalls ++;
891 #endif
892 }
893 branch_alignment_penalty = 0;
894 }
895 #endif
896
897 regs.r_pc += opcode_size;
898
899 rx_flagmask = opcode.flags_s;
900 rx_flagand = ~(int)opcode.flags_0;
901 rx_flagor = opcode.flags_1;
902
903 switch (opcode.id)
904 {
905 case RXO_abs:
906 sll = GS ();
907 tprintf("|%lld| = ", sll);
908 if (sll < 0)
909 sll = -sll;
910 tprintf("%lld\n", sll);
911 PD (sll);
912 set_osz (sll, 4);
913 E (1);
914 break;
915
916 case RXO_adc:
917 MATH_OP (+,carry);
918 break;
919
920 case RXO_add:
921 MATH_OP (+,0);
922 break;
923
924 case RXO_and:
925 LOGIC_OP (&);
926 break;
927
928 case RXO_bclr:
929 ma = GD ();
930 mb = GS ();
931 if (opcode.op[0].type == RX_Operand_Register)
932 mb &= 0x1f;
933 else
934 mb &= 0x07;
935 ma &= ~(1 << mb);
936 PD (ma);
937 EBIT;
938 break;
939
940 case RXO_bmcc:
941 ma = GD ();
942 mb = GS ();
943 if (opcode.op[0].type == RX_Operand_Register)
944 mb &= 0x1f;
945 else
946 mb &= 0x07;
947 if (GS2 ())
948 ma |= (1 << mb);
949 else
950 ma &= ~(1 << mb);
951 PD (ma);
952 EBIT;
953 break;
954
955 case RXO_bnot:
956 ma = GD ();
957 mb = GS ();
958 if (opcode.op[0].type == RX_Operand_Register)
959 mb &= 0x1f;
960 else
961 mb &= 0x07;
962 ma ^= (1 << mb);
963 PD (ma);
964 EBIT;
965 break;
966
967 case RXO_branch:
968 if (GS())
969 {
970 #ifdef CYCLE_ACCURATE
971 SI old_pc = regs.r_pc;
972 int delta;
973 #endif
974 regs.r_pc = GD();
975 #ifdef CYCLE_ACCURATE
976 delta = regs.r_pc - old_pc;
977 if (delta >= 0 && delta < 16
978 && opcode_size > 1)
979 {
980 tprintf("near forward branch bonus\n");
981 cycles (2);
982 }
983 else
984 {
985 cycles (3);
986 branch_alignment_penalty = 1;
987 }
988 #ifdef CYCLE_STATS
989 branch_stalls ++;
990 /* This is just for statistics */
991 if (opcode.op[1].reg == 14)
992 opcode.op[1].type = RX_Operand_None;
993 #endif
994 #endif
995 }
996 #ifdef CYCLE_ACCURATE
997 else
998 cycles (1);
999 #endif
1000 break;
1001
1002 case RXO_branchrel:
1003 if (GS())
1004 {
1005 int delta = GD();
1006 regs.r_pc += delta;
1007 #ifdef CYCLE_ACCURATE
1008 /* Note: specs say 3, chip says 2. */
1009 if (delta >= 0 && delta < 16
1010 && opcode_size > 1)
1011 {
1012 tprintf("near forward branch bonus\n");
1013 cycles (2);
1014 }
1015 else
1016 {
1017 cycles (3);
1018 branch_alignment_penalty = 1;
1019 }
1020 #ifdef CYCLE_STATS
1021 branch_stalls ++;
1022 #endif
1023 #endif
1024 }
1025 #ifdef CYCLE_ACCURATE
1026 else
1027 cycles (1);
1028 #endif
1029 break;
1030
1031 case RXO_brk:
1032 {
1033 int old_psw = regs.r_psw;
1034 if (rx_in_gdb)
1035 return RX_MAKE_HIT_BREAK ();
1036 if (regs.r_intb == 0)
1037 {
1038 tprintf("BREAK hit, no vector table.\n");
1039 return RX_MAKE_EXITED(1);
1040 }
1041 regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
1042 pushpc (old_psw);
1043 pushpc (regs.r_pc);
1044 regs.r_pc = mem_get_si (regs.r_intb);
1045 cycles(6);
1046 }
1047 break;
1048
1049 case RXO_bset:
1050 ma = GD ();
1051 mb = GS ();
1052 if (opcode.op[0].type == RX_Operand_Register)
1053 mb &= 0x1f;
1054 else
1055 mb &= 0x07;
1056 ma |= (1 << mb);
1057 PD (ma);
1058 EBIT;
1059 break;
1060
1061 case RXO_btst:
1062 ma = GS ();
1063 mb = GS2 ();
1064 if (opcode.op[1].type == RX_Operand_Register)
1065 mb &= 0x1f;
1066 else
1067 mb &= 0x07;
1068 umb = ma & (1 << mb);
1069 set_zc (! umb, umb);
1070 EBIT;
1071 break;
1072
1073 case RXO_clrpsw:
1074 v = 1 << opcode.op[0].reg;
1075 if (FLAG_PM
1076 && (v == FLAGBIT_I
1077 || v == FLAGBIT_U))
1078 break;
1079 regs.r_psw &= ~v;
1080 cycles (1);
1081 break;
1082
1083 case RXO_div: /* d = d / s */
1084 ma = GS();
1085 mb = GD();
1086 tprintf("%d / %d = ", mb, ma);
1087 if (ma == 0 || (ma == -1 && (unsigned int) mb == 0x80000000))
1088 {
1089 tprintf("#NAN\n");
1090 set_flags (FLAGBIT_O, FLAGBIT_O);
1091 }
1092 else
1093 {
1094 v = mb/ma;
1095 tprintf("%d\n", v);
1096 set_flags (FLAGBIT_O, 0);
1097 PD (v);
1098 }
1099 /* Note: spec says 3 to 22 cycles, we are pessimistic. */
1100 cycles (22);
1101 break;
1102
1103 case RXO_divu: /* d = d / s */
1104 uma = GS();
1105 umb = GD();
1106 tprintf("%u / %u = ", umb, uma);
1107 if (uma == 0)
1108 {
1109 tprintf("#NAN\n");
1110 set_flags (FLAGBIT_O, FLAGBIT_O);
1111 }
1112 else
1113 {
1114 v = umb / uma;
1115 tprintf("%u\n", v);
1116 set_flags (FLAGBIT_O, 0);
1117 PD (v);
1118 }
1119 /* Note: spec says 2 to 20 cycles, we are pessimistic. */
1120 cycles (20);
1121 break;
1122
1123 case RXO_ediv:
1124 ma = GS();
1125 mb = GD();
1126 tprintf("%d / %d = ", mb, ma);
1127 if (ma == 0 || (ma == -1 && (unsigned int) mb == 0x80000000))
1128 {
1129 tprintf("#NAN\n");
1130 set_flags (FLAGBIT_O, FLAGBIT_O);
1131 }
1132 else
1133 {
1134 v = mb/ma;
1135 mb = mb%ma;
1136 tprintf("%d, rem %d\n", v, mb);
1137 set_flags (FLAGBIT_O, 0);
1138 PD (v);
1139 opcode.op[0].reg ++;
1140 PD (mb);
1141 }
1142 /* Note: spec says 3 to 22 cycles, we are pessimistic. */
1143 cycles (22);
1144 break;
1145
1146 case RXO_edivu:
1147 uma = GS();
1148 umb = GD();
1149 tprintf("%u / %u = ", umb, uma);
1150 if (uma == 0)
1151 {
1152 tprintf("#NAN\n");
1153 set_flags (FLAGBIT_O, FLAGBIT_O);
1154 }
1155 else
1156 {
1157 v = umb/uma;
1158 umb = umb%uma;
1159 tprintf("%u, rem %u\n", v, umb);
1160 set_flags (FLAGBIT_O, 0);
1161 PD (v);
1162 opcode.op[0].reg ++;
1163 PD (umb);
1164 }
1165 /* Note: spec says 2 to 20 cycles, we are pessimistic. */
1166 cycles (20);
1167 break;
1168
1169 case RXO_emul:
1170 ma = GD ();
1171 mb = GS ();
1172 sll = (long long)ma * (long long)mb;
1173 tprintf("%d * %d = %lld\n", ma, mb, sll);
1174 PD (sll);
1175 opcode.op[0].reg ++;
1176 PD (sll >> 32);
1177 E2;
1178 break;
1179
1180 case RXO_emulu:
1181 uma = GD ();
1182 umb = GS ();
1183 ll = (long long)uma * (long long)umb;
1184 tprintf("%#x * %#x = %#llx\n", uma, umb, ll);
1185 PD (ll);
1186 opcode.op[0].reg ++;
1187 PD (ll >> 32);
1188 E2;
1189 break;
1190
1191 case RXO_fadd:
1192 FLOAT_OP (fadd);
1193 E (4);
1194 break;
1195
1196 case RXO_fcmp:
1197 ma = GD();
1198 mb = GS();
1199 FPCLEAR ();
1200 rxfp_cmp (ma, mb);
1201 FPCHECK ();
1202 E (1);
1203 break;
1204
1205 case RXO_fdiv:
1206 FLOAT_OP (fdiv);
1207 E (16);
1208 break;
1209
1210 case RXO_fmul:
1211 FLOAT_OP (fmul);
1212 E (3);
1213 break;
1214
1215 case RXO_rtfi:
1216 PRIVILEDGED ();
1217 regs.r_psw = regs.r_bpsw;
1218 regs.r_pc = regs.r_bpc;
1219 #ifdef CYCLE_ACCURATE
1220 regs.fast_return = 0;
1221 cycles(3);
1222 #endif
1223 break;
1224
1225 case RXO_fsub:
1226 FLOAT_OP (fsub);
1227 E (4);
1228 break;
1229
1230 case RXO_ftoi:
1231 ma = GS ();
1232 FPCLEAR ();
1233 mb = rxfp_ftoi (ma, FPRM_ZERO);
1234 FPCHECK ();
1235 PD (mb);
1236 tprintf("(int) %g = %d\n", int2float(ma), mb);
1237 set_sz (mb, 4);
1238 E (2);
1239 break;
1240
1241 case RXO_int:
1242 v = GS ();
1243 if (v == 255)
1244 {
1245 return rx_syscall (regs.r[5]);
1246 }
1247 else
1248 {
1249 int old_psw = regs.r_psw;
1250 regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
1251 pushpc (old_psw);
1252 pushpc (regs.r_pc);
1253 regs.r_pc = mem_get_si (regs.r_intb + 4 * v);
1254 }
1255 cycles (6);
1256 break;
1257
1258 case RXO_itof:
1259 ma = GS ();
1260 FPCLEAR ();
1261 mb = rxfp_itof (ma, regs.r_fpsw);
1262 FPCHECK ();
1263 tprintf("(float) %d = %x\n", ma, mb);
1264 PD (mb);
1265 set_sz (ma, 4);
1266 E (2);
1267 break;
1268
1269 case RXO_jsr:
1270 case RXO_jsrrel:
1271 {
1272 #ifdef CYCLE_ACCURATE
1273 int delta;
1274 regs.m2m = 0;
1275 #endif
1276 v = GD ();
1277 #ifdef CYCLE_ACCURATE
1278 regs.link_register = regs.r_pc;
1279 #endif
1280 pushpc (get_reg (pc));
1281 if (opcode.id == RXO_jsrrel)
1282 v += regs.r_pc;
1283 #ifdef CYCLE_ACCURATE
1284 delta = v - regs.r_pc;
1285 #endif
1286 put_reg (pc, v);
1287 #ifdef CYCLE_ACCURATE
1288 /* Note: docs say 3, chip says 2 */
1289 if (delta >= 0 && delta < 16)
1290 {
1291 tprintf ("near forward jsr bonus\n");
1292 cycles (2);
1293 }
1294 else
1295 {
1296 branch_alignment_penalty = 1;
1297 cycles (3);
1298 }
1299 regs.fast_return = 1;
1300 #endif
1301 }
1302 break;
1303
1304 case RXO_machi:
1305 ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
1306 ll <<= 16;
1307 put_reg64 (acc64, ll + regs.r_acc);
1308 E1;
1309 break;
1310
1311 case RXO_maclo:
1312 ll = (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
1313 ll <<= 16;
1314 put_reg64 (acc64, ll + regs.r_acc);
1315 E1;
1316 break;
1317
1318 case RXO_max:
1319 mb = GS();
1320 ma = GD();
1321 if (ma > mb)
1322 PD (ma);
1323 else
1324 PD (mb);
1325 E (1);
1326 #ifdef CYCLE_STATS
1327 if (opcode.op[0].type == RX_Operand_Register
1328 && opcode.op[1].type == RX_Operand_Register
1329 && opcode.op[0].reg == opcode.op[1].reg)
1330 opcode.id = RXO_nop3;
1331 #endif
1332 break;
1333
1334 case RXO_min:
1335 mb = GS();
1336 ma = GD();
1337 if (ma < mb)
1338 PD (ma);
1339 else
1340 PD (mb);
1341 E (1);
1342 break;
1343
1344 case RXO_mov:
1345 v = GS ();
1346
1347 if (opcode.op[0].type == RX_Operand_Register
1348 && opcode.op[0].reg == 16 /* PSW */)
1349 {
1350 /* Special case, LDC and POPC can't ever modify PM. */
1351 int pm = regs.r_psw & FLAGBIT_PM;
1352 v &= ~ FLAGBIT_PM;
1353 v |= pm;
1354 if (pm)
1355 {
1356 v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
1357 v |= pm;
1358 }
1359 }
1360 if (FLAG_PM)
1361 {
1362 /* various things can't be changed in user mode. */
1363 if (opcode.op[0].type == RX_Operand_Register)
1364 if (opcode.op[0].reg == 32)
1365 {
1366 v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
1367 v |= regs.r_psw & (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
1368 }
1369 if (opcode.op[0].reg == 34 /* ISP */
1370 || opcode.op[0].reg == 37 /* BPSW */
1371 || opcode.op[0].reg == 39 /* INTB */
1372 || opcode.op[0].reg == 38 /* VCT */)
1373 /* These are ignored. */
1374 break;
1375 }
1376 if (OM(0) && OM(1))
1377 cycles (2);
1378 else
1379 cycles (1);
1380
1381 PD (v);
1382
1383 #ifdef CYCLE_ACCURATE
1384 if ((opcode.op[0].type == RX_Operand_Predec
1385 && opcode.op[1].type == RX_Operand_Register)
1386 || (opcode.op[0].type == RX_Operand_Postinc
1387 && opcode.op[1].type == RX_Operand_Register))
1388 {
1389 /* Special case: push reg doesn't cause a memory stall. */
1390 memory_dest = 0;
1391 tprintf("push special case\n");
1392 }
1393 #endif
1394
1395 set_sz (v, DSZ());
1396 #ifdef CYCLE_STATS
1397 if (opcode.op[0].type == RX_Operand_Register
1398 && opcode.op[1].type == RX_Operand_Register
1399 && opcode.op[0].reg == opcode.op[1].reg)
1400 opcode.id = RXO_nop2;
1401 #endif
1402 break;
1403
1404 case RXO_movbi:
1405 /* We cheat to save on code duplication. */
1406 regs.r_temp = (get_reg (opcode.op[1].reg) * size2bytes[opcode.size]
1407 + get_reg (opcode.op[2].reg));
1408 opcode.op[1].reg = r_temp_idx;
1409 opcode.op[1].type = RX_Operand_Indirect;
1410 opcode.op[1].addend = 0;
1411 PD (GS ());
1412 cycles (1);
1413 break;
1414
1415 case RXO_movbir:
1416 /* We cheat to save on code duplication. */
1417 regs.r_temp = (get_reg (opcode.op[1].reg) * size2bytes[opcode.size]
1418 + get_reg (opcode.op[2].reg));
1419 opcode.op[1].reg = r_temp_idx;
1420 opcode.op[1].type = RX_Operand_Indirect;
1421 opcode.op[1].addend = 0;
1422 PS (GD ());
1423 cycles (1);
1424 break;
1425
1426 case RXO_mul:
1427 v = US2 ();
1428 ll = (unsigned long long) US1() * (unsigned long long) v;
1429 PD(ll);
1430 E (1);
1431 break;
1432
1433 case RXO_mulhi:
1434 v = GS2 ();
1435 ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(v >> 16);
1436 ll <<= 16;
1437 put_reg64 (acc64, ll);
1438 E1;
1439 break;
1440
1441 case RXO_mullo:
1442 v = GS2 ();
1443 ll = (long long)(signed short)(GS()) * (long long)(signed short)(v);
1444 ll <<= 16;
1445 put_reg64 (acc64, ll);
1446 E1;
1447 break;
1448
1449 case RXO_mvfachi:
1450 PD (get_reg (acchi));
1451 E1;
1452 break;
1453
1454 case RXO_mvfaclo:
1455 PD (get_reg (acclo));
1456 E1;
1457 break;
1458
1459 case RXO_mvfacmi:
1460 PD (get_reg (accmi));
1461 E1;
1462 break;
1463
1464 case RXO_mvtachi:
1465 put_reg (acchi, GS ());
1466 E1;
1467 break;
1468
1469 case RXO_mvtaclo:
1470 put_reg (acclo, GS ());
1471 E1;
1472 break;
1473
1474 case RXO_mvtipl:
1475 regs.r_psw &= ~ FLAGBITS_IPL;
1476 regs.r_psw |= (GS () << FLAGSHIFT_IPL) & FLAGBITS_IPL;
1477 E1;
1478 break;
1479
1480 case RXO_nop:
1481 E1;
1482 break;
1483
1484 case RXO_or:
1485 LOGIC_OP (|);
1486 break;
1487
1488 case RXO_popm:
1489 /* POPM cannot pop R0 (sp). */
1490 if (opcode.op[1].reg == 0 || opcode.op[2].reg == 0)
1491 EXCEPTION (EX_UNDEFINED);
1492 if (opcode.op[1].reg >= opcode.op[2].reg)
1493 {
1494 regs.r_pc = opcode_pc;
1495 return RX_MAKE_STOPPED (SIGILL);
1496 }
1497 for (v = opcode.op[1].reg; v <= opcode.op[2].reg; v++)
1498 {
1499 cycles (1);
1500 RLD (v);
1501 put_reg (v, pop ());
1502 }
1503 break;
1504
1505 case RXO_pushm:
1506 /* PUSHM cannot push R0 (sp). */
1507 if (opcode.op[1].reg == 0 || opcode.op[2].reg == 0)
1508 EXCEPTION (EX_UNDEFINED);
1509 if (opcode.op[1].reg >= opcode.op[2].reg)
1510 {
1511 regs.r_pc = opcode_pc;
1512 return RX_MAKE_STOPPED (SIGILL);
1513 }
1514 for (v = opcode.op[2].reg; v >= opcode.op[1].reg; v--)
1515 {
1516 RL (v);
1517 push (get_reg (v));
1518 }
1519 cycles (opcode.op[2].reg - opcode.op[1].reg + 1);
1520 break;
1521
1522 case RXO_racw:
1523 ll = get_reg64 (acc64) << GS ();
1524 ll += 0x80000000ULL;
1525 if ((signed long long)ll > (signed long long)0x00007fff00000000ULL)
1526 ll = 0x00007fff00000000ULL;
1527 else if ((signed long long)ll < (signed long long)0xffff800000000000ULL)
1528 ll = 0xffff800000000000ULL;
1529 else
1530 ll &= 0xffffffff00000000ULL;
1531 put_reg64 (acc64, ll);
1532 E1;
1533 break;
1534
1535 case RXO_rte:
1536 PRIVILEDGED ();
1537 regs.r_pc = poppc ();
1538 regs.r_psw = poppc ();
1539 if (FLAG_PM)
1540 regs.r_psw |= FLAGBIT_U;
1541 #ifdef CYCLE_ACCURATE
1542 regs.fast_return = 0;
1543 cycles (6);
1544 #endif
1545 break;
1546
1547 case RXO_revl:
1548 uma = GS ();
1549 umb = (((uma >> 24) & 0xff)
1550 | ((uma >> 8) & 0xff00)
1551 | ((uma << 8) & 0xff0000)
1552 | ((uma << 24) & 0xff000000UL));
1553 PD (umb);
1554 E1;
1555 break;
1556
1557 case RXO_revw:
1558 uma = GS ();
1559 umb = (((uma >> 8) & 0x00ff00ff)
1560 | ((uma << 8) & 0xff00ff00UL));
1561 PD (umb);
1562 E1;
1563 break;
1564
1565 case RXO_rmpa:
1566 RL(4);
1567 RL(5);
1568 #ifdef CYCLE_ACCURATE
1569 tx = regs.r[3];
1570 #endif
1571
1572 while (regs.r[3] != 0)
1573 {
1574 long long tmp;
1575
1576 switch (opcode.size)
1577 {
1578 case RX_Long:
1579 ma = mem_get_si (regs.r[1]);
1580 mb = mem_get_si (regs.r[2]);
1581 regs.r[1] += 4;
1582 regs.r[2] += 4;
1583 break;
1584 case RX_Word:
1585 ma = sign_ext (mem_get_hi (regs.r[1]), 16);
1586 mb = sign_ext (mem_get_hi (regs.r[2]), 16);
1587 regs.r[1] += 2;
1588 regs.r[2] += 2;
1589 break;
1590 case RX_Byte:
1591 ma = sign_ext (mem_get_qi (regs.r[1]), 8);
1592 mb = sign_ext (mem_get_qi (regs.r[2]), 8);
1593 regs.r[1] += 1;
1594 regs.r[2] += 1;
1595 break;
1596 default:
1597 abort ();
1598 }
1599 /* We do the multiply as a signed value. */
1600 sll = (long long)ma * (long long)mb;
1601 tprintf(" %016llx = %d * %d\n", sll, ma, mb);
1602 /* but we do the sum as unsigned, while sign extending the operands. */
1603 tmp = regs.r[4] + (sll & 0xffffffffUL);
1604 regs.r[4] = tmp & 0xffffffffUL;
1605 tmp >>= 32;
1606 sll >>= 32;
1607 tmp += regs.r[5] + (sll & 0xffffffffUL);
1608 regs.r[5] = tmp & 0xffffffffUL;
1609 tmp >>= 32;
1610 sll >>= 32;
1611 tmp += regs.r[6] + (sll & 0xffffffffUL);
1612 regs.r[6] = tmp & 0xffffffffUL;
1613 tprintf("%08lx\033[36m%08lx\033[0m%08lx\n",
1614 (unsigned long) regs.r[6],
1615 (unsigned long) regs.r[5],
1616 (unsigned long) regs.r[4]);
1617
1618 regs.r[3] --;
1619 }
1620 if (regs.r[6] & 0x00008000)
1621 regs.r[6] |= 0xffff0000UL;
1622 else
1623 regs.r[6] &= 0x0000ffff;
1624 ma = (regs.r[6] & 0x80000000UL) ? FLAGBIT_S : 0;
1625 if (regs.r[6] != 0 && regs.r[6] != 0xffffffffUL)
1626 set_flags (FLAGBIT_O|FLAGBIT_S, ma | FLAGBIT_O);
1627 else
1628 set_flags (FLAGBIT_O|FLAGBIT_S, ma);
1629 #ifdef CYCLE_ACCURATE
1630 switch (opcode.size)
1631 {
1632 case RX_Long:
1633 cycles (6 + 4 * tx);
1634 break;
1635 case RX_Word:
1636 cycles (6 + 5 * (tx / 2) + 4 * (tx % 2));
1637 break;
1638 case RX_Byte:
1639 cycles (6 + 7 * (tx / 4) + 4 * (tx % 4));
1640 break;
1641 default:
1642 abort ();
1643 }
1644 #endif
1645 break;
1646
1647 case RXO_rolc:
1648 v = GD ();
1649 ma = v & 0x80000000UL;
1650 v <<= 1;
1651 v |= carry;
1652 set_szc (v, 4, ma);
1653 PD (v);
1654 E1;
1655 break;
1656
1657 case RXO_rorc:
1658 uma = GD ();
1659 mb = uma & 1;
1660 uma >>= 1;
1661 uma |= (carry ? 0x80000000UL : 0);
1662 set_szc (uma, 4, mb);
1663 PD (uma);
1664 E1;
1665 break;
1666
1667 case RXO_rotl:
1668 mb = GS ();
1669 uma = GD ();
1670 if (mb)
1671 {
1672 uma = (uma << mb) | (uma >> (32-mb));
1673 mb = uma & 1;
1674 }
1675 set_szc (uma, 4, mb);
1676 PD (uma);
1677 E1;
1678 break;
1679
1680 case RXO_rotr:
1681 mb = GS ();
1682 uma = GD ();
1683 if (mb)
1684 {
1685 uma = (uma >> mb) | (uma << (32-mb));
1686 mb = uma & 0x80000000;
1687 }
1688 set_szc (uma, 4, mb);
1689 PD (uma);
1690 E1;
1691 break;
1692
1693 case RXO_round:
1694 ma = GS ();
1695 FPCLEAR ();
1696 mb = rxfp_ftoi (ma, regs.r_fpsw);
1697 FPCHECK ();
1698 PD (mb);
1699 tprintf("(int) %g = %d\n", int2float(ma), mb);
1700 set_sz (mb, 4);
1701 E (2);
1702 break;
1703
1704 case RXO_rts:
1705 {
1706 #ifdef CYCLE_ACCURATE
1707 int cyc = 5;
1708 #endif
1709 regs.r_pc = poppc ();
1710 #ifdef CYCLE_ACCURATE
1711 /* Note: specs say 5, chip says 3. */
1712 if (regs.fast_return && regs.link_register == regs.r_pc)
1713 {
1714 #ifdef CYCLE_STATS
1715 fast_returns ++;
1716 #endif
1717 tprintf("fast return bonus\n");
1718 cyc -= 2;
1719 }
1720 cycles (cyc);
1721 regs.fast_return = 0;
1722 branch_alignment_penalty = 1;
1723 #endif
1724 }
1725 break;
1726
1727 case RXO_rtsd:
1728 if (opcode.op[2].type == RX_Operand_Register)
1729 {
1730 int i;
1731 /* RTSD cannot pop R0 (sp). */
1732 put_reg (0, get_reg (0) + GS() - (opcode.op[0].reg-opcode.op[2].reg+1)*4);
1733 if (opcode.op[2].reg == 0)
1734 EXCEPTION (EX_UNDEFINED);
1735 #ifdef CYCLE_ACCURATE
1736 tx = opcode.op[0].reg - opcode.op[2].reg + 1;
1737 #endif
1738 for (i = opcode.op[2].reg; i <= opcode.op[0].reg; i ++)
1739 {
1740 RLD (i);
1741 put_reg (i, pop ());
1742 }
1743 }
1744 else
1745 {
1746 #ifdef CYCLE_ACCURATE
1747 tx = 0;
1748 #endif
1749 put_reg (0, get_reg (0) + GS());
1750 }
1751 put_reg (pc, poppc());
1752 #ifdef CYCLE_ACCURATE
1753 if (regs.fast_return && regs.link_register == regs.r_pc)
1754 {
1755 tprintf("fast return bonus\n");
1756 #ifdef CYCLE_STATS
1757 fast_returns ++;
1758 #endif
1759 cycles (tx < 3 ? 3 : tx + 1);
1760 }
1761 else
1762 {
1763 cycles (tx < 5 ? 5 : tx + 1);
1764 }
1765 regs.fast_return = 0;
1766 branch_alignment_penalty = 1;
1767 #endif
1768 break;
1769
1770 case RXO_sat:
1771 if (FLAG_O && FLAG_S)
1772 PD (0x7fffffffUL);
1773 else if (FLAG_O && ! FLAG_S)
1774 PD (0x80000000UL);
1775 E1;
1776 break;
1777
1778 case RXO_sbb:
1779 MATH_OP (-, ! carry);
1780 break;
1781
1782 case RXO_sccnd:
1783 if (GS())
1784 PD (1);
1785 else
1786 PD (0);
1787 E1;
1788 break;
1789
1790 case RXO_scmpu:
1791 #ifdef CYCLE_ACCURATE
1792 tx = regs.r[3];
1793 #endif
1794 while (regs.r[3] != 0)
1795 {
1796 uma = mem_get_qi (regs.r[1] ++);
1797 umb = mem_get_qi (regs.r[2] ++);
1798 regs.r[3] --;
1799 if (uma != umb || uma == 0)
1800 break;
1801 }
1802 if (uma == umb)
1803 set_zc (1, 1);
1804 else
1805 set_zc (0, ((int)uma - (int)umb) >= 0);
1806 cycles (2 + 4 * (tx / 4) + 4 * (tx % 4));
1807 break;
1808
1809 case RXO_setpsw:
1810 v = 1 << opcode.op[0].reg;
1811 if (FLAG_PM
1812 && (v == FLAGBIT_I
1813 || v == FLAGBIT_U))
1814 break;
1815 regs.r_psw |= v;
1816 cycles (1);
1817 break;
1818
1819 case RXO_smovb:
1820 RL (3);
1821 #ifdef CYCLE_ACCURATE
1822 tx = regs.r[3];
1823 #endif
1824 while (regs.r[3])
1825 {
1826 uma = mem_get_qi (regs.r[2] --);
1827 mem_put_qi (regs.r[1]--, uma);
1828 regs.r[3] --;
1829 }
1830 #ifdef CYCLE_ACCURATE
1831 if (tx > 3)
1832 cycles (6 + 3 * (tx / 4) + 3 * (tx % 4));
1833 else
1834 cycles (2 + 3 * (tx % 4));
1835 #endif
1836 break;
1837
1838 case RXO_smovf:
1839 RL (3);
1840 #ifdef CYCLE_ACCURATE
1841 tx = regs.r[3];
1842 #endif
1843 while (regs.r[3])
1844 {
1845 uma = mem_get_qi (regs.r[2] ++);
1846 mem_put_qi (regs.r[1]++, uma);
1847 regs.r[3] --;
1848 }
1849 cycles (2 + 3 * (int)(tx / 4) + 3 * (tx % 4));
1850 break;
1851
1852 case RXO_smovu:
1853 while (regs.r[3] != 0)
1854 {
1855 uma = mem_get_qi (regs.r[2] ++);
1856 mem_put_qi (regs.r[1]++, uma);
1857 regs.r[3] --;
1858 if (uma == 0)
1859 break;
1860 }
1861 break;
1862
1863 case RXO_shar: /* d = ma >> mb */
1864 SHIFT_OP (sll, int, mb, >>=, 1);
1865 E (1);
1866 break;
1867
1868 case RXO_shll: /* d = ma << mb */
1869 SHIFT_OP (ll, int, mb, <<=, 0x80000000UL);
1870 E (1);
1871 break;
1872
1873 case RXO_shlr: /* d = ma >> mb */
1874 SHIFT_OP (ll, unsigned int, mb, >>=, 1);
1875 E (1);
1876 break;
1877
1878 case RXO_sstr:
1879 RL (3);
1880 #ifdef CYCLE_ACCURATE
1881 tx = regs.r[3];
1882 #endif
1883 switch (opcode.size)
1884 {
1885 case RX_Long:
1886 while (regs.r[3] != 0)
1887 {
1888 mem_put_si (regs.r[1], regs.r[2]);
1889 regs.r[1] += 4;
1890 regs.r[3] --;
1891 }
1892 cycles (2 + tx);
1893 break;
1894 case RX_Word:
1895 while (regs.r[3] != 0)
1896 {
1897 mem_put_hi (regs.r[1], regs.r[2]);
1898 regs.r[1] += 2;
1899 regs.r[3] --;
1900 }
1901 cycles (2 + (int)(tx / 2) + tx % 2);
1902 break;
1903 case RX_Byte:
1904 while (regs.r[3] != 0)
1905 {
1906 mem_put_qi (regs.r[1], regs.r[2]);
1907 regs.r[1] ++;
1908 regs.r[3] --;
1909 }
1910 cycles (2 + (int)(tx / 4) + tx % 4);
1911 break;
1912 default:
1913 abort ();
1914 }
1915 break;
1916
1917 case RXO_stcc:
1918 if (GS2())
1919 PD (GS ());
1920 E1;
1921 break;
1922
1923 case RXO_stop:
1924 PRIVILEDGED ();
1925 regs.r_psw |= FLAGBIT_I;
1926 return RX_MAKE_STOPPED(0);
1927
1928 case RXO_sub:
1929 MATH_OP (-, 0);
1930 break;
1931
1932 case RXO_suntil:
1933 RL(3);
1934 #ifdef CYCLE_ACCURATE
1935 tx = regs.r[3];
1936 #endif
1937 if (regs.r[3] == 0)
1938 {
1939 cycles (3);
1940 break;
1941 }
1942 switch (opcode.size)
1943 {
1944 case RX_Long:
1945 uma = get_reg (2);
1946 while (regs.r[3] != 0)
1947 {
1948 regs.r[3] --;
1949 umb = mem_get_si (get_reg (1));
1950 regs.r[1] += 4;
1951 if (umb == uma)
1952 break;
1953 }
1954 cycles (3 + 3 * tx);
1955 break;
1956 case RX_Word:
1957 uma = get_reg (2) & 0xffff;
1958 while (regs.r[3] != 0)
1959 {
1960 regs.r[3] --;
1961 umb = mem_get_hi (get_reg (1));
1962 regs.r[1] += 2;
1963 if (umb == uma)
1964 break;
1965 }
1966 cycles (3 + 3 * (tx / 2) + 3 * (tx % 2));
1967 break;
1968 case RX_Byte:
1969 uma = get_reg (2) & 0xff;
1970 while (regs.r[3] != 0)
1971 {
1972 regs.r[3] --;
1973 umb = mem_get_qi (regs.r[1]);
1974 regs.r[1] += 1;
1975 if (umb == uma)
1976 break;
1977 }
1978 cycles (3 + 3 * (tx / 4) + 3 * (tx % 4));
1979 break;
1980 default:
1981 abort();
1982 }
1983 if (uma == umb)
1984 set_zc (1, 1);
1985 else
1986 set_zc (0, ((int)uma - (int)umb) >= 0);
1987 break;
1988
1989 case RXO_swhile:
1990 RL(3);
1991 #ifdef CYCLE_ACCURATE
1992 tx = regs.r[3];
1993 #endif
1994 if (regs.r[3] == 0)
1995 break;
1996 switch (opcode.size)
1997 {
1998 case RX_Long:
1999 uma = get_reg (2);
2000 while (regs.r[3] != 0)
2001 {
2002 regs.r[3] --;
2003 umb = mem_get_si (get_reg (1));
2004 regs.r[1] += 4;
2005 if (umb != uma)
2006 break;
2007 }
2008 cycles (3 + 3 * tx);
2009 break;
2010 case RX_Word:
2011 uma = get_reg (2) & 0xffff;
2012 while (regs.r[3] != 0)
2013 {
2014 regs.r[3] --;
2015 umb = mem_get_hi (get_reg (1));
2016 regs.r[1] += 2;
2017 if (umb != uma)
2018 break;
2019 }
2020 cycles (3 + 3 * (tx / 2) + 3 * (tx % 2));
2021 break;
2022 case RX_Byte:
2023 uma = get_reg (2) & 0xff;
2024 while (regs.r[3] != 0)
2025 {
2026 regs.r[3] --;
2027 umb = mem_get_qi (regs.r[1]);
2028 regs.r[1] += 1;
2029 if (umb != uma)
2030 break;
2031 }
2032 cycles (3 + 3 * (tx / 4) + 3 * (tx % 4));
2033 break;
2034 default:
2035 abort();
2036 }
2037 if (uma == umb)
2038 set_zc (1, 1);
2039 else
2040 set_zc (0, ((int)uma - (int)umb) >= 0);
2041 break;
2042
2043 case RXO_wait:
2044 PRIVILEDGED ();
2045 regs.r_psw |= FLAGBIT_I;
2046 return RX_MAKE_STOPPED(0);
2047
2048 case RXO_xchg:
2049 #ifdef CYCLE_ACCURATE
2050 regs.m2m = 0;
2051 #endif
2052 v = GS (); /* This is the memory operand, if any. */
2053 PS (GD ()); /* and this may change the address register. */
2054 PD (v);
2055 E2;
2056 #ifdef CYCLE_ACCURATE
2057 /* all M cycles happen during xchg's cycles. */
2058 memory_dest = 0;
2059 memory_source = 0;
2060 #endif
2061 break;
2062
2063 case RXO_xor:
2064 LOGIC_OP (^);
2065 break;
2066
2067 default:
2068 EXCEPTION (EX_UNDEFINED);
2069 }
2070
2071 #ifdef CYCLE_ACCURATE
2072 regs.m2m = 0;
2073 if (memory_source)
2074 regs.m2m |= M2M_SRC;
2075 if (memory_dest)
2076 regs.m2m |= M2M_DST;
2077
2078 regs.rt = new_rt;
2079 new_rt = -1;
2080 #endif
2081
2082 #ifdef CYCLE_STATS
2083 if (prev_cycle_count == regs.cycle_count)
2084 {
2085 printf("Cycle count not updated! id %s\n", id_names[opcode.id]);
2086 abort ();
2087 }
2088 #endif
2089
2090 #ifdef CYCLE_STATS
2091 if (running_benchmark)
2092 {
2093 int omap = op_lookup (opcode.op[0].type, opcode.op[1].type, opcode.op[2].type);
2094
2095
2096 cycles_per_id[opcode.id][omap] += regs.cycle_count - prev_cycle_count;
2097 times_per_id[opcode.id][omap] ++;
2098
2099 times_per_pair[prev_opcode_id][po0][opcode.id][omap] ++;
2100
2101 prev_opcode_id = opcode.id;
2102 po0 = omap;
2103 }
2104 #endif
2105
2106 return RX_MAKE_STEPPED ();
2107 }
2108
2109 #ifdef CYCLE_STATS
2110 void
2111 reset_pipeline_stats (void)
2112 {
2113 memset (cycles_per_id, 0, sizeof(cycles_per_id));
2114 memset (times_per_id, 0, sizeof(times_per_id));
2115 memory_stalls = 0;
2116 register_stalls = 0;
2117 branch_stalls = 0;
2118 branch_alignment_stalls = 0;
2119 fast_returns = 0;
2120 memset (times_per_pair, 0, sizeof(times_per_pair));
2121 running_benchmark = 1;
2122
2123 benchmark_start_cycle = regs.cycle_count;
2124 }
2125
2126 void
2127 halt_pipeline_stats (void)
2128 {
2129 running_benchmark = 0;
2130 benchmark_end_cycle = regs.cycle_count;
2131 }
2132 #endif
2133
2134 void
2135 pipeline_stats (void)
2136 {
2137 #ifdef CYCLE_STATS
2138 int i, o1;
2139 int p, p1;
2140 #endif
2141
2142 #ifdef CYCLE_ACCURATE
2143 if (verbose == 1)
2144 {
2145 printf ("cycles: %llu\n", regs.cycle_count);
2146 return;
2147 }
2148
2149 printf ("cycles: %13s\n", comma (regs.cycle_count));
2150 #endif
2151
2152 #ifdef CYCLE_STATS
2153 if (benchmark_start_cycle)
2154 printf ("bmark: %13s\n", comma (benchmark_end_cycle - benchmark_start_cycle));
2155
2156 printf("\n");
2157 for (i = 0; i < N_RXO; i++)
2158 for (o1 = 0; o1 < N_MAP; o1 ++)
2159 if (times_per_id[i][o1])
2160 printf("%13s %13s %7.2f %s %s\n",
2161 comma (cycles_per_id[i][o1]),
2162 comma (times_per_id[i][o1]),
2163 (double)cycles_per_id[i][o1] / times_per_id[i][o1],
2164 op_cache_string(o1),
2165 id_names[i]+4);
2166
2167 printf("\n");
2168 for (p = 0; p < N_RXO; p ++)
2169 for (p1 = 0; p1 < N_MAP; p1 ++)
2170 for (i = 0; i < N_RXO; i ++)
2171 for (o1 = 0; o1 < N_MAP; o1 ++)
2172 if (times_per_pair[p][p1][i][o1])
2173 {
2174 printf("%13s %s %-9s -> %s %s\n",
2175 comma (times_per_pair[p][p1][i][o1]),
2176 op_cache_string(p1),
2177 id_names[p]+4,
2178 op_cache_string(o1),
2179 id_names[i]+4);
2180 }
2181
2182 printf("\n");
2183 printf("%13s memory stalls\n", comma (memory_stalls));
2184 printf("%13s register stalls\n", comma (register_stalls));
2185 printf("%13s branches taken (non-return)\n", comma (branch_stalls));
2186 printf("%13s branch alignment stalls\n", comma (branch_alignment_stalls));
2187 printf("%13s fast returns\n", comma (fast_returns));
2188 #endif
2189 }