⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gglassembler.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        }        if (mask & Z_WRITE) {            if (mask == Z_WRITE) {                // only z-write asked, cc is meaningless                ic = AL;            }            MOV(AL, 0, depth, reg_imm(z, LSR, 16));            STRH(ic, depth, zbase);        }    }}void GGLAssembler::build_iterate_z(const fragment_parts_t& parts){    const needs_t& needs = mBuilderContext.needs;    if ((mDepthTest != GGL_ALWAYS) || GGL_READ_NEEDS(P_MASK_Z, needs.p)) {        Scratch scratches(registerFile());        int dzdx = scratches.obtain();        CONTEXT_LOAD(dzdx, generated_vars.dzdx);    // stall        ADD(AL, 0, parts.z.reg, parts.z.reg, dzdx);     }}void GGLAssembler::build_iterate_f(const fragment_parts_t& parts){    const needs_t& needs = mBuilderContext.needs;    if (GGL_READ_NEEDS(P_FOG, needs.p)) {        Scratch scratches(registerFile());        int dfdx = scratches.obtain();        int f = scratches.obtain();        CONTEXT_LOAD(f,     generated_vars.f);        CONTEXT_LOAD(dfdx,  generated_vars.dfdx);   // stall        ADD(AL, 0, f, f, dfdx);        CONTEXT_STORE(f,    generated_vars.f);    }}// ---------------------------------------------------------------------------void GGLAssembler::build_logic_op(pixel_t& pixel, Scratch& regs){    const needs_t& needs = mBuilderContext.needs;    const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR;    if (opcode == GGL_COPY)        return;        comment("logic operation");    pixel_t s(pixel);    if (!(pixel.flags & CORRUPTIBLE)) {        pixel.reg = regs.obtain();        pixel.flags |= CORRUPTIBLE;    }        pixel_t d(mDstPixel);    switch(opcode) {    case GGL_CLEAR:         MOV(AL, 0, pixel.reg, imm(0));          break;    case GGL_AND:           AND(AL, 0, pixel.reg, s.reg, d.reg);    break;    case GGL_AND_REVERSE:   BIC(AL, 0, pixel.reg, s.reg, d.reg);    break;    case GGL_COPY:                                                  break;    case GGL_AND_INVERTED:  BIC(AL, 0, pixel.reg, d.reg, s.reg);    break;    case GGL_NOOP:          MOV(AL, 0, pixel.reg, d.reg);           break;    case GGL_XOR:           EOR(AL, 0, pixel.reg, s.reg, d.reg);    break;    case GGL_OR:            ORR(AL, 0, pixel.reg, s.reg, d.reg);    break;    case GGL_NOR:           ORR(AL, 0, pixel.reg, s.reg, d.reg);                            MVN(AL, 0, pixel.reg, pixel.reg);       break;    case GGL_EQUIV:         EOR(AL, 0, pixel.reg, s.reg, d.reg);                            MVN(AL, 0, pixel.reg, pixel.reg);       break;    case GGL_INVERT:        MVN(AL, 0, pixel.reg, d.reg);           break;    case GGL_OR_REVERSE:    // s | ~d == ~(~s & d)                            BIC(AL, 0, pixel.reg, d.reg, s.reg);                            MVN(AL, 0, pixel.reg, pixel.reg);       break;    case GGL_COPY_INVERTED: MVN(AL, 0, pixel.reg, s.reg);           break;    case GGL_OR_INVERTED:   // ~s | d == ~(s & ~d)                            BIC(AL, 0, pixel.reg, s.reg, d.reg);                            MVN(AL, 0, pixel.reg, pixel.reg);       break;    case GGL_NAND:          AND(AL, 0, pixel.reg, s.reg, d.reg);                            MVN(AL, 0, pixel.reg, pixel.reg);       break;    case GGL_SET:           MVN(AL, 0, pixel.reg, imm(0));          break;    };        }// ---------------------------------------------------------------------------static uint32_t find_bottom(uint32_t val){    uint32_t i = 0;    while (!(val & (3<<i)))        i+= 2;    return i;}static void normalize(uint32_t& val, uint32_t& rot){    rot = 0;    while (!(val&3)  || (val & 0xFC000000)) {        uint32_t newval;        newval = val >> 2;        newval |= (val&3) << 30;        val = newval;        rot += 2;        if (rot == 32) {            rot = 0;            break;        }    }}void GGLAssembler::build_and_immediate(int d, int s, uint32_t mask, int bits){    uint32_t rot;    uint32_t size = ((bits>=32) ? 0 : (1LU << bits)) - 1;    mask &= size;    if (mask == size) {        if (d != s)            MOV( AL, 0, d, s);        return;    }        int negative_logic = !isValidImmediate(mask);    if (negative_logic) {        mask = ~mask & size;    }    normalize(mask, rot);    if (mask) {        while (mask) {            uint32_t bitpos = find_bottom(mask);            int shift = rot + bitpos;            uint32_t m = mask & (0xff << bitpos);            mask &= ~m;            m >>= bitpos;            int32_t newMask =  (m<<shift) | (m>>(32-shift));            if (!negative_logic) {                AND( AL, 0, d, s, imm(newMask) );            } else {                BIC( AL, 0, d, s, imm(newMask) );            }            s = d;        }    } else {        MOV( AL, 0, d, imm(0));    }}		void GGLAssembler::build_masking(pixel_t& pixel, Scratch& regs){    if (!mMasking)        return;    comment("color mask");    pixel_t fb(mDstPixel);    pixel_t s(pixel);    if (!(pixel.flags & CORRUPTIBLE)) {        pixel.reg = regs.obtain();        pixel.flags |= CORRUPTIBLE;    }    int mask = 0;    for (int i=0 ; i<4 ; i++) {        const int component_mask = 1<<i;        const int h = fb.format.c[i].h;        const int l = fb.format.c[i].l;        if (h && (!(mMasking & component_mask))) {            mask |= ((1<<(h-l))-1) << l;        }    }    // There is no need to clear the masked components of the source    // (unless we applied a logic op), because they're already zeroed     // by contruction (masked components are not computed)    if (mLogicOp) {        const needs_t& needs = mBuilderContext.needs;        const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR;        if (opcode != GGL_CLEAR) {            // clear masked component of source            build_and_immediate(pixel.reg, s.reg, mask, fb.size());            s = pixel;        }    }    // clear non masked components of destination    build_and_immediate(fb.reg, fb.reg, ~mask, fb.size());     // or back the channels that were masked    if (s.reg == fb.reg) {         // this is in fact a MOV        if (s.reg == pixel.reg) {            // ugh. this in in fact a nop        } else {            MOV(AL, 0, pixel.reg, fb.reg);        }    } else {        ORR(AL, 0, pixel.reg, s.reg, fb.reg);    }}// ---------------------------------------------------------------------------void GGLAssembler::base_offset(        const pointer_t& d, const pointer_t& b, const reg_t& o){    switch (b.size) {    case 32:        ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 2));        break;    case 24:        if (d.reg == b.reg) {            ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 1));            ADD(AL, 0, d.reg, d.reg, o.reg);        } else {            ADD(AL, 0, d.reg, o.reg, reg_imm(o.reg, LSL, 1));            ADD(AL, 0, d.reg, d.reg, b.reg);        }        break;    case 16:        ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 1));        break;    case 8:        ADD(AL, 0, d.reg, b.reg, o.reg);        break;    }}// ----------------------------------------------------------------------------// cheezy register allocator...// ----------------------------------------------------------------------------void RegisterAllocator::reset(){    mRegs.reset();}int RegisterAllocator::reserveReg(int reg){    return mRegs.reserve(reg);}int RegisterAllocator::obtainReg(){    return mRegs.obtain();}void RegisterAllocator::recycleReg(int reg){    mRegs.recycle(reg);}RegisterAllocator::RegisterFile& RegisterAllocator::registerFile(){    return mRegs;}// ----------------------------------------------------------------------------RegisterAllocator::RegisterFile::RegisterFile()    : mRegs(0), mTouched(0), mStatus(0){    reserve(ARMAssemblerInterface::SP);    reserve(ARMAssemblerInterface::PC);}RegisterAllocator::RegisterFile::RegisterFile(const RegisterFile& rhs)    : mRegs(rhs.mRegs), mTouched(rhs.mTouched){}RegisterAllocator::RegisterFile::~RegisterFile(){}bool RegisterAllocator::RegisterFile::operator == (const RegisterFile& rhs) const{    return (mRegs == rhs.mRegs);}void RegisterAllocator::RegisterFile::reset(){    mRegs = mTouched = mStatus = 0;    reserve(ARMAssemblerInterface::SP);    reserve(ARMAssemblerInterface::PC);}int RegisterAllocator::RegisterFile::reserve(int reg){    LOG_ALWAYS_FATAL_IF(isUsed(reg),                        "reserving register %d, but already in use",                        reg);    mRegs |= (1<<reg);    mTouched |= mRegs;    return reg;}void RegisterAllocator::RegisterFile::reserveSeveral(uint32_t regMask){    mRegs |= regMask;    mTouched |= regMask;}int RegisterAllocator::RegisterFile::isUsed(int reg) const{    LOG_ALWAYS_FATAL_IF(reg>=16, "invalid register %d", reg);    return mRegs & (1<<reg);}int RegisterAllocator::RegisterFile::obtain(){    const char priorityList[14] = {  0,  1, 2, 3,                                     12, 14, 4, 5,                                      6,  7, 8, 9,                                    10, 11 };    const int nbreg = sizeof(priorityList);    int i, r;    for (i=0 ; i<nbreg ; i++) {        r = priorityList[i];        if (!isUsed(r)) {            break;        }    }    // this is not an error anymore because, we'll try again with    // a lower optimization level.    //LOGE_IF(i >= nbreg, "pixelflinger ran out of registers\n");    if (i >= nbreg) {        mStatus |= OUT_OF_REGISTERS;        // we return SP so we can more easily debug things        // the code will never be run anyway.        return ARMAssemblerInterface::SP;     }    reserve(r);    return r;}bool RegisterAllocator::RegisterFile::hasFreeRegs() const{    return ((mRegs & 0xFFFF) == 0xFFFF) ? false : true;}int RegisterAllocator::RegisterFile::countFreeRegs() const{    int f = ~mRegs & 0xFFFF;    // now count number of 1   f = (f & 0x5555) + ((f>>1) & 0x5555);   f = (f & 0x3333) + ((f>>2) & 0x3333);   f = (f & 0x0F0F) + ((f>>4) & 0x0F0F);   f = (f & 0x00FF) + ((f>>8) & 0x00FF);   return f;}void RegisterAllocator::RegisterFile::recycle(int reg){    LOG_FATAL_IF(!isUsed(reg),            "recycling unallocated register %d",            reg);    mRegs &= ~(1<<reg);}void RegisterAllocator::RegisterFile::recycleSeveral(uint32_t regMask){    LOG_FATAL_IF((mRegs & regMask)!=regMask,            "recycling unallocated registers "            "(recycle=%08x, allocated=%08x, unallocated=%08x)",            regMask, mRegs, mRegs&regMask);    mRegs &= ~regMask;}uint32_t RegisterAllocator::RegisterFile::touched() const{    return mTouched;}// ----------------------------------------------------------------------------}; // namespace android

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -