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