summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.cpp45
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.h2
2 files changed, 31 insertions, 16 deletions
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
index b8476665806..6a391211dc9 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
@@ -661,29 +661,44 @@ Instruction::swapSources(int a, int b)
srcs[b].mod = m;
}
-// TODO: extend for delta < 0
+static inline void moveSourcesAdjustIndex(int8_t &index, int s, int delta)
+{
+ if (index >= s)
+ index += delta;
+ else
+ if ((delta < 0) && (index >= (s + delta)))
+ index = -1;
+}
+
+// Moves sources [@s,last_source] by @delta.
+// If @delta < 0, sources [@s - abs(@delta), @s) are erased.
void
-Instruction::moveSources(int s, int delta)
+Instruction::moveSources(const int s, const int delta)
{
if (delta == 0)
return;
- assert(delta > 0);
+ assert(s + delta >= 0);
int k;
+
for (k = 0; srcExists(k); ++k) {
- for (int i = 0; i < 2; ++i) {
- if (src(k).indirect[i] >= s)
- src(k).indirect[i] += delta;
- }
+ for (int i = 0; i < 2; ++i)
+ moveSourcesAdjustIndex(src(k).indirect[i], s, delta);
+ }
+ moveSourcesAdjustIndex(predSrc, s, delta);
+ moveSourcesAdjustIndex(flagsSrc, s, delta);
+
+ if (delta > 0) {
+ --k;
+ for (int p = k + delta; k >= s; --k, --p)
+ setSrc(p, src(k));
+ } else {
+ int p;
+ for (p = s; p < k; ++p)
+ setSrc(p + delta, src(p));
+ for (; (p + delta) < k; ++p)
+ setSrc(p + delta, NULL);
}
- if (predSrc >= s)
- predSrc += delta;
- if (flagsSrc >= s)
- flagsSrc += delta;
-
- --k;
- for (int p = k + delta; k >= s; --k, --p)
- setSrc(p, src(k));
}
void
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.h b/src/gallium/drivers/nv50/codegen/nv50_ir.h
index 47562beb2fd..637196e4518 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.h
@@ -677,7 +677,7 @@ public:
void setSrc(int s, Value *);
void setSrc(int s, const ValueRef&);
void swapSources(int a, int b);
- void moveSources(int s, int delta); // NOTE: only delta > 0 implemented
+ void moveSources(int s, int delta);
bool setIndirect(int s, int dim, Value *);
inline ValueRef& src(int s) { return srcs[s]; }