diff options
author | Timur Kristóf <[email protected]> | 2019-10-31 13:28:54 +0100 |
---|---|---|
committer | Daniel Schürmann <[email protected]> | 2019-12-04 10:36:01 +0000 |
commit | b4efe179ede6ea7d53bc8074048c96d2aa146701 (patch) | |
tree | c5cf45204b0e783d721e4a18c5e86b056fc0bee4 /src/amd | |
parent | c44af6cbc7731f8f482da38298887198d975e245 (diff) |
aco/wave32: Add wave size specific opcodes to aco_builder.
Several places in ACO we use SOP1 or SOP2 instructions to operate over the
exec mask or VCC, and these need to be adapted to the new size in wave32
mode.
This commit adds a way to deal with this problem in aco_builder: the caller
can specify a wave size specific opcode and the builder will translate that
to the correct opcode based on the current wave size.
Signed-off-by: Timur Kristóf <[email protected]>
Reviewed-by: Daniel Schürmann <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r-- | src/amd/compiler/aco_builder_h.py | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/amd/compiler/aco_builder_h.py b/src/amd/compiler/aco_builder_h.py index d9cd2f00612..e70d9317b3f 100644 --- a/src/amd/compiler/aco_builder_h.py +++ b/src/amd/compiler/aco_builder_h.py @@ -113,6 +113,25 @@ public: Op(Result res) : op((Temp)res) {} }; + enum WaveSpecificOpcode { + s_cselect = (unsigned) aco_opcode::s_cselect_b64, + s_cmp_lg = (unsigned) aco_opcode::s_cmp_lg_u64, + s_and = (unsigned) aco_opcode::s_and_b64, + s_andn2 = (unsigned) aco_opcode::s_andn2_b64, + s_or = (unsigned) aco_opcode::s_or_b64, + s_orn2 = (unsigned) aco_opcode::s_orn2_b64, + s_not = (unsigned) aco_opcode::s_not_b64, + s_mov = (unsigned) aco_opcode::s_mov_b64, + s_wqm = (unsigned) aco_opcode::s_wqm_b64, + s_and_saveexec = (unsigned) aco_opcode::s_and_saveexec_b64, + s_or_saveexec = (unsigned) aco_opcode::s_or_saveexec_b64, + s_xnor = (unsigned) aco_opcode::s_xnor_b64, + s_xor = (unsigned) aco_opcode::s_xor_b64, + s_bcnt1_i32 = (unsigned) aco_opcode::s_bcnt1_i32_b64, + s_bitcmp1 = (unsigned) aco_opcode::s_bitcmp1_b64, + s_ff1_i32 = (unsigned) aco_opcode::s_ff1_i32_b64, + }; + Program *program; bool use_iterator; bool start; // only when use_iterator == false @@ -202,6 +221,48 @@ public: return Definition(program->allocateId(), reg, rc); } + inline aco_opcode w64or32(WaveSpecificOpcode opcode) const { + if (program->wave_size == 64) + return (aco_opcode) opcode; + + switch (opcode) { + case s_cselect: + return aco_opcode::s_cselect_b32; + case s_cmp_lg: + return aco_opcode::s_cmp_lg_u32; + case s_and: + return aco_opcode::s_and_b32; + case s_andn2: + return aco_opcode::s_andn2_b32; + case s_or: + return aco_opcode::s_or_b32; + case s_orn2: + return aco_opcode::s_orn2_b32; + case s_not: + return aco_opcode::s_not_b32; + case s_mov: + return aco_opcode::s_mov_b32; + case s_wqm: + return aco_opcode::s_wqm_b32; + case s_and_saveexec: + return aco_opcode::s_and_saveexec_b32; + case s_or_saveexec: + return aco_opcode::s_or_saveexec_b32; + case s_xnor: + return aco_opcode::s_xnor_b32; + case s_xor: + return aco_opcode::s_xor_b32; + case s_bcnt1_i32: + return aco_opcode::s_bcnt1_i32_b32; + case s_bitcmp1: + return aco_opcode::s_bitcmp1_b32; + case s_ff1_i32: + return aco_opcode::s_ff1_i32_b32; + default: + unreachable("Unsupported wave specific opcode."); + } + } + % for fixed in ['m0', 'vcc', 'exec', 'scc']: Operand ${fixed}(Temp tmp) { Operand op(tmp); @@ -404,6 +465,23 @@ formats = [("pseudo", [Format.PSEUDO], 'Pseudo_instruction', list(itertools.prod % endfor return insert(instr); } + + % if name == 'sop1' or name == 'sop2' or name == 'sopc': + <% + args[0] = 'WaveSpecificOpcode opcode' + params = [] + for i in range(num_definitions): + params.append('def%d' % i) + for i in range(num_operands): + params.append('op%d' % i) + %>\\ + + inline Result ${name}(${', '.join(args)}) + { + return ${name}(w64or32(opcode), ${', '.join(params)}); + } + + % endif % endfor % endfor }; |