1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef ANDROID_GGL_FIXED_H
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ANDROID_GGL_FIXED_H
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <math.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pixelflinger/pixelflinger.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CONST           __attribute__((const))
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ALWAYS_INLINE   __attribute__((always_inline))
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_BITS = 16;
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_EPSILON  = 1;
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_ONE  = 1L<<FIXED_BITS;
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_HALF = 1L<<(FIXED_BITS-1);
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_MIN  = 0x80000000L;
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_MAX  = 0x7FFFFFFFL;
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglIntToFixed(GGLfixed i)       ALWAYS_INLINE ;
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFixedToIntRound(GGLfixed f)  ALWAYS_INLINE ;
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFixedToIntFloor(GGLfixed f)  ALWAYS_INLINE ;
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFixedToIntCeil(GGLfixed f)   ALWAYS_INLINE ;
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFracx(GGLfixed v)            ALWAYS_INLINE ;
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFloorx(GGLfixed v)           ALWAYS_INLINE ;
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglCeilx(GGLfixed v)            ALWAYS_INLINE ;
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglCenterx(GGLfixed v)          ALWAYS_INLINE ;
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRoundx(GGLfixed v)           ALWAYS_INLINE ;
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglIntToFixed(GGLfixed i) {
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return i<<FIXED_BITS;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFixedToIntRound(GGLfixed f) {
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (f + FIXED_HALF)>>FIXED_BITS;
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFixedToIntFloor(GGLfixed f) {
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return f>>FIXED_BITS;
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFixedToIntCeil(GGLfixed f) {
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (f + ((1<<FIXED_BITS) - 1))>>FIXED_BITS;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFracx(GGLfixed v) {
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return v & ((1<<FIXED_BITS)-1);
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFloorx(GGLfixed v) {
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglFixedToIntFloor(v)<<FIXED_BITS;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglCeilx(GGLfixed v) {
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglFixedToIntCeil(v)<<FIXED_BITS;
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglCenterx(GGLfixed v) {
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglFloorx(v + FIXED_HALF) | FIXED_HALF;
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglRoundx(GGLfixed v) {
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglFixedToIntRound(v)<<FIXED_BITS;
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// conversion from (unsigned) int, short, byte to fixed...
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_B_TO_X(_x)      GGLfixed( ((int32_t(_x)+1)>>1)<<10 )
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_S_TO_X(_x)      GGLfixed( ((int32_t(_x)+1)>>1)<<2 )
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_I_TO_X(_x)      GGLfixed( ((int32_t(_x)>>1)+1)>>14 )
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_UB_TO_X(_x)     GGLfixed(   uint32_t(_x) +      \
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                        (uint32_t(_x)<<8) + \
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                        (uint32_t(_x)>>7) )
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_US_TO_X(_x)     GGLfixed( (_x) + ((_x)>>15) )
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_UI_TO_X(_x)     GGLfixed( (((_x)>>1)+1)>>15 )
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglPowx(GGLfixed x, GGLfixed y) CONST;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglSqrtx(GGLfixed a) CONST;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglSqrtRecipx(GGLfixed x) CONST;
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFastDivx(GGLfixed n, GGLfixed d) CONST;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglMulDivi(int32_t a, int32_t b, int32_t c);
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglRecipQNormalized(int32_t x, int* exponent);
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglRecipQ(GGLfixed x, int q) CONST;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecip(GGLfixed x) CONST;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecip(GGLfixed x) {
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglRecipQ(x, 16);
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecip28(GGLfixed x) CONST;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglRecip28(GGLfixed x) {
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglRecipQ(x, 28);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) && !defined(__thumb__)
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// inline ARM implementations
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) CONST;
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) {
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLfixed result, t;
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (__builtin_constant_p(shift)) {
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull  %[lo], %[hi], %[x], %[y]            \n"
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "movs   %[lo], %[lo], lsr %[rshift]         \n"
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "adc    %[lo], %[lo], %[hi], lsl %[lshift]  \n"
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : [lo]"=r"(result), [hi]"=r"(t), [x]"=r"(x)
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%[x]"(x), [y]"r"(y), [lshift] "I"(32-shift), [rshift] "I"(shift)
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "cc"
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull  %[lo], %[hi], %[x], %[y]            \n"
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "movs   %[lo], %[lo], lsr %[rshift]         \n"
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "adc    %[lo], %[lo], %[hi], lsl %[lshift]  \n"
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x)
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%[x]"(x), [y]"r"(y), [lshift] "r"(32-shift), [rshift] "r"(shift)
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "cc"
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return result;
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) {
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLfixed result, t;
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (__builtin_constant_p(shift)) {
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull  %[lo], %[hi], %[x], %[y]            \n"
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "add    %[lo], %[a],  %[lo], lsr %[rshift]  \n"
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "add    %[lo], %[lo], %[hi], lsl %[lshift]  \n"
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x)
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "I"(32-shift), [rshift] "I"(shift)
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull  %[lo], %[hi], %[x], %[y]            \n"
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "add    %[lo], %[a],  %[lo], lsr %[rshift]  \n"
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "add    %[lo], %[lo], %[hi], lsl %[lshift]  \n"
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x)
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "r"(32-shift), [rshift] "r"(shift)
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return result;
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) {
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLfixed result, t;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (__builtin_constant_p(shift)) {
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull  %[lo], %[hi], %[x], %[y]            \n"
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "rsb    %[lo], %[a],  %[lo], lsr %[rshift]  \n"
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "add    %[lo], %[lo], %[hi], lsl %[lshift]  \n"
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x)
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "I"(32-shift), [rshift] "I"(shift)
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull  %[lo], %[hi], %[x], %[y]            \n"
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "rsb    %[lo], %[a],  %[lo], lsr %[rshift]  \n"
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "add    %[lo], %[lo], %[hi], lsl %[lshift]  \n"
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x)
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "r"(32-shift), [rshift] "r"(shift)
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return result;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t x, int32_t y) CONST;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t x, int32_t y)
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // 64-bits result: r0=low, r1=high
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    union {
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct {
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int32_t lo;
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int32_t hi;
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } s;
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int64_t res;
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    };
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("smull %0, %1, %2, %3   \n"
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "=r"(s.lo), "=&r"(s.hi)
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        : "%r"(x), "r"(y)
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        :
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return res;
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else // ----------------------------------------------------------------------
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST;
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) {
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed((int64_t(a)*b + (1<<(shift-1)))>>shift);
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed((int64_t(a)*b)>>shift) + c;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed((int64_t(a)*b)>>shift) - c;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) CONST;
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) {
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return int64_t(a)*b;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) CONST;
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) {
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglMulx(a, b, 16);
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) CONST;
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) {
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglMulAddx(a, b, c, 16);
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) CONST;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) {
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglMulSubx(a, b, c, 16);
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x) CONST;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x)
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) && !defined(__thumb__)
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return __builtin_clz(x);
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!x) return 32;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int32_t exp = 31;
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0xFFFF0000) { exp -=16; x >>= 16; }
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x0000ff00) { exp -= 8; x >>= 8; }
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x000000f0) { exp -= 4; x >>= 4; }
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x0000000c) { exp -= 2; x >>= 2; }
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x00000002) { exp -= 1; }
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return exp;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglDivQ(GGLfixed n, GGLfixed d, int32_t i) CONST;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) CONST;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) {
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglDivQ(n, d, 16);
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) CONST;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) {
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglDivQ(n, d, 16);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x) CONST;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x)
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // This is a really bad approximation of 1/x, but it's also
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // very fast. x must be strictly positive.
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // if x between [0.5, 1[ , then 1/x = 3-2*x
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // (we use 2.30 fixed-point)
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int32_t lz = gglClz(x);
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (0xC0000000 - (x << (lz - 1))) >> (30-lz);
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c) CONST;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c)
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__thumb__)
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // clamp without branches
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c &= ~(c>>31);  c = FIXED_ONE - c;
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c &= ~(c>>31);  c = FIXED_ONE - c;
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__)
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // I don't know why gcc thinks its smarter than me! The code below
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // clamps to zero in one instruction, but gcc won't generate it and
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // replace it by a cmp + movlt (it's quite amazing actually).
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("bic %0, %1, %1, asr #31\n" : "=r"(c) : "r"(c));
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c &= ~(c>>31);
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c>FIXED_ONE)
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = FIXED_ONE;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return c;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ANDROID_GGL_FIXED_H
303