gm107/ir: use CS2R for SV_CLOCK
authorRhys Perry <pendingchaos02@gmail.com>
Thu, 19 Jul 2018 15:58:46 +0000 (16:58 +0100)
committerKarol Herbst <kherbst@redhat.com>
Thu, 19 Jul 2018 21:34:58 +0000 (23:34 +0200)
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 <pendingchaos02@gmail.com>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.h

index 694d1b10a3ceae9aa6e05ec948bbbf369a610c7d..1d31f181e441d506c43069345b2ae9f6439e549d 100644 (file)
@@ -124,6 +124,7 @@ private:
 
    void emitMOV();
    void emitS2R();
+   void emitCS2R();
    void emitF2F();
    void emitF2I();
    void emitI2F();
@@ -749,6 +750,14 @@ CodeEmitterGM107::emitS2R()
    emitGPR (0x00, insn->def(0));
 }
 
+void
+CodeEmitterGM107::emitCS2R()
+{
+   emitInsn(0x50c80000);
+   emitSYS (0x14, insn->src(0));
+   emitGPR (0x00, insn->def(0));
+}
+
 void
 CodeEmitterGM107::emitF2F()
 {
@@ -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:
index 04cbd402a1802d74fb295ae55319a2b8293afe29..adbfcc3cfec0e547dcdedddbd26bd81f0f8b0280 100644 (file)
@@ -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:
@@ -321,6 +324,12 @@ TargetGM107::getReadLatency(const Instruction *insn) const
    return 0;
 }
 
+bool
+TargetGM107::isCS2RSV(SVSemantic sv) const
+{
+   return sv == SV_CLOCK;
+}
+
 bool
 TargetGM107::runLegalizePass(Program *prog, CGStage stage) const
 {
index dd4aa6a54d0b6fb2bfafe553ffa236520f3b8fc5..10f06d24f4f545163e65405d3f24e030efe5e7cf 100644 (file)
@@ -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