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 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.
21 */
22
23#include "codegen/nv50_ir.h"
24#include "codegen/nv50_ir_build_util.h"
25
26namespace nv50_ir {
27
28class NVC0LegalizeSSA : public Pass
29{
30private:
31   virtual bool visit(BasicBlock *);
32   virtual bool visit(Function *);
33
34   // we want to insert calls to the builtin library only after optimization
35   void handleDIV(Instruction *); // integer division, modulus
36   void handleRCPRSQ(Instruction *); // double precision float recip/rsqrt
37   void handleFTZ(Instruction *);
38   void handleTEXLOD(TexInstruction *);
39
40protected:
41   BuildUtil bld;
42};
43
44class NVC0LegalizePostRA : public Pass
45{
46public:
47   NVC0LegalizePostRA(const Program *);
48
49private:
50   virtual bool visit(Function *);
51   virtual bool visit(BasicBlock *);
52
53   void replaceZero(Instruction *);
54   bool tryReplaceContWithBra(BasicBlock *);
55   void propagateJoin(BasicBlock *);
56
57   struct TexUse
58   {
59      TexUse(Instruction *use, const Instruction *tex, bool after)
60         : insn(use), tex(tex), after(after), level(-1) { }
61      Instruction *insn;
62      const Instruction *tex; // or split / mov
63      bool after;
64      int level;
65   };
66   struct Limits
67   {
68      Limits() { }
69      Limits(int min, int max) : min(min), max(max) { }
70      int min, max;
71   };
72   bool insertTextureBarriers(Function *);
73   inline bool insnDominatedBy(const Instruction *, const Instruction *) const;
74   void findFirstUses(Instruction *texi, std::list<TexUse> &uses);
75   void findFirstUsesBB(int minGPR, int maxGPR, Instruction *start,
76                        const Instruction *texi, std::list<TexUse> &uses,
77                        unordered_set<const BasicBlock *> &visited);
78   void addTexUse(std::list<TexUse>&, Instruction *, const Instruction *);
79   const Instruction *recurseDef(const Instruction *);
80
81private:
82   LValue *rZero;
83   LValue *carry;
84   LValue *pOne;
85   const bool needTexBar;
86};
87
88class NVC0LoweringPass : public Pass
89{
90public:
91   NVC0LoweringPass(Program *);
92
93protected:
94   bool handleRDSV(Instruction *);
95   bool handleWRSV(Instruction *);
96   bool handleEXPORT(Instruction *);
97   bool handleOUT(Instruction *);
98   bool handleDIV(Instruction *);
99   bool handleMOD(Instruction *);
100   bool handleSQRT(Instruction *);
101   bool handlePOW(Instruction *);
102   bool handleTEX(TexInstruction *);
103   bool handleTXD(TexInstruction *);
104   bool handleTXQ(TexInstruction *);
105   virtual bool handleManualTXD(TexInstruction *);
106   bool handleTXLQ(TexInstruction *);
107   bool handleSUQ(TexInstruction *);
108   bool handleATOM(Instruction *);
109   bool handleCasExch(Instruction *, bool needCctl);
110   void handleSurfaceOpGM107(TexInstruction *);
111   void handleSurfaceOpNVE4(TexInstruction *);
112   void handleSurfaceOpNVC0(TexInstruction *);
113   void handleSharedATOM(Instruction *);
114   void handleSharedATOMNVE4(Instruction *);
115   void handleLDST(Instruction *);
116   bool handleBUFQ(Instruction *);
117
118   void checkPredicate(Instruction *);
119
120   virtual bool visit(Instruction *);
121
122private:
123   virtual bool visit(Function *);
124   virtual bool visit(BasicBlock *);
125
126   void readTessCoord(LValue *dst, int c);
127
128   Value *loadResInfo32(Value *ptr, uint32_t off, uint16_t base);
129   Value *loadResInfo64(Value *ptr, uint32_t off, uint16_t base);
130   Value *loadResLength32(Value *ptr, uint32_t off, uint16_t base);
131   Value *loadSuInfo32(Value *ptr, int slot, uint32_t off);
132   Value *loadBufInfo64(Value *ptr, uint32_t off);
133   Value *loadBufLength32(Value *ptr, uint32_t off);
134   Value *loadUboInfo64(Value *ptr, uint32_t off);
135   Value *loadUboLength32(Value *ptr, uint32_t off);
136   Value *loadMsInfo32(Value *ptr, uint32_t off);
137   Value *loadTexHandle(Value *ptr, unsigned int slot);
138
139   void adjustCoordinatesMS(TexInstruction *);
140   void processSurfaceCoordsGM107(TexInstruction *);
141   void processSurfaceCoordsNVE4(TexInstruction *);
142   void processSurfaceCoordsNVC0(TexInstruction *);
143   void convertSurfaceFormat(TexInstruction *);
144
145protected:
146   BuildUtil bld;
147
148private:
149   const Target *const targ;
150
151   Symbol *gMemBase;
152   LValue *gpEmitAddress;
153};
154
155} // namespace nv50_ir
156