Home | History | Annotate | Download | only in codegen
      1 /*
      2  * Copyright 2011 Christoph Bumiller
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20  * SOFTWARE.
     21  */
     22 
     23 #ifndef __NV50_IR_TARGET_H__
     24 #define __NV50_IR_TARGET_H__
     25 
     26 #include "nv50_ir.h"
     27 
     28 namespace nv50_ir {
     29 
     30 struct RelocInfo;
     31 
     32 struct RelocEntry
     33 {
     34    enum Type
     35    {
     36       TYPE_CODE,
     37       TYPE_BUILTIN,
     38       TYPE_DATA
     39    };
     40 
     41    uint32_t data;
     42    uint32_t mask;
     43    uint32_t offset;
     44    int8_t bitPos;
     45    Type type;
     46 
     47    inline void apply(uint32_t *binary, const RelocInfo *info) const;
     48 };
     49 
     50 struct RelocInfo
     51 {
     52    uint32_t codePos;
     53    uint32_t libPos;
     54    uint32_t dataPos;
     55 
     56    uint32_t count;
     57 
     58    RelocEntry entry[0];
     59 };
     60 
     61 class CodeEmitter
     62 {
     63 public:
     64    CodeEmitter(const Target *);
     65 
     66    // returns whether the instruction was encodable and written
     67    virtual bool emitInstruction(Instruction *) = 0;
     68 
     69    virtual uint32_t getMinEncodingSize(const Instruction *) const = 0;
     70 
     71    void setCodeLocation(void *, uint32_t size);
     72    inline void *getCodeLocation() const { return code; }
     73    inline uint32_t getCodeSize() const { return codeSize; }
     74 
     75    bool addReloc(RelocEntry::Type, int w, uint32_t data, uint32_t m,
     76                  int s);
     77 
     78    inline void *getRelocInfo() const { return relocInfo; }
     79 
     80    void prepareEmission(Program *);
     81    virtual void prepareEmission(Function *);
     82    virtual void prepareEmission(BasicBlock *);
     83 
     84    void printBinary() const;
     85 
     86 protected:
     87    const Target *targ;
     88 
     89    uint32_t *code;
     90    uint32_t codeSize;
     91    uint32_t codeSizeLimit;
     92 
     93    RelocInfo *relocInfo;
     94 };
     95 
     96 
     97 enum OpClass
     98 {
     99    OPCLASS_MOVE          = 0,
    100    OPCLASS_LOAD          = 1,
    101    OPCLASS_STORE         = 2,
    102    OPCLASS_ARITH         = 3,
    103    OPCLASS_SHIFT         = 4,
    104    OPCLASS_SFU           = 5,
    105    OPCLASS_LOGIC         = 6,
    106    OPCLASS_COMPARE       = 7,
    107    OPCLASS_CONVERT       = 8,
    108    OPCLASS_ATOMIC        = 9,
    109    OPCLASS_TEXTURE       = 10,
    110    OPCLASS_SURFACE       = 11,
    111    OPCLASS_FLOW          = 12,
    112    OPCLASS_PSEUDO        = 14,
    113    OPCLASS_OTHER         = 15
    114 };
    115 
    116 class Target
    117 {
    118 public:
    119    Target(bool j, bool s) : joinAnterior(j), hasSWSched(s) { }
    120 
    121    static Target *create(uint32_t chipset);
    122    static void destroy(Target *);
    123 
    124    // 0x50 and 0x84 to 0xaf for nv50
    125    // 0xc0 to 0xdf for nvc0
    126    inline uint32_t getChipset() const { return chipset; }
    127 
    128    virtual CodeEmitter *getCodeEmitter(Program::Type) = 0;
    129 
    130    // Drivers should upload this so we can use it from all programs.
    131    // The address chosen is supplied to the relocation routine.
    132    virtual void getBuiltinCode(const uint32_t **code, uint32_t *size) const = 0;
    133 
    134    virtual void parseDriverInfo(const struct nv50_ir_prog_info *info) { }
    135 
    136    virtual bool runLegalizePass(Program *, CGStage stage) const = 0;
    137 
    138 public:
    139    struct OpInfo
    140    {
    141       OpInfo *variants;
    142       operation op;
    143       uint16_t srcTypes;
    144       uint16_t dstTypes;
    145       uint32_t immdBits;
    146       uint8_t srcNr;
    147       uint8_t srcMods[3];
    148       uint8_t dstMods;
    149       uint8_t srcFiles[3];
    150       uint8_t dstFiles;
    151       unsigned int minEncSize  : 4;
    152       unsigned int vector      : 1;
    153       unsigned int predicate   : 1;
    154       unsigned int commutative : 1;
    155       unsigned int pseudo      : 1;
    156       unsigned int flow        : 1;
    157       unsigned int hasDest     : 1;
    158       unsigned int terminator  : 1;
    159    };
    160 
    161    inline const OpInfo& getOpInfo(const Instruction *) const;
    162    inline const OpInfo& getOpInfo(const operation) const;
    163 
    164    inline DataFile nativeFile(DataFile f) const;
    165 
    166    virtual bool insnCanLoad(const Instruction *insn, int s,
    167                             const Instruction *ld) const = 0;
    168    virtual bool isOpSupported(operation, DataType) const = 0;
    169    virtual bool isAccessSupported(DataFile, DataType) const = 0;
    170    virtual bool isModSupported(const Instruction *,
    171                                int s, Modifier) const = 0;
    172    virtual bool isSatSupported(const Instruction *) const = 0;
    173    virtual bool isPostMultiplySupported(operation op, float f,
    174                                         int& e) const { return false; }
    175    virtual bool mayPredicate(const Instruction *,
    176                              const Value *) const = 0;
    177 
    178    // whether @insn can be issued together with @next (order matters)
    179    virtual bool canDualIssue(const Instruction *insn,
    180                              const Instruction *next) const { return false; }
    181    virtual int getLatency(const Instruction *) const { return 1; }
    182    virtual int getThroughput(const Instruction *) const { return 1; }
    183 
    184    virtual unsigned int getFileSize(DataFile) const = 0;
    185    virtual unsigned int getFileUnit(DataFile) const = 0;
    186 
    187    virtual uint32_t getSVAddress(DataFile, const Symbol *) const = 0;
    188 
    189 public:
    190    const bool joinAnterior; // true if join is executed before the op
    191    const bool hasSWSched;   // true if code should provide scheduling data
    192 
    193    static const uint8_t operationSrcNr[OP_LAST + 1];
    194    static const OpClass operationClass[OP_LAST + 1];
    195 
    196    static inline uint8_t getOpSrcNr(operation op)
    197    {
    198       return operationSrcNr[op];
    199    }
    200    static inline OpClass getOpClass(operation op)
    201    {
    202       return operationClass[op];
    203    }
    204 
    205 protected:
    206    uint32_t chipset;
    207 
    208    DataFile nativeFileMap[DATA_FILE_COUNT];
    209 
    210    OpInfo opInfo[OP_LAST + 1];
    211 };
    212 
    213 const Target::OpInfo& Target::getOpInfo(const Instruction *insn) const
    214 {
    215    return opInfo[MIN2(insn->op, OP_LAST)];
    216 }
    217 
    218 const Target::OpInfo& Target::getOpInfo(const operation op) const
    219 {
    220    return opInfo[op];
    221 }
    222 
    223 inline DataFile Target::nativeFile(DataFile f) const
    224 {
    225    return nativeFileMap[f];
    226 }
    227 
    228 } // namespace nv50_ir
    229 
    230 #endif // __NV50_IR_TARGET_H__
    231