slog2.S 5.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
|	slog2.sa 3.1 12/10/90
|
|       The entry point slog10 computes the base-10
|	logarithm of an input argument X.
|	slog10d does the same except the input value is a
|	denormalized number.
|	sLog2 and sLog2d are the base-2 analogues.
|
|       INPUT:	Double-extended value in memory location pointed to
|		by address register a0.
|
|       OUTPUT: log_10(X) or log_2(X) returned in floating-point
|		register fp0.
|
|       ACCURACY and MONOTONICITY: The returned result is within 1.7
|		ulps in 64 significant bit, i.e. within 0.5003 ulp
|		to 53 bits if the result is subsequently rounded
|		to double precision. The result is provably monotonic
|		in double precision.
|
|       SPEED:	Two timings are measured, both in the copy-back mode.
|		The first one is measured when the function is invoked
|		the first time (so the instructions and data are not
|		in cache), and the second one is measured when the
|		function is reinvoked at the same input argument.
|
|       ALGORITHM and IMPLEMENTATION NOTES:
|
|       slog10d:
|
|       Step 0.   If X < 0, create a NaN and raise the invalid operation
|                 flag. Otherwise, save FPCR in D1; set FpCR to default.
|       Notes:    Default means round-to-nearest mode, no floating-point
|                 traps, and precision control = double extended.
|
|       Step 1.   Call slognd to obtain Y = log(X), the natural log of X.
|       Notes:    Even if X is denormalized, log(X) is always normalized.
|
|       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).
|            2.1  Restore the user FPCR
|            2.2  Return ans := Y * INV_L10.
|
|
|       slog10:
|
|       Step 0.   If X < 0, create a NaN and raise the invalid operation
|                 flag. Otherwise, save FPCR in D1; set FpCR to default.
|       Notes:    Default means round-to-nearest mode, no floating-point
|                 traps, and precision control = double extended.
|
|       Step 1.   Call sLogN to obtain Y = log(X), the natural log of X.
|
|       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).
|            2.1  Restore the user FPCR
|            2.2  Return ans := Y * INV_L10.
|
|
|       sLog2d:
|
|       Step 0.   If X < 0, create a NaN and raise the invalid operation
|                 flag. Otherwise, save FPCR in D1; set FpCR to default.
|       Notes:    Default means round-to-nearest mode, no floating-point
|                 traps, and precision control = double extended.
|
|       Step 1.   Call slognd to obtain Y = log(X), the natural log of X.
|       Notes:    Even if X is denormalized, log(X) is always normalized.
|
|       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).
|            2.1  Restore the user FPCR
|            2.2  Return ans := Y * INV_L2.
|
|
|       sLog2:
|
|       Step 0.   If X < 0, create a NaN and raise the invalid operation
|                 flag. Otherwise, save FPCR in D1; set FpCR to default.
|       Notes:    Default means round-to-nearest mode, no floating-point
|                 traps, and precision control = double extended.
|
|       Step 1.   If X is not an integer power of two, i.e., X != 2^k,
|                 go to Step 3.
|
|       Step 2.   Return k.
|            2.1  Get integer k, X = 2^k.
|            2.2  Restore the user FPCR.
|            2.3  Return ans := convert-to-double-extended(k).
|
|       Step 3.   Call sLogN to obtain Y = log(X), the natural log of X.
|
|       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).
|            4.1  Restore the user FPCR
|            4.2  Return ans := Y * INV_L2.
|

|		Copyright (C) Motorola, Inc. 1990
|			All Rights Reserved
|
99 100
|       For details on the license for this file, please see the
|       file, README, in this same directory.
L
Linus Torvalds 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

|SLOG2    idnt    2,1 | Motorola 040 Floating Point Software Package

	|section	8

	|xref	t_frcinx
	|xref	t_operr
	|xref	slogn
	|xref	slognd

INV_L10:  .long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000

INV_L2:   .long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000

	.global	slog10d
slog10d:
|--entry point for Log10(X), X is denormalized
	movel		(%a0),%d0
	blt		invalid
	movel		%d1,-(%sp)
	clrl		%d1
	bsr		slognd			| ...log(X), X denorm.
	fmovel		(%sp)+,%fpcr
	fmulx		INV_L10,%fp0
	bra		t_frcinx

	.global	slog10
slog10:
|--entry point for Log10(X), X is normalized

	movel		(%a0),%d0
	blt		invalid
	movel		%d1,-(%sp)
	clrl		%d1
	bsr		slogn			| ...log(X), X normal.
	fmovel		(%sp)+,%fpcr
	fmulx		INV_L10,%fp0
	bra		t_frcinx


	.global	slog2d
slog2d:
|--entry point for Log2(X), X is denormalized

	movel		(%a0),%d0
	blt		invalid
	movel		%d1,-(%sp)
	clrl		%d1
	bsr		slognd			| ...log(X), X denorm.
	fmovel		(%sp)+,%fpcr
	fmulx		INV_L2,%fp0
	bra		t_frcinx

	.global	slog2
slog2:
|--entry point for Log2(X), X is normalized
	movel		(%a0),%d0
	blt		invalid

	movel		8(%a0),%d0
	bnes		continue		| ...X is not 2^k

	movel		4(%a0),%d0
	andl		#0x7FFFFFFF,%d0
	tstl		%d0
	bnes		continue

|--X = 2^k.
	movew		(%a0),%d0
	andl		#0x00007FFF,%d0
	subl		#0x3FFF,%d0
	fmovel		%d1,%fpcr
	fmovel		%d0,%fp0
	bra		t_frcinx

continue:
	movel		%d1,-(%sp)
	clrl		%d1
	bsr		slogn			| ...log(X), X normal.
	fmovel		(%sp)+,%fpcr
	fmulx		INV_L2,%fp0
	bra		t_frcinx

invalid:
	bra		t_operr

	|end