Path: blob/21.2-virgl/src/gallium/drivers/nouveau/codegen/nv50_ir_target.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_TARGET_H__23#define __NV50_IR_TARGET_H__2425#include "codegen/nv50_ir.h"2627namespace nv50_ir {2829struct RelocInfo;3031struct RelocEntry32{33enum Type34{35TYPE_CODE,36TYPE_BUILTIN,37TYPE_DATA38};3940uint32_t data;41uint32_t mask;42uint32_t offset;43int8_t bitPos;44Type type;4546inline void apply(uint32_t *binary, const RelocInfo *info) const;47};4849struct RelocInfo50{51uint32_t codePos;52uint32_t libPos;53uint32_t dataPos;5455uint32_t count;5657RelocEntry entry[0];58};5960struct FixupData {61FixupData(bool force, bool flat, uint8_t alphatest, bool msaa) :62force_persample_interp(force), flatshade(flat), alphatest(alphatest), msaa(msaa) {}63bool force_persample_interp;64bool flatshade;65uint8_t alphatest;66bool msaa;67};6869struct FixupEntry;70typedef void (*FixupApply)(const FixupEntry*, uint32_t*, const FixupData&);7172struct FixupEntry73{74FixupEntry(FixupApply apply, int ipa, int reg, int loc) :75apply(apply), ipa(ipa), reg(reg), loc(loc) {}7677FixupApply apply;78union {79struct {80uint32_t ipa:4; // SC mode used to identify colors81uint32_t reg:8; // The reg used for perspective division82uint32_t loc:20; // Let's hope we don't have more than 1M-sized shaders83};84uint32_t val;85};86};8788struct FixupInfo89{90uint32_t count;91FixupEntry entry[0];92};9394class CodeEmitter95{96public:97CodeEmitter(const Target *);98virtual ~CodeEmitter() { }99100// returns whether the instruction was encodable and written101virtual bool emitInstruction(Instruction *) = 0;102103virtual uint32_t getMinEncodingSize(const Instruction *) const = 0;104105void setCodeLocation(void *, uint32_t size);106inline void *getCodeLocation() const { return code; }107inline uint32_t getCodeSize() const { return codeSize; }108109bool addReloc(RelocEntry::Type, int w, uint32_t data, uint32_t m,110int s);111112inline void *getRelocInfo() const { return relocInfo; }113114bool addInterp(int ipa, int reg, FixupApply apply);115inline void *getFixupInfo() const { return fixupInfo; }116117virtual void prepareEmission(Program *);118virtual void prepareEmission(Function *);119virtual void prepareEmission(BasicBlock *);120121void printBinary() const;122123protected:124const Target *targ;125126uint32_t *code;127uint32_t codeSize;128uint32_t codeSizeLimit;129130RelocInfo *relocInfo;131FixupInfo *fixupInfo;132};133134135enum OpClass136{137OPCLASS_MOVE = 0,138OPCLASS_LOAD = 1,139OPCLASS_STORE = 2,140OPCLASS_ARITH = 3,141OPCLASS_SHIFT = 4,142OPCLASS_SFU = 5,143OPCLASS_LOGIC = 6,144OPCLASS_COMPARE = 7,145OPCLASS_CONVERT = 8,146OPCLASS_ATOMIC = 9,147OPCLASS_TEXTURE = 10,148OPCLASS_SURFACE = 11,149OPCLASS_FLOW = 12,150OPCLASS_PSEUDO = 14,151OPCLASS_VECTOR = 15,152OPCLASS_BITFIELD = 16,153OPCLASS_CONTROL = 17,154OPCLASS_OTHER = 18155};156157class Target158{159public:160Target(bool m, bool j, bool s) : hasJoin(m), joinAnterior(j), hasSWSched(s) { }161virtual ~Target() { }162163static Target *create(uint32_t chipset);164static void destroy(Target *);165166// 0x50 and 0x84 to 0xaf for nv50167// 0xc0 to 0xdf for nvc0168inline uint32_t getChipset() const { return chipset; }169170virtual CodeEmitter *getCodeEmitter(Program::Type) = 0;171172// Drivers should upload this so we can use it from all programs.173// The address chosen is supplied to the relocation routine.174virtual void getBuiltinCode(const uint32_t **code, uint32_t *size) const = 0;175176virtual void parseDriverInfo(const struct nv50_ir_prog_info *info,177const struct nv50_ir_prog_info_out *info_out) {178if (info_out->type == PIPE_SHADER_COMPUTE) {179threads = info->prop.cp.numThreads[0] *180info->prop.cp.numThreads[1] *181info->prop.cp.numThreads[2];182if (threads == 0)183threads = info->target >= NVISA_GK104_CHIPSET ? 1024 : 512;184} else {185threads = 32; // doesn't matter, just not too big.186}187}188189virtual bool runLegalizePass(Program *, CGStage stage) const = 0;190191public:192struct OpInfo193{194OpInfo *variants;195operation op;196uint16_t srcTypes;197uint16_t dstTypes;198uint32_t immdBits;199uint8_t srcNr;200uint8_t srcMods[3];201uint8_t dstMods;202uint16_t srcFiles[3];203uint16_t dstFiles;204unsigned int minEncSize : 5;205unsigned int vector : 1;206unsigned int predicate : 1;207unsigned int commutative : 1;208unsigned int pseudo : 1;209unsigned int flow : 1;210unsigned int hasDest : 1;211unsigned int terminator : 1;212};213214inline const OpInfo& getOpInfo(const Instruction *) const;215inline const OpInfo& getOpInfo(const operation) const;216217inline DataFile nativeFile(DataFile f) const;218219virtual bool insnCanLoad(const Instruction *insn, int s,220const Instruction *ld) const = 0;221virtual bool insnCanLoadOffset(const Instruction *insn, int s,222int offset) const = 0;223virtual bool isOpSupported(operation, DataType) const = 0;224virtual bool isAccessSupported(DataFile, DataType) const = 0;225virtual bool isModSupported(const Instruction *,226int s, Modifier) const = 0;227virtual bool isSatSupported(const Instruction *) const = 0;228virtual bool isPostMultiplySupported(operation op, float f,229int& e) const { return false; }230virtual bool mayPredicate(const Instruction *,231const Value *) const = 0;232233// whether @insn can be issued together with @next (order matters)234virtual bool canDualIssue(const Instruction *insn,235const Instruction *next) const { return false; }236virtual int getLatency(const Instruction *) const { return 1; }237virtual int getThroughput(const Instruction *) const { return 1; }238239virtual unsigned int getFileSize(DataFile) const = 0;240virtual unsigned int getFileUnit(DataFile) const = 0;241242virtual uint32_t getSVAddress(DataFile, const Symbol *) const = 0;243244public:245const bool hasJoin; // true if instructions have a join modifier246const bool joinAnterior; // true if join is executed before the op247const bool hasSWSched; // true if code should provide scheduling data248249static const uint8_t operationSrcNr[];250static const OpClass operationClass[];251252static inline uint8_t getOpSrcNr(operation op)253{254return operationSrcNr[op];255}256static inline OpClass getOpClass(operation op)257{258return operationClass[op];259}260261protected:262uint32_t chipset;263uint32_t threads;264265DataFile nativeFileMap[DATA_FILE_COUNT];266267OpInfo opInfo[OP_LAST + 1];268};269270const Target::OpInfo& Target::getOpInfo(const Instruction *insn) const271{272return opInfo[MIN2(insn->op, OP_LAST)];273}274275const Target::OpInfo& Target::getOpInfo(const operation op) const276{277return opInfo[op];278}279280inline DataFile Target::nativeFile(DataFile f) const281{282return nativeFileMap[f];283}284285} // namespace nv50_ir286287#endif // __NV50_IR_TARGET_H__288289290