📄 util.s
字号:
| case RndPr(from cmdreg3b{6:5} = 00 | 01| use precision from fpcr{7:6}| case 00 then RND_PREC = EXT| case 01 then RND_PREC = SGL| case 10 then RND_PREC = DBL| else E1| use precision in fpcr{7:6}| case 00 then RND_PREC = EXT| case 01 then RND_PREC = SGL| case 10 then RND_PREC = DBL| end|__x_g_rndpr: bsrl __x_g_opcls | get opclass in d0{2:0} cmpw #0x0003,d0 | check for opclass 011 jne op_0x0|| For move out instructions (opclass 011) the destination format| is the same as the rounding precision. Pass results from __x_g_dfmtou.| bsrl __x_g_dfmtou rtsop_0x0: btst #E3,a6@(E_BYTE) jeq unf_e1_exc | branch to e1 underflowunf_e3_exc: movel a6@(CMDREG3B),d0 | rounding precision in d0{10:9} bfextu d0{#9:#2},d0 | move the rounding prec bits to d0{1:0} cmpil #0x2,d0 jeq unff_sgl | force precision is single cmpil #0x3,d0 | force precision is double jeq unff_dbl movew a6@(CMDREG3B),d0 | get the command word again andil #0x7f,d0 | clear all except operation cmpil #0x33,d0 jeq unf_fsgl | fsglmul or fsgldiv cmpil #0x30,d0 jeq unf_fsgl | fsgldiv or fsglmul jra unf_fpcrunf_e1_exc: movel a6@(CMDREG1B),d0 | get 32 bits off the stack, 1st 16 bits| | are the command word andil #0x00440000,d0 | clear all bits except bits 6 and 2 cmpil #0x00400000,d0 jeq unff_sgl | force single cmpil #0x00440000,d0 | force double jeq unff_dbl movel a6@(CMDREG1B),d0 | get the command word again andil #0x007f0000,d0 | clear all bits except the operation cmpil #0x00270000,d0 jeq unf_fsgl | fsglmul cmpil #0x00240000,d0 jeq unf_fsgl | fsgldiv jra 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 a6@(USER_FPCR),d0 | rounding precision bits in d0{7:6} bfextu d0{#24:#2},d0 | move the rounding prec bits to d0{1:0} rts|| __x_g_opcls --- put opclass in d0{2:0}|__x_g_opcls: btst #E3,a6@(E_BYTE) jeq opc_1b | if set, go to cmdreg1bopc_3b: clrl d0 | if E3, only opclass 0x0 is possible rtsopc_1b: movel a6@(CMDREG1B),d0 bfextu d0{#0:#3},d0 | shift opclass bits d0{31:29} to d0{2:0} rts|| __x_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|__x_g_dfmtou: btst #E3,a6@(E_BYTE) jeq op011 clrl d0 | if E1, size is always ext rtsop011: movel a6@(CMDREG1B),d0 bfextu d0{#3:#3},d0 | dest fmt from cmdreg1b{12:10} cmpb #1,d0 | check for single jne not_sgl movel #1,d0 rtsnot_sgl: cmpb #5,d0 | check for double jne not_dbl movel #2,d0 rtsnot_dbl: clrl d0 | must be extended rts||| Final result table for __x_unf_sub. Note that the negative counterparts| are unnecessary as __x_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 .globl __x_unf_sub__x_unf_sub: lsll #2,d0 | move round precision to d0{3:2} bfextu a6@(fpcr_MODE){#2:#2},d1 | set round mode orl d1,d0 | index is fmt:mode in d0{3:0} lea tblunf,a1 | load a1 with table address movel a1@(d0:w:4),a1 | use d0 as index to the table jmp a1@ | go to the correct routine||case DEST_FMT = EXT|uEXT_RN: lea EXT_PZRO,a1 | answer is +/- zero bset #z_bit,a6@(FPSR_CC) jra uset_sign | now go set the signuEXT_RZ: lea EXT_PZRO,a1 | answer is +/- zero bset #z_bit,a6@(FPSR_CC) jra uset_sign | now go set the signuEXT_RM: tstb a0@(LOCAL_SGN) | if negative underflow jeq ue_rm_posue_rm_neg: lea EXT_PSML,a1 | answer is negative smallest denorm bset #neg_bit,a6@(FPSR_CC) jra end_unfrue_rm_pos: lea EXT_PZRO,a1 | answer is positive zero bset #z_bit,a6@(FPSR_CC) jra end_unfruEXT_RP: tstb a0@(LOCAL_SGN) | if negative underflow jeq ue_rp_posue_rp_neg: lea EXT_PZRO,a1 | answer is negative zero oril #negz_mask,a6@(USER_FPSR) jra end_unfrue_rp_pos: lea EXT_PSML,a1 | answer is positive smallest denorm jra end_unfr||case DEST_FMT = DBL|uDBL_RN: lea DBL_PZRO,a1 | answer is +/- zero bset #z_bit,a6@(FPSR_CC) jra uset_signuDBL_RZ: lea DBL_PZRO,a1 | answer is +/- zero bset #z_bit,a6@(FPSR_CC) jra uset_sign | now go set the signuDBL_RM: tstb a0@(LOCAL_SGN) | if negative overflow jeq ud_rm_posud_rm_neg: lea DBL_PSML,a1 | answer is smallest denorm negative bset #neg_bit,a6@(FPSR_CC) jra end_unfrud_rm_pos: lea DBL_PZRO,a1 | answer is positive zero bset #z_bit,a6@(FPSR_CC) jra end_unfruDBL_RP: tstb a0@(LOCAL_SGN) | if negative overflow jeq ud_rp_posud_rp_neg: lea DBL_PZRO,a1 | answer is negative zero oril #negz_mask,a6@(USER_FPSR) jra end_unfrud_rp_pos: lea DBL_PSML,a1 | answer is smallest denorm negative jra end_unfr||case DEST_FMT = SGL|uSGL_RN: lea SGL_PZRO,a1 | answer is +/- zero bset #z_bit,a6@(FPSR_CC) jra uset_signuSGL_RZ: lea SGL_PZRO,a1 | answer is +/- zero bset #z_bit,a6@(FPSR_CC) jra uset_signuSGL_RM: tstb a0@(LOCAL_SGN) | if negative overflow jeq us_rm_posus_rm_neg: lea SGL_PSML,a1 | answer is smallest denorm negative bset #neg_bit,a6@(FPSR_CC) jra end_unfrus_rm_pos: lea SGL_PZRO,a1 | answer is positive zero bset #z_bit,a6@(FPSR_CC) jra end_unfruSGL_RP: tstb a0@(LOCAL_SGN) | if negative overflow jeq us_rp_posus_rp_neg: lea SGL_PZRO,a1 | answer is negative zero oril #negz_mask,a6@(USER_FPSR) jra end_unfrus_rp_pos: lea SGL_PSML,a1 | answer is smallest denorm positive jra end_unfruset_sign: tstb a0@(LOCAL_SGN) | if negative overflow jeq end_unfruneg_sign: bset #neg_bit,a6@(FPSR_CC)end_unfr: movew a1@(LOCAL_EX),a0@(LOCAL_EX) | be careful not to overwrite sign movel a1@(LOCAL_HI),a0@(LOCAL_HI) movel a1@(LOCAL_LO),a0@(LOCAL_LO) rts|| __x_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_d7__x_reg_dest: lea pregdst,a0 movel a0@(d1:w:4),a0 jmp a0@__byte_d0: moveb a6@(L_SCR1),a6@(USER_D0+3) rts__byte_d1: moveb a6@(L_SCR1),a6@(USER_D1+3) rts__byte_d2: moveb a6@(L_SCR1),d2 rts__byte_d3: moveb a6@(L_SCR1),d3 rts__byte_d4: moveb a6@(L_SCR1),d4 rts__byte_d5: moveb a6@(L_SCR1),d5 rts__byte_d6: moveb a6@(L_SCR1),d6 rts__byte_d7: moveb a6@(L_SCR1),d7 rts__word_d0: movew a6@(L_SCR1),a6@(USER_D0+2) rts__word_d1: movew a6@(L_SCR1),a6@(USER_D1+2) rts__word_d2: movew a6@(L_SCR1),d2 rts__word_d3: movew a6@(L_SCR1),d3 rts__word_d4: movew a6@(L_SCR1),d4 rts__word_d5: movew a6@(L_SCR1),d5 rts__word_d6: movew a6@(L_SCR1),d6 rts__word_d7: movew a6@(L_SCR1),d7 rts__long_d0: movel a6@(L_SCR1),a6@(USER_D0) rts__long_d1: movel a6@(L_SCR1),a6@(USER_D1) rts__long_d2: movel a6@(L_SCR1),d2 rts__long_d3: movel a6@(L_SCR1),d3 rts__long_d4: movel a6@(L_SCR1),d4 rts__long_d5: movel a6@(L_SCR1),d5 rts__long_d6: movel a6@(L_SCR1),d6 rts__long_d7: movel a6@(L_SCR1),d7 rts| end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -