summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/codegen/nv50_ir_target.h
blob: ddde55868905738a6c5dcbec4773a6e472733eee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

#ifndef __NV50_IR_TARGET_H__
#define __NV50_IR_TARGET_H__

#include "nv50_ir.h"

namespace nv50_ir {

struct RelocInfo;

struct RelocEntry
{
   enum Type
   {
      TYPE_CODE,
      TYPE_BUILTIN,
      TYPE_DATA
   };

   uint32_t data;
   uint32_t mask;
   uint32_t offset;
   int8_t bitPos;
   Type type;

   inline void apply(uint32_t *binary, const RelocInfo *info) const;
};

struct RelocInfo
{
   uint32_t codePos;
   uint32_t libPos;
   uint32_t dataPos;

   uint32_t count;

   RelocEntry entry[0];
};

class CodeEmitter
{
public:
   // returns whether the instruction was encodable and written
   virtual bool emitInstruction(Instruction *) = 0;

   virtual uint32_t getMinEncodingSize(const Instruction *) const = 0;

   void setCodeLocation(void *, uint32_t size);
   inline void *getCodeLocation() const { return code; }
   inline uint32_t getCodeSize() const { return codeSize; }

   bool addReloc(RelocEntry::Type, int w, uint32_t data, uint32_t m,
                 int s);

   inline void *getRelocInfo() const { return relocInfo; }

   void prepareEmission(Program *);
   void prepareEmission(Function *);
   virtual void prepareEmission(BasicBlock *);

   void printBinary() const;

protected:
   uint32_t *code;
   uint32_t codeSize;
   uint32_t codeSizeLimit;

   RelocInfo *relocInfo;
};

class Target
{
public:
   static Target *create(uint32_t chipset);
   static void destroy(Target *);

   // 0x50 and 0x84 to 0xaf for nv50
   // 0xc0 to 0xdf for nvc0
   inline uint32_t getChipset() const { return chipset; }

   virtual CodeEmitter *getCodeEmitter(Program::Type) = 0;

   // Drivers should upload this so we can use it from all programs.
   // The address chosen is supplied to the relocation routine.
   virtual void getBuiltinCode(const uint32_t **code, uint32_t *size) const = 0;

   virtual bool runLegalizePass(Program *, CGStage stage) const = 0;

public:
   struct OpInfo
   {
      OpInfo *variants;
      operation op;
      uint16_t srcTypes;
      uint16_t dstTypes;
      uint32_t immdBits;
      uint8_t srcNr;
      uint8_t srcMods[3];
      uint8_t dstMods;
      uint8_t srcFiles[3];
      uint8_t dstFiles;
      unsigned int minEncSize  : 4;
      unsigned int vector      : 1;
      unsigned int predicate   : 1;
      unsigned int commutative : 1;
      unsigned int pseudo      : 1;
      unsigned int flow        : 1;
      unsigned int hasDest     : 1;
      unsigned int terminator  : 1;
   };

   inline const OpInfo& getOpInfo(const Instruction *) const;
   inline const OpInfo& getOpInfo(const operation) const;

   inline DataFile nativeFile(DataFile f) const;

   virtual bool insnCanLoad(const Instruction *insn, int s,
                            const Instruction *ld) const = 0;
   virtual bool isOpSupported(operation, DataType) const = 0;
   virtual bool isModSupported(const Instruction *,
                               int s, Modifier) const = 0;
   virtual bool isSatSupported(const Instruction *) const = 0;
   virtual bool mayPredicate(const Instruction *,
                             const Value *) const = 0;

   virtual int getLatency(const Instruction *) const { return 1; }
   virtual int getThroughput(const Instruction *) const { return 1; }

   virtual unsigned int getFileSize(DataFile) const = 0;
   virtual unsigned int getFileUnit(DataFile) const = 0;

   virtual uint32_t getSVAddress(DataFile, const Symbol *) const = 0;

public:
   bool joinAnterior; // true if join is executed before the op

   static const uint8_t operationSrcNr[OP_LAST + 1];

protected:
   uint32_t chipset;

   DataFile nativeFileMap[DATA_FILE_COUNT];

   OpInfo opInfo[OP_LAST + 1];
};

const Target::OpInfo& Target::getOpInfo(const Instruction *insn) const
{
   return opInfo[MIN2(insn->op, OP_LAST)];
}

const Target::OpInfo& Target::getOpInfo(const operation op) const
{
   return opInfo[op];
}

inline DataFile Target::nativeFile(DataFile f) const
{
   return nativeFileMap[f];
}

} // namespace nv50_ir

#endif // __NV50_IR_TARGET_H__