summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/codegen
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-02-22 20:08:57 +0100
committerChristoph Bumiller <[email protected]>2013-03-12 12:55:34 +0100
commitc893b9406060d3735b2c9e307ae89f6d83a4be40 (patch)
tree0c344d15703274584863ece29a68e36d221df63f /src/gallium/drivers/nv50/codegen
parentefe55075b505e9d96ccde12f789ec8991273aef4 (diff)
nv50/ir: add support for indirect BRA,CALL
Diffstat (limited to 'src/gallium/drivers/nv50/codegen')
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.cpp2
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.h1
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp4
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp9
4 files changed, 12 insertions, 4 deletions
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
index 3121c5ff270..b8476665806 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp
@@ -968,7 +968,7 @@ FlowInstruction::FlowInstruction(Function *fn, operation op, void *targ)
if (op == OP_JOIN)
terminator = targ ? 1 : 0;
- allWarp = absolute = limit = builtin = 0;
+ allWarp = absolute = limit = builtin = indirect = 0;
}
FlowInstruction *
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.h b/src/gallium/drivers/nv50/codegen/nv50_ir.h
index ae577cc4209..47562beb2fd 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.h
@@ -918,6 +918,7 @@ public:
unsigned absolute : 1;
unsigned limit : 1;
unsigned builtin : 1; // true for calls to emulation code
+ unsigned indirect : 1; // target in src(0)
union {
BasicBlock *bb;
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp
index 48ade15842d..00a80544c17 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp
@@ -500,6 +500,10 @@ void Instruction::print() const
if (asFlow()) {
PRINT("%s", operationStr[op]);
+ if (asFlow()->indirect)
+ PRINT(" ind");
+ if (asFlow()->absolute)
+ PRINT(" abs");
if (op == OP_CALL && asFlow()->builtin) {
PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin);
} else
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp
index e0fea4b9337..ed991dac30b 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp
@@ -409,14 +409,17 @@ RegAlloc::ArgumentMovesPass::visit(BasicBlock *bb)
// conflict arises.
for (Instruction *i = bb->getEntry(); i; i = i->next) {
FlowInstruction *cal = i->asFlow();
- if (!cal || cal->op != OP_CALL || cal->builtin)
+ // TODO: Handle indirect calls.
+ // Right now they should only be generated for builtins.
+ if (!cal || cal->op != OP_CALL || cal->builtin || cal->indirect)
continue;
RegisterSet clobberSet(prog->getTarget());
// Bind input values.
- for (int s = 0; cal->srcExists(s); ++s) {
+ for (int s = cal->indirect ? 1 : 0; cal->srcExists(s); ++s) {
+ const int t = cal->indirect ? (s - 1) : s;
LValue *tmp = new_LValue(func, cal->getSrc(s)->asLValue());
- tmp->reg.data.id = cal->target.fn->ins[s].rep()->reg.data.id;
+ tmp->reg.data.id = cal->target.fn->ins[t].rep()->reg.data.id;
Instruction *mov =
new_Instruction(func, OP_MOV, typeOfSize(tmp->reg.size));