📄 emuoperalib.s
字号:
/* Copyright 1991-2001 Wind River Systems, Inc. *//*modification history--------------------01c,14jul99,tdl added FUNC / FUNC_LABEL01b,24oct96,yp stuck in a # in USSC mailing addr so cpp will work01a,24jan95,hdn original US Software version.*/#* * * * * * * * * *# Filename: EMUOPER.ASM## Copyright (C) 1990,1991 By# # United States Software Corporation# # 14215 N.W. Science Park Drive# # Portland, Oregon 97229## This software is furnished under a license and may be used# and copied only in accordance with the terms of such license# and with the inclusion of the above copyright notice.# This software or any other copies thereof may not be provided# or otherwise made available to any other person. No title to# and ownership of the software is hereby transferred.## The information in this software is subject to change without# notice and should not be construed as a commitment by United# States Software Corporation.## Version: V3.09 01/19/95 GOFAST WRS GNU version of GF-PROT# Released: 1 March 1991##* * * * * * * * * *#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h" .data .globl FUNC(copyright_wind_river) .long FUNC(copyright_wind_river) .include "emuIncALib.s" .text# extrn roundi:near,rounde:near,chkarg:near# extrn retnan:near,tnormal:near,renorm:near,getqn:near# extrn mul10:near,shiftr:near,exproc:near,exprop:near# extrn exret:near#DGROUP GROUP hwseg#CGROUP GROUP emuseg#hwseg segment RW para public 'DATA'# assume ds:DGROUP, es:DGROUP, ss:DGROUP# extrn h_ctrl:word,h_stat:word,s_iptr:dword,s_memp:dword#hwseg ends#emuseg segment public USE32 'CODE'# assume cs:CGROUP__lib:# subttl Convert To Internal Floating-Point Format# page# convert 16-bit or 32-bit integer to extended floating-point# input: *eax = signed integer# output: EP in ecx:edx:eax .globl witoep,wiepwitoep: movswl (%eax),%edx jmp wiep2 .globl sitoepsitoep: movl (%eax),%edx #pick up numberwiep2: #SAVEII movl %esi,s_iptr movl %eax,s_memp wiep: movl $31,%ecx #initial sign -> cx xorl %eax,%eax orl %edx,%edx #weed out zero jz liep20 jns siep5 #if negative, set sign, negate orl $0x80000000,%ecx negl %edx siep5: bsrl %edx,%esi subl %esi,%ecx shll %cl,%edx negw %cx addw $tBIAS+31,%cx ret # convert 64-bit integer to extended floating-point# input: *eax = signed integer# output: EP in ecx:edx:eax .globl litoeplitoep: #SAVEII movl %esi,s_iptr movl %eax,s_memp movl 4(%eax),%edx #pick up number movl (%eax),%eax movl %eax,%ecx #jump if all zero orl %edx,%ecx jz liep20 movl $tBIAS+63,%ecx #initial exponent -> cx orl %edx,%edx #if negative, set sign, negate jns liep5 orl $0x80000000,%ecx notl %edx negl %eax sbbl $-1,%edx js liep7 liep5: decl %ecx #shift left until high bit = 1 addl %eax,%eax adcl %edx,%edx jns liep5 liep7: ret liep20: movl $0x00010000,%ecx #zero ret # convert 10-byte packed decimal integer to extended floating-point# input: *eax = signed integer# output: EP in ecx:edx:eax .globl pdtoeppdtoep: movl $9,%ecx #set up loop counter and pointer lea 9(%eax),%edi xorl %edx,%edx #initialize mantissa xorl %eax,%eax pdep3: call mul10 #multiply mantissa by 10 decl %edi #pick up next 2-digit movb (%edi),%bl pushl %ebx #add low digit to mantissa shrb $4,%bl andl $0x0f,%ebx addl %ebx,%eax adcl $0,%edx call mul10 #again multiply mantissa by 10 popl %ebx #add high digit to mantissa andl $0x0f,%ebx addl %ebx,%eax adcl $0,%edx loop pdep3 #loop for all digits movl %eax,%ecx #jump if all zero orl %edx,%ecx jz pdep20 movl $tBIAS+63,%ecx #initial exponent -> cxpdep5: decl %ecx #shift left until high bit = 1 addl %eax,%eax adcl %edx,%edx jns pdep5 pdep7: movb 9(%edi),%bl #set the sign bit andb $0x80,%bl shll $24,%ebx orl %ebx,%ecx ret pdep20: movl $0x00010000,%ecx #zero jmp pdep7 # convert single-precision to extended floating-point# input: *eax = single-precision# output: EP in ecx:edx:eax .globl fptoepfptoep: #SAVEII movl %esi,s_iptr movl %eax,s_memp movl (%eax),%edx #pick up number movl %edx,%ecx #sign, exponent to ecx sarl $23,%ecx andl $0x800000ff,%ecx shll $9,%edx #mantissa -> edx:eax xorl %eax,%eax cmpb $0,%cl #go handle zero and denormal jz fpep20 cmpb $-1,%cl #go handle INF and NaN jz dpep30 rcrl $1,%edx fpep7: addw $tBIAS-sBIAS,%cx #adjust bias ret fpep20: shrl $1,%edx #this is either zero or denormal jz dpep29 # zero if mantissa = 0 orb $denorm,h_stat call exprop incl %ecx fpep21: decw %cx addl %edx,%edx jns fpep21 jmp fpep7 # convert double-precision to extended floating-point# input: eax -> double-precision# output: EP in ecx:edx:eax .globl dptoepdptoep: #SAVEII movl %esi,s_iptr movl %eax,s_memp movl 4(%eax),%edx #pick up number movl (%eax),%eax movl %edx,%ecx #sign, exponent to ecx sarl $20,%ecx andl $0x800007ff,%ecx shldl $12,%eax,%edx #mantissa -> edx:eax shll $11,%eax orw %cx,%cx jz dpep20 cmpw $0x7ff,%cx jz dpep30 rcrl $1,%edx dpep7: addw $tBIAS-lBIAS,%cx #adjust exponent biasdpep9: ret dpep30: orl $0x00027fff,%ecx #this is INF or NaN movl %edx,%ebx # INF if mantissa 800..00 shrdl $1,%ecx,%edx orl %eax,%ebx jz dpep9 nanret: btl $30,%edx jc dpep32 orw $invop,h_stat call exproc btsl $30,%edx dpep32: xorl %ebx,%ebx ret dpep20: shrl $1,%edx #this is either zero or denormal movl %edx,%ebx # zero if mantissa = 0 orl %eax,%ebx jz dpep29 orb $denorm,h_stat call exprop incl %ecx dpep21: decw %cx addl %eax,%eax adcl %edx,%edx jns dpep21 jmp dpep7 dpep29: btsl $16,%ecx #zero ret # convert extended floating-point number to internal formal# input: EP in *ss:eax# output: EP in ecx:edx:eax .globl eptoepeptoep: movl 4(%eax),%edx #pick up the number movzwl 8(%eax),%ecx movl (%eax),%eax addw %cx,%cx rcrl $1,%ecx jz epe11 #tags: 10 = INF, denormal, illegal cmpw $0x7fff,%cx # 01 = zero jz epe6 orl %edx,%edx jns epe6 movl %edx,%ebx orl %eax,%ebx jz epe6 ret epe6: btsl $17,%ecx #illegal etc ret epe11: movl %edx,%ebx #this is zero or denormal orl %eax,%ebx jnz epe6 btsl $16,%ecx ret # subttl Convert From Internal Floating-Point Format# page# convert extended floating-point to 16 or 32 bit integer# input: EP in ecx:edx:eax# output: eax = signed integer .globl eptowieptowi: movl $15,%ebx #integer size jmp epsi1 .globl eptosieptosi: movl $31,%ebx #integer sizeepsi1: testl $0x00020000,%ecx #weed out specials jnz epsi20 epsi3: subw $tBIAS,%cx #subtract the bias cmpw %bx,%cx #if exponent too large, return INF jge epsi32 subw $63,%cx #here shift right negw %cx call shiftr call roundi #IEEE rounding adcl $0,%eax orl %ecx,%ecx #if negative take 2s complement jns epsi11 negl %eax epsi11: ret #returnepsi20: rorl $8,%ecx #check for stack underflow cmpb $3,%ch roll $8,%ecx jz epsi80 orw %cx,%cx #specials, but denormals go back jz epsi3 jmp epsi30 epsi32: jg epsi30 #overflow addl %edx,%edx orl %eax,%edx jz epsi34 epsi30: orb $invop,h_stat #either +INF or -INF call exproc epsi34: movl $1,%eax movb %bl,%cl shll %cl,%eax ret epsi80: orb $stacku,h_stat #stack underflow call exproc jmp epsi34 # convert extended floating-point to 64-bit integer# input: EP in ecx:edx:eax# output: edx:eax = signed integer .globl eptolieptoli: testl $0x00020000,%ecx #weed out specials jnz epli20 epli3: subw $tBIAS,%cx #subtract the bias cmpw $63,%cx #if exponent too large, return INF je epli32 jg epli30 subw $63,%cx #here shift right negw %cx call shiftr call roundi #do IEEE rounding adcl $0,%eax adcl $0,%edx orl %ecx,%ecx #if negative take 2s complement jns epli11 notl %edx negl %eax sbbl $-1,%edx epli11: ret #returnepli20: shldl $16,%ecx,%ebx #check for stack underflow cmpb $3,%bl jz epli80 orw %cx,%cx #specials, but denormals go back jz epli3 jmp epli30 epli32: addl %edx,%edx #treat 0x80000000 as special case orl %eax,%edx jz epli34 epli30: orb $invop,h_stat #either +INF or -INF call exproc epli34: movl $0x80000000,%edx xorl %eax,%eax jmp epli11 epli80: orb $stacku,h_stat #stack underflow call exproc jmp epli34 # convert EP to 10-byte packed-decimal integer# input: EP in ecx:edx:eax# edi pointer to result area# output: signed integer in result area .globl eptopdeppd20: shldl $16,%ecx,%ebx #check for stack underflow cmpb $3,%bl jz eppd80 orw %cx,%cx #specials, but denormals go back jz eppd3 eppd30: orb $invop,h_stat #either +INF or -INF call exproc eppd34: movl $0xffff8000,%eax movl %eax,6(%edi) movl $6,%ecx repz stosb ret eppd80: orb $stacku,h_stat #stack underflow call exproc jmp eppd34 eppd33: subl $9,%edi #number too big jmp eppd30 eptopd: movl %ecx,6(%edi) #store the sign btl $17,%ecx #weed out specials jc eppd20 eppd3: subw $tBIAS+63,%cx #subtract the bias jge eppd30 negw %cx call shiftr call roundi #do IEEE rounding adcl $0,%eax adcl $0,%edx movl %edx,%esi #get the digits by dividing with 10 movl $9,%ecx pushl %ebp movl $10,%ebp eppd11: xchgl %esi,%eax xorl %edx,%edx divl %ebp xchgl %esi,%eax divl %ebp movb %dl,%bl xchgl %esi,%eax xorl %edx,%edx divl %ebp xchgl %esi,%eax divl %ebp shlb $4,%dl orb %bl,%dl movb %dl,(%edi) incl %edi loop eppd11 popl %ebp orl %eax,%eax jnz eppd33 ret # convert extended floating-point to single-precision floating-point# input: EP in ecx:edx:eax# output: eax = floating-point .globl eptofpepfp2: shldl $16,%ecx,%ebx #check for stack underflow cmpb $3,%bl jz epfp38 btsl $16,%ecx #check zero, denormal jc epfp9 orw %cx,%cx jz epfp3 orl %edx,%edx jns epfp36 jmp epfp30 eptofp: testl $0x00030000,%ecx #jump if special value jnz epfp2 epfp3: addw $sBIAS-tBIAS,%cx #adjust the bias cmpw $0,%cx #weed out underflow and overflow jle epfp20 cmpw $0x0ff,%cx jnc epfp32 epfp6: addl %edx,%edx #shift left to delete hidden bit epfp7: movl %edx,%ebx #set rounding bits shll $23,%ebx addl $-1,%eax adcl %ebx,%ebx jz epfp71 movb $0x80,%bl epfp71: rcrb $1,%bl epfp8: shldl $9,%ecx,%eax #combine sign, exponent, mantissa movb %cl,%al shldl $23,%edx,%eax orb %cl,%cl #set underflow if necessary jnz epfp11 testb $underf,h_ctrl jz epfp13 orb %bl,%bl jz epfp11 epfp13: orb $underf,h_stat call exproc epfp11: call roundi #IEEE rounding adcl $0,%eax ret epfp9: addl %ecx,%ecx #return signed zero rcrl $1,%eax ret epfp20: negw %cx #underflow, we return zero or denormal jz epfp7 cmpw $25,%cx jc epfp23 movw $25,%cx epfp23: xorl %ebx,%ebx shrdl %cl,%edx,%ebx shrl %cl,%edx xorw %cx,%cx orl %ebx,%ebx jz epfp7 orb $1,%dl jmp epfp7 epfp30: btcl $31,%edx #this is NaN or INF orl %edx,%eax jnz epfp34 movw $2*sBIAS+1,%cx jmp epfp7 epfp32: orb $overf,h_stat #this is overflow call exproc movw $2*sBIAS,%cx movl $-1,%edx jmp epfp7 epfp38: call getqn orb $stacku,h_stat jmp epfp39 epfp36: call getqn #this is NaN jmp epfp37 epfp34: btl $30,%edx jc epfp35 epfp37: orb $invop,h_stat epfp39: call exproc btsl $30,%edx epfp35: movw $2*sBIAS+1,%cx addl %edx,%edx xorl %ebx,%ebx jmp epfp8 # convert extended floating-point to double-precision floating-point# input: EP in ecx:edx:eax# output: edx:eax = double-precision .globl eptodpepdp32: orb $overf,h_stat #this is overflow call exproc movw $0x7fe,%cx movl $-1,%edx movl %edx,%eax jmp epdp6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -