18c2ecf20Sopenharmony_ci| 28c2ecf20Sopenharmony_ci| round.sa 3.4 7/29/91 38c2ecf20Sopenharmony_ci| 48c2ecf20Sopenharmony_ci| handle rounding and normalization tasks 58c2ecf20Sopenharmony_ci| 68c2ecf20Sopenharmony_ci| 78c2ecf20Sopenharmony_ci| 88c2ecf20Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 98c2ecf20Sopenharmony_ci| All Rights Reserved 108c2ecf20Sopenharmony_ci| 118c2ecf20Sopenharmony_ci| For details on the license for this file, please see the 128c2ecf20Sopenharmony_ci| file, README, in this same directory. 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci|ROUND idnt 2,1 | Motorola 040 Floating Point Software Package 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci |section 8 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "fpsp.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci| 218c2ecf20Sopenharmony_ci| round --- round result according to precision/mode 228c2ecf20Sopenharmony_ci| 238c2ecf20Sopenharmony_ci| a0 points to the input operand in the internal extended format 248c2ecf20Sopenharmony_ci| d1(high word) contains rounding precision: 258c2ecf20Sopenharmony_ci| ext = $0000xxxx 268c2ecf20Sopenharmony_ci| sgl = $0001xxxx 278c2ecf20Sopenharmony_ci| dbl = $0002xxxx 288c2ecf20Sopenharmony_ci| d1(low word) contains rounding mode: 298c2ecf20Sopenharmony_ci| RN = $xxxx0000 308c2ecf20Sopenharmony_ci| RZ = $xxxx0001 318c2ecf20Sopenharmony_ci| RM = $xxxx0010 328c2ecf20Sopenharmony_ci| RP = $xxxx0011 338c2ecf20Sopenharmony_ci| d0{31:29} contains the g,r,s bits (extended) 348c2ecf20Sopenharmony_ci| 358c2ecf20Sopenharmony_ci| On return the value pointed to by a0 is correctly rounded, 368c2ecf20Sopenharmony_ci| a0 is preserved and the g-r-s bits in d0 are cleared. 378c2ecf20Sopenharmony_ci| The result is not typed - the tag field is invalid. The 388c2ecf20Sopenharmony_ci| result is still in the internal extended format. 398c2ecf20Sopenharmony_ci| 408c2ecf20Sopenharmony_ci| The INEX bit of USER_FPSR will be set if the rounded result was 418c2ecf20Sopenharmony_ci| inexact (i.e. if any of the g-r-s bits were set). 428c2ecf20Sopenharmony_ci| 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci .global round 458c2ecf20Sopenharmony_ciround: 468c2ecf20Sopenharmony_ci| If g=r=s=0 then result is exact and round is done, else set 478c2ecf20Sopenharmony_ci| the inex flag in status reg and continue. 488c2ecf20Sopenharmony_ci| 498c2ecf20Sopenharmony_ci bsrs ext_grs |this subroutine looks at the 508c2ecf20Sopenharmony_ci| :rounding precision and sets 518c2ecf20Sopenharmony_ci| ;the appropriate g-r-s bits. 528c2ecf20Sopenharmony_ci tstl %d0 |if grs are zero, go force 538c2ecf20Sopenharmony_ci bne rnd_cont |lower bits to zero for size 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci swap %d1 |set up d1.w for round prec. 568c2ecf20Sopenharmony_ci bra truncate 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cirnd_cont: 598c2ecf20Sopenharmony_ci| 608c2ecf20Sopenharmony_ci| Use rounding mode as an index into a jump table for these modes. 618c2ecf20Sopenharmony_ci| 628c2ecf20Sopenharmony_ci orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 638c2ecf20Sopenharmony_ci lea mode_tab,%a1 648c2ecf20Sopenharmony_ci movel (%a1,%d1.w*4),%a1 658c2ecf20Sopenharmony_ci jmp (%a1) 668c2ecf20Sopenharmony_ci| 678c2ecf20Sopenharmony_ci| Jump table indexed by rounding mode in d1.w. All following assumes 688c2ecf20Sopenharmony_ci| grs != 0. 698c2ecf20Sopenharmony_ci| 708c2ecf20Sopenharmony_cimode_tab: 718c2ecf20Sopenharmony_ci .long rnd_near 728c2ecf20Sopenharmony_ci .long rnd_zero 738c2ecf20Sopenharmony_ci .long rnd_mnus 748c2ecf20Sopenharmony_ci .long rnd_plus 758c2ecf20Sopenharmony_ci| 768c2ecf20Sopenharmony_ci| ROUND PLUS INFINITY 778c2ecf20Sopenharmony_ci| 788c2ecf20Sopenharmony_ci| If sign of fp number = 0 (positive), then add 1 to l. 798c2ecf20Sopenharmony_ci| 808c2ecf20Sopenharmony_cirnd_plus: 818c2ecf20Sopenharmony_ci swap %d1 |set up d1 for round prec. 828c2ecf20Sopenharmony_ci tstb LOCAL_SGN(%a0) |check for sign 838c2ecf20Sopenharmony_ci bmi truncate |if positive then truncate 848c2ecf20Sopenharmony_ci movel #0xffffffff,%d0 |force g,r,s to be all f's 858c2ecf20Sopenharmony_ci lea add_to_l,%a1 868c2ecf20Sopenharmony_ci movel (%a1,%d1.w*4),%a1 878c2ecf20Sopenharmony_ci jmp (%a1) 888c2ecf20Sopenharmony_ci| 898c2ecf20Sopenharmony_ci| ROUND MINUS INFINITY 908c2ecf20Sopenharmony_ci| 918c2ecf20Sopenharmony_ci| If sign of fp number = 1 (negative), then add 1 to l. 928c2ecf20Sopenharmony_ci| 938c2ecf20Sopenharmony_cirnd_mnus: 948c2ecf20Sopenharmony_ci swap %d1 |set up d1 for round prec. 958c2ecf20Sopenharmony_ci tstb LOCAL_SGN(%a0) |check for sign 968c2ecf20Sopenharmony_ci bpl truncate |if negative then truncate 978c2ecf20Sopenharmony_ci movel #0xffffffff,%d0 |force g,r,s to be all f's 988c2ecf20Sopenharmony_ci lea add_to_l,%a1 998c2ecf20Sopenharmony_ci movel (%a1,%d1.w*4),%a1 1008c2ecf20Sopenharmony_ci jmp (%a1) 1018c2ecf20Sopenharmony_ci| 1028c2ecf20Sopenharmony_ci| ROUND ZERO 1038c2ecf20Sopenharmony_ci| 1048c2ecf20Sopenharmony_ci| Always truncate. 1058c2ecf20Sopenharmony_cirnd_zero: 1068c2ecf20Sopenharmony_ci swap %d1 |set up d1 for round prec. 1078c2ecf20Sopenharmony_ci bra truncate 1088c2ecf20Sopenharmony_ci| 1098c2ecf20Sopenharmony_ci| 1108c2ecf20Sopenharmony_ci| ROUND NEAREST 1118c2ecf20Sopenharmony_ci| 1128c2ecf20Sopenharmony_ci| If (g=1), then add 1 to l and if (r=s=0), then clear l 1138c2ecf20Sopenharmony_ci| Note that this will round to even in case of a tie. 1148c2ecf20Sopenharmony_ci| 1158c2ecf20Sopenharmony_cirnd_near: 1168c2ecf20Sopenharmony_ci swap %d1 |set up d1 for round prec. 1178c2ecf20Sopenharmony_ci asll #1,%d0 |shift g-bit to c-bit 1188c2ecf20Sopenharmony_ci bcc truncate |if (g=1) then 1198c2ecf20Sopenharmony_ci lea add_to_l,%a1 1208c2ecf20Sopenharmony_ci movel (%a1,%d1.w*4),%a1 1218c2ecf20Sopenharmony_ci jmp (%a1) 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci| 1248c2ecf20Sopenharmony_ci| ext_grs --- extract guard, round and sticky bits 1258c2ecf20Sopenharmony_ci| 1268c2ecf20Sopenharmony_ci| Input: d1 = PREC:ROUND 1278c2ecf20Sopenharmony_ci| Output: d0{31:29}= guard, round, sticky 1288c2ecf20Sopenharmony_ci| 1298c2ecf20Sopenharmony_ci| The ext_grs extract the guard/round/sticky bits according to the 1308c2ecf20Sopenharmony_ci| selected rounding precision. It is called by the round subroutine 1318c2ecf20Sopenharmony_ci| only. All registers except d0 are kept intact. d0 becomes an 1328c2ecf20Sopenharmony_ci| updated guard,round,sticky in d0{31:29} 1338c2ecf20Sopenharmony_ci| 1348c2ecf20Sopenharmony_ci| Notes: the ext_grs uses the round PREC, and therefore has to swap d1 1358c2ecf20Sopenharmony_ci| prior to usage, and needs to restore d1 to original. 1368c2ecf20Sopenharmony_ci| 1378c2ecf20Sopenharmony_ciext_grs: 1388c2ecf20Sopenharmony_ci swap %d1 |have d1.w point to round precision 1398c2ecf20Sopenharmony_ci cmpiw #0,%d1 1408c2ecf20Sopenharmony_ci bnes sgl_or_dbl 1418c2ecf20Sopenharmony_ci bras end_ext_grs 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cisgl_or_dbl: 1448c2ecf20Sopenharmony_ci moveml %d2/%d3,-(%a7) |make some temp registers 1458c2ecf20Sopenharmony_ci cmpiw #1,%d1 1468c2ecf20Sopenharmony_ci bnes grs_dbl 1478c2ecf20Sopenharmony_cigrs_sgl: 1488c2ecf20Sopenharmony_ci bfextu LOCAL_HI(%a0){#24:#2},%d3 |sgl prec. g-r are 2 bits right 1498c2ecf20Sopenharmony_ci movel #30,%d2 |of the sgl prec. limits 1508c2ecf20Sopenharmony_ci lsll %d2,%d3 |shift g-r bits to MSB of d3 1518c2ecf20Sopenharmony_ci movel LOCAL_HI(%a0),%d2 |get word 2 for s-bit test 1528c2ecf20Sopenharmony_ci andil #0x0000003f,%d2 |s bit is the or of all other 1538c2ecf20Sopenharmony_ci bnes st_stky |bits to the right of g-r 1548c2ecf20Sopenharmony_ci tstl LOCAL_LO(%a0) |test lower mantissa 1558c2ecf20Sopenharmony_ci bnes st_stky |if any are set, set sticky 1568c2ecf20Sopenharmony_ci tstl %d0 |test original g,r,s 1578c2ecf20Sopenharmony_ci bnes st_stky |if any are set, set sticky 1588c2ecf20Sopenharmony_ci bras end_sd |if words 3 and 4 are clr, exit 1598c2ecf20Sopenharmony_cigrs_dbl: 1608c2ecf20Sopenharmony_ci bfextu LOCAL_LO(%a0){#21:#2},%d3 |dbl-prec. g-r are 2 bits right 1618c2ecf20Sopenharmony_ci movel #30,%d2 |of the dbl prec. limits 1628c2ecf20Sopenharmony_ci lsll %d2,%d3 |shift g-r bits to the MSB of d3 1638c2ecf20Sopenharmony_ci movel LOCAL_LO(%a0),%d2 |get lower mantissa for s-bit test 1648c2ecf20Sopenharmony_ci andil #0x000001ff,%d2 |s bit is the or-ing of all 1658c2ecf20Sopenharmony_ci bnes st_stky |other bits to the right of g-r 1668c2ecf20Sopenharmony_ci tstl %d0 |test word original g,r,s 1678c2ecf20Sopenharmony_ci bnes st_stky |if any are set, set sticky 1688c2ecf20Sopenharmony_ci bras end_sd |if clear, exit 1698c2ecf20Sopenharmony_cist_stky: 1708c2ecf20Sopenharmony_ci bset #rnd_stky_bit,%d3 1718c2ecf20Sopenharmony_ciend_sd: 1728c2ecf20Sopenharmony_ci movel %d3,%d0 |return grs to d0 1738c2ecf20Sopenharmony_ci moveml (%a7)+,%d2/%d3 |restore scratch registers 1748c2ecf20Sopenharmony_ciend_ext_grs: 1758c2ecf20Sopenharmony_ci swap %d1 |restore d1 to original 1768c2ecf20Sopenharmony_ci rts 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci|******************* Local Equates 1798c2ecf20Sopenharmony_ci .set ad_1_sgl,0x00000100 | constant to add 1 to l-bit in sgl prec 1808c2ecf20Sopenharmony_ci .set ad_1_dbl,0x00000800 | constant to add 1 to l-bit in dbl prec 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci|Jump table for adding 1 to the l-bit indexed by rnd prec 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ciadd_to_l: 1868c2ecf20Sopenharmony_ci .long add_ext 1878c2ecf20Sopenharmony_ci .long add_sgl 1888c2ecf20Sopenharmony_ci .long add_dbl 1898c2ecf20Sopenharmony_ci .long add_dbl 1908c2ecf20Sopenharmony_ci| 1918c2ecf20Sopenharmony_ci| ADD SINGLE 1928c2ecf20Sopenharmony_ci| 1938c2ecf20Sopenharmony_ciadd_sgl: 1948c2ecf20Sopenharmony_ci addl #ad_1_sgl,LOCAL_HI(%a0) 1958c2ecf20Sopenharmony_ci bccs scc_clr |no mantissa overflow 1968c2ecf20Sopenharmony_ci roxrw LOCAL_HI(%a0) |shift v-bit back in 1978c2ecf20Sopenharmony_ci roxrw LOCAL_HI+2(%a0) |shift v-bit back in 1988c2ecf20Sopenharmony_ci addw #0x1,LOCAL_EX(%a0) |and incr exponent 1998c2ecf20Sopenharmony_ciscc_clr: 2008c2ecf20Sopenharmony_ci tstl %d0 |test for rs = 0 2018c2ecf20Sopenharmony_ci bnes sgl_done 2028c2ecf20Sopenharmony_ci andiw #0xfe00,LOCAL_HI+2(%a0) |clear the l-bit 2038c2ecf20Sopenharmony_cisgl_done: 2048c2ecf20Sopenharmony_ci andil #0xffffff00,LOCAL_HI(%a0) |truncate bits beyond sgl limit 2058c2ecf20Sopenharmony_ci clrl LOCAL_LO(%a0) |clear d2 2068c2ecf20Sopenharmony_ci rts 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci| 2098c2ecf20Sopenharmony_ci| ADD EXTENDED 2108c2ecf20Sopenharmony_ci| 2118c2ecf20Sopenharmony_ciadd_ext: 2128c2ecf20Sopenharmony_ci addql #1,LOCAL_LO(%a0) |add 1 to l-bit 2138c2ecf20Sopenharmony_ci bccs xcc_clr |test for carry out 2148c2ecf20Sopenharmony_ci addql #1,LOCAL_HI(%a0) |propagate carry 2158c2ecf20Sopenharmony_ci bccs xcc_clr 2168c2ecf20Sopenharmony_ci roxrw LOCAL_HI(%a0) |mant is 0 so restore v-bit 2178c2ecf20Sopenharmony_ci roxrw LOCAL_HI+2(%a0) |mant is 0 so restore v-bit 2188c2ecf20Sopenharmony_ci roxrw LOCAL_LO(%a0) 2198c2ecf20Sopenharmony_ci roxrw LOCAL_LO+2(%a0) 2208c2ecf20Sopenharmony_ci addw #0x1,LOCAL_EX(%a0) |and inc exp 2218c2ecf20Sopenharmony_cixcc_clr: 2228c2ecf20Sopenharmony_ci tstl %d0 |test rs = 0 2238c2ecf20Sopenharmony_ci bnes add_ext_done 2248c2ecf20Sopenharmony_ci andib #0xfe,LOCAL_LO+3(%a0) |clear the l bit 2258c2ecf20Sopenharmony_ciadd_ext_done: 2268c2ecf20Sopenharmony_ci rts 2278c2ecf20Sopenharmony_ci| 2288c2ecf20Sopenharmony_ci| ADD DOUBLE 2298c2ecf20Sopenharmony_ci| 2308c2ecf20Sopenharmony_ciadd_dbl: 2318c2ecf20Sopenharmony_ci addl #ad_1_dbl,LOCAL_LO(%a0) 2328c2ecf20Sopenharmony_ci bccs dcc_clr 2338c2ecf20Sopenharmony_ci addql #1,LOCAL_HI(%a0) |propagate carry 2348c2ecf20Sopenharmony_ci bccs dcc_clr 2358c2ecf20Sopenharmony_ci roxrw LOCAL_HI(%a0) |mant is 0 so restore v-bit 2368c2ecf20Sopenharmony_ci roxrw LOCAL_HI+2(%a0) |mant is 0 so restore v-bit 2378c2ecf20Sopenharmony_ci roxrw LOCAL_LO(%a0) 2388c2ecf20Sopenharmony_ci roxrw LOCAL_LO+2(%a0) 2398c2ecf20Sopenharmony_ci addw #0x1,LOCAL_EX(%a0) |incr exponent 2408c2ecf20Sopenharmony_cidcc_clr: 2418c2ecf20Sopenharmony_ci tstl %d0 |test for rs = 0 2428c2ecf20Sopenharmony_ci bnes dbl_done 2438c2ecf20Sopenharmony_ci andiw #0xf000,LOCAL_LO+2(%a0) |clear the l-bit 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cidbl_done: 2468c2ecf20Sopenharmony_ci andil #0xfffff800,LOCAL_LO(%a0) |truncate bits beyond dbl limit 2478c2ecf20Sopenharmony_ci rts 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cierror: 2508c2ecf20Sopenharmony_ci rts 2518c2ecf20Sopenharmony_ci| 2528c2ecf20Sopenharmony_ci| Truncate all other bits 2538c2ecf20Sopenharmony_ci| 2548c2ecf20Sopenharmony_citrunct: 2558c2ecf20Sopenharmony_ci .long end_rnd 2568c2ecf20Sopenharmony_ci .long sgl_done 2578c2ecf20Sopenharmony_ci .long dbl_done 2588c2ecf20Sopenharmony_ci .long dbl_done 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_citruncate: 2618c2ecf20Sopenharmony_ci lea trunct,%a1 2628c2ecf20Sopenharmony_ci movel (%a1,%d1.w*4),%a1 2638c2ecf20Sopenharmony_ci jmp (%a1) 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ciend_rnd: 2668c2ecf20Sopenharmony_ci rts 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci| 2698c2ecf20Sopenharmony_ci| NORMALIZE 2708c2ecf20Sopenharmony_ci| 2718c2ecf20Sopenharmony_ci| These routines (nrm_zero & nrm_set) normalize the unnorm. This 2728c2ecf20Sopenharmony_ci| is done by shifting the mantissa left while decrementing the 2738c2ecf20Sopenharmony_ci| exponent. 2748c2ecf20Sopenharmony_ci| 2758c2ecf20Sopenharmony_ci| NRM_SET shifts and decrements until there is a 1 set in the integer 2768c2ecf20Sopenharmony_ci| bit of the mantissa (msb in d1). 2778c2ecf20Sopenharmony_ci| 2788c2ecf20Sopenharmony_ci| NRM_ZERO shifts and decrements until there is a 1 set in the integer 2798c2ecf20Sopenharmony_ci| bit of the mantissa (msb in d1) unless this would mean the exponent 2808c2ecf20Sopenharmony_ci| would go less than 0. In that case the number becomes a denorm - the 2818c2ecf20Sopenharmony_ci| exponent (d0) is set to 0 and the mantissa (d1 & d2) is not 2828c2ecf20Sopenharmony_ci| normalized. 2838c2ecf20Sopenharmony_ci| 2848c2ecf20Sopenharmony_ci| Note that both routines have been optimized (for the worst case) and 2858c2ecf20Sopenharmony_ci| therefore do not have the easy to follow decrement/shift loop. 2868c2ecf20Sopenharmony_ci| 2878c2ecf20Sopenharmony_ci| NRM_ZERO 2888c2ecf20Sopenharmony_ci| 2898c2ecf20Sopenharmony_ci| Distance to first 1 bit in mantissa = X 2908c2ecf20Sopenharmony_ci| Distance to 0 from exponent = Y 2918c2ecf20Sopenharmony_ci| If X < Y 2928c2ecf20Sopenharmony_ci| Then 2938c2ecf20Sopenharmony_ci| nrm_set 2948c2ecf20Sopenharmony_ci| Else 2958c2ecf20Sopenharmony_ci| shift mantissa by Y 2968c2ecf20Sopenharmony_ci| set exponent = 0 2978c2ecf20Sopenharmony_ci| 2988c2ecf20Sopenharmony_ci|input: 2998c2ecf20Sopenharmony_ci| FP_SCR1 = exponent, ms mantissa part, ls mantissa part 3008c2ecf20Sopenharmony_ci|output: 3018c2ecf20Sopenharmony_ci| L_SCR1{4} = fpte15 or ete15 bit 3028c2ecf20Sopenharmony_ci| 3038c2ecf20Sopenharmony_ci .global nrm_zero 3048c2ecf20Sopenharmony_cinrm_zero: 3058c2ecf20Sopenharmony_ci movew LOCAL_EX(%a0),%d0 3068c2ecf20Sopenharmony_ci cmpw #64,%d0 |see if exp > 64 3078c2ecf20Sopenharmony_ci bmis d0_less 3088c2ecf20Sopenharmony_ci bsr nrm_set |exp > 64 so exp won't exceed 0 3098c2ecf20Sopenharmony_ci rts 3108c2ecf20Sopenharmony_cid0_less: 3118c2ecf20Sopenharmony_ci moveml %d2/%d3/%d5/%d6,-(%a7) 3128c2ecf20Sopenharmony_ci movel LOCAL_HI(%a0),%d1 3138c2ecf20Sopenharmony_ci movel LOCAL_LO(%a0),%d2 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci bfffo %d1{#0:#32},%d3 |get the distance to the first 1 3168c2ecf20Sopenharmony_ci| ;in ms mant 3178c2ecf20Sopenharmony_ci beqs ms_clr |branch if no bits were set 3188c2ecf20Sopenharmony_ci cmpw %d3,%d0 |of X>Y 3198c2ecf20Sopenharmony_ci bmis greater |then exp will go past 0 (neg) if 3208c2ecf20Sopenharmony_ci| ;it is just shifted 3218c2ecf20Sopenharmony_ci bsr nrm_set |else exp won't go past 0 3228c2ecf20Sopenharmony_ci moveml (%a7)+,%d2/%d3/%d5/%d6 3238c2ecf20Sopenharmony_ci rts 3248c2ecf20Sopenharmony_cigreater: 3258c2ecf20Sopenharmony_ci movel %d2,%d6 |save ls mant in d6 3268c2ecf20Sopenharmony_ci lsll %d0,%d2 |shift ls mant by count 3278c2ecf20Sopenharmony_ci lsll %d0,%d1 |shift ms mant by count 3288c2ecf20Sopenharmony_ci movel #32,%d5 3298c2ecf20Sopenharmony_ci subl %d0,%d5 |make op a denorm by shifting bits 3308c2ecf20Sopenharmony_ci lsrl %d5,%d6 |by the number in the exp, then 3318c2ecf20Sopenharmony_ci| ;set exp = 0. 3328c2ecf20Sopenharmony_ci orl %d6,%d1 |shift the ls mant bits into the ms mant 3338c2ecf20Sopenharmony_ci movel #0,%d0 |same as if decremented exp to 0 3348c2ecf20Sopenharmony_ci| ;while shifting 3358c2ecf20Sopenharmony_ci movew %d0,LOCAL_EX(%a0) 3368c2ecf20Sopenharmony_ci movel %d1,LOCAL_HI(%a0) 3378c2ecf20Sopenharmony_ci movel %d2,LOCAL_LO(%a0) 3388c2ecf20Sopenharmony_ci moveml (%a7)+,%d2/%d3/%d5/%d6 3398c2ecf20Sopenharmony_ci rts 3408c2ecf20Sopenharmony_cims_clr: 3418c2ecf20Sopenharmony_ci bfffo %d2{#0:#32},%d3 |check if any bits set in ls mant 3428c2ecf20Sopenharmony_ci beqs all_clr |branch if none set 3438c2ecf20Sopenharmony_ci addw #32,%d3 3448c2ecf20Sopenharmony_ci cmpw %d3,%d0 |if X>Y 3458c2ecf20Sopenharmony_ci bmis greater |then branch 3468c2ecf20Sopenharmony_ci bsr nrm_set |else exp won't go past 0 3478c2ecf20Sopenharmony_ci moveml (%a7)+,%d2/%d3/%d5/%d6 3488c2ecf20Sopenharmony_ci rts 3498c2ecf20Sopenharmony_ciall_clr: 3508c2ecf20Sopenharmony_ci movew #0,LOCAL_EX(%a0) |no mantissa bits set. Set exp = 0. 3518c2ecf20Sopenharmony_ci moveml (%a7)+,%d2/%d3/%d5/%d6 3528c2ecf20Sopenharmony_ci rts 3538c2ecf20Sopenharmony_ci| 3548c2ecf20Sopenharmony_ci| NRM_SET 3558c2ecf20Sopenharmony_ci| 3568c2ecf20Sopenharmony_ci .global nrm_set 3578c2ecf20Sopenharmony_cinrm_set: 3588c2ecf20Sopenharmony_ci movel %d7,-(%a7) 3598c2ecf20Sopenharmony_ci bfffo LOCAL_HI(%a0){#0:#32},%d7 |find first 1 in ms mant to d7) 3608c2ecf20Sopenharmony_ci beqs lower |branch if ms mant is all 0's 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci movel %d6,-(%a7) 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci subw %d7,LOCAL_EX(%a0) |sub exponent by count 3658c2ecf20Sopenharmony_ci movel LOCAL_HI(%a0),%d0 |d0 has ms mant 3668c2ecf20Sopenharmony_ci movel LOCAL_LO(%a0),%d1 |d1 has ls mant 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci lsll %d7,%d0 |shift first 1 to j bit position 3698c2ecf20Sopenharmony_ci movel %d1,%d6 |copy ls mant into d6 3708c2ecf20Sopenharmony_ci lsll %d7,%d6 |shift ls mant by count 3718c2ecf20Sopenharmony_ci movel %d6,LOCAL_LO(%a0) |store ls mant into memory 3728c2ecf20Sopenharmony_ci moveql #32,%d6 3738c2ecf20Sopenharmony_ci subl %d7,%d6 |continue shift 3748c2ecf20Sopenharmony_ci lsrl %d6,%d1 |shift off all bits but those that will 3758c2ecf20Sopenharmony_ci| ;be shifted into ms mant 3768c2ecf20Sopenharmony_ci orl %d1,%d0 |shift the ls mant bits into the ms mant 3778c2ecf20Sopenharmony_ci movel %d0,LOCAL_HI(%a0) |store ms mant into memory 3788c2ecf20Sopenharmony_ci moveml (%a7)+,%d7/%d6 |restore registers 3798c2ecf20Sopenharmony_ci rts 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci| 3828c2ecf20Sopenharmony_ci| We get here if ms mant was = 0, and we assume ls mant has bits 3838c2ecf20Sopenharmony_ci| set (otherwise this would have been tagged a zero not a denorm). 3848c2ecf20Sopenharmony_ci| 3858c2ecf20Sopenharmony_cilower: 3868c2ecf20Sopenharmony_ci movew LOCAL_EX(%a0),%d0 |d0 has exponent 3878c2ecf20Sopenharmony_ci movel LOCAL_LO(%a0),%d1 |d1 has ls mant 3888c2ecf20Sopenharmony_ci subw #32,%d0 |account for ms mant being all zeros 3898c2ecf20Sopenharmony_ci bfffo %d1{#0:#32},%d7 |find first 1 in ls mant to d7) 3908c2ecf20Sopenharmony_ci subw %d7,%d0 |subtract shift count from exp 3918c2ecf20Sopenharmony_ci lsll %d7,%d1 |shift first 1 to integer bit in ms mant 3928c2ecf20Sopenharmony_ci movew %d0,LOCAL_EX(%a0) |store ms mant 3938c2ecf20Sopenharmony_ci movel %d1,LOCAL_HI(%a0) |store exp 3948c2ecf20Sopenharmony_ci clrl LOCAL_LO(%a0) |clear ls mant 3958c2ecf20Sopenharmony_ci movel (%a7)+,%d7 3968c2ecf20Sopenharmony_ci rts 3978c2ecf20Sopenharmony_ci| 3988c2ecf20Sopenharmony_ci| denorm --- denormalize an intermediate result 3998c2ecf20Sopenharmony_ci| 4008c2ecf20Sopenharmony_ci| Used by underflow. 4018c2ecf20Sopenharmony_ci| 4028c2ecf20Sopenharmony_ci| Input: 4038c2ecf20Sopenharmony_ci| a0 points to the operand to be denormalized 4048c2ecf20Sopenharmony_ci| (in the internal extended format) 4058c2ecf20Sopenharmony_ci| 4068c2ecf20Sopenharmony_ci| d0: rounding precision 4078c2ecf20Sopenharmony_ci| Output: 4088c2ecf20Sopenharmony_ci| a0 points to the denormalized result 4098c2ecf20Sopenharmony_ci| (in the internal extended format) 4108c2ecf20Sopenharmony_ci| 4118c2ecf20Sopenharmony_ci| d0 is guard,round,sticky 4128c2ecf20Sopenharmony_ci| 4138c2ecf20Sopenharmony_ci| d0 comes into this routine with the rounding precision. It 4148c2ecf20Sopenharmony_ci| is then loaded with the denormalized exponent threshold for the 4158c2ecf20Sopenharmony_ci| rounding precision. 4168c2ecf20Sopenharmony_ci| 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci .global denorm 4198c2ecf20Sopenharmony_cidenorm: 4208c2ecf20Sopenharmony_ci btstb #6,LOCAL_EX(%a0) |check for exponents between $7fff-$4000 4218c2ecf20Sopenharmony_ci beqs no_sgn_ext 4228c2ecf20Sopenharmony_ci bsetb #7,LOCAL_EX(%a0) |sign extend if it is so 4238c2ecf20Sopenharmony_cino_sgn_ext: 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci cmpib #0,%d0 |if 0 then extended precision 4268c2ecf20Sopenharmony_ci bnes not_ext |else branch 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci clrl %d1 |load d1 with ext threshold 4298c2ecf20Sopenharmony_ci clrl %d0 |clear the sticky flag 4308c2ecf20Sopenharmony_ci bsr dnrm_lp |denormalize the number 4318c2ecf20Sopenharmony_ci tstb %d1 |check for inex 4328c2ecf20Sopenharmony_ci beq no_inex |if clr, no inex 4338c2ecf20Sopenharmony_ci bras dnrm_inex |if set, set inex 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_cinot_ext: 4368c2ecf20Sopenharmony_ci cmpil #1,%d0 |if 1 then single precision 4378c2ecf20Sopenharmony_ci beqs load_sgl |else must be 2, double prec 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ciload_dbl: 4408c2ecf20Sopenharmony_ci movew #dbl_thresh,%d1 |put copy of threshold in d1 4418c2ecf20Sopenharmony_ci movel %d1,%d0 |copy d1 into d0 4428c2ecf20Sopenharmony_ci subw LOCAL_EX(%a0),%d0 |diff = threshold - exp 4438c2ecf20Sopenharmony_ci cmpw #67,%d0 |if diff > 67 (mant + grs bits) 4448c2ecf20Sopenharmony_ci bpls chk_stky |then branch (all bits would be 4458c2ecf20Sopenharmony_ci| ; shifted off in denorm routine) 4468c2ecf20Sopenharmony_ci clrl %d0 |else clear the sticky flag 4478c2ecf20Sopenharmony_ci bsr dnrm_lp |denormalize the number 4488c2ecf20Sopenharmony_ci tstb %d1 |check flag 4498c2ecf20Sopenharmony_ci beqs no_inex |if clr, no inex 4508c2ecf20Sopenharmony_ci bras dnrm_inex |if set, set inex 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ciload_sgl: 4538c2ecf20Sopenharmony_ci movew #sgl_thresh,%d1 |put copy of threshold in d1 4548c2ecf20Sopenharmony_ci movel %d1,%d0 |copy d1 into d0 4558c2ecf20Sopenharmony_ci subw LOCAL_EX(%a0),%d0 |diff = threshold - exp 4568c2ecf20Sopenharmony_ci cmpw #67,%d0 |if diff > 67 (mant + grs bits) 4578c2ecf20Sopenharmony_ci bpls chk_stky |then branch (all bits would be 4588c2ecf20Sopenharmony_ci| ; shifted off in denorm routine) 4598c2ecf20Sopenharmony_ci clrl %d0 |else clear the sticky flag 4608c2ecf20Sopenharmony_ci bsr dnrm_lp |denormalize the number 4618c2ecf20Sopenharmony_ci tstb %d1 |check flag 4628c2ecf20Sopenharmony_ci beqs no_inex |if clr, no inex 4638c2ecf20Sopenharmony_ci bras dnrm_inex |if set, set inex 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cichk_stky: 4668c2ecf20Sopenharmony_ci tstl LOCAL_HI(%a0) |check for any bits set 4678c2ecf20Sopenharmony_ci bnes set_stky 4688c2ecf20Sopenharmony_ci tstl LOCAL_LO(%a0) |check for any bits set 4698c2ecf20Sopenharmony_ci bnes set_stky 4708c2ecf20Sopenharmony_ci bras clr_mant 4718c2ecf20Sopenharmony_ciset_stky: 4728c2ecf20Sopenharmony_ci orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 4738c2ecf20Sopenharmony_ci movel #0x20000000,%d0 |set sticky bit in return value 4748c2ecf20Sopenharmony_ciclr_mant: 4758c2ecf20Sopenharmony_ci movew %d1,LOCAL_EX(%a0) |load exp with threshold 4768c2ecf20Sopenharmony_ci movel #0,LOCAL_HI(%a0) |set d1 = 0 (ms mantissa) 4778c2ecf20Sopenharmony_ci movel #0,LOCAL_LO(%a0) |set d2 = 0 (ms mantissa) 4788c2ecf20Sopenharmony_ci rts 4798c2ecf20Sopenharmony_cidnrm_inex: 4808c2ecf20Sopenharmony_ci orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 4818c2ecf20Sopenharmony_cino_inex: 4828c2ecf20Sopenharmony_ci rts 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci| 4858c2ecf20Sopenharmony_ci| dnrm_lp --- normalize exponent/mantissa to specified threshold 4868c2ecf20Sopenharmony_ci| 4878c2ecf20Sopenharmony_ci| Input: 4888c2ecf20Sopenharmony_ci| a0 points to the operand to be denormalized 4898c2ecf20Sopenharmony_ci| d0{31:29} initial guard,round,sticky 4908c2ecf20Sopenharmony_ci| d1{15:0} denormalization threshold 4918c2ecf20Sopenharmony_ci| Output: 4928c2ecf20Sopenharmony_ci| a0 points to the denormalized operand 4938c2ecf20Sopenharmony_ci| d0{31:29} final guard,round,sticky 4948c2ecf20Sopenharmony_ci| d1.b inexact flag: all ones means inexact result 4958c2ecf20Sopenharmony_ci| 4968c2ecf20Sopenharmony_ci| The LOCAL_LO and LOCAL_GRS parts of the value are copied to FP_SCR2 4978c2ecf20Sopenharmony_ci| so that bfext can be used to extract the new low part of the mantissa. 4988c2ecf20Sopenharmony_ci| Dnrm_lp can be called with a0 pointing to ETEMP or WBTEMP and there 4998c2ecf20Sopenharmony_ci| is no LOCAL_GRS scratch word following it on the fsave frame. 5008c2ecf20Sopenharmony_ci| 5018c2ecf20Sopenharmony_ci .global dnrm_lp 5028c2ecf20Sopenharmony_cidnrm_lp: 5038c2ecf20Sopenharmony_ci movel %d2,-(%sp) |save d2 for temp use 5048c2ecf20Sopenharmony_ci btstb #E3,E_BYTE(%a6) |test for type E3 exception 5058c2ecf20Sopenharmony_ci beqs not_E3 |not type E3 exception 5068c2ecf20Sopenharmony_ci bfextu WBTEMP_GRS(%a6){#6:#3},%d2 |extract guard,round, sticky bit 5078c2ecf20Sopenharmony_ci movel #29,%d0 5088c2ecf20Sopenharmony_ci lsll %d0,%d2 |shift g,r,s to their positions 5098c2ecf20Sopenharmony_ci movel %d2,%d0 5108c2ecf20Sopenharmony_cinot_E3: 5118c2ecf20Sopenharmony_ci movel (%sp)+,%d2 |restore d2 5128c2ecf20Sopenharmony_ci movel LOCAL_LO(%a0),FP_SCR2+LOCAL_LO(%a6) 5138c2ecf20Sopenharmony_ci movel %d0,FP_SCR2+LOCAL_GRS(%a6) 5148c2ecf20Sopenharmony_ci movel %d1,%d0 |copy the denorm threshold 5158c2ecf20Sopenharmony_ci subw LOCAL_EX(%a0),%d1 |d1 = threshold - uns exponent 5168c2ecf20Sopenharmony_ci bles no_lp |d1 <= 0 5178c2ecf20Sopenharmony_ci cmpw #32,%d1 5188c2ecf20Sopenharmony_ci blts case_1 |0 = d1 < 32 5198c2ecf20Sopenharmony_ci cmpw #64,%d1 5208c2ecf20Sopenharmony_ci blts case_2 |32 <= d1 < 64 5218c2ecf20Sopenharmony_ci bra case_3 |d1 >= 64 5228c2ecf20Sopenharmony_ci| 5238c2ecf20Sopenharmony_ci| No normalization necessary 5248c2ecf20Sopenharmony_ci| 5258c2ecf20Sopenharmony_cino_lp: 5268c2ecf20Sopenharmony_ci clrb %d1 |set no inex2 reported 5278c2ecf20Sopenharmony_ci movel FP_SCR2+LOCAL_GRS(%a6),%d0 |restore original g,r,s 5288c2ecf20Sopenharmony_ci rts 5298c2ecf20Sopenharmony_ci| 5308c2ecf20Sopenharmony_ci| case (0<d1<32) 5318c2ecf20Sopenharmony_ci| 5328c2ecf20Sopenharmony_cicase_1: 5338c2ecf20Sopenharmony_ci movel %d2,-(%sp) 5348c2ecf20Sopenharmony_ci movew %d0,LOCAL_EX(%a0) |exponent = denorm threshold 5358c2ecf20Sopenharmony_ci movel #32,%d0 5368c2ecf20Sopenharmony_ci subw %d1,%d0 |d0 = 32 - d1 5378c2ecf20Sopenharmony_ci bfextu LOCAL_EX(%a0){%d0:#32},%d2 5388c2ecf20Sopenharmony_ci bfextu %d2{%d1:%d0},%d2 |d2 = new LOCAL_HI 5398c2ecf20Sopenharmony_ci bfextu LOCAL_HI(%a0){%d0:#32},%d1 |d1 = new LOCAL_LO 5408c2ecf20Sopenharmony_ci bfextu FP_SCR2+LOCAL_LO(%a6){%d0:#32},%d0 |d0 = new G,R,S 5418c2ecf20Sopenharmony_ci movel %d2,LOCAL_HI(%a0) |store new LOCAL_HI 5428c2ecf20Sopenharmony_ci movel %d1,LOCAL_LO(%a0) |store new LOCAL_LO 5438c2ecf20Sopenharmony_ci clrb %d1 5448c2ecf20Sopenharmony_ci bftst %d0{#2:#30} 5458c2ecf20Sopenharmony_ci beqs c1nstky 5468c2ecf20Sopenharmony_ci bsetl #rnd_stky_bit,%d0 5478c2ecf20Sopenharmony_ci st %d1 5488c2ecf20Sopenharmony_cic1nstky: 5498c2ecf20Sopenharmony_ci movel FP_SCR2+LOCAL_GRS(%a6),%d2 |restore original g,r,s 5508c2ecf20Sopenharmony_ci andil #0xe0000000,%d2 |clear all but G,R,S 5518c2ecf20Sopenharmony_ci tstl %d2 |test if original G,R,S are clear 5528c2ecf20Sopenharmony_ci beqs grs_clear 5538c2ecf20Sopenharmony_ci orl #0x20000000,%d0 |set sticky bit in d0 5548c2ecf20Sopenharmony_cigrs_clear: 5558c2ecf20Sopenharmony_ci andil #0xe0000000,%d0 |clear all but G,R,S 5568c2ecf20Sopenharmony_ci movel (%sp)+,%d2 5578c2ecf20Sopenharmony_ci rts 5588c2ecf20Sopenharmony_ci| 5598c2ecf20Sopenharmony_ci| case (32<=d1<64) 5608c2ecf20Sopenharmony_ci| 5618c2ecf20Sopenharmony_cicase_2: 5628c2ecf20Sopenharmony_ci movel %d2,-(%sp) 5638c2ecf20Sopenharmony_ci movew %d0,LOCAL_EX(%a0) |unsigned exponent = threshold 5648c2ecf20Sopenharmony_ci subw #32,%d1 |d1 now between 0 and 32 5658c2ecf20Sopenharmony_ci movel #32,%d0 5668c2ecf20Sopenharmony_ci subw %d1,%d0 |d0 = 32 - d1 5678c2ecf20Sopenharmony_ci bfextu LOCAL_EX(%a0){%d0:#32},%d2 5688c2ecf20Sopenharmony_ci bfextu %d2{%d1:%d0},%d2 |d2 = new LOCAL_LO 5698c2ecf20Sopenharmony_ci bfextu LOCAL_HI(%a0){%d0:#32},%d1 |d1 = new G,R,S 5708c2ecf20Sopenharmony_ci bftst %d1{#2:#30} 5718c2ecf20Sopenharmony_ci bnes c2_sstky |bra if sticky bit to be set 5728c2ecf20Sopenharmony_ci bftst FP_SCR2+LOCAL_LO(%a6){%d0:#32} 5738c2ecf20Sopenharmony_ci bnes c2_sstky |bra if sticky bit to be set 5748c2ecf20Sopenharmony_ci movel %d1,%d0 5758c2ecf20Sopenharmony_ci clrb %d1 5768c2ecf20Sopenharmony_ci bras end_c2 5778c2ecf20Sopenharmony_cic2_sstky: 5788c2ecf20Sopenharmony_ci movel %d1,%d0 5798c2ecf20Sopenharmony_ci bsetl #rnd_stky_bit,%d0 5808c2ecf20Sopenharmony_ci st %d1 5818c2ecf20Sopenharmony_ciend_c2: 5828c2ecf20Sopenharmony_ci clrl LOCAL_HI(%a0) |store LOCAL_HI = 0 5838c2ecf20Sopenharmony_ci movel %d2,LOCAL_LO(%a0) |store LOCAL_LO 5848c2ecf20Sopenharmony_ci movel FP_SCR2+LOCAL_GRS(%a6),%d2 |restore original g,r,s 5858c2ecf20Sopenharmony_ci andil #0xe0000000,%d2 |clear all but G,R,S 5868c2ecf20Sopenharmony_ci tstl %d2 |test if original G,R,S are clear 5878c2ecf20Sopenharmony_ci beqs clear_grs 5888c2ecf20Sopenharmony_ci orl #0x20000000,%d0 |set sticky bit in d0 5898c2ecf20Sopenharmony_ciclear_grs: 5908c2ecf20Sopenharmony_ci andil #0xe0000000,%d0 |get rid of all but G,R,S 5918c2ecf20Sopenharmony_ci movel (%sp)+,%d2 5928c2ecf20Sopenharmony_ci rts 5938c2ecf20Sopenharmony_ci| 5948c2ecf20Sopenharmony_ci| d1 >= 64 Force the exponent to be the denorm threshold with the 5958c2ecf20Sopenharmony_ci| correct sign. 5968c2ecf20Sopenharmony_ci| 5978c2ecf20Sopenharmony_cicase_3: 5988c2ecf20Sopenharmony_ci movew %d0,LOCAL_EX(%a0) 5998c2ecf20Sopenharmony_ci tstw LOCAL_SGN(%a0) 6008c2ecf20Sopenharmony_ci bges c3con 6018c2ecf20Sopenharmony_cic3neg: 6028c2ecf20Sopenharmony_ci orl #0x80000000,LOCAL_EX(%a0) 6038c2ecf20Sopenharmony_cic3con: 6048c2ecf20Sopenharmony_ci cmpw #64,%d1 6058c2ecf20Sopenharmony_ci beqs sixty_four 6068c2ecf20Sopenharmony_ci cmpw #65,%d1 6078c2ecf20Sopenharmony_ci beqs sixty_five 6088c2ecf20Sopenharmony_ci| 6098c2ecf20Sopenharmony_ci| Shift value is out of range. Set d1 for inex2 flag and 6108c2ecf20Sopenharmony_ci| return a zero with the given threshold. 6118c2ecf20Sopenharmony_ci| 6128c2ecf20Sopenharmony_ci clrl LOCAL_HI(%a0) 6138c2ecf20Sopenharmony_ci clrl LOCAL_LO(%a0) 6148c2ecf20Sopenharmony_ci movel #0x20000000,%d0 6158c2ecf20Sopenharmony_ci st %d1 6168c2ecf20Sopenharmony_ci rts 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_cisixty_four: 6198c2ecf20Sopenharmony_ci movel LOCAL_HI(%a0),%d0 6208c2ecf20Sopenharmony_ci bfextu %d0{#2:#30},%d1 6218c2ecf20Sopenharmony_ci andil #0xc0000000,%d0 6228c2ecf20Sopenharmony_ci bras c3com 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_cisixty_five: 6258c2ecf20Sopenharmony_ci movel LOCAL_HI(%a0),%d0 6268c2ecf20Sopenharmony_ci bfextu %d0{#1:#31},%d1 6278c2ecf20Sopenharmony_ci andil #0x80000000,%d0 6288c2ecf20Sopenharmony_ci lsrl #1,%d0 |shift high bit into R bit 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_cic3com: 6318c2ecf20Sopenharmony_ci tstl %d1 6328c2ecf20Sopenharmony_ci bnes c3ssticky 6338c2ecf20Sopenharmony_ci tstl LOCAL_LO(%a0) 6348c2ecf20Sopenharmony_ci bnes c3ssticky 6358c2ecf20Sopenharmony_ci tstb FP_SCR2+LOCAL_GRS(%a6) 6368c2ecf20Sopenharmony_ci bnes c3ssticky 6378c2ecf20Sopenharmony_ci clrb %d1 6388c2ecf20Sopenharmony_ci bras c3end 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cic3ssticky: 6418c2ecf20Sopenharmony_ci bsetl #rnd_stky_bit,%d0 6428c2ecf20Sopenharmony_ci st %d1 6438c2ecf20Sopenharmony_cic3end: 6448c2ecf20Sopenharmony_ci clrl LOCAL_HI(%a0) 6458c2ecf20Sopenharmony_ci clrl LOCAL_LO(%a0) 6468c2ecf20Sopenharmony_ci rts 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci |end 649