diff options
-rw-r--r-- | src/gallium/drivers/nv50/codegen/nv50_ir.cpp | 45 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/codegen/nv50_ir.h | 2 |
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]; } |