• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisión3c29390f0cb4faa183825ee7c80b627b8b9a219b (tree)
Tiempo2015-12-17 02:41:18
AutorYoshinori Sato <ysato@user...>
CommiterYoshinori Sato

Log Message

RXv2 instructions support

Cambiar Resumen

Diferencia incremental

--- a/include/gdb/sim-rx.h
+++ b/include/gdb/sim-rx.h
@@ -49,7 +49,9 @@ enum sim_rx_regnum
4949 sim_rx_bpc_regnum,
5050 sim_rx_fintv_regnum,
5151 sim_rx_fpsw_regnum,
52- sim_rx_acc_regnum,
52+ sim_rx_acc0_regnum,
53+ sim_rx_acc1_regnum,
54+ sim_rx_extb_regnum,
5355 sim_rx_num_regs
5456 };
5557
--- a/sim/rx/Makefile.in
+++ b/sim/rx/Makefile.in
@@ -40,6 +40,7 @@ SIM_OBJS = \
4040 $(ENDLIST)
4141
4242 LIBS = $B/bfd/libbfd.a $B/libiberty/libiberty.a
43+SIM_EXTRA_LIBS = -lm
4344
4445 ## COMMON_POST_CONFIG_FRAG
4546
--- a/sim/rx/cpu.h
+++ b/sim/rx/cpu.h
@@ -35,6 +35,12 @@ extern int rx_big_endian;
3535
3636 typedef struct
3737 {
38+ SI hi;
39+ DI lo;
40+} acc_t;
41+
42+typedef struct
43+{
3844 SI r[16];
3945
4046 SI r_psw;
@@ -51,8 +57,8 @@ typedef struct
5157 SI r_isp;
5258 SI r_fintv;
5359 SI r_intb;
54- SI r__reserved_cr_13;
55- SI r__reserved_cr_14;
60+ SI r_extb;
61+ SI r_li;
5662 SI r__reserved_cr_15;
5763
5864 SI r__reserved_cr_16;
@@ -75,7 +81,7 @@ typedef struct
7581
7682 SI r_temp;
7783
78- DI r_acc;
84+ acc_t r_acc[2];
7985
8086 #ifdef CYCLE_ACCURATE
8187 /* If set, RTS/RTSD take 2 fewer cycles. */
@@ -105,12 +111,12 @@ typedef struct
105111 #define isp 26
106112 #define fintv 27
107113 #define intb 28
114+#define extb 29
115+#define li 30
108116
109117 #define r_temp_idx 48
110-#define acc64 49
111-#define acchi 50
112-#define accmi 51
113-#define acclo 52
118+#define acc0 49
119+#define acc1 50
114120
115121 extern regs_type regs;
116122
@@ -170,9 +176,9 @@ void init_regs (void);
170176 void stack_heap_stats (void);
171177 void set_pointer_width (int bytes);
172178 unsigned int get_reg (int id);
173-unsigned long long get_reg64 (int id);
179+void get_acc (int id, acc_t *valuel);
174180 void put_reg (int id, unsigned int value);
175-void put_reg64 (int id, unsigned long long value);
181+void put_acc (int id, acc_t *value);
176182
177183 void set_flags (int mask, int newbits);
178184 void set_oszc (long long value, int bytes, int c);
--- a/sim/rx/fpu.c
+++ b/sim/rx/fpu.c
@@ -790,3 +790,174 @@ rxfp_itof (long fa, int round_mode)
790790 return rv;
791791 }
792792
793+double sqrt(double x);
794+
795+static FP_ExceptionCases ex_sqrt_tab[5][5] = {
796+ /* N +0 -0 +In -In */
797+ { eNR, eDZ, eDZ, eSZ, eSZ }, /* Normal */
798+ { eSZ, eIn, eIn, ePZ, eNZ }, /* +0 */
799+ { eSZ, eIn, eIn, eNZ, ePZ }, /* -0 */
800+ { eSI, ePI, eNI, eIn, eIn }, /* +Inf */
801+ { eSI, eNI, ePI, eIn, eIn }, /* -Inf */
802+};
803+
804+fp_t
805+rxfp_fsqrt (fp_t fa)
806+{
807+ FP_Parts a, b, c;
808+ fp_t rv;
809+ double da;
810+
811+ fp_explode (fa, &a);
812+ fp_explode (fa, &b);
813+ CHECK_EXCEPTIONS (a, b, rv, ex_sqrt_tab);
814+
815+ da = fp_to_double (&a);
816+ tprintf("sqrt(%g) = %g\n", da, sqrt(da));
817+
818+ double_to_fp (sqrt(da), &c);
819+ rv = fp_implode (&c);
820+
821+ return rv;
822+}
823+
824+unsigned long
825+rxfp_ftou (fp_t fa, int round_mode)
826+{
827+ FP_Parts a;
828+ fp_t rv;
829+ int sign;
830+ int whole_bits, frac_bits;
831+
832+ fp_explode (fa, &a);
833+ sign = fa & 0x80000000UL;
834+
835+ switch (a.type)
836+ {
837+ case FP_NORMAL:
838+ break;
839+ case FP_PZERO:
840+ case FP_NZERO:
841+ return 0;
842+ case FP_PINFINITY:
843+ FP_RAISE (V);
844+ return 0xffffffffL;
845+ case FP_NINFINITY:
846+ FP_RAISE (V);
847+ return 0x00000000L;
848+ case FP_DENORMAL:
849+ FP_RAISE (E);
850+ return 0;
851+ case FP_QNAN:
852+ case FP_SNAN:
853+ FP_RAISE (V);
854+ return sign ? 0x00000000 : 0xffffffff;
855+ }
856+
857+ if (sign)
858+ return 0;
859+ if (a.exp >= 32)
860+ {
861+ FP_RAISE (V);
862+ return 0xffffffff;
863+ }
864+
865+ a.exp -= 23;
866+
867+ if (a.exp <= -25)
868+ {
869+ /* Less than 0.49999 */
870+ frac_bits = a.mant;
871+ whole_bits = 0;
872+ }
873+ else if (a.exp < 0)
874+ {
875+ frac_bits = a.mant << (33 + a.exp);
876+ whole_bits = a.mant >> (-a.exp);
877+ }
878+ else
879+ {
880+ frac_bits = 0;
881+ whole_bits = a.mant << a.exp;
882+ }
883+
884+ if (frac_bits)
885+ {
886+ switch (round_mode & 3)
887+ {
888+ case FPRM_NEAREST:
889+ if (frac_bits & 0x80000000UL)
890+ whole_bits ++;
891+ break;
892+ case FPRM_ZERO:
893+ case FPRM_NINF:
894+ break;
895+ case FPRM_PINF:
896+ if (!sign)
897+ whole_bits ++;
898+ break;
899+ }
900+ }
901+
902+ rv = whole_bits;
903+
904+ return rv;
905+}
906+
907+fp_t
908+rxfp_utof (unsigned long fa, int round_mode)
909+{
910+ fp_t rv;
911+ int sign = 0;
912+ unsigned int frac_bits;
913+ volatile unsigned int whole_bits;
914+ FP_Parts a;
915+
916+ if (fa == 0)
917+ return PLUS_ZERO;
918+
919+ a.sign = 1;
920+
921+ whole_bits = fa;
922+ a.exp = 31;
923+
924+ while (! (whole_bits & 0x80000000UL))
925+ {
926+ a.exp --;
927+ whole_bits <<= 1;
928+ }
929+ frac_bits = whole_bits & 0xff;
930+ whole_bits = whole_bits >> 8;
931+
932+ if (frac_bits)
933+ {
934+ /* We must round */
935+ switch (round_mode & 3)
936+ {
937+ case FPRM_NEAREST:
938+ if (frac_bits & 0x80)
939+ whole_bits ++;
940+ break;
941+ case FPRM_ZERO:
942+ break;
943+ case FPRM_PINF:
944+ if (!sign)
945+ whole_bits ++;
946+ break;
947+ case FPRM_NINF:
948+ if (sign)
949+ whole_bits ++;
950+ break;
951+ }
952+ }
953+
954+ a.mant = whole_bits;
955+ if (whole_bits & 0xff000000UL)
956+ {
957+ a.mant >>= 1;
958+ a.exp ++;
959+ }
960+
961+ rv = fp_implode (&a);
962+ return rv;
963+}
--- a/sim/rx/fpu.h
+++ b/sim/rx/fpu.h
@@ -27,3 +27,6 @@ extern fp_t rxfp_div (fp_t fa, fp_t fb);
2727 extern void rxfp_cmp (fp_t fa, fp_t fb);
2828 extern long rxfp_ftoi (fp_t fa, int round_mode);
2929 extern fp_t rxfp_itof (long fa, int round_mode);
30+extern fp_t rxfp_fsqrt (fp_t fa);
31+extern unsigned long rxfp_ftou (fp_t fa, int round_mode);
32+extern fp_t rxfp_utof (unsigned long fa, int round_mode);
--- a/sim/rx/gdb-if.c
+++ b/sim/rx/gdb-if.c
@@ -387,6 +387,9 @@ reg_size (enum sim_rx_regnum regno)
387387 case sim_rx_intb_regnum:
388388 size = sizeof (regs.r_intb);
389389 break;
390+ case sim_rx_extb_regnum:
391+ size = sizeof (regs.r_extb);
392+ break;
390393 case sim_rx_pc_regnum:
391394 size = sizeof (regs.r_pc);
392395 break;
@@ -405,8 +408,9 @@ reg_size (enum sim_rx_regnum regno)
405408 case sim_rx_fpsw_regnum:
406409 size = sizeof (regs.r_fpsw);
407410 break;
408- case sim_rx_acc_regnum:
409- size = sizeof (regs.r_acc);
411+ case sim_rx_acc0_regnum:
412+ case sim_rx_acc1_regnum:
413+ size = 8;
410414 break;
411415 default:
412416 size = 0;
@@ -490,6 +494,9 @@ sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
490494 case sim_rx_intb_regnum:
491495 val = get_reg (intb);
492496 break;
497+ case sim_rx_extb_regnum:
498+ val = get_reg (extb);
499+ break;
493500 case sim_rx_pc_regnum:
494501 val = get_reg (pc);
495502 break;
@@ -508,9 +515,34 @@ sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
508515 case sim_rx_fpsw_regnum:
509516 val = get_reg (fpsw);
510517 break;
511- case sim_rx_acc_regnum:
512- val = ((DI) get_reg (acchi) << 32) | get_reg (acclo);
513- break;
518+ case sim_rx_acc0_regnum:
519+ {
520+ acc_t acc;
521+ get_acc(0, &acc);
522+ if (rx_big_endian)
523+ {
524+ put_be (buf, 8, acc.lo);
525+ }
526+ else
527+ {
528+ put_le (buf, 8, acc.lo);
529+ }
530+ return 8;
531+ }
532+ case sim_rx_acc1_regnum:
533+ {
534+ acc_t acc;
535+ get_acc(1, &acc);
536+ if (rx_big_endian)
537+ {
538+ put_be (buf, 8, acc.lo);
539+ }
540+ else
541+ {
542+ put_le (buf, 8, acc.lo);
543+ }
544+ return 8;
545+ }
514546 default:
515547 fprintf (stderr, "rx minisim: unrecognized register number: %d\n",
516548 regno);
@@ -623,10 +655,38 @@ sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
623655 case sim_rx_fpsw_regnum:
624656 put_reg (fpsw, val);
625657 break;
626- case sim_rx_acc_regnum:
627- put_reg (acclo, val & 0xffffffff);
628- put_reg (acchi, (val >> 32) & 0xffffffff);
629- break;
658+ case sim_rx_acc0_regnum:
659+ {
660+ acc_t acc;
661+ if (rx_big_endian)
662+ {
663+ acc.hi = get_be (buf, 8);
664+ acc.lo = get_be (buf + 8, 8);
665+ }
666+ else
667+ {
668+ acc.lo = get_le (buf, 8);
669+ acc.hi = get_le (buf + 8, 8);
670+ }
671+ put_acc (0, &acc);
672+ break;
673+ }
674+ case sim_rx_acc1_regnum:
675+ {
676+ acc_t acc;
677+ if (rx_big_endian)
678+ {
679+ acc.hi = get_be (buf, 8);
680+ acc.lo = get_be (buf + 8, 8);
681+ }
682+ else
683+ {
684+ acc.lo = get_le (buf, 8);
685+ acc.hi = get_le (buf + 8, 8);
686+ }
687+ put_acc (1, &acc);
688+ break;
689+ }
630690 default:
631691 fprintf (stderr, "rx minisim: unrecognized register number: %d\n",
632692 regno);
--- a/sim/rx/reg.c
+++ b/sim/rx/reg.c
@@ -50,10 +50,10 @@ char *reg_names[] = {
5050 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
5151 /* control register */
5252 "psw", "pc", "usp", "fpsw", "RES", "RES", "RES", "RES",
53- "bpsw", "bpc", "isp", "fintv", "intb", "RES", "RES", "RES",
53+ "bpsw", "bpc", "isp", "fintv", "intb", "extb", "li", "RES",
5454 "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
5555 "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
56- "temp", "acc", "acchi", "accmi", "acclo"
56+ "temp", "acc0", "acc1",
5757 };
5858
5959 unsigned int b2mask[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
@@ -69,6 +69,9 @@ init_regs (void)
6969 memset (&regs, 0, sizeof (regs));
7070 memset (&oldregs, 0, sizeof (oldregs));
7171
72+ regs.r_extb = 0xffffff80;
73+ oldregs.r_extb = 0xffffff80;
74+
7275 #ifdef CYCLE_ACCURATE
7376 regs.rt = -1;
7477 oldregs.rt = -1;
@@ -102,16 +105,14 @@ get_reg_i (int id)
102105 return regs.r_fintv;
103106 case intb:
104107 return regs.r_intb;
108+ case extb:
109+ return regs.r_extb;
110+ case li:
111+ return regs.r_li;
105112 case pc:
106113 return regs.r_pc;
107114 case r_temp_idx:
108115 return regs.r_temp;
109- case acchi:
110- return (SI)(regs.r_acc >> 32);
111- case accmi:
112- return (SI)(regs.r_acc >> 16);
113- case acclo:
114- return (SI)regs.r_acc;
115116 }
116117 abort();
117118 }
@@ -125,25 +126,14 @@ get_reg (int id)
125126 return rv;
126127 }
127128
128-static unsigned long long
129-get_reg64_i (int id)
130-{
131- switch (id)
132- {
133- case acc64:
134- return regs.r_acc;
135- default:
136- abort ();
137- }
138-}
139-
140-unsigned long long
141-get_reg64 (int id)
129+void
130+get_acc (int id, acc_t *acc)
142131 {
143- unsigned long long rv = get_reg64_i (id);
144- if (trace > ((id != pc && id != sp) ? 0 : 1))
145- printf ("get_reg (%s) = %016llx\n", reg_names[id], rv);
146- return rv;
132+ if (id >= 2)
133+ abort ();
134+ *acc = regs.r_acc[id];
135+ if (trace > 0)
136+ printf ("get_reg (%s) = %08x%016lx\n", reg_names[acc0 + id], acc->hi, acc->lo);
147137 }
148138
149139 static int highest_sp = 0, lowest_sp = 0xffffff;
@@ -203,18 +193,14 @@ put_reg (int id, unsigned int v)
203193 case intb:
204194 regs.r_intb = v;
205195 break;
206- case pc:
207- regs.r_pc = v;
196+ case extb:
197+ regs.r_extb = v;
208198 break;
209-
210- case acchi:
211- regs.r_acc = (regs.r_acc & 0xffffffffULL) | ((DI)v << 32);
199+ case li:
200+ regs.r_li = v;
212201 break;
213- case accmi:
214- regs.r_acc = (regs.r_acc & ~0xffffffff0000ULL) | ((DI)v << 16);
215- break;
216- case acclo:
217- regs.r_acc = (regs.r_acc & ~0xffffffffULL) | ((DI)v);
202+ case pc:
203+ regs.r_pc = v;
218204 break;
219205
220206 case 0: /* Stack pointer is "in" R0. */
@@ -261,19 +247,15 @@ put_reg (int id, unsigned int v)
261247 }
262248
263249 void
264-put_reg64 (int id, unsigned long long v)
250+put_acc (int id, acc_t *acc)
265251 {
266- if (trace > ((id != pc) ? 0 : 1))
267- printf ("put_reg (%s) = %016llx\n", reg_names[id], v);
268252
269- switch (id)
270- {
271- case acc64:
272- regs.r_acc = v;
273- break;
274- default:
275- abort ();
276- }
253+ if (id >= 2)
254+ abort ();
255+ if (trace > 0)
256+ printf ("put_reg (%s) = %08x%016lx\n", reg_names[acc0 + id], acc->hi, acc->lo);
257+
258+ regs.r_acc[id] = *acc;
277259 }
278260
279261 int
@@ -545,14 +527,19 @@ trace_register_changes (void)
545527 oldregs.r_fpsw = regs.r_fpsw;
546528 }
547529
548- if (oldregs.r_acc != regs.r_acc)
530+ for(i = 0; i < 2; i++)
549531 {
550- if (tag) { printf (tag); tag = 0; }
551- printf(" acc %016llx:", oldregs.r_acc);
552- printf("%016llx", regs.r_acc);
553- oldregs.r_acc = regs.r_acc;
532+ if (oldregs.r_acc[i].hi != regs.r_acc[i].hi ||
533+ oldregs.r_acc[i].lo != regs.r_acc[i].lo)
534+ {
535+ if (tag) { printf (tag); tag = 0; }
536+ printf(" acc%d %08x%016lx:", i, oldregs.r_acc[i].hi,
537+ oldregs.r_acc[i].lo);
538+ printf("%08x%016lx", regs.r_acc[i].hi,
539+ oldregs.r_acc[i].lo);
540+ oldregs.r_acc[i] = regs.r_acc[i];
541+ }
554542 }
555-
556543 if (tag == 0)
557544 printf ("\033[0m\n");
558545 }
--- a/sim/rx/rx.c
+++ b/sim/rx/rx.c
@@ -137,6 +137,25 @@ static const char * id_names[] = {
137137 "RXO_wait",
138138
139139 "RXO_sccnd", /* d = cond(s) ? 1 : 0 */
140+
141+ "RXO_fsqrt",
142+ "RXO_ftou",
143+ "RXO_utof",
144+ "RXO_movco",
145+ "RXO_movli",
146+ "RXO_emaca",
147+ "RXO_emsba",
148+ "RXO_emula",
149+ "RXO_maclh",
150+ "RXO_msbhi",
151+ "RXO_msblh",
152+ "RXO_msblo",
153+ "RXO_mullh",
154+ "RXO_mvfacgu",
155+ "RXO_mvtacgu",
156+ "RXO_racl",
157+ "RXO_rdacl",
158+ "RXO_rdacw",
140159 };
141160
142161 static const char * optype_names[] = {
@@ -806,8 +825,8 @@ fop_fsub (fp_t s1, fp_t s2, fp_t *d)
806825 int do_store; \
807826 fp_t fa, fb, fc; \
808827 FPCLEAR(); \
809- fb = GS (); \
810- fa = GD (); \
828+ fb = US2 (); \
829+ fa = US1 (); \
811830 do_store = fop_##func (fa, fb, &fc); \
812831 tprintf("%g " #func " %g = %g %08x\n", int2float(fa), int2float(fb), int2float(fc), fc); \
813832 FPCHECK(); \
@@ -929,6 +948,66 @@ op_is_memory (const RX_Opcode_Decoded *rd, int i)
929948
930949 #define DO_RETURN(x) { longjmp (decode_jmp_buf, x); }
931950
951+#define MULADD(val, s) \
952+{ \
953+ get_acc(opcode->op[0].reg - 32, &acc); \
954+ sll = val; \
955+ sll <<= s; \
956+ if (sll > 0 && (unsigned long long)acc.lo > (unsigned long long)(acc.lo + sll)) \
957+ acc.hi++; \
958+ else if (sll < 0 && (unsigned long long)(acc.lo + sll) > (unsigned long long)acc.lo) \
959+ acc.hi--; \
960+ acc.lo += sll; \
961+ put_acc (opcode->op[0].reg - 32, &acc); \
962+ E1; \
963+ break; \
964+}
965+
966+#define MULSUB(val, s) \
967+{ \
968+ get_acc(opcode->op[0].reg - 32, &acc); \
969+ sll = val; \
970+ sll <<= s; \
971+ if (sll > 0 && (unsigned long long)(sll - acc.lo) > (unsigned long long)acc.lo) \
972+ acc.hi--; \
973+ else if (sll < 0 && (unsigned long long)acc.lo >(unsigned long long)(sll - acc.lo)) \
974+ acc.hi++; \
975+ acc.hi = (signed char)acc.hi; \
976+ acc.lo -= sll; \
977+ put_acc (opcode->op[0].reg - 32, &acc); \
978+ E1; \
979+ break; \
980+}
981+
982+#define MULACC(val, s) \
983+{ \
984+ sll = val; \
985+ sll <<= s; \
986+ acc.lo = sll; \
987+ acc.hi = (sll < 0)? -1 : 0; \
988+ put_acc (opcode->op[0].reg - 32, &acc); \
989+ E1; \
990+ break; \
991+}
992+
993+#define RAC(add, pl, ml) \
994+{ \
995+ get_acc(opcode->op[0].reg - 32, &acc); \
996+ ll = acc.lo << GS (); \
997+ ll += add; \
998+ if ((signed long long)ll > (signed long long)0x00007fff00000000ULL) \
999+ ll = 0x00007fff00000000ULL; \
1000+ else if ((signed long long)ll < (signed long long)0xffff800000000000ULL) \
1001+ ll = 0xffff800000000000ULL; \
1002+ else \
1003+ ll &= 0xffffffff00000000ULL; \
1004+ acc.hi = ((signed long long)ll < 0) ? -1 : 0; \
1005+ acc.lo = ll; \
1006+ put_acc (opcode->op[0].reg - 32, &acc); \
1007+ E1; \
1008+ break; \
1009+}
1010+
9321011 int
9331012 decode_opcode ()
9341013 {
@@ -940,6 +1019,7 @@ decode_opcode ()
9401019 unsigned long opcode_pc;
9411020 RX_Data rx_data;
9421021 const RX_Opcode_Decoded *opcode;
1022+ acc_t acc;
9431023 #ifdef CYCLE_STATS
9441024 unsigned long long prev_cycle_count;
9451025 #endif
@@ -1216,6 +1296,12 @@ decode_opcode ()
12161296 }
12171297 break;
12181298
1299+ case RXO_emaca:
1300+ MULADD((long long)GS2 () * (long long)GS (), 0)
1301+
1302+ case RXO_emsba:
1303+ MULSUB((long long)GS2 () * (long long)GS (), 0)
1304+
12191305 case RXO_emul:
12201306 ma = GD ();
12211307 mb = GS ();
@@ -1226,6 +1312,18 @@ decode_opcode ()
12261312 E2;
12271313 break;
12281314
1315+ case RXO_emula:
1316+ ma = GS2 ();
1317+ mb = GS ();
1318+ acc.lo = (long long)ma * (long long)mb;
1319+ if (acc.lo < 0)
1320+ acc.hi = -1;
1321+ else
1322+ acc.hi = 0;
1323+ put_acc (opcode->op[0].reg - 32, &acc);
1324+ E (3);
1325+ break;
1326+
12291327 case RXO_emulu:
12301328 uma = GD ();
12311329 umb = GS ();
@@ -1264,12 +1362,24 @@ decode_opcode ()
12641362 PRIVILEDGED ();
12651363 regs.r_psw = regs.r_bpsw;
12661364 regs.r_pc = regs.r_bpc;
1365+ regs.r_li = 0;
12671366 #ifdef CYCLE_ACCURATE
12681367 regs.fast_return = 0;
12691368 cycles(3);
12701369 #endif
12711370 break;
12721371
1372+ case RXO_fsqrt:
1373+ ma = GS ();
1374+ FPCLEAR ();
1375+ mb = rxfp_fsqrt (ma);
1376+ FPCHECK ();
1377+ PD (mb);
1378+ tprintf("(int) %g = %d\n", int2float(ma), mb);
1379+ set_sz (mb, 4);
1380+ E (16);
1381+ break;
1382+
12731383 case RXO_fsub:
12741384 FLOAT_OP (fsub);
12751385 E (4);
@@ -1286,6 +1396,17 @@ decode_opcode ()
12861396 E (2);
12871397 break;
12881398
1399+ case RXO_ftou:
1400+ ma = GS ();
1401+ FPCLEAR ();
1402+ mb = rxfp_ftou (ma, FPRM_ZERO);
1403+ FPCHECK ();
1404+ PD (mb);
1405+ tprintf("(int) %g = %d\n", int2float(ma), mb);
1406+ set_sz (mb, 4);
1407+ E (2);
1408+ break;
1409+
12891410 case RXO_int:
12901411 v = GS ();
12911412 if (v == 255)
@@ -1352,18 +1473,13 @@ decode_opcode ()
13521473 break;
13531474
13541475 case RXO_machi:
1355- ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
1356- ll <<= 16;
1357- put_reg64 (acc64, ll + regs.r_acc);
1358- E1;
1359- break;
1476+ MULADD((long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16), 16)
1477+
1478+ case RXO_maclh:
1479+ MULADD((long long)(signed short)(GS()) * (long long)(signed short)(GS2 () >> 16), 16)
13601480
13611481 case RXO_maclo:
1362- ll = (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
1363- ll <<= 16;
1364- put_reg64 (acc64, ll + regs.r_acc);
1365- E1;
1366- break;
1482+ MULADD((long long)(signed short)(GS()) * (long long)(signed short)(GS2 ()), 16)
13671483
13681484 case RXO_max:
13691485 mb = GS();
@@ -1457,6 +1573,33 @@ decode_opcode ()
14571573 cycles (1);
14581574 break;
14591575
1576+ case RXO_movli:
1577+ PD (mem_get_si (GS ()));
1578+ regs.r_li = 1;
1579+ E1;
1580+ break;
1581+
1582+ case RXO_movco:
1583+ if (regs.r_li == 1)
1584+ {
1585+ mem_put_si (GD (), GS ());
1586+ PS (0);
1587+ }
1588+ else
1589+ PS (1);
1590+ regs.r_li = 0;
1591+ E1;
1592+ break;
1593+
1594+ case RXO_msbhi:
1595+ MULSUB((long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16), 16)
1596+
1597+ case RXO_msblh:
1598+ MULSUB((long long)(signed short)(GS()) * (long long)(signed short)(GS2 () >> 16), 16)
1599+
1600+ case RXO_msblo:
1601+ MULSUB((long long)(signed short)(GS()) * (long long)(signed short)(GS2 ()), 16)
1602+
14601603 case RXO_mul:
14611604 v = US2 ();
14621605 ll = (unsigned long long) US1() * (unsigned long long) v;
@@ -1465,43 +1608,64 @@ decode_opcode ()
14651608 break;
14661609
14671610 case RXO_mulhi:
1468- v = GS2 ();
1469- ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(v >> 16);
1470- ll <<= 16;
1471- put_reg64 (acc64, ll);
1472- E1;
1473- break;
1611+ MULACC((long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16), 16)
1612+ case RXO_mullh:
1613+ MULACC((long long)(signed short)(GS()) * (long long)(signed short)(GS2 () >> 16), 16)
14741614
14751615 case RXO_mullo:
1476- v = GS2 ();
1477- ll = (long long)(signed short)(GS()) * (long long)(signed short)(v);
1478- ll <<= 16;
1479- put_reg64 (acc64, ll);
1480- E1;
1481- break;
1616+ MULACC((long long)(signed short)(GS()) * (long long)(signed short)(GS2 ()), 16)
14821617
14831618 case RXO_mvfachi:
1484- PD (get_reg (acchi));
1619+ get_acc (opcode->op[1].reg - 32, &acc);
1620+ PD ((acc.lo << GS2 ()) >> 32);
14851621 E1;
14861622 break;
14871623
14881624 case RXO_mvfaclo:
1489- PD (get_reg (acclo));
1625+ get_acc (opcode->op[1].reg - 32, &acc);
1626+ PD (acc.lo << GS2 ());
14901627 E1;
14911628 break;
14921629
14931630 case RXO_mvfacmi:
1494- PD (get_reg (accmi));
1631+ get_acc (opcode->op[1].reg - 32, &acc);
1632+ PD ((acc.lo << GS2 ()) >> 16);
1633+ E1;
1634+ break;
1635+
1636+ case RXO_mvfacgu:
1637+ get_acc (opcode->op[1].reg - 32, &acc);
1638+ uma = (signed char)acc.hi;
1639+ umb = GS2 ();
1640+ if (umb)
1641+ {
1642+ uma <<= umb;
1643+ uma |= ((acc.lo >> (64 - umb)) & 3);
1644+ }
1645+ PD (uma);
14951646 E1;
14961647 break;
14971648
14981649 case RXO_mvtachi:
1499- put_reg (acchi, GS ());
1650+ get_acc (opcode->op[0].reg - 32, &acc);
1651+ acc.lo &= ((1ULL << 32) - 1);
1652+ acc.lo |= (unsigned long long) GS () << 32ULL;
1653+ put_acc (opcode->op[0].reg - 32, &acc);
15001654 E1;
15011655 break;
15021656
15031657 case RXO_mvtaclo:
1504- put_reg (acclo, GS ());
1658+ get_acc (opcode->op[0].reg - 32, &acc);
1659+ acc.lo &= ~((1ULL << 32ULL) - 1);
1660+ acc.lo |= (unsigned long) GS ();
1661+ put_acc (opcode->op[0].reg - 32, &acc);
1662+ E1;
1663+ break;
1664+
1665+ case RXO_mvtacgu:
1666+ get_acc (opcode->op[0].reg - 32, &acc);
1667+ acc.hi = GS ();
1668+ put_acc (opcode->op[0].reg - 32, &acc);
15051669 E1;
15061670 break;
15071671
@@ -1560,22 +1724,22 @@ decode_opcode ()
15601724 break;
15611725
15621726 case RXO_racw:
1563- ll = get_reg64 (acc64) << GS ();
1564- ll += 0x80000000ULL;
1565- if ((signed long long)ll > (signed long long)0x00007fff00000000ULL)
1566- ll = 0x00007fff00000000ULL;
1567- else if ((signed long long)ll < (signed long long)0xffff800000000000ULL)
1568- ll = 0xffff800000000000ULL;
1569- else
1570- ll &= 0xffffffff00000000ULL;
1571- put_reg64 (acc64, ll);
1572- E1;
1573- break;
1727+ RAC(0x80000000ULL, 0x00007fff00000000ULL, 0xffff800000000000ULL)
1728+
1729+ case RXO_rdacw:
1730+ RAC(0, 0x00007fff00000000ULL, 0xffffffff80000000ULL)
1731+
1732+ case RXO_racl:
1733+ RAC(0x80000000ULL, 0x7fffffff00000000ULL, 0xffffffff80000000ULL)
1734+
1735+ case RXO_rdacl:
1736+ RAC(0, 0x7fffffff00000000ULL, 0xffff800000000000ULL)
15741737
15751738 case RXO_rte:
15761739 PRIVILEDGED ();
15771740 regs.r_pc = poppc ();
15781741 regs.r_psw = poppc ();
1742+ regs.r_li = 0;
15791743 if (FLAG_PM)
15801744 regs.r_psw |= FLAGBIT_U;
15811745 #ifdef CYCLE_ACCURATE
@@ -2130,6 +2294,21 @@ decode_opcode ()
21302294 set_zc (0, ((int)uma - (int)umb) >= 0);
21312295 break;
21322296
2297+ case RXO_utof:
2298+ ma = GS ();
2299+ FPCLEAR ();
2300+ mb = rxfp_utof (ma, regs.r_fpsw);
2301+ FPCHECK ();
2302+ tprintf("(float) %d = %x\n", ma, mb);
2303+ PD (mb);
2304+ if (mb)
2305+ set_flags (FLAGBIT_Z, 0);
2306+ else
2307+ set_flags (FLAGBIT_Z, FLAGBIT_Z);
2308+ set_flags (FLAGBIT_S, 0);
2309+ E (2);
2310+ break;
2311+
21332312 case RXO_wait:
21342313 PRIVILEDGED ();
21352314 regs.r_psw |= FLAGBIT_I;