Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
math.c
Go to the documentation of this file.
1 /*
2  * S390 version
3  * Copyright IBM Corp. 1999, 2001
4  * Author(s): Martin Schwidefsky ([email protected]),
5  *
6  * 'math.c' emulates IEEE instructions on a S390 processor
7  * that does not have the IEEE fpu (all processors before G5).
8  */
9 
10 #include <linux/types.h>
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <asm/uaccess.h>
14 #include <asm/lowcore.h>
15 
16 #include <asm/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 /*
23  * I miss a macro to round a floating point number to the
24  * nearest integer in the same floating point format.
25  */
26 #define _FP_TO_FPINT_ROUND(fs, wc, X) \
27  do { \
28  switch (X##_c) \
29  { \
30  case FP_CLS_NORMAL: \
31  if (X##_e > _FP_FRACBITS_##fs + _FP_EXPBIAS_##fs) \
32  { /* floating point number has no bits after the dot. */ \
33  } \
34  else if (X##_e <= _FP_FRACBITS_##fs + _FP_EXPBIAS_##fs && \
35  X##_e > _FP_EXPBIAS_##fs) \
36  { /* some bits before the dot, some after it. */ \
37  _FP_FRAC_SRS_##wc(X, _FP_WFRACBITS_##fs, \
38  X##_e - _FP_EXPBIAS_##fs \
39  + _FP_FRACBITS_##fs); \
40  _FP_ROUND(wc, X); \
41  _FP_FRAC_SLL_##wc(X, X##_e - _FP_EXPBIAS_##fs \
42  + _FP_FRACBITS_##fs); \
43  } \
44  else \
45  { /* all bits after the dot. */ \
46  FP_SET_EXCEPTION(FP_EX_INEXACT); \
47  X##_c = FP_CLS_ZERO; \
48  } \
49  break; \
50  case FP_CLS_NAN: \
51  case FP_CLS_INF: \
52  case FP_CLS_ZERO: \
53  break; \
54  } \
55  } while (0)
56 
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)
60 
61 typedef union {
62  long double ld;
63  struct {
66  } w;
67 } mathemu_ldcv;
68 
69 #ifdef CONFIG_SYSCTL
71 #endif
72 
73 #define mathemu_put_user(x, p) \
74  do { \
75  if (put_user((x),(p))) \
76  return SIGSEGV; \
77  } while (0)
78 
79 #define mathemu_get_user(x, p) \
80  do { \
81  if (get_user((x),(p))) \
82  return SIGSEGV; \
83  } while (0)
84 
85 #define mathemu_copy_from_user(d, s, n)\
86  do { \
87  if (copy_from_user((d),(s),(n)) != 0) \
88  return SIGSEGV; \
89  } while (0)
90 
91 #define mathemu_copy_to_user(d, s, n) \
92  do { \
93  if (copy_to_user((d),(s),(n)) != 0) \
94  return SIGSEGV; \
95  } while (0)
96 
97 static void display_emulation_not_implemented(struct pt_regs *regs, char *instr)
98 {
99  __u16 *location;
100 
101 #ifdef CONFIG_SYSCTL
103 #endif
104  {
105  location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
106  printk("%s ieee fpu instruction not emulated "
107  "process name: %s pid: %d \n",
108  instr, current->comm, current->pid);
109  printk("%s's PSW: %08lx %08lx\n", instr,
110  (unsigned long) regs->psw.mask,
111  (unsigned long) location);
112  }
113 }
114 
115 static inline void emu_set_CC (struct pt_regs *regs, int cc)
116 {
117  regs->psw.mask = (regs->psw.mask & 0xFFFFCFFF) | ((cc&3) << 12);
118 }
119 
120 /*
121  * Set the condition code in the user psw.
122  * 0 : Result is zero
123  * 1 : Result is less than zero
124  * 2 : Result is greater than zero
125  * 3 : Result is NaN or INF
126  */
127 static inline void emu_set_CC_cs(struct pt_regs *regs, int class, int sign)
128 {
129  switch (class) {
130  case FP_CLS_NORMAL:
131  case FP_CLS_INF:
132  emu_set_CC(regs, sign ? 1 : 2);
133  break;
134  case FP_CLS_ZERO:
135  emu_set_CC(regs, 0);
136  break;
137  case FP_CLS_NAN:
138  emu_set_CC(regs, 3);
139  break;
140  }
141 }
142 
143 /* Add long double */
144 static int emu_axbr (struct pt_regs *regs, int rx, int ry) {
145  FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
146  FP_DECL_EX;
148  int mode;
149 
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;
153  FP_UNPACK_QP(QA, &cvt.ld);
154  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
155  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
156  FP_UNPACK_QP(QB, &cvt.ld);
157  FP_ADD_Q(QR, QA, QB);
158  FP_PACK_QP(&cvt.ld, QR);
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);
162  return _fex;
163 }
164 
165 /* Add double */
166 static int emu_adbr (struct pt_regs *regs, int rx, int ry) {
168  FP_DECL_EX;
169  int mode;
170 
171  mode = current->thread.fp_regs.fpc & 3;
172  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
173  FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
174  FP_ADD_D(DR, DA, DB);
175  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
176  emu_set_CC_cs(regs, DR_c, DR_s);
177  return _fex;
178 }
179 
180 /* Add double */
181 static int emu_adb (struct pt_regs *regs, int rx, double *val) {
183  FP_DECL_EX;
184  int mode;
185 
186  mode = current->thread.fp_regs.fpc & 3;
187  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
188  FP_UNPACK_DP(DB, val);
189  FP_ADD_D(DR, DA, DB);
190  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
191  emu_set_CC_cs(regs, DR_c, DR_s);
192  return _fex;
193 }
194 
195 /* Add float */
196 static int emu_aebr (struct pt_regs *regs, int rx, int ry) {
198  FP_DECL_EX;
199  int mode;
200 
201  mode = current->thread.fp_regs.fpc & 3;
202  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
203  FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
204  FP_ADD_S(SR, SA, SB);
205  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
206  emu_set_CC_cs(regs, SR_c, SR_s);
207  return _fex;
208 }
209 
210 /* Add float */
211 static int emu_aeb (struct pt_regs *regs, int rx, float *val) {
213  FP_DECL_EX;
214  int mode;
215 
216  mode = current->thread.fp_regs.fpc & 3;
217  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
218  FP_UNPACK_SP(SB, val);
219  FP_ADD_S(SR, SA, SB);
220  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
221  emu_set_CC_cs(regs, SR_c, SR_s);
222  return _fex;
223 }
224 
225 /* Compare long double */
226 static int emu_cxbr (struct pt_regs *regs, int rx, int ry) {
227  FP_DECL_Q(QA); FP_DECL_Q(QB);
229  int IR;
230 
231  cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
232  cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
233  FP_UNPACK_RAW_QP(QA, &cvt.ld);
234  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
235  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
236  FP_UNPACK_RAW_QP(QB, &cvt.ld);
237  FP_CMP_Q(IR, QA, QB, 3);
238  /*
239  * IR == -1 if DA < DB, IR == 0 if DA == DB,
240  * IR == 1 if DA > DB and IR == 3 if unorderded
241  */
242  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
243  return 0;
244 }
245 
246 /* Compare double */
247 static int emu_cdbr (struct pt_regs *regs, int rx, int ry) {
249  int IR;
250 
251  FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
252  FP_UNPACK_RAW_DP(DB, &current->thread.fp_regs.fprs[ry].d);
253  FP_CMP_D(IR, DA, DB, 3);
254  /*
255  * IR == -1 if DA < DB, IR == 0 if DA == DB,
256  * IR == 1 if DA > DB and IR == 3 if unorderded
257  */
258  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
259  return 0;
260 }
261 
262 /* Compare double */
263 static int emu_cdb (struct pt_regs *regs, int rx, double *val) {
265  int IR;
266 
267  FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
268  FP_UNPACK_RAW_DP(DB, val);
269  FP_CMP_D(IR, DA, DB, 3);
270  /*
271  * IR == -1 if DA < DB, IR == 0 if DA == DB,
272  * IR == 1 if DA > DB and IR == 3 if unorderded
273  */
274  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
275  return 0;
276 }
277 
278 /* Compare float */
279 static int emu_cebr (struct pt_regs *regs, int rx, int ry) {
281  int IR;
282 
283  FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
284  FP_UNPACK_RAW_SP(SB, &current->thread.fp_regs.fprs[ry].f);
285  FP_CMP_S(IR, SA, SB, 3);
286  /*
287  * IR == -1 if DA < DB, IR == 0 if DA == DB,
288  * IR == 1 if DA > DB and IR == 3 if unorderded
289  */
290  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
291  return 0;
292 }
293 
294 /* Compare float */
295 static int emu_ceb (struct pt_regs *regs, int rx, float *val) {
297  int IR;
298 
299  FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
300  FP_UNPACK_RAW_SP(SB, val);
301  FP_CMP_S(IR, SA, SB, 3);
302  /*
303  * IR == -1 if DA < DB, IR == 0 if DA == DB,
304  * IR == 1 if DA > DB and IR == 3 if unorderded
305  */
306  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
307  return 0;
308 }
309 
310 /* Compare and signal long double */
311 static int emu_kxbr (struct pt_regs *regs, int rx, int ry) {
312  FP_DECL_Q(QA); FP_DECL_Q(QB);
313  FP_DECL_EX;
315  int IR;
316 
317  cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
318  cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
319  FP_UNPACK_RAW_QP(QA, &cvt.ld);
320  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
321  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
322  FP_UNPACK_QP(QB, &cvt.ld);
323  FP_CMP_Q(IR, QA, QB, 3);
324  /*
325  * IR == -1 if DA < DB, IR == 0 if DA == DB,
326  * IR == 1 if DA > DB and IR == 3 if unorderded
327  */
328  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
329  if (IR == 3)
331  return _fex;
332 }
333 
334 /* Compare and signal double */
335 static int emu_kdbr (struct pt_regs *regs, int rx, int ry) {
337  FP_DECL_EX;
338  int IR;
339 
340  FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
341  FP_UNPACK_RAW_DP(DB, &current->thread.fp_regs.fprs[ry].d);
342  FP_CMP_D(IR, DA, DB, 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)
350  return _fex;
351 }
352 
353 /* Compare and signal double */
354 static int emu_kdb (struct pt_regs *regs, int rx, double *val) {
356  FP_DECL_EX;
357  int IR;
358 
359  FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
360  FP_UNPACK_RAW_DP(DB, val);
361  FP_CMP_D(IR, DA, DB, 3);
362  /*
363  * IR == -1 if DA < DB, IR == 0 if DA == DB,
364  * IR == 1 if DA > DB and IR == 3 if unorderded
365  */
366  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
367  if (IR == 3)
369  return _fex;
370 }
371 
372 /* Compare and signal float */
373 static int emu_kebr (struct pt_regs *regs, int rx, int ry) {
375  FP_DECL_EX;
376  int IR;
377 
378  FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
379  FP_UNPACK_RAW_SP(SB, &current->thread.fp_regs.fprs[ry].f);
380  FP_CMP_S(IR, SA, SB, 3);
381  /*
382  * IR == -1 if DA < DB, IR == 0 if DA == DB,
383  * IR == 1 if DA > DB and IR == 3 if unorderded
384  */
385  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
386  if (IR == 3)
388  return _fex;
389 }
390 
391 /* Compare and signal float */
392 static int emu_keb (struct pt_regs *regs, int rx, float *val) {
394  FP_DECL_EX;
395  int IR;
396 
397  FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
398  FP_UNPACK_RAW_SP(SB, val);
399  FP_CMP_S(IR, SA, SB, 3);
400  /*
401  * IR == -1 if DA < DB, IR == 0 if DA == DB,
402  * IR == 1 if DA > DB and IR == 3 if unorderded
403  */
404  emu_set_CC(regs, (IR == -1) ? 1 : (IR == 1) ? 2 : IR);
405  if (IR == 3)
407  return _fex;
408 }
409 
410 /* Convert from fixed long double */
411 static int emu_cxfbr (struct pt_regs *regs, int rx, int ry) {
412  FP_DECL_Q(QR);
413  FP_DECL_EX;
415  __s32 si;
416  int mode;
417 
418  mode = current->thread.fp_regs.fpc & 3;
419  si = regs->gprs[ry];
420  FP_FROM_INT_Q(QR, si, 32, int);
421  FP_PACK_QP(&cvt.ld, QR);
422  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
423  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
424  return _fex;
425 }
426 
427 /* Convert from fixed double */
428 static int emu_cdfbr (struct pt_regs *regs, int rx, int ry) {
429  FP_DECL_D(DR);
430  FP_DECL_EX;
431  __s32 si;
432  int mode;
433 
434  mode = current->thread.fp_regs.fpc & 3;
435  si = regs->gprs[ry];
436  FP_FROM_INT_D(DR, si, 32, int);
437  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
438  return _fex;
439 }
440 
441 /* Convert from fixed float */
442 static int emu_cefbr (struct pt_regs *regs, int rx, int ry) {
443  FP_DECL_S(SR);
444  FP_DECL_EX;
445  __s32 si;
446  int mode;
447 
448  mode = current->thread.fp_regs.fpc & 3;
449  si = regs->gprs[ry];
450  FP_FROM_INT_S(SR, si, 32, int);
451  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
452  return _fex;
453 }
454 
455 /* Convert to fixed long double */
456 static int emu_cfxbr (struct pt_regs *regs, int rx, int ry, int mask) {
457  FP_DECL_Q(QA);
458  FP_DECL_EX;
460  __s32 si;
461  int mode;
462 
463  if (mask == 0)
464  mode = current->thread.fp_regs.fpc & 3;
465  else if (mask == 1)
466  mode = FP_RND_NEAREST;
467  else
468  mode = mask - 4;
469  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
470  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
471  FP_UNPACK_QP(QA, &cvt.ld);
472  FP_TO_INT_ROUND_Q(si, QA, 32, 1);
473  regs->gprs[rx] = si;
474  emu_set_CC_cs(regs, QA_c, QA_s);
475  return _fex;
476 }
477 
478 /* Convert to fixed double */
479 static int emu_cfdbr (struct pt_regs *regs, int rx, int ry, int mask) {
480  FP_DECL_D(DA);
481  FP_DECL_EX;
482  __s32 si;
483  int mode;
484 
485  if (mask == 0)
486  mode = current->thread.fp_regs.fpc & 3;
487  else if (mask == 1)
488  mode = FP_RND_NEAREST;
489  else
490  mode = mask - 4;
491  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
492  FP_TO_INT_ROUND_D(si, DA, 32, 1);
493  regs->gprs[rx] = si;
494  emu_set_CC_cs(regs, DA_c, DA_s);
495  return _fex;
496 }
497 
498 /* Convert to fixed float */
499 static int emu_cfebr (struct pt_regs *regs, int rx, int ry, int mask) {
500  FP_DECL_S(SA);
501  FP_DECL_EX;
502  __s32 si;
503  int mode;
504 
505  if (mask == 0)
506  mode = current->thread.fp_regs.fpc & 3;
507  else if (mask == 1)
508  mode = FP_RND_NEAREST;
509  else
510  mode = mask - 4;
511  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
512  FP_TO_INT_ROUND_S(si, SA, 32, 1);
513  regs->gprs[rx] = si;
514  emu_set_CC_cs(regs, SA_c, SA_s);
515  return _fex;
516 }
517 
518 /* Divide long double */
519 static int emu_dxbr (struct pt_regs *regs, int rx, int ry) {
520  FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
521  FP_DECL_EX;
523  int mode;
524 
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;
528  FP_UNPACK_QP(QA, &cvt.ld);
529  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
530  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
531  FP_UNPACK_QP(QB, &cvt.ld);
532  FP_DIV_Q(QR, QA, QB);
533  FP_PACK_QP(&cvt.ld, QR);
534  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
535  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
536  return _fex;
537 }
538 
539 /* Divide double */
540 static int emu_ddbr (struct pt_regs *regs, int rx, int ry) {
542  FP_DECL_EX;
543  int mode;
544 
545  mode = current->thread.fp_regs.fpc & 3;
546  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
547  FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
548  FP_DIV_D(DR, DA, DB);
549  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
550  return _fex;
551 }
552 
553 /* Divide double */
554 static int emu_ddb (struct pt_regs *regs, int rx, double *val) {
556  FP_DECL_EX;
557  int mode;
558 
559  mode = current->thread.fp_regs.fpc & 3;
560  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
561  FP_UNPACK_DP(DB, val);
562  FP_DIV_D(DR, DA, DB);
563  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
564  return _fex;
565 }
566 
567 /* Divide float */
568 static int emu_debr (struct pt_regs *regs, int rx, int ry) {
570  FP_DECL_EX;
571  int mode;
572 
573  mode = current->thread.fp_regs.fpc & 3;
574  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
575  FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
576  FP_DIV_S(SR, SA, SB);
577  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
578  return _fex;
579 }
580 
581 /* Divide float */
582 static int emu_deb (struct pt_regs *regs, int rx, float *val) {
584  FP_DECL_EX;
585  int mode;
586 
587  mode = current->thread.fp_regs.fpc & 3;
588  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
589  FP_UNPACK_SP(SB, val);
590  FP_DIV_S(SR, SA, SB);
591  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
592  return _fex;
593 }
594 
595 /* Divide to integer double */
596 static int emu_didbr (struct pt_regs *regs, int rx, int ry, int mask) {
597  display_emulation_not_implemented(regs, "didbr");
598  return 0;
599 }
600 
601 /* Divide to integer float */
602 static int emu_diebr (struct pt_regs *regs, int rx, int ry, int mask) {
603  display_emulation_not_implemented(regs, "diebr");
604  return 0;
605 }
606 
607 /* Extract fpc */
608 static int emu_efpc (struct pt_regs *regs, int rx, int ry) {
609  regs->gprs[rx] = current->thread.fp_regs.fpc;
610  return 0;
611 }
612 
613 /* Load and test long double */
614 static int emu_ltxbr (struct pt_regs *regs, int rx, int ry) {
615  s390_fp_regs *fp_regs = &current->thread.fp_regs;
617  FP_DECL_Q(QA);
618  FP_DECL_EX;
619 
620  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
621  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
622  FP_UNPACK_QP(QA, &cvt.ld);
623  fp_regs->fprs[rx].ui = fp_regs->fprs[ry].ui;
624  fp_regs->fprs[rx+2].ui = fp_regs->fprs[ry+2].ui;
625  emu_set_CC_cs(regs, QA_c, QA_s);
626  return _fex;
627 }
628 
629 /* Load and test double */
630 static int emu_ltdbr (struct pt_regs *regs, int rx, int ry) {
631  s390_fp_regs *fp_regs = &current->thread.fp_regs;
632  FP_DECL_D(DA);
633  FP_DECL_EX;
634 
635  FP_UNPACK_DP(DA, &fp_regs->fprs[ry].d);
636  fp_regs->fprs[rx].ui = fp_regs->fprs[ry].ui;
637  emu_set_CC_cs(regs, DA_c, DA_s);
638  return _fex;
639 }
640 
641 /* Load and test double */
642 static int emu_ltebr (struct pt_regs *regs, int rx, int ry) {
643  s390_fp_regs *fp_regs = &current->thread.fp_regs;
644  FP_DECL_S(SA);
645  FP_DECL_EX;
646 
647  FP_UNPACK_SP(SA, &fp_regs->fprs[ry].f);
648  fp_regs->fprs[rx].ui = fp_regs->fprs[ry].ui;
649  emu_set_CC_cs(regs, SA_c, SA_s);
650  return _fex;
651 }
652 
653 /* Load complement long double */
654 static int emu_lcxbr (struct pt_regs *regs, int rx, int ry) {
655  FP_DECL_Q(QA); FP_DECL_Q(QR);
656  FP_DECL_EX;
658  int mode;
659 
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;
663  FP_UNPACK_QP(QA, &cvt.ld);
664  FP_NEG_Q(QR, QA);
665  FP_PACK_QP(&cvt.ld, QR);
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);
669  return _fex;
670 }
671 
672 /* Load complement double */
673 static int emu_lcdbr (struct pt_regs *regs, int rx, int ry) {
675  FP_DECL_EX;
676  int mode;
677 
678  mode = current->thread.fp_regs.fpc & 3;
679  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
680  FP_NEG_D(DR, DA);
681  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
682  emu_set_CC_cs(regs, DR_c, DR_s);
683  return _fex;
684 }
685 
686 /* Load complement float */
687 static int emu_lcebr (struct pt_regs *regs, int rx, int ry) {
689  FP_DECL_EX;
690  int mode;
691 
692  mode = current->thread.fp_regs.fpc & 3;
693  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
694  FP_NEG_S(SR, SA);
695  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
696  emu_set_CC_cs(regs, SR_c, SR_s);
697  return _fex;
698 }
699 
700 /* Load floating point integer long double */
701 static int emu_fixbr (struct pt_regs *regs, int rx, int ry, int mask) {
702  s390_fp_regs *fp_regs = &current->thread.fp_regs;
703  FP_DECL_Q(QA);
704  FP_DECL_EX;
706  __s32 si;
707  int mode;
708 
709  if (mask == 0)
710  mode = fp_regs->fpc & 3;
711  else if (mask == 1)
712  mode = FP_RND_NEAREST;
713  else
714  mode = mask - 4;
715  cvt.w.high = fp_regs->fprs[ry].ui;
716  cvt.w.low = fp_regs->fprs[ry+2].ui;
717  FP_UNPACK_QP(QA, &cvt.ld);
719  FP_PACK_QP(&cvt.ld, QA);
720  fp_regs->fprs[rx].ui = cvt.w.high;
721  fp_regs->fprs[rx+2].ui = cvt.w.low;
722  return _fex;
723 }
724 
725 /* Load floating point integer double */
726 static int emu_fidbr (struct pt_regs *regs, int rx, int ry, int mask) {
727  /* FIXME: rounding mode !! */
728  s390_fp_regs *fp_regs = &current->thread.fp_regs;
729  FP_DECL_D(DA);
730  FP_DECL_EX;
731  __s32 si;
732  int mode;
733 
734  if (mask == 0)
735  mode = fp_regs->fpc & 3;
736  else if (mask == 1)
737  mode = FP_RND_NEAREST;
738  else
739  mode = mask - 4;
740  FP_UNPACK_DP(DA, &fp_regs->fprs[ry].d);
742  FP_PACK_DP(&fp_regs->fprs[rx].d, DA);
743  return _fex;
744 }
745 
746 /* Load floating point integer float */
747 static int emu_fiebr (struct pt_regs *regs, int rx, int ry, int mask) {
748  s390_fp_regs *fp_regs = &current->thread.fp_regs;
749  FP_DECL_S(SA);
750  FP_DECL_EX;
751  __s32 si;
752  int mode;
753 
754  if (mask == 0)
755  mode = fp_regs->fpc & 3;
756  else if (mask == 1)
757  mode = FP_RND_NEAREST;
758  else
759  mode = mask - 4;
760  FP_UNPACK_SP(SA, &fp_regs->fprs[ry].f);
762  FP_PACK_SP(&fp_regs->fprs[rx].f, SA);
763  return _fex;
764 }
765 
766 /* Load lengthened double to long double */
767 static int emu_lxdbr (struct pt_regs *regs, int rx, int ry) {
768  FP_DECL_D(DA); FP_DECL_Q(QR);
769  FP_DECL_EX;
771  int mode;
772 
773  mode = current->thread.fp_regs.fpc & 3;
774  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
775  FP_CONV (Q, D, 4, 2, QR, DA);
776  FP_PACK_QP(&cvt.ld, QR);
777  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
778  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
779  return _fex;
780 }
781 
782 /* Load lengthened double to long double */
783 static int emu_lxdb (struct pt_regs *regs, int rx, double *val) {
784  FP_DECL_D(DA); FP_DECL_Q(QR);
785  FP_DECL_EX;
787  int mode;
788 
789  mode = current->thread.fp_regs.fpc & 3;
790  FP_UNPACK_DP(DA, val);
791  FP_CONV (Q, D, 4, 2, QR, DA);
792  FP_PACK_QP(&cvt.ld, QR);
793  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
794  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
795  return _fex;
796 }
797 
798 /* Load lengthened float to long double */
799 static int emu_lxebr (struct pt_regs *regs, int rx, int ry) {
800  FP_DECL_S(SA); FP_DECL_Q(QR);
801  FP_DECL_EX;
803  int mode;
804 
805  mode = current->thread.fp_regs.fpc & 3;
806  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
807  FP_CONV (Q, S, 4, 1, QR, SA);
808  FP_PACK_QP(&cvt.ld, QR);
809  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
810  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
811  return _fex;
812 }
813 
814 /* Load lengthened float to long double */
815 static int emu_lxeb (struct pt_regs *regs, int rx, float *val) {
816  FP_DECL_S(SA); FP_DECL_Q(QR);
817  FP_DECL_EX;
819  int mode;
820 
821  mode = current->thread.fp_regs.fpc & 3;
822  FP_UNPACK_SP(SA, val);
823  FP_CONV (Q, S, 4, 1, QR, SA);
824  FP_PACK_QP(&cvt.ld, QR);
825  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
826  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
827  return _fex;
828 }
829 
830 /* Load lengthened float to double */
831 static int emu_ldebr (struct pt_regs *regs, int rx, int ry) {
833  FP_DECL_EX;
834  int mode;
835 
836  mode = current->thread.fp_regs.fpc & 3;
837  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
838  FP_CONV (D, S, 2, 1, DR, SA);
839  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
840  return _fex;
841 }
842 
843 /* Load lengthened float to double */
844 static int emu_ldeb (struct pt_regs *regs, int rx, float *val) {
846  FP_DECL_EX;
847  int mode;
848 
849  mode = current->thread.fp_regs.fpc & 3;
850  FP_UNPACK_SP(SA, val);
851  FP_CONV (D, S, 2, 1, DR, SA);
852  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
853  return _fex;
854 }
855 
856 /* Load negative long double */
857 static int emu_lnxbr (struct pt_regs *regs, int rx, int ry) {
858  FP_DECL_Q(QA); FP_DECL_Q(QR);
859  FP_DECL_EX;
861  int mode;
862 
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;
866  FP_UNPACK_QP(QA, &cvt.ld);
867  if (QA_s == 0) {
868  FP_NEG_Q(QR, QA);
869  FP_PACK_QP(&cvt.ld, QR);
870  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
871  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
872  } else {
873  current->thread.fp_regs.fprs[rx].ui =
874  current->thread.fp_regs.fprs[ry].ui;
875  current->thread.fp_regs.fprs[rx+2].ui =
876  current->thread.fp_regs.fprs[ry+2].ui;
877  }
878  emu_set_CC_cs(regs, QR_c, QR_s);
879  return _fex;
880 }
881 
882 /* Load negative double */
883 static int emu_lndbr (struct pt_regs *regs, int rx, int ry) {
885  FP_DECL_EX;
886  int mode;
887 
888  mode = current->thread.fp_regs.fpc & 3;
889  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
890  if (DA_s == 0) {
891  FP_NEG_D(DR, DA);
892  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
893  } else
894  current->thread.fp_regs.fprs[rx].ui =
895  current->thread.fp_regs.fprs[ry].ui;
896  emu_set_CC_cs(regs, DR_c, DR_s);
897  return _fex;
898 }
899 
900 /* Load negative float */
901 static int emu_lnebr (struct pt_regs *regs, int rx, int ry) {
903  FP_DECL_EX;
904  int mode;
905 
906  mode = current->thread.fp_regs.fpc & 3;
907  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
908  if (SA_s == 0) {
909  FP_NEG_S(SR, SA);
910  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
911  } else
912  current->thread.fp_regs.fprs[rx].ui =
913  current->thread.fp_regs.fprs[ry].ui;
914  emu_set_CC_cs(regs, SR_c, SR_s);
915  return _fex;
916 }
917 
918 /* Load positive long double */
919 static int emu_lpxbr (struct pt_regs *regs, int rx, int ry) {
920  FP_DECL_Q(QA); FP_DECL_Q(QR);
921  FP_DECL_EX;
923  int mode;
924 
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;
928  FP_UNPACK_QP(QA, &cvt.ld);
929  if (QA_s != 0) {
930  FP_NEG_Q(QR, QA);
931  FP_PACK_QP(&cvt.ld, QR);
932  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
933  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
934  } else{
935  current->thread.fp_regs.fprs[rx].ui =
936  current->thread.fp_regs.fprs[ry].ui;
937  current->thread.fp_regs.fprs[rx+2].ui =
938  current->thread.fp_regs.fprs[ry+2].ui;
939  }
940  emu_set_CC_cs(regs, QR_c, QR_s);
941  return _fex;
942 }
943 
944 /* Load positive double */
945 static int emu_lpdbr (struct pt_regs *regs, int rx, int ry) {
947  FP_DECL_EX;
948  int mode;
949 
950  mode = current->thread.fp_regs.fpc & 3;
951  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
952  if (DA_s != 0) {
953  FP_NEG_D(DR, DA);
954  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
955  } else
956  current->thread.fp_regs.fprs[rx].ui =
957  current->thread.fp_regs.fprs[ry].ui;
958  emu_set_CC_cs(regs, DR_c, DR_s);
959  return _fex;
960 }
961 
962 /* Load positive float */
963 static int emu_lpebr (struct pt_regs *regs, int rx, int ry) {
965  FP_DECL_EX;
966  int mode;
967 
968  mode = current->thread.fp_regs.fpc & 3;
969  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
970  if (SA_s != 0) {
971  FP_NEG_S(SR, SA);
972  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
973  } else
974  current->thread.fp_regs.fprs[rx].ui =
975  current->thread.fp_regs.fprs[ry].ui;
976  emu_set_CC_cs(regs, SR_c, SR_s);
977  return _fex;
978 }
979 
980 /* Load rounded long double to double */
981 static int emu_ldxbr (struct pt_regs *regs, int rx, int ry) {
982  FP_DECL_Q(QA); FP_DECL_D(DR);
983  FP_DECL_EX;
985  int mode;
986 
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;
990  FP_UNPACK_QP(QA, &cvt.ld);
991  FP_CONV (D, Q, 2, 4, DR, QA);
992  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].f, DR);
993  return _fex;
994 }
995 
996 /* Load rounded long double to float */
997 static int emu_lexbr (struct pt_regs *regs, int rx, int ry) {
998  FP_DECL_Q(QA); FP_DECL_S(SR);
999  FP_DECL_EX;
1000  mathemu_ldcv cvt;
1001  int mode;
1002 
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;
1006  FP_UNPACK_QP(QA, &cvt.ld);
1007  FP_CONV (S, Q, 1, 4, SR, QA);
1008  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1009  return _fex;
1010 }
1011 
1012 /* Load rounded double to float */
1013 static int emu_ledbr (struct pt_regs *regs, int rx, int ry) {
1014  FP_DECL_D(DA); FP_DECL_S(SR);
1015  FP_DECL_EX;
1016  int mode;
1017 
1018  mode = current->thread.fp_regs.fpc & 3;
1019  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
1020  FP_CONV (S, D, 1, 2, SR, DA);
1021  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1022  return _fex;
1023 }
1024 
1025 /* Multiply long double */
1026 static int emu_mxbr (struct pt_regs *regs, int rx, int ry) {
1027  FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
1028  FP_DECL_EX;
1029  mathemu_ldcv cvt;
1030  int mode;
1031 
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;
1035  FP_UNPACK_QP(QA, &cvt.ld);
1036  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
1037  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
1038  FP_UNPACK_QP(QB, &cvt.ld);
1039  FP_MUL_Q(QR, QA, QB);
1040  FP_PACK_QP(&cvt.ld, QR);
1041  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
1042  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
1043  return _fex;
1044 }
1045 
1046 /* Multiply double */
1047 static int emu_mdbr (struct pt_regs *regs, int rx, int ry) {
1049  FP_DECL_EX;
1050  int mode;
1051 
1052  mode = current->thread.fp_regs.fpc & 3;
1053  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1054  FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
1055  FP_MUL_D(DR, DA, DB);
1056  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1057  return _fex;
1058 }
1059 
1060 /* Multiply double */
1061 static int emu_mdb (struct pt_regs *regs, int rx, double *val) {
1063  FP_DECL_EX;
1064  int mode;
1065 
1066  mode = current->thread.fp_regs.fpc & 3;
1067  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1068  FP_UNPACK_DP(DB, val);
1069  FP_MUL_D(DR, DA, DB);
1070  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1071  return _fex;
1072 }
1073 
1074 /* Multiply double to long double */
1075 static int emu_mxdbr (struct pt_regs *regs, int rx, int ry) {
1076  FP_DECL_D(DA); FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
1077  FP_DECL_EX;
1078  mathemu_ldcv cvt;
1079  int mode;
1080 
1081  mode = current->thread.fp_regs.fpc & 3;
1082  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1083  FP_CONV (Q, D, 4, 2, QA, DA);
1084  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
1085  FP_CONV (Q, D, 4, 2, QB, DA);
1086  FP_MUL_Q(QR, QA, QB);
1087  FP_PACK_QP(&cvt.ld, QR);
1088  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
1089  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
1090  return _fex;
1091 }
1092 
1093 /* Multiply double to long double */
1094 static int emu_mxdb (struct pt_regs *regs, int rx, long double *val) {
1095  FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
1096  FP_DECL_EX;
1097  mathemu_ldcv cvt;
1098  int mode;
1099 
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;
1103  FP_UNPACK_QP(QA, &cvt.ld);
1104  FP_UNPACK_QP(QB, val);
1105  FP_MUL_Q(QR, QA, QB);
1106  FP_PACK_QP(&cvt.ld, QR);
1107  current->thread.fp_regs.fprs[rx].ui = cvt.w.high;
1108  current->thread.fp_regs.fprs[rx+2].ui = cvt.w.low;
1109  return _fex;
1110 }
1111 
1112 /* Multiply float */
1113 static int emu_meebr (struct pt_regs *regs, int rx, int ry) {
1115  FP_DECL_EX;
1116  int mode;
1117 
1118  mode = current->thread.fp_regs.fpc & 3;
1119  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1120  FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
1121  FP_MUL_S(SR, SA, SB);
1122  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1123  return _fex;
1124 }
1125 
1126 /* Multiply float */
1127 static int emu_meeb (struct pt_regs *regs, int rx, float *val) {
1129  FP_DECL_EX;
1130  int mode;
1131 
1132  mode = current->thread.fp_regs.fpc & 3;
1133  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1134  FP_UNPACK_SP(SB, val);
1135  FP_MUL_S(SR, SA, SB);
1136  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1137  return _fex;
1138 }
1139 
1140 /* Multiply float to double */
1141 static int emu_mdebr (struct pt_regs *regs, int rx, int ry) {
1143  FP_DECL_EX;
1144  int mode;
1145 
1146  mode = current->thread.fp_regs.fpc & 3;
1147  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1148  FP_CONV (D, S, 2, 1, DA, SA);
1149  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
1150  FP_CONV (D, S, 2, 1, DB, SA);
1151  FP_MUL_D(DR, DA, DB);
1152  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1153  return _fex;
1154 }
1155 
1156 /* Multiply float to double */
1157 static int emu_mdeb (struct pt_regs *regs, int rx, float *val) {
1159  FP_DECL_EX;
1160  int mode;
1161 
1162  mode = current->thread.fp_regs.fpc & 3;
1163  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1164  FP_CONV (D, S, 2, 1, DA, SA);
1165  FP_UNPACK_SP(SA, val);
1166  FP_CONV (D, S, 2, 1, DB, SA);
1167  FP_MUL_D(DR, DA, DB);
1168  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1169  return _fex;
1170 }
1171 
1172 /* Multiply and add double */
1173 static int emu_madbr (struct pt_regs *regs, int rx, int ry, int rz) {
1175  FP_DECL_EX;
1176  int mode;
1177 
1178  mode = current->thread.fp_regs.fpc & 3;
1179  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1180  FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
1181  FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
1182  FP_MUL_D(DR, DA, DB);
1183  FP_ADD_D(DR, DR, DC);
1184  FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
1185  return _fex;
1186 }
1187 
1188 /* Multiply and add double */
1189 static int emu_madb (struct pt_regs *regs, int rx, double *val, int rz) {
1191  FP_DECL_EX;
1192  int mode;
1193 
1194  mode = current->thread.fp_regs.fpc & 3;
1195  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1196  FP_UNPACK_DP(DB, val);
1197  FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
1198  FP_MUL_D(DR, DA, DB);
1199  FP_ADD_D(DR, DR, DC);
1200  FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
1201  return _fex;
1202 }
1203 
1204 /* Multiply and add float */
1205 static int emu_maebr (struct pt_regs *regs, int rx, int ry, int rz) {
1207  FP_DECL_EX;
1208  int mode;
1209 
1210  mode = current->thread.fp_regs.fpc & 3;
1211  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1212  FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
1213  FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
1214  FP_MUL_S(SR, SA, SB);
1215  FP_ADD_S(SR, SR, SC);
1216  FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
1217  return _fex;
1218 }
1219 
1220 /* Multiply and add float */
1221 static int emu_maeb (struct pt_regs *regs, int rx, float *val, int rz) {
1223  FP_DECL_EX;
1224  int mode;
1225 
1226  mode = current->thread.fp_regs.fpc & 3;
1227  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1228  FP_UNPACK_SP(SB, val);
1229  FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
1230  FP_MUL_S(SR, SA, SB);
1231  FP_ADD_S(SR, SR, SC);
1232  FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
1233  return _fex;
1234 }
1235 
1236 /* Multiply and subtract double */
1237 static int emu_msdbr (struct pt_regs *regs, int rx, int ry, int rz) {
1239  FP_DECL_EX;
1240  int mode;
1241 
1242  mode = current->thread.fp_regs.fpc & 3;
1243  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1244  FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
1245  FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
1246  FP_MUL_D(DR, DA, DB);
1247  FP_SUB_D(DR, DR, DC);
1248  FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
1249  return _fex;
1250 }
1251 
1252 /* Multiply and subtract double */
1253 static int emu_msdb (struct pt_regs *regs, int rx, double *val, int rz) {
1255  FP_DECL_EX;
1256  int mode;
1257 
1258  mode = current->thread.fp_regs.fpc & 3;
1259  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1260  FP_UNPACK_DP(DB, val);
1261  FP_UNPACK_DP(DC, &current->thread.fp_regs.fprs[rz].d);
1262  FP_MUL_D(DR, DA, DB);
1263  FP_SUB_D(DR, DR, DC);
1264  FP_PACK_DP(&current->thread.fp_regs.fprs[rz].d, DR);
1265  return _fex;
1266 }
1267 
1268 /* Multiply and subtract float */
1269 static int emu_msebr (struct pt_regs *regs, int rx, int ry, int rz) {
1271  FP_DECL_EX;
1272  int mode;
1273 
1274  mode = current->thread.fp_regs.fpc & 3;
1275  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1276  FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
1277  FP_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
1278  FP_MUL_S(SR, SA, SB);
1279  FP_SUB_S(SR, SR, SC);
1280  FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
1281  return _fex;
1282 }
1283 
1284 /* Multiply and subtract float */
1285 static int emu_mseb (struct pt_regs *regs, int rx, float *val, int rz) {
1287  FP_DECL_EX;
1288  int mode;
1289 
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_UNPACK_SP(SC, &current->thread.fp_regs.fprs[rz].f);
1294  FP_MUL_S(SR, SA, SB);
1295  FP_SUB_S(SR, SR, SC);
1296  FP_PACK_SP(&current->thread.fp_regs.fprs[rz].f, SR);
1297  return _fex;
1298 }
1299 
1300 /* Set floating point control word */
1301 static int emu_sfpc (struct pt_regs *regs, int rx, int ry) {
1302  __u32 temp;
1303 
1304  temp = regs->gprs[rx];
1305  if ((temp & ~FPC_VALID_MASK) != 0)
1306  return SIGILL;
1307  current->thread.fp_regs.fpc = temp;
1308  return 0;
1309 }
1310 
1311 /* Square root long double */
1312 static int emu_sqxbr (struct pt_regs *regs, int rx, int ry) {
1313  FP_DECL_Q(QA); FP_DECL_Q(QR);
1314  FP_DECL_EX;
1315  mathemu_ldcv cvt;
1316  int mode;
1317 
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;
1321  FP_UNPACK_QP(QA, &cvt.ld);
1322  FP_SQRT_Q(QR, QA);
1323  FP_PACK_QP(&cvt.ld, QR);
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);
1327  return _fex;
1328 }
1329 
1330 /* Square root double */
1331 static int emu_sqdbr (struct pt_regs *regs, int rx, int ry) {
1332  FP_DECL_D(DA); FP_DECL_D(DR);
1333  FP_DECL_EX;
1334  int mode;
1335 
1336  mode = current->thread.fp_regs.fpc & 3;
1337  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[ry].d);
1338  FP_SQRT_D(DR, DA);
1339  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1340  emu_set_CC_cs(regs, DR_c, DR_s);
1341  return _fex;
1342 }
1343 
1344 /* Square root double */
1345 static int emu_sqdb (struct pt_regs *regs, int rx, double *val) {
1346  FP_DECL_D(DA); FP_DECL_D(DR);
1347  FP_DECL_EX;
1348  int mode;
1349 
1350  mode = current->thread.fp_regs.fpc & 3;
1351  FP_UNPACK_DP(DA, val);
1352  FP_SQRT_D(DR, DA);
1353  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1354  emu_set_CC_cs(regs, DR_c, DR_s);
1355  return _fex;
1356 }
1357 
1358 /* Square root float */
1359 static int emu_sqebr (struct pt_regs *regs, int rx, int ry) {
1360  FP_DECL_S(SA); FP_DECL_S(SR);
1361  FP_DECL_EX;
1362  int mode;
1363 
1364  mode = current->thread.fp_regs.fpc & 3;
1365  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[ry].f);
1366  FP_SQRT_S(SR, SA);
1367  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1368  emu_set_CC_cs(regs, SR_c, SR_s);
1369  return _fex;
1370 }
1371 
1372 /* Square root float */
1373 static int emu_sqeb (struct pt_regs *regs, int rx, float *val) {
1374  FP_DECL_S(SA); FP_DECL_S(SR);
1375  FP_DECL_EX;
1376  int mode;
1377 
1378  mode = current->thread.fp_regs.fpc & 3;
1379  FP_UNPACK_SP(SA, val);
1380  FP_SQRT_S(SR, SA);
1381  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1382  emu_set_CC_cs(regs, SR_c, SR_s);
1383  return _fex;
1384 }
1385 
1386 /* Subtract long double */
1387 static int emu_sxbr (struct pt_regs *regs, int rx, int ry) {
1388  FP_DECL_Q(QA); FP_DECL_Q(QB); FP_DECL_Q(QR);
1389  FP_DECL_EX;
1390  mathemu_ldcv cvt;
1391  int mode;
1392 
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;
1396  FP_UNPACK_QP(QA, &cvt.ld);
1397  cvt.w.high = current->thread.fp_regs.fprs[ry].ui;
1398  cvt.w.low = current->thread.fp_regs.fprs[ry+2].ui;
1399  FP_UNPACK_QP(QB, &cvt.ld);
1400  FP_SUB_Q(QR, QA, QB);
1401  FP_PACK_QP(&cvt.ld, QR);
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);
1405  return _fex;
1406 }
1407 
1408 /* Subtract double */
1409 static int emu_sdbr (struct pt_regs *regs, int rx, int ry) {
1411  FP_DECL_EX;
1412  int mode;
1413 
1414  mode = current->thread.fp_regs.fpc & 3;
1415  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1416  FP_UNPACK_DP(DB, &current->thread.fp_regs.fprs[ry].d);
1417  FP_SUB_D(DR, DA, DB);
1418  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1419  emu_set_CC_cs(regs, DR_c, DR_s);
1420  return _fex;
1421 }
1422 
1423 /* Subtract double */
1424 static int emu_sdb (struct pt_regs *regs, int rx, double *val) {
1426  FP_DECL_EX;
1427  int mode;
1428 
1429  mode = current->thread.fp_regs.fpc & 3;
1430  FP_UNPACK_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1431  FP_UNPACK_DP(DB, val);
1432  FP_SUB_D(DR, DA, DB);
1433  FP_PACK_DP(&current->thread.fp_regs.fprs[rx].d, DR);
1434  emu_set_CC_cs(regs, DR_c, DR_s);
1435  return _fex;
1436 }
1437 
1438 /* Subtract float */
1439 static int emu_sebr (struct pt_regs *regs, int rx, int ry) {
1441  FP_DECL_EX;
1442  int mode;
1443 
1444  mode = current->thread.fp_regs.fpc & 3;
1445  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1446  FP_UNPACK_SP(SB, &current->thread.fp_regs.fprs[ry].f);
1447  FP_SUB_S(SR, SA, SB);
1448  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1449  emu_set_CC_cs(regs, SR_c, SR_s);
1450  return _fex;
1451 }
1452 
1453 /* Subtract float */
1454 static int emu_seb (struct pt_regs *regs, int rx, float *val) {
1456  FP_DECL_EX;
1457  int mode;
1458 
1459  mode = current->thread.fp_regs.fpc & 3;
1460  FP_UNPACK_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1461  FP_UNPACK_SP(SB, val);
1462  FP_SUB_S(SR, SA, SB);
1463  FP_PACK_SP(&current->thread.fp_regs.fprs[rx].f, SR);
1464  emu_set_CC_cs(regs, SR_c, SR_s);
1465  return _fex;
1466 }
1467 
1468 /* Test data class long double */
1469 static int emu_tcxb (struct pt_regs *regs, int rx, long val) {
1470  FP_DECL_Q(QA);
1471  mathemu_ldcv cvt;
1472  int bit;
1473 
1474  cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
1475  cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
1476  FP_UNPACK_RAW_QP(QA, &cvt.ld);
1477  switch (QA_e) {
1478  default:
1479  bit = 8; /* normalized number */
1480  break;
1481  case 0:
1482  if (_FP_FRAC_ZEROP_4(QA))
1483  bit = 10; /* zero */
1484  else
1485  bit = 6; /* denormalized number */
1486  break;
1487  case _FP_EXPMAX_Q:
1488  if (_FP_FRAC_ZEROP_4(QA))
1489  bit = 4; /* infinity */
1490  else if (_FP_FRAC_HIGH_RAW_Q(QA) & _FP_QNANBIT_Q)
1491  bit = 2; /* quiet NAN */
1492  else
1493  bit = 0; /* signaling NAN */
1494  break;
1495  }
1496  if (!QA_s)
1497  bit++;
1498  emu_set_CC(regs, ((__u32) val >> bit) & 1);
1499  return 0;
1500 }
1501 
1502 /* Test data class double */
1503 static int emu_tcdb (struct pt_regs *regs, int rx, long val) {
1504  FP_DECL_D(DA);
1505  int bit;
1506 
1507  FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
1508  switch (DA_e) {
1509  default:
1510  bit = 8; /* normalized number */
1511  break;
1512  case 0:
1513  if (_FP_FRAC_ZEROP_2(DA))
1514  bit = 10; /* zero */
1515  else
1516  bit = 6; /* denormalized number */
1517  break;
1518  case _FP_EXPMAX_D:
1519  if (_FP_FRAC_ZEROP_2(DA))
1520  bit = 4; /* infinity */
1521  else if (_FP_FRAC_HIGH_RAW_D(DA) & _FP_QNANBIT_D)
1522  bit = 2; /* quiet NAN */
1523  else
1524  bit = 0; /* signaling NAN */
1525  break;
1526  }
1527  if (!DA_s)
1528  bit++;
1529  emu_set_CC(regs, ((__u32) val >> bit) & 1);
1530  return 0;
1531 }
1532 
1533 /* Test data class float */
1534 static int emu_tceb (struct pt_regs *regs, int rx, long val) {
1535  FP_DECL_S(SA);
1536  int bit;
1537 
1538  FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
1539  switch (SA_e) {
1540  default:
1541  bit = 8; /* normalized number */
1542  break;
1543  case 0:
1544  if (_FP_FRAC_ZEROP_1(SA))
1545  bit = 10; /* zero */
1546  else
1547  bit = 6; /* denormalized number */
1548  break;
1549  case _FP_EXPMAX_S:
1550  if (_FP_FRAC_ZEROP_1(SA))
1551  bit = 4; /* infinity */
1552  else if (_FP_FRAC_HIGH_RAW_S(SA) & _FP_QNANBIT_S)
1553  bit = 2; /* quiet NAN */
1554  else
1555  bit = 0; /* signaling NAN */
1556  break;
1557  }
1558  if (!SA_s)
1559  bit++;
1560  emu_set_CC(regs, ((__u32) val >> bit) & 1);
1561  return 0;
1562 }
1563 
1564 static inline void emu_load_regd(int reg) {
1565  if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
1566  return;
1567  asm volatile( /* load reg from fp_regs.fprs[reg] */
1568  " bras 1,0f\n"
1569  " ld 0,0(%1)\n"
1570  "0: ex %0,0(1)"
1571  : /* no output */
1572  : "a" (reg<<4),"a" (&current->thread.fp_regs.fprs[reg].d)
1573  : "1");
1574 }
1575 
1576 static inline void emu_load_rege(int reg) {
1577  if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
1578  return;
1579  asm volatile( /* load reg from fp_regs.fprs[reg] */
1580  " bras 1,0f\n"
1581  " le 0,0(%1)\n"
1582  "0: ex %0,0(1)"
1583  : /* no output */
1584  : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
1585  : "1");
1586 }
1587 
1588 static inline void emu_store_regd(int reg) {
1589  if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
1590  return;
1591  asm volatile( /* store reg to fp_regs.fprs[reg] */
1592  " bras 1,0f\n"
1593  " std 0,0(%1)\n"
1594  "0: ex %0,0(1)"
1595  : /* no output */
1596  : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
1597  : "1");
1598 }
1599 
1600 
1601 static inline void emu_store_rege(int reg) {
1602  if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
1603  return;
1604  asm volatile( /* store reg to fp_regs.fprs[reg] */
1605  " bras 1,0f\n"
1606  " ste 0,0(%1)\n"
1607  "0: ex %0,0(1)"
1608  : /* no output */
1609  : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
1610  : "1");
1611 }
1612 
1613 int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
1614  int _fex = 0;
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
1631  };
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,
1652  [0x9a] = emu_cfxbr
1653  };
1654 
1655  switch (format_table[opcode[1]]) {
1656  case 1: /* RRE format, long double operation */
1657  if (opcode[3] & 0x22)
1658  return SIGILL;
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);
1663  /* call the emulation function */
1664  _fex = ((int (*)(struct pt_regs *,int, int))
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);
1671  break;
1672  case 2: /* RRE format, double operation */
1673  emu_store_regd((opcode[3] >> 4) & 15);
1674  emu_store_regd(opcode[3] & 15);
1675  /* call the emulation function */
1676  _fex = ((int (*)(struct pt_regs *, int, int))
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);
1681  break;
1682  case 3: /* RRE format, float operation */
1683  emu_store_rege((opcode[3] >> 4) & 15);
1684  emu_store_rege(opcode[3] & 15);
1685  /* call the emulation function */
1686  _fex = ((int (*)(struct pt_regs *, int, int))
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);
1691  break;
1692  case 4: /* RRF format, long double operation */
1693  if (opcode[3] & 0x22)
1694  return SIGILL;
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);
1699  /* call the emulation function */
1700  _fex = ((int (*)(struct pt_regs *, int, int, int))
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);
1707  break;
1708  case 5: /* RRF format, double operation */
1709  emu_store_regd((opcode[2] >> 4) & 15);
1710  emu_store_regd((opcode[3] >> 4) & 15);
1711  emu_store_regd(opcode[3] & 15);
1712  /* call the emulation function */
1713  _fex = ((int (*)(struct pt_regs *, int, int, int))
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);
1719  break;
1720  case 6: /* RRF format, float operation */
1721  emu_store_rege((opcode[2] >> 4) & 15);
1722  emu_store_rege((opcode[3] >> 4) & 15);
1723  emu_store_rege(opcode[3] & 15);
1724  /* call the emulation function */
1725  _fex = ((int (*)(struct pt_regs *, int, int, int))
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);
1731  break;
1732  case 7: /* RRE format, cxfbr instruction */
1733  /* call the emulation function */
1734  if (opcode[3] & 0x20)
1735  return SIGILL;
1736  _fex = ((int (*)(struct pt_regs *, int, int))
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);
1741  break;
1742  case 8: /* RRE format, cdfbr instruction */
1743  /* call the emulation function */
1744  _fex = ((int (*)(struct pt_regs *, int, int))
1745  jump_table[opcode[1]])
1746  (regs, opcode[3] >> 4, opcode[3] & 15);
1747  emu_load_regd((opcode[3] >> 4) & 15);
1748  break;
1749  case 9: /* RRE format, cefbr instruction */
1750  /* call the emulation function */
1751  _fex = ((int (*)(struct pt_regs *, int, int))
1752  jump_table[opcode[1]])
1753  (regs, opcode[3] >> 4, opcode[3] & 15);
1754  emu_load_rege((opcode[3] >> 4) & 15);
1755  break;
1756  case 10: /* RRF format, cfxbr instruction */
1757  if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
1758  /* mask of { 2,3,8-15 } is invalid */
1759  return SIGILL;
1760  if (opcode[3] & 2)
1761  return SIGILL;
1762  emu_store_regd(opcode[3] & 15);
1763  emu_store_regd((opcode[3] & 15) + 2);
1764  /* call the emulation function */
1765  _fex = ((int (*)(struct pt_regs *, int, int, int))
1766  jump_table[opcode[1]])
1767  (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1768  break;
1769  case 11: /* RRF format, cfdbr instruction */
1770  if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
1771  /* mask of { 2,3,8-15 } is invalid */
1772  return SIGILL;
1773  emu_store_regd(opcode[3] & 15);
1774  /* call the emulation function */
1775  _fex = ((int (*)(struct pt_regs *, int, int, int))
1776  jump_table[opcode[1]])
1777  (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1778  break;
1779  case 12: /* RRF format, cfebr instruction */
1780  if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32)
1781  /* mask of { 2,3,8-15 } is invalid */
1782  return SIGILL;
1783  emu_store_rege(opcode[3] & 15);
1784  /* call the emulation function */
1785  _fex = ((int (*)(struct pt_regs *, int, int, int))
1786  jump_table[opcode[1]])
1787  (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4);
1788  break;
1789  case 13: /* RRE format, ldxbr & mdxbr instruction */
1790  /* double store but long double load */
1791  if (opcode[3] & 0x20)
1792  return SIGILL;
1793  emu_store_regd((opcode[3] >> 4) & 15);
1794  emu_store_regd(opcode[3] & 15);
1795  /* call the emulation function */
1796  _fex = ((int (*)(struct pt_regs *, int, int))
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);
1801  break;
1802  case 14: /* RRE format, ldxbr & mdxbr instruction */
1803  /* float store but long double load */
1804  if (opcode[3] & 0x20)
1805  return SIGILL;
1806  emu_store_rege((opcode[3] >> 4) & 15);
1807  emu_store_rege(opcode[3] & 15);
1808  /* call the emulation function */
1809  _fex = ((int (*)(struct pt_regs *, int, int))
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);
1814  break;
1815  case 15: /* RRE format, ldebr & mdebr instruction */
1816  /* float store but double load */
1817  emu_store_rege((opcode[3] >> 4) & 15);
1818  emu_store_rege(opcode[3] & 15);
1819  /* call the emulation function */
1820  _fex = ((int (*)(struct pt_regs *, int, int))
1821  jump_table[opcode[1]])
1822  (regs, opcode[3] >> 4, opcode[3] & 15);
1823  emu_load_regd((opcode[3] >> 4) & 15);
1824  break;
1825  case 16: /* RRE format, ldxbr instruction */
1826  /* long double store but double load */
1827  if (opcode[3] & 2)
1828  return SIGILL;
1829  emu_store_regd(opcode[3] & 15);
1830  emu_store_regd((opcode[3] & 15) + 2);
1831  /* call the emulation function */
1832  _fex = ((int (*)(struct pt_regs *, int, int))
1833  jump_table[opcode[1]])
1834  (regs, opcode[3] >> 4, opcode[3] & 15);
1835  emu_load_regd((opcode[3] >> 4) & 15);
1836  break;
1837  case 17: /* RRE format, ldxbr instruction */
1838  /* long double store but float load */
1839  if (opcode[3] & 2)
1840  return SIGILL;
1841  emu_store_regd(opcode[3] & 15);
1842  emu_store_regd((opcode[3] & 15) + 2);
1843  /* call the emulation function */
1844  _fex = ((int (*)(struct pt_regs *, int, int))
1845  jump_table[opcode[1]])
1846  (regs, opcode[3] >> 4, opcode[3] & 15);
1847  emu_load_rege((opcode[3] >> 4) & 15);
1848  break;
1849  case 18: /* RRE format, ledbr instruction */
1850  /* double store but float load */
1851  emu_store_regd(opcode[3] & 15);
1852  /* call the emulation function */
1853  _fex = ((int (*)(struct pt_regs *, int, int))
1854  jump_table[opcode[1]])
1855  (regs, opcode[3] >> 4, opcode[3] & 15);
1856  emu_load_rege((opcode[3] >> 4) & 15);
1857  break;
1858  case 19: /* RRE format, efpc & sfpc instruction */
1859  /* call the emulation function */
1860  _fex = ((int (*)(struct pt_regs *, int, int))
1861  jump_table[opcode[1]])
1862  (regs, opcode[3] >> 4, opcode[3] & 15);
1863  break;
1864  default: /* invalid operation */
1865  return SIGILL;
1866  }
1867  if (_fex != 0) {
1868  current->thread.fp_regs.fpc |= _fex;
1869  if (current->thread.fp_regs.fpc & (_fex << 8))
1870  return SIGFPE;
1871  }
1872  return 0;
1873 }
1874 
1875 static void* calc_addr(struct pt_regs *regs, int rx, int rb, int disp)
1876 {
1877  addr_t addr;
1878 
1879  rx &= 15;
1880  rb &= 15;
1881  addr = disp & 0xfff;
1882  addr += (rx != 0) ? regs->gprs[rx] : 0; /* + index */
1883  addr += (rb != 0) ? regs->gprs[rb] : 0; /* + base */
1884  return (void*) addr;
1885 }
1886 
1887 int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
1888  int _fex = 0;
1889 
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,
1898  };
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
1909  };
1910 
1911  switch (format_table[opcode[5]]) {
1912  case 1: /* RXE format, double constant */ {
1913  __u64 *dxb, temp;
1914  __u32 opc;
1915 
1916  emu_store_regd((opcode[1] >> 4) & 15);
1917  opc = *((__u32 *) opcode);
1918  dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1919  mathemu_copy_from_user(&temp, dxb, 8);
1920  /* call the emulation function */
1921  _fex = ((int (*)(struct pt_regs *, int, double *))
1922  jump_table[opcode[5]])
1923  (regs, opcode[1] >> 4, (double *) &temp);
1924  emu_load_regd((opcode[1] >> 4) & 15);
1925  break;
1926  }
1927  case 2: /* RXE format, float constant */ {
1928  __u32 *dxb, temp;
1929  __u32 opc;
1930 
1931  emu_store_rege((opcode[1] >> 4) & 15);
1932  opc = *((__u32 *) opcode);
1933  dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1934  mathemu_get_user(temp, dxb);
1935  /* call the emulation function */
1936  _fex = ((int (*)(struct pt_regs *, int, float *))
1937  jump_table[opcode[5]])
1938  (regs, opcode[1] >> 4, (float *) &temp);
1939  emu_load_rege((opcode[1] >> 4) & 15);
1940  break;
1941  }
1942  case 3: /* RXF format, double constant */ {
1943  __u64 *dxb, temp;
1944  __u32 opc;
1945 
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);
1950  mathemu_copy_from_user(&temp, dxb, 8);
1951  /* call the emulation function */
1952  _fex = ((int (*)(struct pt_regs *, int, double *, int))
1953  jump_table[opcode[5]])
1954  (regs, opcode[1] >> 4, (double *) &temp, opcode[4] >> 4);
1955  emu_load_regd((opcode[1] >> 4) & 15);
1956  break;
1957  }
1958  case 4: /* RXF format, float constant */ {
1959  __u32 *dxb, temp;
1960  __u32 opc;
1961 
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);
1966  mathemu_get_user(temp, dxb);
1967  /* call the emulation function */
1968  _fex = ((int (*)(struct pt_regs *, int, float *, int))
1969  jump_table[opcode[5]])
1970  (regs, opcode[1] >> 4, (float *) &temp, opcode[4] >> 4);
1971  emu_load_rege((opcode[4] >> 4) & 15);
1972  break;
1973  }
1974  case 5: /* RXE format, double constant */
1975  /* store double and load long double */
1976  {
1977  __u64 *dxb, temp;
1978  __u32 opc;
1979  if ((opcode[1] >> 4) & 0x20)
1980  return SIGILL;
1981  emu_store_regd((opcode[1] >> 4) & 15);
1982  opc = *((__u32 *) opcode);
1983  dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
1984  mathemu_copy_from_user(&temp, dxb, 8);
1985  /* call the emulation function */
1986  _fex = ((int (*)(struct pt_regs *, int, double *))
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);
1991  break;
1992  }
1993  case 6: /* RXE format, float constant */
1994  /* store float and load double */
1995  {
1996  __u32 *dxb, temp;
1997  __u32 opc;
1998  emu_store_rege((opcode[1] >> 4) & 15);
1999  opc = *((__u32 *) opcode);
2000  dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2001  mathemu_get_user(temp, dxb);
2002  /* call the emulation function */
2003  _fex = ((int (*)(struct pt_regs *, int, float *))
2004  jump_table[opcode[5]])
2005  (regs, opcode[1] >> 4, (float *) &temp);
2006  emu_load_regd((opcode[1] >> 4) & 15);
2007  break;
2008  }
2009  case 7: /* RXE format, float constant */
2010  /* store float and load long double */
2011  {
2012  __u32 *dxb, temp;
2013  __u32 opc;
2014  if ((opcode[1] >> 4) & 0x20)
2015  return SIGILL;
2016  emu_store_rege((opcode[1] >> 4) & 15);
2017  opc = *((__u32 *) opcode);
2018  dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2019  mathemu_get_user(temp, dxb);
2020  /* call the emulation function */
2021  _fex = ((int (*)(struct pt_regs *, int, float *))
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);
2026  break;
2027  }
2028  case 8: /* RXE format, RX address used as int value */ {
2029  __u64 dxb;
2030  __u32 opc;
2031 
2032  emu_store_rege((opcode[1] >> 4) & 15);
2033  opc = *((__u32 *) opcode);
2034  dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
2035  /* call the emulation function */
2036  _fex = ((int (*)(struct pt_regs *, int, long))
2037  jump_table[opcode[5]])
2038  (regs, opcode[1] >> 4, dxb);
2039  break;
2040  }
2041  case 9: /* RXE format, RX address used as int value */ {
2042  __u64 dxb;
2043  __u32 opc;
2044 
2045  emu_store_regd((opcode[1] >> 4) & 15);
2046  opc = *((__u32 *) opcode);
2047  dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
2048  /* call the emulation function */
2049  _fex = ((int (*)(struct pt_regs *, int, long))
2050  jump_table[opcode[5]])
2051  (regs, opcode[1] >> 4, dxb);
2052  break;
2053  }
2054  case 10: /* RXE format, RX address used as int value */ {
2055  __u64 dxb;
2056  __u32 opc;
2057 
2058  if ((opcode[1] >> 4) & 2)
2059  return SIGILL;
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);
2064  /* call the emulation function */
2065  _fex = ((int (*)(struct pt_regs *, int, long))
2066  jump_table[opcode[5]])
2067  (regs, opcode[1] >> 4, dxb);
2068  break;
2069  }
2070  default: /* invalid operation */
2071  return SIGILL;
2072  }
2073  if (_fex != 0) {
2074  current->thread.fp_regs.fpc |= _fex;
2075  if (current->thread.fp_regs.fpc & (_fex << 8))
2076  return SIGFPE;
2077  }
2078  return 0;
2079 }
2080 
2081 /*
2082  * Emulate LDR Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
2083  */
2085  s390_fp_regs *fp_regs = &current->thread.fp_regs;
2086  __u16 opc = *((__u16 *) opcode);
2087 
2088  if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */
2089  /* we got an exception therefore ry can't be in {0,2,4,6} */
2090  asm volatile( /* load rx from fp_regs.fprs[ry] */
2091  " bras 1,0f\n"
2092  " ld 0,0(%1)\n"
2093  "0: ex %0,0(1)"
2094  : /* no output */
2095  : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].d)
2096  : "1");
2097  } else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */
2098  asm volatile ( /* store ry to fp_regs.fprs[rx] */
2099  " bras 1,0f\n"
2100  " std 0,0(%1)\n"
2101  "0: ex %0,0(1)"
2102  : /* no output */
2103  : "a" ((opc & 0xf) << 4),
2104  "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d)
2105  : "1");
2106  } else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
2107  fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
2108  return 0;
2109 }
2110 
2111 /*
2112  * Emulate LER Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
2113  */
2115  s390_fp_regs *fp_regs = &current->thread.fp_regs;
2116  __u16 opc = *((__u16 *) opcode);
2117 
2118  if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */
2119  /* we got an exception therefore ry can't be in {0,2,4,6} */
2120  asm volatile( /* load rx from fp_regs.fprs[ry] */
2121  " bras 1,0f\n"
2122  " le 0,0(%1)\n"
2123  "0: ex %0,0(1)"
2124  : /* no output */
2125  : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].f)
2126  : "1");
2127  } else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */
2128  asm volatile( /* store ry to fp_regs.fprs[rx] */
2129  " bras 1,0f\n"
2130  " ste 0,0(%1)\n"
2131  "0: ex %0,0(1)"
2132  : /* no output */
2133  : "a" ((opc & 0xf) << 4),
2134  "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f)
2135  : "1");
2136  } else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
2137  fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
2138  return 0;
2139 }
2140 
2141 /*
2142  * Emulate LD R,D(X,B) with R not in {0, 2, 4, 6}
2143  */
2144 int math_emu_ld(__u8 *opcode, struct pt_regs * regs) {
2145  s390_fp_regs *fp_regs = &current->thread.fp_regs;
2146  __u32 opc = *((__u32 *) opcode);
2147  __u64 *dxb;
2148 
2149  dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2150  mathemu_copy_from_user(&fp_regs->fprs[(opc >> 20) & 0xf].d, dxb, 8);
2151  return 0;
2152 }
2153 
2154 /*
2155  * Emulate LE R,D(X,B) with R not in {0, 2, 4, 6}
2156  */
2157 int math_emu_le(__u8 *opcode, struct pt_regs * regs) {
2158  s390_fp_regs *fp_regs = &current->thread.fp_regs;
2159  __u32 opc = *((__u32 *) opcode);
2160  __u32 *mem, *dxb;
2161 
2162  dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2163  mem = (__u32 *) (&fp_regs->fprs[(opc >> 20) & 0xf].f);
2164  mathemu_get_user(mem[0], dxb);
2165  return 0;
2166 }
2167 
2168 /*
2169  * Emulate STD R,D(X,B) with R not in {0, 2, 4, 6}
2170  */
2171 int math_emu_std(__u8 *opcode, struct pt_regs * regs) {
2172  s390_fp_regs *fp_regs = &current->thread.fp_regs;
2173  __u32 opc = *((__u32 *) opcode);
2174  __u64 *dxb;
2175 
2176  dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2177  mathemu_copy_to_user(dxb, &fp_regs->fprs[(opc >> 20) & 0xf].d, 8);
2178  return 0;
2179 }
2180 
2181 /*
2182  * Emulate STE R,D(X,B) with R not in {0, 2, 4, 6}
2183  */
2184 int math_emu_ste(__u8 *opcode, struct pt_regs * regs) {
2185  s390_fp_regs *fp_regs = &current->thread.fp_regs;
2186  __u32 opc = *((__u32 *) opcode);
2187  __u32 *mem, *dxb;
2188 
2189  dxb = (__u32 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
2190  mem = (__u32 *) (&fp_regs->fprs[(opc >> 20) & 0xf].f);
2191  mathemu_put_user(mem[0], dxb);
2192  return 0;
2193 }
2194 
2195 /*
2196  * Emulate LFPC D(B)
2197  */
2198 int math_emu_lfpc(__u8 *opcode, struct pt_regs *regs) {
2199  __u32 opc = *((__u32 *) opcode);
2200  __u32 *dxb, temp;
2201 
2202  dxb= (__u32 *) calc_addr(regs, 0, opc>>12, opc);
2203  mathemu_get_user(temp, dxb);
2204  if ((temp & ~FPC_VALID_MASK) != 0)
2205  return SIGILL;
2206  current->thread.fp_regs.fpc = temp;
2207  return 0;
2208 }
2209 
2210 /*
2211  * Emulate STFPC D(B)
2212  */
2213 int math_emu_stfpc(__u8 *opcode, struct pt_regs *regs) {
2214  __u32 opc = *((__u32 *) opcode);
2215  __u32 *dxb;
2216 
2217  dxb= (__u32 *) calc_addr(regs, 0, opc>>12, opc);
2218  mathemu_put_user(current->thread.fp_regs.fpc, dxb);
2219  return 0;
2220 }
2221 
2222 /*
2223  * Emulate SRNM D(B)
2224  */
2225 int math_emu_srnm(__u8 *opcode, struct pt_regs *regs) {
2226  __u32 opc = *((__u32 *) opcode);
2227  __u32 temp;
2228 
2229  temp = calc_addr(regs, 0, opc>>12, opc);
2230  current->thread.fp_regs.fpc &= ~3;
2231  current->thread.fp_regs.fpc |= (temp & 3);
2232  return 0;
2233 }
2234 
2235 /* broken compiler ... */
2236 long long
2237 __negdi2 (long long u)
2238 {
2239 
2240  union lll {
2241  long long ll;
2242  long s[2];
2243  };
2244 
2245  union lll w,uu;
2246 
2247  uu.ll = u;
2248 
2249  w.s[1] = -uu.s[1];
2250  w.s[0] = -uu.s[0] - ((int) w.s[1] != 0);
2251 
2252  return w.ll;
2253 }