diff --git a/src/panfrost/compiler/bifrost/valhall/disasm.py b/src/panfrost/compiler/bifrost/valhall/disasm.py index 20441318cc0..6ec53f3fafd 100644 --- a/src/panfrost/compiler/bifrost/valhall/disasm.py +++ b/src/panfrost/compiler/bifrost/valhall/disasm.py @@ -218,6 +218,14 @@ va_disasm_instr(FILE *fp, uint64_t instr) ${recurse_subcodes(OPCODES)} } +void +va_disasm_instr_v15(FILE *fp, uint64_t instr) +{ + unsigned opcode; + +${recurse_subcodes(OPCODES_V15)} +} + static bool is_branch(uint64_t instr) { <% (exact, mask) = OPCODES.get_exact_mask("BRANCHZ") %> @@ -229,6 +237,17 @@ static bool is_branch(uint64_t instr) return false; } +static bool is_branch_v15(uint64_t instr) +{ +<% (exact, mask) = OPCODES_V15.get_exact_mask("BRANCHZ") %> + if ((instr & ${hex(mask)}) == ${hex(exact)}) + return true; +<% (exact, mask) = OPCODES_V15.get_exact_mask("BRANCHZI") %> + if ((instr & ${hex(mask)}) == ${hex(exact)}) + return true; + return false; +} + void disassemble_valhall(FILE *fp, const void *code, size_t size, bool verbose) { @@ -276,6 +295,9 @@ class OpBucket: self.children = {} def insert(self, subcodes, ins): + # Need an early return in case of removed instructions + if subcodes is None: + return if len(subcodes) == 0: self.instr = ins else: @@ -305,10 +327,12 @@ class OpBucket: # Build opcode hierarchy: OPCODES = OpBucket() +OPCODES_V15 = OpBucket() for ins in instructions: OPCODES.insert(ins.opcode, ins) + OPCODES_V15.insert(ins.opcode_v15, ins) try: - print(Template(template).render(OPCODES = OPCODES, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name)) + print(Template(template).render(OPCODES = OPCODES, OPCODES_V15 = OPCODES_V15, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name)) except: print(exceptions.text_error_template().render()) diff --git a/src/panfrost/compiler/bifrost/valhall/disassemble.h b/src/panfrost/compiler/bifrost/valhall/disassemble.h index e9057fa860b..a7f73db52b8 100644 --- a/src/panfrost/compiler/bifrost/valhall/disassemble.h +++ b/src/panfrost/compiler/bifrost/valhall/disassemble.h @@ -15,6 +15,7 @@ #include void va_disasm_instr(FILE *fp, uint64_t instr); +void va_disasm_instr_v15(FILE *fp, uint64_t instr); void disassemble_valhall(FILE *fp, const void *code, size_t size, bool verbose); #endif diff --git a/src/panfrost/compiler/bifrost/valhall/valhall.c.py b/src/panfrost/compiler/bifrost/valhall/valhall.c.py index 81e9a2ba523..ae7a1b5a001 100644 --- a/src/panfrost/compiler/bifrost/valhall/valhall.c.py +++ b/src/panfrost/compiler/bifrost/valhall/valhall.c.py @@ -100,7 +100,64 @@ valhall_opcodes[BI_NUM_OPCODES] = { sr_control = op.staging[0].encoded_flags >> 6 %> [BI_OPCODE_${name.replace('.', '_').upper()}] = { - .exact = ${hex(exact(op))}ULL, + .exact = ${hex(exact(op.opcode))}ULL, + .srcs = { +% for src in ([sr for sr in op.staging if sr.read] + op.srcs): + { + .absneg = ${ibool(src.absneg)}, + .swizzle = ${ibool(src.swizzle)}, + .notted = ${ibool(src.notted)}, + .widen = ${ibool(src.widen)}, + .lanes = ${ibool(src.lanes)}, + .halfswizzle = ${ibool(src.halfswizzle)}, + .lane = ${ibool(src.lane)}, + .combine = ${ibool(src.combine)}, +% if src.size in [8, 16, 32, 64]: + .size = VA_SIZE_${src.size}, +% endif + }, +% endfor + }, + .type_size = ${typesize(op.name)}, + .has_dest = ${ibool(len(op.dests) > 0)}, + .is_signed = ${ibool(op.is_signed)}, + .unit = VA_UNIT_${op.unit}, + .nr_srcs = ${len(op.srcs)}, + .nr_staging_srcs = ${sum([sr.read for sr in op.staging])}, + .nr_staging_dests = ${sum([sr.write for sr in op.staging])}, + .clamp = ${hasmod(x, 'clamp')}, + .saturate = ${hasmod(x, 'saturate')}, + .rhadd = ${hasmod(x, 'rhadd')}, + .round_mode = ${hasmod(x, 'round_mode')}, + .condition = ${hasmod(x, 'condition')}, + .result_type = ${hasmod(x, 'result_type')}, + .vecsize = ${hasmod(x, 'vector_size')}, + .register_format = ${hasmod(x, 'register_format')}, + .slot = ${hasmod(x, 'slot')}, + .sr_count = ${hasmod(x, 'staging_register_count')}, + .sr_write_count = ${hasmod(x, 'staging_register_write_count')}, + .sr_control = ${sr_control}, + }, +% endif +% endfor +}; + +const struct va_opcode_info +valhall_v15_opcodes[BI_NUM_OPCODES] = { +% for op in instructions: +% if op.name not in skip: +<% + name = op.name + if name == 'BRANCHZ': + name = 'BRANCHZ.i16' + + sr_control = 0 + + if len(op.staging) > 0: + sr_control = op.staging[0].encoded_flags >> 6 +%> + [BI_OPCODE_${name.replace('.', '_').upper()}] = { + .exact = ${hex(exact(op.opcode_v15))}ULL, .srcs = { % for src in ([sr for sr in op.staging if sr.read] + op.srcs): { @@ -144,9 +201,14 @@ valhall_opcodes[BI_NUM_OPCODES] = { """ # Exact value to be ORed in to every opcode -def exact_op(op): +def exact_op(opcode): exact_op = 0 - for subcode in op.opcode: + + # Need an early return in case of removed instructions + if not opcode: + return exact_op + + for subcode in opcode: exact_op |= (subcode.value << subcode.start) return exact_op diff --git a/src/panfrost/compiler/bifrost/valhall/valhall.py b/src/panfrost/compiler/bifrost/valhall/valhall.py index 7cae9521b87..c6cbf31ed86 100644 --- a/src/panfrost/compiler/bifrost/valhall/valhall.py +++ b/src/panfrost/compiler/bifrost/valhall/valhall.py @@ -186,11 +186,12 @@ class Opcode: self.mask = mask class Instruction: - def __init__(self, name, opcode, srcs = [], dests = [], immediates = [], modifiers = [], staging = None, unit = None): + def __init__(self, name, opcode, opcode_v15, srcs = [], dests = [], immediates = [], modifiers = [], staging = None, unit = None): self.name = name self.srcs = srcs self.dests = dests self.opcode = opcode + self.opcode_v15 = opcode_v15 self.immediates = immediates self.modifiers = modifiers self.staging = staging @@ -273,6 +274,7 @@ def build_instr(el, overrides = {}): # Get overridables name = overrides.get('name') or el.attrib.get('name') opcode = overrides.get('opcode') or build_opcode(el, 'opcode') + opcode_v15 = overrides.get('opcode_v15') or build_opcode(el, 'opcode_v15') unit = overrides.get('unit') or el.attrib.get('unit') # Get explicit sources/dests @@ -312,7 +314,7 @@ def build_instr(el, overrides = {}): elif mod.tag =='va_mod': modifiers.append(build_modifier(mod)) - instr = Instruction(name, opcode, srcs = sources, dests = dests, immediates = imms, modifiers = modifiers, staging = staging, unit = unit) + instr = Instruction(name, opcode, opcode_v15, srcs = sources, dests = dests, immediates = imms, modifiers = modifiers, staging = staging, unit = unit) instructions.append(instr) @@ -323,6 +325,7 @@ def build_group(el): build_instr(el, overrides = { 'name': ins.attrib['name'], 'opcode': build_opcode(ins, 'opcode'), + 'opcode_v15': build_opcode(ins, 'opcode_v15'), 'unit': ins.attrib.get('unit'), })