1bf215546Sopenharmony_ci#encoding=utf-8 2bf215546Sopenharmony_ci 3bf215546Sopenharmony_ci# Copyright (C) 2016 Intel Corporation 4bf215546Sopenharmony_ci# Copyright (C) 2016 Broadcom 5bf215546Sopenharmony_ci# Copyright (C) 2020 Collabora, Ltd. 6bf215546Sopenharmony_ci# 7bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci# the rights to use, copy, modify, merge, publish, distribute, sublicense, 11bf215546Sopenharmony_ci# and/or sell copies of the Software, and to permit persons to whom the 12bf215546Sopenharmony_ci# Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci# 14bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 15bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 16bf215546Sopenharmony_ci# Software. 17bf215546Sopenharmony_ci# 18bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21bf215546Sopenharmony_ci# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24bf215546Sopenharmony_ci# IN THE SOFTWARE. 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ciimport os 27bf215546Sopenharmony_ciimport textwrap 28bf215546Sopenharmony_ciimport xml.etree.ElementTree as ET 29bf215546Sopenharmony_ciimport sys 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_citree = ET.parse(os.path.join(os.path.dirname(__file__), 'ISA.xml')) 32bf215546Sopenharmony_ciroot = tree.getroot() 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci# All instructions in the ISA 35bf215546Sopenharmony_ciinstructions = [] 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci# All immediates in the ISA 38bf215546Sopenharmony_ciilut = root.findall('lut')[0] 39bf215546Sopenharmony_ciassert(ilut.attrib['name'] == "Immediates") 40bf215546Sopenharmony_ciimmediates = [int(imm.text, base=0) for imm in ilut.findall('constant')] 41bf215546Sopenharmony_cienums = {} 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cidef xmlbool(s): 44bf215546Sopenharmony_ci assert(s.lower() in ["false", "true"]) 45bf215546Sopenharmony_ci return False if s.lower() == "false" else True 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ciclass EnumValue: 48bf215546Sopenharmony_ci def __init__(self, value, default): 49bf215546Sopenharmony_ci self.value = value 50bf215546Sopenharmony_ci self.default = default 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ciclass Enum: 53bf215546Sopenharmony_ci def __init__(self, name, values): 54bf215546Sopenharmony_ci self.name = name 55bf215546Sopenharmony_ci self.values = values 56bf215546Sopenharmony_ci self.bare_values = [x.value for x in values] 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci defaults = [x.value for x in values if x.default] 59bf215546Sopenharmony_ci if len(defaults) > 0: 60bf215546Sopenharmony_ci assert(len(defaults) == 1) 61bf215546Sopenharmony_ci self.default = defaults[0] 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_cidef build_enum(el): 64bf215546Sopenharmony_ci values = [] 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci for child in el: 67bf215546Sopenharmony_ci if child.tag == 'value': 68bf215546Sopenharmony_ci is_default = child.attrib.get('default', False) 69bf215546Sopenharmony_ci values.append(EnumValue(child.text, is_default)) 70bf215546Sopenharmony_ci elif child.tag == 'reserved': 71bf215546Sopenharmony_ci values.append(EnumValue("reserved", False)) 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci return Enum(el.attrib['name'], values) 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ciclass Modifier: 76bf215546Sopenharmony_ci def __init__(self, name, start, size, implied = False, force_enum = None): 77bf215546Sopenharmony_ci self.name = name 78bf215546Sopenharmony_ci self.start = start 79bf215546Sopenharmony_ci self.size = size 80bf215546Sopenharmony_ci self.implied = implied 81bf215546Sopenharmony_ci self.is_enum = (force_enum is not None) or size > 1 82bf215546Sopenharmony_ci self.enum = force_enum or name 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci if not self.is_enum: 85bf215546Sopenharmony_ci self.bare_values = ['', name] 86bf215546Sopenharmony_ci self.default = 0 87bf215546Sopenharmony_ci else: 88bf215546Sopenharmony_ci self.bare_values = [x.value for x in enums[self.enum].values] 89bf215546Sopenharmony_ci defaults = [x for x in enums[self.enum].values if x.default] 90bf215546Sopenharmony_ci assert(len(defaults) <= 1) 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci if len(defaults) > 0: 93bf215546Sopenharmony_ci self.default = self.bare_values.index(defaults[0].value) 94bf215546Sopenharmony_ci else: 95bf215546Sopenharmony_ci self.default = None 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_cidef Flag(name, start): 98bf215546Sopenharmony_ci return Modifier(name, start, 1) 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci# Model a single instruction 101bf215546Sopenharmony_ciclass Source: 102bf215546Sopenharmony_ci def __init__(self, index, size, is_float = False, swizzle = False, 103bf215546Sopenharmony_ci halfswizzle = False, widen = False, lanes = False, combine = False, lane = None, absneg = False, notted = False, name = ""): 104bf215546Sopenharmony_ci self.is_float = is_float or absneg 105bf215546Sopenharmony_ci self.start = (index * 8) 106bf215546Sopenharmony_ci self.size = size 107bf215546Sopenharmony_ci self.absneg = absneg 108bf215546Sopenharmony_ci self.notted = notted 109bf215546Sopenharmony_ci self.swizzle = swizzle 110bf215546Sopenharmony_ci self.halfswizzle = halfswizzle 111bf215546Sopenharmony_ci self.widen = widen 112bf215546Sopenharmony_ci self.lanes = lanes 113bf215546Sopenharmony_ci self.lane = lane 114bf215546Sopenharmony_ci self.combine = combine 115bf215546Sopenharmony_ci self.name = name 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci self.offset = {} 118bf215546Sopenharmony_ci self.bits = {} 119bf215546Sopenharmony_ci if absneg: 120bf215546Sopenharmony_ci self.offset['neg'] = 32 + 2 + ((2 - index) * 2) 121bf215546Sopenharmony_ci self.offset['abs'] = 33 + 2 + ((2 - index) * 2) 122bf215546Sopenharmony_ci self.bits['neg'] = 1 123bf215546Sopenharmony_ci self.bits['abs'] = 1 124bf215546Sopenharmony_ci if notted: 125bf215546Sopenharmony_ci self.offset['not'] = 35 126bf215546Sopenharmony_ci self.bits['not'] = 1 127bf215546Sopenharmony_ci if widen or lanes or halfswizzle: 128bf215546Sopenharmony_ci self.offset['widen'] = 26 if index == 1 else 36 129bf215546Sopenharmony_ci self.bits['widen'] = 4 # XXX: too much? 130bf215546Sopenharmony_ci if lane: 131bf215546Sopenharmony_ci self.offset['lane'] = self.lane 132bf215546Sopenharmony_ci self.bits['lane'] = 2 if size in (8, 32) else 1 133bf215546Sopenharmony_ci if swizzle: 134bf215546Sopenharmony_ci assert(size in [16, 32]) 135bf215546Sopenharmony_ci self.offset['swizzle'] = 24 + ((2 - index) * 2) 136bf215546Sopenharmony_ci self.bits['swizzle'] = 2 137bf215546Sopenharmony_ci if combine: 138bf215546Sopenharmony_ci self.offset['combine'] = 37 139bf215546Sopenharmony_ci self.bits['combine'] = 3 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ciclass Dest: 142bf215546Sopenharmony_ci def __init__(self, name = ""): 143bf215546Sopenharmony_ci self.name = name 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ciclass Staging: 146bf215546Sopenharmony_ci def __init__(self, read = False, write = False, count = 0, flags = 'true', name = ""): 147bf215546Sopenharmony_ci self.name = name 148bf215546Sopenharmony_ci self.read = read 149bf215546Sopenharmony_ci self.write = write 150bf215546Sopenharmony_ci self.count = count 151bf215546Sopenharmony_ci self.flags = (flags != 'false') 152bf215546Sopenharmony_ci self.start = 40 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci if write and not self.flags: 155bf215546Sopenharmony_ci self.start = 16 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci # For compatibility 158bf215546Sopenharmony_ci self.absneg = False 159bf215546Sopenharmony_ci self.swizzle = False 160bf215546Sopenharmony_ci self.notted = False 161bf215546Sopenharmony_ci self.widen = False 162bf215546Sopenharmony_ci self.lanes = False 163bf215546Sopenharmony_ci self.lane = False 164bf215546Sopenharmony_ci self.halfswizzle = False 165bf215546Sopenharmony_ci self.combine = False 166bf215546Sopenharmony_ci self.size = 32 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci if not self.flags: 169bf215546Sopenharmony_ci self.encoded_flags = 0 170bf215546Sopenharmony_ci elif flags == 'rw': 171bf215546Sopenharmony_ci self.encoded_flags = 0xc0 172bf215546Sopenharmony_ci else: 173bf215546Sopenharmony_ci assert(flags == 'true') 174bf215546Sopenharmony_ci self.encoded_flags = (0x80 if write else 0) | (0x40 if read else 0) 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ciclass Immediate: 177bf215546Sopenharmony_ci def __init__(self, name, start, size, signed): 178bf215546Sopenharmony_ci self.name = name 179bf215546Sopenharmony_ci self.start = start 180bf215546Sopenharmony_ci self.size = size 181bf215546Sopenharmony_ci self.signed = signed 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ciclass Instruction: 184bf215546Sopenharmony_ci def __init__(self, name, opcode, opcode2, srcs = [], dests = [], immediates = [], modifiers = [], staging = None, unit = None): 185bf215546Sopenharmony_ci self.name = name 186bf215546Sopenharmony_ci self.srcs = srcs 187bf215546Sopenharmony_ci self.dests = dests 188bf215546Sopenharmony_ci self.opcode = opcode 189bf215546Sopenharmony_ci self.opcode2 = opcode2 or 0 190bf215546Sopenharmony_ci self.immediates = immediates 191bf215546Sopenharmony_ci self.modifiers = modifiers 192bf215546Sopenharmony_ci self.staging = staging 193bf215546Sopenharmony_ci self.unit = unit 194bf215546Sopenharmony_ci self.is_signed = len(name.split(".")) > 1 and ('s' in name.split(".")[1]) 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci # Message-passing instruction <===> not ALU instruction 197bf215546Sopenharmony_ci self.message = unit not in ["FMA", "CVT", "SFU"] 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci self.secondary_shift = max(len(self.srcs) * 8, 16) 200bf215546Sopenharmony_ci self.secondary_mask = 0xF if opcode2 is not None else 0x0 201bf215546Sopenharmony_ci if "left" in [x.name for x in self.modifiers]: 202bf215546Sopenharmony_ci self.secondary_mask |= 0x100 203bf215546Sopenharmony_ci if len(srcs) == 3 and (srcs[1].widen or srcs[1].lanes): 204bf215546Sopenharmony_ci self.secondary_mask &= ~0xC # conflicts 205bf215546Sopenharmony_ci if opcode == 0x90: 206bf215546Sopenharmony_ci # XXX: XMLify this, but disambiguates sign of conversions 207bf215546Sopenharmony_ci self.secondary_mask |= 0x10 208bf215546Sopenharmony_ci if name.startswith("LOAD.i") or name.startswith("STORE.i") or name.startswith("LD_BUFFER.i"): 209bf215546Sopenharmony_ci self.secondary_shift = 27 # Alias with memory_size 210bf215546Sopenharmony_ci self.secondary_mask = 0x7 211bf215546Sopenharmony_ci if "descriptor_type" in [x.name for x in self.modifiers]: 212bf215546Sopenharmony_ci self.secondary_mask = 0x3 213bf215546Sopenharmony_ci self.secondary_shift = 37 214bf215546Sopenharmony_ci elif "memory_width" in [x.name for x in self.modifiers]: 215bf215546Sopenharmony_ci self.secondary_mask = 0x7 216bf215546Sopenharmony_ci self.secondary_shift = 27 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci assert(len(dests) == 0 or not staging) 219bf215546Sopenharmony_ci assert(not opcode2 or (opcode2 & self.secondary_mask) == opcode2) 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci def __str__(self): 222bf215546Sopenharmony_ci return self.name 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci# Build a single source from XML 225bf215546Sopenharmony_cidef build_source(el, i, size): 226bf215546Sopenharmony_ci lane = el.get('lane', None) 227bf215546Sopenharmony_ci if lane == "true": 228bf215546Sopenharmony_ci lane = 38 if i == 0 else 36 229bf215546Sopenharmony_ci elif lane is not None: 230bf215546Sopenharmony_ci lane = int(lane) 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci return Source(i, int(el.get('size', size)), 233bf215546Sopenharmony_ci absneg = el.get('absneg', False), 234bf215546Sopenharmony_ci is_float = el.get('float', False), 235bf215546Sopenharmony_ci swizzle = el.get('swizzle', False), 236bf215546Sopenharmony_ci halfswizzle = el.get('halfswizzle', False), 237bf215546Sopenharmony_ci widen = el.get('widen', False), 238bf215546Sopenharmony_ci lanes = el.get('lanes', False), 239bf215546Sopenharmony_ci combine = el.get('combine', False), 240bf215546Sopenharmony_ci lane = lane, 241bf215546Sopenharmony_ci notted = el.get('not', False), 242bf215546Sopenharmony_ci name = el.text or "") 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_cidef build_imm(el): 245bf215546Sopenharmony_ci return Immediate(el.attrib['name'], int(el.attrib['start']), 246bf215546Sopenharmony_ci int(el.attrib['size']), bool(el.attrib.get('signed', False))) 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_cidef build_staging(i, el): 249bf215546Sopenharmony_ci r = xmlbool(el.attrib.get('read', 'false')) 250bf215546Sopenharmony_ci w = xmlbool(el.attrib.get('write', 'false')) 251bf215546Sopenharmony_ci count = int(el.attrib.get('count', '0')) 252bf215546Sopenharmony_ci flags = el.attrib.get('flags', 'true') 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci return Staging(r, w, count, flags, el.text or '') 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_cidef build_modifier(el): 257bf215546Sopenharmony_ci name = el.attrib['name'] 258bf215546Sopenharmony_ci start = int(el.attrib['start']) 259bf215546Sopenharmony_ci size = int(el.attrib['size']) 260bf215546Sopenharmony_ci implied = xmlbool(el.get('implied', 'false')) 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci return Modifier(name, start, size, implied) 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci# Build a single instruction from XML and group based overrides 265bf215546Sopenharmony_cidef build_instr(el, overrides = {}): 266bf215546Sopenharmony_ci # Get overridables 267bf215546Sopenharmony_ci name = overrides.get('name') or el.attrib.get('name') 268bf215546Sopenharmony_ci opcode = overrides.get('opcode') or el.attrib.get('opcode') 269bf215546Sopenharmony_ci opcode2 = overrides.get('opcode2') or el.attrib.get('opcode2') 270bf215546Sopenharmony_ci unit = overrides.get('unit') or el.attrib.get('unit') 271bf215546Sopenharmony_ci opcode = int(opcode, base=0) 272bf215546Sopenharmony_ci opcode2 = int(opcode2, base=0) if opcode2 else None 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci # Get explicit sources/dests 275bf215546Sopenharmony_ci tsize = typesize(name) 276bf215546Sopenharmony_ci sources = [] 277bf215546Sopenharmony_ci i = 0 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci for src in el.findall('src'): 280bf215546Sopenharmony_ci built = build_source(src, i, tsize) 281bf215546Sopenharmony_ci sources += [built] 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci # 64-bit sources in a 32-bit (message) instruction count as two slots 284bf215546Sopenharmony_ci # Affects BLEND, ST_CVT 285bf215546Sopenharmony_ci if tsize != 64 and built.size == 64: 286bf215546Sopenharmony_ci i = i + 2 287bf215546Sopenharmony_ci else: 288bf215546Sopenharmony_ci i = i + 1 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci dests = [Dest(dest.text or '') for dest in el.findall('dest')] 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci # Get implicit ones 293bf215546Sopenharmony_ci sources = sources + ([Source(i, int(tsize)) for i in range(int(el.attrib.get('srcs', 0)))]) 294bf215546Sopenharmony_ci dests = dests + ([Dest()] * int(el.attrib.get('dests', 0))) 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci # Get staging registers 297bf215546Sopenharmony_ci staging = [build_staging(i, el) for i, el in enumerate(el.findall('sr'))] 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci # Get immediates 300bf215546Sopenharmony_ci imms = [build_imm(imm) for imm in el.findall('imm')] 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci modifiers = [] 303bf215546Sopenharmony_ci for mod in el: 304bf215546Sopenharmony_ci if mod.tag in MODIFIERS: 305bf215546Sopenharmony_ci modifiers.append(MODIFIERS[mod.tag]) 306bf215546Sopenharmony_ci elif mod.tag =='mod': 307bf215546Sopenharmony_ci modifiers.append(build_modifier(mod)) 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci instr = Instruction(name, opcode, opcode2, srcs = sources, dests = dests, immediates = imms, modifiers = modifiers, staging = staging, unit = unit) 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci instructions.append(instr) 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci# Build all the instructions in a group by duplicating the group itself with 314bf215546Sopenharmony_ci# overrides for each distinct instruction 315bf215546Sopenharmony_cidef build_group(el): 316bf215546Sopenharmony_ci for ins in el.findall('ins'): 317bf215546Sopenharmony_ci build_instr(el, overrides = { 318bf215546Sopenharmony_ci 'name': ins.attrib['name'], 319bf215546Sopenharmony_ci 'opcode': ins.attrib.get('opcode'), 320bf215546Sopenharmony_ci 'opcode2': ins.attrib.get('opcode2'), 321bf215546Sopenharmony_ci 'unit': ins.attrib.get('unit'), 322bf215546Sopenharmony_ci }) 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_cidef to_alphanum(name): 325bf215546Sopenharmony_ci substitutions = { 326bf215546Sopenharmony_ci ' ': '_', 327bf215546Sopenharmony_ci '/': '_', 328bf215546Sopenharmony_ci '[': '', 329bf215546Sopenharmony_ci ']': '', 330bf215546Sopenharmony_ci '(': '', 331bf215546Sopenharmony_ci ')': '', 332bf215546Sopenharmony_ci '-': '_', 333bf215546Sopenharmony_ci ':': '', 334bf215546Sopenharmony_ci '.': '', 335bf215546Sopenharmony_ci ',': '', 336bf215546Sopenharmony_ci '=': '', 337bf215546Sopenharmony_ci '>': '', 338bf215546Sopenharmony_ci '#': '', 339bf215546Sopenharmony_ci '&': '', 340bf215546Sopenharmony_ci '*': '', 341bf215546Sopenharmony_ci '"': '', 342bf215546Sopenharmony_ci '+': '', 343bf215546Sopenharmony_ci '\'': '', 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci for i, j in substitutions.items(): 347bf215546Sopenharmony_ci name = name.replace(i, j) 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci return name 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_cidef safe_name(name): 352bf215546Sopenharmony_ci name = to_alphanum(name) 353bf215546Sopenharmony_ci if not name[0].isalpha(): 354bf215546Sopenharmony_ci name = '_' + name 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci return name.lower() 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci# Parses out the size part of an opocde name 359bf215546Sopenharmony_cidef typesize(opcode): 360bf215546Sopenharmony_ci if opcode[-3:] == '128': 361bf215546Sopenharmony_ci return 128 362bf215546Sopenharmony_ci if opcode[-2:] == '48': 363bf215546Sopenharmony_ci return 48 364bf215546Sopenharmony_ci elif opcode[-1] == '8': 365bf215546Sopenharmony_ci return 8 366bf215546Sopenharmony_ci else: 367bf215546Sopenharmony_ci try: 368bf215546Sopenharmony_ci return int(opcode[-2:]) 369bf215546Sopenharmony_ci except: 370bf215546Sopenharmony_ci return 32 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_cifor child in root.findall('enum'): 373bf215546Sopenharmony_ci enums[safe_name(child.attrib['name'])] = build_enum(child) 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ciMODIFIERS = { 376bf215546Sopenharmony_ci # Texture instructions share a common encoding 377bf215546Sopenharmony_ci "wide_indices": Flag("wide_indices", 8), 378bf215546Sopenharmony_ci "array_enable": Flag("array_enable", 10), 379bf215546Sopenharmony_ci "texel_offset": Flag("texel_offset", 11), 380bf215546Sopenharmony_ci "shadow": Flag("shadow", 12), 381bf215546Sopenharmony_ci "integer_coordinates": Flag("integer_coordinates", 13), 382bf215546Sopenharmony_ci "fetch_component": Modifier("fetch_component", 14, 2), 383bf215546Sopenharmony_ci "lod_mode": Modifier("lod_mode", 13, 3), 384bf215546Sopenharmony_ci "lod_bias_disable": Modifier("lod_mode", 13, 1), 385bf215546Sopenharmony_ci "lod_clamp_disable": Modifier("lod_mode", 14, 1), 386bf215546Sopenharmony_ci "write_mask": Modifier("write_mask", 22, 4), 387bf215546Sopenharmony_ci "register_type": Modifier("register_type", 26, 2), 388bf215546Sopenharmony_ci "dimension": Modifier("dimension", 28, 2), 389bf215546Sopenharmony_ci "skip": Flag("skip", 39), 390bf215546Sopenharmony_ci "register_width": Modifier("register_width", 46, 1, force_enum = "register_width"), 391bf215546Sopenharmony_ci "secondary_register_width": Modifier("secondary_register_width", 47, 1, force_enum = "register_width"), 392bf215546Sopenharmony_ci "vartex_register_width": Modifier("varying_texture_register_width", 24, 2), 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci "atom_opc": Modifier("atomic_operation", 22, 4), 395bf215546Sopenharmony_ci "atom_opc_1": Modifier("atomic_operation_with_1", 22, 4), 396bf215546Sopenharmony_ci "inactive_result": Modifier("inactive_result", 22, 4), 397bf215546Sopenharmony_ci "memory_access": Modifier("memory_access", 24, 2), 398bf215546Sopenharmony_ci "regfmt": Modifier("register_format", 24, 3), 399bf215546Sopenharmony_ci "source_format": Modifier("source_format", 24, 4), 400bf215546Sopenharmony_ci "vecsize": Modifier("vector_size", 28, 2), 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci "slot": Modifier("slot", 30, 3), 403bf215546Sopenharmony_ci "roundmode": Modifier("round_mode", 30, 2), 404bf215546Sopenharmony_ci "result_type": Modifier("result_type", 30, 2), 405bf215546Sopenharmony_ci "saturate": Flag("saturate", 30), 406bf215546Sopenharmony_ci "not_result": Flag("not_result", 30), 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci "lane_op": Modifier("lane_operation", 32, 2), 409bf215546Sopenharmony_ci "cmp": Modifier("condition", 32, 3), 410bf215546Sopenharmony_ci "clamp": Modifier("clamp", 32, 2), 411bf215546Sopenharmony_ci "sr_count": Modifier("staging_register_count", 33, 3, implied = True), 412bf215546Sopenharmony_ci "sample_and_update": Modifier("sample_and_update_mode", 33, 3), 413bf215546Sopenharmony_ci "sr_write_count": Modifier("staging_register_write_count", 36, 3, implied = True), 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci "conservative": Flag("conservative", 35), 416bf215546Sopenharmony_ci "subgroup": Modifier("subgroup_size", 36, 4), 417bf215546Sopenharmony_ci "update": Modifier("update_mode", 36, 2), 418bf215546Sopenharmony_ci "sample": Modifier("sample_mode", 38, 2), 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci# Parse the ISA 422bf215546Sopenharmony_cifor child in root: 423bf215546Sopenharmony_ci if child.tag == 'group': 424bf215546Sopenharmony_ci build_group(child) 425bf215546Sopenharmony_ci elif child.tag == 'ins': 426bf215546Sopenharmony_ci build_instr(child) 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ciinstruction_dict = { ins.name: ins for ins in instructions } 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci# Validate there are no duplicated instructions 431bf215546Sopenharmony_ciif len(instruction_dict) != len(instructions): 432bf215546Sopenharmony_ci import collections 433bf215546Sopenharmony_ci counts = collections.Counter([i.name for i in instructions]) 434bf215546Sopenharmony_ci for c in counts: 435bf215546Sopenharmony_ci if counts[c] != 1: 436bf215546Sopenharmony_ci print(f'{c} appeared {counts[c]} times.') 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ciassert(len(instruction_dict) == len(instructions)) 439