aco: emit v_interp_*_f16 instructions as VOP3 instead of VINTRP
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 8 May 2020 14:21:07 +0000 (16:21 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 19 May 2020 17:05:05 +0000 (17:05 +0000)
This adds a separate emission path in the assembly for the 16-bit
interp instructions.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4966>

src/amd/compiler/aco_assembler.cpp

index ed2e3982976493ac4062151b0c25708d008dbde3..bac91c899e77a0a8fbaca491c5982d4d404cfb83 100644 (file)
@@ -274,22 +274,50 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
       Interp_instruction* interp = static_cast<Interp_instruction*>(instr);
       uint32_t encoding = 0;
 
-      if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) {
-         encoding = (0b110101 << 26); /* Vega ISA doc says 110010 but it's wrong */
+      if (instr->opcode == aco_opcode::v_interp_p1ll_f16 ||
+          instr->opcode == aco_opcode::v_interp_p1lv_f16 ||
+          instr->opcode == aco_opcode::v_interp_p2_legacy_f16 ||
+          instr->opcode == aco_opcode::v_interp_p2_f16) {
+         if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) {
+            encoding = (0b110100 << 26);
+         } else if (ctx.chip_class == GFX10) {
+            encoding = (0b110101 << 26);
+         } else {
+            unreachable("Unknown chip_class.");
+         }
+
+         encoding |= opcode << 16;
+         encoding |= (0xFF & instr->definitions[0].physReg());
+         out.push_back(encoding);
+
+         encoding = 0;
+         encoding |= interp->attribute;
+         encoding |= interp->component << 6;
+         encoding |= instr->operands[0].physReg() << 9;
+         if (instr->opcode == aco_opcode::v_interp_p2_f16 ||
+             instr->opcode == aco_opcode::v_interp_p2_legacy_f16 ||
+             instr->opcode == aco_opcode::v_interp_p1lv_f16) {
+            encoding |= instr->operands[2].physReg() << 18;
+         }
+         out.push_back(encoding);
       } else {
-         encoding = (0b110010 << 26);
-      }
+         if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) {
+            encoding = (0b110101 << 26); /* Vega ISA doc says 110010 but it's wrong */
+         } else {
+            encoding = (0b110010 << 26);
+         }
 
-      assert(encoding);
-      encoding |= (0xFF & instr->definitions[0].physReg()) << 18;
-      encoding |= opcode << 16;
-      encoding |= interp->attribute << 10;
-      encoding |= interp->component << 8;
-      if (instr->opcode == aco_opcode::v_interp_mov_f32)
-         encoding |= (0x3 & instr->operands[0].constantValue());
-      else
-         encoding |= (0xFF & instr->operands[0].physReg());
-      out.push_back(encoding);
+         assert(encoding);
+         encoding |= (0xFF & instr->definitions[0].physReg()) << 18;
+         encoding |= opcode << 16;
+         encoding |= interp->attribute << 10;
+         encoding |= interp->component << 8;
+         if (instr->opcode == aco_opcode::v_interp_mov_f32)
+            encoding |= (0x3 & instr->operands[0].constantValue());
+         else
+            encoding |= (0xFF & instr->operands[0].physReg());
+         out.push_back(encoding);
+      }
       break;
    }
    case Format::DS: {