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