📄 gglassembler.h
字号:
/* libs/pixelflinger/codeflinger/GGLAssembler.h**** 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.*/#ifndef ANDROID_GGLASSEMBLER_H#define ANDROID_GGLASSEMBLER_H#include <stdint.h>#include <sys/types.h>#include <private/pixelflinger/ggl_context.h>#include "codeflinger/ARMAssemblerProxy.h"namespace android {// ----------------------------------------------------------------------------#define CONTEXT_LOAD(REG, FIELD) \ LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))#define CONTEXT_STORE(REG, FIELD) \ STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))class RegisterAllocator{public: class RegisterFile; RegisterFile& registerFile(); int reserveReg(int reg); int obtainReg(); void recycleReg(int reg); void reset(); class RegisterFile { public: RegisterFile(); RegisterFile(const RegisterFile& rhs); ~RegisterFile(); void reset(); bool operator == (const RegisterFile& rhs) const; bool operator != (const RegisterFile& rhs) const { return !operator == (rhs); } int reserve(int reg); void reserveSeveral(uint32_t regMask); void recycle(int reg); void recycleSeveral(uint32_t regMask); int obtain(); inline int isUsed(int reg) const; bool hasFreeRegs() const; int countFreeRegs() const; uint32_t touched() const; inline uint32_t status() const { return mStatus; } enum { OUT_OF_REGISTERS = 0x1 }; private: uint32_t mRegs; uint32_t mTouched; uint32_t mStatus; }; class Scratch { public: Scratch(RegisterFile& regFile) : mRegFile(regFile), mScratch(0) { } ~Scratch() { mRegFile.recycleSeveral(mScratch); } int obtain() { int reg = mRegFile.obtain(); mScratch |= 1<<reg; return reg; } void recycle(int reg) { mRegFile.recycle(reg); mScratch &= ~(1<<reg); } bool isUsed(int reg) { return (mScratch & (1<<reg)); } int countFreeRegs() { return mRegFile.countFreeRegs(); } private: RegisterFile& mRegFile; uint32_t mScratch; }; class Spill { public: Spill(RegisterFile& regFile, ARMAssemblerInterface& gen, uint32_t reglist) : mRegFile(regFile), mGen(gen), mRegList(reglist), mCount(0) { if (reglist) { int count = 0; while (reglist) { count++; reglist &= ~(1 << (31 - __builtin_clz(reglist))); } if (count == 1) { int reg = 31 - __builtin_clz(mRegList); mGen.STR(mGen.AL, reg, mGen.SP, mGen.immed12_pre(-4, 1)); } else { mGen.STM(mGen.AL, mGen.DB, mGen.SP, 1, mRegList); } mRegFile.recycleSeveral(mRegList); mCount = count; } } ~Spill() { if (mRegList) { if (mCount == 1) { int reg = 31 - __builtin_clz(mRegList); mGen.LDR(mGen.AL, reg, mGen.SP, mGen.immed12_post(4)); } else { mGen.LDM(mGen.AL, mGen.IA, mGen.SP, 1, mRegList); } mRegFile.reserveSeveral(mRegList); } } private: RegisterFile& mRegFile; ARMAssemblerInterface& mGen; uint32_t mRegList; int mCount; }; private: RegisterFile mRegs;};// ----------------------------------------------------------------------------class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator{public: GGLAssembler(ARMAssemblerInterface* target); virtual ~GGLAssembler(); uint32_t* base() const { return 0; } // XXX uint32_t* pc() const { return 0; } // XXX void reset(int opt_level); virtual void prolog(); virtual void epilog(uint32_t touched); // generate scanline code for given needs int scanline(const needs_t& needs, context_t const* c); int scanline_core(const needs_t& needs, context_t const* c); enum { CLEAR_LO = 0x0001, CLEAR_HI = 0x0002, CORRUPTIBLE = 0x0004, FIRST = 0x0008 }; enum { //load/store flags WRITE_BACK = 0x0001 }; struct reg_t { reg_t() : reg(-1), flags(0) { } reg_t(int r, int f=0) : reg(r), flags(f) { } void setTo(int r, int f=0) { reg=r; flags=f; } int reg; uint16_t flags; }; struct integer_t : public reg_t { integer_t() : reg_t(), s(0) { } integer_t(int r, int sz=32, int f=0) : reg_t(r, f), s(sz) { } void setTo(int r, int sz=32, int f=0) { reg_t::setTo(r, f); s=sz; } int8_t s; inline int size() const { return s; } }; struct pixel_t : public reg_t { pixel_t() : reg_t() { memset(&format, 0, sizeof(GGLFormat)); } pixel_t(int r, const GGLFormat* fmt, int f=0) : reg_t(r, f), format(*fmt) { } void setTo(int r, const GGLFormat* fmt, int f=0) { reg_t::setTo(r, f); format = *fmt; } GGLFormat format; inline int hi(int c) const { return format.c[c].h; } inline int low(int c) const { return format.c[c].l; } inline int mask(int c) const { return ((1<<size(c))-1) << low(c); } inline int size() const { return format.size*8; } inline int size(int c) const { return component_size(c); } inline int component_size(int c) const { return hi(c) - low(c); } }; struct component_t : public reg_t { component_t() : reg_t(), h(0), l(0) { } component_t(int r, int f=0) : reg_t(r, f), h(0), l(0) { } component_t(int r, int lo, int hi, int f=0) : reg_t(r, f), h(hi), l(lo) { } explicit component_t(const integer_t& rhs) : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) { } explicit component_t(const pixel_t& rhs, int component) { setTo( rhs.reg, rhs.format.c[component].l, rhs.format.c[component].h, rhs.flags|CLEAR_LO|CLEAR_HI); } void setTo(int r, int lo=0, int hi=0, int f=0) { reg_t::setTo(r, f); h=hi; l=lo; } int8_t h; int8_t l; inline int size() const { return h-l; } }; struct pointer_t : public reg_t { pointer_t() : reg_t(), size(0) { } pointer_t(int r, int s, int f=0) : reg_t(r, f), size(s) { } void setTo(int r, int s, int f=0) { reg_t::setTo(r, f); size=s; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -