blob: 5e08856d0a3ea764ef75f28a93f6a669c771a289 [file] [log] [blame]
/* libs/opengles/fixed_asm.S
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
.text
.align 2
.global gglFloatToFixed
.type gglFloatToFixed, %function
.global gglFloatToFixedFast
.type gglFloatToFixedFast, %function
/*
* Converts a float to a s15.16 fixed-point number.
* this doesn't handle floats out of the [-32768, +32768[ range
* and doesn't performs round-to-nearest.
* however, it's very fast :-)
*/
gglFloatToFixedFast:
movs r1, r0, lsl #1 /* remove bit sign */
mov r2, #0x8E /* 127 + 15 */
sub r1, r2, r1, lsr #24 /* compute shift */
mov r2, r0, lsl #8 /* mantissa<<8 */
orr r2, r2, #0x80000000 /* add the missing 1 */
mov r0, r2, lsr r1 /* scale to 16.16 */
rsbcs r0, r0, #0 /* negate if needed */
bx lr
/*
* this version rounds-to-nearest and saturates numbers
* outside the range (but not NaNs).
*/
gglFloatToFixed:
mov r1, r0, lsl #1 /* remove bit sign */
mov r2, #0x8E /* 127 + 15 */
subs r1, r2, r1, lsr #24 /* compute shift */
bls 0f /* too big */
mov r2, r0, lsl #8 /* mantissa<<8 */
orr r2, r2, #0x80000000 /* add the missing 1 */
mov r3, r0
movs r0, r2, lsr r1 /* scale to 16.16 */
addcs r0, r0, #1 /* round-to-nearest */
tst r3, #0x80000000 /* negative? */
rsbne r0, r0, #0 /* negate if needed */
bx lr
0: ands r0, r0, #0x80000000 /* keep only the sign bit */
moveq r0, #0x7fffffff /* positive, maximum value */
bx lr