📄 util.s
字号:
cmpil #0x00400000,%d0 beql unff_sgl |force single cmpil #0x00440000,%d0 |force double beql unff_dbl movel CMDREG1B(%a6),%d0 |get the command word again andil #0x007f0000,%d0 |clear all bits except the operation cmpil #0x00270000,%d0 beql unf_fsgl |fsglmul cmpil #0x00240000,%d0 beql unf_fsgl |fsgldiv bra unf_fpcr|| Convert to return format. The values from cmdreg3b and the return| values are:| cmdreg3b return precision| -------- ------ ---------| 00,01 0 ext| 10 1 sgl| 11 2 dbl| Force single|unff_sgl: movel #1,%d0 |return 1 rts|| Force double|unff_dbl: movel #2,%d0 |return 2 rts|| Force extended|unf_fsgl: movel #0,%d0 rts|| Get rounding precision set in FPCR{7:6}.|unf_fpcr: movel USER_FPCR(%a6),%d0 |rounding precision bits in d0{7:6} bfextu %d0{#24:#2},%d0 |move the rounding prec bits to d0{1:0} rts|| g_opcls --- put opclass in d0{2:0}|g_opcls: btstb #E3,E_BYTE(%a6) beqs opc_1b |if set, go to cmdreg1bopc_3b: clrl %d0 |if E3, only opclass 0x0 is possible rtsopc_1b: movel CMDREG1B(%a6),%d0 bfextu %d0{#0:#3},%d0 |shift opclass bits d0{31:29} to d0{2:0} rts|| g_dfmtou --- put destination format in d0{1:0}|| If E1, the format is from cmdreg1b{12:10}| If E3, the format is extended.|| Dest. Fmt. | extended 010 -> 00| single 001 -> 01| double 101 -> 10|g_dfmtou: btstb #E3,E_BYTE(%a6) beqs op011 clrl %d0 |if E1, size is always ext rtsop011: movel CMDREG1B(%a6),%d0 bfextu %d0{#3:#3},%d0 |dest fmt from cmdreg1b{12:10} cmpb #1,%d0 |check for single bnes not_sgl movel #1,%d0 rtsnot_sgl: cmpb #5,%d0 |check for double bnes not_dbl movel #2,%d0 rtsnot_dbl: clrl %d0 |must be extended rts||| Final result table for unf_sub. Note that the negative counterparts| are unnecessary as unf_sub always returns the sign separately from| the exponent.| ;+zeroEXT_PZRO: .long 0x00000000,0x00000000,0x00000000,0x00000000 | ;+zeroSGL_PZRO: .long 0x3f810000,0x00000000,0x00000000,0x00000000 | ;+zeroDBL_PZRO: .long 0x3c010000,0x00000000,0x00000000,0x00000000 | ;smallest +ext denormEXT_PSML: .long 0x00000000,0x00000000,0x00000001,0x00000000 | ;smallest +sgl denormSGL_PSML: .long 0x3f810000,0x00000100,0x00000000,0x00000000 | ;smallest +dbl denormDBL_PSML: .long 0x3c010000,0x00000000,0x00000800,0x00000000 || UNF_SUB --- underflow result calculation|| Input:| d0 contains round precision| a0 points to input operand in the internal extended format|| Output:| a0 points to correct internal extended precision result.|tblunf: .long uEXT_RN .long uEXT_RZ .long uEXT_RM .long uEXT_RP .long uSGL_RN .long uSGL_RZ .long uSGL_RM .long uSGL_RP .long uDBL_RN .long uDBL_RZ .long uDBL_RM .long uDBL_RP .long uDBL_RN .long uDBL_RZ .long uDBL_RM .long uDBL_RP .global unf_subunf_sub: lsll #2,%d0 |move round precision to d0{3:2} bfextu FPCR_MODE(%a6){#2:#2},%d1 |set round mode orl %d1,%d0 |index is fmt:mode in d0{3:0} leal tblunf,%a1 |load a1 with table address movel %a1@(%d0:l:4),%a1 |use d0 as index to the table jmp (%a1) |go to the correct routine||case DEST_FMT = EXT|uEXT_RN: leal EXT_PZRO,%a1 |answer is +/- zero bsetb #z_bit,FPSR_CC(%a6) bra uset_sign |now go set the sign uEXT_RZ: leal EXT_PZRO,%a1 |answer is +/- zero bsetb #z_bit,FPSR_CC(%a6) bra uset_sign |now go set the signuEXT_RM: tstb LOCAL_SGN(%a0) |if negative underflow beqs ue_rm_posue_rm_neg: leal EXT_PSML,%a1 |answer is negative smallest denorm bsetb #neg_bit,FPSR_CC(%a6) bra end_unfrue_rm_pos: leal EXT_PZRO,%a1 |answer is positive zero bsetb #z_bit,FPSR_CC(%a6) bra end_unfruEXT_RP: tstb LOCAL_SGN(%a0) |if negative underflow beqs ue_rp_posue_rp_neg: leal EXT_PZRO,%a1 |answer is negative zero oril #negz_mask,USER_FPSR(%a6) bra end_unfrue_rp_pos: leal EXT_PSML,%a1 |answer is positive smallest denorm bra end_unfr||case DEST_FMT = DBL|uDBL_RN: leal DBL_PZRO,%a1 |answer is +/- zero bsetb #z_bit,FPSR_CC(%a6) bra uset_signuDBL_RZ: leal DBL_PZRO,%a1 |answer is +/- zero bsetb #z_bit,FPSR_CC(%a6) bra uset_sign |now go set the signuDBL_RM: tstb LOCAL_SGN(%a0) |if negative overflow beqs ud_rm_posud_rm_neg: leal DBL_PSML,%a1 |answer is smallest denormalized negative bsetb #neg_bit,FPSR_CC(%a6) bra end_unfrud_rm_pos: leal DBL_PZRO,%a1 |answer is positive zero bsetb #z_bit,FPSR_CC(%a6) bra end_unfruDBL_RP: tstb LOCAL_SGN(%a0) |if negative overflow beqs ud_rp_posud_rp_neg: leal DBL_PZRO,%a1 |answer is negative zero oril #negz_mask,USER_FPSR(%a6) bra end_unfrud_rp_pos: leal DBL_PSML,%a1 |answer is smallest denormalized negative bra end_unfr||case DEST_FMT = SGL|uSGL_RN: leal SGL_PZRO,%a1 |answer is +/- zero bsetb #z_bit,FPSR_CC(%a6) bras uset_signuSGL_RZ: leal SGL_PZRO,%a1 |answer is +/- zero bsetb #z_bit,FPSR_CC(%a6) bras uset_signuSGL_RM: tstb LOCAL_SGN(%a0) |if negative overflow beqs us_rm_posus_rm_neg: leal SGL_PSML,%a1 |answer is smallest denormalized negative bsetb #neg_bit,FPSR_CC(%a6) bras end_unfrus_rm_pos: leal SGL_PZRO,%a1 |answer is positive zero bsetb #z_bit,FPSR_CC(%a6) bras end_unfruSGL_RP: tstb LOCAL_SGN(%a0) |if negative overflow beqs us_rp_posus_rp_neg: leal SGL_PZRO,%a1 |answer is negative zero oril #negz_mask,USER_FPSR(%a6) bras end_unfrus_rp_pos: leal SGL_PSML,%a1 |answer is smallest denormalized positive bras end_unfruset_sign: tstb LOCAL_SGN(%a0) |if negative overflow beqs end_unfruneg_sign: bsetb #neg_bit,FPSR_CC(%a6)end_unfr: movew LOCAL_EX(%a1),LOCAL_EX(%a0) |be careful not to overwrite sign movel LOCAL_HI(%a1),LOCAL_HI(%a0) movel LOCAL_LO(%a1),LOCAL_LO(%a0) rts|| reg_dest --- write byte, word, or long data to Dn||| Input:| L_SCR1: Data | d1: data size and dest register number formatted as:|| 32 5 4 3 2 1 0| -----------------------------------------------| | 0 | Size | Dest Reg # || -----------------------------------------------|| Size is:| 0 - Byte| 1 - Word| 2 - Long/Single|pregdst: .long byte_d0 .long byte_d1 .long byte_d2 .long byte_d3 .long byte_d4 .long byte_d5 .long byte_d6 .long byte_d7 .long word_d0 .long word_d1 .long word_d2 .long word_d3 .long word_d4 .long word_d5 .long word_d6 .long word_d7 .long long_d0 .long long_d1 .long long_d2 .long long_d3 .long long_d4 .long long_d5 .long long_d6 .long long_d7reg_dest: leal pregdst,%a0 movel %a0@(%d1:l:4),%a0 jmp (%a0)byte_d0: moveb L_SCR1(%a6),USER_D0+3(%a6) rtsbyte_d1: moveb L_SCR1(%a6),USER_D1+3(%a6) rtsbyte_d2: moveb L_SCR1(%a6),%d2 rtsbyte_d3: moveb L_SCR1(%a6),%d3 rtsbyte_d4: moveb L_SCR1(%a6),%d4 rtsbyte_d5: moveb L_SCR1(%a6),%d5 rtsbyte_d6: moveb L_SCR1(%a6),%d6 rtsbyte_d7: moveb L_SCR1(%a6),%d7 rtsword_d0: movew L_SCR1(%a6),USER_D0+2(%a6) rtsword_d1: movew L_SCR1(%a6),USER_D1+2(%a6) rtsword_d2: movew L_SCR1(%a6),%d2 rtsword_d3: movew L_SCR1(%a6),%d3 rtsword_d4: movew L_SCR1(%a6),%d4 rtsword_d5: movew L_SCR1(%a6),%d5 rtsword_d6: movew L_SCR1(%a6),%d6 rtsword_d7: movew L_SCR1(%a6),%d7 rtslong_d0: movel L_SCR1(%a6),USER_D0(%a6) rtslong_d1: movel L_SCR1(%a6),USER_D1(%a6) rtslong_d2: movel L_SCR1(%a6),%d2 rtslong_d3: movel L_SCR1(%a6),%d3 rtslong_d4: movel L_SCR1(%a6),%d4 rtslong_d5: movel L_SCR1(%a6),%d5 rtslong_d6: movel L_SCR1(%a6),%d6 rtslong_d7: movel L_SCR1(%a6),%d7 rts |end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -