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}
193096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#elif defined(__mips__)
194096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
195096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand/*inline MIPS implementations*/
196096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST;
197096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) {
198096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    GGLfixed result,tmp,tmp1,tmp2;
199096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
200096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    if (__builtin_constant_p(shift)) {
201096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        if (shift == 0) {
202096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            asm ("mult %[a], %[b] \t\n"
203096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand              "mflo  %[res]   \t\n"
204096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [res]"=&r"(result),[tmp]"=&r"(tmp)
205096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [a]"r"(a),[b]"r"(b)
206096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : "%hi","%lo"
207096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            );
208096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        } else if (shift == 32)
209096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        {
210096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            asm ("mult %[a], %[b] \t\n"
211096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "li  %[tmp],1\t\n"
212096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sll  %[tmp],%[tmp],0x1f\t\n"
213096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "mflo %[res]   \t\n"
214096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu %[tmp1],%[tmp],%[res] \t\n"
215096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sltu %[tmp1],%[tmp1],%[tmp]\t\n"   /*obit*/
216096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sra %[tmp],%[tmp],0x1f \t\n"
217096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "mfhi  %[res]   \t\n"
218096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu %[res],%[res],%[tmp]\t\n"
219096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu %[res],%[res],%[tmp1]\t\n"
220096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1)
221096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [a]"r"(a),[b]"r"(b),[shift]"I"(shift)
222096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : "%hi","%lo"
223096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            );
224096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        } else if ((shift >0) && (shift < 32))
225096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        {
226096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            asm ("mult %[a], %[b] \t\n"
227096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "li  %[tmp],1 \t\n"
228096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sll  %[tmp],%[tmp],%[shiftm1] \t\n"
229096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "mflo  %[res]   \t\n"
230096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu %[tmp1],%[tmp],%[res] \t\n"
231096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sltu %[tmp1],%[tmp1],%[tmp] \t\n"  /*obit?*/
232096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu  %[res],%[res],%[tmp] \t\n"
233096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "mfhi  %[tmp]   \t\n"
234096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu  %[tmp],%[tmp],%[tmp1] \t\n"
235096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sll   %[tmp],%[tmp],%[lshift] \t\n"
236096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "srl   %[res],%[res],%[rshift]    \t\n"
237096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "or    %[res],%[res],%[tmp] \t\n"
238096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
239096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [a]"r"(a),[b]"r"(b),[lshift]"I"(32-shift),[rshift]"I"(shift),[shiftm1]"I"(shift-1)
240096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : "%hi","%lo"
241096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            );
242096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        } else {
243096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            asm ("mult %[a], %[b] \t\n"
244096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "li  %[tmp],1 \t\n"
245096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sll  %[tmp],%[tmp],%[shiftm1] \t\n"
246096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "mflo  %[res]   \t\n"
247096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu %[tmp1],%[tmp],%[res] \t\n"
248096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sltu %[tmp1],%[tmp1],%[tmp] \t\n"  /*obit?*/
249096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sra  %[tmp2],%[tmp],0x1f \t\n"
250096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu  %[res],%[res],%[tmp] \t\n"
251096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "mfhi  %[tmp]   \t\n"
252096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu  %[tmp],%[tmp],%[tmp2] \t\n"
253096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "addu  %[tmp],%[tmp],%[tmp1] \t\n"            /*tmp=hi*/
254096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "srl   %[tmp2],%[res],%[rshift]    \t\n"
255096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "srav  %[res], %[tmp],%[rshift]\t\n"
256096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sll   %[tmp],%[tmp],1 \t\n"
257096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "sll   %[tmp],%[tmp],%[norbits] \t\n"
258096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "or    %[tmp],%[tmp],%[tmp2] \t\n"
259096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            "movz  %[res],%[tmp],%[bit5] \t\n"
260096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
261096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : [a]"r"(a),[b]"r"(b),[norbits]"I"(~(shift)),[rshift]"I"(shift),[shiftm1] "I"(shift-1),[bit5]"I"(shift & 0x20)
262096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            : "%hi","%lo"
263096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            );
264096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        }
265096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    } else {
266096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        asm ("mult %[a], %[b] \t\n"
267096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "li  %[tmp],1 \t\n"
268096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "sll  %[tmp],%[tmp],%[shiftm1] \t\n"
269096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "mflo  %[res]   \t\n"
270096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "addu %[tmp1],%[tmp],%[res] \t\n"
271096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "sltu %[tmp1],%[tmp1],%[tmp] \t\n"  /*obit?*/
272096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "sra  %[tmp2],%[tmp],0x1f \t\n"
273096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "addu  %[res],%[res],%[tmp] \t\n"
274096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "mfhi  %[tmp]   \t\n"
275096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "addu  %[tmp],%[tmp],%[tmp2] \t\n"
276096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "addu  %[tmp],%[tmp],%[tmp1] \t\n"            /*tmp=hi*/
277096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "srl   %[tmp2],%[res],%[rshift]    \t\n"
278096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "srav  %[res], %[tmp],%[rshift]\t\n"
279096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "sll   %[tmp],%[tmp],1 \t\n"
280096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "sll   %[tmp],%[tmp],%[norbits] \t\n"
281096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "or    %[tmp],%[tmp],%[tmp2] \t\n"
282096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "movz  %[res],%[tmp],%[bit5] \t\n"
283096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand         : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
284096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand         : [a]"r"(a),[b]"r"(b),[norbits]"r"(~(shift)),[rshift] "r"(shift),[shiftm1]"r"(shift-1),[bit5] "r"(shift & 0x20)
285096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand         : "%hi","%lo"
286096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand         );
287096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        }
288096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
289096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        return result;
290096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand}
291096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
292096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
293096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
294096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    GGLfixed result,t,tmp1,tmp2;
295096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
296096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    if (__builtin_constant_p(shift)) {
297096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        if (shift == 0) {
298096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 asm ("mult %[a], %[b] \t\n"
299096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 "mflo  %[lo]   \t\n"
300096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 "addu  %[lo],%[lo],%[c]    \t\n"
301096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 : [lo]"=&r"(result)
302096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 : [a]"r"(a),[b]"r"(b),[c]"r"(c)
303096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 : "%hi","%lo"
304096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 );
305096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else if (shift == 32) {
306096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    asm ("mult %[a], %[b] \t\n"
307096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mfhi  %[lo]   \t\n"
308096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "addu  %[lo],%[lo],%[c]    \t\n"
309096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [lo]"=&r"(result)
310096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [a]"r"(a),[b]"r"(b),[c]"r"(c)
311096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : "%hi","%lo"
312096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    );
313096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else if ((shift>0) && (shift<32)) {
314096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    asm ("mult %[a], %[b] \t\n"
315096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mflo  %[res]   \t\n"
316096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mfhi  %[t]   \t\n"
317096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "srl   %[res],%[res],%[rshift]    \t\n"
318096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "sll   %[t],%[t],%[lshift]     \t\n"
319096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "or  %[res],%[res],%[t]    \t\n"
320096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "addu  %[res],%[res],%[c]    \t\n"
321096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [res]"=&r"(result),[t]"=&r"(t)
322096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift)
323096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : "%hi","%lo"
324096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    );
325096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else {
326096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    asm ("mult %[a], %[b] \t\n"
327096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "nor %[tmp1],$zero,%[shift]\t\n"
328096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mflo  %[res]   \t\n"
329096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mfhi  %[t]   \t\n"
330096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "srl   %[res],%[res],%[shift]    \t\n"
331096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "sll   %[tmp2],%[t],1     \t\n"
332096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
333096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "or  %[tmp1],%[tmp2],%[res]    \t\n"
334096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "srav  %[res],%[t],%[shift]     \t\n"
335096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "andi %[tmp2],%[shift],0x20\t\n"
336096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "movz %[res],%[tmp1],%[tmp2]\t\n"
337096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "addu  %[res],%[res],%[c]    \t\n"
338096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
339096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift)
340096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : "%hi","%lo"
341096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    );
342096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                }
343096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            } else {
344096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                asm ("mult %[a], %[b] \t\n"
345096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "nor %[tmp1],$zero,%[shift]\t\n"
346096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "mflo  %[res]   \t\n"
347096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "mfhi  %[t]   \t\n"
348096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "srl   %[res],%[res],%[shift]    \t\n"
349096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "sll   %[tmp2],%[t],1     \t\n"
350096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
351096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "or  %[tmp1],%[tmp2],%[res]    \t\n"
352096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "srav  %[res],%[t],%[shift]     \t\n"
353096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "andi %[tmp2],%[shift],0x20\t\n"
354096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "movz %[res],%[tmp1],%[tmp2]\t\n"
355096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "addu  %[res],%[res],%[c]    \t\n"
356096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
357096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift)
358096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                : "%hi","%lo"
359096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                );
360096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            }
361096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            return result;
362096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand}
363096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
364096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
365096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
366096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    GGLfixed result,t,tmp1,tmp2;
367096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
368096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    if (__builtin_constant_p(shift)) {
369096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        if (shift == 0) {
370096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 asm ("mult %[a], %[b] \t\n"
371096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 "mflo  %[lo]   \t\n"
372096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 "subu  %[lo],%[lo],%[c]    \t\n"
373096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 : [lo]"=&r"(result)
374096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 : [a]"r"(a),[b]"r"(b),[c]"r"(c)
375096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 : "%hi","%lo"
376096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                 );
377096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else if (shift == 32) {
378096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    asm ("mult %[a], %[b] \t\n"
379096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mfhi  %[lo]   \t\n"
380096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "subu  %[lo],%[lo],%[c]    \t\n"
381096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [lo]"=&r"(result)
382096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [a]"r"(a),[b]"r"(b),[c]"r"(c)
383096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : "%hi","%lo"
384096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    );
385096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else if ((shift>0) && (shift<32)) {
386096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    asm ("mult %[a], %[b] \t\n"
387096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mflo  %[res]   \t\n"
388096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "mfhi  %[t]   \t\n"
389096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "srl   %[res],%[res],%[rshift]    \t\n"
390096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "sll   %[t],%[t],%[lshift]     \t\n"
391096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "or  %[res],%[res],%[t]    \t\n"
392096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "subu  %[res],%[res],%[c]    \t\n"
393096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [res]"=&r"(result),[t]"=&r"(t)
394096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift)
395096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    : "%hi","%lo"
396096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    );
397096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else {
398096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    asm ("mult %[a], %[b] \t\n"
399096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    "nor %[tmp1],$zero,%[shift]\t\n"
400096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "mflo  %[res]   \t\n"
401096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "mfhi  %[t]   \t\n"
402096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "srl   %[res],%[res],%[shift]    \t\n"
403096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "sll   %[tmp2],%[t],1     \t\n"
404096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
405096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "or  %[tmp1],%[tmp2],%[res]    \t\n"
406096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "srav  %[res],%[t],%[shift]     \t\n"
407096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "andi %[tmp2],%[shift],0x20\t\n"
408096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "movz %[res],%[tmp1],%[tmp2]\t\n"
409096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     "subu  %[res],%[res],%[c]    \t\n"
410096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
411096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift)
412096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     : "%hi","%lo"
413096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                     );
414096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                    }
415096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                } else {
416096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                asm ("mult %[a], %[b] \t\n"
417096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "nor %[tmp1],$zero,%[shift]\t\n"
418096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "mflo  %[res]   \t\n"
419096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "mfhi  %[t]   \t\n"
420096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "srl   %[res],%[res],%[shift]    \t\n"
421096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "sll   %[tmp2],%[t],1     \t\n"
422096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
423096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "or  %[tmp1],%[tmp2],%[res]    \t\n"
424096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "srav  %[res],%[t],%[shift]     \t\n"
425096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "andi %[tmp2],%[shift],0x20\t\n"
426096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "movz %[res],%[tmp1],%[tmp2]\t\n"
427096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                "subu  %[res],%[res],%[c]    \t\n"
428096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
429096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift)
430096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                : "%hi","%lo"
431096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand                );
432096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            }
433096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    return result;
434096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand}
435096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand
436096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline int64_t gglMulii(int32_t x, int32_t y) CONST;
437096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline int64_t gglMulii(int32_t x, int32_t y) {
438096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    union {
439096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        struct {
440096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#if defined(__MIPSEL__)
441096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            int32_t lo;
442096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            int32_t hi;
443096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#elif defined(__MIPSEB__)
444096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            int32_t hi;
445096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand            int32_t lo;
446096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#endif
447096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        } s;
448096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        int64_t res;
449096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    }u;
450096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    asm("mult %2, %3 \t\n"
451096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "mfhi %1   \t\n"
452096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        "mflo %0   \t\n"
453096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        : "=r"(u.s.lo), "=&r"(u.s.hi)
454096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        : "%r"(x), "r"(y)
455096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand	: "%hi","%lo"
456096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand        );
457096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand    return u.res;
458096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand}
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else // ----------------------------------------------------------------------
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST;
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) {
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed((int64_t(a)*b + (1<<(shift-1)))>>shift);
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed((int64_t(a)*b)>>shift) + c;
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed((int64_t(a)*b)>>shift) - c;
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) CONST;
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) {
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return int64_t(a)*b;
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) CONST;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) {
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglMulx(a, b, 16);
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) CONST;
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) {
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglMulAddx(a, b, c, 16);
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) CONST;
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) {
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglMulSubx(a, b, c, 16);
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x) CONST;
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x)
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
501096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#if (defined(__arm__) && !defined(__thumb__)) || defined(__mips__)
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return __builtin_clz(x);
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!x) return 32;
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int32_t exp = 31;
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0xFFFF0000) { exp -=16; x >>= 16; }
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x0000ff00) { exp -= 8; x >>= 8; }
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x000000f0) { exp -= 4; x >>= 4; }
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x0000000c) { exp -= 2; x >>= 2; }
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x & 0x00000002) { exp -= 1; }
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return exp;
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglDivQ(GGLfixed n, GGLfixed d, int32_t i) CONST;
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) CONST;
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) {
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglDivQ(n, d, 16);
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) CONST;
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) {
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return gglDivQ(n, d, 16);
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x) CONST;
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x)
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // This is a really bad approximation of 1/x, but it's also
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // very fast. x must be strictly positive.
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // if x between [0.5, 1[ , then 1/x = 3-2*x
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // (we use 2.30 fixed-point)
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int32_t lz = gglClz(x);
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (0xC0000000 - (x << (lz - 1))) >> (30-lz);
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c) CONST;
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c)
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__thumb__)
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // clamp without branches
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c &= ~(c>>31);  c = FIXED_ONE - c;
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c &= ~(c>>31);  c = FIXED_ONE - c;
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__)
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // I don't know why gcc thinks its smarter than me! The code below
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // clamps to zero in one instruction, but gcc won't generate it and
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // replace it by a cmp + movlt (it's quite amazing actually).
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asm("bic %0, %1, %1, asr #31\n" : "=r"(c) : "r"(c));
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c &= ~(c>>31);
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c>FIXED_ONE)
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = FIXED_ONE;
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return c;
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ANDROID_GGL_FIXED_H
569