aco: unify different SALU types into single struct SALU_instruction
This removes - SOP1_instruction - SOP2_instruction - SOPC_instruction - SOPK_instruction - SOPP_instruction and their corresponding methods. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28370>
This commit is contained in:

committed by
Marge Bot

parent
5d265257a0
commit
1187189235
@@ -44,7 +44,7 @@ struct constaddr_info {
|
|||||||
struct asm_context {
|
struct asm_context {
|
||||||
Program* program;
|
Program* program;
|
||||||
enum amd_gfx_level gfx_level;
|
enum amd_gfx_level gfx_level;
|
||||||
std::vector<std::pair<int, SOPP_instruction*>> branches;
|
std::vector<std::pair<int, SALU_instruction*>> branches;
|
||||||
std::map<unsigned, constaddr_info> constaddrs;
|
std::map<unsigned, constaddr_info> constaddrs;
|
||||||
std::map<unsigned, constaddr_info> resumeaddrs;
|
std::map<unsigned, constaddr_info> resumeaddrs;
|
||||||
std::vector<struct aco_symbol>* symbols;
|
std::vector<struct aco_symbol>* symbols;
|
||||||
@@ -155,7 +155,8 @@ void
|
|||||||
emit_sopk_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction* instr)
|
emit_sopk_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction* instr)
|
||||||
{
|
{
|
||||||
uint32_t opcode = ctx.opcode[(int)instr->opcode];
|
uint32_t opcode = ctx.opcode[(int)instr->opcode];
|
||||||
SOPK_instruction& sopk = instr->sopk();
|
SALU_instruction& sopk = instr->salu();
|
||||||
|
assert(sopk.imm <= UINT16_MAX);
|
||||||
|
|
||||||
if (instr->opcode == aco_opcode::s_subvector_loop_begin) {
|
if (instr->opcode == aco_opcode::s_subvector_loop_begin) {
|
||||||
assert(ctx.gfx_level >= GFX10);
|
assert(ctx.gfx_level >= GFX10);
|
||||||
@@ -211,7 +212,7 @@ emit_sopp_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
|
|||||||
bool force_imm = false)
|
bool force_imm = false)
|
||||||
{
|
{
|
||||||
uint32_t opcode = ctx.opcode[(int)instr->opcode];
|
uint32_t opcode = ctx.opcode[(int)instr->opcode];
|
||||||
SOPP_instruction& sopp = instr->sopp();
|
SALU_instruction& sopp = instr->salu();
|
||||||
|
|
||||||
uint32_t encoding = (0b101111111 << 23);
|
uint32_t encoding = (0b101111111 << 23);
|
||||||
encoding |= opcode << 16;
|
encoding |= opcode << 16;
|
||||||
@@ -1316,7 +1317,7 @@ fix_branches_gfx10(asm_context& ctx, std::vector<uint32_t>& out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
emit_long_jump(asm_context& ctx, SOPP_instruction* branch, bool backwards,
|
emit_long_jump(asm_context& ctx, SALU_instruction* branch, bool backwards,
|
||||||
std::vector<uint32_t>& out)
|
std::vector<uint32_t>& out)
|
||||||
{
|
{
|
||||||
Builder bld(ctx.program);
|
Builder bld(ctx.program);
|
||||||
@@ -1384,7 +1385,7 @@ fix_branches(asm_context& ctx, std::vector<uint32_t>& out)
|
|||||||
if (ctx.gfx_level == GFX10)
|
if (ctx.gfx_level == GFX10)
|
||||||
fix_branches_gfx10(ctx, out);
|
fix_branches_gfx10(ctx, out);
|
||||||
|
|
||||||
for (std::pair<int, SOPP_instruction*>& branch : ctx.branches) {
|
for (std::pair<int, SALU_instruction*>& branch : ctx.branches) {
|
||||||
int offset = (int)ctx.program->blocks[branch.second->imm].offset - branch.first - 1;
|
int offset = (int)ctx.program->blocks[branch.second->imm].offset - branch.first - 1;
|
||||||
if ((offset < INT16_MIN || offset > INT16_MAX) && !branch.second->pass_flags) {
|
if ((offset < INT16_MIN || offset > INT16_MAX) && !branch.second->pass_flags) {
|
||||||
std::vector<uint32_t> long_jump;
|
std::vector<uint32_t> long_jump;
|
||||||
@@ -1461,7 +1462,7 @@ align_block(asm_context& ctx, std::vector<uint32_t>& code, Block& block)
|
|||||||
insert_code(ctx, code, loop_header->offset, nops.size(), nops.data());
|
insert_code(ctx, code, loop_header->offset, nops.size(), nops.data());
|
||||||
|
|
||||||
/* Change prefetch mode back to default (0x3). */
|
/* Change prefetch mode back to default (0x3). */
|
||||||
instr->sopp().imm = 0x3;
|
instr->salu().imm = 0x3;
|
||||||
emit_instruction(ctx, code, instr.get());
|
emit_instruction(ctx, code, instr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -566,11 +566,11 @@ public:
|
|||||||
<%
|
<%
|
||||||
import itertools
|
import itertools
|
||||||
formats = [("pseudo", [Format.PSEUDO], 'Pseudo_instruction', list(itertools.product(range(5), range(6))) + [(8, 1), (1, 8), (2, 6), (3, 6), (1, 6)]),
|
formats = [("pseudo", [Format.PSEUDO], 'Pseudo_instruction', list(itertools.product(range(5), range(6))) + [(8, 1), (1, 8), (2, 6), (3, 6), (1, 6)]),
|
||||||
("sop1", [Format.SOP1], 'SOP1_instruction', [(0, 1), (1, 0), (1, 1), (2, 1), (3, 2)]),
|
("sop1", [Format.SOP1], 'SALU_instruction', [(0, 1), (1, 0), (1, 1), (2, 1), (3, 2)]),
|
||||||
("sop2", [Format.SOP2], 'SOP2_instruction', itertools.product([1, 2], [2, 3])),
|
("sop2", [Format.SOP2], 'SALU_instruction', itertools.product([1, 2], [2, 3])),
|
||||||
("sopk", [Format.SOPK], 'SOPK_instruction', itertools.product([0, 1, 2], [0, 1])),
|
("sopk", [Format.SOPK], 'SALU_instruction', itertools.product([0, 1, 2], [0, 1])),
|
||||||
("sopp", [Format.SOPP], 'SOPP_instruction', itertools.product([0, 1], [0, 1])),
|
("sopp", [Format.SOPP], 'SALU_instruction', itertools.product([0, 1], [0, 1])),
|
||||||
("sopc", [Format.SOPC], 'SOPC_instruction', [(1, 2)]),
|
("sopc", [Format.SOPC], 'SALU_instruction', [(1, 2)]),
|
||||||
("smem", [Format.SMEM], 'SMEM_instruction', [(0, 4), (0, 3), (1, 0), (1, 3), (1, 2), (1, 1), (0, 0)]),
|
("smem", [Format.SMEM], 'SMEM_instruction', [(0, 4), (0, 3), (1, 0), (1, 3), (1, 2), (1, 1), (0, 0)]),
|
||||||
("ds", [Format.DS], 'DS_instruction', [(1, 1), (1, 2), (1, 3), (0, 3), (0, 4)]),
|
("ds", [Format.DS], 'DS_instruction', [(1, 1), (1, 2), (1, 3), (0, 3), (0, 4)]),
|
||||||
("ldsdir", [Format.LDSDIR], 'LDSDIR_instruction', [(1, 1)]),
|
("ldsdir", [Format.LDSDIR], 'LDSDIR_instruction', [(1, 1)]),
|
||||||
|
@@ -313,7 +313,7 @@ int
|
|||||||
get_wait_states(aco_ptr<Instruction>& instr)
|
get_wait_states(aco_ptr<Instruction>& instr)
|
||||||
{
|
{
|
||||||
if (instr->opcode == aco_opcode::s_nop)
|
if (instr->opcode == aco_opcode::s_nop)
|
||||||
return instr->sopp().imm + 1;
|
return instr->salu().imm + 1;
|
||||||
else if (instr->opcode == aco_opcode::p_constaddr)
|
else if (instr->opcode == aco_opcode::p_constaddr)
|
||||||
return 3; /* lowered to 3 instructions in the assembler */
|
return 3; /* lowered to 3 instructions in the assembler */
|
||||||
else
|
else
|
||||||
@@ -611,8 +611,8 @@ handle_instruction_gfx6(State& state, NOP_ctx_gfx6& ctx, aco_ptr<Instruction>& i
|
|||||||
// TODO: try to schedule the NOP-causing instruction up to reduce the number of stall cycles
|
// TODO: try to schedule the NOP-causing instruction up to reduce the number of stall cycles
|
||||||
if (NOPs) {
|
if (NOPs) {
|
||||||
/* create NOP */
|
/* create NOP */
|
||||||
aco_ptr<SOPP_instruction> nop{
|
aco_ptr<SALU_instruction> nop{
|
||||||
create_instruction<SOPP_instruction>(aco_opcode::s_nop, Format::SOPP, 0, 0)};
|
create_instruction<SALU_instruction>(aco_opcode::s_nop, Format::SOPP, 0, 0)};
|
||||||
nop->imm = NOPs - 1;
|
nop->imm = NOPs - 1;
|
||||||
new_instructions.emplace_back(std::move(nop));
|
new_instructions.emplace_back(std::move(nop));
|
||||||
}
|
}
|
||||||
@@ -668,7 +668,7 @@ handle_instruction_gfx6(State& state, NOP_ctx_gfx6& ctx, aco_ptr<Instruction>& i
|
|||||||
}
|
}
|
||||||
} else if (instr->opcode == aco_opcode::s_setreg_b32 ||
|
} else if (instr->opcode == aco_opcode::s_setreg_b32 ||
|
||||||
instr->opcode == aco_opcode::s_setreg_imm32_b32) {
|
instr->opcode == aco_opcode::s_setreg_imm32_b32) {
|
||||||
SOPK_instruction& sopk = instr->sopk();
|
SALU_instruction& sopk = instr->salu();
|
||||||
unsigned offset = (sopk.imm >> 6) & 0x1f;
|
unsigned offset = (sopk.imm >> 6) & 0x1f;
|
||||||
unsigned size = ((sopk.imm >> 11) & 0x1f) + 1;
|
unsigned size = ((sopk.imm >> 11) & 0x1f) + 1;
|
||||||
unsigned reg = sopk.imm & 0x3f;
|
unsigned reg = sopk.imm & 0x3f;
|
||||||
@@ -900,8 +900,8 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr<Instruction>&
|
|||||||
vm_vsrc = 0;
|
vm_vsrc = 0;
|
||||||
sa_sdst = 0;
|
sa_sdst = 0;
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt_depctr) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt_depctr) {
|
||||||
vm_vsrc = (instr->sopp().imm >> 2) & 0x7;
|
vm_vsrc = (instr->salu().imm >> 2) & 0x7;
|
||||||
sa_sdst = instr->sopp().imm & 0x1;
|
sa_sdst = instr->salu().imm & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VMEMtoScalarWriteHazard
|
/* VMEMtoScalarWriteHazard
|
||||||
@@ -918,12 +918,12 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr<Instruction>&
|
|||||||
mark_read_regs_exec(state, instr, ctx.sgprs_read_by_DS);
|
mark_read_regs_exec(state, instr, ctx.sgprs_read_by_DS);
|
||||||
} else if (instr->isSALU() || instr->isSMEM()) {
|
} else if (instr->isSALU() || instr->isSMEM()) {
|
||||||
if (instr->opcode == aco_opcode::s_waitcnt) {
|
if (instr->opcode == aco_opcode::s_waitcnt) {
|
||||||
wait_imm imm(state.program->gfx_level, instr->sopp().imm);
|
wait_imm imm(state.program->gfx_level, instr->salu().imm);
|
||||||
if (imm.vm == 0)
|
if (imm.vm == 0)
|
||||||
ctx.sgprs_read_by_VMEM.reset();
|
ctx.sgprs_read_by_VMEM.reset();
|
||||||
if (imm.lgkm == 0)
|
if (imm.lgkm == 0)
|
||||||
ctx.sgprs_read_by_DS.reset();
|
ctx.sgprs_read_by_DS.reset();
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->sopk().imm == 0) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->salu().imm == 0) {
|
||||||
ctx.sgprs_read_by_VMEM_store.reset();
|
ctx.sgprs_read_by_VMEM_store.reset();
|
||||||
} else if (vm_vsrc == 0) {
|
} else if (vm_vsrc == 0) {
|
||||||
ctx.sgprs_read_by_VMEM.reset();
|
ctx.sgprs_read_by_VMEM.reset();
|
||||||
@@ -1002,11 +1002,11 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr<Instruction>&
|
|||||||
} else if (instr->isSALU()) {
|
} else if (instr->isSALU()) {
|
||||||
/* Reducing lgkmcnt count to 0 always mitigates the hazard. */
|
/* Reducing lgkmcnt count to 0 always mitigates the hazard. */
|
||||||
if (instr->opcode == aco_opcode::s_waitcnt_lgkmcnt) {
|
if (instr->opcode == aco_opcode::s_waitcnt_lgkmcnt) {
|
||||||
const SOPK_instruction& sopk = instr->sopk();
|
const SALU_instruction& sopk = instr->salu();
|
||||||
if (sopk.imm == 0 && sopk.operands[0].physReg() == sgpr_null)
|
if (sopk.imm == 0 && sopk.operands[0].physReg() == sgpr_null)
|
||||||
ctx.sgprs_read_by_SMEM.reset();
|
ctx.sgprs_read_by_SMEM.reset();
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
||||||
wait_imm imm(state.program->gfx_level, instr->sopp().imm);
|
wait_imm imm(state.program->gfx_level, instr->salu().imm);
|
||||||
if (imm.lgkm == 0)
|
if (imm.lgkm == 0)
|
||||||
ctx.sgprs_read_by_SMEM.reset();
|
ctx.sgprs_read_by_SMEM.reset();
|
||||||
} else if (instr->format != Format::SOPP && instr->definitions.size()) {
|
} else if (instr->format != Format::SOPP && instr->definitions.size()) {
|
||||||
@@ -1034,7 +1034,7 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr<Instruction>&
|
|||||||
ctx.has_VMEM = ctx.has_DS = false;
|
ctx.has_VMEM = ctx.has_DS = false;
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt) {
|
||||||
/* Only s_waitcnt_vscnt can mitigate the hazard */
|
/* Only s_waitcnt_vscnt can mitigate the hazard */
|
||||||
const SOPK_instruction& sopk = instr->sopk();
|
const SALU_instruction& sopk = instr->salu();
|
||||||
if (sopk.operands[0].physReg() == sgpr_null && sopk.imm == 0)
|
if (sopk.operands[0].physReg() == sgpr_null && sopk.imm == 0)
|
||||||
ctx.has_VMEM = ctx.has_branch_after_VMEM = ctx.has_DS = ctx.has_branch_after_DS = false;
|
ctx.has_VMEM = ctx.has_branch_after_VMEM = ctx.has_DS = ctx.has_branch_after_DS = false;
|
||||||
}
|
}
|
||||||
@@ -1145,7 +1145,7 @@ parse_vdst_wait(aco_ptr<Instruction>& instr)
|
|||||||
else if (instr->isLDSDIR())
|
else if (instr->isLDSDIR())
|
||||||
return instr->ldsdir().wait_vdst;
|
return instr->ldsdir().wait_vdst;
|
||||||
else if (instr->opcode == aco_opcode::s_waitcnt_depctr)
|
else if (instr->opcode == aco_opcode::s_waitcnt_depctr)
|
||||||
return (instr->sopp().imm >> 12) & 0xf;
|
return (instr->salu().imm >> 12) & 0xf;
|
||||||
else
|
else
|
||||||
return 15;
|
return 15;
|
||||||
}
|
}
|
||||||
@@ -1417,8 +1417,8 @@ handle_instruction_gfx11(State& state, NOP_ctx_gfx11& ctx, aco_ptr<Instruction>&
|
|||||||
sa_sdst = 0;
|
sa_sdst = 0;
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt_depctr) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt_depctr) {
|
||||||
/* va_vdst already obtained through parse_vdst_wait(). */
|
/* va_vdst already obtained through parse_vdst_wait(). */
|
||||||
vm_vsrc = (instr->sopp().imm >> 2) & 0x7;
|
vm_vsrc = (instr->salu().imm >> 2) & 0x7;
|
||||||
sa_sdst = instr->sopp().imm & 0x1;
|
sa_sdst = instr->salu().imm & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instr->isLDSDIR()) {
|
if (instr->isLDSDIR()) {
|
||||||
@@ -1539,12 +1539,12 @@ handle_instruction_gfx11(State& state, NOP_ctx_gfx11& ctx, aco_ptr<Instruction>&
|
|||||||
ctx.vgpr_used_by_vmem_store.reset();
|
ctx.vgpr_used_by_vmem_store.reset();
|
||||||
ctx.vgpr_used_by_ds.reset();
|
ctx.vgpr_used_by_ds.reset();
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
||||||
wait_imm imm(GFX11, instr->sopp().imm);
|
wait_imm imm(GFX11, instr->salu().imm);
|
||||||
if (imm.vm == 0)
|
if (imm.vm == 0)
|
||||||
ctx.vgpr_used_by_vmem_load.reset();
|
ctx.vgpr_used_by_vmem_load.reset();
|
||||||
if (imm.lgkm == 0)
|
if (imm.lgkm == 0)
|
||||||
ctx.vgpr_used_by_ds.reset();
|
ctx.vgpr_used_by_ds.reset();
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->sopk().imm == 0) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->salu().imm == 0) {
|
||||||
ctx.vgpr_used_by_vmem_store.reset();
|
ctx.vgpr_used_by_vmem_store.reset();
|
||||||
}
|
}
|
||||||
if (instr->isLDSDIR()) {
|
if (instr->isLDSDIR()) {
|
||||||
|
@@ -498,7 +498,7 @@ process_instructions(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instructio
|
|||||||
Definition dst = instr->definitions[0];
|
Definition dst = instr->definitions[0];
|
||||||
assert(dst.size() == bld.lm.size());
|
assert(dst.size() == bld.lm.size());
|
||||||
if (state == Exact) {
|
if (state == Exact) {
|
||||||
instr.reset(create_instruction<SOP1_instruction>(bld.w64or32(Builder::s_mov),
|
instr.reset(create_instruction<SALU_instruction>(bld.w64or32(Builder::s_mov),
|
||||||
Format::SOP1, 1, 1));
|
Format::SOP1, 1, 1));
|
||||||
instr->operands[0] = Operand::zero();
|
instr->operands[0] = Operand::zero();
|
||||||
instr->definitions[0] = dst;
|
instr->definitions[0] = dst;
|
||||||
@@ -506,7 +506,7 @@ process_instructions(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instructio
|
|||||||
std::pair<Operand, uint8_t>& exact_mask = info.exec[0];
|
std::pair<Operand, uint8_t>& exact_mask = info.exec[0];
|
||||||
assert(exact_mask.second & mask_type_exact);
|
assert(exact_mask.second & mask_type_exact);
|
||||||
|
|
||||||
instr.reset(create_instruction<SOP2_instruction>(bld.w64or32(Builder::s_andn2),
|
instr.reset(create_instruction<SALU_instruction>(bld.w64or32(Builder::s_andn2),
|
||||||
Format::SOP2, 2, 2));
|
Format::SOP2, 2, 2));
|
||||||
instr->operands[0] = Operand(exec, bld.lm); /* current exec */
|
instr->operands[0] = Operand(exec, bld.lm); /* current exec */
|
||||||
instr->operands[1] = Operand(exact_mask.first);
|
instr->operands[1] = Operand(exact_mask.first);
|
||||||
|
@@ -448,10 +448,10 @@ bool
|
|||||||
parse_wait_instr(wait_ctx& ctx, wait_imm& imm, Instruction* instr)
|
parse_wait_instr(wait_ctx& ctx, wait_imm& imm, Instruction* instr)
|
||||||
{
|
{
|
||||||
if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->operands[0].physReg() == sgpr_null) {
|
if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->operands[0].physReg() == sgpr_null) {
|
||||||
imm.vs = std::min<uint8_t>(imm.vs, instr->sopk().imm);
|
imm.vs = std::min<uint8_t>(imm.vs, instr->salu().imm);
|
||||||
return true;
|
return true;
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
||||||
imm.combine(wait_imm(ctx.gfx_level, instr->sopp().imm));
|
imm.combine(wait_imm(ctx.gfx_level, instr->salu().imm));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -463,7 +463,7 @@ parse_delay_alu(wait_ctx& ctx, alu_delay_info& delay, Instruction* instr)
|
|||||||
if (instr->opcode != aco_opcode::s_delay_alu)
|
if (instr->opcode != aco_opcode::s_delay_alu)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned imm[2] = {instr->sopp().imm & 0xf, (instr->sopp().imm >> 7) & 0xf};
|
unsigned imm[2] = {instr->salu().imm & 0xf, (instr->salu().imm >> 7) & 0xf};
|
||||||
for (unsigned i = 0; i < 2; ++i) {
|
for (unsigned i = 0; i < 2; ++i) {
|
||||||
alu_delay_wait wait = (alu_delay_wait)imm[i];
|
alu_delay_wait wait = (alu_delay_wait)imm[i];
|
||||||
if (wait >= alu_delay_wait::VALU_DEP_1 && wait <= alu_delay_wait::VALU_DEP_4)
|
if (wait >= alu_delay_wait::VALU_DEP_1 && wait <= alu_delay_wait::VALU_DEP_4)
|
||||||
@@ -570,7 +570,7 @@ kill(wait_imm& imm, alu_delay_info& delay, Instruction* instr, wait_ctx& ctx,
|
|||||||
if (ctx.program->has_pops_overlapped_waves_wait &&
|
if (ctx.program->has_pops_overlapped_waves_wait &&
|
||||||
(ctx.gfx_level >= GFX11 ? instr->isEXP() && instr->exp().done
|
(ctx.gfx_level >= GFX11 ? instr->isEXP() && instr->exp().done
|
||||||
: (instr->opcode == aco_opcode::s_sendmsg &&
|
: (instr->opcode == aco_opcode::s_sendmsg &&
|
||||||
instr->sopp().imm == sendmsg_ordered_ps_done))) {
|
instr->salu().imm == sendmsg_ordered_ps_done))) {
|
||||||
if (ctx.vm_nonzero)
|
if (ctx.vm_nonzero)
|
||||||
imm.vm = 0;
|
imm.vm = 0;
|
||||||
if (ctx.gfx_level >= GFX10 && ctx.vs_nonzero)
|
if (ctx.gfx_level >= GFX10 && ctx.vs_nonzero)
|
||||||
@@ -993,16 +993,16 @@ emit_waitcnt(wait_ctx& ctx, std::vector<aco_ptr<Instruction>>& instructions, wai
|
|||||||
{
|
{
|
||||||
if (imm.vs != wait_imm::unset_counter) {
|
if (imm.vs != wait_imm::unset_counter) {
|
||||||
assert(ctx.gfx_level >= GFX10);
|
assert(ctx.gfx_level >= GFX10);
|
||||||
SOPK_instruction* waitcnt_vs =
|
SALU_instruction* waitcnt_vs =
|
||||||
create_instruction<SOPK_instruction>(aco_opcode::s_waitcnt_vscnt, Format::SOPK, 1, 0);
|
create_instruction<SALU_instruction>(aco_opcode::s_waitcnt_vscnt, Format::SOPK, 1, 0);
|
||||||
waitcnt_vs->operands[0] = Operand(sgpr_null, s1);
|
waitcnt_vs->operands[0] = Operand(sgpr_null, s1);
|
||||||
waitcnt_vs->imm = imm.vs;
|
waitcnt_vs->imm = imm.vs;
|
||||||
instructions.emplace_back(waitcnt_vs);
|
instructions.emplace_back(waitcnt_vs);
|
||||||
imm.vs = wait_imm::unset_counter;
|
imm.vs = wait_imm::unset_counter;
|
||||||
}
|
}
|
||||||
if (!imm.empty()) {
|
if (!imm.empty()) {
|
||||||
SOPP_instruction* waitcnt =
|
SALU_instruction* waitcnt =
|
||||||
create_instruction<SOPP_instruction>(aco_opcode::s_waitcnt, Format::SOPP, 0, 0);
|
create_instruction<SALU_instruction>(aco_opcode::s_waitcnt, Format::SOPP, 0, 0);
|
||||||
waitcnt->imm = imm.pack(ctx.gfx_level);
|
waitcnt->imm = imm.pack(ctx.gfx_level);
|
||||||
instructions.emplace_back(waitcnt);
|
instructions.emplace_back(waitcnt);
|
||||||
}
|
}
|
||||||
@@ -1030,8 +1030,8 @@ emit_delay_alu(wait_ctx& ctx, std::vector<aco_ptr<Instruction>>& instructions,
|
|||||||
imm |= ((uint32_t)alu_delay_wait::SALU_CYCLE_1 + cycles - 1) << (imm ? 7 : 0);
|
imm |= ((uint32_t)alu_delay_wait::SALU_CYCLE_1 + cycles - 1) << (imm ? 7 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SOPP_instruction* inst =
|
SALU_instruction* inst =
|
||||||
create_instruction<SOPP_instruction>(aco_opcode::s_delay_alu, Format::SOPP, 0, 0);
|
create_instruction<SALU_instruction>(aco_opcode::s_delay_alu, Format::SOPP, 0, 0);
|
||||||
inst->imm = imm;
|
inst->imm = imm;
|
||||||
inst->pass_flags = (delay.valu_cycles | (delay.trans_cycles << 16));
|
inst->pass_flags = (delay.valu_cycles | (delay.trans_cycles << 16));
|
||||||
instructions.emplace_back(inst);
|
instructions.emplace_back(inst);
|
||||||
@@ -1176,7 +1176,7 @@ insert_wait_states(Program* program)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t imm = instr->sopp().imm;
|
uint16_t imm = instr->salu().imm;
|
||||||
int skip = i - prev_delay_alu - 1;
|
int skip = i - prev_delay_alu - 1;
|
||||||
if (imm >> 7 || prev_delay_alu < 0 || skip >= 6) {
|
if (imm >> 7 || prev_delay_alu < 0 || skip >= 6) {
|
||||||
if (imm >> 7 == 0)
|
if (imm >> 7 == 0)
|
||||||
@@ -1185,7 +1185,7 @@ insert_wait_states(Program* program)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
block.instructions[prev_delay_alu]->sopp().imm |= (skip << 4) | (imm << 7);
|
block.instructions[prev_delay_alu]->salu().imm |= (skip << 4) | (imm << 7);
|
||||||
prev_delay_alu = -1;
|
prev_delay_alu = -1;
|
||||||
}
|
}
|
||||||
block.instructions.resize(i);
|
block.instructions.resize(i);
|
||||||
|
@@ -823,8 +823,8 @@ void
|
|||||||
emit_sop2_instruction(isel_context* ctx, nir_alu_instr* instr, aco_opcode op, Temp dst,
|
emit_sop2_instruction(isel_context* ctx, nir_alu_instr* instr, aco_opcode op, Temp dst,
|
||||||
bool writes_scc, uint8_t uses_ub = 0)
|
bool writes_scc, uint8_t uses_ub = 0)
|
||||||
{
|
{
|
||||||
aco_ptr<SOP2_instruction> sop2{
|
aco_ptr<SALU_instruction> sop2{
|
||||||
create_instruction<SOP2_instruction>(op, Format::SOP2, 2, writes_scc ? 2 : 1)};
|
create_instruction<SALU_instruction>(op, Format::SOP2, 2, writes_scc ? 2 : 1)};
|
||||||
sop2->operands[0] = Operand(get_alu_src(ctx, instr->src[0]));
|
sop2->operands[0] = Operand(get_alu_src(ctx, instr->src[0]));
|
||||||
sop2->operands[1] = Operand(get_alu_src(ctx, instr->src[1]));
|
sop2->operands[1] = Operand(get_alu_src(ctx, instr->src[1]));
|
||||||
sop2->definitions[0] = Definition(dst);
|
sop2->definitions[0] = Definition(dst);
|
||||||
|
@@ -231,7 +231,7 @@ get_sync_info(const Instruction* instr)
|
|||||||
*/
|
*/
|
||||||
if (instr->opcode == aco_opcode::p_pops_gfx9_overlapped_wave_wait_done ||
|
if (instr->opcode == aco_opcode::p_pops_gfx9_overlapped_wave_wait_done ||
|
||||||
(instr->opcode == aco_opcode::s_wait_event &&
|
(instr->opcode == aco_opcode::s_wait_event &&
|
||||||
!(instr->sopp().imm & wait_event_imm_dont_wait_export_ready))) {
|
!(instr->salu().imm & wait_event_imm_dont_wait_export_ready))) {
|
||||||
return memory_sync_info(storage_buffer | storage_image, semantic_acquire, scope_queuefamily);
|
return memory_sync_info(storage_buffer | storage_image, semantic_acquire, scope_queuefamily);
|
||||||
} else if (instr->opcode == aco_opcode::p_pops_gfx9_ordered_section_done) {
|
} else if (instr->opcode == aco_opcode::p_pops_gfx9_ordered_section_done) {
|
||||||
return memory_sync_info(storage_buffer | storage_image, semantic_release, scope_queuefamily);
|
return memory_sync_info(storage_buffer | storage_image, semantic_release, scope_queuefamily);
|
||||||
|
@@ -939,11 +939,7 @@ private:
|
|||||||
struct Block;
|
struct Block;
|
||||||
struct Instruction;
|
struct Instruction;
|
||||||
struct Pseudo_instruction;
|
struct Pseudo_instruction;
|
||||||
struct SOP1_instruction;
|
struct SALU_instruction;
|
||||||
struct SOP2_instruction;
|
|
||||||
struct SOPK_instruction;
|
|
||||||
struct SOPP_instruction;
|
|
||||||
struct SOPC_instruction;
|
|
||||||
struct SMEM_instruction;
|
struct SMEM_instruction;
|
||||||
struct DS_instruction;
|
struct DS_instruction;
|
||||||
struct LDSDIR_instruction;
|
struct LDSDIR_instruction;
|
||||||
@@ -1002,61 +998,13 @@ struct Instruction {
|
|||||||
return *(Pseudo_instruction*)this;
|
return *(Pseudo_instruction*)this;
|
||||||
}
|
}
|
||||||
constexpr bool isPseudo() const noexcept { return format == Format::PSEUDO; }
|
constexpr bool isPseudo() const noexcept { return format == Format::PSEUDO; }
|
||||||
SOP1_instruction& sop1() noexcept
|
|
||||||
{
|
|
||||||
assert(isSOP1());
|
|
||||||
return *(SOP1_instruction*)this;
|
|
||||||
}
|
|
||||||
const SOP1_instruction& sop1() const noexcept
|
|
||||||
{
|
|
||||||
assert(isSOP1());
|
|
||||||
return *(SOP1_instruction*)this;
|
|
||||||
}
|
|
||||||
constexpr bool isSOP1() const noexcept { return format == Format::SOP1; }
|
constexpr bool isSOP1() const noexcept { return format == Format::SOP1; }
|
||||||
SOP2_instruction& sop2() noexcept
|
|
||||||
{
|
|
||||||
assert(isSOP2());
|
|
||||||
return *(SOP2_instruction*)this;
|
|
||||||
}
|
|
||||||
const SOP2_instruction& sop2() const noexcept
|
|
||||||
{
|
|
||||||
assert(isSOP2());
|
|
||||||
return *(SOP2_instruction*)this;
|
|
||||||
}
|
|
||||||
constexpr bool isSOP2() const noexcept { return format == Format::SOP2; }
|
constexpr bool isSOP2() const noexcept { return format == Format::SOP2; }
|
||||||
SOPK_instruction& sopk() noexcept
|
|
||||||
{
|
|
||||||
assert(isSOPK());
|
|
||||||
return *(SOPK_instruction*)this;
|
|
||||||
}
|
|
||||||
const SOPK_instruction& sopk() const noexcept
|
|
||||||
{
|
|
||||||
assert(isSOPK());
|
|
||||||
return *(SOPK_instruction*)this;
|
|
||||||
}
|
|
||||||
constexpr bool isSOPK() const noexcept { return format == Format::SOPK; }
|
constexpr bool isSOPK() const noexcept { return format == Format::SOPK; }
|
||||||
SOPP_instruction& sopp() noexcept
|
|
||||||
{
|
|
||||||
assert(isSOPP());
|
|
||||||
return *(SOPP_instruction*)this;
|
|
||||||
}
|
|
||||||
const SOPP_instruction& sopp() const noexcept
|
|
||||||
{
|
|
||||||
assert(isSOPP());
|
|
||||||
return *(SOPP_instruction*)this;
|
|
||||||
}
|
|
||||||
constexpr bool isSOPP() const noexcept { return format == Format::SOPP; }
|
constexpr bool isSOPP() const noexcept { return format == Format::SOPP; }
|
||||||
SOPC_instruction& sopc() noexcept
|
|
||||||
{
|
|
||||||
assert(isSOPC());
|
|
||||||
return *(SOPC_instruction*)this;
|
|
||||||
}
|
|
||||||
const SOPC_instruction& sopc() const noexcept
|
|
||||||
{
|
|
||||||
assert(isSOPC());
|
|
||||||
return *(SOPC_instruction*)this;
|
|
||||||
}
|
|
||||||
constexpr bool isSOPC() const noexcept { return format == Format::SOPC; }
|
constexpr bool isSOPC() const noexcept { return format == Format::SOPC; }
|
||||||
|
|
||||||
SMEM_instruction& smem() noexcept
|
SMEM_instruction& smem() noexcept
|
||||||
{
|
{
|
||||||
assert(isSMEM());
|
assert(isSMEM());
|
||||||
@@ -1295,6 +1243,16 @@ struct Instruction {
|
|||||||
isVOPD();
|
isVOPD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SALU_instruction& salu() noexcept
|
||||||
|
{
|
||||||
|
assert(isSALU());
|
||||||
|
return *(SALU_instruction*)this;
|
||||||
|
}
|
||||||
|
const SALU_instruction& salu() const noexcept
|
||||||
|
{
|
||||||
|
assert(isSALU());
|
||||||
|
return *(SALU_instruction*)this;
|
||||||
|
}
|
||||||
constexpr bool isSALU() const noexcept
|
constexpr bool isSALU() const noexcept
|
||||||
{
|
{
|
||||||
return isSOP1() || isSOP2() || isSOPC() || isSOPK() || isSOPP();
|
return isSOP1() || isSOP2() || isSOPC() || isSOPK() || isSOPP();
|
||||||
@@ -1307,32 +1265,13 @@ struct Instruction {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(Instruction) == 16, "Unexpected padding");
|
static_assert(sizeof(Instruction) == 16, "Unexpected padding");
|
||||||
|
|
||||||
struct SOPK_instruction : public Instruction {
|
struct SALU_instruction : public Instruction {
|
||||||
uint16_t imm;
|
/* In case of SOPP branch instructions, contains the Block index,
|
||||||
uint16_t padding;
|
* and otherwise, for SOPP and SOPK the 16-bit signed immediate.
|
||||||
};
|
|
||||||
static_assert(sizeof(SOPK_instruction) == sizeof(Instruction) + 4, "Unexpected padding");
|
|
||||||
|
|
||||||
struct SOPP_instruction : public Instruction {
|
|
||||||
/* In case of branch instructions, contains the Block index,
|
|
||||||
* and otherwise, the 16-bit signed immediate.
|
|
||||||
*/
|
*/
|
||||||
uint32_t imm;
|
uint32_t imm;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SOPP_instruction) == sizeof(Instruction) + 4, "Unexpected padding");
|
static_assert(sizeof(SALU_instruction) == sizeof(Instruction) + 4, "Unexpected padding");
|
||||||
|
|
||||||
struct SOPC_instruction : public Instruction {
|
|
||||||
uint32_t padding;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(SOPC_instruction) == sizeof(Instruction) + 4, "Unexpected padding");
|
|
||||||
|
|
||||||
struct SOP1_instruction : public Instruction {};
|
|
||||||
static_assert(sizeof(SOP1_instruction) == sizeof(Instruction) + 0, "Unexpected padding");
|
|
||||||
|
|
||||||
struct SOP2_instruction : public Instruction {
|
|
||||||
uint32_t padding;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(SOP2_instruction) == sizeof(Instruction) + 4, "Unexpected padding");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scalar Memory Format:
|
* Scalar Memory Format:
|
||||||
|
@@ -2895,7 +2895,7 @@ lower_to_hw_instr(Program* program)
|
|||||||
bool is_break_continue =
|
bool is_break_continue =
|
||||||
program->blocks[i].kind & (block_kind_break | block_kind_continue);
|
program->blocks[i].kind & (block_kind_break | block_kind_continue);
|
||||||
bool discard_early_exit =
|
bool discard_early_exit =
|
||||||
program->blocks[inst->sopp().imm].kind & block_kind_discard_early_exit;
|
program->blocks[inst->salu().imm].kind & block_kind_discard_early_exit;
|
||||||
if ((inst->opcode != aco_opcode::s_cbranch_scc0 &&
|
if ((inst->opcode != aco_opcode::s_cbranch_scc0 &&
|
||||||
inst->opcode != aco_opcode::s_cbranch_scc1) ||
|
inst->opcode != aco_opcode::s_cbranch_scc1) ||
|
||||||
(!discard_early_exit && !is_break_continue))
|
(!discard_early_exit && !is_break_continue))
|
||||||
|
@@ -104,7 +104,7 @@ class Format(IntEnum):
|
|||||||
|
|
||||||
def get_builder_fields(self):
|
def get_builder_fields(self):
|
||||||
if self == Format.SOPK:
|
if self == Format.SOPK:
|
||||||
return [('uint16_t', 'imm', None)]
|
return [('uint32_t', 'imm', '0')]
|
||||||
elif self == Format.SOPP:
|
elif self == Format.SOPP:
|
||||||
return [('uint32_t', 'imm', '0')]
|
return [('uint32_t', 'imm', '0')]
|
||||||
elif self == Format.SMEM:
|
elif self == Format.SMEM:
|
||||||
|
@@ -103,8 +103,8 @@ struct InstrHash {
|
|||||||
case Format::SMEM: return hash_murmur_32<SMEM_instruction>(instr);
|
case Format::SMEM: return hash_murmur_32<SMEM_instruction>(instr);
|
||||||
case Format::VINTRP: return hash_murmur_32<VINTRP_instruction>(instr);
|
case Format::VINTRP: return hash_murmur_32<VINTRP_instruction>(instr);
|
||||||
case Format::DS: return hash_murmur_32<DS_instruction>(instr);
|
case Format::DS: return hash_murmur_32<DS_instruction>(instr);
|
||||||
case Format::SOPP: return hash_murmur_32<SOPP_instruction>(instr);
|
case Format::SOPP: return hash_murmur_32<SALU_instruction>(instr);
|
||||||
case Format::SOPK: return hash_murmur_32<SOPK_instruction>(instr);
|
case Format::SOPK: return hash_murmur_32<SALU_instruction>(instr);
|
||||||
case Format::EXP: return hash_murmur_32<Export_instruction>(instr);
|
case Format::EXP: return hash_murmur_32<Export_instruction>(instr);
|
||||||
case Format::MUBUF: return hash_murmur_32<MUBUF_instruction>(instr);
|
case Format::MUBUF: return hash_murmur_32<MUBUF_instruction>(instr);
|
||||||
case Format::MIMG: return hash_murmur_32<MIMG_instruction>(instr);
|
case Format::MIMG: return hash_murmur_32<MIMG_instruction>(instr);
|
||||||
@@ -209,8 +209,8 @@ struct InstrPred {
|
|||||||
case Format::SOPK: {
|
case Format::SOPK: {
|
||||||
if (a->opcode == aco_opcode::s_getreg_b32)
|
if (a->opcode == aco_opcode::s_getreg_b32)
|
||||||
return false;
|
return false;
|
||||||
SOPK_instruction& aK = a->sopk();
|
SALU_instruction& aK = a->salu();
|
||||||
SOPK_instruction& bK = b->sopk();
|
SALU_instruction& bK = b->salu();
|
||||||
return aK.imm == bK.imm;
|
return aK.imm == bK.imm;
|
||||||
}
|
}
|
||||||
case Format::SMEM: {
|
case Format::SMEM: {
|
||||||
|
@@ -2468,7 +2468,7 @@ optimize_cmp_subgroup_invocation(opt_ctx& ctx, aco_ptr<Instruction>& instr)
|
|||||||
const uint64_t mask = BITFIELD64_RANGE(first_bit, num_bits);
|
const uint64_t mask = BITFIELD64_RANGE(first_bit, num_bits);
|
||||||
if (wave_size == 64 && mask > 0x7fffffff && mask != -1ull) {
|
if (wave_size == 64 && mask > 0x7fffffff && mask != -1ull) {
|
||||||
/* Mask can't be represented as a 64-bit constant or literal, use s_bfm_b64. */
|
/* Mask can't be represented as a 64-bit constant or literal, use s_bfm_b64. */
|
||||||
cpy = create_instruction<SOP2_instruction>(aco_opcode::s_bfm_b64, Format::SOP2, 2, 1);
|
cpy = create_instruction<SALU_instruction>(aco_opcode::s_bfm_b64, Format::SOP2, 2, 1);
|
||||||
cpy->operands[0] = Operand::c32(num_bits);
|
cpy->operands[0] = Operand::c32(num_bits);
|
||||||
cpy->operands[1] = Operand::c32(first_bit);
|
cpy->operands[1] = Operand::c32(first_bit);
|
||||||
} else {
|
} else {
|
||||||
@@ -5244,10 +5244,8 @@ try_convert_sopc_to_sopk(aco_ptr<Instruction>& instr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(SOPK_instruction) <= sizeof(SOPC_instruction),
|
|
||||||
"Invalid direct instruction cast.");
|
|
||||||
instr->format = Format::SOPK;
|
instr->format = Format::SOPK;
|
||||||
SOPK_instruction* instr_sopk = &instr->sopk();
|
SALU_instruction* instr_sopk = &instr->salu();
|
||||||
|
|
||||||
instr_sopk->imm = instr_sopk->operands[1].constantValue() & 0xffff;
|
instr_sopk->imm = instr_sopk->operands[1].constantValue() & 0xffff;
|
||||||
instr_sopk->opcode = sopk_opcode_for_sopc(instr_sopk->opcode);
|
instr_sopk->opcode = sopk_opcode_for_sopc(instr_sopk->opcode);
|
||||||
|
@@ -412,10 +412,10 @@ try_optimize_scc_nocompare(pr_opt_ctx& ctx, aco_ptr<Instruction>& instr)
|
|||||||
* This means that the original instruction will be eliminated.
|
* This means that the original instruction will be eliminated.
|
||||||
*/
|
*/
|
||||||
if (wr_instr->format == Format::SOP2) {
|
if (wr_instr->format == Format::SOP2) {
|
||||||
instr.reset(create_instruction<SOP2_instruction>(pulled_opcode, Format::SOP2, 2, 2));
|
instr.reset(create_instruction<SALU_instruction>(pulled_opcode, Format::SOP2, 2, 2));
|
||||||
instr->operands[1] = wr_instr->operands[1];
|
instr->operands[1] = wr_instr->operands[1];
|
||||||
} else if (wr_instr->format == Format::SOP1) {
|
} else if (wr_instr->format == Format::SOP1) {
|
||||||
instr.reset(create_instruction<SOP1_instruction>(pulled_opcode, Format::SOP1, 1, 2));
|
instr.reset(create_instruction<SALU_instruction>(pulled_opcode, Format::SOP1, 1, 2));
|
||||||
}
|
}
|
||||||
instr->definitions[0] = wr_instr->definitions[0];
|
instr->definitions[0] = wr_instr->definitions[0];
|
||||||
instr->definitions[1] = scc_def;
|
instr->definitions[1] = scc_def;
|
||||||
@@ -526,7 +526,7 @@ try_eliminate_scc_copy(pr_opt_ctx& ctx, aco_ptr<Instruction>& instr)
|
|||||||
Idx producer_idx = {wr_idx.block, wr_instr->pass_flags};
|
Idx producer_idx = {wr_idx.block, wr_instr->pass_flags};
|
||||||
Instruction* producer_instr = ctx.get(producer_idx);
|
Instruction* producer_instr = ctx.get(producer_idx);
|
||||||
|
|
||||||
if (!producer_instr)
|
if (!producer_instr || !producer_instr->isSALU())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Verify that the operands of the producer instruction haven't been overwritten. */
|
/* Verify that the operands of the producer instruction haven't been overwritten. */
|
||||||
@@ -544,20 +544,10 @@ try_eliminate_scc_copy(pr_opt_ctx& ctx, aco_ptr<Instruction>& instr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the original producer of the SCC */
|
/* Duplicate the original producer of the SCC */
|
||||||
if (producer_instr->isSOP1())
|
instr.reset(create_instruction<SALU_instruction>(producer_instr->opcode, producer_instr->format,
|
||||||
instr.reset(create_instruction<SOP1_instruction>(producer_instr->opcode, Format::SOP1,
|
producer_instr->operands.size(),
|
||||||
producer_instr->operands.size(),
|
producer_instr->definitions.size()));
|
||||||
producer_instr->definitions.size()));
|
instr->salu().imm = producer_instr->salu().imm;
|
||||||
else if (producer_instr->isSOP2())
|
|
||||||
instr.reset(create_instruction<SOP2_instruction>(producer_instr->opcode, Format::SOP2,
|
|
||||||
producer_instr->operands.size(),
|
|
||||||
producer_instr->definitions.size()));
|
|
||||||
else if (producer_instr->isSOPC())
|
|
||||||
instr.reset(create_instruction<SOPC_instruction>(producer_instr->opcode, Format::SOPC,
|
|
||||||
producer_instr->operands.size(),
|
|
||||||
producer_instr->definitions.size()));
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* The copy is no longer needed. */
|
/* The copy is no longer needed. */
|
||||||
if (--ctx.uses[wr_instr->definitions[0].tempId()] == 0)
|
if (--ctx.uses[wr_instr->definitions[0].tempId()] == 0)
|
||||||
|
@@ -285,12 +285,12 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins
|
|||||||
{
|
{
|
||||||
switch (instr->format) {
|
switch (instr->format) {
|
||||||
case Format::SOPK: {
|
case Format::SOPK: {
|
||||||
const SOPK_instruction& sopk = instr->sopk();
|
const SALU_instruction& sopk = instr->salu();
|
||||||
fprintf(output, " imm:%d", sopk.imm & 0x8000 ? (sopk.imm - 65536) : sopk.imm);
|
fprintf(output, " imm:%d", sopk.imm & 0x8000 ? (sopk.imm - 65536) : sopk.imm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Format::SOPP: {
|
case Format::SOPP: {
|
||||||
uint16_t imm = instr->sopp().imm;
|
uint16_t imm = instr->salu().imm;
|
||||||
switch (instr->opcode) {
|
switch (instr->opcode) {
|
||||||
case aco_opcode::s_waitcnt: {
|
case aco_opcode::s_waitcnt: {
|
||||||
wait_imm unpacked(gfx_level, imm);
|
wait_imm unpacked(gfx_level, imm);
|
||||||
@@ -400,7 +400,7 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
if (instr_info.classes[(int)instr->opcode] == instr_class::branch)
|
if (instr_info.classes[(int)instr->opcode] == instr_class::branch)
|
||||||
fprintf(output, " block:BB%d", instr->sopp().imm);
|
fprintf(output, " block:BB%d", imm);
|
||||||
else if (imm)
|
else if (imm)
|
||||||
fprintf(output, " imm:%u", imm);
|
fprintf(output, " imm:%u", imm);
|
||||||
break;
|
break;
|
||||||
|
@@ -2848,10 +2848,8 @@ optimize_encoding_sopk(Program* program, ra_ctx& ctx, RegisterFile& register_fil
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(SOPK_instruction) <= sizeof(SOP2_instruction),
|
|
||||||
"Invalid direct instruction cast.");
|
|
||||||
instr->format = Format::SOPK;
|
instr->format = Format::SOPK;
|
||||||
SOPK_instruction* instr_sopk = &instr->sopk();
|
SALU_instruction* instr_sopk = &instr->salu();
|
||||||
|
|
||||||
instr_sopk->imm = instr_sopk->operands[literal_idx].constantValue() & 0xffff;
|
instr_sopk->imm = instr_sopk->operands[literal_idx].constantValue() & 0xffff;
|
||||||
if (literal_idx == 0)
|
if (literal_idx == 0)
|
||||||
@@ -3319,7 +3317,7 @@ register_allocation(Program* program, live& live_vars, ra_test_policy policy)
|
|||||||
|
|
||||||
aco_ptr<Instruction> mov;
|
aco_ptr<Instruction> mov;
|
||||||
if (can_sgpr)
|
if (can_sgpr)
|
||||||
mov.reset(create_instruction<SOP1_instruction>(aco_opcode::s_mov_b32,
|
mov.reset(create_instruction<SALU_instruction>(aco_opcode::s_mov_b32,
|
||||||
Format::SOP1, 1, 1));
|
Format::SOP1, 1, 1));
|
||||||
else
|
else
|
||||||
mov.reset(create_instruction<VALU_instruction>(aco_opcode::v_mov_b32,
|
mov.reset(create_instruction<VALU_instruction>(aco_opcode::v_mov_b32,
|
||||||
|
@@ -424,7 +424,7 @@ bool
|
|||||||
is_done_sendmsg(amd_gfx_level gfx_level, const Instruction* instr)
|
is_done_sendmsg(amd_gfx_level gfx_level, const Instruction* instr)
|
||||||
{
|
{
|
||||||
if (gfx_level <= GFX10_3 && instr->opcode == aco_opcode::s_sendmsg)
|
if (gfx_level <= GFX10_3 && instr->opcode == aco_opcode::s_sendmsg)
|
||||||
return (instr->sopp().imm & sendmsg_id_mask) == sendmsg_gs_done;
|
return (instr->salu().imm & sendmsg_id_mask) == sendmsg_gs_done;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,7 +577,7 @@ perform_hazard_query(hazard_query* query, Instruction* instr, bool upwards)
|
|||||||
if (upwards) {
|
if (upwards) {
|
||||||
if (instr->opcode == aco_opcode::p_pops_gfx9_add_exiting_wave_id ||
|
if (instr->opcode == aco_opcode::p_pops_gfx9_add_exiting_wave_id ||
|
||||||
(instr->opcode == aco_opcode::s_wait_event &&
|
(instr->opcode == aco_opcode::s_wait_event &&
|
||||||
!(instr->sopp().imm & wait_event_imm_dont_wait_export_ready))) {
|
!(instr->salu().imm & wait_event_imm_dont_wait_export_ready))) {
|
||||||
return hazard_fail_unreorderable;
|
return hazard_fail_unreorderable;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -355,15 +355,15 @@ do_reload(spill_ctx& ctx, Temp tmp, Temp new_name, uint32_t spill_id)
|
|||||||
res.reset(create_instruction<VALU_instruction>(
|
res.reset(create_instruction<VALU_instruction>(
|
||||||
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
||||||
} else if (instr->isSOP1()) {
|
} else if (instr->isSOP1()) {
|
||||||
res.reset(create_instruction<SOP1_instruction>(
|
res.reset(create_instruction<SALU_instruction>(
|
||||||
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
||||||
} else if (instr->isPseudo()) {
|
} else if (instr->isPseudo()) {
|
||||||
res.reset(create_instruction<Pseudo_instruction>(
|
res.reset(create_instruction<Pseudo_instruction>(
|
||||||
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
||||||
} else if (instr->isSOPK()) {
|
} else if (instr->isSOPK()) {
|
||||||
res.reset(create_instruction<SOPK_instruction>(
|
res.reset(create_instruction<SALU_instruction>(
|
||||||
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
instr->opcode, instr->format, instr->operands.size(), instr->definitions.size()));
|
||||||
res->sopk().imm = instr->sopk().imm;
|
res->salu().imm = instr->salu().imm;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < instr->operands.size(); i++) {
|
for (unsigned i = 0; i < instr->operands.size(); i++) {
|
||||||
res->operands[i] = instr->operands[i];
|
res->operands[i] = instr->operands[i];
|
||||||
|
@@ -350,9 +350,9 @@ get_wait_imm(Program* program, aco_ptr<Instruction>& instr)
|
|||||||
if (instr->opcode == aco_opcode::s_endpgm) {
|
if (instr->opcode == aco_opcode::s_endpgm) {
|
||||||
return wait_imm(0, 0, 0, 0);
|
return wait_imm(0, 0, 0, 0);
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt) {
|
||||||
return wait_imm(GFX10_3, instr->sopp().imm);
|
return wait_imm(GFX10_3, instr->salu().imm);
|
||||||
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt) {
|
} else if (instr->opcode == aco_opcode::s_waitcnt_vscnt) {
|
||||||
return wait_imm(0, 0, 0, instr->sopk().imm);
|
return wait_imm(0, 0, 0, instr->salu().imm);
|
||||||
} else {
|
} else {
|
||||||
unsigned max_lgkm_cnt = program->gfx_level >= GFX10 ? 62 : 14;
|
unsigned max_lgkm_cnt = program->gfx_level >= GFX10 ? 62 : 14;
|
||||||
unsigned max_exp_cnt = 6;
|
unsigned max_exp_cnt = 6;
|
||||||
|
Reference in New Issue
Block a user