blob: 05044f2cd0a7dc103d9f234af776113b347fb8f4 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* libs/opengles/fixed_asm.S
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18
19 .text
20 .align
21
22 .global gglFloatToFixed
Doug Kwan89fe2452009-12-07 13:21:24 -080023 .type gglFloatToFixed, %function
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024 .global gglFloatToFixedFast
Doug Kwan89fe2452009-12-07 13:21:24 -080025 .type gglFloatToFixedFast, %function
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026
27
28/*
29 * Converts a float to a s15.16 fixed-point number.
30 * this doesn't handle floats out of the [-32768, +32768[ range
31 * and doesn't performs round-to-nearest.
32 * however, it's very fast :-)
33 */
34
35gglFloatToFixedFast:
36 movs r1, r0, lsl #1 /* remove bit sign */
37 mov r2, #0x8E /* 127 + 15 */
38 sub r1, r2, r1, lsr #24 /* compute shift */
39 mov r2, r0, lsl #8 /* mantissa<<8 */
40 orr r2, r2, #0x80000000 /* add the missing 1 */
41 mov r0, r2, lsr r1 /* scale to 16.16 */
42 rsbcs r0, r0, #0 /* negate if needed */
43 bx lr
44
45/*
46 * this version rounds-to-nearest and saturates numbers
47 * outside the range (but not NaNs).
48 */
49
50gglFloatToFixed:
51 mov r1, r0, lsl #1 /* remove bit sign */
52 mov r2, #0x8E /* 127 + 15 */
53 subs r1, r2, r1, lsr #24 /* compute shift */
54 bls 0f /* too big */
55 mov r2, r0, lsl #8 /* mantissa<<8 */
56 orr r2, r2, #0x80000000 /* add the missing 1 */
57 mov r3, r0
58 movs r0, r2, lsr r1 /* scale to 16.16 */
59 addcs r0, r0, #1 /* round-to-nearest */
60 tst r3, #0x80000000 /* negative? */
61 rsbne r0, r0, #0 /* negate if needed */
62 bx lr
63
640: ands r0, r0, #0x80000000 /* keep only the sign bit */
65 moveq r0, #0x7fffffff /* positive, maximum value */
66 bx lr
67