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