Path: blob/21.2-virgl/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h
4574 views
/*1* Copyright 2011 Christoph Bumiller2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*/2122#ifndef __NV50_IR_BUILD_UTIL__23#define __NV50_IR_BUILD_UTIL__2425namespace nv50_ir {2627class BuildUtil28{29public:30BuildUtil();31BuildUtil(Program *);3233inline void setProgram(Program *);34inline Program *getProgram() const { return prog; }35inline Function *getFunction() const { return func; }3637// keeps inserting at head/tail of block38inline void setPosition(BasicBlock *, bool tail);39// position advances only if @after is true40inline void setPosition(Instruction *, bool after);4142inline BasicBlock *getBB() { return bb; }4344inline void insert(Instruction *);45inline void remove(Instruction *i) { assert(i->bb == bb); bb->remove(i); }4647inline LValue *getScratch(int size = 4, DataFile = FILE_GPR);48// scratch value for a single assignment:49inline LValue *getSSA(int size = 4, DataFile = FILE_GPR);5051inline Instruction *mkOp(operation, DataType, Value *);52Instruction *mkOp1(operation, DataType, Value *, Value *);53Instruction *mkOp2(operation, DataType, Value *, Value *, Value *);54Instruction *mkOp3(operation, DataType, Value *, Value *, Value *, Value *);5556LValue *mkOp1v(operation, DataType, Value *, Value *);57LValue *mkOp2v(operation, DataType, Value *, Value *, Value *);58LValue *mkOp3v(operation, DataType, Value *, Value *, Value *, Value *);5960Instruction *mkLoad(DataType, Value *dst, Symbol *, Value *ptr);61Instruction *mkStore(operation, DataType, Symbol *, Value *ptr, Value *val);6263LValue *mkLoadv(DataType, Symbol *, Value *ptr);6465Instruction *mkMov(Value *, Value *, DataType = TYPE_U32);66Instruction *mkMovToReg(int id, Value *);67Instruction *mkMovFromReg(Value *, int id);68inline Instruction *mkBMov(Value *, Value *);6970Instruction *mkInterp(unsigned mode, Value *, int32_t offset, Value *rel);71Instruction *mkFetch(Value *, DataType, DataFile, int32_t offset,72Value *attrRel, Value *primRel);7374Instruction *mkCvt(operation, DataType, Value *, DataType, Value *);75CmpInstruction *mkCmp(operation, CondCode, DataType,76Value *,77DataType, Value *, Value *, Value * = NULL);78TexInstruction *mkTex(operation, TexTarget,79uint16_t tic, uint16_t tsc,80const std::vector<Value *> &def,81const std::vector<Value *> &src);82Instruction *mkQuadop(uint8_t qop, Value *, uint8_t l, Value *, Value *);8384FlowInstruction *mkFlow(operation, void *target, CondCode, Value *pred);8586Instruction *mkSelect(Value *pred, Value *dst, Value *trSrc, Value *flSrc);8788Instruction *mkSplit(Value *half[2], uint8_t halfSize, Value *);8990void mkClobber(DataFile file, uint32_t regMask, int regUnitLog2);9192ImmediateValue *mkImm(float);93ImmediateValue *mkImm(double);94ImmediateValue *mkImm(uint16_t);95ImmediateValue *mkImm(uint32_t);96ImmediateValue *mkImm(uint64_t);9798ImmediateValue *mkImm(int i) { return mkImm((uint32_t)i); }99100Value *loadImm(Value *dst, float);101Value *loadImm(Value *dst, double);102Value *loadImm(Value *dst, uint16_t);103Value *loadImm(Value *dst, uint32_t);104Value *loadImm(Value *dst, uint64_t);105106Value *loadImm(Value *dst, int i) { return loadImm(dst, (uint32_t)i); }107108// returns high part of the operation109static Instruction *split64BitOpPostRA(Function *, Instruction *,110Value *zero, Value *carry);111112struct Location113{114Location(unsigned array, unsigned arrayIdx, unsigned i, unsigned c)115: array(array), arrayIdx(arrayIdx), i(i), c(c) { }116Location(const Location &l)117: array(l.array), arrayIdx(l.arrayIdx), i(l.i), c(l.c) { }118119bool operator==(const Location &l) const120{121return122array == l.array && arrayIdx == l.arrayIdx && i == l.i && c == l.c;123}124125bool operator<(const Location &l) const126{127return array != l.array ? array < l.array :128arrayIdx != l.arrayIdx ? arrayIdx < l.arrayIdx :129i != l.i ? i < l.i :130c != l.c ? c < l.c :131false;132}133134unsigned array, arrayIdx, i, c;135};136137typedef bimap<Location, Value *> ValueMap;138139class DataArray140{141public:142DataArray(BuildUtil *bld) : up(bld), array(0), arrayIdx(0), baseAddr(0),143arrayLen(0), baseSym(NULL), vecDim(0), eltSize(0), file(FILE_NULL),144regOnly(false) { }145146void setup(unsigned array, unsigned arrayIdx,147uint32_t base, int len, int vecDim, int eltSize,148DataFile file, int8_t fileIdx);149150inline bool exists(ValueMap&, unsigned int i, unsigned int c);151152Value *load(ValueMap&, int i, int c, Value *ptr);153void store(ValueMap&, int i, int c, Value *ptr, Value *value);154Value *acquire(ValueMap&, int i, int c);155156private:157inline Value *lookup(ValueMap&, unsigned i, unsigned c);158inline Value *insert(ValueMap&, unsigned i, unsigned c, Value *v);159160Symbol *mkSymbol(int i, int c);161162private:163BuildUtil *up;164unsigned array, arrayIdx;165166uint32_t baseAddr;167uint32_t arrayLen;168Symbol *baseSym;169170uint8_t vecDim;171uint8_t eltSize; // in bytes172173DataFile file;174bool regOnly;175};176177Symbol *mkSymbol(DataFile file, int8_t fileIndex,178DataType ty, uint32_t baseAddress);179180Symbol *mkSysVal(SVSemantic svName, uint32_t svIndex);181Symbol *mkTSVal(TSSemantic tsName);182183private:184void init(Program *);185void addImmediate(ImmediateValue *);186inline unsigned int u32Hash(uint32_t);187188protected:189Program *prog;190Function *func;191Instruction *pos;192BasicBlock *bb;193bool tail;194195#define NV50_IR_BUILD_IMM_HT_SIZE 256196197ImmediateValue *imms[NV50_IR_BUILD_IMM_HT_SIZE];198unsigned int immCount;199};200201unsigned int BuildUtil::u32Hash(uint32_t u)202{203return (u % 273) % NV50_IR_BUILD_IMM_HT_SIZE;204}205206void BuildUtil::setProgram(Program *program)207{208prog = program;209}210211void212BuildUtil::setPosition(BasicBlock *block, bool atTail)213{214bb = block;215prog = bb->getProgram();216func = bb->getFunction();217pos = NULL;218tail = atTail;219}220221void222BuildUtil::setPosition(Instruction *i, bool after)223{224bb = i->bb;225prog = bb->getProgram();226func = bb->getFunction();227pos = i;228tail = after;229assert(bb);230}231232LValue *233BuildUtil::getScratch(int size, DataFile f)234{235LValue *lval = new_LValue(func, f);236lval->reg.size = size;237return lval;238}239240LValue *241BuildUtil::getSSA(int size, DataFile f)242{243LValue *lval = new_LValue(func, f);244lval->ssa = 1;245lval->reg.size = size;246return lval;247}248249void BuildUtil::insert(Instruction *i)250{251if (!pos) {252tail ? bb->insertTail(i) : bb->insertHead(i);253} else {254if (tail) {255bb->insertAfter(pos, i);256pos = i;257} else {258bb->insertBefore(pos, i);259}260}261}262263Instruction *264BuildUtil::mkOp(operation op, DataType ty, Value *dst)265{266Instruction *insn = new_Instruction(func, op, ty);267insn->setDef(0, dst);268insert(insn);269if (op == OP_DISCARD || op == OP_EXIT ||270op == OP_JOIN ||271op == OP_QUADON || op == OP_QUADPOP ||272op == OP_EMIT || op == OP_RESTART)273insn->fixed = 1;274return insn;275}276277inline LValue *278BuildUtil::mkOp1v(operation op, DataType ty, Value *dst, Value *src)279{280mkOp1(op, ty, dst, src);281return dst->asLValue();282}283284inline LValue *285BuildUtil::mkOp2v(operation op, DataType ty, Value *dst,286Value *src0, Value *src1)287{288mkOp2(op, ty, dst, src0, src1);289return dst->asLValue();290}291292inline LValue *293BuildUtil::mkOp3v(operation op, DataType ty, Value *dst,294Value *src0, Value *src1, Value *src2)295{296mkOp3(op, ty, dst, src0, src1, src2);297return dst->asLValue();298}299300inline LValue *301BuildUtil::mkLoadv(DataType ty, Symbol *mem, Value *ptr)302{303LValue *dst = getScratch(typeSizeof(ty));304mkLoad(ty, dst, mem, ptr);305return dst;306}307308inline Instruction *309BuildUtil::mkBMov(Value *dst, Value *src)310{311return mkCvt(OP_CVT, TYPE_U32, dst, TYPE_U32, src);312}313314bool315BuildUtil::DataArray::exists(ValueMap &m, unsigned int i, unsigned int c)316{317assert(i < arrayLen && c < vecDim);318return !regOnly || m.r.count(Location(array, arrayIdx, i, c));319}320321Value *322BuildUtil::DataArray::lookup(ValueMap &m, unsigned i, unsigned c)323{324ValueMap::r_iterator it = m.r.find(Location(array, arrayIdx, i, c));325return it != m.r.end() ? it->second : NULL;326}327328Value *329BuildUtil::DataArray::insert(ValueMap &m, unsigned i, unsigned c, Value *v)330{331m.insert(Location(array, arrayIdx, i, c), v);332return v;333}334335} // namespace nv50_ir336337#endif // __NV50_IR_BUILD_UTIL_H__338339340