diff --git a/src/amd/compiler/aco_insert_waitcnt.cpp b/src/amd/compiler/aco_insert_waitcnt.cpp index 43c95ebb3eb..4f59f7cdaa7 100644 --- a/src/amd/compiler/aco_insert_waitcnt.cpp +++ b/src/amd/compiler/aco_insert_waitcnt.cpp @@ -123,78 +123,6 @@ uint16_t get_events_for_counter(counter_type ctr) return 0; } -struct wait_imm { - static const uint8_t unset_counter = 0xff; - - uint8_t vm; - uint8_t exp; - uint8_t lgkm; - uint8_t vs; - - wait_imm() : - vm(unset_counter), exp(unset_counter), lgkm(unset_counter), vs(unset_counter) {} - wait_imm(uint16_t vm_, uint16_t exp_, uint16_t lgkm_, uint16_t vs_) : - vm(vm_), exp(exp_), lgkm(lgkm_), vs(vs_) {} - - wait_imm(enum chip_class chip, uint16_t packed) : vs(unset_counter) - { - vm = packed & 0xf; - if (chip >= GFX9) - vm |= (packed >> 10) & 0x30; - - exp = (packed >> 4) & 0x7; - - lgkm = (packed >> 8) & 0xf; - if (chip >= GFX10) - lgkm |= (packed >> 8) & 0x30; - } - - uint16_t pack(enum chip_class chip) const - { - uint16_t imm = 0; - assert(exp == unset_counter || exp <= 0x7); - switch (chip) { - case GFX10: - case GFX10_3: - assert(lgkm == unset_counter || lgkm <= 0x3f); - assert(vm == unset_counter || vm <= 0x3f); - imm = ((vm & 0x30) << 10) | ((lgkm & 0x3f) << 8) | ((exp & 0x7) << 4) | (vm & 0xf); - break; - case GFX9: - assert(lgkm == unset_counter || lgkm <= 0xf); - assert(vm == unset_counter || vm <= 0x3f); - imm = ((vm & 0x30) << 10) | ((lgkm & 0xf) << 8) | ((exp & 0x7) << 4) | (vm & 0xf); - break; - default: - assert(lgkm == unset_counter || lgkm <= 0xf); - assert(vm == unset_counter || vm <= 0xf); - imm = ((lgkm & 0xf) << 8) | ((exp & 0x7) << 4) | (vm & 0xf); - break; - } - if (chip < GFX9 && vm == wait_imm::unset_counter) - imm |= 0xc000; /* should have no effect on pre-GFX9 and now we won't have to worry about the architecture when interpreting the immediate */ - if (chip < GFX10 && lgkm == wait_imm::unset_counter) - imm |= 0x3000; /* should have no effect on pre-GFX10 and now we won't have to worry about the architecture when interpreting the immediate */ - return imm; - } - - bool combine(const wait_imm& other) - { - bool changed = other.vm < vm || other.exp < exp || other.lgkm < lgkm || other.vs < vs; - vm = std::min(vm, other.vm); - exp = std::min(exp, other.exp); - lgkm = std::min(lgkm, other.lgkm); - vs = std::min(vs, other.vs); - return changed; - } - - bool empty() const - { - return vm == unset_counter && exp == unset_counter && - lgkm == unset_counter && vs == unset_counter; - } -}; - struct wait_entry { wait_imm imm; uint16_t events; /* use wait_event notion */ diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index 3525433dfa5..12c5f6d43a8 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -477,4 +477,67 @@ bool needs_exec_mask(const Instruction* instr) { return true; } +wait_imm::wait_imm() : + vm(unset_counter), exp(unset_counter), lgkm(unset_counter), vs(unset_counter) {} +wait_imm::wait_imm(uint16_t vm_, uint16_t exp_, uint16_t lgkm_, uint16_t vs_) : + vm(vm_), exp(exp_), lgkm(lgkm_), vs(vs_) {} + +wait_imm::wait_imm(enum chip_class chip, uint16_t packed) : vs(unset_counter) +{ + vm = packed & 0xf; + if (chip >= GFX9) + vm |= (packed >> 10) & 0x30; + + exp = (packed >> 4) & 0x7; + + lgkm = (packed >> 8) & 0xf; + if (chip >= GFX10) + lgkm |= (packed >> 8) & 0x30; +} + +uint16_t wait_imm::pack(enum chip_class chip) const +{ + uint16_t imm = 0; + assert(exp == unset_counter || exp <= 0x7); + switch (chip) { + case GFX10: + case GFX10_3: + assert(lgkm == unset_counter || lgkm <= 0x3f); + assert(vm == unset_counter || vm <= 0x3f); + imm = ((vm & 0x30) << 10) | ((lgkm & 0x3f) << 8) | ((exp & 0x7) << 4) | (vm & 0xf); + break; + case GFX9: + assert(lgkm == unset_counter || lgkm <= 0xf); + assert(vm == unset_counter || vm <= 0x3f); + imm = ((vm & 0x30) << 10) | ((lgkm & 0xf) << 8) | ((exp & 0x7) << 4) | (vm & 0xf); + break; + default: + assert(lgkm == unset_counter || lgkm <= 0xf); + assert(vm == unset_counter || vm <= 0xf); + imm = ((lgkm & 0xf) << 8) | ((exp & 0x7) << 4) | (vm & 0xf); + break; + } + if (chip < GFX9 && vm == wait_imm::unset_counter) + imm |= 0xc000; /* should have no effect on pre-GFX9 and now we won't have to worry about the architecture when interpreting the immediate */ + if (chip < GFX10 && lgkm == wait_imm::unset_counter) + imm |= 0x3000; /* should have no effect on pre-GFX10 and now we won't have to worry about the architecture when interpreting the immediate */ + return imm; +} + +bool wait_imm::combine(const wait_imm& other) +{ + bool changed = other.vm < vm || other.exp < exp || other.lgkm < lgkm || other.vs < vs; + vm = std::min(vm, other.vm); + exp = std::min(exp, other.exp); + lgkm = std::min(lgkm, other.lgkm); + vs = std::min(vs, other.vs); + return changed; +} + +bool wait_imm::empty() const +{ + return vm == unset_counter && exp == unset_counter && + lgkm == unset_counter && vs == unset_counter; +} + } diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 7d8e3cec64b..246a0f9bb58 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -233,6 +233,25 @@ struct float_mode { } }; +struct wait_imm { + static const uint8_t unset_counter = 0xff; + + uint8_t vm; + uint8_t exp; + uint8_t lgkm; + uint8_t vs; + + wait_imm(); + wait_imm(uint16_t vm_, uint16_t exp_, uint16_t lgkm_, uint16_t vs_); + wait_imm(enum chip_class chip, uint16_t packed); + + uint16_t pack(enum chip_class chip) const; + + bool combine(const wait_imm& other); + + bool empty() const; +}; + constexpr Format asVOP3(Format format) { return (Format) ((uint32_t) Format::VOP3 | (uint32_t) format); };