diff options
author | Rhys Perry <[email protected]> | 2018-07-19 16:58:46 +0100 |
---|---|---|
committer | Karol Herbst <[email protected]> | 2018-07-19 23:34:58 +0200 |
commit | 3b6edd0b591378bba5c369b13a650239c1cf0e6f (patch) | |
tree | 4a4aa41242e4d851329757c964a94658924e3401 | |
parent | 94cf96458604d4b0f59b200c77ba5f32adbcc669 (diff) |
gm107/ir: use CS2R for SV_CLOCK
This instruction seems to be faster than S2R and requires no barrier,
though the range of special registers it can read from is limited.
Signed-off-by: Rhys Perry <[email protected]>
Reviewed-by: Karol Herbst <[email protected]>
3 files changed, 25 insertions, 2 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp index 694d1b10a3c..1d31f181e44 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -124,6 +124,7 @@ private: void emitMOV(); void emitS2R(); + void emitCS2R(); void emitF2F(); void emitF2I(); void emitI2F(); @@ -750,6 +751,14 @@ CodeEmitterGM107::emitS2R() } void +CodeEmitterGM107::emitCS2R() +{ + emitInsn(0x50c80000); + emitSYS (0x14, insn->src(0)); + emitGPR (0x00, insn->def(0)); +} + +void CodeEmitterGM107::emitF2F() { RoundMode rnd = insn->rnd; @@ -3192,7 +3201,10 @@ CodeEmitterGM107::emitInstruction(Instruction *i) emitMOV(); break; case OP_RDSV: - emitS2R(); + if (targGM107->isCS2RSV(insn->getSrc(0)->reg.data.sv.sv)) + emitCS2R(); + else + emitS2R(); break; case OP_ABS: case OP_NEG: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp index 04cbd402a18..adbfcc3cfec 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp @@ -153,9 +153,10 @@ TargetGM107::isBarrierRequired(const Instruction *insn) const case OP_AFETCH: case OP_PFETCH: case OP_PIXLD: - case OP_RDSV: case OP_SHFL: return true; + case OP_RDSV: + return !isCS2RSV(insn->getSrc(0)->reg.data.sv.sv); default: break; } @@ -232,6 +233,8 @@ TargetGM107::getLatency(const Instruction *insn) const if (insn->dType != TYPE_F64) return 6; break; + case OP_RDSV: + return isCS2RSV(insn->getSrc(0)->reg.data.sv.sv) ? 6 : 15; case OP_ABS: case OP_CEIL: case OP_CVT: @@ -322,6 +325,12 @@ TargetGM107::getReadLatency(const Instruction *insn) const } bool +TargetGM107::isCS2RSV(SVSemantic sv) const +{ + return sv == SV_CLOCK; +} + +bool TargetGM107::runLegalizePass(Program *prog, CGStage stage) const { if (stage == CG_STAGE_PRE_SSA) { diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.h index dd4aa6a54d0..10f06d24f4f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.h @@ -23,6 +23,8 @@ public: virtual bool canDualIssue(const Instruction *, const Instruction *) const; virtual int getLatency(const Instruction *) const; virtual int getReadLatency(const Instruction *) const; + + virtual bool isCS2RSV(SVSemantic) const; }; } // namespace nv50_ir |