10 #include <linux/types.h>
11 #include <linux/sched.h>
13 #include <asm/uaccess.h>
26 #define _FP_TO_FPINT_ROUND(fs, wc, X) \
31 if (X##_e > _FP_FRACBITS_##fs + _FP_EXPBIAS_##fs) \
34 else if (X##_e <= _FP_FRACBITS_##fs + _FP_EXPBIAS_##fs && \
35 X##_e > _FP_EXPBIAS_##fs) \
37 _FP_FRAC_SRS_##wc(X, _FP_WFRACBITS_##fs, \
38 X##_e - _FP_EXPBIAS_##fs \
39 + _FP_FRACBITS_##fs); \
41 _FP_FRAC_SLL_##wc(X, X##_e - _FP_EXPBIAS_##fs \
42 + _FP_FRACBITS_##fs); \
46 FP_SET_EXCEPTION(FP_EX_INEXACT); \
47 X##_c = FP_CLS_ZERO; \
57 #define FP_TO_FPINT_ROUND_S(X) _FP_TO_FPINT_ROUND(S,1,X)
58 #define FP_TO_FPINT_ROUND_D(X) _FP_TO_FPINT_ROUND(D,2,X)
59 #define FP_TO_FPINT_ROUND_Q(X) _FP_TO_FPINT_ROUND(Q,4,X)
73 #define mathemu_put_user(x, p) \
75 if (put_user((x),(p))) \
79 #define mathemu_get_user(x, p) \
81 if (get_user((x),(p))) \
85 #define mathemu_copy_from_user(d, s, n)\
87 if (copy_from_user((d),(s),(n)) != 0) \
91 #define mathemu_copy_to_user(d, s, n) \
93 if (copy_to_user((d),(s),(n)) != 0) \
97 static void display_emulation_not_implemented(
struct pt_regs *
regs,
char *
instr)
106 printk(
"%s ieee fpu instruction not emulated "
107 "process name: %s pid: %d \n",
109 printk(
"%s's PSW: %08lx %08lx\n", instr,
110 (
unsigned long) regs->
psw.mask,
111 (
unsigned long) location);
117 regs->
psw.mask = (regs->
psw.mask & 0xFFFFCFFF) | ((cc&3) << 12);
127 static inline void emu_set_CC_cs(
struct pt_regs *regs,
int class,
int sign)
132 emu_set_CC(regs, sign ? 1 : 2);
144 static int emu_axbr (
struct pt_regs *regs,
int rx,
int ry) {
150 mode =
current->thread.fp_regs.fpc & 3;
151 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
152 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
154 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
155 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
159 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
160 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
161 emu_set_CC_cs(regs, QR_c, QR_s);
166 static int emu_adbr (
struct pt_regs *regs,
int rx,
int ry) {
171 mode =
current->thread.fp_regs.fpc & 3;
176 emu_set_CC_cs(regs, DR_c, DR_s);
181 static int emu_adb (
struct pt_regs *regs,
int rx,
double *
val) {
186 mode =
current->thread.fp_regs.fpc & 3;
191 emu_set_CC_cs(regs, DR_c, DR_s);
196 static int emu_aebr (
struct pt_regs *regs,
int rx,
int ry) {
201 mode =
current->thread.fp_regs.fpc & 3;
206 emu_set_CC_cs(regs, SR_c, SR_s);
211 static int emu_aeb (
struct pt_regs *regs,
int rx,
float *
val) {
216 mode =
current->thread.fp_regs.fpc & 3;
221 emu_set_CC_cs(regs, SR_c, SR_s);
226 static int emu_cxbr (
struct pt_regs *regs,
int rx,
int ry) {
231 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
232 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
234 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
235 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
242 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
247 static int emu_cdbr (
struct pt_regs *regs,
int rx,
int ry) {
258 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
263 static int emu_cdb (
struct pt_regs *regs,
int rx,
double *
val) {
274 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
279 static int emu_cebr (
struct pt_regs *regs,
int rx,
int ry) {
290 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
295 static int emu_ceb (
struct pt_regs *regs,
int rx,
float *val) {
306 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
311 static int emu_kxbr (
struct pt_regs *regs,
int rx,
int ry) {
317 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
318 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
320 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
321 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
328 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
335 static int emu_kdbr (
struct pt_regs *regs,
int rx,
int ry) {
347 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
354 static int emu_kdb (
struct pt_regs *regs,
int rx,
double *val) {
366 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
373 static int emu_kebr (
struct pt_regs *regs,
int rx,
int ry) {
385 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
392 static int emu_keb (
struct pt_regs *regs,
int rx,
float *val) {
404 emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
411 static int emu_cxfbr (
struct pt_regs *regs,
int rx,
int ry) {
418 mode =
current->thread.fp_regs.fpc & 3;
422 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
423 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
428 static int emu_cdfbr (
struct pt_regs *regs,
int rx,
int ry) {
434 mode =
current->thread.fp_regs.fpc & 3;
442 static int emu_cefbr (
struct pt_regs *regs,
int rx,
int ry) {
448 mode =
current->thread.fp_regs.fpc & 3;
456 static int emu_cfxbr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
464 mode =
current->thread.fp_regs.fpc & 3;
469 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
470 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
474 emu_set_CC_cs(regs, QA_c, QA_s);
479 static int emu_cfdbr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
486 mode =
current->thread.fp_regs.fpc & 3;
494 emu_set_CC_cs(regs, DA_c, DA_s);
499 static int emu_cfebr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
506 mode =
current->thread.fp_regs.fpc & 3;
514 emu_set_CC_cs(regs, SA_c, SA_s);
519 static int emu_dxbr (
struct pt_regs *regs,
int rx,
int ry) {
525 mode =
current->thread.fp_regs.fpc & 3;
526 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
527 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
529 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
530 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
534 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
535 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
540 static int emu_ddbr (
struct pt_regs *regs,
int rx,
int ry) {
545 mode =
current->thread.fp_regs.fpc & 3;
554 static int emu_ddb (
struct pt_regs *regs,
int rx,
double *val) {
559 mode =
current->thread.fp_regs.fpc & 3;
568 static int emu_debr (
struct pt_regs *regs,
int rx,
int ry) {
573 mode =
current->thread.fp_regs.fpc & 3;
582 static int emu_deb (
struct pt_regs *regs,
int rx,
float *val) {
587 mode =
current->thread.fp_regs.fpc & 3;
596 static int emu_didbr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
597 display_emulation_not_implemented(regs,
"didbr");
602 static int emu_diebr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
603 display_emulation_not_implemented(regs,
"diebr");
608 static int emu_efpc (
struct pt_regs *regs,
int rx,
int ry) {
614 static int emu_ltxbr (
struct pt_regs *regs,
int rx,
int ry) {
620 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
621 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
625 emu_set_CC_cs(regs, QA_c, QA_s);
630 static int emu_ltdbr (
struct pt_regs *regs,
int rx,
int ry) {
637 emu_set_CC_cs(regs, DA_c, DA_s);
642 static int emu_ltebr (
struct pt_regs *regs,
int rx,
int ry) {
649 emu_set_CC_cs(regs, SA_c, SA_s);
654 static int emu_lcxbr (
struct pt_regs *regs,
int rx,
int ry) {
660 mode =
current->thread.fp_regs.fpc & 3;
661 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
662 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
666 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
667 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
668 emu_set_CC_cs(regs, QR_c, QR_s);
673 static int emu_lcdbr (
struct pt_regs *regs,
int rx,
int ry) {
678 mode =
current->thread.fp_regs.fpc & 3;
682 emu_set_CC_cs(regs, DR_c, DR_s);
687 static int emu_lcebr (
struct pt_regs *regs,
int rx,
int ry) {
692 mode =
current->thread.fp_regs.fpc & 3;
696 emu_set_CC_cs(regs, SR_c, SR_s);
701 static int emu_fixbr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
710 mode = fp_regs->
fpc & 3;
716 cvt.
w.low = fp_regs->
fprs[ry+2].
ui;
721 fp_regs->
fprs[rx+2].
ui = cvt.
w.low;
726 static int emu_fidbr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
735 mode = fp_regs->
fpc & 3;
747 static int emu_fiebr (
struct pt_regs *regs,
int rx,
int ry,
int mask) {
755 mode = fp_regs->
fpc & 3;
767 static int emu_lxdbr (
struct pt_regs *regs,
int rx,
int ry) {
773 mode =
current->thread.fp_regs.fpc & 3;
777 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
778 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
783 static int emu_lxdb (
struct pt_regs *regs,
int rx,
double *val) {
789 mode =
current->thread.fp_regs.fpc & 3;
793 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
794 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
799 static int emu_lxebr (
struct pt_regs *regs,
int rx,
int ry) {
805 mode =
current->thread.fp_regs.fpc & 3;
809 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
810 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
815 static int emu_lxeb (
struct pt_regs *regs,
int rx,
float *val) {
821 mode =
current->thread.fp_regs.fpc & 3;
825 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
826 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
831 static int emu_ldebr (
struct pt_regs *regs,
int rx,
int ry) {
836 mode =
current->thread.fp_regs.fpc & 3;
844 static int emu_ldeb (
struct pt_regs *regs,
int rx,
float *val) {
849 mode =
current->thread.fp_regs.fpc & 3;
857 static int emu_lnxbr (
struct pt_regs *regs,
int rx,
int ry) {
863 mode =
current->thread.fp_regs.fpc & 3;
864 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
865 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
870 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
871 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
875 current->thread.fp_regs.fprs[rx+2].ui =
876 current->thread.fp_regs.fprs[ry+2].ui;
878 emu_set_CC_cs(regs, QR_c, QR_s);
883 static int emu_lndbr (
struct pt_regs *regs,
int rx,
int ry) {
888 mode =
current->thread.fp_regs.fpc & 3;
896 emu_set_CC_cs(regs, DR_c, DR_s);
901 static int emu_lnebr (
struct pt_regs *regs,
int rx,
int ry) {
906 mode =
current->thread.fp_regs.fpc & 3;
914 emu_set_CC_cs(regs, SR_c, SR_s);
919 static int emu_lpxbr (
struct pt_regs *regs,
int rx,
int ry) {
925 mode =
current->thread.fp_regs.fpc & 3;
926 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
927 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
932 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
933 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
937 current->thread.fp_regs.fprs[rx+2].ui =
938 current->thread.fp_regs.fprs[ry+2].ui;
940 emu_set_CC_cs(regs, QR_c, QR_s);
945 static int emu_lpdbr (
struct pt_regs *regs,
int rx,
int ry) {
950 mode =
current->thread.fp_regs.fpc & 3;
958 emu_set_CC_cs(regs, DR_c, DR_s);
963 static int emu_lpebr (
struct pt_regs *regs,
int rx,
int ry) {
968 mode =
current->thread.fp_regs.fpc & 3;
976 emu_set_CC_cs(regs, SR_c, SR_s);
981 static int emu_ldxbr (
struct pt_regs *regs,
int rx,
int ry) {
987 mode =
current->thread.fp_regs.fpc & 3;
988 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
989 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
997 static int emu_lexbr (
struct pt_regs *regs,
int rx,
int ry) {
1003 mode =
current->thread.fp_regs.fpc & 3;
1004 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
1005 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
1013 static int emu_ledbr (
struct pt_regs *regs,
int rx,
int ry) {
1018 mode =
current->thread.fp_regs.fpc & 3;
1026 static int emu_mxbr (
struct pt_regs *regs,
int rx,
int ry) {
1032 mode =
current->thread.fp_regs.fpc & 3;
1033 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
1034 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
1036 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
1037 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
1041 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
1042 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
1047 static int emu_mdbr (
struct pt_regs *regs,
int rx,
int ry) {
1052 mode =
current->thread.fp_regs.fpc & 3;
1061 static int emu_mdb (
struct pt_regs *regs,
int rx,
double *val) {
1066 mode =
current->thread.fp_regs.fpc & 3;
1075 static int emu_mxdbr (
struct pt_regs *regs,
int rx,
int ry) {
1081 mode =
current->thread.fp_regs.fpc & 3;
1088 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
1089 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
1094 static int emu_mxdb (
struct pt_regs *regs,
int rx,
long double *val) {
1100 mode =
current->thread.fp_regs.fpc & 3;
1101 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
1102 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
1107 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
1108 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
1113 static int emu_meebr (
struct pt_regs *regs,
int rx,
int ry) {
1118 mode =
current->thread.fp_regs.fpc & 3;
1127 static int emu_meeb (
struct pt_regs *regs,
int rx,
float *val) {
1132 mode =
current->thread.fp_regs.fpc & 3;
1141 static int emu_mdebr (
struct pt_regs *regs,
int rx,
int ry) {
1146 mode =
current->thread.fp_regs.fpc & 3;
1157 static int emu_mdeb (
struct pt_regs *regs,
int rx,
float *val) {
1162 mode =
current->thread.fp_regs.fpc & 3;
1173 static int emu_madbr (
struct pt_regs *regs,
int rx,
int ry,
int rz) {
1178 mode =
current->thread.fp_regs.fpc & 3;
1189 static int emu_madb (
struct pt_regs *regs,
int rx,
double *val,
int rz) {
1194 mode =
current->thread.fp_regs.fpc & 3;
1205 static int emu_maebr (
struct pt_regs *regs,
int rx,
int ry,
int rz) {
1210 mode =
current->thread.fp_regs.fpc & 3;
1221 static int emu_maeb (
struct pt_regs *regs,
int rx,
float *val,
int rz) {
1226 mode =
current->thread.fp_regs.fpc & 3;
1237 static int emu_msdbr (
struct pt_regs *regs,
int rx,
int ry,
int rz) {
1242 mode =
current->thread.fp_regs.fpc & 3;
1253 static int emu_msdb (
struct pt_regs *regs,
int rx,
double *val,
int rz) {
1258 mode =
current->thread.fp_regs.fpc & 3;
1269 static int emu_msebr (
struct pt_regs *regs,
int rx,
int ry,
int rz) {
1274 mode =
current->thread.fp_regs.fpc & 3;
1285 static int emu_mseb (
struct pt_regs *regs,
int rx,
float *val,
int rz) {
1290 mode =
current->thread.fp_regs.fpc & 3;
1301 static int emu_sfpc (
struct pt_regs *regs,
int rx,
int ry) {
1312 static int emu_sqxbr (
struct pt_regs *regs,
int rx,
int ry) {
1318 mode =
current->thread.fp_regs.fpc & 3;
1319 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
1320 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
1324 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
1325 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
1326 emu_set_CC_cs(regs, QR_c, QR_s);
1331 static int emu_sqdbr (
struct pt_regs *regs,
int rx,
int ry) {
1336 mode =
current->thread.fp_regs.fpc & 3;
1340 emu_set_CC_cs(regs, DR_c, DR_s);
1345 static int emu_sqdb (
struct pt_regs *regs,
int rx,
double *val) {
1350 mode =
current->thread.fp_regs.fpc & 3;
1354 emu_set_CC_cs(regs, DR_c, DR_s);
1359 static int emu_sqebr (
struct pt_regs *regs,
int rx,
int ry) {
1364 mode =
current->thread.fp_regs.fpc & 3;
1368 emu_set_CC_cs(regs, SR_c, SR_s);
1373 static int emu_sqeb (
struct pt_regs *regs,
int rx,
float *val) {
1378 mode =
current->thread.fp_regs.fpc & 3;
1382 emu_set_CC_cs(regs, SR_c, SR_s);
1387 static int emu_sxbr (
struct pt_regs *regs,
int rx,
int ry) {
1393 mode =
current->thread.fp_regs.fpc & 3;
1394 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
1395 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
1397 cvt.
w.high =
current->thread.fp_regs.fprs[
ry].ui;
1398 cvt.
w.low =
current->thread.fp_regs.fprs[ry+2].ui;
1402 current->thread.fp_regs.fprs[
rx].ui = cvt.
w.high;
1403 current->thread.fp_regs.fprs[rx+2].ui = cvt.
w.low;
1404 emu_set_CC_cs(regs, QR_c, QR_s);
1409 static int emu_sdbr (
struct pt_regs *regs,
int rx,
int ry) {
1414 mode =
current->thread.fp_regs.fpc & 3;
1419 emu_set_CC_cs(regs, DR_c, DR_s);
1424 static int emu_sdb (
struct pt_regs *regs,
int rx,
double *val) {
1429 mode =
current->thread.fp_regs.fpc & 3;
1434 emu_set_CC_cs(regs, DR_c, DR_s);
1439 static int emu_sebr (
struct pt_regs *regs,
int rx,
int ry) {
1444 mode =
current->thread.fp_regs.fpc & 3;
1449 emu_set_CC_cs(regs, SR_c, SR_s);
1454 static int emu_seb (
struct pt_regs *regs,
int rx,
float *val) {
1459 mode =
current->thread.fp_regs.fpc & 3;
1464 emu_set_CC_cs(regs, SR_c, SR_s);
1469 static int emu_tcxb (
struct pt_regs *regs,
int rx,
long val) {
1474 cvt.
w.high =
current->thread.fp_regs.fprs[
rx].ui;
1475 cvt.
w.low =
current->thread.fp_regs.fprs[rx+2].ui;
1498 emu_set_CC(regs, ((
__u32) val >> bit) & 1);
1503 static int emu_tcdb (
struct pt_regs *regs,
int rx,
long val) {
1529 emu_set_CC(regs, ((
__u32) val >> bit) & 1);
1534 static int emu_tceb (
struct pt_regs *regs,
int rx,
long val) {
1560 emu_set_CC(regs, ((
__u32) val >> bit) & 1);
1564 static inline void emu_load_regd(
int reg) {
1572 :
"a" (reg<<4),
"a" (&
current->thread.fp_regs.fprs[reg].d)
1576 static inline void emu_load_rege(
int reg) {
1584 :
"a" (reg<<4),
"a" (&
current->thread.fp_regs.fprs[reg].f)
1588 static inline void emu_store_regd(
int reg) {
1596 :
"a" (reg<<4),
"a" (&
current->thread.fp_regs.fprs[reg].d)
1601 static inline void emu_store_rege(
int reg) {
1609 :
"a" (reg<<4),
"a" (&
current->thread.fp_regs.fprs[reg].f)
1615 static const __u8 format_table[256] = {
1616 [0x00] = 0x03,[0x01] = 0x03,[0x02] = 0x03,[0x03] = 0x03,
1617 [0x04] = 0x0f,[0x05] = 0x0d,[0x06] = 0x0e,[0x07] = 0x0d,
1618 [0x08] = 0x03,[0x09] = 0x03,[0x0a] = 0x03,[0x0b] = 0x03,
1619 [0x0c] = 0x0f,[0x0d] = 0x03,[0x0e] = 0x06,[0x0f] = 0x06,
1620 [0x10] = 0x02,[0x11] = 0x02,[0x12] = 0x02,[0x13] = 0x02,
1621 [0x14] = 0x03,[0x15] = 0x02,[0x16] = 0x01,[0x17] = 0x03,
1622 [0x18] = 0x02,[0x19] = 0x02,[0x1a] = 0x02,[0x1b] = 0x02,
1623 [0x1c] = 0x02,[0x1d] = 0x02,[0x1e] = 0x05,[0x1f] = 0x05,
1624 [0x40] = 0x01,[0x41] = 0x01,[0x42] = 0x01,[0x43] = 0x01,
1625 [0x44] = 0x12,[0x45] = 0x0d,[0x46] = 0x11,[0x47] = 0x04,
1626 [0x48] = 0x01,[0x49] = 0x01,[0x4a] = 0x01,[0x4b] = 0x01,
1627 [0x4c] = 0x01,[0x4d] = 0x01,[0x53] = 0x06,[0x57] = 0x06,
1628 [0x5b] = 0x05,[0x5f] = 0x05,[0x84] = 0x13,[0x8c] = 0x13,
1629 [0x94] = 0x09,[0x95] = 0x08,[0x96] = 0x07,[0x98] = 0x0c,
1630 [0x99] = 0x0b,[0x9a] = 0x0a
1632 static const void *jump_table[256]= {
1633 [0x00] = emu_lpebr,[0x01] = emu_lnebr,[0x02] = emu_ltebr,
1634 [0x03] = emu_lcebr,[0x04] = emu_ldebr,[0x05] = emu_lxdbr,
1635 [0x06] = emu_lxebr,[0x07] = emu_mxdbr,[0x08] = emu_kebr,
1636 [0x09] = emu_cebr, [0x0a] = emu_aebr, [0x0b] = emu_sebr,
1637 [0x0c] = emu_mdebr,[0x0d] = emu_debr, [0x0e] = emu_maebr,
1638 [0x0f] = emu_msebr,[0x10] = emu_lpdbr,[0x11] = emu_lndbr,
1639 [0x12] = emu_ltdbr,[0x13] = emu_lcdbr,[0x14] = emu_sqebr,
1640 [0x15] = emu_sqdbr,[0x16] = emu_sqxbr,[0x17] = emu_meebr,
1641 [0x18] = emu_kdbr, [0x19] = emu_cdbr, [0x1a] = emu_adbr,
1642 [0x1b] = emu_sdbr, [0x1c] = emu_mdbr, [0x1d] = emu_ddbr,
1643 [0x1e] = emu_madbr,[0x1f] = emu_msdbr,[0x40] = emu_lpxbr,
1644 [0x41] = emu_lnxbr,[0x42] = emu_ltxbr,[0x43] = emu_lcxbr,
1645 [0x44] = emu_ledbr,[0x45] = emu_ldxbr,[0x46] = emu_lexbr,
1646 [0x47] = emu_fixbr,[0x48] = emu_kxbr, [0x49] = emu_cxbr,
1647 [0x4a] = emu_axbr, [0x4b] = emu_sxbr, [0x4c] = emu_mxbr,
1648 [0x4d] = emu_dxbr, [0x53] = emu_diebr,[0x57] = emu_fiebr,
1649 [0x5b] = emu_didbr,[0x5f] = emu_fidbr,[0x84] = emu_sfpc,
1650 [0x8c] = emu_efpc, [0x94] = emu_cefbr,[0x95] = emu_cdfbr,
1651 [0x96] = emu_cxfbr,[0x98] = emu_cfebr,[0x99] = emu_cfdbr,
1655 switch (format_table[opcode[1]]) {
1657 if (opcode[3] & 0x22)
1659 emu_store_regd((opcode[3] >> 4) & 15);
1660 emu_store_regd(((opcode[3] >> 4) & 15) + 2);
1661 emu_store_regd(opcode[3] & 15);
1662 emu_store_regd((opcode[3] & 15) + 2);
1665 jump_table[opcode[1]])
1666 (regs, opcode[3] >> 4, opcode[3] & 15);
1667 emu_load_regd((opcode[3] >> 4) & 15);
1668 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
1669 emu_load_regd(opcode[3] & 15);
1670 emu_load_regd((opcode[3] & 15) + 2);
1673 emu_store_regd((opcode[3] >> 4) & 15);
1674 emu_store_regd(opcode[3] & 15);
1677 jump_table[opcode[1]])
1678 (regs, opcode[3] >> 4, opcode[3] & 15);
1679 emu_load_regd((opcode[3] >> 4) & 15);
1680 emu_load_regd(opcode[3] & 15);
1683 emu_store_rege((opcode[3] >> 4) & 15);
1684 emu_store_rege(opcode[3] & 15);
1687 jump_table[opcode[1]])
1688 (regs, opcode[3] >> 4, opcode[3] & 15);
1689 emu_load_rege((opcode[3] >> 4) & 15);
1690 emu_load_rege(opcode[3] & 15);
1693 if (opcode[3] & 0x22)
1695 emu_store_regd((opcode[3] >> 4) & 15);
1696 emu_store_regd(((opcode[3] >> 4) & 15) + 2);
1697 emu_store_regd(opcode[3] & 15);
1698 emu_store_regd((opcode[3] & 15) + 2);
1701 jump_table[opcode[1]])
1702 (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1703 emu_load_regd((opcode[3] >> 4) & 15);
1704 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
1705 emu_load_regd(opcode[3] & 15);
1706 emu_load_regd((opcode[3] & 15) + 2);
1709 emu_store_regd((opcode[2] >> 4) & 15);
1710 emu_store_regd((opcode[3] >> 4) & 15);
1711 emu_store_regd(opcode[3] & 15);
1714 jump_table[opcode[1]])
1715 (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1716 emu_load_regd((opcode[2] >> 4) & 15);
1717 emu_load_regd((opcode[3] >> 4) & 15);
1718 emu_load_regd(opcode[3] & 15);
1721 emu_store_rege((opcode[2] >> 4) & 15);
1722 emu_store_rege((opcode[3] >> 4) & 15);
1723 emu_store_rege(opcode[3] & 15);
1726 jump_table[opcode[1]])
1727 (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1728 emu_load_rege((opcode[2] >> 4) & 15);
1729 emu_load_rege((opcode[3] >> 4) & 15);
1730 emu_load_rege(opcode[3] & 15);
1734 if (opcode[3] & 0x20)
1737 jump_table[opcode[1]])
1738 (regs, opcode[3] >> 4, opcode[3] & 15);
1739 emu_load_regd((opcode[3] >> 4) & 15);
1740 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
1745 jump_table[opcode[1]])
1746 (regs, opcode[3] >> 4, opcode[3] & 15);
1747 emu_load_regd((opcode[3] >> 4) & 15);
1752 jump_table[opcode[1]])
1753 (regs, opcode[3] >> 4, opcode[3] & 15);
1754 emu_load_rege((opcode[3] >> 4) & 15);
1757 if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
1762 emu_store_regd(opcode[3] & 15);
1763 emu_store_regd((opcode[3] & 15) + 2);
1766 jump_table[opcode[1]])
1767 (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1770 if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
1773 emu_store_regd(opcode[3] & 15);
1776 jump_table[opcode[1]])
1777 (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1780 if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
1783 emu_store_rege(opcode[3] & 15);
1786 jump_table[opcode[1]])
1787 (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1791 if (opcode[3] & 0x20)
1793 emu_store_regd((opcode[3] >> 4) & 15);
1794 emu_store_regd(opcode[3] & 15);
1797 jump_table[opcode[1]])
1798 (regs, opcode[3] >> 4, opcode[3] & 15);
1799 emu_load_regd((opcode[3] >> 4) & 15);
1800 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
1804 if (opcode[3] & 0x20)
1806 emu_store_rege((opcode[3] >> 4) & 15);
1807 emu_store_rege(opcode[3] & 15);
1810 jump_table[opcode[1]])
1811 (regs, opcode[3] >> 4, opcode[3] & 15);
1812 emu_load_regd((opcode[3] >> 4) & 15);
1813 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
1817 emu_store_rege((opcode[3] >> 4) & 15);
1818 emu_store_rege(opcode[3] & 15);
1821 jump_table[opcode[1]])
1822 (regs, opcode[3] >> 4, opcode[3] & 15);
1823 emu_load_regd((opcode[3] >> 4) & 15);
1829 emu_store_regd(opcode[3] & 15);
1830 emu_store_regd((opcode[3] & 15) + 2);
1833 jump_table[opcode[1]])
1834 (regs, opcode[3] >> 4, opcode[3] & 15);
1835 emu_load_regd((opcode[3] >> 4) & 15);
1841 emu_store_regd(opcode[3] & 15);
1842 emu_store_regd((opcode[3] & 15) + 2);
1845 jump_table[opcode[1]])
1846 (regs, opcode[3] >> 4, opcode[3] & 15);
1847 emu_load_rege((opcode[3] >> 4) & 15);
1851 emu_store_regd(opcode[3] & 15);
1854 jump_table[opcode[1]])
1855 (regs, opcode[3] >> 4, opcode[3] & 15);
1856 emu_load_rege((opcode[3] >> 4) & 15);
1861 jump_table[opcode[1]])
1862 (regs, opcode[3] >> 4, opcode[3] & 15);
1868 current->thread.fp_regs.fpc |= _fex;
1869 if (
current->thread.fp_regs.fpc & (_fex << 8))
1875 static void* calc_addr(
struct pt_regs *regs,
int rx,
int rb,
int disp)
1881 addr = disp & 0xfff;
1882 addr += (rx != 0) ? regs->
gprs[rx] : 0;
1883 addr += (rb != 0) ? regs->
gprs[
rb] : 0;
1884 return (
void*)
addr;
1890 static const __u8 format_table[256] = {
1891 [0x04] = 0x06,[0x05] = 0x05,[0x06] = 0x07,[0x07] = 0x05,
1892 [0x08] = 0x02,[0x09] = 0x02,[0x0a] = 0x02,[0x0b] = 0x02,
1893 [0x0c] = 0x06,[0x0d] = 0x02,[0x0e] = 0x04,[0x0f] = 0x04,
1894 [0x10] = 0x08,[0x11] = 0x09,[0x12] = 0x0a,[0x14] = 0x02,
1895 [0x15] = 0x01,[0x17] = 0x02,[0x18] = 0x01,[0x19] = 0x01,
1896 [0x1a] = 0x01,[0x1b] = 0x01,[0x1c] = 0x01,[0x1d] = 0x01,
1897 [0x1e] = 0x03,[0x1f] = 0x03,
1899 static const void *jump_table[]= {
1900 [0x04] = emu_ldeb,[0x05] = emu_lxdb,[0x06] = emu_lxeb,
1901 [0x07] = emu_mxdb,[0x08] = emu_keb, [0x09] = emu_ceb,
1902 [0x0a] = emu_aeb, [0x0b] = emu_seb, [0x0c] = emu_mdeb,
1903 [0x0d] = emu_deb, [0x0e] = emu_maeb,[0x0f] = emu_mseb,
1904 [0x10] = emu_tceb,[0x11] = emu_tcdb,[0x12] = emu_tcxb,
1905 [0x14] = emu_sqeb,[0x15] = emu_sqdb,[0x17] = emu_meeb,
1906 [0x18] = emu_kdb, [0x19] = emu_cdb, [0x1a] = emu_adb,
1907 [0x1b] = emu_sdb, [0x1c] = emu_mdb, [0x1d] = emu_ddb,
1908 [0x1e] = emu_madb,[0x1f] = emu_msdb
1911 switch (format_table[opcode[5]]) {
1916 emu_store_regd((opcode[1] >> 4) & 15);
1917 opc = *((
__u32 *) opcode);
1918 dxb = (
__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1922 jump_table[opcode[5]])
1923 (regs, opcode[1] >> 4, (
double *) &
temp);
1924 emu_load_regd((opcode[1] >> 4) & 15);
1931 emu_store_rege((opcode[1] >> 4) & 15);
1932 opc = *((
__u32 *) opcode);
1933 dxb = (
__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1937 jump_table[opcode[5]])
1938 (regs, opcode[1] >> 4, (
float *) &
temp);
1939 emu_load_rege((opcode[1] >> 4) & 15);
1946 emu_store_regd((opcode[1] >> 4) & 15);
1947 emu_store_regd((opcode[4] >> 4) & 15);
1948 opc = *((
__u32 *) opcode);
1949 dxb = (
__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1953 jump_table[opcode[5]])
1954 (regs, opcode[1] >> 4, (
double *) &
temp, opcode[4] >> 4);
1955 emu_load_regd((opcode[1] >> 4) & 15);
1962 emu_store_rege((opcode[1] >> 4) & 15);
1963 emu_store_rege((opcode[4] >> 4) & 15);
1964 opc = *((
__u32 *) opcode);
1965 dxb = (
__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1969 jump_table[opcode[5]])
1970 (regs, opcode[1] >> 4, (
float *) &
temp, opcode[4] >> 4);
1971 emu_load_rege((opcode[4] >> 4) & 15);
1979 if ((opcode[1] >> 4) & 0x20)
1981 emu_store_regd((opcode[1] >> 4) & 15);
1982 opc = *((
__u32 *) opcode);
1983 dxb = (
__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1987 jump_table[opcode[5]])
1988 (regs, opcode[1] >> 4, (
double *) &
temp);
1989 emu_load_regd((opcode[1] >> 4) & 15);
1990 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
1998 emu_store_rege((opcode[1] >> 4) & 15);
1999 opc = *((
__u32 *) opcode);
2000 dxb = (
__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2004 jump_table[opcode[5]])
2005 (regs, opcode[1] >> 4, (
float *) &
temp);
2006 emu_load_regd((opcode[1] >> 4) & 15);
2014 if ((opcode[1] >> 4) & 0x20)
2016 emu_store_rege((opcode[1] >> 4) & 15);
2017 opc = *((
__u32 *) opcode);
2018 dxb = (
__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2022 jump_table[opcode[5]])
2023 (regs, opcode[1] >> 4, (
float *) &
temp);
2024 emu_load_regd((opcode[1] >> 4) & 15);
2025 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
2032 emu_store_rege((opcode[1] >> 4) & 15);
2033 opc = *((
__u32 *) opcode);
2034 dxb = (
__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
2037 jump_table[opcode[5]])
2038 (regs, opcode[1] >> 4, dxb);
2045 emu_store_regd((opcode[1] >> 4) & 15);
2046 opc = *((
__u32 *) opcode);
2047 dxb = (
__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
2050 jump_table[opcode[5]])
2051 (regs, opcode[1] >> 4, dxb);
2058 if ((opcode[1] >> 4) & 2)
2060 emu_store_regd((opcode[1] >> 4) & 15);
2061 emu_store_regd(((opcode[1] >> 4) & 15) + 2);
2062 opc = *((
__u32 *) opcode);
2063 dxb = (
__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
2066 jump_table[opcode[5]])
2067 (regs, opcode[1] >> 4, dxb);
2074 current->thread.fp_regs.fpc |= _fex;
2075 if (
current->thread.fp_regs.fpc & (_fex << 8))
2088 if ((opc & 0x90) == 0) {
2095 :
"a" (opc & 0xf0),
"a" (&fp_regs->
fprs[opc & 0xf].
d)
2097 }
else if ((opc & 0x9) == 0) {
2103 :
"a" ((opc & 0xf) << 4),
2104 "a" (&fp_regs->
fprs[(opc & 0xf0)>>4].
d)
2107 fp_regs->
fprs[(opc & 0xf0) >> 4] = fp_regs->
fprs[opc & 0xf];
2118 if ((opc & 0x90) == 0) {
2125 :
"a" (opc & 0xf0),
"a" (&fp_regs->
fprs[opc & 0xf].
f)
2127 }
else if ((opc & 0x9) == 0) {
2133 :
"a" ((opc & 0xf) << 4),
2134 "a" (&fp_regs->
fprs[(opc & 0xf0) >> 4].
f)
2137 fp_regs->
fprs[(opc & 0xf0) >> 4] = fp_regs->
fprs[opc & 0xf];
2149 dxb = (
__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2162 dxb = (
__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2163 mem = (
__u32 *) (&fp_regs->
fprs[(opc >> 20) & 0xf].
f);
2176 dxb = (
__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2189 dxb = (
__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2190 mem = (
__u32 *) (&fp_regs->
fprs[(opc >> 20) & 0xf].
f);
2202 dxb= (
__u32 *) calc_addr(regs, 0, opc>>12, opc);
2217 dxb= (
__u32 *) calc_addr(regs, 0, opc>>12, opc);
2229 temp = calc_addr(regs, 0, opc>>12, opc);
2230 current->thread.fp_regs.fpc &= ~3;
2231 current->thread.fp_regs.fpc |= (temp & 3);
2250 w.s[0] = -uu.s[0] - ((
int) w.s[1] != 0);