1 /* rx.c --- opcode semantics for stand-alone RX simulator.
3 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
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.
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.
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/>. */
26 #include "opcode/rx.h"
33 #define tprintf if (trace) printf
35 jmp_buf decode_jmp_buf
;
36 unsigned int rx_cycles
= 0;
38 static int size2bytes
[] = {
39 4, 1, 1, 1, 2, 2, 2, 3, 4
46 #define rx_abort() _rx_abort(__FILE__, __LINE__)
48 _rx_abort (const char *file
, int line
)
50 if (strrchr (file
, '/'))
51 file
= strrchr (file
, '/') + 1;
52 fprintf(stderr
, "abort at %s:%d\n", file
, line
);
57 rx_get_byte (void *vdata
)
59 int saved_trace
= trace
;
65 RX_Data
*rx_data
= (RX_Data
*)vdata
;
67 /* See load.c for an explanation of this. */
68 rv
= mem_get_pc (rx_data
->dpc
^ 3);
70 rv
= mem_get_pc (rx_data
->dpc
);
77 get_op (RX_Opcode_Decoded
*rd
, int i
)
79 RX_Opcode_Operand
*o
= rd
->op
+ i
;
87 case RX_Operand_Immediate
: /* #addend */
90 case RX_Operand_Register
: /* Rn */
91 rv
= get_reg (o
->reg
);
94 case RX_Operand_Predec
: /* [-Rn] */
95 put_reg (o
->reg
, get_reg (o
->reg
) - size2bytes
[o
->size
]);
97 case RX_Operand_Postinc
: /* [Rn+] */
98 case RX_Operand_Indirect
: /* [Rn + addend] */
100 addr
= get_reg (o
->reg
) + o
->addend
;
106 case RX_Byte
: /* undefined extension */
109 rv
= mem_get_qi (addr
);
112 case RX_Word
: /* undefined extension */
115 rv
= mem_get_hi (addr
);
119 rv
= mem_get_psi (addr
);
123 rv
= mem_get_si (addr
);
127 if (o
->type
== RX_Operand_Postinc
)
128 put_reg (o
->reg
, get_reg (o
->reg
) + size2bytes
[o
->size
]);
132 case RX_Operand_Condition
: /* eq, gtu, etc */
133 return condition_true (o
->reg
);
135 case RX_Operand_Flag
: /* [UIOSZC] */
136 return (regs
.r_psw
& (1 << o
->reg
)) ? 1 : 0;
139 /* if we've gotten here, we need to clip/extend the value according
146 case RX_Byte
: /* undefined extension */
147 rv
|= 0xdeadbe00; /* keep them honest */
155 rv
= sign_ext (rv
, 8);
158 case RX_Word
: /* undefined extension */
159 rv
|= 0xdead0000; /* keep them honest */
167 rv
= sign_ext (rv
, 16);
181 put_op (RX_Opcode_Decoded
*rd
, int i
, int v
)
183 RX_Opcode_Operand
*o
= rd
->op
+ i
;
189 if (o
->type
!= RX_Operand_Register
)
193 case RX_Byte
: /* undefined extension */
194 v
|= 0xdeadbe00; /* keep them honest */
205 case RX_Word
: /* undefined extension */
206 v
|= 0xdead0000; /* keep them honest */
214 v
= sign_ext (v
, 16);
227 case RX_Operand_None
:
228 /* Opcodes like TST and CMP use this. */
231 case RX_Operand_Immediate
: /* #addend */
232 case RX_Operand_Condition
: /* eq, gtu, etc */
235 case RX_Operand_Register
: /* Rn */
239 case RX_Operand_Predec
: /* [-Rn] */
240 put_reg (o
->reg
, get_reg (o
->reg
) - size2bytes
[o
->size
]);
242 case RX_Operand_Postinc
: /* [Rn+] */
243 case RX_Operand_Indirect
: /* [Rn + addend] */
245 addr
= get_reg (o
->reg
) + o
->addend
;
251 case RX_Byte
: /* undefined extension */
254 mem_put_qi (addr
, v
);
257 case RX_Word
: /* undefined extension */
260 mem_put_hi (addr
, v
);
264 mem_put_psi (addr
, v
);
268 mem_put_si (addr
, v
);
272 if (o
->type
== RX_Operand_Postinc
)
273 put_reg (o
->reg
, get_reg (o
->reg
) + size2bytes
[o
->size
]);
277 case RX_Operand_Flag
: /* [UIOSZC] */
279 regs
.r_psw
|= (1 << o
->reg
);
281 regs
.r_psw
&= ~(1 << o
->reg
);
286 #define PD(x) put_op (&opcode, 0, x)
287 #define PS(x) put_op (&opcode, 1, x)
288 #define PS2(x) put_op (&opcode, 2, x)
289 #define GD() get_op (&opcode, 0)
290 #define GS() get_op (&opcode, 1)
291 #define GS2() get_op (&opcode, 2)
292 #define DSZ() size2bytes[opcode.op[0].size]
293 #define SSZ() size2bytes[opcode.op[0].size]
294 #define S2SZ() size2bytes[opcode.op[0].size]
296 /* "Universal" sources. */
297 #define US1() ((opcode.op[2].type == RX_Operand_None) ? GD() : GS())
298 #define US2() ((opcode.op[2].type == RX_Operand_None) ? GS() : GS2())
303 int rsp
= get_reg (sp
);
306 mem_put_si (rsp
, val
);
309 /* Just like the above, but tag the memory as "pushed pc" so if anyone
310 tries to write to it, it will cause an error. */
314 int rsp
= get_reg (sp
);
317 mem_put_si (rsp
, val
);
318 mem_set_content_range (rsp
, rsp
+3, MC_PUSHED_PC
);
325 int rsp
= get_reg (sp
);
326 rv
= mem_get_si (rsp
);
336 int rsp
= get_reg (sp
);
337 if (mem_get_content_type (rsp
) != MC_PUSHED_PC
)
338 execution_error (SIM_ERR_CORRUPT_STACK
, rsp
);
339 rv
= mem_get_si (rsp
);
340 mem_set_content_range (rsp
, rsp
+3, MC_UNINIT
);
346 #define MATH_OP(vop,c) \
350 ll = (unsigned long long) uma vop (unsigned long long) umb vop c; \
351 tprintf ("0x%x " #vop " 0x%x " #vop " 0x%x = 0x%llx\n", uma, umb, c, ll); \
352 ma = sign_ext (uma, DSZ() * 8); \
353 mb = sign_ext (umb, DSZ() * 8); \
354 sll = (long long) ma vop (long long) mb vop c; \
355 tprintf ("%d " #vop " %d " #vop " %d = %lld\n", ma, mb, c, sll); \
356 set_oszc (sll, DSZ(), (long long) ll > ((1 vop 1) ? (long long) b2mask[DSZ()] : (long long) -1)); \
360 #define LOGIC_OP(vop) \
365 tprintf("0x%x " #vop " 0x%x = 0x%x\n", ma, mb, v); \
370 #define SHIFT_OP(val, type, count, OP, carry_mask) \
375 tprintf("%lld " #OP " %d\n", val, count); \
376 for (i = 0; i < count; i ++) \
378 c = val & carry_mask; \
382 set_oszc (val, 4, c); \
408 fop_fadd (fp_t s1
, fp_t s2
, fp_t
*d
)
410 *d
= rxfp_add (s1
, s2
);
415 fop_fmul (fp_t s1
, fp_t s2
, fp_t
*d
)
417 *d
= rxfp_mul (s1
, s2
);
422 fop_fdiv (fp_t s1
, fp_t s2
, fp_t
*d
)
424 *d
= rxfp_div (s1
, s2
);
429 fop_fsub (fp_t s1
, fp_t s2
, fp_t
*d
)
431 *d
= rxfp_sub (s1
, s2
);
435 #define FPPENDING() (regs.r_fpsw & (FPSWBITS_CE | (FPSWBITS_FMASK & (regs.r_fpsw << FPSW_EFSH))))
436 #define FPCLEAR() regs.r_fpsw &= FPSWBITS_CLEAR
439 return do_fp_exception (opcode_pc)
441 #define FLOAT_OP(func) \
448 do_store = fop_##func (fa, fb, &fc); \
449 tprintf("%g " #func " %g = %g %08x\n", int2float(fa), int2float(fb), int2float(fc), fc); \
454 if ((fc & 0x80000000UL) != 0) \
456 if ((fc & 0x7fffffffUL) == 0) \
458 set_flags (FLAGBIT_S | FLAGBIT_Z, mb); \
461 #define carry (FLAG_C ? 1 : 0)
467 } exception_info
[] = {
468 { 0xFFFFFFD0UL
, "priviledged opcode", SIGILL
},
469 { 0xFFFFFFD4UL
, "access violation", SIGSEGV
},
470 { 0xFFFFFFDCUL
, "undefined opcode", SIGILL
},
471 { 0xFFFFFFE4UL
, "floating point", SIGFPE
}
473 #define EX_PRIVILEDGED 0
475 #define EX_UNDEFINED 2
476 #define EX_FLOATING 3
477 #define EXCEPTION(n) \
478 return generate_exception (n, opcode_pc)
480 #define PRIVILEDGED() \
482 EXCEPTION (EX_PRIVILEDGED)
485 generate_exception (unsigned long type
, SI opcode_pc
)
487 SI old_psw
, old_pc
, new_pc
;
489 new_pc
= mem_get_si (exception_info
[type
].vaddr
);
490 /* 0x00020000 is the value used to initialise the known
491 exception vectors (see rx.ld), but it is a reserved
492 area of memory so do not try to access it, and if the
493 value has not been changed by the program then the
494 vector has not been installed. */
495 if (new_pc
== 0 || new_pc
== 0x00020000)
498 return RX_MAKE_STOPPED (exception_info
[type
].signal
);
500 fprintf(stderr
, "Unhandled %s exception at pc = %#lx\n",
501 exception_info
[type
].str
, (unsigned long) opcode_pc
);
502 if (type
== EX_FLOATING
)
504 int mask
= FPPENDING ();
505 fprintf (stderr
, "Pending FP exceptions:");
506 if (mask
& FPSWBITS_FV
)
507 fprintf(stderr
, " Invalid");
508 if (mask
& FPSWBITS_FO
)
509 fprintf(stderr
, " Overflow");
510 if (mask
& FPSWBITS_FZ
)
511 fprintf(stderr
, " Division-by-zero");
512 if (mask
& FPSWBITS_FU
)
513 fprintf(stderr
, " Underflow");
514 if (mask
& FPSWBITS_FX
)
515 fprintf(stderr
, " Inexact");
516 if (mask
& FPSWBITS_CE
)
517 fprintf(stderr
, " Unimplemented");
518 fprintf(stderr
, "\n");
520 return RX_MAKE_EXITED (1);
523 tprintf ("Triggering %s exception\n", exception_info
[type
].str
);
525 old_psw
= regs
.r_psw
;
526 regs
.r_psw
&= ~ (FLAGBIT_I
| FLAGBIT_U
| FLAGBIT_PM
);
531 return RX_MAKE_STEPPED ();
535 generate_access_exception (void)
539 rv
= generate_exception (EX_ACCESS
, regs
.r_pc
);
541 longjmp (decode_jmp_buf
, rv
);
545 do_fp_exception (unsigned long opcode_pc
)
548 EXCEPTION (EX_FLOATING
);
549 return RX_MAKE_STEPPED ();
555 unsigned int uma
=0, umb
=0;
558 unsigned long long ll
;
560 unsigned long opcode_pc
;
562 RX_Opcode_Decoded opcode
;
565 if ((rv
= setjmp (decode_jmp_buf
)))
570 rx_data
.dpc
= opcode_pc
= regs
.r_pc
;
571 opcode_size
= rx_decode_opcode (opcode_pc
, &opcode
, rx_get_byte
, &rx_data
);
572 regs
.r_pc
+= opcode_size
;
574 rx_flagmask
= opcode
.flags_s
;
575 rx_flagand
= ~(int)opcode
.flags_0
;
576 rx_flagor
= opcode
.flags_1
;
582 tprintf("|%lld| = ", sll
);
585 tprintf("%lld\n", sll
);
605 if (opcode
.op
[0].type
== RX_Operand_Register
)
616 if (opcode
.op
[0].type
== RX_Operand_Register
)
630 if (opcode
.op
[0].type
== RX_Operand_Register
)
650 int old_psw
= regs
.r_psw
;
652 return RX_MAKE_HIT_BREAK ();
653 if (regs
.r_intb
== 0)
655 tprintf("BREAK hit, no vector table.\n");
656 return RX_MAKE_EXITED(1);
658 regs
.r_psw
&= ~(FLAGBIT_I
| FLAGBIT_U
| FLAGBIT_PM
);
661 regs
.r_pc
= mem_get_si (regs
.r_intb
);
668 if (opcode
.op
[0].type
== RX_Operand_Register
)
679 if (opcode
.op
[1].type
== RX_Operand_Register
)
683 umb
= ma
& (1 << mb
);
688 v
= 1 << opcode
.op
[0].reg
;
696 case RXO_div
: /* d = d / s */
699 tprintf("%d / %d = ", mb
, ma
);
700 if (ma
== 0 || (ma
== -1 && (unsigned int) mb
== 0x80000000))
703 set_flags (FLAGBIT_O
, FLAGBIT_O
);
709 set_flags (FLAGBIT_O
, 0);
714 case RXO_divu
: /* d = d / s */
717 tprintf("%u / %u = ", umb
, uma
);
721 set_flags (FLAGBIT_O
, FLAGBIT_O
);
727 set_flags (FLAGBIT_O
, 0);
735 tprintf("%d / %d = ", mb
, ma
);
736 if (ma
== 0 || (ma
== -1 && (unsigned int) mb
== 0x80000000))
739 set_flags (FLAGBIT_O
, FLAGBIT_O
);
745 tprintf("%d, rem %d\n", v
, mb
);
746 set_flags (FLAGBIT_O
, 0);
756 tprintf("%u / %u = ", umb
, uma
);
760 set_flags (FLAGBIT_O
, FLAGBIT_O
);
766 tprintf("%u, rem %u\n", v
, umb
);
767 set_flags (FLAGBIT_O
, 0);
777 sll
= (long long)ma
* (long long)mb
;
778 tprintf("%d * %d = %lld\n", ma
, mb
, sll
);
787 ll
= (long long)uma
* (long long)umb
;
788 tprintf("%#x * %#x = %#llx\n", uma
, umb
, ll
);
816 regs
.r_psw
= regs
.r_bpsw
;
817 regs
.r_pc
= regs
.r_bpc
;
827 mb
= rxfp_ftoi (ma
, FPRM_ZERO
);
830 tprintf("(int) %g = %d\n", int2float(ma
), mb
);
838 return rx_syscall (regs
.r
[5]);
842 int old_psw
= regs
.r_psw
;
843 regs
.r_psw
&= ~(FLAGBIT_I
| FLAGBIT_U
| FLAGBIT_PM
);
846 regs
.r_pc
= mem_get_si (regs
.r_intb
+ 4 * v
);
853 mb
= rxfp_itof (ma
, regs
.r_fpsw
);
855 tprintf("(float) %d = %x\n", ma
, mb
);
863 pushpc (get_reg (pc
));
864 if (opcode
.id
== RXO_jsrrel
)
870 ll
= (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
872 put_reg64 (acc64
, ll
+ regs
.r_acc
);
876 ll
= (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
878 put_reg64 (acc64
, ll
+ regs
.r_acc
);
901 if (opcode
.op
[0].type
== RX_Operand_Register
902 && opcode
.op
[0].reg
== 16 /* PSW */)
904 /* Special case, LDC and POPC can't ever modify PM. */
905 int pm
= regs
.r_psw
& FLAGBIT_PM
;
910 v
&= ~ (FLAGBIT_I
| FLAGBIT_U
| FLAGBITS_IPL
);
916 /* various things can't be changed in user mode. */
917 if (opcode
.op
[0].type
== RX_Operand_Register
)
918 if (opcode
.op
[0].reg
== 32)
920 v
&= ~ (FLAGBIT_I
| FLAGBIT_U
| FLAGBITS_IPL
);
921 v
|= regs
.r_psw
& (FLAGBIT_I
| FLAGBIT_U
| FLAGBITS_IPL
);
923 if (opcode
.op
[0].reg
== 34 /* ISP */
924 || opcode
.op
[0].reg
== 37 /* BPSW */
925 || opcode
.op
[0].reg
== 39 /* INTB */
926 || opcode
.op
[0].reg
== 38 /* VCT */)
927 /* These are ignored. */
935 /* We cheat to save on code duplication. */
936 regs
.r_temp
= (get_reg (opcode
.op
[1].reg
) * size2bytes
[opcode
.size
]
937 + get_reg (opcode
.op
[2].reg
));
938 opcode
.op
[1].reg
= r_temp_idx
;
939 opcode
.op
[1].type
= RX_Operand_Indirect
;
940 opcode
.op
[1].addend
= 0;
945 /* We cheat to save on code duplication. */
946 regs
.r_temp
= (get_reg (opcode
.op
[1].reg
) * size2bytes
[opcode
.size
]
947 + get_reg (opcode
.op
[2].reg
));
948 opcode
.op
[1].reg
= r_temp_idx
;
949 opcode
.op
[1].type
= RX_Operand_Indirect
;
950 opcode
.op
[1].addend
= 0;
955 ll
= (unsigned long long) US1() * (unsigned long long) US2();
960 ll
= (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
962 put_reg64 (acc64
, ll
);
966 ll
= (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
968 put_reg64 (acc64
, ll
);
972 PD (get_reg (acchi
));
976 PD (get_reg (acclo
));
980 PD (get_reg (accmi
));
984 put_reg (acchi
, GS ());
988 put_reg (acclo
, GS ());
992 regs
.r_psw
&= ~ FLAGBITS_IPL
;
993 regs
.r_psw
|= (GS () << FLAGSHIFT_IPL
) & FLAGBITS_IPL
;
1004 /* POPM cannot pop R0 (sp). */
1005 if (opcode
.op
[1].reg
== 0 || opcode
.op
[2].reg
== 0)
1006 EXCEPTION (EX_UNDEFINED
);
1007 if (opcode
.op
[1].reg
>= opcode
.op
[2].reg
)
1009 regs
.r_pc
= opcode_pc
;
1010 return RX_MAKE_STOPPED (SIGILL
);
1012 for (v
= opcode
.op
[1].reg
; v
<= opcode
.op
[2].reg
; v
++)
1013 put_reg (v
, pop ());
1017 push (get_reg (opcode
.op
[1].reg
) + opcode
.op
[1].addend
);
1021 /* PUSHM cannot push R0 (sp). */
1022 if (opcode
.op
[1].reg
== 0 || opcode
.op
[2].reg
== 0)
1023 EXCEPTION (EX_UNDEFINED
);
1024 if (opcode
.op
[1].reg
>= opcode
.op
[2].reg
)
1026 regs
.r_pc
= opcode_pc
;
1027 return RX_MAKE_STOPPED (SIGILL
);
1029 for (v
= opcode
.op
[2].reg
; v
>= opcode
.op
[1].reg
; v
--)
1034 ll
= get_reg64 (acc64
) << GS ();
1035 ll
+= 0x80000000ULL
;
1036 if ((signed long long)ll
> (signed long long)0x00007fff00000000ULL
)
1037 ll
= 0x00007fff00000000ULL
;
1038 else if ((signed long long)ll
< (signed long long)0xffff800000000000ULL
)
1039 ll
= 0xffff800000000000ULL
;
1041 ll
&= 0xffffffff00000000ULL
;
1042 put_reg64 (acc64
, ll
);
1047 regs
.r_pc
= poppc ();
1048 regs
.r_psw
= poppc ();
1050 regs
.r_psw
|= FLAGBIT_U
;
1055 umb
= (((uma
>> 24) & 0xff)
1056 | ((uma
>> 8) & 0xff00)
1057 | ((uma
<< 8) & 0xff0000)
1058 | ((uma
<< 24) & 0xff000000UL
));
1064 umb
= (((uma
>> 8) & 0x00ff00ff)
1065 | ((uma
<< 8) & 0xff00ff00UL
));
1070 while (regs
.r
[3] != 0)
1074 switch (opcode
.size
)
1077 ma
= mem_get_si (regs
.r
[1]);
1078 mb
= mem_get_si (regs
.r
[2]);
1083 ma
= sign_ext (mem_get_hi (regs
.r
[1]), 16);
1084 mb
= sign_ext (mem_get_hi (regs
.r
[2]), 16);
1089 ma
= sign_ext (mem_get_qi (regs
.r
[1]), 8);
1090 mb
= sign_ext (mem_get_qi (regs
.r
[2]), 8);
1097 /* We do the multiply as a signed value. */
1098 sll
= (long long)ma
* (long long)mb
;
1099 tprintf(" %016llx = %d * %d\n", sll
, ma
, mb
);
1100 /* but we do the sum as unsigned, while sign extending the operands. */
1101 tmp
= regs
.r
[4] + (sll
& 0xffffffffUL
);
1102 regs
.r
[4] = tmp
& 0xffffffffUL
;
1105 tmp
+= regs
.r
[5] + (sll
& 0xffffffffUL
);
1106 regs
.r
[5] = tmp
& 0xffffffffUL
;
1109 tmp
+= regs
.r
[6] + (sll
& 0xffffffffUL
);
1110 regs
.r
[6] = tmp
& 0xffffffffUL
;
1111 tprintf("%08lx\033[36m%08lx\033[0m%08lx\n",
1112 (unsigned long) regs
.r
[6],
1113 (unsigned long) regs
.r
[5],
1114 (unsigned long) regs
.r
[4]);
1118 if (regs
.r
[6] & 0x00008000)
1119 regs
.r
[6] |= 0xffff0000UL
;
1121 regs
.r
[6] &= 0x0000ffff;
1122 ma
= (regs
.r
[6] & 0x80000000UL
) ? FLAGBIT_S
: 0;
1123 if (regs
.r
[6] != 0 && regs
.r
[6] != 0xffffffffUL
)
1124 set_flags (FLAGBIT_O
|FLAGBIT_S
, ma
| FLAGBIT_O
);
1126 set_flags (FLAGBIT_O
|FLAGBIT_S
, ma
);
1131 ma
= v
& 0x80000000UL
;
1142 uma
|= (carry
? 0x80000000UL
: 0);
1143 set_szc (uma
, 4, mb
);
1152 uma
= (uma
<< mb
) | (uma
>> (32-mb
));
1155 set_szc (uma
, 4, mb
);
1164 uma
= (uma
>> mb
) | (uma
<< (32-mb
));
1165 mb
= uma
& 0x80000000;
1167 set_szc (uma
, 4, mb
);
1174 mb
= rxfp_ftoi (ma
, regs
.r_fpsw
);
1177 tprintf("(int) %g = %d\n", int2float(ma
), mb
);
1182 regs
.r_pc
= poppc ();
1186 if (opcode
.op
[2].type
== RX_Operand_Register
)
1189 /* RTSD cannot pop R0 (sp). */
1190 put_reg (0, get_reg (0) + GS() - (opcode
.op
[0].reg
-opcode
.op
[2].reg
+1)*4);
1191 if (opcode
.op
[2].reg
== 0)
1192 EXCEPTION (EX_UNDEFINED
);
1193 for (i
= opcode
.op
[2].reg
; i
<= opcode
.op
[0].reg
; i
++)
1194 put_reg (i
, pop ());
1197 put_reg (0, get_reg (0) + GS());
1198 put_reg (pc
, poppc ());
1202 if (FLAG_O
&& FLAG_S
)
1204 else if (FLAG_O
&& ! FLAG_S
)
1209 MATH_OP (-, ! carry
);
1220 while (regs
.r
[3] != 0)
1222 uma
= mem_get_qi (regs
.r
[1] ++);
1223 umb
= mem_get_qi (regs
.r
[2] ++);
1225 if (uma
!= umb
|| uma
== 0)
1231 set_zc (0, ((int)uma
- (int)umb
) >= 0);
1235 v
= 1 << opcode
.op
[0].reg
;
1246 uma
= mem_get_qi (regs
.r
[2] --);
1247 mem_put_qi (regs
.r
[1]--, uma
);
1255 uma
= mem_get_qi (regs
.r
[2] ++);
1256 mem_put_qi (regs
.r
[1]++, uma
);
1262 while (regs
.r
[3] != 0)
1264 uma
= mem_get_qi (regs
.r
[2] ++);
1265 mem_put_qi (regs
.r
[1]++, uma
);
1272 case RXO_shar
: /* d = ma >> mb */
1273 SHIFT_OP (sll
, int, mb
, >>=, 1);
1276 case RXO_shll
: /* d = ma << mb */
1277 SHIFT_OP (ll
, int, mb
, <<=, 0x80000000UL
);
1280 case RXO_shlr
: /* d = ma >> mb */
1281 SHIFT_OP (ll
, unsigned int, mb
, >>=, 1);
1285 switch (opcode
.size
)
1288 while (regs
.r
[3] != 0)
1290 mem_put_si (regs
.r
[1], regs
.r
[2]);
1296 while (regs
.r
[3] != 0)
1298 mem_put_hi (regs
.r
[1], regs
.r
[2]);
1304 while (regs
.r
[3] != 0)
1306 mem_put_qi (regs
.r
[1], regs
.r
[2]);
1323 regs
.r_psw
|= FLAGBIT_I
;
1324 return RX_MAKE_STOPPED(0);
1333 switch (opcode
.size
)
1337 while (regs
.r
[3] != 0)
1340 umb
= mem_get_si (get_reg (1));
1347 uma
= get_reg (2) & 0xffff;
1348 while (regs
.r
[3] != 0)
1351 umb
= mem_get_hi (get_reg (1));
1358 uma
= get_reg (2) & 0xff;
1359 while (regs
.r
[3] != 0)
1362 umb
= mem_get_qi (regs
.r
[1]);
1374 set_zc (0, ((int)uma
- (int)umb
) >= 0);
1380 switch (opcode
.size
)
1384 while (regs
.r
[3] != 0)
1387 umb
= mem_get_si (get_reg (1));
1394 uma
= get_reg (2) & 0xffff;
1395 while (regs
.r
[3] != 0)
1398 umb
= mem_get_hi (get_reg (1));
1405 uma
= get_reg (2) & 0xff;
1406 while (regs
.r
[3] != 0)
1409 umb
= mem_get_qi (regs
.r
[1]);
1421 set_zc (0, ((int)uma
- (int)umb
) >= 0);
1426 regs
.r_psw
|= FLAGBIT_I
;
1427 return RX_MAKE_STOPPED(0);
1430 v
= GS (); /* This is the memory operand, if any. */
1431 PS (GD ()); /* and this may change the address register. */
1440 EXCEPTION (EX_UNDEFINED
);
1443 return RX_MAKE_STEPPED ();
This page took 0.072245 seconds and 4 git commands to generate.