📄 dtoa.s
字号:
/************************************************************* * File: lib/dtoa.s * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history * 970928 bgtu commented out on line 123. Was a nop. */#include "mips.h"/* * dtoa() is the only C callable routine in this module. * * dtoa() * ITCONV: * _tpwr10: * _tmul: * _tmul: */#define asc_sp 32#define asc_minus 45#define asc_zero 48#ifdef MIPSEB#define MSHALF 0#define LSHALF 4#else#define MSHALF 4#define LSHALF 0#endif .dataOneMinusEps: .half 0x0000, 0xffff, 0xffff, 0xffff, 0xfc66 # 1-5*10^-17OneTenth: .half 0xfffd, 0xcccc, 0xcccc, 0xcccc, 0xcccd # 10^-0001Powers10Positive: .half 0x0004, 0xa000, 0x0000, 0x0000, 0x0000 # 10^+0001 .half 0x0007, 0xc800, 0x0000, 0x0000, 0x0000 # 10^+0002 .half 0x000e, 0x9c40, 0x0000, 0x0000, 0x0000 # 10^+0004 .half 0x001b, 0xbebc, 0x2000, 0x0000, 0x0000 # 10^+0008 .half 0x0036, 0x8e1b, 0xc9bf, 0x0400, 0x0000 # 10^+0016 .half 0x006b, 0x9dc5, 0xada8, 0x2b70, 0xb59e # 10^+0032 .half 0x00d5, 0xc278, 0x1f49, 0xffcf, 0xa6d5 # 10^+0064 .half 0x01aa, 0x93ba, 0x47c9, 0x80e9, 0x8ce0 # 10^+0128 .half 0x0353, 0xaa7e, 0xebfb, 0x9df9, 0xde8e # 10^+0256Powers10Negative: .half 0xfffd, 0xcccc, 0xcccc, 0xcccc, 0xcccd # 10^-0001 .half 0xfffa, 0xa3d7, 0x0a3d, 0x70a3, 0xd70a # 10^-0002 .half 0xfff3, 0xd1b7, 0x1758, 0xe219, 0x652c # 10^-0004 .half 0xffe6, 0xabcc, 0x7711, 0x8461, 0xcefd # 10^-0008 .half 0xffcb, 0xe695, 0x94be, 0xc44d, 0xe15b # 10^-0016 .half 0xff96, 0xcfb1, 0x1ead, 0x4539, 0x94ba # 10^-0032 .half 0xff2c, 0xa87f, 0xea27, 0xa539, 0xe9a5 # 10^-0064 .half 0xfe57, 0xddd0, 0x467c, 0x64bc, 0xe4a1 # 10^-0128 .half 0xfcae, 0xc031, 0x4325, 0x637a, 0x193a # 10^-0256 .text .align 2/************************************************************** dtoa(double *src,char *mant,char *sign,long *exp)* converts dp fp value in src to ascii.* warning src gets clobbered*/ .globl dtoa .ent dtoadtoa: subu sp, 56 sw $31, 40(sp)/* Save the register list s0..s6 */ sw s0, 36(sp) sw s1, 32(sp) sw s2, 28(sp) sw s3, 24(sp) sw s4, 20(sp) sw s5, 44(sp) sw s6, 48(sp) move s5,a2 # save &sign in s5 move s6,a3 # save &exp in s6 lw s0, MSHALF(a0) # save the sign bit and t0, s0, 0x7fffffff # store the abso no back in the memory sw t0, MSHALF(a0) add s3, $0, asc_sp # assume +ve input bgez s0, RealPositive # brif +ve add s3, $0, asc_minus # save the sign bitRealPositive: jal ITCONV # convert to EP.Output comes in t8:t7:t6NToStr: beqz s0, ZeroStr # return the zero string add t4, t8, 0x3ffe # add the expo bias and t4, t4, 0x0000ffff add t0, $0, 0x4d10 multu t4, t0 srl t5, t4, 8 mflo t4 srl t0, t0, 8 multu t0, t5 mflo t5 add t4, t4, t5 srl t2, t7, 24 add t0, $0, 0x9a multu t2, t0 mflo t2 add t2, t2, t4 sub t2, t2, 0x134312f4 srl s1, t2, 16 # t2 has the expo neg s4, s1 sll s4, s4, 16 srl s4, s4, 16 jal _tpwr10 sll t2, t8, 16 bltz t2, Normalized bgtz t2, DivideByTen bltu t7, 0xffffffff, Normalized #bgtu t7, 0xffffffff, DivideByTen bltu t6, 0xfffffc66, NormalizedDivideByTen: add s1, s1, 1 la a3, OneTenth jal _tmulNormalized: neg t8, t8 sll t8, t8, 16 srl t8, t8, 16 move t4, $0 b ConvertToFixedConvertToFixedLoop: sll t9, t6, 31 srl t6, t6, 1 srl t4, t4, 1 or t4, t4, t9 sll t9, t7, 31 or t6, t6, t9 srl t7, t7, 1ConvertToFixed: sub t8, t8, 1 bgez t8, ConvertToFixedLoop srl t4, t4, 16FixedPointMantissa: sll t4, t4, 16 addu v0, t4, 0x56000000 sltu t9, v0, t4 move t4, v0 add t0, $0, 0x39a beqz t9, NoCarry addu v0, t6, 1 addu v0, v0, t0 not t9, t6 sltu v1, t0, t9 xor v1, 1 b Chk_v1NoCarry: addu v0, t6, t0 sltu v1, v0, t6Chk_v1: move t6, v0 addu t7, t7, v1/* Start printing the digits out *//* a1=addr of output string *//* inputs t7:t6:t4 */ add s2, $0, 0xf # 16 bytes will be outputMantToCharLoop: move t1, t7 move t2, t6 move t3, t4 srl t0, t7, 30 sll t7, t7, 2 srl t5, t6, 30 sll t6, t6, 2 or t7, t7, t5 srl t5, t4, 30 sll t4, t4, 2 or t6, t6, t5 addu v0, t4, t3 sltu v1, v0, t4 move t4, v0 beqz v1, NoCarryIn addu v0, t6, v1 addu v0, v0, t2 not t9, t6 sltu v1, t2, t9 xor v1, 1 b ProceedNoCarryIn: addu v0, t6, t2 sltu v1, v0, t6Proceed: move t6, v0 beqz v1, NoCarryInAgain addu v0, t7, t1 addu v0, v0, v1 not t9, t7 sltu v1, t1, t9 xor v1, 1 b ProceedAgainNoCarryInAgain: addu v0, t7, t1 sltu v1, v0, t7ProceedAgain: move t7, v0 add t0, t0, v1 sll t0, t0, 1 srl t5, t7, 31 sll t7, t7, 1 or t0, t0, t5 srl t5, t6, 31 or t7, t7, t5 sll t6, t6, 1 srl t5, t4, 31 or t6, t6, t5 sll t4, t4, 1 add t0, t0, asc_zero # convert to ascii char sb t0, (a1) add a1, a1, 1 sub s2, s2, 1 bgez s2, MantToCharLoop add t0, $0, asc_zeroCompareLoop: sub a1, a1, 1 lb t1, (a1) beq t1, t0, CompareLoop sb $0, 1(a1) /* Now, s3=sign, s1=expo, mantissa stored */ sll s1, s1, 16 sra s1, s1, 16 sw s1, (s6) # return the signed expo sb s3, (s5) # store the sign of the mantissaCommonExit: lw s0, 36(sp) lw s1, 32(sp) lw s2, 28(sp) lw s3, 24(sp) lw s4, 20(sp) lw ra, 40(sp) lw s5, 44(sp) lw s6, 48(sp) addu sp, 56 j $31ZeroStr: add t1, $0, asc_zero sb t1, (a1) sb $0, 1(a1) sw $0, (s6) sb s3, (s5) b CommonExit .end dtoa/************************************************************** _tmul:* This routine multiplies two extended precision numbers* and returns the result in t8:t7:t6. The lower half of t8* contains the unbiased exponent, and t7:t6 contain the 64* bit mantissa. * Inputs are expected to be in the following registers:* For the I operand, t8 contains the expo, and t7:t6* contain the mantissa.* For the II operand, a pointer to it comes in a3.*/ .globl _tmul .ent _tmul_tmul:/* First, read the second operand in t9:t5:t4. */ lh t9, (a3) sll t9, t9, 16 lh t5, 2(a3) lh v0, 4(a3) and v0, v0, 0x0000ffff sll t5, t5, 16 or t5, t5, v0 # t5 has the higher mantissa lh t4, 6(a3) lh v0, 8(a3) and v0, v0, 0x0000ffff sll t4, t4, 16 or t4, t4, v0 # t4 has the lower mantissa/* Now, set the resultant expo */ sll t8, t8, 16 add t8, t8, t9 # resultant unbiased expo value srl t8, t8, 16/* Multiply the operands in t5:t4 and t7:t6 * * and put the result in t3:t2:t1:t0. */ multu t4, t6 mflo t0 mfhi t1 not v0, t1 multu t5, t6 mflo v1 mfhi t2 sltu v0, v0, v1 addu t1, v1 multu t4, t7 add t2, v0 not v0, t1 mflo v1 mfhi t3 sltu v0, v0, v1 addu t1, v1 multu t5, t7 add t2, v0 not v1, t2 sltu v1, v1, t3 addu t2, t3 not v0, t2 mfhi t3 add t3, v1 mflo v1 sltu v0, v0, v1 addu t3, v0 addu t2, v1/* Now, the result of the multiplication is in * * t3:t2:t1:t0. First, normalize it and then * * round it. Also, t8 has the expo value in it. */ and t4, t0, 0x0000ffff or t1, t1, t4 srl t0, t0, 16 or t1, t1, t0 # t1 contains the sticky bit bltz t3, TMulNorm # brif result is normalized/* Else shift the result left by 1 bit */ sub t8, t8, 1 sll t3, t3, 1 srl t0, t2, 31 sll t2, t2, 1 or t3, t3, t0 srl t0, t1, 31 or t2, t2, t0 sll t1, t1, 1TMulNorm: bltu t1, 0x80000000, TMulRound and t0, t2, 0x1 beqz t0, TMulRound # brif low bit off addu v0, t2, 1 sltu v1, v0, t2 move t2, v0 addu v0, t3, v1 sltu v1, v0, t3 move t3, v0 beqz v1, TMulRound add t8, t8, 1 # incr the expo or t3, t3, 0x80000000 # turn the overflow into 0x80000000TMulRound: move t7, t3 move t6, t2 j $31 # result set into appro registers .end _tmul/************************************************************** _tpwr10:*/ .globl _tpwr10 .ent _tpwr10_tpwr10: subu sp, 24 sw $31, 20(sp) # save the return address la a3, Powers10Positive # default sign is +ve sll t9, s4, 16 bgez t9, PowersTableOK # brif expo +ve la a3, Powers10Negative neg s4, s4 # make the expo +ve sll s4, s4, 16 srl s4, s4, 16PowersTableOK: sub a3, a3, 10 # decr the table pointerPowersLoop: add a3, a3, 10 # incr the table pointer beqz s4, PowersExit # brif no expo residue sll t9, s4, 31 srl s4, s4, 1 beqz t9, PowersLoop # brif bit off jal _tmul b PowersLoop # process next bitPowersExit: lw $31, 20(sp) addu sp, 24 # restore stack status j $31 .end _tpwr10/************************************************************** ITCONV:* Gets a pointer to a DP no in a0, and returns the EP in t8:t7:t6*/ .globl ITCONV .ent ITCONVITCONV:/* Gets a pointer to a DP no in a0, and * * returns the EP in t8:t7:t6 */ lw t0, MSHALF(a0) lw t1, LSHALF(a0) srl t8, t0, 20 # t8 gets the expo sll t7, t0, 12 srl t7, t7, 1 # make space for leading bit srl t0, t1, 21 sll t6, t1, 11 or t7, t7, t0 # t7:t6 get the extended mantissa add s0, $0, 1 bnez t8, Make_It_ON move s0, $0 or t0, t8, t7 or t0, t0, t6 beqz t0, LeadingBitOK add s0, $0, 1 b LeadingBitOKMake_It_ON: or t7, t7, 0x80000000LeadingBitOK: sub t8, t8, 0x3fe # t8 has unbiased exponent sll t8, t8, 16 srl t8, t8, 16 j $31 .end ITCONV
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -