/* libs/pixelflinger/codeflinger/load_store.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#include <assert.h>
#include <stdio.h>
#include <cutils/log.h>
#include "GGLAssembler.h"

#ifdef __ARM_ARCH__
#include <machine/cpu-features.h>
#endif

namespace android {

// ----------------------------------------------------------------------------

void GGLAssembler::store(const pointer_t& addr, const pixel_t& s, uint32_t flags)
{    
    const int bits = addr.size;
    const int inc = (flags & WRITE_BACK)?1:0;
    switch (bits) {
    case 32:
        if (inc)    STR(AL, s.reg, addr.reg, immed12_post(4));
        else        STR(AL, s.reg, addr.reg);
        break;
    case 24:
        // 24 bits formats are a little special and used only for RGB
        // 0x00BBGGRR is unpacked as R,G,B
        STRB(AL, s.reg, addr.reg, immed12_pre(0));
        MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8));
        STRB(AL, s.reg, addr.reg, immed12_pre(1));
        MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8));
        STRB(AL, s.reg, addr.reg, immed12_pre(2));
        if (!(s.flags & CORRUPTIBLE)) {
            MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 16));
        }
        if (inc)
            ADD(AL, 0, addr.reg, addr.reg, imm(3));
        break;
    case 16:
        if (inc)    STRH(AL, s.reg, addr.reg, immed8_post(2));
        else        STRH(AL, s.reg, addr.reg);
        break;
    case  8:
        if (inc)    STRB(AL, s.reg, addr.reg, immed12_post(1));
        else        STRB(AL, s.reg, addr.reg);
        break;
    }
}

void GGLAssembler::load(const pointer_t& addr, const pixel_t& s, uint32_t flags)
{    
    Scratch scratches(registerFile());    
    int s0;

    const int bits = addr.size;
    const int inc = (flags & WRITE_BACK)?1:0;
    switch (bits) {
    case 32:
        if (inc)    LDR(AL, s.reg, addr.reg, immed12_post(4));
        else        LDR(AL, s.reg, addr.reg);
        break;
    case 24:
        // 24 bits formats are a little special and used only for RGB
        // R,G,B is packed as 0x00BBGGRR 
        s0 = scratches.obtain();
        if (s.reg != addr.reg) {
            LDRB(AL, s.reg, addr.reg, immed12_pre(0));      // R
            LDRB(AL, s0, addr.reg, immed12_pre(1));         // G
            ORR(AL, 0, s.reg, s.reg, reg_imm(s0, LSL, 8));
            LDRB(AL, s0, addr.reg, immed12_pre(2));         // B
            ORR(AL, 0, s.reg, s.reg, reg_imm(s0, LSL, 16));
        } else {
            int s1 = scratches.obtain();
            LDRB(AL, s1, addr.reg, immed12_pre(0));         // R
            LDRB(AL, s0, addr.reg, immed12_pre(1));         // G
            ORR(AL, 0, s1, s1, reg_imm(s0, LSL, 8));
            LDRB(AL, s0, addr.reg, immed12_pre(2));         // B
            ORR(AL, 0, s.reg, s1, reg_imm(s0, LSL, 16));
        }
        if (inc)
            ADD(AL, 0, addr.reg, addr.reg, imm(3));
        break;        
    case 16:
        if (inc)    LDRH(AL, s.reg, addr.reg, immed8_post(2));
        else        LDRH(AL, s.reg, addr.reg);
        break;
    case  8:
        if (inc)    LDRB(AL, s.reg, addr.reg, immed12_post(1));
        else        LDRB(AL, s.reg, addr.reg);
        break;
    }
}

void GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits)
{
    const int maskLen = h-l;

#ifdef __mips__
    assert(maskLen<=11);
#else
    assert(maskLen<=8);
#endif
    assert(h);
    
#if __ARM_ARCH__ >= 7
    const int mask = (1<<maskLen)-1;
    if ((h == bits) && !l && (s != d.reg)) {
        MOV(AL, 0, d.reg, s);                   // component = packed;
    } else if ((h == bits) && l) {
        MOV(AL, 0, d.reg, reg_imm(s, LSR, l));  // component = packed >> l;
    } else if (!l && isValidImmediate(mask)) {
        AND(AL, 0, d.reg, s, imm(mask));        // component = packed & mask;
    } else if (!l && isValidImmediate(~mask)) {
        BIC(AL, 0, d.reg, s, imm(~mask));       // component = packed & mask;
    } else {
        UBFX(AL, d.reg, s, l, maskLen);         // component = (packed & mask) >> l;
    }
#else
    if (h != bits) {
        const int mask = ((1<<maskLen)-1) << l;
        if (isValidImmediate(mask)) {
            AND(AL, 0, d.reg, s, imm(mask));    // component = packed & mask;
        } else if (isValidImmediate(~mask)) {
            BIC(AL, 0, d.reg, s, imm(~mask));   // component = packed & mask;
        } else {
            MOV(AL, 0, d.reg, reg_imm(s, LSL, 32-h));
            l += 32-h;
            h = 32;
        }
        s = d.reg;
    }
    
    if (l) {
        MOV(AL, 0, d.reg, reg_imm(s, LSR, l));  // component = packed >> l;
        s = d.reg;
    }
    
    if (s != d.reg) {
        MOV(AL, 0, d.reg, s);
    }
#endif

    d.s = maskLen;
}

void GGLAssembler::extract(integer_t& d, const pixel_t& s, int component)
{
    extract(d,  s.reg,
                s.format.c[component].h,
                s.format.c[component].l,
                s.size());
}

void GGLAssembler::extract(component_t& d, const pixel_t& s, int component)
{
    integer_t r(d.reg, 32, d.flags);
    extract(r,  s.reg,
                s.format.c[component].h,
                s.format.c[component].l,
                s.size());
    d = component_t(r);
}


void GGLAssembler::expand(integer_t& d, const component_t& s, int dbits)
{
    if (s.l || (s.flags & CLEAR_HI)) {
        extract(d, s.reg, s.h, s.l, 32);
        expand(d, d, dbits);
    } else {
        expand(d, integer_t(s.reg, s.size(), s.flags), dbits);
    }
}

void GGLAssembler::expand(component_t& d, const component_t& s, int dbits)
{
    integer_t r(d.reg, 32, d.flags);
    expand(r, s, dbits);
    d = component_t(r);
}

void GGLAssembler::expand(integer_t& dst, const integer_t& src, int dbits)
{
    assert(src.size());

    int sbits = src.size();
    int s = src.reg;
    int d = dst.reg;

    // be sure to set 'dst' after we read 'src' as they may be identical
    dst.s = dbits;
    dst.flags = 0;

    if (dbits<=sbits) {
        if (s != d) {
            MOV(AL, 0, d, s);
        }
        return;
    }

    if (sbits == 1) {
        RSB(AL, 0, d, s, reg_imm(s, LSL, dbits));
            // d = (s<<dbits) - s;
        return;
    }

    if (dbits % sbits) {
        MOV(AL, 0, d, reg_imm(s, LSL, dbits-sbits));
            // d = s << (dbits-sbits);
        dbits -= sbits;
        do {
            ORR(AL, 0, d, d, reg_imm(d, LSR, sbits));
                // d |= d >> sbits;
            dbits -= sbits;
            sbits *= 2;
        } while(dbits>0);
        return;
    }
    
    dbits -= sbits;
    do {
        ORR(AL, 0, d, s, reg_imm(s, LSL, sbits));
            // d |= d<<sbits;
        s = d;        
        dbits -= sbits;
        if (sbits*2 < dbits) {
            sbits *= 2;
        }
    } while(dbits>0);
}

void GGLAssembler::downshift(
        pixel_t& d, int component, component_t s, const reg_t& dither)
{
    const needs_t& needs = mBuilderContext.needs;
    Scratch scratches(registerFile());

    int sh = s.h;
    int sl = s.l;
    int maskHiBits = (sh!=32) ? ((s.flags & CLEAR_HI)?1:0) : 0;
    int maskLoBits = (sl!=0)  ? ((s.flags & CLEAR_LO)?1:0) : 0;
    int sbits = sh - sl;

    int dh = d.format.c[component].h;
    int dl = d.format.c[component].l;
    int dbits = dh - dl;
    int dithering = 0;
    
    ALOGE_IF(sbits<dbits, "sbits (%d) < dbits (%d) in downshift", sbits, dbits);

    if (sbits>dbits) {
        // see if we need to dither
        dithering = mDithering;
    }
    
    int ireg = d.reg;
    if (!(d.flags & FIRST)) {
        if (s.flags & CORRUPTIBLE)  {
            ireg = s.reg;
        } else {
            ireg = scratches.obtain();
        }
    }
    d.flags &= ~FIRST;

    if (maskHiBits) {
        // we need to mask the high bits (and possibly the lowbits too)
        // and we might be able to use immediate mask.
        if (!dithering) {
            // we don't do this if we only have maskLoBits because we can
            // do it more efficiently below (in the case where dl=0)
            const int offset = sh - dbits;
            if (dbits<=8 && offset >= 0) {
                const uint32_t mask = ((1<<dbits)-1) << offset;
                if (isValidImmediate(mask) || isValidImmediate(~mask)) {
                    build_and_immediate(ireg, s.reg, mask, 32);
                    sl = offset;
                    s.reg = ireg; 
                    sbits = dbits;
                    maskLoBits = maskHiBits = 0;
                }
            }
        } else {
            // in the dithering case though, we need to preserve the lower bits
            const uint32_t mask = ((1<<sbits)-1) << sl;
            if (isValidImmediate(mask) || isValidImmediate(~mask)) {
                build_and_immediate(ireg, s.reg, mask, 32);
                s.reg = ireg; 
                maskLoBits = maskHiBits = 0;
            }
        }
    }

    // XXX: we could special case (maskHiBits & !maskLoBits)
    // like we do for maskLoBits below, but it happens very rarely
    // that we have maskHiBits only and the conditions necessary to lead
    // to better code (like doing d |= s << 24)

    if (maskHiBits) {
        MOV(AL, 0, ireg, reg_imm(s.reg, LSL, 32-sh));
        sl += 32-sh;
        sh = 32;
        s.reg = ireg;
        maskHiBits = 0;
    }

    //	Downsampling should be performed as follows:
    //  V * ((1<<dbits)-1) / ((1<<sbits)-1)
    //	V * [(1<<dbits)/((1<<sbits)-1)	-	1/((1<<sbits)-1)]
    //	V * [1/((1<<sbits)-1)>>dbits	-	1/((1<<sbits)-1)]
    //	V/((1<<(sbits-dbits))-(1>>dbits))	-	(V>>sbits)/((1<<sbits)-1)>>sbits
    //	V/((1<<(sbits-dbits))-(1>>dbits))	-	(V>>sbits)/(1-(1>>sbits))
    //
    //	By approximating (1>>dbits) and (1>>sbits) to 0:
    //
    //		V>>(sbits-dbits)	-	V>>sbits
    //
	//  A good approximation is V>>(sbits-dbits),
    //  but better one (needed for dithering) is:
    //
    //		(V>>(sbits-dbits)<<sbits	-	V)>>sbits
    //		(V<<dbits	-	V)>>sbits
    //		(V	-	V>>dbits)>>(sbits-dbits)

    // Dithering is done here
    if (dithering) {
        comment("dithering");
        if (sl) {
            MOV(AL, 0, ireg, reg_imm(s.reg, LSR, sl));
            sh -= sl;
            sl = 0;
            s.reg = ireg; 
        }
        // scaling (V-V>>dbits)
        SUB(AL, 0, ireg, s.reg, reg_imm(s.reg, LSR, dbits));
        const int shift = (GGL_DITHER_BITS - (sbits-dbits));
        if (shift>0)        ADD(AL, 0, ireg, ireg, reg_imm(dither.reg, LSR, shift));
        else if (shift<0)   ADD(AL, 0, ireg, ireg, reg_imm(dither.reg, LSL,-shift));
        else                ADD(AL, 0, ireg, ireg, dither.reg);
        s.reg = ireg; 
    }

    if ((maskLoBits|dithering) && (sh > dbits)) {
        int shift = sh-dbits;
        if (dl) {
            MOV(AL, 0, ireg, reg_imm(s.reg, LSR, shift));
            if (ireg == d.reg) {
                MOV(AL, 0, d.reg, reg_imm(ireg, LSL, dl));
            } else {
                ORR(AL, 0, d.reg, d.reg, reg_imm(ireg, LSL, dl));
            }
        } else {
            if (ireg == d.reg) {
                MOV(AL, 0, d.reg, reg_imm(s.reg, LSR, shift));
            } else {
                ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSR, shift));
            }
        }
    } else {
        int shift = sh-dh;
        if (shift>0) {
            if (ireg == d.reg) {
                MOV(AL, 0, d.reg, reg_imm(s.reg, LSR, shift));
            } else {
                ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSR, shift));
            }
        } else if (shift<0) {
            if (ireg == d.reg) {
                MOV(AL, 0, d.reg, reg_imm(s.reg, LSL, -shift));
            } else {
                ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSL, -shift));
            }
        } else {
            if (ireg == d.reg) {
                if (s.reg != d.reg) {
                    MOV(AL, 0, d.reg, s.reg);
                }
            } else {
                ORR(AL, 0, d.reg, d.reg, s.reg);
            }
        }
    }
}

}; // namespace android
