summaryrefslogtreecommitdiffstats
path: root/opengl/libagl/fixed_asm.S
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/libagl/fixed_asm.S')
-rw-r--r--opengl/libagl/fixed_asm.S65
1 files changed, 65 insertions, 0 deletions
diff --git a/opengl/libagl/fixed_asm.S b/opengl/libagl/fixed_asm.S
new file mode 100644
index 0000000..6cbc56f
--- /dev/null
+++ b/opengl/libagl/fixed_asm.S
@@ -0,0 +1,65 @@
+/* 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
+
+ .global gglFloatToFixed
+ .global gglFloatToFixedFast
+
+
+/*
+ * 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
+