load_store.cpp revision 4dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/codeflinger/load_store.cpp
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License.
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "codeflinger/GGLAssembler.h"
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
234dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#include <machine/cpu-features.h>
244dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::store(const pointer_t& addr, const pixel_t& s, uint32_t flags)
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int bits = addr.size;
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int inc = (flags & WRITE_BACK)?1:0;
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (bits) {
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 32:
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)    STR(AL, s.reg, addr.reg, immed12_post(4));
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else        STR(AL, s.reg, addr.reg);
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 24:
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // 24 bits formats are a little special and used only for RGB
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // 0x00BBGGRR is unpacked as R,G,B
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        STRB(AL, s.reg, addr.reg, immed12_pre(0));
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8));
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        STRB(AL, s.reg, addr.reg, immed12_pre(1));
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8));
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        STRB(AL, s.reg, addr.reg, immed12_pre(2));
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!(s.flags & CORRUPTIBLE)) {
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 16));
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, addr.reg, addr.reg, imm(3));
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 16:
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)    STRH(AL, s.reg, addr.reg, immed8_post(2));
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else        STRH(AL, s.reg, addr.reg);
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case  8:
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)    STRB(AL, s.reg, addr.reg, immed12_post(1));
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else        STRB(AL, s.reg, addr.reg);
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::load(const pointer_t& addr, const pixel_t& s, uint32_t flags)
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    Scratch scratches(registerFile());
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s0;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int bits = addr.size;
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int inc = (flags & WRITE_BACK)?1:0;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (bits) {
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 32:
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)    LDR(AL, s.reg, addr.reg, immed12_post(4));
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else        LDR(AL, s.reg, addr.reg);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 24:
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // 24 bits formats are a little special and used only for RGB
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // R,G,B is packed as 0x00BBGGRR
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s0 = scratches.obtain();
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (s.reg != addr.reg) {
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRB(AL, s.reg, addr.reg, immed12_pre(0));      // R
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRB(AL, s0, addr.reg, immed12_pre(1));         // G
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ORR(AL, 0, s.reg, s.reg, reg_imm(s0, LSL, 8));
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRB(AL, s0, addr.reg, immed12_pre(2));         // B
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ORR(AL, 0, s.reg, s.reg, reg_imm(s0, LSL, 16));
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int s1 = scratches.obtain();
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRB(AL, s1, addr.reg, immed12_pre(0));         // R
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRB(AL, s0, addr.reg, immed12_pre(1));         // G
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ORR(AL, 0, s1, s1, reg_imm(s0, LSL, 8));
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRB(AL, s0, addr.reg, immed12_pre(2));         // B
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ORR(AL, 0, s.reg, s1, reg_imm(s0, LSL, 16));
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, addr.reg, addr.reg, imm(3));
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 16:
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)    LDRH(AL, s.reg, addr.reg, immed8_post(2));
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else        LDRH(AL, s.reg, addr.reg);
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case  8:
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (inc)    LDRB(AL, s.reg, addr.reg, immed12_post(1));
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else        LDRB(AL, s.reg, addr.reg);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits)
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int maskLen = h-l;
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert(maskLen<=8);
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert(h);
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1144dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#if __ARM_ARCH__ >= 7
1154dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    const int mask = (1<<maskLen)-1;
1164dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    if ((h == bits) && !l && (s != d.reg)) {
1174dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell        MOV(AL, 0, d.reg, s);                   // component = packed;
1184dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    } else if ((h == bits) && l) {
1194dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell        MOV(AL, 0, d.reg, reg_imm(s, LSR, l));  // component = packed >> l;
1204dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    } else if (!l && isValidImmediate(mask)) {
1214dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell        AND(AL, 0, d.reg, s, imm(mask));        // component = packed & mask;
1224dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    } else if (!l && isValidImmediate(~mask)) {
1234dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell        BIC(AL, 0, d.reg, s, imm(~mask));       // component = packed & mask;
1244dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    } else {
1254dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell        UBFX(AL, d.reg, s, l, maskLen);         // component = (packed & mask) >> l;
1264dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    }
1274dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#else
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (h != bits) {
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int mask = ((1<<maskLen)-1) << l;
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (isValidImmediate(mask)) {
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            AND(AL, 0, d.reg, s, imm(mask));    // component = packed & mask;
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (isValidImmediate(~mask)) {
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            BIC(AL, 0, d.reg, s, imm(~mask));   // component = packed & mask;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, d.reg, reg_imm(s, LSL, 32-h));
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            l += 32-h;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            h = 32;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s = d.reg;
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (l) {
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, d.reg, reg_imm(s, LSR, l));  // component = packed >> l;
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s = d.reg;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (s != d.reg) {
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, d.reg, s);
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1504dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#endif
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d.s = maskLen;
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::extract(integer_t& d, const pixel_t& s, int component)
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    extract(d,  s.reg,
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.format.c[component].h,
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.format.c[component].l,
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.size());
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::extract(component_t& d, const pixel_t& s, int component)
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    integer_t r(d.reg, 32, d.flags);
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    extract(r,  s.reg,
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.format.c[component].h,
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.format.c[component].l,
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.size());
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d = component_t(r);
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::expand(integer_t& d, const component_t& s, int dbits)
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (s.l || (s.flags & CLEAR_HI)) {
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        extract(d, s.reg, s.h, s.l, 32);
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        expand(d, d, dbits);
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        expand(d, integer_t(s.reg, s.size(), s.flags), dbits);
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::expand(component_t& d, const component_t& s, int dbits)
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    integer_t r(d.reg, 32, d.flags);
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    expand(r, s, dbits);
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d = component_t(r);
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::expand(integer_t& dst, const integer_t& src, int dbits)
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert(src.size());
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int sbits = src.size();
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s = src.reg;
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int d = dst.reg;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // be sure to set 'dst' after we read 'src' as they may be identical
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst.s = dbits;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst.flags = 0;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (dbits<=sbits) {
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (s != d) {
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, d, s);
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sbits == 1) {
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RSB(AL, 0, d, s, reg_imm(s, LSL, dbits));
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // d = (s<<dbits) - s;
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (dbits % sbits) {
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, d, reg_imm(s, LSL, dbits-sbits));
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // d = s << (dbits-sbits);
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dbits -= sbits;
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do {
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ORR(AL, 0, d, d, reg_imm(d, LSR, sbits));
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // d |= d >> sbits;
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dbits -= sbits;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sbits *= 2;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } while(dbits>0);
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dbits -= sbits;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    do {
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ORR(AL, 0, d, s, reg_imm(s, LSL, sbits));
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // d |= d<<sbits;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s = d;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dbits -= sbits;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (sbits*2 < dbits) {
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sbits *= 2;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } while(dbits>0);
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::downshift(
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel_t& d, int component, component_t s, const reg_t& dither)
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const needs_t& needs = mBuilderContext.needs;
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    Scratch scratches(registerFile());
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int sh = s.h;
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int sl = s.l;
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int maskHiBits = (sh!=32) ? ((s.flags & CLEAR_HI)?1:0) : 0;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int maskLoBits = (sl!=0)  ? ((s.flags & CLEAR_LO)?1:0) : 0;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int sbits = sh - sl;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dh = d.format.c[component].h;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dl = d.format.c[component].l;
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dbits = dh - dl;
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dithering = 0;
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOGE_IF(sbits<dbits, "sbits (%d) < dbits (%d) in downshift", sbits, dbits);
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sbits>dbits) {
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // see if we need to dither
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dithering = mDithering;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ireg = d.reg;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!(d.flags & FIRST)) {
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (s.flags & CORRUPTIBLE)  {
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ireg = s.reg;
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ireg = scratches.obtain();
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d.flags &= ~FIRST;
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (maskHiBits) {
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // we need to mask the high bits (and possibly the lowbits too)
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // and we might be able to use immediate mask.
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!dithering) {
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // we don't do this if we only have maskLoBits because we can
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // do it more efficiently below (in the case where dl=0)
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const int offset = sh - dbits;
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (dbits<=8 && offset >= 0) {
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const uint32_t mask = ((1<<dbits)-1) << offset;
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (isValidImmediate(mask) || isValidImmediate(~mask)) {
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    build_and_immediate(ireg, s.reg, mask, 32);
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    sl = offset;
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    s.reg = ireg;
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    sbits = dbits;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    maskLoBits = maskHiBits = 0;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // in the dithering case though, we need to preserve the lower bits
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const uint32_t mask = ((1<<sbits)-1) << sl;
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (isValidImmediate(mask) || isValidImmediate(~mask)) {
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                build_and_immediate(ireg, s.reg, mask, 32);
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s.reg = ireg;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                maskLoBits = maskHiBits = 0;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: we could special case (maskHiBits & !maskLoBits)
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // like we do for maskLoBits below, but it happens very rarely
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // that we have maskHiBits only and the conditions necessary to lead
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // to better code (like doing d |= s << 24)
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (maskHiBits) {
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, ireg, reg_imm(s.reg, LSL, 32-sh));
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sl += 32-sh;
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sh = 32;
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s.reg = ireg;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        maskHiBits = 0;
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //	Downsampling should be performed as follows:
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //  V * ((1<<dbits)-1) / ((1<<sbits)-1)
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //	V * [(1<<dbits)/((1<<sbits)-1)	-	1/((1<<sbits)-1)]
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //	V * [1/((1<<sbits)-1)>>dbits	-	1/((1<<sbits)-1)]
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //	V/((1<<(sbits-dbits))-(1>>dbits))	-	(V>>sbits)/((1<<sbits)-1)>>sbits
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //	V/((1<<(sbits-dbits))-(1>>dbits))	-	(V>>sbits)/(1-(1>>sbits))
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //	By approximating (1>>dbits) and (1>>sbits) to 0:
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //		V>>(sbits-dbits)	-	V>>sbits
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	//  A good approximation is V>>(sbits-dbits),
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //  but better one (needed for dithering) is:
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //		(V>>(sbits-dbits)<<sbits	-	V)>>sbits
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //		(V<<dbits	-	V)>>sbits
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //		(V	-	V>>dbits)>>(sbits-dbits)
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Dithering is done here
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (dithering) {
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("dithering");
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (sl) {
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, ireg, reg_imm(s.reg, LSR, sl));
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sh -= sl;
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sl = 0;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            s.reg = ireg;
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // scaling (V-V>>dbits)
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SUB(AL, 0, ireg, s.reg, reg_imm(s.reg, LSR, dbits));
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int shift = (GGL_DITHER_BITS - (sbits-dbits));
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (shift>0)        ADD(AL, 0, ireg, ireg, reg_imm(dither.reg, LSR, shift));
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else if (shift<0)   ADD(AL, 0, ireg, ireg, reg_imm(dither.reg, LSL,-shift));
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else                ADD(AL, 0, ireg, ireg, dither.reg);
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s.reg = ireg;
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((maskLoBits|dithering) && (sh > dbits)) {
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int shift = sh-dbits;
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (dl) {
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, ireg, reg_imm(s.reg, LSR, shift));
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ireg == d.reg) {
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                MOV(AL, 0, d.reg, reg_imm(ireg, LSL, dl));
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ORR(AL, 0, d.reg, d.reg, reg_imm(ireg, LSL, dl));
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ireg == d.reg) {
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                MOV(AL, 0, d.reg, reg_imm(s.reg, LSR, shift));
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSR, shift));
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int shift = sh-dh;
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (shift>0) {
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ireg == d.reg) {
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                MOV(AL, 0, d.reg, reg_imm(s.reg, LSR, shift));
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSR, shift));
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (shift<0) {
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ireg == d.reg) {
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                MOV(AL, 0, d.reg, reg_imm(s.reg, LSL, -shift));
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSL, -shift));
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ireg == d.reg) {
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (s.reg != d.reg) {
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    MOV(AL, 0, d.reg, s.reg);
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ORR(AL, 0, d.reg, d.reg, s.reg);
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android
395