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 ();