From 9915af5ca17f94f58135413cd8034b4733c0abb4 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Thu, 30 Jan 2020 11:41:34 +0000 Subject: [PATCH] aco: print and validate opsel MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Reviewed-By: Timur Kristóf Part-of: --- src/amd/compiler/aco_print_ir.cpp | 13 +++++++++++-- src/amd/compiler/aco_validate.cpp | 7 +++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/amd/compiler/aco_print_ir.cpp b/src/amd/compiler/aco_print_ir.cpp index 43afe0a77c0..0f607fe3f68 100644 --- a/src/amd/compiler/aco_print_ir.cpp +++ b/src/amd/compiler/aco_print_ir.cpp @@ -490,6 +490,8 @@ static void print_instr_format_specific(struct Instruction *instr, FILE *output) } if (vop3->clamp) fprintf(output, " clamp"); + if (vop3->opsel & (1 << 3)) + fprintf(output, " opsel_hi"); } else if (instr->isDPP()) { DPP_instruction* dpp = static_cast(instr); if (dpp->dpp_ctrl <= 0xff) { @@ -577,12 +579,14 @@ void aco_print_instr(struct Instruction *instr, FILE *output) if (instr->operands.size()) { bool abs[instr->operands.size()]; bool neg[instr->operands.size()]; + bool opsel[instr->operands.size()]; uint8_t sel[instr->operands.size()]; if ((int)instr->format & (int)Format::VOP3A) { VOP3A_instruction* vop3 = static_cast(instr); for (unsigned i = 0; i < instr->operands.size(); ++i) { abs[i] = vop3->abs[i]; neg[i] = vop3->neg[i]; + opsel[i] = vop3->opsel & (1 << i); sel[i] = sdwa_udword; } } else if (instr->isDPP()) { @@ -590,6 +594,7 @@ void aco_print_instr(struct Instruction *instr, FILE *output) for (unsigned i = 0; i < instr->operands.size(); ++i) { abs[i] = i < 2 ? dpp->abs[i] : false; neg[i] = i < 2 ? dpp->neg[i] : false; + opsel[i] = false; sel[i] = sdwa_udword; } } else if (instr->isSDWA()) { @@ -597,12 +602,14 @@ void aco_print_instr(struct Instruction *instr, FILE *output) for (unsigned i = 0; i < instr->operands.size(); ++i) { abs[i] = i < 2 ? sdwa->abs[i] : false; neg[i] = i < 2 ? sdwa->neg[i] : false; + opsel[i] = false; sel[i] = i < 2 ? sdwa->sel[i] : sdwa_udword; } } else { for (unsigned i = 0; i < instr->operands.size(); ++i) { abs[i] = false; neg[i] = false; + opsel[i] = false; sel[i] = sdwa_udword; } } @@ -616,10 +623,12 @@ void aco_print_instr(struct Instruction *instr, FILE *output) fprintf(output, "-"); if (abs[i]) fprintf(output, "|"); - if (sel[i] & sdwa_sext) + if (opsel[i]) + fprintf(output, "hi("); + else if (sel[i] & sdwa_sext) fprintf(output, "sext("); print_operand(&instr->operands[i], output); - if (sel[i] & sdwa_sext) + if (opsel[i] || (sel[i] & sdwa_sext)) fprintf(output, ")"); if ((sel[i] & sdwa_asuint) == sdwa_udword) { /* print nothing */ diff --git a/src/amd/compiler/aco_validate.cpp b/src/amd/compiler/aco_validate.cpp index 4bbce14a86a..dd13fa34ed6 100644 --- a/src/amd/compiler/aco_validate.cpp +++ b/src/amd/compiler/aco_validate.cpp @@ -137,6 +137,13 @@ void validate(Program* program, FILE * output) } } + /* check opsel */ + if (instr->isVOP3()) { + VOP3A_instruction *vop3 = static_cast(instr.get()); + check(vop3->opsel == 0 || program->chip_class >= GFX9, "Opsel is only supported on GFX9+", instr.get()); + check((vop3->opsel & ~(0x10 | ((1 << instr->operands.size()) - 1))) == 0, "Unused bits in opsel must be zeroed out", instr.get()); + } + /* check for undefs */ for (unsigned i = 0; i < instr->operands.size(); i++) { if (instr->operands[i].isUndefined()) { -- 2.30.2