math.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:74k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/s390/math-emu/math.c
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  7.  *
  8.  * 'math.c' emulates IEEE instructions on a S390 processor
  9.  *          that does not have the IEEE fpu (all processors before G5).
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/types.h>
  13. #include <linux/sched.h>
  14. #include <linux/mm.h>
  15. #include <asm/uaccess.h>
  16. #include "sfp-util.h"
  17. #include <math-emu/soft-fp.h>
  18. #include <math-emu/single.h>
  19. #include <math-emu/double.h>
  20. #include <math-emu/quad.h>
  21. /*
  22.  * I miss a macro to round a floating point number to the
  23.  * nearest integer in the same floating point format.
  24.  */
  25. #define _FP_TO_FPINT_ROUND(fs, wc, X)
  26.   do {
  27.     switch (X##_c)
  28.       {
  29.       case FP_CLS_NORMAL:
  30.         if (X##_e > _FP_FRACBITS_##fs + _FP_EXPBIAS_##fs)
  31.           { /* floating point number has no bits after the dot. */
  32.           }
  33.         else if (X##_e <= _FP_FRACBITS_##fs + _FP_EXPBIAS_##fs &&
  34.                  X##_e > _FP_EXPBIAS_##fs)
  35.   { /* some bits before the dot, some after it. */
  36.             _FP_FRAC_SRS_##wc(X, _FP_WFRACBITS_##fs,
  37.                               X##_e - _FP_EXPBIAS_##fs
  38.                               + _FP_FRACBITS_##fs);
  39.     _FP_ROUND(wc, X);
  40.     _FP_FRAC_SLL_##wc(X, X##_e - _FP_EXPBIAS_##fs
  41.                               + _FP_FRACBITS_##fs);
  42.           }
  43.         else
  44.           { /* all bits after the dot. */
  45.     FP_SET_EXCEPTION(FP_EX_INEXACT);
  46.             X##_c = FP_CLS_ZERO;
  47.   }
  48.         break;
  49.       case FP_CLS_NAN:
  50.       case FP_CLS_INF:
  51.       case FP_CLS_ZERO:
  52.         break;
  53.       }
  54.   } while (0)
  55. #define FP_TO_FPINT_ROUND_S(X) _FP_TO_FPINT_ROUND(S,1,X)
  56. #define FP_TO_FPINT_ROUND_D(X) _FP_TO_FPINT_ROUND(D,2,X)
  57. #define FP_TO_FPINT_ROUND_Q(X) _FP_TO_FPINT_ROUND(Q,4,X)
  58. typedef union {
  59.         long double ld;
  60.         struct {
  61.                 __u64 high;
  62.                 __u64 low;
  63.         } w;
  64. } mathemu_ldcv;
  65. #ifdef CONFIG_SYSCTL
  66. int sysctl_ieee_emulation_warnings=1;
  67. #endif
  68. #define mathemu_put_user(x, p) 
  69.         do { 
  70.                 if (put_user((x),(p))) 
  71.                         return SIGSEGV; 
  72.         } while (0)
  73. #define mathemu_get_user(x, p) 
  74.         do { 
  75.                 if (get_user((x),(p))) 
  76.                         return SIGSEGV; 
  77.         } while (0)
  78. #define mathemu_copy_from_user(d, s, n)
  79.         do { 
  80.                 if (copy_from_user((d),(s),(n)) == -EFAULT) 
  81.                         return SIGSEGV; 
  82.         } while (0)
  83. #define mathemu_copy_to_user(d, s, n) 
  84.         do { 
  85.                 if (copy_to_user((d),(s),(n)) == -EFAULT) 
  86.                         return SIGSEGV; 
  87.         } while (0)
  88. static void display_emulation_not_implemented(struct pt_regs *regs, char *instr)
  89. {
  90.         struct pt_regs *regs;
  91.         __u16 *location;
  92.         
  93. #if CONFIG_SYSCTL
  94.         if(sysctl_ieee_emulation_warnings)
  95. #endif
  96.         {
  97.                 location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
  98.                 printk("%s ieee fpu instruction not emulated "
  99.                        "process name: %s pid: %d n",
  100.                        instr, current->comm, current->pid);
  101.                 printk("%s's PSW:    %08lx %08lxn", instr,
  102.                        (unsigned long) regs->psw.mask,
  103.                        (unsigned long) location);
  104.         }
  105. }
  106. static inline void emu_set_CC (struct pt_regs *regs, int cc)
  107. {
  108.         regs->psw.mask = (regs->psw.mask & 0xFFFFCFFF) | ((cc&3) << 12);
  109. }
  110. /*
  111.  * Set the condition code in the user psw.
  112.  *  0 : Result is zero
  113.  *  1 : Result is less than zero
  114.  *  2 : Result is greater than zero
  115.  *  3 : Result is NaN or INF
  116.  */
  117. static inline void emu_set_CC_cs(struct pt_regs *regs, int class, int sign)
  118. {
  119.         switch (class) {
  120.         case FP_CLS_NORMAL:
  121.         case FP_CLS_INF:
  122.                 emu_set_CC(regs, sign ? 1 : 2);
  123.                 break;
  124.         case FP_CLS_ZERO:
  125.                 emu_set_CC(regs, 0);
  126.                 break;
  127.         case FP_CLS_NAN:
  128.                 emu_set_CC(regs, 3);
  129.                 break;
  130.         }
  131. }
  132. /* Add long double */
  133. static int emu_axbr (struct pt_regs *regs, int rx, int ry) {
  134.         FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
  135.         FP_DECL_EX;
  136. mathemu_ldcv cvt;
  137.         int mode;
  138. mode = current->thread.fp_regs.fpc & 3;
  139.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  140.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  141.         FP_UNPACK_QP(QA, &cvt.ld);
  142.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  143.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  144.         FP_UNPACK_QP(QB, &cvt.ld);
  145.         FP_ADD_Q(QR, QA, QB);
  146.         FP_PACK_QP(&cvt.ld, QR);
  147.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  148.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  149.         emu_set_CC_cs(regs, QR_c, QR_s);
  150.         return _fex;
  151. }
  152. /* Add double */
  153. static int emu_adbr (struct pt_regs *regs, int rx, int ry) {
  154.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  155.         FP_DECL_EX;
  156.         int mode;
  157. mode = current->thread.fp_regs.fpc & 3;
  158.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  159.         FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  160.         FP_ADD_D(DR, DA, DB);
  161. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  162.         emu_set_CC_cs(regs, DR_c, DR_s);
  163.         return _fex;
  164. }
  165. /* Add double */
  166. static int emu_adb (struct pt_regs *regs, int rx, double *val) {
  167.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  168.         FP_DECL_EX;
  169.         int mode;
  170. mode = current->thread.fp_regs.fpc & 3;
  171.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  172.         FP_UNPACK_DP(DB, val);
  173.         FP_ADD_D(DR, DA, DB);
  174. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  175.         emu_set_CC_cs(regs, DR_c, DR_s);
  176.         return _fex;
  177. }
  178. /* Add float */
  179. static int emu_aebr (struct pt_regs *regs, int rx, int ry) {
  180.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  181.         FP_DECL_EX;
  182.         int mode;
  183. mode = current->thread.fp_regs.fpc & 3;
  184.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  185.         FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  186.         FP_ADD_S(SR, SA, SB);
  187. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  188.         emu_set_CC_cs(regs, SR_c, SR_s);
  189.         return _fex;
  190. }
  191. /* Add float */
  192. static int emu_aeb (struct pt_regs *regs, int rx, float *val) {
  193.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  194.         FP_DECL_EX;
  195.         int mode;
  196. mode = current->thread.fp_regs.fpc & 3;
  197.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  198.         FP_UNPACK_SP(SB, val);
  199.         FP_ADD_S(SR, SA, SB);
  200. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  201.         emu_set_CC_cs(regs, SR_c, SR_s);
  202.         return _fex;
  203. }
  204. /* Compare long double */
  205. static int emu_cxbr (struct pt_regs *regs, int rx, int ry) {
  206.         FP_DECL_Q(QA); FP_DECL_Q(QB);
  207. mathemu_ldcv cvt;
  208.         int IR;
  209.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  210.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  211.         FP_UNPACK_RAW_QP(QA, &cvt.ld);
  212.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  213.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  214.         FP_UNPACK_RAW_QP(QB, &cvt.ld);
  215.         FP_CMP_Q(IR, QA, QB, 3);
  216.         /*
  217.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  218.          * IR == 1 if DA > DB and IR == 3 if unorderded
  219.          */
  220.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  221.         return 0;
  222. }
  223. /* Compare double */
  224. static int emu_cdbr (struct pt_regs *regs, int rx, int ry) {
  225.         FP_DECL_D(DA); FP_DECL_D(DB);
  226.         int IR;
  227.         FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  228.         FP_UNPACK_RAW_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  229.         FP_CMP_D(IR, DA, DB, 3);
  230.         /*
  231.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  232.          * IR == 1 if DA > DB and IR == 3 if unorderded
  233.          */
  234.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  235.         return 0;
  236. }
  237. /* Compare double */
  238. static int emu_cdb (struct pt_regs *regs, int rx, double *val) {
  239.         FP_DECL_D(DA); FP_DECL_D(DB);
  240.         int IR;
  241.         FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  242.         FP_UNPACK_RAW_DP(DB, val);
  243.         FP_CMP_D(IR, DA, DB, 3);
  244.         /*
  245.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  246.          * IR == 1 if DA > DB and IR == 3 if unorderded
  247.          */
  248.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  249.         return 0;
  250. }
  251. /* Compare float */
  252. static int emu_cebr (struct pt_regs *regs, int rx, int ry) {
  253.         FP_DECL_S(SA); FP_DECL_S(SB);
  254.         int IR;
  255.         FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  256.         FP_UNPACK_RAW_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  257.         FP_CMP_S(IR, SA, SB, 3);
  258.         /*
  259.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  260.          * IR == 1 if DA > DB and IR == 3 if unorderded
  261.          */
  262.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  263.         return 0;
  264. }
  265. /* Compare float */
  266. static int emu_ceb (struct pt_regs *regs, int rx, float *val) {
  267.         FP_DECL_S(SA); FP_DECL_S(SB);
  268.         int IR;
  269.         FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  270.         FP_UNPACK_RAW_SP(SB, val);
  271.         FP_CMP_S(IR, SA, SB, 3);
  272.         /*
  273.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  274.          * IR == 1 if DA > DB and IR == 3 if unorderded
  275.          */
  276.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  277.         return 0;
  278. }
  279. /* Compare and signal long double */
  280. static int emu_kxbr (struct pt_regs *regs, int rx, int ry) {
  281.         FP_DECL_Q(QA); FP_DECL_Q(QB);
  282.         FP_DECL_EX;
  283. mathemu_ldcv cvt;
  284.         int IR;
  285.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  286.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  287.         FP_UNPACK_RAW_QP(QA, &cvt.ld);
  288.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  289.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  290.         FP_UNPACK_QP(QB, &cvt.ld);
  291.         FP_CMP_Q(IR, QA, QB, 3);
  292.         /*
  293.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  294.          * IR == 1 if DA > DB and IR == 3 if unorderded
  295.          */
  296.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  297.         if (IR == 3)
  298.                 FP_SET_EXCEPTION (FP_EX_INVALID);
  299.         return _fex;
  300. }
  301. /* Compare and signal double */
  302. static int emu_kdbr (struct pt_regs *regs, int rx, int ry) {
  303.         FP_DECL_D(DA); FP_DECL_D(DB);
  304.         FP_DECL_EX;
  305.         int IR;
  306.         FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  307.         FP_UNPACK_RAW_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  308.         FP_CMP_D(IR, DA, DB, 3);
  309.         /*
  310.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  311.          * IR == 1 if DA > DB and IR == 3 if unorderded
  312.          */
  313.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  314.         if (IR == 3)
  315.                 FP_SET_EXCEPTION (FP_EX_INVALID);
  316.         return _fex;
  317. }
  318. /* Compare and signal double */
  319. static int emu_kdb (struct pt_regs *regs, int rx, double *val) {
  320.         FP_DECL_D(DA); FP_DECL_D(DB);
  321.         FP_DECL_EX;
  322.         int IR;
  323.         FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  324.         FP_UNPACK_RAW_DP(DB, val);
  325.         FP_CMP_D(IR, DA, DB, 3);
  326.         /*
  327.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  328.          * IR == 1 if DA > DB and IR == 3 if unorderded
  329.          */
  330.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  331.         if (IR == 3)
  332.                 FP_SET_EXCEPTION (FP_EX_INVALID);
  333.         return _fex;
  334. }
  335. /* Compare and signal float */
  336. static int emu_kebr (struct pt_regs *regs, int rx, int ry) {
  337.         FP_DECL_S(SA); FP_DECL_S(SB);
  338.         FP_DECL_EX;
  339.         int IR;
  340.         FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  341.         FP_UNPACK_RAW_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  342.         FP_CMP_S(IR, SA, SB, 3);
  343.         /*
  344.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  345.          * IR == 1 if DA > DB and IR == 3 if unorderded
  346.          */
  347.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  348.         if (IR == 3)
  349.                 FP_SET_EXCEPTION (FP_EX_INVALID);
  350.         return _fex;
  351. }
  352. /* Compare and signal float */
  353. static int emu_keb (struct pt_regs *regs, int rx, float *val) {
  354.         FP_DECL_S(SA); FP_DECL_S(SB);
  355.         FP_DECL_EX;
  356.         int IR;
  357.         FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  358.         FP_UNPACK_RAW_SP(SB, val);
  359.         FP_CMP_S(IR, SA, SB, 3);
  360.         /*
  361.          * IR == -1 if DA < DB, IR == 0 if DA == DB,
  362.          * IR == 1 if DA > DB and IR == 3 if unorderded
  363.          */
  364.         emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
  365.         if (IR == 3)
  366.                 FP_SET_EXCEPTION (FP_EX_INVALID);
  367.         return _fex;
  368. }
  369. /* Convert from fixed long double */
  370. static int emu_cxfbr (struct pt_regs *regs, int rx, int ry) {
  371.         FP_DECL_Q(QR);
  372.         FP_DECL_EX;
  373. mathemu_ldcv cvt;
  374.         __s32 si;
  375.         int mode;
  376. mode = current->thread.fp_regs.fpc & 3;
  377.         si = regs->gprs[ry];
  378.         FP_FROM_INT_Q(QR, si, 32, int);
  379.         FP_PACK_QP(&cvt.ld, QR);
  380.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  381.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  382.         return _fex;
  383. }
  384. /* Convert from fixed double */
  385. static int emu_cdfbr (struct pt_regs *regs, int rx, int ry) {
  386.         FP_DECL_D(DR);
  387.         FP_DECL_EX;
  388.         __s32 si;
  389.         int mode;
  390. mode = current->thread.fp_regs.fpc & 3;
  391.         si = regs->gprs[ry];
  392.         FP_FROM_INT_D(DR, si, 32, int);
  393.         FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  394.         return _fex;
  395. }
  396. /* Convert from fixed float */
  397. static int emu_cefbr (struct pt_regs *regs, int rx, int ry) {
  398.         FP_DECL_S(SR);
  399.         FP_DECL_EX;
  400.         __s32 si;
  401.         int mode;
  402. mode = current->thread.fp_regs.fpc & 3;
  403.         si = regs->gprs[ry];
  404.         FP_FROM_INT_S(SR, si, 32, int);
  405.         FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  406.         return _fex;
  407. }
  408. /* Convert to fixed long double */
  409. static int emu_cfxbr (struct pt_regs *regs, int rx, int ry, int mask) {
  410.         FP_DECL_Q(QA);
  411.         FP_DECL_EX;
  412. mathemu_ldcv cvt;
  413.         __s32 si;
  414.         int mode;
  415. if (mask == 0)
  416. mode = current->thread.fp_regs.fpc & 3;
  417. else if (mask == 1)
  418. mode = FP_RND_NEAREST;
  419. else
  420. mode = mask - 4;
  421.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  422.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  423.         FP_UNPACK_QP(QA, &cvt.ld);
  424.         FP_TO_INT_ROUND_Q(si, QA, 32, 1);
  425.         regs->gprs[rx] = si;
  426.         emu_set_CC_cs(regs, QA_c, QA_s);
  427.         return _fex;
  428. }
  429. /* Convert to fixed double */
  430. static int emu_cfdbr (struct pt_regs *regs, int rx, int ry, int mask) {
  431.         FP_DECL_D(DA);
  432.         FP_DECL_EX;
  433.         __s32 si;
  434.         int mode;
  435. if (mask == 0)
  436. mode = current->thread.fp_regs.fpc & 3;
  437. else if (mask == 1)
  438. mode = FP_RND_NEAREST;
  439. else
  440. mode = mask - 4;
  441.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  442.         FP_TO_INT_ROUND_D(si, DA, 32, 1);
  443.         regs->gprs[rx] = si;
  444.         emu_set_CC_cs(regs, DA_c, DA_s);
  445.         return _fex;
  446. }
  447. /* Convert to fixed float */
  448. static int emu_cfebr (struct pt_regs *regs, int rx, int ry, int mask) {
  449.         FP_DECL_S(SA);
  450.         FP_DECL_EX;
  451.         __s32 si;
  452.         int mode;
  453. if (mask == 0)
  454. mode = current->thread.fp_regs.fpc & 3;
  455. else if (mask == 1)
  456. mode = FP_RND_NEAREST;
  457. else
  458. mode = mask - 4;
  459.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  460.         FP_TO_INT_ROUND_S(si, SA, 32, 1);
  461.         regs->gprs[rx] = si;
  462.         emu_set_CC_cs(regs, SA_c, SA_s);
  463.         return _fex;
  464. }
  465. /* Divide long double */
  466. static int emu_dxbr (struct pt_regs *regs, int rx, int ry) {
  467.         FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
  468.         FP_DECL_EX;
  469. mathemu_ldcv cvt;
  470.         int mode;
  471. mode = current->thread.fp_regs.fpc & 3;
  472.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  473.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  474.         FP_UNPACK_QP(QA, &cvt.ld);
  475.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  476.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  477.         FP_UNPACK_QP(QB, &cvt.ld);
  478.         FP_DIV_Q(QR, QA, QB);
  479.         FP_PACK_QP(&cvt.ld, QR);
  480.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  481.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  482.         return _fex;
  483. }
  484. /* Divide double */
  485. static int emu_ddbr (struct pt_regs *regs, int rx, int ry) {
  486.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  487.         FP_DECL_EX;
  488.         int mode;
  489. mode = current->thread.fp_regs.fpc & 3;
  490.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  491.         FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  492.         FP_DIV_D(DR, DA, DB);
  493. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  494.         return _fex;
  495. }
  496. /* Divide double */
  497. static int emu_ddb (struct pt_regs *regs, int rx, double *val) {
  498.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  499.         FP_DECL_EX;
  500.         int mode;
  501. mode = current->thread.fp_regs.fpc & 3;
  502.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  503.         FP_UNPACK_DP(DB, val);
  504.         FP_DIV_D(DR, DA, DB);
  505. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  506.         return _fex;
  507. }
  508. /* Divide float */
  509. static int emu_debr (struct pt_regs *regs, int rx, int ry) {
  510.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  511.         FP_DECL_EX;
  512.         int mode;
  513. mode = current->thread.fp_regs.fpc & 3;
  514.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  515.         FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  516.         FP_DIV_S(SR, SA, SB);
  517. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  518.         return _fex;
  519. }
  520. /* Divide float */
  521. static int emu_deb (struct pt_regs *regs, int rx, float *val) {
  522.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  523.         FP_DECL_EX;
  524.         int mode;
  525. mode = current->thread.fp_regs.fpc & 3;
  526.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  527.         FP_UNPACK_SP(SB, val);
  528.         FP_DIV_S(SR, SA, SB);
  529. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  530.         return _fex;
  531. }
  532. /* Divide to integer double */
  533. static int emu_didbr (struct pt_regs *regs, int rx, int ry, int mask) {
  534.         display_emulation_not_implemented(regs, "didbr");
  535.         return 0;
  536. }
  537. /* Divide to integer float */
  538. static int emu_diebr (struct pt_regs *regs, int rx, int ry, int mask) {
  539.         display_emulation_not_implemented(regs, "diebr");
  540.         return 0;
  541. }
  542. /* Extract fpc */
  543. static int emu_efpc (struct pt_regs *regs, int rx, int ry) {
  544.         regs->gprs[rx] = current->thread.fp_regs.fpc;
  545.         return 0;
  546. }
  547. /* Load and test long double */
  548. static int emu_ltxbr (struct pt_regs *regs, int rx, int ry) {
  549.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  550. mathemu_ldcv cvt;
  551.         FP_DECL_Q(QA);
  552.         FP_DECL_EX;
  553.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  554.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  555.         FP_UNPACK_QP(QA, &cvt.ld);
  556.         fp_regs->fprs[rx].ui = fp_regs->fprs[ry].ui;
  557.         fp_regs->fprs[rx+2].ui = fp_regs->fprs[ry+2].ui;
  558.         emu_set_CC_cs(regs, QA_c, QA_s);
  559.         return _fex;
  560. }
  561. /* Load and test double */
  562. static int emu_ltdbr (struct pt_regs *regs, int rx, int ry) {
  563.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  564.         FP_DECL_D(DA);
  565.         FP_DECL_EX;
  566.         FP_UNPACK_DP(DA, &fp_regs->fprs[ry].d);
  567.         fp_regs->fprs[rx].ui = fp_regs->fprs[ry].ui;
  568.         emu_set_CC_cs(regs, DA_c, DA_s);
  569.         return _fex;
  570. }
  571. /* Load and test double */
  572. static int emu_ltebr (struct pt_regs *regs, int rx, int ry) {
  573.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  574.         FP_DECL_S(SA);
  575.         FP_DECL_EX;
  576.         FP_UNPACK_SP(SA, &fp_regs->fprs[ry].f);
  577.         fp_regs->fprs[rx].ui = fp_regs->fprs[ry].ui;
  578.         emu_set_CC_cs(regs, SA_c, SA_s);
  579.         return _fex;
  580. }
  581. /* Load complement long double */
  582. static int emu_lcxbr (struct pt_regs *regs, int rx, int ry) {
  583.         FP_DECL_Q(QA); FP_DECL_Q(QR);
  584.         FP_DECL_EX;
  585. mathemu_ldcv cvt;
  586.         int mode;
  587. mode = current->thread.fp_regs.fpc & 3;
  588.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  589.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  590.         FP_UNPACK_QP(QA, &cvt.ld);
  591. FP_NEG_Q(QR, QA);
  592.         FP_PACK_QP(&cvt.ld, QR);
  593.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  594.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  595.         emu_set_CC_cs(regs, QR_c, QR_s);
  596.         return _fex;
  597. }
  598. /* Load complement double */
  599. static int emu_lcdbr (struct pt_regs *regs, int rx, int ry) {
  600.         FP_DECL_D(DA); FP_DECL_D(DR);
  601.         FP_DECL_EX;
  602.         int mode;
  603. mode = current->thread.fp_regs.fpc & 3;
  604.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  605. FP_NEG_D(DR, DA);
  606. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  607.         emu_set_CC_cs(regs, DR_c, DR_s);
  608.         return _fex;
  609. }
  610. /* Load complement float */
  611. static int emu_lcebr (struct pt_regs *regs, int rx, int ry) {
  612.         FP_DECL_S(SA); FP_DECL_S(SR);
  613.         FP_DECL_EX;
  614.         int mode;
  615. mode = current->thread.fp_regs.fpc & 3;
  616.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  617. FP_NEG_S(SR, SA);
  618. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  619.         emu_set_CC_cs(regs, SR_c, SR_s);
  620.         return _fex;
  621. }
  622. /* Load floating point integer long double */
  623. static int emu_fixbr (struct pt_regs *regs, int rx, int ry, int mask) {
  624.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  625.         FP_DECL_Q(QA);
  626.         FP_DECL_EX;
  627. mathemu_ldcv cvt;
  628.         __s32 si;
  629.         int mode;
  630. if (mask == 0)
  631. mode = fp_regs->fpc & 3;
  632. else if (mask == 1)
  633. mode = FP_RND_NEAREST;
  634. else
  635. mode = mask - 4;
  636.         cvt.w.high = fp_regs->fprs[ry].ui;
  637.         cvt.w.low = fp_regs->fprs[ry+2].ui;
  638.         FP_UNPACK_QP(QA, &cvt.ld);
  639. FP_TO_FPINT_ROUND_Q(QA);
  640. FP_PACK_QP(&cvt.ld, QA);
  641. fp_regs->fprs[rx].ui = cvt.w.high;
  642. fp_regs->fprs[rx+2].ui = cvt.w.low;
  643.         return _fex;
  644. }
  645. /* Load floating point integer double */
  646. static int emu_fidbr (struct pt_regs *regs, int rx, int ry, int mask) {
  647. /* FIXME: rounding mode !! */
  648.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  649.         FP_DECL_D(DA);
  650.         FP_DECL_EX;
  651.         __s32 si;
  652.         int mode;
  653. if (mask == 0)
  654. mode = fp_regs->fpc & 3;
  655. else if (mask == 1)
  656. mode = FP_RND_NEAREST;
  657. else
  658. mode = mask - 4;
  659.         FP_UNPACK_DP(DA, &fp_regs->fprs[ry].d);
  660. FP_TO_FPINT_ROUND_D(DA);
  661. FP_PACK_DP(&fp_regs->fprs[rx].d, DA);
  662.         return _fex;
  663. }
  664. /* Load floating point integer float */
  665. static int emu_fiebr (struct pt_regs *regs, int rx, int ry, int mask) {
  666.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  667.         FP_DECL_S(SA);
  668.         FP_DECL_EX;
  669.         __s32 si;
  670.         int mode;
  671. if (mask == 0)
  672. mode = fp_regs->fpc & 3;
  673. else if (mask == 1)
  674. mode = FP_RND_NEAREST;
  675. else
  676. mode = mask - 4;
  677.         FP_UNPACK_SP(SA, &fp_regs->fprs[ry].f);
  678. FP_TO_FPINT_ROUND_S(SA);
  679. FP_PACK_SP(&fp_regs->fprs[rx].f, SA);
  680.         return _fex;
  681. }
  682. /* Load lengthened double to long double */
  683. static int emu_lxdbr (struct pt_regs *regs, int rx, int ry) {
  684.         FP_DECL_D(DA); FP_DECL_Q(QR);
  685. FP_DECL_EX;
  686. mathemu_ldcv cvt;
  687.         int mode;
  688. mode = current->thread.fp_regs.fpc & 3;
  689.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  690. FP_CONV (Q, D, 4, 2, QR, DA);
  691.         FP_PACK_QP(&cvt.ld, QR);
  692.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  693.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  694.         return _fex;
  695. }
  696. /* Load lengthened double to long double */
  697. static int emu_lxdb (struct pt_regs *regs, int rx, double *val) {
  698.         FP_DECL_D(DA); FP_DECL_Q(QR);
  699. FP_DECL_EX;
  700. mathemu_ldcv cvt;
  701.         int mode;
  702. mode = current->thread.fp_regs.fpc & 3;
  703.         FP_UNPACK_DP(DA, val);
  704. FP_CONV (Q, D, 4, 2, QR, DA);
  705.         FP_PACK_QP(&cvt.ld, QR);
  706.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  707.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  708.         return _fex;
  709. }
  710. /* Load lengthened float to long double */
  711. static int emu_lxebr (struct pt_regs *regs, int rx, int ry) {
  712.         FP_DECL_S(SA); FP_DECL_Q(QR);
  713. FP_DECL_EX;
  714. mathemu_ldcv cvt;
  715.         int mode;
  716. mode = current->thread.fp_regs.fpc & 3;
  717.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  718. FP_CONV (Q, S, 4, 1, QR, SA);
  719.         FP_PACK_QP(&cvt.ld, QR);
  720.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  721.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  722.         return _fex;
  723. }
  724. /* Load lengthened float to long double */
  725. static int emu_lxeb (struct pt_regs *regs, int rx, float *val) {
  726.         FP_DECL_S(SA); FP_DECL_Q(QR);
  727. FP_DECL_EX;
  728. mathemu_ldcv cvt;
  729.         int mode;
  730. mode = current->thread.fp_regs.fpc & 3;
  731.         FP_UNPACK_SP(SA, val);
  732. FP_CONV (Q, S, 4, 1, QR, SA);
  733.         FP_PACK_QP(&cvt.ld, QR);
  734.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  735.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  736.         return _fex;
  737. }
  738. /* Load lengthened float to double */
  739. static int emu_ldebr (struct pt_regs *regs, int rx, int ry) {
  740.         FP_DECL_S(SA); FP_DECL_D(DR);
  741. FP_DECL_EX;
  742.         int mode;
  743. mode = current->thread.fp_regs.fpc & 3;
  744.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  745. FP_CONV (D, S, 2, 1, DR, SA);
  746. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  747.         return _fex;
  748. }
  749. /* Load lengthened float to double */
  750. static int emu_ldeb (struct pt_regs *regs, int rx, float *val) {
  751.         FP_DECL_S(SA); FP_DECL_D(DR);
  752. FP_DECL_EX;
  753.         int mode;
  754. mode = current->thread.fp_regs.fpc & 3;
  755.         FP_UNPACK_SP(SA, val);
  756. FP_CONV (D, S, 2, 1, DR, SA);
  757. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  758.         return _fex;
  759. }
  760. /* Load negative long double */
  761. static int emu_lnxbr (struct pt_regs *regs, int rx, int ry) {
  762.         FP_DECL_Q(QA); FP_DECL_Q(QR);
  763. FP_DECL_EX;
  764. mathemu_ldcv cvt;
  765.         int mode;
  766. mode = current->thread.fp_regs.fpc & 3;
  767.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  768.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  769.         FP_UNPACK_QP(QA, &cvt.ld);
  770.         if (QA_s == 0) {
  771. FP_NEG_Q(QR, QA);
  772. FP_PACK_QP(&cvt.ld, QR);
  773. current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  774. current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  775. } else {
  776. current->thread.fp_regs.fprs[rx].ui =
  777. current->thread.fp_regs.fprs[ry].ui;
  778. current->thread.fp_regs.fprs[rx+2].ui =
  779. current->thread.fp_regs.fprs[ry+2].ui;
  780. }
  781. emu_set_CC_cs(regs, QR_c, QR_s);
  782.         return _fex;
  783. }
  784. /* Load negative double */
  785. static int emu_lndbr (struct pt_regs *regs, int rx, int ry) {
  786.         FP_DECL_D(DA); FP_DECL_D(DR);
  787. FP_DECL_EX;
  788.         int mode;
  789. mode = current->thread.fp_regs.fpc & 3;
  790.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  791.         if (DA_s == 0) {
  792. FP_NEG_D(DR, DA);
  793. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  794. } else
  795. current->thread.fp_regs.fprs[rx].ui =
  796. current->thread.fp_regs.fprs[ry].ui;
  797. emu_set_CC_cs(regs, DR_c, DR_s);
  798.         return _fex;
  799. }
  800. /* Load negative float */
  801. static int emu_lnebr (struct pt_regs *regs, int rx, int ry) {
  802.         FP_DECL_S(SA); FP_DECL_S(SR);
  803. FP_DECL_EX;
  804.         int mode;
  805. mode = current->thread.fp_regs.fpc & 3;
  806.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  807.         if (SA_s == 0) {
  808. FP_NEG_S(SR, SA);
  809. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  810. } else
  811. current->thread.fp_regs.fprs[rx].ui =
  812. current->thread.fp_regs.fprs[ry].ui;
  813. emu_set_CC_cs(regs, SR_c, SR_s);
  814.         return _fex;
  815. }
  816. /* Load positive long double */
  817. static int emu_lpxbr (struct pt_regs *regs, int rx, int ry) {
  818.         FP_DECL_Q(QA); FP_DECL_Q(QR);
  819. FP_DECL_EX;
  820. mathemu_ldcv cvt;
  821.         int mode;
  822. mode = current->thread.fp_regs.fpc & 3;
  823.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  824.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  825.         FP_UNPACK_QP(QA, &cvt.ld);
  826.         if (QA_s != 0) {
  827. FP_NEG_Q(QR, QA);
  828. FP_PACK_QP(&cvt.ld, QR);
  829. current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  830. current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  831. } else{
  832. current->thread.fp_regs.fprs[rx].ui =
  833. current->thread.fp_regs.fprs[ry].ui;
  834. current->thread.fp_regs.fprs[rx+2].ui =
  835. current->thread.fp_regs.fprs[ry+2].ui;
  836. }
  837. emu_set_CC_cs(regs, QR_c, QR_s);
  838.         return _fex;
  839. }
  840. /* Load positive double */
  841. static int emu_lpdbr (struct pt_regs *regs, int rx, int ry) {
  842.         FP_DECL_D(DA); FP_DECL_D(DR);
  843. FP_DECL_EX;
  844.         int mode;
  845. mode = current->thread.fp_regs.fpc & 3;
  846.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  847.         if (DA_s != 0) {
  848. FP_NEG_D(DR, DA);
  849. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  850. } else
  851. current->thread.fp_regs.fprs[rx].ui =
  852. current->thread.fp_regs.fprs[ry].ui;
  853. emu_set_CC_cs(regs, DR_c, DR_s);
  854.         return _fex;
  855. }
  856. /* Load positive float */
  857. static int emu_lpebr (struct pt_regs *regs, int rx, int ry) {
  858.         FP_DECL_S(SA); FP_DECL_S(SR);
  859. FP_DECL_EX;
  860.         int mode;
  861. mode = current->thread.fp_regs.fpc & 3;
  862.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  863.         if (SA_s != 0) {
  864. FP_NEG_S(SR, SA);
  865. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  866. } else
  867. current->thread.fp_regs.fprs[rx].ui =
  868. current->thread.fp_regs.fprs[ry].ui;
  869. emu_set_CC_cs(regs, SR_c, SR_s);
  870.         return _fex;
  871. }
  872. /* Load rounded long double to double */
  873. static int emu_ldxbr (struct pt_regs *regs, int rx, int ry) {
  874.         FP_DECL_Q(QA); FP_DECL_D(DR);
  875. FP_DECL_EX;
  876. mathemu_ldcv cvt;
  877.         int mode;
  878. mode = current->thread.fp_regs.fpc & 3;
  879.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  880.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  881.         FP_UNPACK_QP(QA, &cvt.ld);
  882. FP_CONV (D, Q, 2, 4, DR, QA);
  883. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].f, DR);
  884.         return _fex;
  885. }
  886. /* Load rounded long double to float */
  887. static int emu_lexbr (struct pt_regs *regs, int rx, int ry) {
  888.         FP_DECL_Q(QA); FP_DECL_S(SR);
  889. FP_DECL_EX;
  890. mathemu_ldcv cvt;
  891.         int mode;
  892. mode = current->thread.fp_regs.fpc & 3;
  893.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  894.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  895.         FP_UNPACK_QP(QA, &cvt.ld);
  896. FP_CONV (S, Q, 1, 4, SR, QA);
  897. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  898.         return _fex;
  899. }
  900. /* Load rounded double to float */
  901. static int emu_ledbr (struct pt_regs *regs, int rx, int ry) {
  902.         FP_DECL_D(DA); FP_DECL_S(SR);
  903. FP_DECL_EX;
  904.         int mode;
  905. mode = current->thread.fp_regs.fpc & 3;
  906.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  907. FP_CONV (S, D, 1, 2, SR, DA);
  908. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  909.         return _fex;
  910. }
  911. /* Multiply long double */
  912. static int emu_mxbr (struct pt_regs *regs, int rx, int ry) {
  913.         FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
  914.         FP_DECL_EX;
  915. mathemu_ldcv cvt;
  916.         int mode;
  917. mode = current->thread.fp_regs.fpc & 3;
  918.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  919.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  920.         FP_UNPACK_QP(QA, &cvt.ld);
  921.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  922.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  923.         FP_UNPACK_QP(QB, &cvt.ld);
  924.         FP_MUL_Q(QR, QA, QB);
  925.         FP_PACK_QP(&cvt.ld, QR);
  926.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  927.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  928.         return _fex;
  929. }
  930. /* Multiply double */
  931. static int emu_mdbr (struct pt_regs *regs, int rx, int ry) {
  932.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  933.         FP_DECL_EX;
  934.         int mode;
  935. mode = current->thread.fp_regs.fpc & 3;
  936.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  937.         FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  938.         FP_MUL_D(DR, DA, DB);
  939. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  940.         return _fex;
  941. }
  942. /* Multiply double */
  943. static int emu_mdb (struct pt_regs *regs, int rx, double *val) {
  944.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  945.         FP_DECL_EX;
  946.         int mode;
  947. mode = current->thread.fp_regs.fpc & 3;
  948.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  949.         FP_UNPACK_DP(DB, val);
  950.         FP_MUL_D(DR, DA, DB);
  951. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  952.         return _fex;
  953. }
  954. /* Multiply double to long double */
  955. static int emu_mxdbr (struct pt_regs *regs, int rx, int ry) {
  956.         FP_DECL_D(DA); FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
  957. FP_DECL_EX;
  958. mathemu_ldcv cvt;
  959.         int mode;
  960. mode = current->thread.fp_regs.fpc & 3;
  961.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  962. FP_CONV (Q, D, 4, 2, QA, DA);
  963.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  964. FP_CONV (Q, D, 4, 2, QB, DA);
  965.         FP_MUL_Q(QR, QA, QB);
  966.         FP_PACK_QP(&cvt.ld, QR);
  967.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  968.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  969.         return _fex;
  970. }
  971. /* Multiply double to long double */
  972. static int emu_mxdb (struct pt_regs *regs, int rx, long double *val) {
  973.         FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
  974.         FP_DECL_EX;
  975. mathemu_ldcv cvt;
  976.         int mode;
  977. mode = current->thread.fp_regs.fpc & 3;
  978.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  979.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  980.         FP_UNPACK_QP(QA, &cvt.ld);
  981.         FP_UNPACK_QP(QB, val);
  982.         FP_MUL_Q(QR, QA, QB);
  983.         FP_PACK_QP(&cvt.ld, QR);
  984.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  985.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  986.         return _fex;
  987. }
  988. /* Multiply float */
  989. static int emu_meebr (struct pt_regs *regs, int rx, int ry) {
  990.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  991.         FP_DECL_EX;
  992.         int mode;
  993. mode = current->thread.fp_regs.fpc & 3;
  994.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  995.         FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  996.         FP_MUL_S(SR, SA, SB);
  997. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  998.         return _fex;
  999. }
  1000. /* Multiply float */
  1001. static int emu_meeb (struct pt_regs *regs, int rx, float *val) {
  1002.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  1003.         FP_DECL_EX;
  1004.         int mode;
  1005. mode = current->thread.fp_regs.fpc & 3;
  1006.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1007.         FP_UNPACK_SP(SB, val);
  1008.         FP_MUL_S(SR, SA, SB);
  1009. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  1010.         return _fex;
  1011. }
  1012. /* Multiply float to double */
  1013. static int emu_mdebr (struct pt_regs *regs, int rx, int ry) {
  1014.         FP_DECL_S(SA); FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  1015. FP_DECL_EX;
  1016.         int mode;
  1017. mode = current->thread.fp_regs.fpc & 3;
  1018.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1019. FP_CONV (D, S, 2, 1, DA, SA);
  1020.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  1021. FP_CONV (D, S, 2, 1, DB, SA);
  1022.         FP_MUL_D(DR, DA, DB);
  1023. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  1024.         return _fex;
  1025. }
  1026. /* Multiply float to double */
  1027. static int emu_mdeb (struct pt_regs *regs, int rx, float *val) {
  1028.         FP_DECL_S(SA); FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  1029. FP_DECL_EX;
  1030.         int mode;
  1031. mode = current->thread.fp_regs.fpc & 3;
  1032.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1033. FP_CONV (D, S, 2, 1, DA, SA);
  1034.         FP_UNPACK_SP(SA, val);
  1035. FP_CONV (D, S, 2, 1, DB, SA);
  1036.         FP_MUL_D(DR, DA, DB);
  1037. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  1038.         return _fex;
  1039. }
  1040. /* Multiply and add double */
  1041. static int emu_madbr (struct pt_regs *regs, int rx, int ry, int rz) {
  1042.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DC); FP_DECL_D(DR);
  1043.         FP_DECL_EX;
  1044.         int mode;
  1045. mode = current->thread.fp_regs.fpc & 3;
  1046.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1047.         FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  1048.         FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
  1049.         FP_MUL_D(DR, DA, DB);
  1050.         FP_ADD_D(DR, DR, DC);
  1051. FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
  1052.         return _fex;
  1053. }
  1054. /* Multiply and add double */
  1055. static int emu_madb (struct pt_regs *regs, int rx, double *val, int rz) {
  1056.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DC); FP_DECL_D(DR);
  1057.         FP_DECL_EX;
  1058.         int mode;
  1059. mode = current->thread.fp_regs.fpc & 3;
  1060.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1061.         FP_UNPACK_DP(DB, val);
  1062.         FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
  1063.         FP_MUL_D(DR, DA, DB);
  1064.         FP_ADD_D(DR, DR, DC);
  1065. FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
  1066.         return _fex;
  1067. }
  1068. /* Multiply and add float */
  1069. static int emu_maebr (struct pt_regs *regs, int rx, int ry, int rz) {
  1070.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SC); FP_DECL_S(SR);
  1071.         FP_DECL_EX;
  1072.         int mode;
  1073. mode = current->thread.fp_regs.fpc & 3;
  1074.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1075.         FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  1076.         FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
  1077.         FP_MUL_S(SR, SA, SB);
  1078.         FP_ADD_S(SR, SR, SC);
  1079. FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
  1080.         return _fex;
  1081. }
  1082. /* Multiply and add float */
  1083. static int emu_maeb (struct pt_regs *regs, int rx, float *val, int rz) {
  1084.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SC); FP_DECL_S(SR);
  1085.         FP_DECL_EX;
  1086.         int mode;
  1087. mode = current->thread.fp_regs.fpc & 3;
  1088.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1089.         FP_UNPACK_SP(SB, val);
  1090.         FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
  1091.         FP_MUL_S(SR, SA, SB);
  1092.         FP_ADD_S(SR, SR, SC);
  1093. FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
  1094.         return _fex;
  1095. }
  1096. /* Multiply and subtract double */
  1097. static int emu_msdbr (struct pt_regs *regs, int rx, int ry, int rz) {
  1098.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DC); FP_DECL_D(DR);
  1099.         FP_DECL_EX;
  1100.         int mode;
  1101. mode = current->thread.fp_regs.fpc & 3;
  1102.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1103.         FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  1104.         FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
  1105.         FP_MUL_D(DR, DA, DB);
  1106.         FP_SUB_D(DR, DR, DC);
  1107. FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
  1108.         return _fex;
  1109. }
  1110. /* Multiply and subtract double */
  1111. static int emu_msdb (struct pt_regs *regs, int rx, double *val, int rz) {
  1112.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DC); FP_DECL_D(DR);
  1113.         FP_DECL_EX;
  1114.         int mode;
  1115. mode = current->thread.fp_regs.fpc & 3;
  1116.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1117.         FP_UNPACK_DP(DB, val);
  1118.         FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
  1119.         FP_MUL_D(DR, DA, DB);
  1120.         FP_SUB_D(DR, DR, DC);
  1121. FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
  1122.         return _fex;
  1123. }
  1124. /* Multiply and subtract float */
  1125. static int emu_msebr (struct pt_regs *regs, int rx, int ry, int rz) {
  1126.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SC); FP_DECL_S(SR);
  1127.         FP_DECL_EX;
  1128.         int mode;
  1129. mode = current->thread.fp_regs.fpc & 3;
  1130.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1131.         FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  1132.         FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
  1133.         FP_MUL_S(SR, SA, SB);
  1134.         FP_SUB_S(SR, SR, SC);
  1135. FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
  1136.         return _fex;
  1137. }
  1138. /* Multiply and subtract float */
  1139. static int emu_mseb (struct pt_regs *regs, int rx, float *val, int rz) {
  1140.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SC); FP_DECL_S(SR);
  1141.         FP_DECL_EX;
  1142.         int mode;
  1143. mode = current->thread.fp_regs.fpc & 3;
  1144.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1145.         FP_UNPACK_SP(SB, val);
  1146.         FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
  1147.         FP_MUL_S(SR, SA, SB);
  1148.         FP_SUB_S(SR, SR, SC);
  1149. FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
  1150.         return _fex;
  1151. }
  1152. /* Set floating point control word */
  1153. static int emu_sfpc (struct pt_regs *regs, int rx, int ry) {
  1154.         __u32 temp;
  1155.         temp = regs->gprs[rx];
  1156.         if ((temp & ~FPC_VALID_MASK) != 0)
  1157. return SIGILL;
  1158. current->thread.fp_regs.fpc = temp;
  1159.         return 0;
  1160. }
  1161. /* Square root long double */
  1162. static int emu_sqxbr (struct pt_regs *regs, int rx, int ry) {
  1163.         FP_DECL_Q(QA); FP_DECL_Q(QR);
  1164.         FP_DECL_EX;
  1165. mathemu_ldcv cvt;
  1166.         int mode;
  1167. mode = current->thread.fp_regs.fpc & 3;
  1168.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  1169.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  1170.         FP_UNPACK_QP(QA, &cvt.ld);
  1171. FP_SQRT_Q(QR, QA);
  1172.         FP_PACK_QP(&cvt.ld, QR);
  1173.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  1174.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  1175.         emu_set_CC_cs(regs, QR_c, QR_s);
  1176.         return _fex;
  1177. }
  1178. /* Square root double */
  1179. static int emu_sqdbr (struct pt_regs *regs, int rx, int ry) {
  1180.         FP_DECL_D(DA); FP_DECL_D(DR);
  1181.         FP_DECL_EX;
  1182.         int mode;
  1183. mode = current->thread.fp_regs.fpc & 3;
  1184.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
  1185. FP_SQRT_D(DR, DA);
  1186. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  1187.         emu_set_CC_cs(regs, DR_c, DR_s);
  1188.         return _fex;
  1189. }
  1190. /* Square root double */
  1191. static int emu_sqdb (struct pt_regs *regs, int rx, double *val) {
  1192.         FP_DECL_D(DA); FP_DECL_D(DR);
  1193.         FP_DECL_EX;
  1194.         int mode;
  1195. mode = current->thread.fp_regs.fpc & 3;
  1196.         FP_UNPACK_DP(DA, val);
  1197. FP_SQRT_D(DR, DA);
  1198. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  1199.         emu_set_CC_cs(regs, DR_c, DR_s);
  1200.         return _fex;
  1201. }
  1202. /* Square root float */
  1203. static int emu_sqebr (struct pt_regs *regs, int rx, int ry) {
  1204.         FP_DECL_S(SA); FP_DECL_S(SR);
  1205.         FP_DECL_EX;
  1206.         int mode;
  1207. mode = current->thread.fp_regs.fpc & 3;
  1208.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
  1209. FP_SQRT_S(SR, SA);
  1210. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  1211.         emu_set_CC_cs(regs, SR_c, SR_s);
  1212.         return _fex;
  1213. }
  1214. /* Square root float */
  1215. static int emu_sqeb (struct pt_regs *regs, int rx, float *val) {
  1216.         FP_DECL_S(SA); FP_DECL_S(SR);
  1217.         FP_DECL_EX;
  1218.         int mode;
  1219. mode = current->thread.fp_regs.fpc & 3;
  1220.         FP_UNPACK_SP(SA, val);
  1221. FP_SQRT_S(SR, SA);
  1222. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  1223.         emu_set_CC_cs(regs, SR_c, SR_s);
  1224.         return _fex;
  1225. }
  1226. /* Subtract long double */
  1227. static int emu_sxbr (struct pt_regs *regs, int rx, int ry) {
  1228.         FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
  1229.         FP_DECL_EX;
  1230. mathemu_ldcv cvt;
  1231.         int mode;
  1232. mode = current->thread.fp_regs.fpc & 3;
  1233.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  1234.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  1235.         FP_UNPACK_QP(QA, &cvt.ld);
  1236.         cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
  1237.         cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
  1238.         FP_UNPACK_QP(QB, &cvt.ld);
  1239.         FP_SUB_Q(QR, QA, QB);
  1240.         FP_PACK_QP(&cvt.ld, QR);
  1241.         current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
  1242.         current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
  1243.         emu_set_CC_cs(regs, QR_c, QR_s);
  1244.         return _fex;
  1245. }
  1246. /* Subtract double */
  1247. static int emu_sdbr (struct pt_regs *regs, int rx, int ry) {
  1248.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  1249.         FP_DECL_EX;
  1250.         int mode;
  1251. mode = current->thread.fp_regs.fpc & 3;
  1252.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1253.         FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
  1254.         FP_SUB_D(DR, DA, DB);
  1255. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  1256.         emu_set_CC_cs(regs, DR_c, DR_s);
  1257.         return _fex;
  1258. }
  1259. /* Subtract double */
  1260. static int emu_sdb (struct pt_regs *regs, int rx, double *val) {
  1261.         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
  1262.         FP_DECL_EX;
  1263.         int mode;
  1264. mode = current->thread.fp_regs.fpc & 3;
  1265.         FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1266.         FP_UNPACK_DP(DB, val);
  1267.         FP_SUB_D(DR, DA, DB);
  1268. FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
  1269.         emu_set_CC_cs(regs, DR_c, DR_s);
  1270.         return _fex;
  1271. }
  1272. /* Subtract float */
  1273. static int emu_sebr (struct pt_regs *regs, int rx, int ry) {
  1274.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  1275.         FP_DECL_EX;
  1276.         int mode;
  1277. mode = current->thread.fp_regs.fpc & 3;
  1278.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1279.         FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
  1280.         FP_SUB_S(SR, SA, SB);
  1281. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  1282.         emu_set_CC_cs(regs, SR_c, SR_s);
  1283.         return _fex;
  1284. }
  1285. /* Subtract float */
  1286. static int emu_seb (struct pt_regs *regs, int rx, float *val) {
  1287.         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
  1288.         FP_DECL_EX;
  1289.         int mode;
  1290. mode = current->thread.fp_regs.fpc & 3;
  1291.         FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1292.         FP_UNPACK_SP(SB, val);
  1293.         FP_SUB_S(SR, SA, SB);
  1294. FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
  1295.         emu_set_CC_cs(regs, SR_c, SR_s);
  1296.         return _fex;
  1297. }
  1298. /* Test data class long double */
  1299. static int emu_tcxb (struct pt_regs *regs, int rx, long val) {
  1300.         FP_DECL_Q(QA);
  1301. mathemu_ldcv cvt;
  1302. int bit;
  1303.         cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
  1304.         cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
  1305.         FP_UNPACK_RAW_QP(QA, &cvt.ld);
  1306. switch (QA_e) {
  1307. default:
  1308. bit = 8; /* normalized number */
  1309. break;
  1310. case 0:
  1311. if (_FP_FRAC_ZEROP_4(QA))
  1312. bit = 10; /* zero */
  1313. else
  1314. bit = 6; /* denormalized number */
  1315. break;
  1316. case _FP_EXPMAX_Q:
  1317. if (_FP_FRAC_ZEROP_4(QA))
  1318. bit = 4; /* infinity */
  1319. else if (_FP_FRAC_HIGH_RAW_Q(QA) & _FP_QNANBIT_Q)
  1320. bit = 2; /* quiet NAN */
  1321. else
  1322. bit = 0; /* signaling NAN */
  1323. break;
  1324. }
  1325. if (!QA_s)
  1326. bit++;
  1327. emu_set_CC(regs, ((__u32) val >> bit) & 1);
  1328.         return 0;
  1329. }
  1330. /* Test data class double */
  1331. static int emu_tcdb (struct pt_regs *regs, int rx, long val) {
  1332.         FP_DECL_D(DA);
  1333. int bit;
  1334.         FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
  1335. switch (DA_e) {
  1336. default:
  1337. bit = 8; /* normalized number */
  1338. break;
  1339. case 0:
  1340. if (_FP_FRAC_ZEROP_2(DA))
  1341. bit = 10; /* zero */
  1342. else
  1343. bit = 6; /* denormalized number */
  1344. break;
  1345. case _FP_EXPMAX_D:
  1346. if (_FP_FRAC_ZEROP_2(DA))
  1347. bit = 4; /* infinity */
  1348. else if (_FP_FRAC_HIGH_RAW_D(DA) & _FP_QNANBIT_D)
  1349. bit = 2; /* quiet NAN */
  1350. else
  1351. bit = 0; /* signaling NAN */
  1352. break;
  1353. }
  1354. if (!DA_s)
  1355. bit++;
  1356. emu_set_CC(regs, ((__u32) val >> bit) & 1);
  1357.         return 0;
  1358. }
  1359. /* Test data class float */
  1360. static int emu_tceb (struct pt_regs *regs, int rx, long val) {
  1361.         FP_DECL_S(SA);
  1362. int bit;
  1363.         FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
  1364. switch (SA_e) {
  1365. default:
  1366. bit = 8; /* normalized number */
  1367. break;
  1368. case 0:
  1369. if (_FP_FRAC_ZEROP_1(SA))
  1370. bit = 10; /* zero */
  1371. else
  1372. bit = 6; /* denormalized number */
  1373. break;
  1374. case _FP_EXPMAX_S:
  1375. if (_FP_FRAC_ZEROP_1(SA))
  1376. bit = 4; /* infinity */
  1377. else if (_FP_FRAC_HIGH_RAW_S(SA) & _FP_QNANBIT_S)
  1378. bit = 2; /* quiet NAN */
  1379. else
  1380. bit = 0; /* signaling NAN */
  1381. break;
  1382. }
  1383. if (!SA_s)
  1384. bit++;
  1385. emu_set_CC(regs, ((__u32) val >> bit) & 1);
  1386.         return 0;
  1387. }
  1388. static inline void emu_load_regd(int reg) {
  1389.         if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
  1390.                 return;
  1391.         asm volatile (            /* load reg from fp_regs.fprs[reg] */
  1392.                 "     bras  1,0fn"
  1393.                 "     ld    0,0(%1)n"
  1394.                 "0:   ex    %0,0(1)"
  1395.                 : /* no output */
  1396.                 : "a" (reg<<4),"a" (&current->thread.fp_regs.fprs[reg].d)
  1397.                 : "1" );
  1398. }
  1399. static inline void emu_load_rege(int reg) {
  1400.         if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
  1401.                 return;
  1402.         asm volatile (            /* load reg from fp_regs.fprs[reg] */
  1403.                 "     bras  1,0fn"
  1404.                 "     le    0,0(%1)n"
  1405.                 "0:   ex    %0,0(1)"
  1406.                 : /* no output */
  1407.                 : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
  1408.                 : "1" );
  1409. }
  1410. static inline void emu_store_regd(int reg) {
  1411.         if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
  1412.                 return;
  1413.         asm volatile (            /* store reg to fp_regs.fprs[reg] */
  1414.                 "     bras  1,0fn"
  1415.                 "     std   0,0(%1)n"
  1416.                 "0:   ex    %0,0(1)"
  1417.                 : /* no output */
  1418.                 : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
  1419.                 : "1" );
  1420. }
  1421. static inline void emu_store_rege(int reg) {
  1422.         if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
  1423.                 return;
  1424.         asm volatile (            /* store reg to fp_regs.fprs[reg] */
  1425.                 "     bras  1,0fn"
  1426.                 "     ste   0,0(%1)n"
  1427.                 "0:   ex    %0,0(1)"
  1428.                 : /* no output */
  1429.                 : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
  1430.                 : "1" );
  1431. }
  1432. int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
  1433.         int _fex = 0;
  1434.         static const __u8 format_table[256] = {
  1435.                 [0x00] = 0x03,[0x01] = 0x03,[0x02] = 0x03,[0x03] = 0x03,
  1436. [0x04] = 0x0f,[0x05] = 0x0d,[0x06] = 0x0e,[0x07] = 0x0d,
  1437. [0x08] = 0x03,[0x09] = 0x03,[0x0a] = 0x03,[0x0b] = 0x03,
  1438.                 [0x0c] = 0x0f,[0x0d] = 0x03,[0x0e] = 0x06,[0x0f] = 0x06,
  1439. [0x10] = 0x02,[0x11] = 0x02,[0x12] = 0x02,[0x13] = 0x02,
  1440. [0x14] = 0x03,[0x15] = 0x02,[0x16] = 0x01,[0x17] = 0x03,
  1441.                 [0x18] = 0x02,[0x19] = 0x02,[0x1a] = 0x02,[0x1b] = 0x02,
  1442. [0x1c] = 0x02,[0x1d] = 0x02,[0x1e] = 0x05,[0x1f] = 0x05,
  1443. [0x40] = 0x01,[0x41] = 0x01,[0x42] = 0x01,[0x43] = 0x01,
  1444.                 [0x44] = 0x12,[0x45] = 0x0d,[0x46] = 0x11,[0x47] = 0x04,
  1445. [0x48] = 0x01,[0x49] = 0x01,[0x4a] = 0x01,[0x4b] = 0x01,
  1446. [0x4c] = 0x01,[0x4d] = 0x01,[0x53] = 0x06,[0x57] = 0x06,
  1447.                 [0x5b] = 0x05,[0x5f] = 0x05,[0x84] = 0x13,[0x8c] = 0x13,
  1448. [0x94] = 0x09,[0x95] = 0x08,[0x96] = 0x07,[0x98] = 0x0c,
  1449. [0x99] = 0x0b,[0x9a] = 0x0a
  1450.         };
  1451.         static const void *jump_table[256]= {
  1452.                 [0x00] = emu_lpebr,[0x01] = emu_lnebr,[0x02] = emu_ltebr,
  1453.                 [0x03] = emu_lcebr,[0x04] = emu_ldebr,[0x05] = emu_lxdbr,
  1454.                 [0x06] = emu_lxebr,[0x07] = emu_mxdbr,[0x08] = emu_kebr,
  1455.                 [0x09] = emu_cebr, [0x0a] = emu_aebr, [0x0b] = emu_sebr,
  1456.                 [0x0c] = emu_mdebr,[0x0d] = emu_debr, [0x0e] = emu_maebr,
  1457.                 [0x0f] = emu_msebr,[0x10] = emu_lpdbr,[0x11] = emu_lndbr, 
  1458.                 [0x12] = emu_ltdbr,[0x13] = emu_lcdbr,[0x14] = emu_sqebr,
  1459.                 [0x15] = emu_sqdbr,[0x16] = emu_sqxbr,[0x17] = emu_meebr,
  1460.                 [0x18] = emu_kdbr, [0x19] = emu_cdbr, [0x1a] = emu_adbr,
  1461.                 [0x1b] = emu_sdbr, [0x1c] = emu_mdbr, [0x1d] = emu_ddbr,  
  1462.                 [0x1e] = emu_madbr,[0x1f] = emu_msdbr,[0x40] = emu_lpxbr,
  1463.                 [0x41] = emu_lnxbr,[0x42] = emu_ltxbr,[0x43] = emu_lcxbr,
  1464.                 [0x44] = emu_ledbr,[0x45] = emu_ldxbr,[0x46] = emu_lexbr,
  1465.                 [0x47] = emu_fixbr,[0x48] = emu_kxbr, [0x49] = emu_cxbr,  
  1466.                 [0x4a] = emu_axbr, [0x4b] = emu_sxbr, [0x4c] = emu_mxbr,
  1467.                 [0x4d] = emu_dxbr, [0x53] = emu_diebr,[0x57] = emu_fiebr,
  1468.                 [0x5b] = emu_didbr,[0x5f] = emu_fidbr,[0x84] = emu_sfpc,
  1469.                 [0x8c] = emu_efpc, [0x94] = emu_cefbr,[0x95] = emu_cdfbr, 
  1470.                 [0x96] = emu_cxfbr,[0x98] = emu_cfebr,[0x99] = emu_cfdbr,
  1471.                 [0x9a] = emu_cfxbr
  1472.         };
  1473.         switch (format_table[opcode[1]]) {
  1474.         case 1: /* RRE format, long double operation */
  1475.                 if (opcode[3] & 0x22)
  1476. return SIGILL;
  1477.                 emu_store_regd((opcode[3] >> 4) & 15);
  1478.                 emu_store_regd(((opcode[3] >> 4) & 15) + 2);
  1479.                 emu_store_regd(opcode[3] & 15);
  1480.                 emu_store_regd((opcode[3] & 15) + 2);
  1481.                 /* call the emulation function */
  1482.                 _fex = ((int (*)(struct pt_regs *,int, int))
  1483. jump_table[opcode[1]])
  1484.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1485.                 emu_load_regd((opcode[3] >> 4) & 15);
  1486.                 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
  1487.                 emu_load_regd(opcode[3] & 15);
  1488.                 emu_load_regd((opcode[3] & 15) + 2);
  1489. break;
  1490.         case 2: /* RRE format, double operation */
  1491.                 emu_store_regd((opcode[3] >> 4) & 15);
  1492.                 emu_store_regd(opcode[3] & 15);
  1493.                 /* call the emulation function */
  1494.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1495. jump_table[opcode[1]])
  1496.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1497.                 emu_load_regd((opcode[3] >> 4) & 15);
  1498.                 emu_load_regd(opcode[3] & 15);
  1499. break;
  1500.         case 3: /* RRE format, float operation */
  1501.                 emu_store_rege((opcode[3] >> 4) & 15);
  1502.                 emu_store_rege(opcode[3] & 15);
  1503.                 /* call the emulation function */
  1504.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1505. jump_table[opcode[1]])
  1506.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1507.                 emu_load_rege((opcode[3] >> 4) & 15);
  1508.                 emu_load_rege(opcode[3] & 15);
  1509. break;
  1510.         case 4: /* RRF format, long double operation */
  1511.                 if (opcode[3] & 0x22)
  1512. return SIGILL;
  1513.                 emu_store_regd((opcode[3] >> 4) & 15);
  1514.                 emu_store_regd(((opcode[3] >> 4) & 15) + 2);
  1515.                 emu_store_regd(opcode[3] & 15);
  1516.                 emu_store_regd((opcode[3] & 15) + 2);
  1517.                 /* call the emulation function */
  1518.                 _fex = ((int (*)(struct pt_regs *, int, int, int))
  1519. jump_table[opcode[1]])
  1520.                         (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
  1521.                 emu_load_regd((opcode[3] >> 4) & 15);
  1522.                 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
  1523.                 emu_load_regd(opcode[3] & 15);
  1524.                 emu_load_regd((opcode[3] & 15) + 2);
  1525. break;
  1526.         case 5: /* RRF format, double operation */
  1527.                 emu_store_regd((opcode[2] >> 4) & 15);
  1528.                 emu_store_regd((opcode[3] >> 4) & 15);
  1529.                 emu_store_regd(opcode[3] & 15);
  1530.                 /* call the emulation function */
  1531.                 _fex = ((int (*)(struct pt_regs *, int, int, int))
  1532. jump_table[opcode[1]])
  1533.                         (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
  1534.                 emu_load_regd((opcode[2] >> 4) & 15);
  1535.                 emu_load_regd((opcode[3] >> 4) & 15);
  1536.                 emu_load_regd(opcode[3] & 15);
  1537. break;
  1538.         case 6: /* RRF format, float operation */
  1539.                 emu_store_rege((opcode[2] >> 4) & 15);
  1540.                 emu_store_rege((opcode[3] >> 4) & 15);
  1541.                 emu_store_rege(opcode[3] & 15);
  1542.                 /* call the emulation function */
  1543.                 _fex = ((int (*)(struct pt_regs *, int, int, int))
  1544. jump_table[opcode[1]])
  1545.                         (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
  1546.                 emu_load_rege((opcode[2] >> 4) & 15);
  1547.                 emu_load_rege((opcode[3] >> 4) & 15);
  1548.                 emu_load_rege(opcode[3] & 15);
  1549. break;
  1550.         case 7: /* RRE format, cxfbr instruction */
  1551.                 /* call the emulation function */
  1552.                 if (opcode[3] & 0x20)
  1553. return SIGILL;
  1554.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1555. jump_table[opcode[1]])
  1556.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1557.                 emu_load_regd((opcode[3] >> 4) & 15);
  1558.                 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
  1559. break;
  1560.         case 8: /* RRE format, cdfbr instruction */
  1561.                 /* call the emulation function */
  1562.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1563. jump_table[opcode[1]])
  1564.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1565.                 emu_load_regd((opcode[3] >> 4) & 15);
  1566. break;
  1567.         case 9: /* RRE format, cefbr instruction */
  1568.                 /* call the emulation function */
  1569.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1570. jump_table[opcode[1]])
  1571.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1572.                 emu_load_rege((opcode[3] >> 4) & 15);
  1573. break;
  1574.         case 10: /* RRF format, cfxbr instruction */
  1575.                 if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
  1576. /* mask of { 2,3,8-15 } is invalid */
  1577. return SIGILL;
  1578.                 if (opcode[3] & 2)
  1579. return SIGILL;
  1580.                 emu_store_regd(opcode[3] & 15);
  1581.                 emu_store_regd((opcode[3] & 15) + 2);
  1582.                 /* call the emulation function */
  1583.                 _fex = ((int (*)(struct pt_regs *, int, int, int))
  1584. jump_table[opcode[1]])
  1585.                         (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
  1586. break;
  1587.         case 11: /* RRF format, cfdbr instruction */
  1588.                 if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
  1589. /* mask of { 2,3,8-15 } is invalid */
  1590. return SIGILL;
  1591.                 emu_store_regd(opcode[3] & 15);
  1592.                 /* call the emulation function */
  1593.                 _fex = ((int (*)(struct pt_regs *, int, int, int))
  1594. jump_table[opcode[1]])
  1595.                         (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
  1596. break;
  1597.         case 12: /* RRF format, cfebr instruction */
  1598.                 if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
  1599. /* mask of { 2,3,8-15 } is invalid */
  1600. return SIGILL;
  1601.                 emu_store_rege(opcode[3] & 15);
  1602.                 /* call the emulation function */
  1603.                 _fex = ((int (*)(struct pt_regs *, int, int, int))
  1604. jump_table[opcode[1]])
  1605.                         (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
  1606. break;
  1607.         case 13: /* RRE format, ldxbr & mdxbr instruction */
  1608.                 /* double store but long double load */
  1609.                 if (opcode[3] & 0x20)
  1610. return SIGILL;
  1611.                 emu_store_regd((opcode[3] >> 4) & 15);
  1612.                 emu_store_regd(opcode[3]  & 15);
  1613.                 /* call the emulation function */
  1614.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1615. jump_table[opcode[1]])
  1616.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1617.                 emu_load_regd((opcode[3] >> 4) & 15);
  1618.                 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
  1619. break;
  1620.         case 14: /* RRE format, ldxbr & mdxbr instruction */
  1621.                 /* float store but long double load */
  1622.                 if (opcode[3] & 0x20)
  1623. return SIGILL;
  1624.                 emu_store_rege((opcode[3] >> 4) & 15);
  1625.                 emu_store_rege(opcode[3]  & 15);
  1626.                 /* call the emulation function */
  1627.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1628. jump_table[opcode[1]])
  1629.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1630.                 emu_load_regd((opcode[3] >> 4) & 15);
  1631.                 emu_load_regd(((opcode[3] >> 4) & 15) + 2);
  1632. break;
  1633.         case 15: /* RRE format, ldebr & mdebr instruction */
  1634.                 /* float store but double load */
  1635.                 emu_store_rege((opcode[3] >> 4) & 15);
  1636.                 emu_store_rege(opcode[3]  & 15);
  1637.                 /* call the emulation function */
  1638.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1639. jump_table[opcode[1]])
  1640.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1641.                 emu_load_regd((opcode[3] >> 4) & 15);
  1642. break;
  1643.         case 16: /* RRE format, ldxbr instruction */
  1644.                 /* long double store but double load */
  1645.                 if (opcode[3] & 2)
  1646. return SIGILL;
  1647.                 emu_store_regd(opcode[3] & 15);
  1648.                 emu_store_regd((opcode[3] & 15) + 2);
  1649.                 /* call the emulation function */
  1650.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1651. jump_table[opcode[1]])
  1652.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1653.                 emu_load_regd((opcode[3] >> 4) & 15);
  1654.                 break;
  1655.         case 17: /* RRE format, ldxbr instruction */
  1656.                 /* long double store but float load */
  1657.                 if (opcode[3] & 2)
  1658. return SIGILL;
  1659.                 emu_store_regd(opcode[3] & 15);
  1660.                 emu_store_regd((opcode[3] & 15) + 2);
  1661.                 /* call the emulation function */
  1662.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1663. jump_table[opcode[1]])
  1664.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1665.                 emu_load_rege((opcode[3] >> 4) & 15);
  1666.                 break;
  1667.         case 18: /* RRE format, ledbr instruction */
  1668.                 /* double store but float load */
  1669.                 emu_store_regd(opcode[3] & 15);
  1670.                 /* call the emulation function */
  1671.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1672. jump_table[opcode[1]])
  1673.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1674.                 emu_load_rege((opcode[3] >> 4) & 15);
  1675.                 break;
  1676.         case 19: /* RRE format, efpc & sfpc instruction */
  1677.                 /* call the emulation function */
  1678.                 _fex = ((int (*)(struct pt_regs *, int, int))
  1679. jump_table[opcode[1]])
  1680.                         (regs, opcode[3] >> 4, opcode[3] & 15);
  1681.                 break;
  1682.         default: /* invalid operation */
  1683.                 return SIGILL;
  1684.         }
  1685. if (_fex != 0) {
  1686. current->thread.fp_regs.fpc |= _fex;
  1687. if (current->thread.fp_regs.fpc & (_fex << 8))
  1688. return SIGFPE;
  1689. }
  1690. return 0;
  1691. }
  1692. static void* calc_addr(struct pt_regs *regs, int rx, int rb, int disp)
  1693. {
  1694.         addr_t addr;
  1695.         rx &= 15;
  1696.         rb &= 15;
  1697.         addr = disp & 0xfff;
  1698.         addr += (rx != 0) ? regs->gprs[rx] : 0;  /* + index */
  1699.         addr += (rb != 0) ? regs->gprs[rb] : 0;  /* + base  */
  1700.         return (void*) addr;
  1701. }
  1702.     
  1703. int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
  1704.         int _fex = 0;
  1705.         static const __u8 format_table[256] = {
  1706.                 [0x04] = 0x06,[0x05] = 0x05,[0x06] = 0x07,[0x07] = 0x05,
  1707. [0x08] = 0x02,[0x09] = 0x02,[0x0a] = 0x02,[0x0b] = 0x02,
  1708. [0x0c] = 0x06,[0x0d] = 0x02,[0x0e] = 0x04,[0x0f] = 0x04,
  1709.                 [0x10] = 0x08,[0x11] = 0x09,[0x12] = 0x0a,[0x14] = 0x02,
  1710. [0x15] = 0x01,[0x17] = 0x02,[0x18] = 0x01,[0x19] = 0x01,
  1711. [0x1a] = 0x01,[0x1b] = 0x01,[0x1c] = 0x01,[0x1d] = 0x01,
  1712.                 [0x1e] = 0x03,[0x1f] = 0x03,
  1713.         };
  1714.         static const void *jump_table[]= {
  1715.                 [0x04] = emu_ldeb,[0x05] = emu_lxdb,[0x06] = emu_lxeb,
  1716.                 [0x07] = emu_mxdb,[0x08] = emu_keb, [0x09] = emu_ceb,
  1717.                 [0x0a] = emu_aeb, [0x0b] = emu_seb, [0x0c] = emu_mdeb,
  1718.                 [0x0d] = emu_deb, [0x0e] = emu_maeb,[0x0f] = emu_mseb,
  1719.                 [0x10] = emu_tceb,[0x11] = emu_tcdb,[0x12] = emu_tcxb,
  1720.                 [0x14] = emu_sqeb,[0x15] = emu_sqdb,[0x17] = emu_meeb,
  1721.                 [0x18] = emu_kdb, [0x19] = emu_cdb, [0x1a] = emu_adb,
  1722.                 [0x1b] = emu_sdb, [0x1c] = emu_mdb, [0x1d] = emu_ddb,
  1723.                 [0x1e] = emu_madb,[0x1f] = emu_msdb
  1724.         };
  1725.         switch (format_table[opcode[5]]) {
  1726.         case 1: /* RXE format, double constant */ {
  1727.                 __u64 *dxb, temp;
  1728.                 __u32 opc;
  1729.                 emu_store_regd((opcode[1] >> 4) & 15);
  1730.                 opc = *((__u32 *) opcode);
  1731.                 dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1732.                 mathemu_copy_from_user(&temp, dxb, 8);
  1733.                 /* call the emulation function */
  1734.                 _fex = ((int (*)(struct pt_regs *, int, double *))
  1735. jump_table[opcode[5]])
  1736.                         (regs, opcode[1] >> 4, (double *) &temp);
  1737.                 emu_load_regd((opcode[1] >> 4) & 15);
  1738.                 break;
  1739.         }
  1740.         case 2: /* RXE format, float constant */ {
  1741.                 __u32 *dxb, temp;
  1742.                 __u32 opc;
  1743.                 emu_store_rege((opcode[1] >> 4) & 15);
  1744.                 opc = *((__u32 *) opcode);
  1745.                 dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1746.                 mathemu_get_user(temp, dxb);
  1747.                 /* call the emulation function */
  1748.                 _fex = ((int (*)(struct pt_regs *, int, float *))
  1749. jump_table[opcode[5]])
  1750.                         (regs, opcode[1] >> 4, (float *) &temp);
  1751.                 emu_load_rege((opcode[1] >> 4) & 15);
  1752.                 break;
  1753.         }
  1754.         case 3: /* RXF format, double constant */ {
  1755.                 __u64 *dxb, temp;
  1756.                 __u32 opc;
  1757.                 emu_store_regd((opcode[1] >> 4) & 15);
  1758.                 emu_store_regd((opcode[4] >> 4) & 15);
  1759.                 opc = *((__u32 *) opcode);
  1760.                 dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1761.                 mathemu_copy_from_user(&temp, dxb, 8);
  1762.                 /* call the emulation function */
  1763.                 _fex = ((int (*)(struct pt_regs *, int, double *, int))
  1764. jump_table[opcode[5]])
  1765.                         (regs, opcode[1] >> 4, (double *) &temp, opcode[4] >> 4);
  1766.                 emu_load_regd((opcode[1] >> 4) & 15);
  1767.                 break;
  1768.         }
  1769.         case 4: /* RXF format, float constant */ {
  1770.                 __u32 *dxb, temp;
  1771.                 __u32 opc;
  1772.                 emu_store_rege((opcode[1] >> 4) & 15);
  1773.                 emu_store_rege((opcode[4] >> 4) & 15);
  1774.                 opc = *((__u32 *) opcode);
  1775.                 dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1776.                 mathemu_get_user(temp, dxb);
  1777.                 /* call the emulation function */
  1778.                 _fex = ((int (*)(struct pt_regs *, int, float *, int))
  1779. jump_table[opcode[5]])
  1780.                         (regs, opcode[1] >> 4, (float *) &temp, opcode[4] >> 4);
  1781.                 emu_load_rege((opcode[4] >> 4) & 15);
  1782.                 break;
  1783.         }
  1784.         case 5: /* RXE format, double constant */
  1785.                 /* store double and load long double */ 
  1786.         {
  1787.                 __u64 *dxb, temp;
  1788.                 __u32 opc;
  1789.                 if ((opcode[1] >> 4) & 0x20)
  1790. return SIGILL;
  1791.                 emu_store_regd((opcode[1] >> 4) & 15);
  1792.                 opc = *((__u32 *) opcode);
  1793.                 dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1794.                 mathemu_copy_from_user(&temp, dxb, 8);
  1795.                 /* call the emulation function */
  1796.                 _fex = ((int (*)(struct pt_regs *, int, double *))
  1797. jump_table[opcode[5]])
  1798.                         (regs, opcode[1] >> 4, (double *) &temp);
  1799.                 emu_load_regd((opcode[1] >> 4) & 15);
  1800.                 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
  1801.                 break;
  1802.         }
  1803.         case 6: /* RXE format, float constant */
  1804.                 /* store float and load double */ 
  1805.         {
  1806.                 __u32 *dxb, temp;
  1807.                 __u32 opc;
  1808.                 emu_store_rege((opcode[1] >> 4) & 15);
  1809.                 opc = *((__u32 *) opcode);
  1810.                 dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1811.                 mathemu_get_user(temp, dxb);
  1812.                 /* call the emulation function */
  1813.                 _fex = ((int (*)(struct pt_regs *, int, float *))
  1814. jump_table[opcode[5]])
  1815.                         (regs, opcode[1] >> 4, (float *) &temp);
  1816.                 emu_load_regd((opcode[1] >> 4) & 15);
  1817.                 break;
  1818.         }
  1819.         case 7: /* RXE format, float constant */
  1820.                 /* store float and load long double */ 
  1821.         {
  1822.                 __u32 *dxb, temp;
  1823.                 __u32 opc;
  1824.                 if ((opcode[1] >> 4) & 0x20)
  1825. return SIGILL;
  1826.                 emu_store_rege((opcode[1] >> 4) & 15);
  1827.                 opc = *((__u32 *) opcode);
  1828.                 dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1829.                 mathemu_get_user(temp, dxb);
  1830.                 /* call the emulation function */
  1831.                 _fex = ((int (*)(struct pt_regs *, int, float *))
  1832. jump_table[opcode[5]])
  1833.                         (regs, opcode[1] >> 4, (float *) &temp);
  1834.                 emu_load_regd((opcode[1] >> 4) & 15);
  1835.                 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
  1836.                 break;
  1837.         }
  1838.         case 8: /* RXE format, RX address used as int value */ {
  1839.                 __u64 dxb;
  1840.                 __u32 opc;
  1841.                 emu_store_rege((opcode[1] >> 4) & 15);
  1842.                 opc = *((__u32 *) opcode);
  1843.                 dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1844.                 /* call the emulation function */
  1845.                 _fex = ((int (*)(struct pt_regs *, int, long))
  1846. jump_table[opcode[5]])
  1847.                         (regs, opcode[1] >> 4, dxb);
  1848.                 break;
  1849.         }
  1850.         case 9: /* RXE format, RX address used as int value */ {
  1851.                 __u64 dxb;
  1852.                 __u32 opc;
  1853.                 emu_store_regd((opcode[1] >> 4) & 15);
  1854.                 opc = *((__u32 *) opcode);
  1855.                 dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1856.                 /* call the emulation function */
  1857.                 _fex = ((int (*)(struct pt_regs *, int, long))
  1858. jump_table[opcode[5]])
  1859.                         (regs, opcode[1] >> 4, dxb);
  1860.                 break;
  1861.         }
  1862.         case 10: /* RXE format, RX address used as int value */ {
  1863.                 __u64 dxb;
  1864.                 __u32 opc;
  1865.                 if ((opcode[1] >> 4) & 2)
  1866. return SIGILL;
  1867.                 emu_store_regd((opcode[1] >> 4) & 15);
  1868.                 emu_store_regd(((opcode[1] >> 4) & 15) + 2);
  1869.                 opc = *((__u32 *) opcode);
  1870.                 dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1871.                 /* call the emulation function */
  1872.                 _fex = ((int (*)(struct pt_regs *, int, long))
  1873. jump_table[opcode[5]])
  1874.                         (regs, opcode[1] >> 4, dxb);
  1875.                 break;
  1876.         }
  1877.         default: /* invalid operation */
  1878.                 return SIGILL;
  1879.         }
  1880. if (_fex != 0) {
  1881. current->thread.fp_regs.fpc |= _fex;
  1882. if (current->thread.fp_regs.fpc & (_fex << 8))
  1883. return SIGFPE;
  1884. }
  1885. return 0;
  1886. }
  1887. /*
  1888.  * Emulate LDR Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
  1889.  */
  1890. int math_emu_ldr(__u8 *opcode) {
  1891.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  1892.         __u16 opc = *((__u16 *) opcode);
  1893.         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
  1894.                 /* we got an exception therfore ry can't be in {0,2,4,6} */
  1895.                 __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
  1896.                         "     bras  1,0fn"
  1897.                         "     ld    0,0(%1)n"
  1898.                         "0:   ex    %0,0(1)"
  1899.                         : /* no output */
  1900.                         : "a" (opc & 0xf0),
  1901.                           "a" (&fp_regs->fprs[opc & 0xf].d)
  1902.                         : "1" );
  1903.         } else if ((opc & 0x9) == 0) {     /* test if ry in {0,2,4,6} */
  1904.                 __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
  1905.                         "     bras  1,0fn"
  1906.                         "     std   0,0(%1)n"
  1907.                         "0:   ex    %0,0(1)"
  1908.                         : /* no output */
  1909.                         : "a" ((opc & 0xf) << 4),
  1910.                           "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d)
  1911.                         : "1" );
  1912.         } else  /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
  1913.                 fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
  1914. return 0;
  1915. }
  1916. /*
  1917.  * Emulate LER Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
  1918.  */
  1919. int math_emu_ler(__u8 *opcode) {
  1920.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  1921.         __u16 opc = *((__u16 *) opcode);
  1922.         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
  1923.                 /* we got an exception therfore ry can't be in {0,2,4,6} */
  1924.                 __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
  1925.                         "     bras  1,0fn"
  1926.                         "     le    0,0(%1)n"
  1927.                         "0:   ex    %0,0(1)"
  1928.                         : /* no output */
  1929.                         : "a" (opc & 0xf0),
  1930.                           "a" (&fp_regs->fprs[opc & 0xf].f)
  1931.                         : "1" );
  1932.         } else if ((opc & 0x9) == 0) {     /* test if ry in {0,2,4,6} */
  1933.                 __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
  1934.                         "     bras  1,0fn"
  1935.                         "     ste   0,0(%1)n"
  1936.                         "0:   ex    %0,0(1)"
  1937.                         : /* no output */
  1938.                         : "a" ((opc & 0xf) << 4),
  1939.                           "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f)
  1940.                         : "1" );
  1941.         } else  /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
  1942.                 fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
  1943. return 0;
  1944. }
  1945. /*
  1946.  * Emulate LD R,D(X,B) with R not in {0, 2, 4, 6}
  1947.  */
  1948. int math_emu_ld(__u8 *opcode, struct pt_regs * regs) {
  1949.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  1950.         __u32 opc = *((__u32 *) opcode);
  1951.         __u64 *dxb;
  1952.         dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1953.         mathemu_copy_from_user(&fp_regs->fprs[(opc >> 20) & 0xf].d, dxb, 8);
  1954. return 0;
  1955. }
  1956. /*
  1957.  * Emulate LE R,D(X,B) with R not in {0, 2, 4, 6}
  1958.  */
  1959. int math_emu_le(__u8 *opcode, struct pt_regs * regs) {
  1960.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  1961.         __u32 opc = *((__u32 *) opcode);
  1962.         __u32 *mem, *dxb;
  1963.         dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1964.         mem = (__u32 *) (&fp_regs->fprs[(opc >> 20) & 0xf].f);
  1965.         mathemu_get_user(mem[0], dxb);
  1966. return 0;
  1967. }
  1968. /*
  1969.  * Emulate STD R,D(X,B) with R not in {0, 2, 4, 6}
  1970.  */
  1971. int math_emu_std(__u8 *opcode, struct pt_regs * regs) {
  1972.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  1973.         __u32 opc = *((__u32 *) opcode);
  1974.         __u64 *dxb;
  1975.         dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1976.         mathemu_copy_to_user(dxb, &fp_regs->fprs[(opc >> 20) & 0xf].d, 8);
  1977. return 0;
  1978. }
  1979. /*
  1980.  * Emulate STE R,D(X,B) with R not in {0, 2, 4, 6}
  1981.  */
  1982. int math_emu_ste(__u8 *opcode, struct pt_regs * regs) {
  1983.         s390_fp_regs *fp_regs = &current->thread.fp_regs;
  1984.         __u32 opc = *((__u32 *) opcode);
  1985.         __u32 *mem, *dxb;
  1986.         dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
  1987.         mem = (__u32 *) (&fp_regs->fprs[(opc >> 20) & 0xf].f);
  1988.         mathemu_put_user(mem[0], dxb);
  1989. return 0;
  1990. }
  1991. /*
  1992.  * Emulate LFPC D(B)
  1993.  */
  1994. int math_emu_lfpc(__u8 *opcode, struct pt_regs *regs) {
  1995.         __u32 opc = *((__u32 *) opcode);
  1996.         __u32 *dxb, temp;
  1997.         dxb= (__u32 *) calc_addr(regs, 0, opc>>12, opc);
  1998.         mathemu_get_user(temp, dxb);
  1999.         if ((temp & ~FPC_VALID_MASK) != 0)
  2000. return SIGILL;
  2001. current->thread.fp_regs.fpc = temp;
  2002.         return 0;
  2003. }
  2004. /*
  2005.  * Emulate STFPC D(B)
  2006.  */
  2007. int math_emu_stfpc(__u8 *opcode, struct pt_regs *regs) {
  2008.         __u32 opc = *((__u32 *) opcode);
  2009.         __u32 *dxb;
  2010.         dxb= (__u32 *) calc_addr(regs, 0, opc>>12, opc);
  2011.         mathemu_put_user(current->thread.fp_regs.fpc, dxb);
  2012.         return 0;
  2013. }
  2014. /*
  2015.  * Emulate SRNM D(B)
  2016.  */
  2017. int math_emu_srnm(__u8 *opcode, struct pt_regs *regs) {
  2018.         __u32 opc = *((__u32 *) opcode);
  2019.         __u32 temp;
  2020.         temp = calc_addr(regs, 0, opc>>12, opc);
  2021. current->thread.fp_regs.fpc &= ~3;
  2022.         current->thread.fp_regs.fpc |= (temp & 3);
  2023.         return 0;
  2024. }
  2025. /* broken compiler ... */
  2026. long long
  2027. __negdi2 (long long u)
  2028. {
  2029.   union lll {
  2030.     long long ll;
  2031.     long s[2];
  2032.   };
  2033.   union lll w,uu;
  2034.   uu.ll = u;
  2035.   w.s[1] = -uu.s[1];
  2036.   w.s[0] = -uu.s[0] - ((int) w.s[1] != 0);
  2037.   return w.ll;
  2038. }