Path: blob/21.2-virgl/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.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_INLINES_H__23#define __NV50_IR_INLINES_H__2425static inline CondCode reverseCondCode(CondCode cc)26{27static const uint8_t ccRev[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };2829return static_cast<CondCode>(ccRev[cc & 7] | (cc & ~7));30}3132static inline CondCode inverseCondCode(CondCode cc)33{34return static_cast<CondCode>(cc ^ 7);35}3637static inline bool isMemoryFile(DataFile f)38{39return (f >= FILE_MEMORY_CONST && f <= FILE_MEMORY_LOCAL);40}4142// contrary to asTex(), this will never include SULD/SUST43static inline bool isTextureOp(operation op)44{45return (op >= OP_TEX && op <= OP_TEXPREP);46}4748static inline bool isSurfaceOp(operation op)49{50return (op >= OP_SULDB && op <= OP_SULEA) || (op == OP_SUQ);51}5253static inline unsigned int typeSizeof(DataType ty)54{55switch (ty) {56case TYPE_U8:57case TYPE_S8:58return 1;59case TYPE_F16:60case TYPE_U16:61case TYPE_S16:62return 2;63case TYPE_F32:64case TYPE_U32:65case TYPE_S32:66return 4;67case TYPE_F64:68case TYPE_U64:69case TYPE_S64:70return 8;71case TYPE_B96:72return 12;73case TYPE_B128:74return 16;75default:76return 0;77}78}7980static inline unsigned int typeSizeofLog2(DataType ty)81{82switch (ty) {83case TYPE_F16:84case TYPE_U16:85case TYPE_S16:86return 1;87case TYPE_F32:88case TYPE_U32:89case TYPE_S32:90return 2;91case TYPE_F64:92case TYPE_U64:93case TYPE_S64:94return 3;95case TYPE_B96:96case TYPE_B128:97return 4;98case TYPE_U8:99case TYPE_S8:100default:101return 0;102}103}104105static inline DataType typeOfSize(unsigned int size,106bool flt = false, bool sgn = false)107{108switch (size) {109case 1: return sgn ? TYPE_S8 : TYPE_U8;110case 2: return flt ? TYPE_F16 : (sgn ? TYPE_S16 : TYPE_U16);111case 8: return flt ? TYPE_F64 : (sgn ? TYPE_S64 : TYPE_U64);112case 12: return TYPE_B96;113case 16: return TYPE_B128;114case 4:115return flt ? TYPE_F32 : (sgn ? TYPE_S32 : TYPE_U32);116default:117return TYPE_NONE;118}119}120121static inline bool isFloatType(DataType ty)122{123return (ty >= TYPE_F16 && ty <= TYPE_F64);124}125126static inline bool isSignedIntType(DataType ty)127{128return (ty == TYPE_S8 || ty == TYPE_S16 || ty == TYPE_S32 || ty == TYPE_S64);129}130131static inline bool isSignedType(DataType ty)132{133switch (ty) {134case TYPE_NONE:135case TYPE_U8:136case TYPE_U16:137case TYPE_U32:138case TYPE_U64:139case TYPE_B96:140case TYPE_B128:141return false;142default:143return true;144}145}146147static inline DataType intTypeToSigned(DataType ty)148{149switch (ty) {150case TYPE_U64: return TYPE_S64;151case TYPE_U32: return TYPE_S32;152case TYPE_U16: return TYPE_S16;153case TYPE_U8: return TYPE_S8;154default:155return ty;156}157}158159const ValueRef *ValueRef::getIndirect(int dim) const160{161return isIndirect(dim) ? &insn->src(indirect[dim]) : NULL;162}163164DataFile ValueRef::getFile() const165{166return value ? value->reg.file : FILE_NULL;167}168169unsigned int ValueRef::getSize() const170{171return value ? value->reg.size : 0;172}173174Value *ValueRef::rep() const175{176assert(value);177return value->join;178}179180Value *ValueDef::rep() const181{182assert(value);183return value->join;184}185186DataFile ValueDef::getFile() const187{188return value ? value->reg.file : FILE_NULL;189}190191unsigned int ValueDef::getSize() const192{193return value ? value->reg.size : 0;194}195196void ValueDef::setSSA(LValue *lval)197{198origin = value->asLValue();199set(lval);200}201202const LValue *ValueDef::preSSA() const203{204return origin;205}206207Instruction *Value::getInsn() const208{209return defs.empty() ? NULL : defs.front()->getInsn();210}211212Instruction *Value::getUniqueInsn() const213{214if (defs.empty())215return NULL;216217// after regalloc, the definitions of coalesced values are linked218if (join != this) {219for (DefCIterator it = defs.begin(); it != defs.end(); ++it)220if ((*it)->get() == this)221return (*it)->getInsn();222// should be unreachable and trigger assertion at the end223}224#ifndef NDEBUG225if (reg.data.id < 0) {226int n = 0;227for (DefCIterator it = defs.begin(); n < 2 && it != defs.end(); ++it)228if ((*it)->get() == this) // don't count joined values229++n;230if (n > 1)231WARN("value %%%i not uniquely defined\n", id); // return NULL ?232}233#endif234assert(defs.front()->get() == this);235return defs.front()->getInsn();236}237238inline bool Instruction::constrainedDefs() const239{240return defExists(1) || op == OP_UNION;241}242243Value *Instruction::getIndirect(int s, int dim) const244{245return srcs[s].isIndirect(dim) ? getSrc(srcs[s].indirect[dim]) : NULL;246}247248Value *Instruction::getPredicate() const249{250return (predSrc >= 0) ? getSrc(predSrc) : NULL;251}252253void Instruction::setFlagsDef(int d, Value *val)254{255if (val) {256if (flagsDef < 0)257flagsDef = d;258setDef(flagsDef, val);259} else {260if (flagsDef >= 0) {261setDef(flagsDef, NULL);262flagsDef = -1;263}264}265}266267void Instruction::setFlagsSrc(int s, Value *val)268{269flagsSrc = s;270setSrc(flagsSrc, val);271}272273Value *TexInstruction::getIndirectR() const274{275return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;276}277278Value *TexInstruction::getIndirectS() const279{280return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;281}282283CmpInstruction *Instruction::asCmp()284{285if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)286return static_cast<CmpInstruction *>(this);287return NULL;288}289290const CmpInstruction *Instruction::asCmp() const291{292if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)293return static_cast<const CmpInstruction *>(this);294return NULL;295}296297FlowInstruction *Instruction::asFlow()298{299if (op >= OP_BRA && op <= OP_JOIN)300return static_cast<FlowInstruction *>(this);301return NULL;302}303304const FlowInstruction *Instruction::asFlow() const305{306if (op >= OP_BRA && op <= OP_JOIN)307return static_cast<const FlowInstruction *>(this);308return NULL;309}310311TexInstruction *Instruction::asTex()312{313if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)314return static_cast<TexInstruction *>(this);315return NULL;316}317318const TexInstruction *Instruction::asTex() const319{320if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)321return static_cast<const TexInstruction *>(this);322return NULL;323}324325static inline Instruction *cloneForward(Function *ctx, Instruction *obj)326{327DeepClonePolicy<Function> pol(ctx);328329for (int i = 0; obj->srcExists(i); ++i)330pol.set(obj->getSrc(i), obj->getSrc(i));331332return obj->clone(pol);333}334335// XXX: use a virtual function so we're really really safe ?336LValue *Value::asLValue()337{338if (reg.file >= FILE_GPR && reg.file <= LAST_REGISTER_FILE)339return static_cast<LValue *>(this);340return NULL;341}342343Symbol *Value::asSym()344{345if (reg.file >= FILE_MEMORY_CONST)346return static_cast<Symbol *>(this);347return NULL;348}349350const Symbol *Value::asSym() const351{352if (reg.file >= FILE_MEMORY_CONST)353return static_cast<const Symbol *>(this);354return NULL;355}356357void Symbol::setOffset(int32_t offset)358{359reg.data.offset = offset;360}361362void Symbol::setAddress(Symbol *base, int32_t offset)363{364baseSym = base;365reg.data.offset = offset;366}367368void Symbol::setSV(SVSemantic sv, uint32_t index)369{370reg.data.sv.sv = sv;371reg.data.sv.index = index;372}373374ImmediateValue *Value::asImm()375{376if (reg.file == FILE_IMMEDIATE)377return static_cast<ImmediateValue *>(this);378return NULL;379}380381const ImmediateValue *Value::asImm() const382{383if (reg.file == FILE_IMMEDIATE)384return static_cast<const ImmediateValue *>(this);385return NULL;386}387388Value *Value::get(Iterator &it)389{390return reinterpret_cast<Value *>(it.get());391}392393bool BasicBlock::reachableBy(const BasicBlock *by, const BasicBlock *term)394{395return cfg.reachableBy(&by->cfg, &term->cfg);396}397398BasicBlock *BasicBlock::get(Iterator &iter)399{400return reinterpret_cast<BasicBlock *>(iter.get());401}402403BasicBlock *BasicBlock::get(Graph::Node *node)404{405assert(node);406return reinterpret_cast<BasicBlock *>(node->data);407}408409Function *Function::get(Graph::Node *node)410{411assert(node);412return reinterpret_cast<Function *>(node->data);413}414415LValue *Function::getLValue(int id)416{417assert((unsigned int)id < (unsigned int)allLValues.getSize());418return reinterpret_cast<LValue *>(allLValues.get(id));419}420421#endif // __NV50_IR_INLINES_H__422423424