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