math.c 74 KB

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