diff --git a/src/panfrost/compiler/bifrost/valhall/disasm.py b/src/panfrost/compiler/bifrost/valhall/disasm.py index 90f16810bf4..20441318cc0 100644 --- a/src/panfrost/compiler/bifrost/valhall/disasm.py +++ b/src/panfrost/compiler/bifrost/valhall/disasm.py @@ -31,64 +31,64 @@ template = """ % for name, en in ENUMS.items(): UNUSED static const char *valhall_${name}[] = { % for v in en.values: - "${"" if v.default else "." + v.value}", + "${"" if v.default else "." + v.value}", % endfor }; % endfor static const uint32_t va_immediates[32] = { % for imm in IMMEDIATES: - ${hex(imm)}, + ${hex(imm)}, % endfor }; static inline void va_print_src(FILE *fp, unsigned type, unsigned value, unsigned size, unsigned fau_page) { - if (type == VA_SRC_IMM_TYPE) { - if (value >= 32) { - if (fau_page == 0) - fputs(valhall_fau_special_page_0[(value - 0x20) >> 1] + 1, fp); - else if (fau_page == 1) - fputs(valhall_fau_special_page_1[(value - 0x20) >> 1] + 1, fp); - else if (fau_page == 3) - fputs(valhall_fau_special_page_3[(value - 0x20) >> 1] + 1, fp); - else - fprintf(fp, "reserved_page2"); + if (type == VA_SRC_IMM_TYPE) { + if (value >= 32) { + if (fau_page == 0) + fputs(valhall_fau_special_page_0[(value - 0x20) >> 1] + 1, fp); + else if (fau_page == 1) + fputs(valhall_fau_special_page_1[(value - 0x20) >> 1] + 1, fp); + else if (fau_page == 3) + fputs(valhall_fau_special_page_3[(value - 0x20) >> 1] + 1, fp); + else + fprintf(fp, "reserved_page2"); - fprintf(fp, ".w%u", value & 1); - } else { - fprintf(fp, "0x%X", va_immediates[value]); - } - } else if (type == VA_SRC_UNIFORM_TYPE) { - fprintf(fp, "u%u", value >> 1 | (fau_page << 5)); - if (size <= 32) - fprintf(fp, ".w%u", value & 1); - } else { - bool discard = (type & 1); - char *dmark = discard ? "^" : ""; - if (size > 32) - fprintf(fp, "[r%u%s:r%u%s]", value, dmark, value + 1, dmark); - else - fprintf(fp, "r%u%s", value, dmark); - } + fprintf(fp, ".w%u", value & 1); + } else { + fprintf(fp, "0x%X", va_immediates[value]); + } + } else if (type == VA_SRC_UNIFORM_TYPE) { + fprintf(fp, "u%u", value >> 1 | (fau_page << 5)); + if (size <= 32) + fprintf(fp, ".w%u", value & 1); + } else { + bool discard = (type & 1); + char *dmark = discard ? "^" : ""; + if (size > 32) + fprintf(fp, "[r%u%s:r%u%s]", value, dmark, value + 1, dmark); + else + fprintf(fp, "r%u%s", value, dmark); + } } static inline void va_print_float_src(FILE *fp, unsigned type, unsigned value, unsigned size, unsigned fau_page, bool neg, bool abs) { - if (type == VA_SRC_IMM_TYPE) { - assert(value < 32 && "overflow in LUT"); - fprintf(fp, "0x%X", va_immediates[value]); - } else { - va_print_src(fp, type, value, size, fau_page); - } + if (type == VA_SRC_IMM_TYPE) { + assert(value < 32 && "overflow in LUT"); + fprintf(fp, "0x%X", va_immediates[value]); + } else { + va_print_src(fp, type, value, size, fau_page); + } - if (neg) - fprintf(fp, ".neg"); + if (neg) + fprintf(fp, ".neg"); - if (abs) - fprintf(fp, ".abs"); + if (abs) + fprintf(fp, ".abs"); } static inline void @@ -105,91 +105,90 @@ va_print_dest(FILE *fp, unsigned mask, unsigned value, unsigned size) <%def name="print_instr(op)"> <% no_comma = True %> - fputs("${op.name}", fp); + fputs("${op.name}", fp); % for mod in op.modifiers: % if mod.name not in ["staging_register_count", "staging_register_write_count"]: % if mod.is_enum: - fputs(valhall_${safe_name(mod.enum)}[(instr >> ${mod.start}) & ${hex((1 << mod.size) - 1)}], fp); + fputs(valhall_${safe_name(mod.enum)}[(instr >> ${mod.start}) & ${hex((1 << mod.size) - 1)}], fp); % else: - if (instr & BIT(${mod.start})) fputs(".${mod.name}", fp); + if (instr & BIT(${mod.start})) fputs(".${mod.name}", fp); % endif % endif % endfor - fprintf(fp, "%s ", valhall_flow[(instr >> ${op.offset['flow']}) & ${hex(op.mask['flow'])}]); + fprintf(fp, "%s ", valhall_flow[(instr >> ${op.offset['flow']}) & ${hex(op.mask['flow'])}]); % for i, dest in enumerate(op.dests): <% no_comma = False %> - va_print_dest(fp, (instr >> ${dest.offset['mode']}) & ${hex(dest.mask['mode'])}, (instr >> ${dest.offset['value']}) & ${hex(dest.mask['value'])}, ${dest.size}); + va_print_dest(fp, (instr >> ${dest.offset['mode']}) & ${hex(dest.mask['mode'])}, (instr >> ${dest.offset['value']}) & ${hex(dest.mask['value'])}, ${dest.size}); % endfor % for index, sr in enumerate(op.staging): % if not no_comma: - fputs(", ", fp); + fputs(", ", fp); % endif <% - no_comma = False + no_comma = False - if sr.count != 0: - sr_count = sr.count; - else: - for mod in op.modifiers: - if mod.name == "staging_register_write_count" and sr.write: - sr_count = f"(((instr >> {mod.start}) & {hex((1 << mod.size) - 1)}) + 1)"; - elif mod.name == "staging_register_count": - sr_count = f"((instr >> {mod.start}) & {hex((1 << mod.size) - 1)})"; + if sr.count != 0: + sr_count = sr.count; + else: + for mod in op.modifiers: + if mod.name == "staging_register_write_count" and sr.write: + sr_count = f"(((instr >> {mod.start}) & {hex((1 << mod.size) - 1)}) + 1)"; + elif mod.name == "staging_register_count": + sr_count = f"((instr >> {mod.start}) & {hex((1 << mod.size) - 1)})"; %> -// assert(((instr >> ${sr.start}) & 0xC0) == ${sr.encoded_flags}); - fprintf(fp, "@"); - for (unsigned i = 0; i < ${sr_count}; ++i) { - fprintf(fp, "%sr%u", (i == 0) ? "" : ":", - (uint32_t) (((instr >> ${sr.offset['value']}) & ${hex(sr.mask['value'])}) + i)); - } +// assert(((instr >> ${sr.start}) & 0xC0) == ${sr.encoded_flags}); + fprintf(fp, "@"); + for (unsigned i = 0; i < ${sr_count}; ++i) { + fprintf(fp, "%sr%u", (i == 0) ? "" : ":", + (uint32_t) (((instr >> ${sr.offset['value']}) & ${hex(sr.mask['value'])}) + i)); + } % endfor % for i, src in enumerate(op.srcs): % if not no_comma: - fputs(", ", fp); + fputs(", ", fp); % endif <% no_comma = False %> % if src.absneg: - va_print_float_src(fp, (instr >> ${src.offset['mode']}) & ${hex(src.mask['mode'])}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, - ${src.size}, (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}, - instr & BIT(${src.offset['neg']}), - instr & BIT(${src.offset['abs']})); + va_print_float_src(fp, (instr >> ${src.offset['mode']}) & ${hex(src.mask['mode'])}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, + ${src.size}, (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}, + instr & BIT(${src.offset['neg']}), + instr & BIT(${src.offset['abs']})); % elif src.is_float: - va_print_float_src(fp, (instr >> ${src.offset['mode']}) & ${src.mask['mode']}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, - ${src.size}, (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}, false, false); + va_print_float_src(fp, (instr >> ${src.offset['mode']}) & ${src.mask['mode']}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, + ${src.size}, (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}, false, false); % else: - va_print_src(fp, (instr >> ${src.offset['mode']}) & ${src.mask['mode']}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, - ${src.size}, (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}); + va_print_src(fp, (instr >> ${src.offset['mode']}) & ${src.mask['mode']}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, + ${src.size}, (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}); % endif % if src.swizzle: % if src.size == 32: - fputs(valhall_widen[(instr >> ${src.offset['swizzle']}) & ${hex(src.mask['swizzle'])}], fp); + fputs(valhall_widen[(instr >> ${src.offset['swizzle']}) & ${hex(src.mask['swizzle'])}], fp); % else: - fputs(valhall_swizzles_16_bit[(instr >> ${src.offset['swizzle']}) & ${hex(src.mask['swizzle'])}], fp); + fputs(valhall_swizzles_16_bit[(instr >> ${src.offset['swizzle']}) & ${hex(src.mask['swizzle'])}], fp); % endif % endif % if src.lanes: - fputs(valhall_lanes_8_bit[(instr >> ${src.offset['widen']}) & ${hex(src.mask['widen'])}], fp); + fputs(valhall_lanes_8_bit[(instr >> ${src.offset['widen']}) & ${hex(src.mask['widen'])}], fp); % elif src.halfswizzle: - fputs(valhall_half_swizzles_8_bit[(instr >> ${src.offset['widen']}) & ${hex(src.mask['widen'])}], fp); + fputs(valhall_half_swizzles_8_bit[(instr >> ${src.offset['widen']}) & ${hex(src.mask['widen'])}], fp); % elif src.widen: - fputs(valhall_swizzles_${src.size}_bit[(instr >> ${src.offset['widen']}) & ${hex(src.mask['widen'])}], fp); + fputs(valhall_swizzles_${src.size}_bit[(instr >> ${src.offset['widen']}) & ${hex(src.mask['widen'])}], fp); % elif src.combine: - fputs(valhall_combine[(instr >> ${src.offset['combine']}) & ${hex(src.mask['combine'])}], fp); + fputs(valhall_combine[(instr >> ${src.offset['combine']}) & ${hex(src.mask['combine'])}], fp); % endif % if src.lane: - fputs(valhall_lane_${src.size}_bit[(instr >> ${src.offset['lane']}) & ${hex(src.mask['lane'])}], fp); + fputs(valhall_lane_${src.size}_bit[(instr >> ${src.offset['lane']}) & ${hex(src.mask['lane'])}], fp); % endif % if 'not' in src.offset: - if (instr & BIT(${src.offset['not']})) fputs(".not", fp); + if (instr & BIT(${src.offset['not']})) fputs(".not", fp); % endif % endfor % for imm in op.immediates: <% - prefix = "#" if imm.name == "constant" else imm.name + ":" - fmt = "%d" if imm.signed else "0x%X" + prefix = "#" if imm.name == "constant" else imm.name + ":" + fmt = "%d" if imm.signed else "0x%X" %> - fprintf(fp, ", ${prefix}${fmt}", (uint32_t) ${"SEXT(" if imm.signed else ""} - ((instr >> ${imm.start}) & MASK(${imm.size})) ${f", {imm.size})" if imm.signed else ""}); + fprintf(fp, ", ${prefix}${fmt}", (uint32_t) ${"SEXT(" if imm.signed else ""} ((instr >> ${imm.start}) & MASK(${imm.size})) ${f", {imm.size})" if imm.signed else ""}); % endfor @@ -197,16 +196,16 @@ va_print_dest(FILE *fp, unsigned mask, unsigned value, unsigned size) %if op_bucket.instr: ${print_instr(op_bucket.instr)} %else: - opcode = (instr >> ${op_bucket.start}) & ${hex(op_bucket.mask)}; - switch (opcode) { + opcode = (instr >> ${op_bucket.start}) & ${hex(op_bucket.mask)}; + switch (opcode) { %for op in op_bucket.children: - case ${hex(op)}: - { + case ${hex(op)}: + { ${recurse_subcodes(op_bucket.children[op])} - break; - } + break; + } %endfor - } + } %endif @@ -222,12 +221,12 @@ ${recurse_subcodes(OPCODES)} static bool is_branch(uint64_t instr) { <% (exact, mask) = OPCODES.get_exact_mask("BRANCHZ") %> - if ((instr & ${hex(mask)}) == ${hex(exact)}) - return true; + if ((instr & ${hex(mask)}) == ${hex(exact)}) + return true; <% (exact, mask) = OPCODES.get_exact_mask("BRANCHZI") %> - if ((instr & ${hex(mask)}) == ${hex(exact)}) - return true; - return false; + if ((instr & ${hex(mask)}) == ${hex(exact)}) + return true; + return false; } void @@ -270,46 +269,46 @@ disassemble_valhall(FILE *fp, const void *code, size_t size, bool verbose) """ class OpBucket: - def __init__(self): - self.start = None - self.mask = None - self.instr = None - self.children = {} + def __init__(self): + self.start = None + self.mask = None + self.instr = None + self.children = {} - def insert(self, subcodes, ins): - if len(subcodes) == 0: - self.instr = ins - else: - sc = subcodes[0] - assert(self.start is None or self.start == sc.start) - assert(self.mask is None or self.mask == sc.mask) - self.start = sc.start - self.mask = sc.mask - if sc.value not in self.children: - self.children[sc.value] = OpBucket() - self.children[sc.value].insert(subcodes[1:], ins) + def insert(self, subcodes, ins): + if len(subcodes) == 0: + self.instr = ins + else: + sc = subcodes[0] + assert(self.start is None or self.start == sc.start) + assert(self.mask is None or self.mask == sc.mask) + self.start = sc.start + self.mask = sc.mask + if sc.value not in self.children: + self.children[sc.value] = OpBucket() + self.children[sc.value].insert(subcodes[1:], ins) - def get_exact_mask(self, op_name, exact = 0, mask = 0): - if self.instr: - if self.instr.name == op_name: - return (exact, mask) - else: - return () - else: - for op in self.children: - exact_mask = self.children[op].get_exact_mask(op_name, - exact | (op << self.start), - mask | (self.mask << self.start)) - if exact_mask: - return exact_mask + def get_exact_mask(self, op_name, exact = 0, mask = 0): + if self.instr: + if self.instr.name == op_name: + return (exact, mask) + else: return () + else: + for op in self.children: + exact_mask = self.children[op].get_exact_mask(op_name, + exact | (op << self.start), + mask | (self.mask << self.start)) + if exact_mask: + return exact_mask + return () # Build opcode hierarchy: OPCODES = OpBucket() for ins in instructions: - OPCODES.insert(ins.opcode, ins) + OPCODES.insert(ins.opcode, ins) try: - print(Template(template).render(OPCODES = OPCODES, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name)) + print(Template(template).render(OPCODES = OPCODES, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name)) except: - print(exceptions.text_error_template().render()) + print(exceptions.text_error_template().render())