summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Kristóf <timur.kristof@gmail.com>2019-10-31 13:28:54 +0100
committerDaniel Schürmann <daniel@schuermann.dev>2019-12-04 10:36:01 +0000
commitb4efe179ede6ea7d53bc8074048c96d2aa146701 (patch)
treec5cf45204b0e783d721e4a18c5e86b056fc0bee4
parentc44af6cbc7731f8f482da38298887198d975e245 (diff)
downloadmesa-b4efe179ede6ea7d53bc8074048c96d2aa146701.tar.gz
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 <timur.kristof@gmail.com> Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
-rw-r--r--src/amd/compiler/aco_builder_h.py78
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
};