diff --git a/src/panfrost/compiler/bifrost/valhall/asm.py b/src/panfrost/compiler/bifrost/valhall/asm.py index 2e001fda929..563733f06cc 100644 --- a/src/panfrost/compiler/bifrost/valhall/asm.py +++ b/src/panfrost/compiler/bifrost/valhall/asm.py @@ -215,7 +215,7 @@ def parse_asm(line): for mod in parts[1:]: # Encode the modifier - if mod in src.offset and src.bits[mod] == 1: + if mod in src.offset and src.mask[mod] == 0x1: encoded |= (1 << src.offset[mod]) elif src.halfswizzle and mod in enums[f'half_swizzles_{src.size}_bit'].bare_values: die_if(swizzled, "Multiple swizzles specified") @@ -320,7 +320,7 @@ def parse_asm(line): # Encode FAU page if fau.page: - encoded |= (fau.page << 57) + encoded |= (fau.page << ins.offset['fau_page']) # Encode modifiers has_flow = False @@ -331,7 +331,7 @@ def parse_asm(line): if mod in enums['flow'].bare_values: die_if(has_flow, "Multiple flow control modifiers specified") has_flow = True - encoded |= (enums['flow'].bare_values.index(mod) << 59) + encoded |= (enums['flow'].bare_values.index(mod) << ins.offset['flow']) else: candidates = [c for c in ins.modifiers if mod in c.bare_values] diff --git a/src/panfrost/compiler/bifrost/valhall/disasm.py b/src/panfrost/compiler/bifrost/valhall/disasm.py index a627dd8ac5c..6563b82bba3 100644 --- a/src/panfrost/compiler/bifrost/valhall/disasm.py +++ b/src/panfrost/compiler/bifrost/valhall/disasm.py @@ -43,11 +43,8 @@ static const uint32_t va_immediates[32] = { }; static inline void -va_print_src(FILE *fp, uint8_t src, unsigned fau_page) +va_print_src(FILE *fp, unsigned type, unsigned value, unsigned fau_page) { - unsigned type = (src >> 6); - unsigned value = (src & 0x3F); - if (type == VA_SRC_IMM_TYPE) { if (value >= 32) { if (fau_page == 0) @@ -72,16 +69,13 @@ va_print_src(FILE *fp, uint8_t src, unsigned fau_page) } static inline void -va_print_float_src(FILE *fp, uint8_t src, unsigned fau_page, bool neg, bool abs) +va_print_float_src(FILE *fp, unsigned type, unsigned value, unsigned fau_page, bool neg, bool abs) { - unsigned type = (src >> 6); - unsigned value = (src & 0x3F); - if (type == VA_SRC_IMM_TYPE) { assert(value < 32 && "overflow in LUT"); fprintf(fp, "0x%X", va_immediates[value]); } else { - va_print_src(fp, src, fau_page); + va_print_src(fp, type, value, fau_page); } if (neg) @@ -92,10 +86,8 @@ va_print_float_src(FILE *fp, uint8_t src, unsigned fau_page, bool neg, bool abs) } static inline void -va_print_dest(FILE *fp, uint8_t dest, bool can_mask) +va_print_dest(FILE *fp, unsigned mask, unsigned value, bool can_mask) { - unsigned mask = (dest >> 6); - unsigned value = (dest & 0x3F); fprintf(fp, "r%u", value); /* Should write at least one component */ @@ -118,12 +110,11 @@ va_print_dest(FILE *fp, uint8_t dest, bool can_mask) % endif % endif % endfor - assert((instr & (1ull << 63)) == 0 /* reserved */); - fprintf(fp, "%s ", valhall_flow[instr >> 59]); -% if len(op.dests) > 0: + 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 >> 40), true); -% endif + va_print_dest(fp, (instr >> ${dest.offset['mode']}) & ${hex(dest.mask['mode'])}, (instr >> ${dest.offset['value']}) & ${hex(dest.mask['value'])}, true); +% endfor % for index, sr in enumerate(op.staging): % if not no_comma: fputs(", ", fp); @@ -132,19 +123,19 @@ va_print_dest(FILE *fp, uint8_t dest, bool can_mask) no_comma = False if sr.count != 0: - sr_count = sr.count - elif "staging_register_write_count" in [x.name for x in op.modifiers] and sr.write: - sr_count = "(((instr >> 36) & MASK(3)) + 1)" - elif "staging_register_count" in [x.name for x in op.modifiers]: - sr_count = "((instr >> 33) & MASK(3))" + sr_count = sr.count; else: - assert(0) + 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.start}) & 0x3F) + i)); + (uint32_t) (((instr >> ${sr.offset['value']}) & ${hex(sr.mask['value'])}) + i)); } % endfor % for i, src in enumerate(op.srcs): @@ -153,32 +144,35 @@ va_print_dest(FILE *fp, uint8_t dest, bool can_mask) % endif <% no_comma = False %> % if src.absneg: - va_print_float_src(fp, instr >> ${src.start}, fau_page, + va_print_float_src(fp, (instr >> ${src.offset['mode']}) & ${hex(src.mask['mode'])}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, + (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.start}, fau_page, false, false); + va_print_float_src(fp, (instr >> ${src.offset['mode']}) & ${src.mask['mode']}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, + (instr >> ${op.offset['fau_page']}) & ${hex(op.mask['fau_page'])}, false, false); % else: - va_print_src(fp, instr >> ${src.start}, fau_page); + va_print_src(fp, (instr >> ${src.offset['mode']}) & ${src.mask['mode']}, (instr >> ${src.offset['value']}) & ${hex(src.mask['value'])}, + (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']}) & 3], fp); + fputs(valhall_widen[(instr >> ${src.offset['swizzle']}) & ${hex(src.mask['swizzle'])}], fp); % else: - fputs(valhall_swizzles_16_bit[(instr >> ${src.offset['swizzle']}) & 3], 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']}) & 0xF], 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']}) & 0xF], 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']}) & 0xF], 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']}) & 0x7], 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.lane}) & 0x3], 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); @@ -216,7 +210,6 @@ void va_disasm_instr(FILE *fp, uint64_t instr) { unsigned opcode; - unsigned fau_page = (instr >> 57) & MASK(2); ${recurse_subcodes(OPCODES)} } diff --git a/src/panfrost/compiler/bifrost/valhall/valhall.py b/src/panfrost/compiler/bifrost/valhall/valhall.py index 366fc3c240c..326d2e28977 100644 --- a/src/panfrost/compiler/bifrost/valhall/valhall.py +++ b/src/panfrost/compiler/bifrost/valhall/valhall.py @@ -21,6 +21,9 @@ def xmlbool(s): assert(s.lower() in ["false", "true"]) return False if s.lower() == "false" else True +def bitmask(size): + return (1 << size) - 1 + class EnumValue: def __init__(self, value, default): self.value = value @@ -92,32 +95,46 @@ class Source: self.name = name self.offset = {} - self.bits = {} + self.mask = {} + + self.offset['mode'] = self.start + 6 + self.mask['mode'] = bitmask(2) + self.offset['value'] = self.start + self.mask['value'] = bitmask(6) + if absneg: self.offset['neg'] = 32 + 2 + ((2 - index) * 2) self.offset['abs'] = 33 + 2 + ((2 - index) * 2) - self.bits['neg'] = 1 - self.bits['abs'] = 1 + self.mask['neg'] = bitmask(1) + self.mask['abs'] = bitmask(1) if notted: self.offset['not'] = 35 - self.bits['not'] = 1 + self.mask['not'] = bitmask(1) if widen or lanes or halfswizzle: self.offset['widen'] = 26 if index == 1 else 36 - self.bits['widen'] = 4 # XXX: too much? + self.mask['widen'] = bitmask(4) if lane: self.offset['lane'] = self.lane - self.bits['lane'] = 2 if size in (8, 32) else 1 + self.mask['lane'] = bitmask(2) if size in (8, 32) else bitmask(1) if swizzle: assert(size in [16, 32]) self.offset['swizzle'] = 24 + ((2 - index) * 2) - self.bits['swizzle'] = 2 + self.mask['swizzle'] = bitmask(2) if combine: self.offset['combine'] = 37 - self.bits['combine'] = 3 + self.mask['combine'] = bitmask(3) class Dest: def __init__(self, name = ""): self.name = name + self.start = 40 + self.offset = {} + self.mask = {} + + self.offset['mode'] = self.start + 6 + self.mask['mode'] = bitmask(2) + self.offset['value'] = self.start + self.mask['value'] = bitmask(6) class Staging: def __init__(self, read = False, write = False, count = 0, flags = 'true', name = ""): @@ -127,9 +144,13 @@ class Staging: self.count = count self.flags = (flags != 'false') self.start = 40 - if write and not self.flags: self.start = 16 + self.offset = {} + self.mask = {} + + self.offset['value'] = self.start + self.mask['value'] = bitmask(6) # For compatibility self.absneg = False @@ -175,6 +196,14 @@ class Instruction: self.unit = unit self.is_signed = len(name.split(".")) > 1 and ('s' in name.split(".")[1]) + self.offset = {} + self.mask = {} + + self.offset['flow'] = 59 + self.mask['flow'] = bitmask(4) + self.offset['fau_page'] = 57 + self.mask['fau_page'] = bitmask(2) + # Message-passing instruction <===> not ALU instruction self.message = unit not in ["FMA", "CVT", "SFU"]