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