1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011 Christoph Bumiller
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included in
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * all copies or substantial portions of the Software.
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50_ir.h"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50_ir_target.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50_ir_driver.h"
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" {
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50/nv50_program.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50/nv50_debug.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace nv50_ir {
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgModifier::Modifier(operation op)
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (op) {
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case OP_NEG: bits = NV50_IR_MOD_NEG; break;
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case OP_ABS: bits = NV50_IR_MOD_ABS; break;
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case OP_SAT: bits = NV50_IR_MOD_SAT; break;
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case OP_NOT: bits = NV50_IR_MOD_NOT; break;
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits = 0;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgModifier Modifier::operator*(const Modifier m) const
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int a, b, c;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   b = m.bits;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->bits & NV50_IR_MOD_ABS)
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      b &= ~NV50_IR_MOD_NEG;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   a = (this->bits ^ b)      & (NV50_IR_MOD_NOT | NV50_IR_MOD_NEG);
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c = (this->bits | m.bits) & (NV50_IR_MOD_ABS | NV50_IR_MOD_SAT);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return Modifier(a | c);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueRef::ValueRef(Value *v) : value(NULL), insn(NULL)
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   indirect[0] = -1;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   indirect[1] = -1;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   usedAsPtr = false;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   set(v);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueRef::ValueRef(const ValueRef& ref) : value(NULL), insn(ref.insn)
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   set(ref);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   usedAsPtr = ref.usedAsPtr;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueRef::~ValueRef()
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->set(NULL);
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ValueRef::getImmediate(ImmediateValue &imm) const
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ValueRef *src = this;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Modifier m;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DataType type = src->insn->sType;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (src) {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (src->mod) {
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (src->insn->sType != type)
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         m *= src->mod;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (src->getFile() == FILE_IMMEDIATE) {
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         imm = *(src->value->asImm());
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         // The immediate's type isn't required to match its use, it's
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         // more of a hint; applying a modifier makes use of that hint.
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         imm.reg.type = type;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         m.applyTo(imm);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return true;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Instruction *insn = src->value->getUniqueInsn();
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (insn && insn->op == OP_MOV) {
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src = &insn->src(0);
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (src->mod)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            WARN("OP_MOV with modifier encountered !\n");
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src = NULL;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueDef::ValueDef(Value *v) : value(NULL), insn(NULL)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   set(v);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueDef::ValueDef(const ValueDef& def) : value(NULL), insn(NULL)
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   set(def.get());
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueDef::~ValueDef()
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->set(NULL);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueRef::set(const ValueRef &ref)
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->set(ref.get());
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mod = ref.mod;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   indirect[0] = ref.indirect[0];
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   indirect[1] = ref.indirect[1];
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueRef::set(Value *refVal)
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value == refVal)
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value)
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      value->uses.remove(this);
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (refVal)
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      refVal->uses.push_back(this);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   value = refVal;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueDef::set(Value *defVal)
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value == defVal)
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value)
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      value->defs.remove(this);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (defVal)
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      defVal->defs.push_back(this);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   value = defVal;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Check if we can replace this definition's value by the value in @rep,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// including the source modifiers, i.e. make sure that all uses support
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// @rep.mod.
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueDef::mayReplace(const ValueRef &rep)
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!rep.mod)
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!insn || !insn->bb) // Unbound instruction ?
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const Target *target = insn->bb->getProgram()->getTarget();
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (Value::UseIterator it = value->uses.begin(); it != value->uses.end();
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++it) {
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Instruction *insn = (*it)->getInsn();
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int s = -1;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i = 0; insn->srcExists(i); ++i) {
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (insn->src(i).get() == value) {
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            // If there are multiple references to us we'd have to check if the
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            // combination of mods is still supported, but just bail for now.
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (&insn->src(i) != (*it))
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return false;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            s = i;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(s >= 0); // integrity of uses list
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!target->isModSupported(insn, s, rep.mod))
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return false;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValueDef::replace(const ValueRef &repVal, bool doSet)
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(mayReplace(repVal));
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value == repVal.get())
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (!value->uses.empty()) {
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ValueRef *ref = value->uses.front();
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ref->set(repVal.get());
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ref->mod *= repVal.mod;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (doSet)
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      set(repVal.get());
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValue::Value()
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  join = this;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  memset(&reg, 0, sizeof(reg));
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  reg.size = 4;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLValue::LValue(Function *fn, DataFile file)
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.file = file;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.size = (file != FILE_PREDICATE) ? 4 : 1;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.data.id = -1;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compMask = 0;
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compound = 0;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ssa = 0;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fixedReg = 0;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   noSpill = 0;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fn->add(this, this->id);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLValue::LValue(Function *fn, LValue *lval)
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(lval);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.file = lval->reg.file;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.size = lval->reg.size;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.data.id = -1;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compMask = 0;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compound = 0;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ssa = 0;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fixedReg = 0;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   noSpill = 0;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fn->add(this, this->id);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLValue *
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLValue::clone(ClonePolicy<Function>& pol) const
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LValue *that = new_LValue(pol.context(), reg.file);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pol.set<Value>(this, that);
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.size = this->reg.size;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.type = this->reg.type;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.data = this->reg.data;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return that;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLValue::isUniform() const
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (defs.size() > 1)
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Instruction *insn = getInsn();
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   // let's not try too hard here for now ...
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return !insn->srcExists(1) && insn->getSrc(0)->isUniform();
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSymbol::Symbol(Program *prog, DataFile f, ubyte fidx)
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   baseSym = NULL;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.file = f;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.fileIndex = fidx;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.data.offset = 0;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->add(this, this->id);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSymbol *
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSymbol::clone(ClonePolicy<Function>& pol) const
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Program *prog = pol.context()->getProgram();
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Symbol *that = new_Symbol(prog, reg.file, reg.fileIndex);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pol.set<Value>(this, that);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.size = this->reg.size;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.type = this->reg.type;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.data = this->reg.data;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->baseSym = this->baseSym;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return that;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSymbol::isUniform() const
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg.file != FILE_SYSTEM_VALUE &&
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg.file != FILE_MEMORY_LOCAL &&
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg.file != FILE_SHADER_INPUT;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::ImmediateValue(Program *prog, uint32_t uval)
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&reg, 0, sizeof(reg));
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.file = FILE_IMMEDIATE;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.size = 4;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.type = TYPE_U32;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.data.u32 = uval;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->add(this, this->id);
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::ImmediateValue(Program *prog, float fval)
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&reg, 0, sizeof(reg));
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.file = FILE_IMMEDIATE;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.size = 4;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.type = TYPE_F32;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.data.f32 = fval;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->add(this, this->id);
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::ImmediateValue(Program *prog, double dval)
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&reg, 0, sizeof(reg));
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.file = FILE_IMMEDIATE;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.size = 8;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.type = TYPE_F64;
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.data.f64 = dval;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->add(this, this->id);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::ImmediateValue(const ImmediateValue *proto, DataType ty)
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg = proto->reg;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.type = ty;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg.size = typeSizeof(ty);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue *
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::clone(ClonePolicy<Function>& pol) const
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Program *prog = pol.context()->getProgram();
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ImmediateValue *that = new_ImmediateValue(prog, 0u);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pol.set<Value>(this, that);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.size = this->reg.size;
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.type = this->reg.type;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   that->reg.data = this->reg.data;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return that;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::isInteger(const int i) const
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (reg.type) {
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S8:
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.s8 == i;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U8:
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.u8 == i;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S16:
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.s16 == i;
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U16:
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.u16 == i;
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S32:
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U32:
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.s32 == i; // as if ...
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_F32:
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.f32 == static_cast<float>(i);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_F64:
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return reg.data.f64 == static_cast<double>(i);
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::isNegative() const
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (reg.type) {
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S8:  return reg.data.s8 < 0;
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S16: return reg.data.s16 < 0;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S32:
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U32: return reg.data.s32 < 0;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_F32: return reg.data.u32 & (1 << 31);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_F64: return reg.data.u64 & (1ULL << 63);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::isPow2() const
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (reg.type) {
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U8:
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U16:
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U32: return util_is_power_of_two(reg.data.u32);
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::applyLog2()
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (reg.type) {
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S8:
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S16:
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_S32:
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!this->isNegative());
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // fall through
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U8:
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U16:
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_U32:
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg.data.u32 = util_logbase2(reg.data.u32);
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_F32:
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg.data.f32 = log2f(reg.data.f32);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TYPE_F64:
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg.data.f64 = log2(reg.data.f64);
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::compare(CondCode cc, float fval) const
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (reg.type != TYPE_F32)
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ERROR("immediate value is not of type f32");
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (static_cast<CondCode>(cc & 7)) {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_TR: return true;
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_FL: return false;
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_LT: return reg.data.f32 <  fval;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_LE: return reg.data.f32 <= fval;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_GT: return reg.data.f32 >  fval;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_GE: return reg.data.f32 >= fval;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_EQ: return reg.data.f32 == fval;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case CC_NE: return reg.data.f32 != fval;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue&
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::operator=(const ImmediateValue &that)
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->reg = that.reg;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (*this);
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValue::interfers(const Value *that) const
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t idA, idB;
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (that->reg.file != reg.file || that->reg.fileIndex != reg.fileIndex)
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->asImm())
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->asSym()) {
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idA = this->join->reg.data.offset;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idB = that->join->reg.data.offset;
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idA = this->join->reg.data.id * MIN2(this->reg.size, 4);
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idB = that->join->reg.data.id * MIN2(that->reg.size, 4);
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (idA < idB)
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (idA + this->reg.size > idB);
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (idA > idB)
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (idB + that->reg.size > idA);
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (idA == idB);
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgValue::equals(const Value *that, bool strict) const
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strict)
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return this == that;
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (that->reg.file != reg.file || that->reg.fileIndex != reg.fileIndex)
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (that->reg.size != this->reg.size)
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (that->reg.data.id != this->reg.data.id)
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgImmediateValue::equals(const Value *that, bool strict) const
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ImmediateValue *imm = that->asImm();
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!imm)
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return reg.data.u64 == imm->reg.data.u64;
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSymbol::equals(const Value *that, bool strict) const
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (reg.file != that->reg.file || reg.fileIndex != that->reg.fileIndex)
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(that->asSym());
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->baseSym != that->asSym()->baseSym)
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return this->reg.data.offset == that->reg.data.offset;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid Instruction::init()
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   next = prev = 0;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cc = CC_ALWAYS;
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rnd = ROUND_N;
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache = CACHE_CA;
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   subOp = 0;
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   saturate = 0;
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   join = 0;
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exit = 0;
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   terminator = 0;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ftz = 0;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dnz = 0;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   atomic = 0;
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   perPatch = 0;
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fixed = 0;
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   encSize = 0;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ipa = 0;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lanes = 0xf;
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   postFactor = 0;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   predSrc = -1;
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flagsDef = -1;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flagsSrc = -1;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::Instruction()
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   init();
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   op = OP_NOP;
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dType = sType = TYPE_F32;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   id = -1;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bb = 0;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::Instruction(Function *fn, operation opr, DataType ty)
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   init();
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   op = opr;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dType = sType = ty;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fn->add(this, id);
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::~Instruction()
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bb) {
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Function *fn = bb->getFunction();
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bb->remove(this);
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fn->allInsns.remove(id);
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int s = 0; srcExists(s); ++s)
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setSrc(s, NULL);
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   // must unlink defs too since the list pointers will get deallocated
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int d = 0; defExists(d); ++d)
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setDef(d, NULL);
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::setDef(int i, Value *val)
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int size = defs.size();
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i >= size) {
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      defs.resize(i + 1);
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      while (size <= i)
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         defs[size++].setInsn(this);
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   defs[i].set(val);
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::setSrc(int s, Value *val)
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int size = srcs.size();
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (s >= size) {
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      srcs.resize(s + 1);
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      while (size <= s)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         srcs[size++].setInsn(this);
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   srcs[s].set(val);
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::setSrc(int s, const ValueRef& ref)
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setSrc(s, ref.get());
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   srcs[s].mod = ref.mod;
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::swapSources(int a, int b)
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Value *value = srcs[a].get();
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Modifier m = srcs[a].mod;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setSrc(a, srcs[b]);
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   srcs[b].set(value);
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   srcs[b].mod = m;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// TODO: extend for delta < 0
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::moveSources(int s, int delta)
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (delta == 0)
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(delta > 0);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int k;
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (k = 0; srcExists(k); ++k) {
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i = 0; i < 2; ++i) {
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (src(k).indirect[i] >= s)
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src(k).indirect[i] += delta;
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (predSrc >= s)
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      predSrc += delta;
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (flagsSrc >= s)
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flagsSrc += delta;
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   --k;
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int p = k + delta; k >= s; --k, --p)
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setSrc(p, src(k));
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::takeExtraSources(int s, Value *values[3])
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   values[0] = getIndirect(s, 0);
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (values[0])
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setIndirect(s, 0, NULL);
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   values[1] = getIndirect(s, 1);
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (values[1])
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setIndirect(s, 1, NULL);
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   values[2] = getPredicate();
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (values[2])
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setPredicate(cc, NULL);
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::putExtraSources(int s, Value *values[3])
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (values[0])
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setIndirect(s, 0, values[0]);
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (values[1])
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setIndirect(s, 1, values[1]);
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (values[2])
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setPredicate(cc, values[2]);
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction *
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!i)
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i = new_Instruction(pol.context(), op, dType);
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef NDEBUG // non-conformant assert, so this is required
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(typeid(*i) == typeid(*this));
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pol.set<Instruction>(this, i);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->sType = sType;
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->rnd = rnd;
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->cache = cache;
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->subOp = subOp;
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->saturate = saturate;
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->join = join;
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->exit = exit;
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->atomic = atomic;
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->ftz = ftz;
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->dnz = dnz;
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->ipa = ipa;
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->lanes = lanes;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->perPatch = perPatch;
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->postFactor = postFactor;
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int d = 0; defExists(d); ++d)
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i->setDef(d, pol.get(getDef(d)));
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int s = 0; srcExists(s); ++s) {
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i->setSrc(s, pol.get(getSrc(s)));
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i->src(s).mod = src(s).mod;
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->cc = cc;
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->predSrc = predSrc;
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->flagsDef = flagsDef;
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i->flagsSrc = flagsSrc;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return i;
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::defCount(unsigned int mask, bool singleFile) const
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i, n;
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (singleFile) {
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned int d = ffs(mask);
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!d)
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return 0;
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = d--; defExists(i); ++i)
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (getDef(i)->reg.file != getDef(d)->reg.file)
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            mask &= ~(1 << i);
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (n = 0, i = 0; this->defExists(i); ++i, mask >>= 1)
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      n += mask & 1;
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return n;
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::srcCount(unsigned int mask, bool singleFile) const
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i, n;
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (singleFile) {
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned int s = ffs(mask);
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!s)
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return 0;
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = s--; srcExists(i); ++i)
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (getSrc(i)->reg.file != getSrc(s)->reg.file)
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            mask &= ~(1 << i);
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (n = 0, i = 0; this->srcExists(i); ++i, mask >>= 1)
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      n += mask & 1;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return n;
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::setIndirect(int s, int dim, Value *value)
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(this->srcExists(s));
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int p = srcs[s].indirect[dim];
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (p < 0) {
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!value)
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return true;
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      p = srcs.size();
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      while (p > 0 && !srcExists(p - 1))
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         --p;
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setSrc(p, value);
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   srcs[p].usedAsPtr = (value != 0);
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   srcs[s].indirect[dim] = value ? p : -1;
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::setPredicate(CondCode ccode, Value *value)
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cc = ccode;
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!value) {
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (predSrc >= 0) {
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         srcs[predSrc].set(NULL);
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         predSrc = -1;
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (predSrc < 0) {
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      predSrc = srcs.size();
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      while (predSrc > 0 && !srcExists(predSrc - 1))
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         --predSrc;
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setSrc(predSrc, value);
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::writesPredicate() const
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int d = 0; defExists(d); ++d)
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (getDef(d)->inFile(FILE_PREDICATE) || getDef(d)->inFile(FILE_FLAGS))
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return true;
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orginsnCheckCommutationDefSrc(const Instruction *a, const Instruction *b)
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int d = 0; a->defExists(d); ++d)
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int s = 0; b->srcExists(s); ++s)
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (a->getDef(d)->interfers(b->getSrc(s)))
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return false;
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orginsnCheckCommutationDefDef(const Instruction *a, const Instruction *b)
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int d = 0; a->defExists(d); ++d)
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int c = 0; b->defExists(c); ++c)
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (a->getDef(d)->interfers(b->getDef(c)))
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return false;
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgInstruction::isCommutationLegal(const Instruction *i) const
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool ret = insnCheckCommutationDefDef(this, i);
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = ret && insnCheckCommutationDefSrc(this, i);
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = ret && insnCheckCommutationDefSrc(i, this);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTexInstruction::TexInstruction(Function *fn, operation op)
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   : Instruction(fn, op, TYPE_F32)
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&tex, 0, sizeof(tex));
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tex.rIndirectSrc = -1;
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tex.sIndirectSrc = -1;
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTexInstruction::~TexInstruction()
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int c = 0; c < 3; ++c) {
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dPdx[c].set(NULL);
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dPdy[c].set(NULL);
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTexInstruction *
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTexInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TexInstruction *tex = (i ? static_cast<TexInstruction *>(i) :
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          new_TexInstruction(pol.context(), op));
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Instruction::clone(pol, tex);
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tex->tex = this->tex;
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op == OP_TXD) {
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned int c = 0; c < tex->tex.target.getDim(); ++c) {
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tex->dPdx[c].set(dPdx[c]);
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tex->dPdy[c].set(dPdy[c]);
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return tex;
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct TexInstruction::Target::Desc TexInstruction::Target::descTable[] =
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "1D",                1, 1, false, false, false },
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "2D",                2, 2, false, false, false },
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "2D_MS",             2, 2, false, false, false },
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "3D",                3, 3, false, false, false },
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "CUBE",              2, 3, false, true,  false },
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "1D_SHADOW",         1, 1, false, false, true  },
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "2D_SHADOW",         2, 2, false, false, true  },
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "CUBE_SHADOW",       2, 3, false, true,  true  },
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "1D_ARRAY",          1, 2, true,  false, false },
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "2D_ARRAY",          2, 3, true,  false, false },
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "2D_MS_ARRAY",       2, 3, true,  false, false },
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "CUBE_ARRAY",        2, 4, true,  true,  false },
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "1D_ARRAY_SHADOW",   1, 2, true,  false, true  },
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "2D_ARRAY_SHADOW",   2, 3, true,  false, true  },
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "RECT",              2, 2, false, false, false },
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "RECT_SHADOW",       2, 2, false, false, true  },
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "CUBE_ARRAY_SHADOW", 2, 4, true,  true,  true  },
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { "BUFFER",            1, 1, false, false, false },
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCmpInstruction::CmpInstruction(Function *fn, operation op)
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   : Instruction(fn, op, TYPE_F32)
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setCond = CC_ALWAYS;
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCmpInstruction *
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCmpInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   CmpInstruction *cmp = (i ? static_cast<CmpInstruction *>(i) :
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          new_CmpInstruction(pol.context(), op));
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cmp->dType = dType;
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Instruction::clone(pol, cmp);
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cmp->setCond = setCond;
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return cmp;
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFlowInstruction::FlowInstruction(Function *fn, operation op, void *targ)
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   : Instruction(fn, op, TYPE_NONE)
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op == OP_CALL)
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target.fn = reinterpret_cast<Function *>(targ);
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target.bb = reinterpret_cast<BasicBlock *>(targ);
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op == OP_BRA ||
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       op == OP_CONT || op == OP_BREAK ||
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       op == OP_RET || op == OP_EXIT)
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      terminator = 1;
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op == OP_JOIN)
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      terminator = targ ? 1 : 0;
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   allWarp = absolute = limit = builtin = 0;
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFlowInstruction *
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFlowInstruction::clone(ClonePolicy<Function>& pol, Instruction *i) const
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FlowInstruction *flow = (i ? static_cast<FlowInstruction *>(i) :
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            new_FlowInstruction(pol.context(), op, NULL));
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Instruction::clone(pol, flow);
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flow->allWarp = allWarp;
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flow->absolute = absolute;
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flow->limit = limit;
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flow->builtin = builtin;
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (builtin)
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flow->target.builtin = target.builtin;
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op == OP_CALL)
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flow->target.fn = target.fn;
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (target.bb)
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flow->target.bb = pol.get<BasicBlock>(target.bb);
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return flow;
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgProgram::Program(Type type, Target *arch)
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   : progType(type),
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     target(arch),
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_Instruction(sizeof(Instruction), 6),
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_CmpInstruction(sizeof(CmpInstruction), 4),
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_TexInstruction(sizeof(TexInstruction), 4),
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_FlowInstruction(sizeof(FlowInstruction), 4),
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_LValue(sizeof(LValue), 8),
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_Symbol(sizeof(Symbol), 7),
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mem_ImmediateValue(sizeof(ImmediateValue), 7)
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   code = NULL;
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   binSize = 0;
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   maxGPR = -1;
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   main = new Function(this, "MAIN", ~0);
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   calls.insert(&main->call);
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dbgFlags = 0;
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   optLevel = 0;
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   targetPriv = NULL;
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgProgram::~Program()
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (ArrayList::Iterator it = allFuncs.iterator(); !it.end(); it.next())
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete reinterpret_cast<Function *>(it.get());
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (ArrayList::Iterator it = allRValues.iterator(); !it.end(); it.next())
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      releaseValue(reinterpret_cast<Value *>(it.get()));
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid Program::releaseInstruction(Instruction *insn)
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   // TODO: make this not suck so much
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   insn->~Instruction();
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->asCmp())
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_CmpInstruction.release(insn);
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->asTex())
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_TexInstruction.release(insn);
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->asFlow())
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_FlowInstruction.release(insn);
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_Instruction.release(insn);
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid Program::releaseValue(Value *value)
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   value->~Value();
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value->asLValue())
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_LValue.release(value);
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value->asImm())
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_ImmediateValue.release(value);
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value->asSym())
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mem_Symbol.release(value);
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // namespace nv50_ir
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" {
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_ir_init_prog_info(struct nv50_ir_prog_info *info)
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_SHADER_HULL) && defined(PIPE_SHADER_DOMAIN)
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (info->type == PIPE_SHADER_HULL || info->type == PIPE_SHADER_DOMAIN) {
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info->prop.tp.domain = PIPE_PRIM_MAX;
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info->prop.tp.outputPrim = PIPE_PRIM_MAX;
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (info->type == PIPE_SHADER_GEOMETRY) {
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info->prop.gp.instanceCount = 1;
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info->prop.gp.maxVertices = 1;
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.clipDistance = 0xff;
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.pointSize = 0xff;
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.instanceId = 0xff;
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.vertexId = 0xff;
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.edgeFlagIn = 0xff;
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.edgeFlagOut = 0xff;
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.fragDepth = 0xff;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.sampleMask = 0xff;
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->io.backFaceColor[0] = info->io.backFaceColor[1] = 0xff;
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_ir_generate_code(struct nv50_ir_prog_info *info)
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret = 0;
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_ir::Program::Type type;
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_ir_init_prog_info(info);
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PROG_TYPE_CASE(a, b)                                      \
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SHADER_##a: type = nv50_ir::Program::TYPE_##b; break
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (info->type) {
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PROG_TYPE_CASE(VERTEX, VERTEX);
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// PROG_TYPE_CASE(HULL, TESSELLATION_CONTROL);
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// PROG_TYPE_CASE(DOMAIN, TESSELLATION_EVAL);
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PROG_TYPE_CASE(GEOMETRY, GEOMETRY);
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PROG_TYPE_CASE(FRAGMENT, FRAGMENT);
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = nv50_ir::Program::TYPE_COMPUTE;
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   INFO_DBG(info->dbgFlags, VERBOSE, "translating program of type %u\n", type);
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_ir::Target *targ = nv50_ir::Target::create(info->target);
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!targ)
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -1;
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_ir::Program *prog = new nv50_ir::Program(type, targ);
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!prog)
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -1;
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->dbgFlags = info->dbgFlags;
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->optLevel = info->optLevel;
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (info->bin.sourceRep) {
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_IR_LLVM:
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_IR_GLSL:
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -1;
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_IR_SM4:
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = prog->makeFromSM4(info) ? 0 : -2;
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_IR_TGSI:
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = prog->makeFromTGSI(info) ? 0 : -2;
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ret < 0)
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto out;
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (prog->dbgFlags & NV50_IR_DEBUG_VERBOSE)
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      prog->print();
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   targ->parseDriverInfo(info);
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->getTarget()->runLegalizePass(prog, nv50_ir::CG_STAGE_PRE_SSA);
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->convertToSSA();
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (prog->dbgFlags & NV50_IR_DEBUG_VERBOSE)
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      prog->print();
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->optimizeSSA(info->optLevel);
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->getTarget()->runLegalizePass(prog, nv50_ir::CG_STAGE_SSA);
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (prog->dbgFlags & NV50_IR_DEBUG_BASIC)
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      prog->print();
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!prog->registerAllocation()) {
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = -4;
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto out;
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->getTarget()->runLegalizePass(prog, nv50_ir::CG_STAGE_POST_RA);
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->optimizePostRA(info->optLevel);
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!prog->emitBinary(info)) {
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = -5;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto out;
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout:
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   INFO_DBG(prog->dbgFlags, VERBOSE, "nv50_ir_generate_code: ret = %i\n", ret);
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->bin.maxGPR = prog->maxGPR;
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->bin.code = prog->code;
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->bin.codeSize = prog->binSize;
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info->bin.tlsSpace = prog->tlsSize;
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   delete prog;
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_ir::Target::destroy(targ);
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // extern "C"
1185