1*61046927SAndroid Build Coastguard Worker#encoding=utf-8 2*61046927SAndroid Build Coastguard Worker 3*61046927SAndroid Build Coastguard Worker# Copyright (C) 2021 Collabora, Ltd. 4*61046927SAndroid Build Coastguard Worker# 5*61046927SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a 6*61046927SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the "Software"), 7*61046927SAndroid Build Coastguard Worker# to deal in the Software without restriction, including without limitation 8*61046927SAndroid Build Coastguard Worker# the rights to use, copy, modify, merge, publish, distribute, sublicense, 9*61046927SAndroid Build Coastguard Worker# and/or sell copies of the Software, and to permit persons to whom the 10*61046927SAndroid Build Coastguard Worker# Software is furnished to do so, subject to the following conditions: 11*61046927SAndroid Build Coastguard Worker# 12*61046927SAndroid Build Coastguard Worker# The above copyright notice and this permission notice (including the next 13*61046927SAndroid Build Coastguard Worker# paragraph) shall be included in all copies or substantial portions of the 14*61046927SAndroid Build Coastguard Worker# Software. 15*61046927SAndroid Build Coastguard Worker# 16*61046927SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*61046927SAndroid Build Coastguard Worker# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*61046927SAndroid Build Coastguard Worker# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*61046927SAndroid Build Coastguard Worker# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*61046927SAndroid Build Coastguard Worker# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21*61046927SAndroid Build Coastguard Worker# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22*61046927SAndroid Build Coastguard Worker# IN THE SOFTWARE. 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Workerimport sys 25*61046927SAndroid Build Coastguard Workerfrom valhall import valhall_parse_isa 26*61046927SAndroid Build Coastguard Workerfrom mako.template import Template 27*61046927SAndroid Build Coastguard Workerfrom mako import exceptions 28*61046927SAndroid Build Coastguard Worker 29*61046927SAndroid Build Coastguard Worker(instructions, immediates, enums, typesize, safe_name) = valhall_parse_isa() 30*61046927SAndroid Build Coastguard Worker 31*61046927SAndroid Build Coastguard Workertemplate = """ 32*61046927SAndroid Build Coastguard Worker#include "disassemble.h" 33*61046927SAndroid Build Coastguard Worker 34*61046927SAndroid Build Coastguard Worker#define BIT(b) (1ull << (b)) 35*61046927SAndroid Build Coastguard Worker#define MASK(count) ((1ull << (count)) - 1) 36*61046927SAndroid Build Coastguard Worker#define SEXT(b, count) ((b ^ BIT(count - 1)) - BIT(count - 1)) 37*61046927SAndroid Build Coastguard Worker#define UNUSED __attribute__((unused)) 38*61046927SAndroid Build Coastguard Worker 39*61046927SAndroid Build Coastguard Worker#define VA_SRC_UNIFORM_TYPE 0x2 40*61046927SAndroid Build Coastguard Worker#define VA_SRC_IMM_TYPE 0x3 41*61046927SAndroid Build Coastguard Worker 42*61046927SAndroid Build Coastguard Worker% for name, en in ENUMS.items(): 43*61046927SAndroid Build Coastguard WorkerUNUSED static const char *valhall_${name}[] = { 44*61046927SAndroid Build Coastguard Worker% for v in en.values: 45*61046927SAndroid Build Coastguard Worker "${"" if v.default else "." + v.value}", 46*61046927SAndroid Build Coastguard Worker% endfor 47*61046927SAndroid Build Coastguard Worker}; 48*61046927SAndroid Build Coastguard Worker 49*61046927SAndroid Build Coastguard Worker% endfor 50*61046927SAndroid Build Coastguard Workerstatic const uint32_t va_immediates[32] = { 51*61046927SAndroid Build Coastguard Worker% for imm in IMMEDIATES: 52*61046927SAndroid Build Coastguard Worker ${hex(imm)}, 53*61046927SAndroid Build Coastguard Worker% endfor 54*61046927SAndroid Build Coastguard Worker}; 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Workerstatic inline void 57*61046927SAndroid Build Coastguard Workerva_print_src(FILE *fp, uint8_t src, unsigned fau_page) 58*61046927SAndroid Build Coastguard Worker{ 59*61046927SAndroid Build Coastguard Worker unsigned type = (src >> 6); 60*61046927SAndroid Build Coastguard Worker unsigned value = (src & 0x3F); 61*61046927SAndroid Build Coastguard Worker 62*61046927SAndroid Build Coastguard Worker if (type == VA_SRC_IMM_TYPE) { 63*61046927SAndroid Build Coastguard Worker if (value >= 32) { 64*61046927SAndroid Build Coastguard Worker if (fau_page == 0) 65*61046927SAndroid Build Coastguard Worker fputs(valhall_fau_special_page_0[(value - 0x20) >> 1] + 1, fp); 66*61046927SAndroid Build Coastguard Worker else if (fau_page == 1) 67*61046927SAndroid Build Coastguard Worker fputs(valhall_fau_special_page_1[(value - 0x20) >> 1] + 1, fp); 68*61046927SAndroid Build Coastguard Worker else if (fau_page == 3) 69*61046927SAndroid Build Coastguard Worker fputs(valhall_fau_special_page_3[(value - 0x20) >> 1] + 1, fp); 70*61046927SAndroid Build Coastguard Worker else 71*61046927SAndroid Build Coastguard Worker fprintf(fp, "reserved_page2"); 72*61046927SAndroid Build Coastguard Worker 73*61046927SAndroid Build Coastguard Worker fprintf(fp, ".w%u", value & 1); 74*61046927SAndroid Build Coastguard Worker } else { 75*61046927SAndroid Build Coastguard Worker fprintf(fp, "0x%X", va_immediates[value]); 76*61046927SAndroid Build Coastguard Worker } 77*61046927SAndroid Build Coastguard Worker } else if (type == VA_SRC_UNIFORM_TYPE) { 78*61046927SAndroid Build Coastguard Worker fprintf(fp, "u%u", value | (fau_page << 6)); 79*61046927SAndroid Build Coastguard Worker } else { 80*61046927SAndroid Build Coastguard Worker bool discard = (type & 1); 81*61046927SAndroid Build Coastguard Worker fprintf(fp, "%sr%u", discard ? "^" : "", value); 82*61046927SAndroid Build Coastguard Worker } 83*61046927SAndroid Build Coastguard Worker} 84*61046927SAndroid Build Coastguard Worker 85*61046927SAndroid Build Coastguard Workerstatic inline void 86*61046927SAndroid Build Coastguard Workerva_print_float_src(FILE *fp, uint8_t src, unsigned fau_page, bool neg, bool abs) 87*61046927SAndroid Build Coastguard Worker{ 88*61046927SAndroid Build Coastguard Worker unsigned type = (src >> 6); 89*61046927SAndroid Build Coastguard Worker unsigned value = (src & 0x3F); 90*61046927SAndroid Build Coastguard Worker 91*61046927SAndroid Build Coastguard Worker if (type == VA_SRC_IMM_TYPE) { 92*61046927SAndroid Build Coastguard Worker assert(value < 32 && "overflow in LUT"); 93*61046927SAndroid Build Coastguard Worker fprintf(fp, "0x%X", va_immediates[value]); 94*61046927SAndroid Build Coastguard Worker } else { 95*61046927SAndroid Build Coastguard Worker va_print_src(fp, src, fau_page); 96*61046927SAndroid Build Coastguard Worker } 97*61046927SAndroid Build Coastguard Worker 98*61046927SAndroid Build Coastguard Worker if (neg) 99*61046927SAndroid Build Coastguard Worker fprintf(fp, ".neg"); 100*61046927SAndroid Build Coastguard Worker 101*61046927SAndroid Build Coastguard Worker if (abs) 102*61046927SAndroid Build Coastguard Worker fprintf(fp, ".abs"); 103*61046927SAndroid Build Coastguard Worker} 104*61046927SAndroid Build Coastguard Worker 105*61046927SAndroid Build Coastguard Workerstatic inline void 106*61046927SAndroid Build Coastguard Workerva_print_dest(FILE *fp, uint8_t dest, bool can_mask) 107*61046927SAndroid Build Coastguard Worker{ 108*61046927SAndroid Build Coastguard Worker unsigned mask = (dest >> 6); 109*61046927SAndroid Build Coastguard Worker unsigned value = (dest & 0x3F); 110*61046927SAndroid Build Coastguard Worker fprintf(fp, "r%u", value); 111*61046927SAndroid Build Coastguard Worker 112*61046927SAndroid Build Coastguard Worker /* Should write at least one component */ 113*61046927SAndroid Build Coastguard Worker // assert(mask != 0); 114*61046927SAndroid Build Coastguard Worker // assert(mask == 0x3 || can_mask); 115*61046927SAndroid Build Coastguard Worker 116*61046927SAndroid Build Coastguard Worker if (mask != 0x3) 117*61046927SAndroid Build Coastguard Worker fprintf(fp, ".h%u", (mask == 1) ? 0 : 1); 118*61046927SAndroid Build Coastguard Worker} 119*61046927SAndroid Build Coastguard Worker 120*61046927SAndroid Build Coastguard Workervoid 121*61046927SAndroid Build Coastguard Workerva_disasm_instr(FILE *fp, uint64_t instr) 122*61046927SAndroid Build Coastguard Worker{ 123*61046927SAndroid Build Coastguard Worker unsigned primary_opc = (instr >> 48) & MASK(9); 124*61046927SAndroid Build Coastguard Worker unsigned fau_page = (instr >> 57) & MASK(2); 125*61046927SAndroid Build Coastguard Worker unsigned secondary_opc = 0; 126*61046927SAndroid Build Coastguard Worker 127*61046927SAndroid Build Coastguard Worker switch (primary_opc) { 128*61046927SAndroid Build Coastguard Worker% for bucket in OPCODES: 129*61046927SAndroid Build Coastguard Worker <% 130*61046927SAndroid Build Coastguard Worker ops = OPCODES[bucket] 131*61046927SAndroid Build Coastguard Worker ambiguous = (len(ops) > 1) 132*61046927SAndroid Build Coastguard Worker %> 133*61046927SAndroid Build Coastguard Worker% if len(ops) > 0: 134*61046927SAndroid Build Coastguard Worker case ${hex(bucket)}: 135*61046927SAndroid Build Coastguard Worker% if ambiguous: 136*61046927SAndroid Build Coastguard Worker secondary_opc = (instr >> ${ops[0].secondary_shift}) & ${hex(ops[0].secondary_mask)}; 137*61046927SAndroid Build Coastguard Worker% endif 138*61046927SAndroid Build Coastguard Worker% for op in ops: 139*61046927SAndroid Build Coastguard Worker<% no_comma = True %> 140*61046927SAndroid Build Coastguard Worker% if ambiguous: 141*61046927SAndroid Build Coastguard Worker 142*61046927SAndroid Build Coastguard Worker if (secondary_opc == ${op.opcode2}) { 143*61046927SAndroid Build Coastguard Worker% endif 144*61046927SAndroid Build Coastguard Worker fputs("${op.name}", fp); 145*61046927SAndroid Build Coastguard Worker% for mod in op.modifiers: 146*61046927SAndroid Build Coastguard Worker% if mod.name not in ["left", "memory_width", "descriptor_type", "staging_register_count", "staging_register_write_count"]: 147*61046927SAndroid Build Coastguard Worker% if mod.is_enum: 148*61046927SAndroid Build Coastguard Worker fputs(valhall_${safe_name(mod.enum)}[(instr >> ${mod.start}) & ${hex((1 << mod.size) - 1)}], fp); 149*61046927SAndroid Build Coastguard Worker% else: 150*61046927SAndroid Build Coastguard Worker if (instr & BIT(${mod.start})) fputs(".${mod.name}", fp); 151*61046927SAndroid Build Coastguard Worker% endif 152*61046927SAndroid Build Coastguard Worker% endif 153*61046927SAndroid Build Coastguard Worker% endfor 154*61046927SAndroid Build Coastguard Worker assert((instr & (1ull << 63)) == 0 /* reserved */); 155*61046927SAndroid Build Coastguard Worker fprintf(fp, "%s ", valhall_flow[instr >> 59]); 156*61046927SAndroid Build Coastguard Worker% if len(op.dests) > 0: 157*61046927SAndroid Build Coastguard Worker<% no_comma = False %> 158*61046927SAndroid Build Coastguard Worker va_print_dest(fp, (instr >> 40), true); 159*61046927SAndroid Build Coastguard Worker% endif 160*61046927SAndroid Build Coastguard Worker% for index, sr in enumerate(op.staging): 161*61046927SAndroid Build Coastguard Worker% if not no_comma: 162*61046927SAndroid Build Coastguard Worker fputs(", ", fp); 163*61046927SAndroid Build Coastguard Worker% endif 164*61046927SAndroid Build Coastguard Worker<% 165*61046927SAndroid Build Coastguard Worker no_comma = False 166*61046927SAndroid Build Coastguard Worker 167*61046927SAndroid Build Coastguard Worker if sr.count != 0: 168*61046927SAndroid Build Coastguard Worker sr_count = sr.count 169*61046927SAndroid Build Coastguard Worker elif "staging_register_write_count" in [x.name for x in op.modifiers] and sr.write: 170*61046927SAndroid Build Coastguard Worker sr_count = "(((instr >> 36) & MASK(3)) + 1)" 171*61046927SAndroid Build Coastguard Worker elif "staging_register_count" in [x.name for x in op.modifiers]: 172*61046927SAndroid Build Coastguard Worker sr_count = "((instr >> 33) & MASK(3))" 173*61046927SAndroid Build Coastguard Worker else: 174*61046927SAndroid Build Coastguard Worker assert(0) 175*61046927SAndroid Build Coastguard Worker%> 176*61046927SAndroid Build Coastguard Worker// assert(((instr >> ${sr.start}) & 0xC0) == ${sr.encoded_flags}); 177*61046927SAndroid Build Coastguard Worker fprintf(fp, "@"); 178*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ${sr_count}; ++i) { 179*61046927SAndroid Build Coastguard Worker fprintf(fp, "%sr%u", (i == 0) ? "" : ":", 180*61046927SAndroid Build Coastguard Worker (uint32_t) (((instr >> ${sr.start}) & 0x3F) + i)); 181*61046927SAndroid Build Coastguard Worker } 182*61046927SAndroid Build Coastguard Worker% endfor 183*61046927SAndroid Build Coastguard Worker% for i, src in enumerate(op.srcs): 184*61046927SAndroid Build Coastguard Worker% if not no_comma: 185*61046927SAndroid Build Coastguard Worker fputs(", ", fp); 186*61046927SAndroid Build Coastguard Worker% endif 187*61046927SAndroid Build Coastguard Worker<% no_comma = False %> 188*61046927SAndroid Build Coastguard Worker% if src.absneg: 189*61046927SAndroid Build Coastguard Worker va_print_float_src(fp, instr >> ${src.start}, fau_page, 190*61046927SAndroid Build Coastguard Worker instr & BIT(${src.offset['neg']}), 191*61046927SAndroid Build Coastguard Worker instr & BIT(${src.offset['abs']})); 192*61046927SAndroid Build Coastguard Worker% elif src.is_float: 193*61046927SAndroid Build Coastguard Worker va_print_float_src(fp, instr >> ${src.start}, fau_page, false, false); 194*61046927SAndroid Build Coastguard Worker% else: 195*61046927SAndroid Build Coastguard Worker va_print_src(fp, instr >> ${src.start}, fau_page); 196*61046927SAndroid Build Coastguard Worker% endif 197*61046927SAndroid Build Coastguard Worker% if src.swizzle: 198*61046927SAndroid Build Coastguard Worker% if src.size == 32: 199*61046927SAndroid Build Coastguard Worker fputs(valhall_widen[(instr >> ${src.offset['swizzle']}) & 3], fp); 200*61046927SAndroid Build Coastguard Worker% else: 201*61046927SAndroid Build Coastguard Worker fputs(valhall_swizzles_16_bit[(instr >> ${src.offset['swizzle']}) & 3], fp); 202*61046927SAndroid Build Coastguard Worker% endif 203*61046927SAndroid Build Coastguard Worker% endif 204*61046927SAndroid Build Coastguard Worker% if src.lanes: 205*61046927SAndroid Build Coastguard Worker fputs(valhall_lanes_8_bit[(instr >> ${src.offset['widen']}) & 0xF], fp); 206*61046927SAndroid Build Coastguard Worker% elif src.halfswizzle: 207*61046927SAndroid Build Coastguard Worker fputs(valhall_half_swizzles_8_bit[(instr >> ${src.offset['widen']}) & 0xF], fp); 208*61046927SAndroid Build Coastguard Worker% elif src.widen: 209*61046927SAndroid Build Coastguard Worker fputs(valhall_swizzles_${src.size}_bit[(instr >> ${src.offset['widen']}) & 0xF], fp); 210*61046927SAndroid Build Coastguard Worker% elif src.combine: 211*61046927SAndroid Build Coastguard Worker fputs(valhall_combine[(instr >> ${src.offset['combine']}) & 0x7], fp); 212*61046927SAndroid Build Coastguard Worker% endif 213*61046927SAndroid Build Coastguard Worker% if src.lane: 214*61046927SAndroid Build Coastguard Worker fputs(valhall_lane_${src.size}_bit[(instr >> ${src.lane}) & 0x3], fp); 215*61046927SAndroid Build Coastguard Worker% endif 216*61046927SAndroid Build Coastguard Worker% if 'not' in src.offset: 217*61046927SAndroid Build Coastguard Worker if (instr & BIT(${src.offset['not']})) fputs(".not", fp); 218*61046927SAndroid Build Coastguard Worker% endif 219*61046927SAndroid Build Coastguard Worker% endfor 220*61046927SAndroid Build Coastguard Worker% for imm in op.immediates: 221*61046927SAndroid Build Coastguard Worker<% 222*61046927SAndroid Build Coastguard Worker prefix = "#" if imm.name == "constant" else imm.name + ":" 223*61046927SAndroid Build Coastguard Worker fmt = "%d" if imm.signed else "0x%X" 224*61046927SAndroid Build Coastguard Worker%> 225*61046927SAndroid Build Coastguard Worker fprintf(fp, ", ${prefix}${fmt}", (uint32_t) ${"SEXT(" if imm.signed else ""} 226*61046927SAndroid Build Coastguard Worker ((instr >> ${imm.start}) & MASK(${imm.size})) ${f", {imm.size})" if imm.signed else ""}); 227*61046927SAndroid Build Coastguard Worker% endfor 228*61046927SAndroid Build Coastguard Worker% if ambiguous: 229*61046927SAndroid Build Coastguard Worker } 230*61046927SAndroid Build Coastguard Worker% endif 231*61046927SAndroid Build Coastguard Worker% endfor 232*61046927SAndroid Build Coastguard Worker break; 233*61046927SAndroid Build Coastguard Worker 234*61046927SAndroid Build Coastguard Worker% endif 235*61046927SAndroid Build Coastguard Worker% endfor 236*61046927SAndroid Build Coastguard Worker } 237*61046927SAndroid Build Coastguard Worker} 238*61046927SAndroid Build Coastguard Worker 239*61046927SAndroid Build Coastguard Workervoid 240*61046927SAndroid Build Coastguard Workerdisassemble_valhall(FILE *fp, const void *code, size_t size, bool verbose) 241*61046927SAndroid Build Coastguard Worker{ 242*61046927SAndroid Build Coastguard Worker assert((size & 7) == 0); 243*61046927SAndroid Build Coastguard Worker 244*61046927SAndroid Build Coastguard Worker const uint64_t *words = (const uint64_t *)code; 245*61046927SAndroid Build Coastguard Worker 246*61046927SAndroid Build Coastguard Worker /* Segment into 8-byte instructions */ 247*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < (size / 8); ++i) { 248*61046927SAndroid Build Coastguard Worker uint64_t instr = words[i]; 249*61046927SAndroid Build Coastguard Worker 250*61046927SAndroid Build Coastguard Worker if (instr == 0) { 251*61046927SAndroid Build Coastguard Worker fprintf(fp, "\\n"); 252*61046927SAndroid Build Coastguard Worker return; 253*61046927SAndroid Build Coastguard Worker } 254*61046927SAndroid Build Coastguard Worker 255*61046927SAndroid Build Coastguard Worker if (verbose) { 256*61046927SAndroid Build Coastguard Worker /* Print byte pattern */ 257*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < 8; ++j) 258*61046927SAndroid Build Coastguard Worker fprintf(fp, "%02x ", (uint8_t)(instr >> (j * 8))); 259*61046927SAndroid Build Coastguard Worker 260*61046927SAndroid Build Coastguard Worker fprintf(fp, " "); 261*61046927SAndroid Build Coastguard Worker } else { 262*61046927SAndroid Build Coastguard Worker /* Print whitespace */ 263*61046927SAndroid Build Coastguard Worker fprintf(fp, " "); 264*61046927SAndroid Build Coastguard Worker } 265*61046927SAndroid Build Coastguard Worker 266*61046927SAndroid Build Coastguard Worker va_disasm_instr(fp, instr); 267*61046927SAndroid Build Coastguard Worker fprintf(fp, "\\n"); 268*61046927SAndroid Build Coastguard Worker 269*61046927SAndroid Build Coastguard Worker /* Detect branches */ 270*61046927SAndroid Build Coastguard Worker uint64_t opcode = (instr >> 48) & MASK(9); 271*61046927SAndroid Build Coastguard Worker bool branchz = (opcode == 0x1F); 272*61046927SAndroid Build Coastguard Worker bool branchzi = (opcode == 0x2F); 273*61046927SAndroid Build Coastguard Worker 274*61046927SAndroid Build Coastguard Worker /* Separate blocks visually by inserting whitespace after branches */ 275*61046927SAndroid Build Coastguard Worker if (branchz || branchzi) 276*61046927SAndroid Build Coastguard Worker fprintf(fp, "\\n"); 277*61046927SAndroid Build Coastguard Worker } 278*61046927SAndroid Build Coastguard Worker 279*61046927SAndroid Build Coastguard Worker fprintf(fp, "\\n"); 280*61046927SAndroid Build Coastguard Worker} 281*61046927SAndroid Build Coastguard Worker""" 282*61046927SAndroid Build Coastguard Worker 283*61046927SAndroid Build Coastguard Worker# Bucket by opcode for hierarchical disassembly 284*61046927SAndroid Build Coastguard WorkerOPCODE_BUCKETS = {} 285*61046927SAndroid Build Coastguard Workerfor ins in instructions: 286*61046927SAndroid Build Coastguard Worker opc = ins.opcode 287*61046927SAndroid Build Coastguard Worker OPCODE_BUCKETS[opc] = OPCODE_BUCKETS.get(opc, []) + [ins] 288*61046927SAndroid Build Coastguard Worker 289*61046927SAndroid Build Coastguard Worker# Check that each bucket may be disambiguated 290*61046927SAndroid Build Coastguard Workerfor op in OPCODE_BUCKETS: 291*61046927SAndroid Build Coastguard Worker bucket = OPCODE_BUCKETS[op] 292*61046927SAndroid Build Coastguard Worker 293*61046927SAndroid Build Coastguard Worker # Nothing to disambiguate 294*61046927SAndroid Build Coastguard Worker if len(bucket) < 2: 295*61046927SAndroid Build Coastguard Worker continue 296*61046927SAndroid Build Coastguard Worker 297*61046927SAndroid Build Coastguard Worker SECONDARY = {} 298*61046927SAndroid Build Coastguard Worker for ins in bucket: 299*61046927SAndroid Build Coastguard Worker # Number of sources determines opcode2 placement, must be consistent 300*61046927SAndroid Build Coastguard Worker assert(len(ins.srcs) == len(bucket[0].srcs)) 301*61046927SAndroid Build Coastguard Worker 302*61046927SAndroid Build Coastguard Worker # Must not repeat, else we're ambiguous 303*61046927SAndroid Build Coastguard Worker assert(ins.opcode2 not in SECONDARY) 304*61046927SAndroid Build Coastguard Worker SECONDARY[ins.opcode2] = ins 305*61046927SAndroid Build Coastguard Worker 306*61046927SAndroid Build Coastguard Workertry: 307*61046927SAndroid Build Coastguard Worker print(Template(template).render(OPCODES = OPCODE_BUCKETS, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name)) 308*61046927SAndroid Build Coastguard Workerexcept: 309*61046927SAndroid Build Coastguard Worker print(exceptions.text_error_template().render()) 310