2 * Copyright 2011 Christoph Bumiller
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef __NV50_IR_BUILD_UTIL__
24 #define __NV50_IR_BUILD_UTIL__
34 inline void setProgram(Program
*);
35 inline Program
*getProgram() const { return prog
; }
36 inline Function
*getFunction() const { return func
; }
38 // keeps inserting at head/tail of block
39 inline void setPosition(BasicBlock
*, bool tail
);
40 // position advances only if @after is true
41 inline void setPosition(Instruction
*, bool after
);
43 inline BasicBlock
*getBB() { return bb
; }
45 inline void insert(Instruction
*);
46 inline void remove(Instruction
*i
) { assert(i
->bb
== bb
); bb
->remove(i
); }
48 inline LValue
*getScratch(int size
= 4, DataFile
= FILE_GPR
);
49 // scratch value for a single assignment:
50 inline LValue
*getSSA(int size
= 4, DataFile
= FILE_GPR
);
52 inline Instruction
*mkOp(operation
, DataType
, Value
*);
53 Instruction
*mkOp1(operation
, DataType
, Value
*, Value
*);
54 Instruction
*mkOp2(operation
, DataType
, Value
*, Value
*, Value
*);
55 Instruction
*mkOp3(operation
, DataType
, Value
*, Value
*, Value
*, Value
*);
57 LValue
*mkOp1v(operation
, DataType
, Value
*, Value
*);
58 LValue
*mkOp2v(operation
, DataType
, Value
*, Value
*, Value
*);
59 LValue
*mkOp3v(operation
, DataType
, Value
*, Value
*, Value
*, Value
*);
61 Instruction
*mkLoad(DataType
, Value
*dst
, Symbol
*, Value
*ptr
);
62 Instruction
*mkStore(operation
, DataType
, Symbol
*, Value
*ptr
, Value
*val
);
64 LValue
*mkLoadv(DataType
, Symbol
*, Value
*ptr
);
66 Instruction
*mkMov(Value
*, Value
*, DataType
= TYPE_U32
);
67 Instruction
*mkMovToReg(int id
, Value
*);
68 Instruction
*mkMovFromReg(Value
*, int id
);
70 Instruction
*mkInterp(unsigned mode
, Value
*, int32_t offset
, Value
*rel
);
71 Instruction
*mkFetch(Value
*, DataType
, DataFile
, int32_t offset
,
72 Value
*attrRel
, Value
*primRel
);
74 Instruction
*mkCvt(operation
, DataType
, Value
*, DataType
, Value
*);
75 CmpInstruction
*mkCmp(operation
, CondCode
, DataType
,
77 DataType
, Value
*, Value
*, Value
* = NULL
);
78 TexInstruction
*mkTex(operation
, TexTarget
,
79 uint16_t tic
, uint16_t tsc
,
80 const std::vector
<Value
*> &def
,
81 const std::vector
<Value
*> &src
);
82 Instruction
*mkQuadop(uint8_t qop
, Value
*, uint8_t l
, Value
*, Value
*);
84 FlowInstruction
*mkFlow(operation
, void *target
, CondCode
, Value
*pred
);
86 Instruction
*mkSelect(Value
*pred
, Value
*dst
, Value
*trSrc
, Value
*flSrc
);
88 Instruction
*mkSplit(Value
*half
[2], uint8_t halfSize
, Value
*);
90 void mkClobber(DataFile file
, uint32_t regMask
, int regUnitLog2
);
92 ImmediateValue
*mkImm(float);
93 ImmediateValue
*mkImm(double);
94 ImmediateValue
*mkImm(uint32_t);
95 ImmediateValue
*mkImm(uint64_t);
97 ImmediateValue
*mkImm(int i
) { return mkImm((uint32_t)i
); }
99 Value
*loadImm(Value
*dst
, float);
100 Value
*loadImm(Value
*dst
, double);
101 Value
*loadImm(Value
*dst
, uint32_t);
102 Value
*loadImm(Value
*dst
, uint64_t);
104 Value
*loadImm(Value
*dst
, int i
) { return loadImm(dst
, (uint32_t)i
); }
106 // returns high part of the operation
107 static Instruction
*split64BitOpPostRA(Function
*, Instruction
*,
108 Value
*zero
, Value
*carry
);
112 Location(unsigned array
, unsigned arrayIdx
, unsigned i
, unsigned c
)
113 : array(array
), arrayIdx(arrayIdx
), i(i
), c(c
) { }
114 Location(const Location
&l
)
115 : array(l
.array
), arrayIdx(l
.arrayIdx
), i(l
.i
), c(l
.c
) { }
117 bool operator==(const Location
&l
) const
120 array
== l
.array
&& arrayIdx
== l
.arrayIdx
&& i
== l
.i
&& c
== l
.c
;
123 bool operator<(const Location
&l
) const
125 return array
!= l
.array
? array
< l
.array
:
126 arrayIdx
!= l
.arrayIdx
? arrayIdx
< l
.arrayIdx
:
132 unsigned array
, arrayIdx
, i
, c
;
135 typedef bimap
<Location
, Value
*> ValueMap
;
140 DataArray(BuildUtil
*bld
) : up(bld
) { }
142 void setup(unsigned array
, unsigned arrayIdx
,
143 uint32_t base
, int len
, int vecDim
, int eltSize
,
144 DataFile file
, int8_t fileIdx
);
146 inline bool exists(ValueMap
&, unsigned int i
, unsigned int c
);
148 Value
*load(ValueMap
&, int i
, int c
, Value
*ptr
);
149 void store(ValueMap
&, int i
, int c
, Value
*ptr
, Value
*value
);
150 Value
*acquire(ValueMap
&, int i
, int c
);
153 inline Value
*lookup(ValueMap
&, unsigned i
, unsigned c
);
154 inline Value
*insert(ValueMap
&, unsigned i
, unsigned c
, Value
*v
);
156 Symbol
*mkSymbol(int i
, int c
);
160 unsigned array
, arrayIdx
;
167 uint8_t eltSize
; // in bytes
173 Symbol
*mkSymbol(DataFile file
, int8_t fileIndex
,
174 DataType ty
, uint32_t baseAddress
);
176 Symbol
*mkSysVal(SVSemantic svName
, uint32_t svIndex
);
179 void init(Program
*);
180 void addImmediate(ImmediateValue
*);
181 inline unsigned int u32Hash(uint32_t);
190 #define NV50_IR_BUILD_IMM_HT_SIZE 256
192 ImmediateValue
*imms
[NV50_IR_BUILD_IMM_HT_SIZE
];
193 unsigned int immCount
;
196 unsigned int BuildUtil::u32Hash(uint32_t u
)
198 return (u
% 273) % NV50_IR_BUILD_IMM_HT_SIZE
;
201 void BuildUtil::setProgram(Program
*program
)
207 BuildUtil::setPosition(BasicBlock
*block
, bool atTail
)
210 prog
= bb
->getProgram();
211 func
= bb
->getFunction();
217 BuildUtil::setPosition(Instruction
*i
, bool after
)
220 prog
= bb
->getProgram();
221 func
= bb
->getFunction();
228 BuildUtil::getScratch(int size
, DataFile f
)
230 LValue
*lval
= new_LValue(func
, f
);
231 lval
->reg
.size
= size
;
236 BuildUtil::getSSA(int size
, DataFile f
)
238 LValue
*lval
= new_LValue(func
, f
);
240 lval
->reg
.size
= size
;
244 void BuildUtil::insert(Instruction
*i
)
247 tail
? bb
->insertTail(i
) : bb
->insertHead(i
);
250 bb
->insertAfter(pos
, i
);
253 bb
->insertBefore(pos
, i
);
259 BuildUtil::mkOp(operation op
, DataType ty
, Value
*dst
)
261 Instruction
*insn
= new_Instruction(func
, op
, ty
);
262 insn
->setDef(0, dst
);
264 if (op
== OP_DISCARD
|| op
== OP_EXIT
||
266 op
== OP_QUADON
|| op
== OP_QUADPOP
||
267 op
== OP_EMIT
|| op
== OP_RESTART
)
273 BuildUtil::mkOp1v(operation op
, DataType ty
, Value
*dst
, Value
*src
)
275 mkOp1(op
, ty
, dst
, src
);
276 return dst
->asLValue();
280 BuildUtil::mkOp2v(operation op
, DataType ty
, Value
*dst
,
281 Value
*src0
, Value
*src1
)
283 mkOp2(op
, ty
, dst
, src0
, src1
);
284 return dst
->asLValue();
288 BuildUtil::mkOp3v(operation op
, DataType ty
, Value
*dst
,
289 Value
*src0
, Value
*src1
, Value
*src2
)
291 mkOp3(op
, ty
, dst
, src0
, src1
, src2
);
292 return dst
->asLValue();
296 BuildUtil::mkLoadv(DataType ty
, Symbol
*mem
, Value
*ptr
)
298 LValue
*dst
= getScratch(typeSizeof(ty
));
299 mkLoad(ty
, dst
, mem
, ptr
);
304 BuildUtil::DataArray::exists(ValueMap
&m
, unsigned int i
, unsigned int c
)
306 assert(i
< arrayLen
&& c
< vecDim
);
307 return !regOnly
|| m
.r
.count(Location(array
, arrayIdx
, i
, c
));
311 BuildUtil::DataArray::lookup(ValueMap
&m
, unsigned i
, unsigned c
)
313 ValueMap::r_iterator it
= m
.r
.find(Location(array
, arrayIdx
, i
, c
));
314 return it
!= m
.r
.end() ? it
->second
: NULL
;
318 BuildUtil::DataArray::insert(ValueMap
&m
, unsigned i
, unsigned c
, Value
*v
)
320 m
.insert(Location(array
, arrayIdx
, i
, c
), v
);
324 } // namespace nv50_ir
326 #endif // __NV50_IR_BUILD_UTIL_H__