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