📄 emuoperalib.s
字号:
epdp2: shldl $16,%ecx,%ebx #check for stack underflow cmpb $3,%bl jz epdp38 btsl $16,%ecx #check zero, denormal jc epdp3 orw %cx,%cx jz epdp4 orl %edx,%edx jns epdp36 jmp epdp30 epdp3: movl %ecx,%edx #return zero andl $0x80000000,%edx ret eptodp: testl $0x00030000,%ecx #jump if special value jnz epdp2 epdp4: addw $lBIAS-tBIAS,%cx #adjust the bias jle epdp20 # weed out underflow and overflow cmpw $0x07ff,%cx jnc epdp32 epdp6: addl %eax,%eax #shift left mantissa to delete hidden bit adcl %edx,%edx xorl %ebx,%ebx #discarded bits into ebx shrdl $12,%eax,%ebx shrdl $12,%edx,%eax #shift right everything 12 bits shrdl $11,%ecx,%edx btl $31,%ecx rcrl $1,%edx epdp8: orl %ebx,%ebx #exact = no rounding jz epdp19 testb $0x0c,h_ctrl+1 #quick round jnz epdp14 btl $0,%eax adcl $-1,%ebx jns epdp17 epdp18: #PREEX precis+rup orw $precis+rup,h_stat testb $precis,h_ctrl jnz LL1 orw $0x8080,h_stat movl $exret,-4(%ebp) LL1: addl $1,%eax adcl $0,%edx ret epdp17: #PREEXS precis orb $precis,h_stat testb $precis,h_ctrl jnz LL2 orw $0x8080,h_stat movl $exret,-4(%ebp) LL2: epdp19: andb $0x0fd,h_stat+1 ret epdp14: roll $8,%ebx #IEEE rounding cmpl $0x0ff,%ebx jna epdp11 orb $0x40,%bl epdp11: call roundi adcl $0,%eax adcl $0,%edx ret epdp20: negw %cx #this is zero or denormal jz epdp7 cmpw $53,%cx jc epdp21 movw $53,%cx epdp21: shrl $1,%edx rcrl $1,%eax jnc epdp22 orl $1,%eax epdp22: decw %cx jnz epdp21 epdp7: xorl %ebx,%ebx #discarded bits into ebx shrdl $12,%eax,%ebx shrdl $12,%edx,%eax #shift right everything 12 bits shrdl $11,%ecx,%edx btl $31,%ecx rcrl $1,%edx testb $underf,h_ctrl #set underflow if necessary jz epdp13 orl %ebx,%ebx jz epdp19 epdp13: orb $underf,h_stat call exproc jmp epdp8 epdp30: movl %edx,%ebx #this is INF or NaN addl %ebx,%ebx orl %eax,%ebx jnz epdp34 movw $0x7ff,%cx jmp epdp6 epdp38: call getqn orb $stacku,h_stat jmp epdp39 epdp36: call getqn #this is NaN jmp epdp37 epdp34: btl $30,%edx jc epdp35 epdp37: orb $invop,h_stat epdp39: call exproc btsl $30,%edx epdp35: movw $2*lBIAS+1,%cx andw $0xf800,%ax jmp epdp6 # round extended floating-point to whole floating-point# input: EP in ecx:edx:eax# output: EP in ecx:edx:eax no decimals .globl eptownepwn2: call chkarg #check for stack underflow, NaN jc epwn82 btl $16,%ecx #check zero, denormal jc epwn82 orw %cx,%cx jz epwn85 cmpw $1,%cx jz epwn43 orl %edx,%edx jns stdnan epwn82: ret #INFepwn85: orw $denorm+precis,h_stat call exproc epwn43: orb $1,%bl epwn40: movb $0,%bl #here answer is 0 or 1 or -1 jnz epwn41 shldl $8,%edx,%ebx addl %edx,%edx epwn41: orl %eax,%edx jz epwn42 orb $0x40,%bl epwn42: xorl %edx,%edx xorl %eax,%eax andl $0x80000000,%ecx movw $0x3fff,%cx call roundi jc epwn16 addl $0xc001,%ecx ret eptown: testl $0x00030000,%ecx #jump if special value jnz epwn2 epwn3: movl %ecx,%esi #number of bits to clear movw $tBIAS+63,%si subw %cx,%si jle epwn8 cmpw $64,%si #over not needed jnc epwn40 xchgl %esi,%ecx xorl %ebx,%ebx cmpb $32,%cl #clear decimal bits jc epwn21 xchgl %ebx,%eax xchgl %eax,%edx jz epwn22 cmpl %ebx,%edx rcrl $1,%ebx epwn21: shrdl %cl,%eax,%ebx shrdl %cl,%edx,%eax shrl %cl,%edx epwn22: roll $8,%ebx cmpl $0x100,%ebx jc epwn23 orb $0x20,%bl epwn23: call roundi adcl $0,%eax adcl $0,%edx cmpb $32,%cl jc epwn24 xchgl %eax,%edx shrl $1,%eax adcl $0,%esi epwn24: shldl %cl,%eax,%edx adcl $0,%esi shll %cl,%eax xchgl %esi,%ecx epwn16: btsl $31,%edx #set high mantissa bitepwn8: ret # extract exponent and mantissa from extended floating-point# input: EP in ecx:edx:eax# output: mantissa as EP in ecx:edx:eax# [edi] exponent as EP .globl xtractxtr2: btl $16,%ecx #check zero, denormal jc xtr80 orw %cx,%cx jz xtr23 orl %edx,%edx jns xtr92 jmp xtr90 xtr23: call tnormal #normalize jmp xtr3 xtract: movl %ecx,%ebx #save original sign andl $0x80000000,%ebx testl $0x00030000,%ecx #jump if special value jnz xtr2 xtr3: pushl %edx #save the argument pushl %eax movswl %cx,%edx #convert real exponent to EP floating-point subl $tBIAS,%edx call wiep orw %cx,%cx jnz xtr7 orl %ebx,%ecx xtr7: #PUTEP movl %eax,(%edi) movl %edx,4(%edi) movl %ecx,8(%edi) popl %eax #restore original argument popl %edx movl $0x3fff,%ecx #make exponent 1 orl %ebx,%ecx ret xtr80: orb $zerod,h_stat #argument was 0, store -INF call exproc movl %eax,(%edi) movl $0x80000000,4(%edi) movl $0x80007fff,8(%edi) ret xtr92: call getqn #invalid jmp xtr97 xtr90: movl %edx,%ebx #either NaN or INF addl %ebx,%ebx orl %eax,%ebx jnz xtr95 movl %eax,(%edi) #argument was INF, store INF movl $0x7fff,8(%edi) movl $0x80000000,%edx movl %edx,4(%edi) ret xtr95: btl $30,%edx #NaN, make into quiet jc xtr96 xtr97: orb $invop,h_stat call exproc btsl $30,%edx xtr96: #PUTEP movl %eax,(%edi) movl %edx,4(%edi) movl %ecx,8(%edi) ret # add integer to exponent or EP# input: integer EP in ecx:edx:eax# [edi] EP# output: EP scaled in ecx:edx:eax .globl scalescaw: call retnan #remove NaNs and invalids movb $0,%bl movl %ecx,%esi #set denormal exception if either addl %esi,%esi # argument denormal cmpl $0x00040000,%esi jz sca24 movl 8(%edi),%esi addl %esi,%esi cmpl $0x00040000,%esi jnz sca26 movb $1,8(%edi) sca24: orb $denorm,h_stat call exproc sca26: testb $0x01,10(%edi) #cases x = 0 jz sca28 cmpl $0x00027fff,%ecx jz stdnan scazer: xorl %edx,%edx #return zero xorl %eax,%eax movl $0x00010000,%ecx jmp sca17 sca28: cmpw $0x7fff,8(%edi) #cases x = INF jnz sca30 cmpl $0x80027fff,%ecx jz stdnan #GETEP #return x movl (%edi),%eax movl 4(%edi),%edx movl 8(%edi),%ecx ret sca30: cmpl $0x80027fff,%ecx #cases n = INF jz scazer cmpl $0x00027fff,%ecx jz sca17 jmp sca4 sca40: movl $-2,%ebx #this is special cases for integer jmp sca9 sca44: xorl %ebx,%ebx jmp sca9 scale: andb $0x0fd,h_stat+1 shldl $16,%ecx,%ebx #weed out special arguments orb 10(%edi),%bl jnz scaw sca4: movl %ecx,%esi #save the sign subw $tBIAS+15,%cx #calculate shift count ja sca40 negw %cx cmpw $16,%cx jnc sca44 addb $16,%cl shrl %cl,%edx #integer -> bx movl %edx,%ebx sca9: #GETEP #load the EP movl (%edi),%eax movl 4(%edi),%edx movl 8(%edi),%ecx andl $0xffff,%ebx #we need 32-bit integers andl $0xffff,%ecx sarl $31,%esi #make twos complement of integer xorl %esi,%ebx subl %esi,%ebx addl %ebx,%ecx #add integer to exponent jle sca70 cmpl $0x7fff,%ecx jge sca74 orl %edx,%edx #also check for denormal jns sca78 movb $0,%bl #no extra bits heresca17: roll $16,%ecx #put sign in place movb 11(%edi),%ch roll $16,%ecx ret sca70: cmpl $0xffff8000,%ecx #renormalization needed jge sca71 movw $0x8000,%cx sca71: clc jmp sca78 sca74: stc sca78: movb $0,%bl call renorm jmp sca17 itsstu: orb $stacku,h_stat jmp nan3 itsnan: btl $30,%edx jc nan9 stdnan: orb $invop,h_stat nan3: call getqn call exproc btsl $30,%edx nan9: xorl %ebx,%ebx ret # subttl CCALL Arithmetic Operations# page# examine an EP operand# input: ecx:edx:eax# output: condition bits in al .globl epexamepexam: xorl %ebx,%ebx #first set sign bit shldl $2,%ecx,%ebx testl $0x00030000,%ecx #check for specials jnz exa10 exa8: orb $4,%bl #regular bitexa9: movb %bl,%al #return bits ret exa10: btl $16,%ecx #check for zero, NaN, unsupported jc exa12 orw %cx,%cx jz exa14 orl %edx,%edx jns exa9 exa20: orb $0x01,%bl #INF or NaN addl %edx,%edx orl %eax,%edx jnz exa9 jmp exa8 exa14: orb $0x4,%bl #denormal caseexa12: orb $0x40,%bl #zero case jmp exa9 # compare two EP operands# input: cx:edx:eax# in epcomu quiet NaN will not cause exception# output: ST - input -> condition bits in al .globl epcomp, epcomu, xcmpepcomu: movb $1,%bl #unordered entry jmp cmp1 epcomp: movb $0,%bl #Intel entrycmp1: movl 8(%edi),%esi #sign, exponent of B shldl $16,%ecx,%ebx #weed out special arguments orb 10(%edi),%bl jnz cmpw cmp7: movl %ecx,%ebx #set bit in bh if both negative andl %esi,%ebx shrl $23,%ebx subl (%edi),%eax #compare hook line and sinker sbbl 4(%edi),%edx sbbl %esi,%ecx jz cmp10 setnl %al cmp8: xorb %bh,%al #if both negative, complement answercmp9: andb $0x0b8,h_stat+1 orb %al,h_stat+1 ret cmp10: orl %eax,%edx #possibly equal movb $1,%al jnz cmp8 cmpeq: movb $0x40,%al jmp cmp9 cmpw: andb $0x0b8,h_stat+1 orb $0x45,h_stat+1 call retnan xcmp: shldl $16,%ecx,%ebx #two zeroes are equal regardless of sign andb 10(%edi),%bl testb $1,%bl jnz cmpeq movl %ecx,%ebx #set denormal exception if either addl %ebx,%ebx # argument denormal cmpl $0x00040000,%ebx jz cmpw2 movl %esi,%ebx addl %ebx,%ebx cmpl $0x00040000,%ebx jnz cmpw4 cmpw2: orb $denorm,h_stat testb $denorm,h_ctrl jnz cmpw4 orw $0x8080,h_stat movl $exret,-4(%ebp) cmpw4: orw %cx,%cx #adjust exponent of pseudo-denormal jnz cmpw5 orl %edx,%edx jns cmpw5 incl %ecx cmpw5: orw %si,%si jnz cmpw6 testb $0x80,7(%edi) jz cmpw6 incl %esi cmpw6: andl $0x8000ffff,%ecx andl $0x8000ffff,%esi jmp cmp7 # add/subtract from registers to stack# input: ecx:edx:eax = EP number# result: registers = ST + number .globl epadd,epadd1,epsub,epsubrepsub: shldl $16,%ecx,%ebx #weed out special arguments orb 10(%edi),%bl jnz sub2 movl 8(%edi),%esi xorl $0x80000000,%esi jmp epadd2 sub2: call retnan #handle special arguments xorb $0x80,11(%edi) jmp addw epsubr: shldl $16,%ecx,%ebx #weed out special arguments orb 10(%edi),%bl jnz subr2 xorl $0x80000000,%ecx jmp epadd1 subr2: call retnan #handle special arguments xorl $0x80000000,%ecx addw: testb $0x02,%bl #zero is handled normally jz epadd1 call retnan #first remove NaNs and invalids cmpw $0x7fff,%cx #weed out A = INF jnz addw3 cmpw %cx,8(%edi) jnz addrta movl %ecx,%esi xorl 8(%edi),%esi jns addrta jmp stdnan addrtb: #GETEP #return B or A as such movl (%edi),%eax movl 4(%edi),%edx movl 8(%edi),%ecx addrta: movb $0,%bl ret addw3: cmpw $0x7fff,8(%edi) #weed out B = INF jz addrtb call tnormal #normalize arguments xchgl %eax,(%edi) xchgl %edx,4(%edi) xchgl %ecx,8(%edi) call tnormal jmp epadd1 epadd: shldl $16,%ecx,%ebx #weed out special arguments orb 10(%edi),%bl jnz addw epadd1: movl 8(%edi),%esi #the other exponentepadd2: cmpw %si,%cx #if exponent of A > exponent of B, jl add7 # we swap arguments movl $0,%ebx je add34 xchgl %eax,(%edi) xchgl %edx,4(%edi) xchgl %ecx,%esi add7: subw %si,%cx negw %cx call shiftr #shift mantissa right by cl movw %si,%cx #load the exponentadd34: andl $0x8000ffff,%ecx #clear special bits xorl %ecx,%esi #go subtract if different signs js add20 addl (%edi),%eax #add mantissas adcl 4(%edi),%edx jnc add15 rcrl $1,%edx rcrl $1,%eax rcrb $1,%bl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -