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