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 99 100 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
|
/*
* floatsisf.s
*
* Signed long to floating point conversion, single precision:
* r0r1 = (float) long r0r1
* Unsigned long to floating point conversion, single precision:
* r0r1 = (float) unsigned long r0r1
*
* GCC does not directly invoke the unsigned long conversion function
* Instead, it wraps the signed long function with a good amount of extra code
* You can save space by calling the latter conversion function yourself
* If you want to use it, you should invoke it yourself, as a function
* The declaration is: extern float __ufloatsisf (unsigned long value);
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Librcx floating point code, released May 27, 1999.
*
* The Initial Developer of the Original Code is Kekoa Proudfoot.
* Portions created by Kekoa Proudfoot are Copyright (C) 1999
* Kekoa Proudfoot. All Rights Reserved.
*
* Contributor(s): Kekoa Proudfoot <kekoa@graphics.stanford.edu>
*/
; possible optimizations
; - integrate msb test and sticky shift with fixoverflow in joinsf
; - add a bor #7,r5h to see if four bit is set
; - factor out stickyshift function, rewrite fixoverflow in joinsf to call it
; - affects this, since we can then call stickyshift right
; - if ufloatsisf removed, msb test should set mantissa to 7fffffff
; - also, msb test should be moved earlier to inside negative input test
.section .text
;;
;; function: ufloatsisf
;; input: unsigned long in r0r1
;; output: float in r0r1
;;
.global ___ufloatsisf
___ufloatsisf:
; Save registers (assume r2 and r3 saved by caller)
push r4
push r5
mov.w r6,r2 ; we need r6 specifically, but do not need r2
; Jump into floatsisf
bra ufloatentry
;;
;; function: floatsisf
;; input: signed long in r0r1
;; output: float in r0r1
;;
.global ___floatsisf
___floatsisf:
; Save registers (assume r2 and r3 saved by caller)
push r4
push r5
mov.w r6,r2 ; we need r6 specifically, but do not need r2
; Is input negative?
btst #7,r0h ; is r0r1 < 0?
beq else_0 ; equal indicates false
; Set sign to negative
mov.b #0x80,r3l ; set sign (r3l) to 0x80 to indicate negative
; Store -input to mantissa
sub.w r5,r5 ; zero destination
sub.w r6,r6
sub.w r1,r6 ; subtract input
subx.b r0l,r5l
subx.b r0h,r5h
bra endif_0
else_0:
ufloatentry:
; Set sign to positive
sub.b r3l,r3l ; set sign (r3l) to zero to indicate positive
; Store input to mantissa
mov.w r0,r5 ; set mantissa
mov.w r1,r6
endif_0:
; Set exponent
mov.w #156,r4 ; set exponent to 29 + bias, bias is 127
; Is msb set?
btst #7,r5h ; is msb set?
beq else_1 ; zero indicates false
; Mantissa overflow, so shift right one place, maintaining sticky bit
shlr.b r5h ; shift mantissa right 1 place
rotxr.b r5l
rotxr.b r6h
rotxr.b r6l ; last shift places old sticky bit in carry
bor #0,r6l ; or lsb with old sticky bit
bst #0,r6l ; store new sticky bit
; Increase exponent
adds #1,r4 ; add one to exponent
bra endif_1
else_1:
; Is mantissa non-zero?
mov.w r5,r5 ; check upper word
bne if_2 ; not equal to zero indicates true
mov.w r6,r6 ; check lower word
beq endif_2 ; equal to zero indicates false
if_2:
; Is the two bit (40000000) clear?
btst #6,r5h ; check 40000000 bit
bne endif_3 ; non-zero indicates false (bit set)
; Normalize
jsr ___normalizesf
endif_3:
endif_2:
endif_1:
; Join
jsr ___joinsf
return:
; Restore registers
mov.w r2,r6
pop r5
pop r4
rts
|