diff options
author | Ilia Mirkin <[email protected]> | 2014-04-26 18:44:19 -0400 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2014-04-28 19:05:16 -0400 |
commit | 46364a53ef30e5c97e1eeb5a879dd99a47415b73 (patch) | |
tree | 35659cdb9cfd71c55c904e4bd17e11cd168145fb /src/gallium/drivers/nouveau/codegen | |
parent | 1c85177419300631ee413b7563cdc1b3eab7c1cc (diff) |
nvc0/ir: do constant folding of extbf/insbf
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index fb82c72f6bc..c89e1c34e2b 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -241,6 +241,7 @@ private: virtual bool visit(BasicBlock *); void expr(Instruction *, ImmediateValue&, ImmediateValue&); + void expr(Instruction *, ImmediateValue&, ImmediateValue&, ImmediateValue&); void opnd(Instruction *, ImmediateValue&, int s); void unary(Instruction *, const ImmediateValue&); @@ -278,8 +279,14 @@ ConstantFolding::visit(BasicBlock *bb) if (i->op == OP_MOV || i->op == OP_CALL) continue; - ImmediateValue src0, src1; + ImmediateValue src0, src1, src2; + if (i->srcExists(2) && + i->src(0).getImmediate(src0) && + i->src(1).getImmediate(src1) && + i->src(2).getImmediate(src2)) + expr(i, src0, src1, src2); + else if (i->srcExists(1) && i->src(0).getImmediate(src0) && i->src(1).getImmediate(src1)) expr(i, src0, src1); @@ -497,6 +504,27 @@ ConstantFolding::expr(Instruction *i, return; res.data.u32 = a->data.u32; break; + case OP_EXTBF: { + int offset = b->data.u32 & 0xff; + int width = (b->data.u32 >> 8) & 0xff; + int rshift = offset; + int lshift = 0; + if (width == 0) { + res.data.u32 = 0; + break; + } + if (width + offset < 32) { + rshift = 32 - width; + lshift = 32 - width - offset; + } + switch (i->dType) { + case TYPE_S32: res.data.s32 = (a->data.s32 << lshift) >> rshift; break; + case TYPE_U32: res.data.u32 = (a->data.u32 << lshift) >> rshift; break; + default: + return; + } + break; + } default: return; } @@ -527,6 +555,43 @@ ConstantFolding::expr(Instruction *i, } void +ConstantFolding::expr(Instruction *i, + ImmediateValue &imm0, + ImmediateValue &imm1, + ImmediateValue &imm2) +{ + struct Storage *const a = &imm0.reg, *const b = &imm1.reg, *const c = &imm2.reg; + struct Storage res; + + memset(&res.data, 0, sizeof(res.data)); + + switch (i->op) { + case OP_INSBF: { + int offset = b->data.u32 & 0xff; + int width = (b->data.u32 >> 8) & 0xff; + unsigned bitmask = ((1 << width) - 1) << offset; + res.data.u32 = ((a->data.u32 << offset) & bitmask) | (c->data.u32 & ~bitmask); + break; + } + default: + return; + } + + ++foldCount; + i->src(0).mod = Modifier(0); + i->src(1).mod = Modifier(0); + i->src(2).mod = Modifier(0); + + i->setSrc(0, new_ImmediateValue(i->bb->getProgram(), res.data.u32)); + i->setSrc(1, NULL); + i->setSrc(2, NULL); + + i->getSrc(0)->reg.data = res.data; + + i->op = OP_MOV; +} + +void ConstantFolding::unary(Instruction *i, const ImmediateValue &imm) { Storage res; |