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