From 3b6edd0b591378bba5c369b13a650239c1cf0e6f Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Thu, 19 Jul 2018 16:58:46 +0100 Subject: [PATCH] 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 Reviewed-by: Karol Herbst --- src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 14 +++++++++++++- .../drivers/nouveau/codegen/nv50_ir_target_gm107.cpp | 11 ++++++++++- src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.h | 2 ++ 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 694d1b1..1d31f18 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 04cbd40..adbfcc3 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 dd4aa6a..10f06d2 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 -- 2.7.4