18c2ecf20Sopenharmony_ci| 28c2ecf20Sopenharmony_ci| x_operr.sa 3.5 7/1/91 38c2ecf20Sopenharmony_ci| 48c2ecf20Sopenharmony_ci| fpsp_operr --- FPSP handler for operand error exception 58c2ecf20Sopenharmony_ci| 68c2ecf20Sopenharmony_ci| See 68040 User's Manual pp. 9-44f 78c2ecf20Sopenharmony_ci| 88c2ecf20Sopenharmony_ci| Note 1: For trap disabled 040 does the following: 98c2ecf20Sopenharmony_ci| If the dest is a fp reg, then an extended precision non_signaling 108c2ecf20Sopenharmony_ci| NAN is stored in the dest reg. If the dest format is b, w, or l and 118c2ecf20Sopenharmony_ci| the source op is a NAN, then garbage is stored as the result (actually 128c2ecf20Sopenharmony_ci| the upper 32 bits of the mantissa are sent to the integer unit). If 138c2ecf20Sopenharmony_ci| the dest format is integer (b, w, l) and the operr is caused by 148c2ecf20Sopenharmony_ci| integer overflow, or the source op is inf, then the result stored is 158c2ecf20Sopenharmony_ci| garbage. 168c2ecf20Sopenharmony_ci| There are three cases in which operr is incorrectly signaled on the 178c2ecf20Sopenharmony_ci| 040. This occurs for move_out of format b, w, or l for the largest 188c2ecf20Sopenharmony_ci| negative integer (-2^7 for b, -2^15 for w, -2^31 for l). 198c2ecf20Sopenharmony_ci| 208c2ecf20Sopenharmony_ci| On opclass = 011 fmove.(b,w,l) that causes a conversion 218c2ecf20Sopenharmony_ci| overflow -> OPERR, the exponent in wbte (and fpte) is: 228c2ecf20Sopenharmony_ci| byte 56 - (62 - exp) 238c2ecf20Sopenharmony_ci| word 48 - (62 - exp) 248c2ecf20Sopenharmony_ci| long 32 - (62 - exp) 258c2ecf20Sopenharmony_ci| 268c2ecf20Sopenharmony_ci| where exp = (true exp) - 1 278c2ecf20Sopenharmony_ci| 288c2ecf20Sopenharmony_ci| So, wbtemp and fptemp will contain the following on erroneously 298c2ecf20Sopenharmony_ci| signalled operr: 308c2ecf20Sopenharmony_ci| fpts = 1 318c2ecf20Sopenharmony_ci| fpte = $4000 (15 bit externally) 328c2ecf20Sopenharmony_ci| byte fptm = $ffffffff ffffff80 338c2ecf20Sopenharmony_ci| word fptm = $ffffffff ffff8000 348c2ecf20Sopenharmony_ci| long fptm = $ffffffff 80000000 358c2ecf20Sopenharmony_ci| 368c2ecf20Sopenharmony_ci| Note 2: For trap enabled 040 does the following: 378c2ecf20Sopenharmony_ci| If the inst is move_out, then same as Note 1. 388c2ecf20Sopenharmony_ci| If the inst is not move_out, the dest is not modified. 398c2ecf20Sopenharmony_ci| The exceptional operand is not defined for integer overflow 408c2ecf20Sopenharmony_ci| during a move_out. 418c2ecf20Sopenharmony_ci| 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 448c2ecf20Sopenharmony_ci| All Rights Reserved 458c2ecf20Sopenharmony_ci| 468c2ecf20Sopenharmony_ci| For details on the license for this file, please see the 478c2ecf20Sopenharmony_ci| file, README, in this same directory. 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciX_OPERR: |idnt 2,1 | Motorola 040 Floating Point Software Package 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci |section 8 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#include "fpsp.h" 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci |xref mem_write 568c2ecf20Sopenharmony_ci |xref real_operr 578c2ecf20Sopenharmony_ci |xref real_inex 588c2ecf20Sopenharmony_ci |xref get_fline 598c2ecf20Sopenharmony_ci |xref fpsp_done 608c2ecf20Sopenharmony_ci |xref reg_dest 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci .global fpsp_operr 638c2ecf20Sopenharmony_cifpsp_operr: 648c2ecf20Sopenharmony_ci| 658c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 668c2ecf20Sopenharmony_ci fsave -(%a7) 678c2ecf20Sopenharmony_ci moveml %d0-%d1/%a0-%a1,USER_DA(%a6) 688c2ecf20Sopenharmony_ci fmovemx %fp0-%fp3,USER_FP0(%a6) 698c2ecf20Sopenharmony_ci fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci| 728c2ecf20Sopenharmony_ci| Check if this is an opclass 3 instruction. 738c2ecf20Sopenharmony_ci| If so, fall through, else branch to operr_end 748c2ecf20Sopenharmony_ci| 758c2ecf20Sopenharmony_ci btstb #TFLAG,T_BYTE(%a6) 768c2ecf20Sopenharmony_ci beqs operr_end 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci| 798c2ecf20Sopenharmony_ci| If the destination size is B,W,or L, the operr must be 808c2ecf20Sopenharmony_ci| handled here. 818c2ecf20Sopenharmony_ci| 828c2ecf20Sopenharmony_ci movel CMDREG1B(%a6),%d0 838c2ecf20Sopenharmony_ci bfextu %d0{#3:#3},%d0 |0=long, 4=word, 6=byte 848c2ecf20Sopenharmony_ci cmpib #0,%d0 |determine size; check long 858c2ecf20Sopenharmony_ci beq operr_long 868c2ecf20Sopenharmony_ci cmpib #4,%d0 |check word 878c2ecf20Sopenharmony_ci beq operr_word 888c2ecf20Sopenharmony_ci cmpib #6,%d0 |check byte 898c2ecf20Sopenharmony_ci beq operr_byte 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci| 928c2ecf20Sopenharmony_ci| The size is not B,W,or L, so the operr is handled by the 938c2ecf20Sopenharmony_ci| kernel handler. Set the operr bits and clean up, leaving 948c2ecf20Sopenharmony_ci| only the integer exception frame on the stack, and the 958c2ecf20Sopenharmony_ci| fpu in the original exceptional state. 968c2ecf20Sopenharmony_ci| 978c2ecf20Sopenharmony_cioperr_end: 988c2ecf20Sopenharmony_ci bsetb #operr_bit,FPSR_EXCEPT(%a6) 998c2ecf20Sopenharmony_ci bsetb #aiop_bit,FPSR_AEXCEPT(%a6) 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 1028c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 1038c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 1048c2ecf20Sopenharmony_ci frestore (%a7)+ 1058c2ecf20Sopenharmony_ci unlk %a6 1068c2ecf20Sopenharmony_ci bral real_operr 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cioperr_long: 1098c2ecf20Sopenharmony_ci moveql #4,%d1 |write size to d1 1108c2ecf20Sopenharmony_ci moveb STAG(%a6),%d0 |test stag for nan 1118c2ecf20Sopenharmony_ci andib #0xe0,%d0 |clr all but tag 1128c2ecf20Sopenharmony_ci cmpib #0x60,%d0 |check for nan 1138c2ecf20Sopenharmony_ci beq operr_nan 1148c2ecf20Sopenharmony_ci cmpil #0x80000000,FPTEMP_LO(%a6) |test if ls lword is special 1158c2ecf20Sopenharmony_ci bnes chklerr |if not equal, check for incorrect operr 1168c2ecf20Sopenharmony_ci bsr check_upper |check if exp and ms mant are special 1178c2ecf20Sopenharmony_ci tstl %d0 1188c2ecf20Sopenharmony_ci bnes chklerr |if d0 is true, check for incorrect operr 1198c2ecf20Sopenharmony_ci movel #0x80000000,%d0 |store special case result 1208c2ecf20Sopenharmony_ci bsr operr_store 1218c2ecf20Sopenharmony_ci bra not_enabled |clean and exit 1228c2ecf20Sopenharmony_ci| 1238c2ecf20Sopenharmony_ci| CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE 1248c2ecf20Sopenharmony_ci| 1258c2ecf20Sopenharmony_cichklerr: 1268c2ecf20Sopenharmony_ci movew FPTEMP_EX(%a6),%d0 1278c2ecf20Sopenharmony_ci andw #0x7FFF,%d0 |ignore sign bit 1288c2ecf20Sopenharmony_ci cmpw #0x3FFE,%d0 |this is the only possible exponent value 1298c2ecf20Sopenharmony_ci bnes chklerr2 1308c2ecf20Sopenharmony_cifixlong: 1318c2ecf20Sopenharmony_ci movel FPTEMP_LO(%a6),%d0 1328c2ecf20Sopenharmony_ci bsr operr_store 1338c2ecf20Sopenharmony_ci bra not_enabled 1348c2ecf20Sopenharmony_cichklerr2: 1358c2ecf20Sopenharmony_ci movew FPTEMP_EX(%a6),%d0 1368c2ecf20Sopenharmony_ci andw #0x7FFF,%d0 |ignore sign bit 1378c2ecf20Sopenharmony_ci cmpw #0x4000,%d0 1388c2ecf20Sopenharmony_ci bcc store_max |exponent out of range 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci movel FPTEMP_LO(%a6),%d0 1418c2ecf20Sopenharmony_ci andl #0x7FFF0000,%d0 |look for all 1's on bits 30-16 1428c2ecf20Sopenharmony_ci cmpl #0x7FFF0000,%d0 1438c2ecf20Sopenharmony_ci beqs fixlong 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci tstl FPTEMP_LO(%a6) 1468c2ecf20Sopenharmony_ci bpls chklepos 1478c2ecf20Sopenharmony_ci cmpl #0xFFFFFFFF,FPTEMP_HI(%a6) 1488c2ecf20Sopenharmony_ci beqs fixlong 1498c2ecf20Sopenharmony_ci bra store_max 1508c2ecf20Sopenharmony_cichklepos: 1518c2ecf20Sopenharmony_ci tstl FPTEMP_HI(%a6) 1528c2ecf20Sopenharmony_ci beqs fixlong 1538c2ecf20Sopenharmony_ci bra store_max 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cioperr_word: 1568c2ecf20Sopenharmony_ci moveql #2,%d1 |write size to d1 1578c2ecf20Sopenharmony_ci moveb STAG(%a6),%d0 |test stag for nan 1588c2ecf20Sopenharmony_ci andib #0xe0,%d0 |clr all but tag 1598c2ecf20Sopenharmony_ci cmpib #0x60,%d0 |check for nan 1608c2ecf20Sopenharmony_ci beq operr_nan 1618c2ecf20Sopenharmony_ci cmpil #0xffff8000,FPTEMP_LO(%a6) |test if ls lword is special 1628c2ecf20Sopenharmony_ci bnes chkwerr |if not equal, check for incorrect operr 1638c2ecf20Sopenharmony_ci bsr check_upper |check if exp and ms mant are special 1648c2ecf20Sopenharmony_ci tstl %d0 1658c2ecf20Sopenharmony_ci bnes chkwerr |if d0 is true, check for incorrect operr 1668c2ecf20Sopenharmony_ci movel #0x80000000,%d0 |store special case result 1678c2ecf20Sopenharmony_ci bsr operr_store 1688c2ecf20Sopenharmony_ci bra not_enabled |clean and exit 1698c2ecf20Sopenharmony_ci| 1708c2ecf20Sopenharmony_ci| CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE 1718c2ecf20Sopenharmony_ci| 1728c2ecf20Sopenharmony_cichkwerr: 1738c2ecf20Sopenharmony_ci movew FPTEMP_EX(%a6),%d0 1748c2ecf20Sopenharmony_ci andw #0x7FFF,%d0 |ignore sign bit 1758c2ecf20Sopenharmony_ci cmpw #0x3FFE,%d0 |this is the only possible exponent value 1768c2ecf20Sopenharmony_ci bnes store_max 1778c2ecf20Sopenharmony_ci movel FPTEMP_LO(%a6),%d0 1788c2ecf20Sopenharmony_ci swap %d0 1798c2ecf20Sopenharmony_ci bsr operr_store 1808c2ecf20Sopenharmony_ci bra not_enabled 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cioperr_byte: 1838c2ecf20Sopenharmony_ci moveql #1,%d1 |write size to d1 1848c2ecf20Sopenharmony_ci moveb STAG(%a6),%d0 |test stag for nan 1858c2ecf20Sopenharmony_ci andib #0xe0,%d0 |clr all but tag 1868c2ecf20Sopenharmony_ci cmpib #0x60,%d0 |check for nan 1878c2ecf20Sopenharmony_ci beqs operr_nan 1888c2ecf20Sopenharmony_ci cmpil #0xffffff80,FPTEMP_LO(%a6) |test if ls lword is special 1898c2ecf20Sopenharmony_ci bnes chkberr |if not equal, check for incorrect operr 1908c2ecf20Sopenharmony_ci bsr check_upper |check if exp and ms mant are special 1918c2ecf20Sopenharmony_ci tstl %d0 1928c2ecf20Sopenharmony_ci bnes chkberr |if d0 is true, check for incorrect operr 1938c2ecf20Sopenharmony_ci movel #0x80000000,%d0 |store special case result 1948c2ecf20Sopenharmony_ci bsr operr_store 1958c2ecf20Sopenharmony_ci bra not_enabled |clean and exit 1968c2ecf20Sopenharmony_ci| 1978c2ecf20Sopenharmony_ci| CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE 1988c2ecf20Sopenharmony_ci| 1998c2ecf20Sopenharmony_cichkberr: 2008c2ecf20Sopenharmony_ci movew FPTEMP_EX(%a6),%d0 2018c2ecf20Sopenharmony_ci andw #0x7FFF,%d0 |ignore sign bit 2028c2ecf20Sopenharmony_ci cmpw #0x3FFE,%d0 |this is the only possible exponent value 2038c2ecf20Sopenharmony_ci bnes store_max 2048c2ecf20Sopenharmony_ci movel FPTEMP_LO(%a6),%d0 2058c2ecf20Sopenharmony_ci asll #8,%d0 2068c2ecf20Sopenharmony_ci swap %d0 2078c2ecf20Sopenharmony_ci bsr operr_store 2088c2ecf20Sopenharmony_ci bra not_enabled 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci| 2118c2ecf20Sopenharmony_ci| This operr condition is not of the special case. Set operr 2128c2ecf20Sopenharmony_ci| and aiop and write the portion of the nan to memory for the 2138c2ecf20Sopenharmony_ci| given size. 2148c2ecf20Sopenharmony_ci| 2158c2ecf20Sopenharmony_cioperr_nan: 2168c2ecf20Sopenharmony_ci orl #opaop_mask,USER_FPSR(%a6) |set operr & aiop 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci movel ETEMP_HI(%a6),%d0 |output will be from upper 32 bits 2198c2ecf20Sopenharmony_ci bsr operr_store 2208c2ecf20Sopenharmony_ci bra end_operr 2218c2ecf20Sopenharmony_ci| 2228c2ecf20Sopenharmony_ci| Store_max loads the max pos or negative for the size, sets 2238c2ecf20Sopenharmony_ci| the operr and aiop bits, and clears inex and ainex, incorrectly 2248c2ecf20Sopenharmony_ci| set by the 040. 2258c2ecf20Sopenharmony_ci| 2268c2ecf20Sopenharmony_cistore_max: 2278c2ecf20Sopenharmony_ci orl #opaop_mask,USER_FPSR(%a6) |set operr & aiop 2288c2ecf20Sopenharmony_ci bclrb #inex2_bit,FPSR_EXCEPT(%a6) 2298c2ecf20Sopenharmony_ci bclrb #ainex_bit,FPSR_AEXCEPT(%a6) 2308c2ecf20Sopenharmony_ci fmovel #0,%FPSR 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci tstw FPTEMP_EX(%a6) |check sign 2338c2ecf20Sopenharmony_ci blts load_neg 2348c2ecf20Sopenharmony_ci movel #0x7fffffff,%d0 2358c2ecf20Sopenharmony_ci bsr operr_store 2368c2ecf20Sopenharmony_ci bra end_operr 2378c2ecf20Sopenharmony_ciload_neg: 2388c2ecf20Sopenharmony_ci movel #0x80000000,%d0 2398c2ecf20Sopenharmony_ci bsr operr_store 2408c2ecf20Sopenharmony_ci bra end_operr 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci| 2438c2ecf20Sopenharmony_ci| This routine stores the data in d0, for the given size in d1, 2448c2ecf20Sopenharmony_ci| to memory or data register as required. A read of the fline 2458c2ecf20Sopenharmony_ci| is required to determine the destination. 2468c2ecf20Sopenharmony_ci| 2478c2ecf20Sopenharmony_cioperr_store: 2488c2ecf20Sopenharmony_ci movel %d0,L_SCR1(%a6) |move write data to L_SCR1 2498c2ecf20Sopenharmony_ci movel %d1,-(%a7) |save register size 2508c2ecf20Sopenharmony_ci bsrl get_fline |fline returned in d0 2518c2ecf20Sopenharmony_ci movel (%a7)+,%d1 2528c2ecf20Sopenharmony_ci bftst %d0{#26:#3} |if mode is zero, dest is Dn 2538c2ecf20Sopenharmony_ci bnes dest_mem 2548c2ecf20Sopenharmony_ci| 2558c2ecf20Sopenharmony_ci| Destination is Dn. Get register number from d0. Data is on 2568c2ecf20Sopenharmony_ci| the stack at (a7). D1 has size: 1=byte,2=word,4=long/single 2578c2ecf20Sopenharmony_ci| 2588c2ecf20Sopenharmony_ci andil #7,%d0 |isolate register number 2598c2ecf20Sopenharmony_ci cmpil #4,%d1 2608c2ecf20Sopenharmony_ci beqs op_long |the most frequent case 2618c2ecf20Sopenharmony_ci cmpil #2,%d1 2628c2ecf20Sopenharmony_ci bnes op_con 2638c2ecf20Sopenharmony_ci orl #8,%d0 2648c2ecf20Sopenharmony_ci bras op_con 2658c2ecf20Sopenharmony_ciop_long: 2668c2ecf20Sopenharmony_ci orl #0x10,%d0 2678c2ecf20Sopenharmony_ciop_con: 2688c2ecf20Sopenharmony_ci movel %d0,%d1 |format size:reg for reg_dest 2698c2ecf20Sopenharmony_ci bral reg_dest |call to reg_dest returns to caller 2708c2ecf20Sopenharmony_ci| ;of operr_store 2718c2ecf20Sopenharmony_ci| 2728c2ecf20Sopenharmony_ci| Destination is memory. Get <ea> from integer exception frame 2738c2ecf20Sopenharmony_ci| and call mem_write. 2748c2ecf20Sopenharmony_ci| 2758c2ecf20Sopenharmony_cidest_mem: 2768c2ecf20Sopenharmony_ci leal L_SCR1(%a6),%a0 |put ptr to write data in a0 2778c2ecf20Sopenharmony_ci movel EXC_EA(%a6),%a1 |put user destination address in a1 2788c2ecf20Sopenharmony_ci movel %d1,%d0 |put size in d0 2798c2ecf20Sopenharmony_ci bsrl mem_write 2808c2ecf20Sopenharmony_ci rts 2818c2ecf20Sopenharmony_ci| 2828c2ecf20Sopenharmony_ci| Check the exponent for $c000 and the upper 32 bits of the 2838c2ecf20Sopenharmony_ci| mantissa for $ffffffff. If both are true, return d0 clr 2848c2ecf20Sopenharmony_ci| and store the lower n bits of the least lword of FPTEMP 2858c2ecf20Sopenharmony_ci| to d0 for write out. If not, it is a real operr, and set d0. 2868c2ecf20Sopenharmony_ci| 2878c2ecf20Sopenharmony_cicheck_upper: 2888c2ecf20Sopenharmony_ci cmpil #0xffffffff,FPTEMP_HI(%a6) |check if first byte is all 1's 2898c2ecf20Sopenharmony_ci bnes true_operr |if not all 1's then was true operr 2908c2ecf20Sopenharmony_ci cmpiw #0xc000,FPTEMP_EX(%a6) |check if incorrectly signalled 2918c2ecf20Sopenharmony_ci beqs not_true_operr |branch if not true operr 2928c2ecf20Sopenharmony_ci cmpiw #0xbfff,FPTEMP_EX(%a6) |check if incorrectly signalled 2938c2ecf20Sopenharmony_ci beqs not_true_operr |branch if not true operr 2948c2ecf20Sopenharmony_citrue_operr: 2958c2ecf20Sopenharmony_ci movel #1,%d0 |signal real operr 2968c2ecf20Sopenharmony_ci rts 2978c2ecf20Sopenharmony_cinot_true_operr: 2988c2ecf20Sopenharmony_ci clrl %d0 |signal no real operr 2998c2ecf20Sopenharmony_ci rts 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci| 3028c2ecf20Sopenharmony_ci| End_operr tests for operr enabled. If not, it cleans up the stack 3038c2ecf20Sopenharmony_ci| and does an rte. If enabled, it cleans up the stack and branches 3048c2ecf20Sopenharmony_ci| to the kernel operr handler with only the integer exception 3058c2ecf20Sopenharmony_ci| frame on the stack and the fpu in the original exceptional state 3068c2ecf20Sopenharmony_ci| with correct data written to the destination. 3078c2ecf20Sopenharmony_ci| 3088c2ecf20Sopenharmony_ciend_operr: 3098c2ecf20Sopenharmony_ci btstb #operr_bit,FPCR_ENABLE(%a6) 3108c2ecf20Sopenharmony_ci beqs not_enabled 3118c2ecf20Sopenharmony_cienabled: 3128c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 3138c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 3148c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 3158c2ecf20Sopenharmony_ci frestore (%a7)+ 3168c2ecf20Sopenharmony_ci unlk %a6 3178c2ecf20Sopenharmony_ci bral real_operr 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cinot_enabled: 3208c2ecf20Sopenharmony_ci| 3218c2ecf20Sopenharmony_ci| It is possible to have either inex2 or inex1 exceptions with the 3228c2ecf20Sopenharmony_ci| operr. If the inex enable bit is set in the FPCR, and either 3238c2ecf20Sopenharmony_ci| inex2 or inex1 occurred, we must clean up and branch to the 3248c2ecf20Sopenharmony_ci| real inex handler. 3258c2ecf20Sopenharmony_ci| 3268c2ecf20Sopenharmony_cick_inex: 3278c2ecf20Sopenharmony_ci moveb FPCR_ENABLE(%a6),%d0 3288c2ecf20Sopenharmony_ci andb FPSR_EXCEPT(%a6),%d0 3298c2ecf20Sopenharmony_ci andib #0x3,%d0 3308c2ecf20Sopenharmony_ci beq operr_exit 3318c2ecf20Sopenharmony_ci| 3328c2ecf20Sopenharmony_ci| Inexact enabled and reported, and we must take an inexact exception. 3338c2ecf20Sopenharmony_ci| 3348c2ecf20Sopenharmony_citake_inex: 3358c2ecf20Sopenharmony_ci moveb #INEX_VEC,EXC_VEC+1(%a6) 3368c2ecf20Sopenharmony_ci movel USER_FPSR(%a6),FPSR_SHADOW(%a6) 3378c2ecf20Sopenharmony_ci orl #sx_mask,E_BYTE(%a6) 3388c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 3398c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 3408c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 3418c2ecf20Sopenharmony_ci frestore (%a7)+ 3428c2ecf20Sopenharmony_ci unlk %a6 3438c2ecf20Sopenharmony_ci bral real_inex 3448c2ecf20Sopenharmony_ci| 3458c2ecf20Sopenharmony_ci| Since operr is only an E1 exception, there is no need to frestore 3468c2ecf20Sopenharmony_ci| any state back to the fpu. 3478c2ecf20Sopenharmony_ci| 3488c2ecf20Sopenharmony_cioperr_exit: 3498c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0-%d1/%a0-%a1 3508c2ecf20Sopenharmony_ci fmovemx USER_FP0(%a6),%fp0-%fp3 3518c2ecf20Sopenharmony_ci fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar 3528c2ecf20Sopenharmony_ci unlk %a6 3538c2ecf20Sopenharmony_ci bral fpsp_done 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci |end 356