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