From d4904b3b89773a7c15862d7c084a514781d761e5 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Wed, 30 Jun 2021 15:42:25 -0500 Subject: [PATCH] arch-gcn3: Remove unused files These files are not used but are still popping up in style checks, such as the new python Black checks. Removing these to reduce maintenance overhead for GCN3. Change-Id: I8d78c8246c29637958a8af99c4a9eb6bb8e23e3d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47419 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/arch/amdgpu/gcn3/ast_interpreter.py | 2895 ------------------- src/arch/amdgpu/gcn3/ast_objects.py | 865 ------ src/arch/amdgpu/gcn3/description_objects.py | 367 --- src/arch/amdgpu/gcn3/description_parser.py | 1327 --------- src/arch/amdgpu/gcn3/gpu_isa_main.py | 46 - src/arch/amdgpu/gcn3/gpu_isa_parser.py | 1263 -------- src/arch/amdgpu/gcn3/hand_coded.py | 414 --- 7 files changed, 7177 deletions(-) delete mode 100644 src/arch/amdgpu/gcn3/ast_interpreter.py delete mode 100644 src/arch/amdgpu/gcn3/ast_objects.py delete mode 100644 src/arch/amdgpu/gcn3/description_objects.py delete mode 100644 src/arch/amdgpu/gcn3/description_parser.py delete mode 100644 src/arch/amdgpu/gcn3/gpu_isa_main.py delete mode 100644 src/arch/amdgpu/gcn3/gpu_isa_parser.py delete mode 100644 src/arch/amdgpu/gcn3/hand_coded.py diff --git a/src/arch/amdgpu/gcn3/ast_interpreter.py b/src/arch/amdgpu/gcn3/ast_interpreter.py deleted file mode 100644 index 77e11700c7..0000000000 --- a/src/arch/amdgpu/gcn3/ast_interpreter.py +++ /dev/null @@ -1,2895 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import copy -import os -import re -import sys - -from ast_objects import * -from description_objects import * -from description_parser import DescriptionParser, ParseError -from hand_coded import * - -from pprint import pprint, pformat - -# generate code using the gem5 style -class CodeGen(object): - def __init__(self, file): - self.file = file - self.line_max = 80 - self.semi_stack = '' - self.tab = ' ' - self.indent = '' - self.code = '' - - # write self.code out to file - def generate(self): - fd = open(self.file, 'w') - fd.write(self.code) - fd.close() - - # add an indent level - def inc_indent(self): - self.indent += self.tab - - # remove an indent level - def dec_indent(self): - self.indent = self.indent[0:-len(self.tab)] - - # add an optional semicolon after brace for matched cg_end() - def push_semi(self, semi): - if semi == '': - semi = ' ' - self.semi_stack += semi - - # used by cg_end to decide if a semicolon should follow the brace - def pop_semi(self): - semi = self.semi_stack[-1:] - self.semi_stack = self.semi_stack[0:-1] - if semi == ' ': - semi = '' - return semi - - def smart_split(self, line): - max = self.line_max - len(self.indent) - len('\n') - if len(line) < max: - self.code += '%s%s\n' % (self.indent, line) - else: - pad = '' - while len(line) > max: - high = max - looking = True - while looking and high > 8: - low = high - 8 - for s in ['&&', '>=', '<<', '>>', ' *', ' +', ' =', - ' ?', ' :', ',']: - pos = line[low:high].find(s) - if pos > 0: - mid = low + pos + len(s) - self.code += '%s%s\n' % (self.indent, line[0:mid]) - line = self.tab + line[mid:].strip() - looking = False - break - high -= 4 - if looking: - import pdb; pdb.set_trace() - self.code += '%s%s\n' % (self.indent, line) - - # close a block with brace and optional semicolon - # }[;] - def cg_end(self, comment): - self.dec_indent() - self.code += self.indent + '}' - semi = self.pop_semi() - if semi: - self.code += semi - if comment: - self.code += ' // %s\n' % comment - - # class [: public ] - # [, public ] - # [, . . . ] - # [, public ] - # { - def cg_class(self, name, base): - self.code += self.indent - self.code += 'class ' - self.code += name - b0 = base[0:1] - if b0: - self.code += ' : public %s' % base[0] - if base[1:]: - spaces = self.indent + (' ' * (len(name) + 7)) - for b in base[1:]: - self.code += '\n%s, public %s' % (spaces, b) - self.code += '\n%s{\n' % self.indent - self.push_semi(';') - self.inc_indent() - - # : - def cg_scope(self, scope): - self.code += '%s%s\n' % (self.indent[0:-2], scope) - - # [] - # [::]([, , ... , ) qual - # { - def cg_method(self, typ, base, name, args, ini, qual=None): - if typ: - self.code += '%s%s\n' % (self.indent, typ) - if base: - line = '%s%s::%s(' % (self.indent, base, name) - else: - line = '%s%s(' % (self.indent, name) - if args: - left = self.line_max - len(line) - if (len(args[0]) + 2) < left: - line += args[0] - else: - self.code += '%s\n' % line - line = '%s %s' % (self.indent, args[0]) - for a in args[1:]: - left = self.line_max - len(line) - if (len(a) + 2) < left: - line += ', %s' % a - else: - self.code += '%s,\n' % line - line = '%s %s' % (self.indent, a) - if qual: - self.code += '%s) %s\n' % (line, qual) - else: - self.code += '%s)\n' % line - if ini: - separator = '%s : ' % self.indent - for i in ini: - self.code += '%s%s\n' % (separator, i) - separator = '%s , ' % self.indent - - self.code += '%s{\n' % self.indent - self.push_semi('') - self.inc_indent() - - # :: [] = { - # &::, - # &::, - # . . . - # &::, - # } - def cg_table(self, typ, base, name, entries): - self.code += '%s%s %s::%s[] = {\n' % (self.indent, typ, base, name) - spaces = self.indent + self.tab - for entry in entries: - self.code += '%s&%s::%s,\n' % (spaces, base, entry) - self.code += '%s};\n\n' % self.indent - - # union { - def cg_union(self, name): - self.code += '%sunion %s {\n' % (self.indent, name) - self.push_semi(';') - self.inc_indent() - - # struct { - # unsigned int : ; - # . . . - # } ; - # - def cg_struct(self, name, fields): - max = len('pad_00_31') - for f in fields: - sz = len(f[0]) - if sz > max: - max = sz - bit = 0 - self.code += '%sstruct %s {\n' % (self.indent, name) - prefix = '%s%sunsigned int ' % (self.indent, self.tab) - for f in fields: - n = f[0] - v = f[1] - m = f[2] - assert v >= bit, 'fields not in sorted order' - if bit < v: - sz = v - bit - p = 'pad_' + str(bit) - if sz > 1: - p += '_' + str(v - 1) - pad = ' ' * ((max - len(p))) - self.code += '%s%s%s : %d;\n' % (prefix, pad, p, sz) - bit += sz - sz = 1 + m - v - pad = ' ' * (max - len(n)) - self.code += '%s%s%s : %d;\n' % (prefix, pad, n, sz) - bit += sz - self.code += '%s};\n' % self.indent - - # for (; ; ) { - def cg_for(self, init, test, fini): - line = '%sfor (%s;' % (self.indent, init) - left = self.line_max - len(line) - if (len(test) + 2) > left: - self.code += line - line = self.indent + self.tab - left = self.line_max - len(line) - line += ' %s;' % test - if (len(fini) + 2) > left: - self.code += line - line = self.indent + self.tab - left = self.line_max - len(line) - line += ' %s) {\n' % fini - self.code += line - self.inc_indent() - - # if () { - def cg_if(self, test): - self.code += '%sif (%s) {\n' % (self.indent, test) - self.push_semi('') - self.inc_indent() - - # } else if () { - def cg_else_if(self, test): - self.dec_indent() - self.code += '%s} else if (%s) {\n' % (self.indent, test) - self.inc_indent() - - # } else { - def cg_else(self): - self.dec_indent() - self.code += '%s} else {\n' % self.indent - self.inc_indent() - - # - def cg_code(self, code): - self.code += '%s%s\n' % (self.indent, code) - - # - def cg_block(self, lines): - for line in lines: - self.smart_split(line) - - # #include - def cg_include(self, file): - if file[0] == '<': - self.code += '#include %s\n' % file - else: - self.code += '#include "%s"\n' % file - - # namespace - # { - def cg_namespace(self, namespace): - self.code += '%snamespace %s\n' % (self.indent, namespace) - self.code += '%s{\n' % (self.indent) - self.inc_indent() - - # // - def cg_comment(self, comment): - self.code += '%s// %s\n' % (self.indent, comment) - - # gem5 fatal() call - def cg_fatal(self, fatal_cause): - self.code += '%sfatal("%s");\n' % (self.indent, fatal_cause) - - # blank line - def cg_newline(self): - self.code += '\n' - -# CodeFrag is used to build up the code for one data reference -class CodeFrag(object): - def __init__(self, k): - self.key = k - self.ctx = '' # context accessor fragment - self.fld = '' # field reference fragment - self.var = '' # variable name fragment - self.typ = '' # variable type fragment - self.exp = '' # general expression fragment - self.vec = '' # vector index fragment - self.scn = '' # section selector - - def setup(self, initList): - assert type(initList) is list - assert len(initList) == 6 - self.ctx = initList[0] - self.fld = initList[1] - self.var = initList[2] - self.typ = initList[3] - self.exp = initList[4] - self.vec = initList[5] - self.scn = '' - - def __repr__(self): - text = '"key":\t' + repr(self.key) + ',\n' - text += '"ctx":\t' + repr(self.ctx) + ',\n' - text += '"fld":\t' + repr(self.fld) + ',\n' - text += '"var":\t' + repr(self.var) + ',\n' - text += '"typ":\t' + repr(self.typ) + ',\n' - text += '"exp":\t' + repr(self.exp) + ',\n' - text += '"vec":\t' + repr(self.vec) + ',\n' - text += '"scn":\t' + repr(self.scn) + ',\n' - return text - -# GenOne is used to build up the code for one method -class GenOne(object): - def __init__(self, op_inst, cg, is_vec, methods, info): - assert type(cg) is CodeGen - self.op_inst = op_inst - self.cg = cg - self.decl = [] - self.vector = [] - self.scalar = [] - self.store = [] - self.modified = [] - self.tab = ' ' - self.indent = '' - self.store_vars = [] - self.mem_vars = {} - self.info = info - self.mem_load = [] - if is_vec: - self.math = self.vector - self.decl = ['SregU64 exec;'] - #self.load = ['exec = readSpecialReg(gpuDynInst, ' - # 'REG_EXEC);'] - self.load = ['exec = ' - 'gpuDynInst->wavefront()->execMask().to_ullong();'] - self.load_vars = ['exec'] - else: - self.math = self.scalar - self.load = [] - self.load_vars = [] - self.methods = methods - - # change scalar v vector mode - def set_vector(self, is_vec): - if is_vec: - self.math = self.vector - else: - self.math = self.scalar - - # add an indent level - def inc_indent(self): - self.indent += self.tab - - # remove an indent level - def dec_indent(self): - self.indent = self.indent[0:-len(self.tab)] - - # add to the scalar or vector code - def add_math(self, stmt): - while True: - m = re.search('(vmem_\$([^$]+)\$)', stmt) - if m is None: - break; - stmt = stmt.replace(m.group(1), self.mem_vars[m.group(2)]) - self.math.append(self.indent + stmt) - - # add to the scalar code - def add_scalar(self, stmt): - self.scalar.append(self.indent + stmt) - - def decl_type(self, var): - assert type(var) is str - for dcl in self.decl: - if var in dcl: - pos = dcl.find(' ') - return dcl[0:pos] - return 'SregU16' - - def add_decl(self, var, dcl): - for d in self.decl: - if var in d: - return - self.decl.append(dcl) - - def add_src_set(self, src_set): - for s in src_set: - assert type(s) is CodeFrag - if s.scn == 'mem': - if s.exp not in self.mem_vars.keys(): - self.mem_vars[s.exp] = 'vmem_%d' % len(self.mem_vars) - s.var = self.mem_vars[s.exp] - if s.var in self.load_vars: - continue - self.load_vars.append(s.var) - if s.vec != '': - vreg = s.typ.replace('S', 'V') - src_dec = '%s %s;' % (vreg, s.var) - else: - sreg = s.typ - src_dec = '%s %s;' % (sreg, s.var) - self.add_decl(s.var, src_dec) - if s.var not in self.modified: - shift_fld = False - # fixup SBASE, which needs to be shifted left by 1 bit - if s.fld == 'instData.SBASE': - shift_fld = True - if s.scn == 'mem': - if s.ctx != 'MEM': - import pdb; pdb.set_trace() - if '+' in s.exp: - pos = s.exp.find('+') + 1 - off = s.exp[pos:].strip() - string = 'calculateAddr<%s>(gpuDynInst, '\ - '%s, (%s).get(), 0);' - params = (self.decl_type(s.fld), s.fld, off) - typ1 = self.decl_type(s.var) - typ2 = self.decl_type(s.fld) - typ3 = self.decl_type(off) - elif ',' in s.exp: - args = s.exp.split(',') - if len(args) == 3: - a1 = args[1].strip() - a2 = args[2].strip() - string = 'calculateAddr<%s>(gpuDynInst, %s, '\ - '(%s).get(), (%s).get());' - params = (self.decl_type(s.fld), s.fld, a1, a2) - typ1 = self.decl_type(s.var) - typ2 = self.decl_type(s.fld) - typ3 = self.decl_type(a1) - typ4 = self.decl_type(a2) - else: - import pdb; pdb.set_trace() - else: - if 'SMEM' in self.op_inst: - string = 'calculateAddr<%s>(gpuDynInst, %s, '\ - 'offset.get());' - elif 'FLAT' in self.op_inst: - string = 'calculateAddr<%s>(gpuDynInst, %s);' - else: - string = 'calculateAddr<%s>(gpuDynInst, %s, 0, 0);' - params = (self.decl_type(s.fld), s.fld) - typ1 = self.decl_type(s.var) - typ2 = self.decl_type(s.fld) - mem_read_str = 'initiateMemRead<%s>(gpuDynInst, %s);' - mem_read_params = (self.decl_type(s.var), s.var) - self.mem_load.append(mem_read_str % mem_read_params) - elif s.ctx != '' and s.fld != '': - if shift_fld: - string = '%s = read%s<%s>(gpuDynInst, %s << 1);' - else: - string = '%s = read%s<%s>(gpuDynInst, %s);' - if s.ctx in SpecialCtx: - params = (s.var, SpecialCtx[s.ctx], - self.decl_type(s.var), s.fld) - else: - params = (s.var, - TypeToAccessMethod[self.decl_type(s.var)], - self.decl_type(s.var), s.fld) - typ1 = self.decl_type(s.var) - typ2 = 'uint32_t' - elif s.exp != '': - if shift_fld: - string = '%s = read%s<%s>(gpuDynInst, %s << 1);' - else: - string = '%s = read%s<%s>(gpuDynInst, %s);' - if s.ctx in SpecialCtx: - params = (s.var, SpecialCtx[s.ctx], - self.decl_type(s.var), s.exp) - else: - params = (s.var, - TypeToAccessMethod[self.decl_type(s.var)], - self.decl_type(s.var), s.exp) - typ1 = self.decl_type(s.var) - typ2 = self.decl_type(s.exp) - elif s.ctx != '': - string = '%s = read%s<%s>(gpuDynInst, REG_%s);' - if s.ctx in SpecialCtx: - params = (s.var, SpecialCtx[s.ctx], - self.decl_type(s.var), s.ctx) - else: - params = (s.var, - TypeToAccessMethod[self.decl_type(s.var)], - self.decl_type(s.var)) - typ1 = self.decl_type(s.var) - elif s.fld != '': - string = '%s = %s;' - params = (s.var, s.fld) - else: - continue - self.load.append(string % params) - - def add_dst_set(self, dst_set): - src_set = [] - for d in dst_set: - assert type(d) is CodeFrag - if d.key == 'src': - src_set.append(d) - if src_set: - self.add_src_set(src_set) - - for d in dst_set: - assert type(d) is CodeFrag - if d.key == 'dst': - if d.scn == 'mem': - if d.exp not in self.mem_vars.keys(): - self.mem_vars[d.exp] = 'vmem_%d' % len(self.mem_vars) - d.var = self.mem_vars[d.exp] - # handle destination declarations - if d.var in self.store_vars: - continue - self.store_vars.append(d.var) - if d.vec != '': - vreg = d.typ.replace('S', 'V') - dst_dec = '%s %s;' % (vreg, d.var) - # vector destination regs are also source regs - src_set.append(d) - else: - sreg = d.typ - dst_dec = '%s %s;' % (sreg, d.var) - self.add_decl(d.var, dst_dec) - - # write back destinations - if d.scn == 'mem': - if d.ctx != 'MEM': - import pdb; pdb.set_trace() - if '+' in d.exp: - pos = d.exp.find('+') + 1 - off = d.exp[pos:].strip() - string = 'writeMem<%s>(gpuDynInst, %s, (%s)'\ - '.get(), %s);' - params = (self.decl_type(d.var), d.fld, off, d.var) - typ1 = self.decl_type(d.var) - typ2 = self.decl_type(d.fld) - typ3 = self.decl_type(off) - else: - string = 'writeMem<%s, %s>(gpuDynInst, %s, 0, %s);' - params = (self.decl_type(d.var), self.decl_type(d.fld), - d.fld, d.var) - typ1 = self.decl_type(d.var) - typ2 = self.decl_type(d.fld) - elif d.ctx != '' and d.fld != '': - if d.fld[0] == '-': - string = 'write%s<%s>(gpuDynInst, REG_%s, %s);' - if d.ctx in SpecialCtx: - params = (SpecialCtx[d.ctx], self.decl_type(d.var), - d.ctx, d.var) - else: - params = (d.fld[1:], self.decl_type(d.var), d.var) - typ1 = self.decl_type(d.var) - else: - string = 'write%s<%s>(gpuDynInst, %s, %s);' - if d.ctx in SpecialCtx: - params = (SpecialCtx[d.ctx], self.decl_type(d.var), - d.fld, d.var) - else: - params = \ - (TypeToAccessMethod[self.decl_type(d.var)], - self.decl_type(d.var), d.fld, d.var) - typ1 = self.decl_type(d.var) - typ2 = 'uint32_t' - elif d.exp != '': - string = 'write%s<%s>(gpuDynInst, %s, %s);' - if d.ctx in SpecialCtx: - params = (SpecialCtx[d.ctx], self.decl_type(d.var), - d.exp, d.var) - else: - params = (d.ctx, self.decl_type(d.var), d.exp, d.var) - typ1 = self.decl_type(d.var) - typ2 = self.decl_type(d.exp) - elif d.ctx != '': - string = 'write%s<%s>(gpuDynInst, REG_%s, %s);' - if d.ctx in SpecialCtx: - params = (SpecialCtx[d.ctx], self.decl_type(d.var), - d.ctx, d.var) - else: - params = (d.ctx, self.decl_type(d.var), d.var) - typ1 = self.decl_type(d.var) - else: - continue - self.store.append(string % params) - - # once all he code for a single execute() method is built up - # the C++ method is generated. memory ops are a special case - # because of the 3-phase nature of their execution. to fully - # execute a memory operation the instruction class must - # implement the following methods: - # - # execute() - issues the reqest to the proper memory pipe, - # i.e., global/local - # - # initiateAcc() - builds a memory request/packet and sends the - # req to memory - # - # completeAcc() - returned data are written back to the - # register file - def finish(self): - self.info.decl = self.decl - - is_store = False - is_load = False - is_atomic = False - - if ('OPF_MEM_STORE' in self.info.flags or 'DS_WRITE_B32' in - self.op_inst or 'DS_WRITE_B64' in self.op_inst): - is_store = True - elif 'OPF_MEM_ATOMIC' in self.info.flags: - is_atomic = True - elif ('LOAD' in self.op_inst or 'DS_READ_B32' in self.op_inst or - 'DS_READ_B64' in self.op_inst): - is_load = True - - if is_store or is_load: - is_smem = 'SMEM' in self.op_inst - is_flat_mem = 'FLAT' in self.op_inst - is_ds_mem = 'DS' in self.op_inst - - self.cg.cg_code('Wavefront *wf = gpuDynInst->wavefront();') - #if not is_flat_mem: - self.cg.cg_code('gpuDynInst->execUnitId = wf->execUnitId;') - if not is_smem: - self.cg.cg_code('gpuDynInst->exec_mask = ' - 'gpuDynInst->wavefront()->execMask();') - self.cg.cg_code('gpuDynInst->latency.init(&gpuDynInst'\ - '->computeUnit()->shader->tick_cnt);') - if is_ds_mem: - self.cg.cg_code('gpuDynInst->latency.set(gpuDynInst'\ - '->computeUnit()->cyclesToTicks(Cycles(24)));') - else: - self.cg.cg_code('gpuDynInst->latency.set(gpuDynInst'\ - '->computeUnit()->clockPeriod());') - self.cg.cg_newline() - if is_smem: - self.cg.cg_if('instData.IMM') - self.cg.cg_code('offset = extData.OFFSET;') - self.cg.cg_else() - self.cg.cg_code('offset = readScalarReg(gpuDynInst,' - 'extData.OFFSET);') - self.cg.cg_end('if') - self.cg.cg_newline() - - self.cg.cg_block(self.load) - - if is_flat_mem and is_store: - has_vgpr_addr = False - for load_entry in self.load: - if 'vgpr_addr' in load_entry: - has_vgpr_addr = True - if has_vgpr_addr: - self.cg.cg_newline() - self.cg.cg_code('typedef decltype(vgpr_src)::RegType ' - 'RegType;') - self.cg.cg_newline() - self.cg.cg_code('assert(!(sizeof(RegType) % ' - 'sizeof(uint32_t))') - self.cg.inc_indent() - self.cg.cg_code(' || sizeof(RegType) < sizeof(uint32_t));') - self.cg.dec_indent() - self.cg.cg_newline() - self.cg.cg_code('int num_words = sizeof(RegType) / ' - 'sizeof(uint32_t);') - self.cg.cg_newline() - self.cg.cg_for('int lane = 0', 'lane < ' - 'wf->computeUnit->wfSize()', - '++lane') - self.cg.cg_if('gpuDynInst->wavefront()->execMask()[lane]') - self.cg.cg_for('int i = 0', 'i < num_words', '++i') - self.cg.cg_code('((uint32_t*)gpuDynInst->d_data)') - self.cg.inc_indent() - self.cg.cg_code('[i * wf->computeUnit->wfSize() + lane] =') - self.cg.inc_indent() - self.cg.cg_code('vgpr_src.getDword(i, lane);') - self.cg.dec_indent() - self.cg.dec_indent() - self.cg.cg_end('for') - self.cg.cg_end('if') - self.cg.cg_end('for') - self.cg.cg_newline() - self.cg.cg_code('calculateAddr(gpuDynInst, ' - 'vgpr_addr);') - if is_ds_mem and is_store: - has_vgpr_addr = False - for load_entry in self.load: - if 'vgpr_a' in load_entry: - has_vgpr_addr = True - if has_vgpr_addr: - self.cg.cg_newline() - self.cg.cg_code('typedef decltype(vgpr_d0)::RegType ' - 'RegType;') - self.cg.cg_newline() - self.cg.cg_code('assert(!(sizeof(RegType) % ' - 'sizeof(uint32_t))') - self.cg.inc_indent() - self.cg.cg_code(' || sizeof(RegType) < sizeof(uint32_t));') - self.cg.dec_indent() - self.cg.cg_newline() - self.cg.cg_code('int num_words = sizeof(RegType) / ' - 'sizeof(uint32_t);') - self.cg.cg_newline() - self.cg.cg_for('int lane = 0', 'lane < ' - 'wf->computeUnit->wfSize()', - '++lane') - self.cg.cg_if('gpuDynInst->wavefront()->execMask()[lane]') - self.cg.cg_for('int i = 0', 'i < num_words', '++i') - self.cg.cg_code('((uint32_t*)gpuDynInst->d_data)') - self.cg.inc_indent() - self.cg.cg_code('[i * wf->computeUnit->wfSize() + lane] =') - self.cg.inc_indent() - self.cg.cg_code('vgpr_d0.getDword(i, lane);') - self.cg.dec_indent() - self.cg.dec_indent() - self.cg.cg_end('for') - self.cg.cg_end('if') - self.cg.cg_end('for') - self.cg.cg_newline() - self.cg.cg_code('calculateAddr(gpuDynInst, ' - 'vgpr_a, 0, 0);') - - self.cg.cg_newline() - - # generate execute(), i.e., issue to appropriate memory pipe - if is_smem: - self.cg.cg_code('gpuDynInst->computeUnit()->scalarMemoryPipe.') - self.cg.inc_indent() - self.cg.cg_code('getGMReqFIFO().push(gpuDynInst);') - self.cg.dec_indent() - self.cg.cg_newline() - if is_load: - self.cg.cg_code('wf->scalarRdGmReqsInPipe--;') - self.cg.cg_code('wf->scalarOutstandingReqsRdGm++;') - else: - self.cg.cg_code('wf->scalarWrGmReqsInPipe--;') - self.cg.cg_code('wf->scalarOutstandingReqsWrGm++;') - elif is_flat_mem: - self.cg.cg_if('gpuDynInst->executedAs() == enums::SC_GLOBAL') - self.cg.cg_code('gpuDynInst->computeUnit()->globalMemoryPipe.') - self.cg.inc_indent() - self.cg.cg_code('getGMReqFIFO().push(gpuDynInst);') - self.cg.dec_indent() - if is_load: - self.cg.cg_code('wf->rdGmReqsInPipe--;') - self.cg.cg_code('wf->outstandingReqsRdGm++;') - else: - self.cg.cg_code('wf->wrGmReqsInPipe--;') - self.cg.cg_code('wf->outstandingReqsWrGm++;') - self.cg.cg_else() - self.cg.cg_code('assert(false);') - self.cg.cg_end('else') - self.cg.cg_newline() - elif is_ds_mem: - self.cg.cg_code('gpuDynInst->computeUnit()->localMemoryPipe.') - self.cg.inc_indent() - self.cg.cg_code('getLMReqFIFO().push(gpuDynInst);') - self.cg.dec_indent() - self.cg.cg_newline() - if is_load: - self.cg.cg_code('wf->rdLmReqsInPipe--;') - self.cg.cg_code('wf->outstandingReqsRdLm++;') - else: - self.cg.cg_code('wf->wrLmReqsInPipe--;') - self.cg.cg_code('wf->outstandingReqsWrLm++;') - else: - self.cg.cg_if('isLocalMem()') - self.cg.cg_code('gpuDynInst->computeUnit()->localMemoryPipe.') - self.cg.inc_indent() - self.cg.cg_code('getLMReqFIFO().push(gpuDynInst);') - self.cg.dec_indent() - self.cg.cg_else() - self.cg.cg_code('gpuDynInst->computeUnit()->globalMemoryPipe.') - self.cg.inc_indent() - self.cg.cg_code('getGMReqFIFO().push(gpuDynInst);') - self.cg.dec_indent() - self.cg.cg_end('if') - self.cg.cg_newline() - self.cg.cg_code('gpuDynInst->wavefront()->outstandingReqs++;') - self.cg.cg_code('gpuDynInst->wavefront()'\ - '->validateRequestCounters();') - self.cg.cg_end('execute') - self.cg.cg_newline() - - # generate initiateAcc() - self.cg.cg_method('void', self.op_inst, 'initiateAcc', - ['GPUDynInstPtr gpuDynInst'], []) - - #if self.mem_load and 'SMEM' in self.op_inst: - if self.mem_load: - self.cg.cg_block(self.mem_load); - - if is_store: - if self.vector: - self.cg.cg_for('int t = 0', 'exec != 0', 't++, exec >>= 1') - self.cg.cg_if('(exec & 1) != 0') - self.cg.cg_block(self.vector) - self.cg.cg_end('if') # cg_if - self.cg.cg_end('for') # cg_for - - self.cg.cg_block(self.scalar) - self.cg.cg_block(self.store) - - self.cg.cg_end('initiateAcc') - self.cg.cg_newline() - - # generate completeAcc() - self.cg.cg_method('void', self.op_inst, 'completeAcc', - ['GPUDynInstPtr gpuDynInst'], []) - - if is_load: - if self.vector: - self.cg.cg_for('int t = 0', 'exec != 0', 't++, exec >>= 1') - self.cg.cg_if('(exec & 1) != 0') - self.cg.cg_block(self.vector) - self.cg.cg_end('if') # cg_if - self.cg.cg_end('for') # cg_for - - self.cg.cg_block(self.scalar) - self.cg.cg_block(self.store) - - else: - self.cg.cg_block(self.load) - - if self.mem_load: - self.cg.cg_block(self.mem_load); - - if self.vector: - self.cg.cg_for('int t = 0', 'exec != 0', 't++, exec >>= 1') - self.cg.cg_if('(exec & 1) != 0') - self.cg.cg_block(self.vector) - self.cg.cg_end('if') # cg_if - self.cg.cg_end('for') # cg_for - - self.cg.cg_block(self.scalar) - self.cg.cg_block(self.store) - - if self.store: - if is_load or is_store: - self.cg.cg_end('completeAcc') - else: - self.cg.cg_end('execute') - return True - else: - return False - -# a list where list[n] is always list[n] and -# the unreferenced elements have a default fill value -class IndexedList(object): - def __init__(self, size, fill): - self.list = [] - self.size = size - self.fill = fill - self.next_index = 0 - for i in range(0, size): - self.list.append(fill) - def grow(self, index, fill): - old_size = self.size - for i in range(old_size, index): - self.list.append(self.fill) - self.list.append(fill) - self.size = index + 1 - def __len__(self): - return self.size - def __iter__(self): - self.next_index = 0 - return self - def next(self): - while True: - if self.next_index >= self.size: - self.next_index = 0 - raise StopIteration - entry = self.list[self.next_index] - self.next_index += 1 - if entry != None: - return entry - def __getitem__(self, index): - if index >= self.size: - self.grow(index, self.fill) - return self.list[index] - def __setitem__(self, index, value): - if index >= self.size: - self.grow(index, value) - else: - self.list[index] = value - def __repr__(self): - text = '[\n' - for i in range(0, self.size): - text += '\t' + str(i) + ' :\t' + repr(self.list[i]) + '\n' - text += ']' - return text - -# Abstract Syntax Tree Interpreter -class RefinedOpInfo(object): - def __init__(self, name, inst, encode, op_typ): - self.name = name - self.inst = inst.name - self.enc = encode.name - self.sub_enc = op_typ.sub_enc - self.desc = op_typ.desc - self.flags = op_typ.flags - self.num_dst = 0 - self.num_src = 0 - self.dst = [] - self.src = [] - self.decl = [] - - def __repr__(self): - text = '"name":\t' + repr(self.name) + ',\n' - text += '"enc":\t' + repr(self.enc) + ',\n' - text += '"sub enc":\t' + repr(self.sub_enc) + ',\n' - text += '"desc":\t' + repr(self.desc) + ',\n' - text += '"flags":\t' + repr(self.flags) + ',\n' - text += '"num_dst":\t' + repr(self.num_dst) + ',\n' - text += '"num_src":\t' + repr(self.num_src) + ',\n' - text += '"dst":\t' + repr(self.dst) + ',\n' - text += '"src":\t' + repr(self.src) + '\n' - return text - - def override(self, operand): - assert type(operand) is Operand - if operand.num_dst > 0: - self.num_dst = operand.num_dst - if operand.num_src > 0: - self.num_src = operand.num_src - for od in operand.dst: - match = False - for sd in self.dst: - if sd.match(od): - sd.override(od) - match = True - if not match: - self.dst.append(copy.copy(od)) - for os in operand.src: - match = False - for ss in self.src: - if ss.match(os): - ss.override(os) - match = True - if not match: - self.src.append(copy.copy(os)) - -class AstInterpreter(object): - def __init__(self): - self.high_bits = 9 - self.max_bits = 6 - self.prefix = '' - self.constant = {} - self.type_by_value = {} - self.decode_info = {} - self.enc_by_name = {} - self.decode_tables = {} - self.inst_by_name = {} - self.inst_formats = {} - self.inst_fields = {} - self.inst_by_optype = {} - self.op_types_seen = [] - self.invalid_type = TypeClause() - self.invalid_type.name = 'invalid' - self.invalid_type.desc = ['invalid'] - self.default_type = TypeClause() - self.default_type.name = 'default' - self.default_type.desc = ['default'] - main_decode_table = IndexedList(512, 'subDecode_invalid') - self.decode_tables['tableDecodePrimary'] = main_decode_table - self.inst_with_encodings = [] - self.refined_op_info = [] - self.desc_parser = DescriptionParser() - self.look_for_comma_before_equal = False - self.ref_op_info_fixup = ['DS'] - self.methods = [] - - def bits_info(self, pattern, bits): - care_bits = 0 - match = 0 - for b in range(len(pattern) - 1, -1, -1): - if pattern[b] == '0': - care_bits += 1 - elif pattern[b] == '1': - match += 1 << care_bits - care_bits += 1 - shift = bits - care_bits - base = match << shift - copy = 1 << shift - return (base, copy) - - def handle_const(self, inst): - for clause in inst.clauses: - self.constant[clause.name] = clause.value - - def get_type_value_desc(self, type_value, type_list): - for t in type_list: - if t.name == type_value: - return t.desc - names = [] - for k in self.type_by_value.keys(): - tbv = self.type_by_value[k] - for t in range(0, len(tbv)): - if tbv[t] and tbv[t].name == type_value: - return tbv[t].desc - import pdb; pdb.set_trace() - return ['get_type_value_desc(%s)' % (type_value)] - - def handle_type(self, inst): - type_list = IndexedList(0, None) - regexp = re.compile('get_type_value_desc\(([^\)]+)\)') - for clause in inst.clauses: - assert type(clause) is TypeClause - if clause.v_max != 0: - # handle 'ID = NUMBER:NUMBER' clauses - for v in range(clause.value, clause.v_max + 1): - newc = copy.deepcopy(clause) - newc.name = clause.name + str(v) - newc.v_max = 0 - newc.value = v - type_list[v] = newc - elif clause.var == False: - if clause.name != '': - # handle 'ID = NUMBER' clauses - newc = copy.deepcopy(clause) - if newc.desc: - found = regexp.match(newc.desc[0]) - if found: - tval = found.group(1) - tlst = type_list - newc.desc = self.get_type_value_desc(tval, tlst) - type_list[newc.value] = newc - elif clause.type != '': - # handle 'type ID' clauses - for t in self.type_by_value[clause.type]: - type_list[t.value] = t - else: - # handle $(ID} substitution - orig_name = clause.name - a = orig_name.find('${') - b = orig_name.find('}') - var = orig_name[a:b+1] - vartype = self.type_by_value[var[2:-1]] - assert type(vartype) is IndexedList - for t in vartype: - assert type(t) is TypeClause - newc = copy.deepcopy(clause) - newc.name = orig_name.replace(var, t.name) - newc.desc = [] - for d in clause.desc: - edited = d.replace(var, t.desc[0]) - if self.look_for_comma_before_equal: - m = re.match('([^,]+(,[^,=]+)+)=', edited) - if m: - # import pdb; pdb.set_trace() - orig = m.group(1).strip() - repl = '{%s}' % orig - edited = edited.replace(orig, repl) - newc.desc.append(edited) - newc.value = clause.value + t.value - type_list[newc.value] = newc - self.type_by_value[inst.name] = type_list - - # decode an encoding with an OP field - def decode_enc_op(self, inst, enc_field, op_field): - assert type(inst) is InstBlock - assert type(enc_field) is InstField - assert type(op_field) is InstField - op_type = self.type_by_value[op_field.type] - assert type(op_type) is IndexedList - encode = self.enc_by_name[enc_field.enc] - assert type(encode) is EncodingBlock - if op_field.type not in self.inst_by_optype.keys(): - self.inst_by_optype[op_field.type] = inst.name - (base, copy) = self.bits_info(encode.bits, self.high_bits) - low_bit = 32 - self.high_bits - if op_field.value >= low_bit: - shift = op_field.value - low_bit - c = 1 << shift - for t in op_type: - assert type(t) is TypeClause - if 'OPF_INTERNAL' in t.flags: - continue - b = base + (t.value << shift) - n = 'decode_' + op_field.type + '__' + t.name - self.decode_info[n] = [ op_field.type, t ] - for i in range(b, b + c): - self.decode_tables['tableDecodePrimary'][i] = n - elif op_field.v_max >= low_bit: - blk_bits = low_bit - op_field.value - c = 1 << blk_bits - n = 'decode_' + op_field.type + '__invalid' - self.decode_info[n] = [ op_field.type, self.invalid_type ] - decode_table = IndexedList(c, n) - block = 0 - for i in range(base, base + copy): - valid = 0 - for t in op_type: - assert type(t) is TypeClause - if 'OPF_INTERNAL' in t.flags: - continue - if op_field.type == 'OPU_VOP3': - if 'OPF_NOVOP3' in t.flags: - continue - if (t.value >> blk_bits) == block: - valid += 1 - n = 'decode_' + op_field.type + '__' + t.name - self.decode_info[n] = [ op_field.type, t ] - decode_table[t.value] = n - if valid > 0: - # make sure table grows to a multiple of - # block size by referencing last entry - n = decode_table[((block + 1) << blk_bits) - 1] - # - n = 'tableSubDecode_' + op_field.type - self.decode_tables[n] = decode_table - n = 'subDecode_' + op_field.type - self.decode_tables['tableDecodePrimary'][i] = n - else: - n = 'decode_' + op_field.type + '__invalid' - self.decode_info[n] = [ op_field.type, self.invalid_type ] - self.decode_tables['tableDecodePrimary'][i] = n - block += 1 - else: - op_bits = 1 + op_field.v_max - op_field.value - for i in range(base, base + copy): - c = 1 << op_bits - n = 'decode_' + op_field.type + '__invalid' - self.decode_info[n] = [ op_field.type, self.invalid_type ] - decode_table = IndexedList(c, n) - valid = 0 - for t in op_type: - assert type(t) is TypeClause - if 'OPF_INTERNAL' in t.flags: - continue - valid += 1 - n = 'decode_' + op_field.type + '__' + t.name - self.decode_info[n] = [ op_field.type, t ] - decode_table[t.value] = n - if valid > 0: - n = 'tableSubDecode_' + op_field.type - self.decode_tables[n] = decode_table - n = 'subDecode_' + op_field.type - self.decode_tables['tableDecodePrimary'][i] = n - else: - n = decode_table[0] - self.decode_tables['tableDecodePrimary'][i] = n - - def find_relevant_operand(self, operands, op_typ): - default_operand = None - for operand in operands: - if operand.parent_enc and operand.sub_enc: - if operand.parent_enc == op_typ.parent_enc: - if operand.sub_enc == op_typ.sub_enc: - return operand - continue - if operand.parent_enc: - if operand.parent_enc == op_typ.parent_enc: - return operand - continue - if operand.sub_enc: - if operand.sub_enc == op_typ.sub_enc: - return operand - if operand.sub_enc == 'NEVER': - # NEVER indicates a deeper set of operands - # which share this operand's attributes - if operand.operands: - sub = self.find_relevant_operand(operand.operands, - op_typ) - if sub: - merge = copy.deepcopy(operand) - merge.override(sub) - return merge - continue - if operand.flags: - if operand.flags[0] in op_typ.flags: - return operand - continue - default_operand = operand - return default_operand - - # return True if when clause matches op type - def when_match(self, when, op_typ): - if when.left == 'flags': - for f in when.right: - if f not in op_typ.flags: - return False - return True - return False - - def refine_op_info(self, ref_op_info, encode, op_typ): - assert type(ref_op_info) is RefinedOpInfo - assert type(encode) is EncodingBlock - assert type(op_typ) is TypeClause - relevant_operand = self.find_relevant_operand(encode.operands, op_typ) - if not relevant_operand: - return - ref_op_info.override(relevant_operand) - if op_typ.flags: - for when in relevant_operand.when: - if self.when_match(when, op_typ): - ref_op_info.override(when.operand) - sub_operands = relevant_operand.operands - if sub_operands: - sub_operand = self.find_relevant_operand(sub_operands, op_typ) - if sub_operand: - ref_op_info.override(sub_operand) - if op_typ.size >= 0 or encode.size >= 0: - default_size = op_typ.size - if default_size < 0: - default_size = encode.size - for d in ref_op_info.dst: - if not d.fmt: - if d.size < 0: - d.size = default_size - for s in ref_op_info.src: - if not s.fmt: - if s.size < 0: - s.size = default_size - if encode.name in self.ref_op_info_fixup: - suffix = op_typ.name[-3:] - if suffix not in SuffixToFmt.keys(): - return - fmt = SuffixToFmt[suffix] - for d in ref_op_info.dst: - d.fmt = fmt - for s in ref_op_info.src: - if s.index != 0: - s.fmt = fmt - - # generate instructions for an encoding with an OP field - def gen_inst(self, inst_tag, inst, encode, op_typ): - assert type(inst_tag) is str - assert type(inst) is InstBlock - assert type(encode) is EncodingBlock - assert type(op_typ) is TypeClause - if 'OPF_INTERNAL' in op_typ.flags: - return - if encode.name == 'VOP3': - if 'OPF_NOVOP3' in op_typ.flags: - return - ref_op_info = RefinedOpInfo(inst_tag, inst, encode, op_typ) - self.refine_op_info(ref_op_info, encode, op_typ) - self.refined_op_info.append(ref_op_info) - - # generate instructions for an encoding with an OP field - def gen_inst_enc_op(self, inst, enc_field, op_field): - op_type = self.type_by_value[op_field.type] - encode = self.enc_by_name[enc_field.enc] - for t in op_type: - inst_tag = enc_field.enc + '__' + t.name - self.gen_inst(inst_tag, inst, encode, t) - - # an encoding with an OP field - def handle_enc_op(self, inst, enc_field, op_field): - if op_field.type not in self.op_types_seen: - self.op_types_seen.append(op_field.type) - self.handle_parent_enc(inst, enc_field, op_field) - self.decode_enc_op(inst, enc_field, op_field) - self.gen_inst_enc_op(inst, enc_field, op_field) - - # decode an encoding with no OP field - def decode_enc_no_op(self, inst, enc_field): - encode = self.enc_by_name[enc_field.enc] - (base, copy) = self.bits_info(encode.bits, self.high_bits) - low_bit = 32 - self.high_bits - n = 'decode_OP_' + enc_field.enc - self.decode_info[n] = [ 'OP_' + enc_field.enc, self.default_type ] - for i in range(base, base + copy): - self.decode_tables['tableDecodePrimary'][i] = n - - # generate instructions for an encoding with no OP field - def gen_inst_enc_no_op(self, inst, enc_field): - op_field = InstField() - op_field.tag = 'virtual' - op_field.name = 'OP' - op_field.desc = 'default OP field for encodings with no OP field' - op_field.type = 'OP_' + enc_field.enc - self.gen_inst_enc_op(inst, enc_field, op_field) - - # an encoding with no OP field - def handle_enc_no_op(self, inst, enc_field): - self.decode_enc_no_op(inst, enc_field) - self.gen_inst_enc_no_op(inst, enc_field) - - - def handle_parent_enc_search_replace(self, operands, op_type): - for opr in operands: - if opr.sub_enc == 'NEVER': - self.handle_parent_enc_search_replace(opr.operands, op_type) - elif opr.parent_enc != '': - # add '_' after first character for OFFSET/COUNT prefix - tag = opr.parent_enc[0] + '_' + opr.parent_enc[1:] - match = tag + '_OFFSET' - offset = 0 - found = False - for t in op_type: - if t.name == match: - offset = t.value - found = True - if found != False: - op = 'OP_' + opr.parent_enc - par_enc_type = self.type_by_value[op] - add_flags = '' - for t in par_enc_type: - newt = copy.deepcopy(t) - newt.value += offset - newt.parent_enc = opr.parent_enc - newt.flags.append('OPF_PEN_%s' % opr.parent_enc) - op_type[newt.value] = newt - # check to make sure entry at offset was replaced - if op_type[offset].name == match: - op_type[offset] = None - - # handle an encoding with a parent_enc entry - def handle_parent_enc(self, inst, enc_field, op_field): - encode = self.enc_by_name[enc_field.enc] - op_type = self.type_by_value[op_field.type] - self.handle_parent_enc_search_replace(encode.operands, op_type) - - # build a table to lookup in which word an inst.field is found - def build_inst_fields(self, inst): - assert type(inst) is InstBlock - if re.search('[Ss]econd', inst.desc): - which_word = 'extData' - else: - which_word = 'instData' - - key = re.match('([^_]+)', inst.name).group(1) - if key == 'VOP': - key = inst.name - - if key in self.inst_fields.keys(): - table = self.inst_fields[key] - else: - self.inst_fields[key] = table = {} - for field in inst.fields: - table[field.name] = which_word - - def handle_inst(self, inst): - assert type(inst) is InstBlock - self.inst_by_name[inst.name] = inst - self.build_inst_fields(inst) - op_field = None - enc_field = None - # field_list will be in a form that cg_struct can use - field_list = [] - for field in inst.fields: - field_list.append([ field.name, field.value, field.v_max ]) - if field.name == 'OP': - op_field = field - elif field.name == 'ENCODING': - if field.enc != '': - enc_field = field - self.inst_formats[inst.name] = field_list - if enc_field != None: - if inst.name not in self.inst_with_encodings: - self.inst_with_encodings.append(inst.name) - if op_field != None: - self.handle_enc_op(inst, enc_field, op_field) - else: - self.handle_enc_no_op(inst, enc_field) - else: - assert op_field == None, 'inst %s enc:None op: %s' % ( - inst.name, op_field.type) - - def handle_encoding(self, statement): - self.enc_by_name[statement.name] = statement - (base, copy) = self.bits_info(statement.bits, self.high_bits) - n = 'decode_OP_' + statement.name + '__invalid' - self.decode_info[n] = [ 'OP_' + statement.name, self.invalid_type ] - primary_decode_table = self.decode_tables['tableDecodePrimary'] - for i in range(base, base + copy): - if primary_decode_table[i] == 'subDecode_invalid': - primary_decode_table[i] = n - - # check for vector v scalar instruction encodings - def vector_or_scalar(self): - enc_vec = {} - for k in self.enc_by_name.keys(): - e = self.enc_by_name[k] - if 'Vector ALU' in e.desc[0]: - enc_vec[e.name] = True - else: - enc_vec[e.name] = False - - inst_vec = {} - for k in self.inst_by_name.keys(): - i = self.inst_by_name[k] - is_vec = False - for f in i.fields: - if f.type == 'VGPR': - is_vec = True - inst_vec[i.name] = is_vec - - # check the second word if a second word exists - for k in self.inst_by_name.keys(): - i = self.inst_by_name[k] - if '_1' in i.name: - continue - if inst_vec[i.name]: - continue - if '_' in i.name: - other_word = re.sub('_.*', '_1', i.name) - else: - other_word = '%s_1' % i.name - if other_word in inst_vec.keys(): - if inst_vec[other_word]: - inst_vec[i.name] = True - - for info in self.refined_op_info: - if enc_vec[info.enc] or inst_vec[info.inst]: - if 'OPF_VECTOR' not in info.flags: - info.flags.append('OPF_VECTOR') - else: - if 'OPF_SCALAR' not in info.flags: - info.flags.append('OPF_SCALAR') - - def post_process_statements(self): - self.vector_or_scalar() - - def process_statements(self, statements): - for statement in statements: - if statement.keyword == 'const': - self.handle_const(statement) - elif statement.keyword == 'type': - self.handle_type(statement) - elif statement.keyword == 'encoding': - self.handle_encoding(statement) - elif statement.keyword == 'inst': - self.handle_inst(statement) - self.post_process_statements() - - def is_special_lit(self, inst): - for field in inst.fields: - if field.type == '': - continue - tbv = self.type_by_value[field.type] - assert type(tbv) is IndexedList - for t in range(0, len(tbv)): - if tbv[t] and tbv[t].name == 'SRC_LITERAL': - return True - return False - - def is_var_size_enc(self, pri, sec): - if self.is_special_lit(self.inst_by_name[pri]): - return True - if sec in self.inst_by_name.keys(): - if self.is_special_lit(self.inst_by_name[sec]): - return True - return False - - # gpu_decoder.hh - def generate_decoder_hh(self, output_dir): - file = os.path.join(output_dir, 'gpu_decoder.hh') - cg = CodeGen(file) - - cg.cg_code('#ifndef __GPU_INTERNAL_ARCH_VI_DECODER_HH__') - cg.cg_code('#define __GPU_INTERNAL_ARCH_VI_DECODER_HH__') - cg.cg_newline() - - cg.cg_include('') - cg.cg_include('') - cg.cg_newline() - - cg.cg_include('gpu-internal/arch/vi/gpu_types.hh') - cg.cg_newline() - cg.cg_code('class GPUStaticInst;') - cg.cg_newline() - - cg.cg_namespace('ViISA') - - cg.cg_code('class Decoder;') - cg.cg_code('union InstFormat;') - cg.cg_newline() - cg.cg_code('using IsaDecodeMethod = GPUStaticInst*' - '(Decoder::*)(MachInst);') - cg.cg_newline() - cg.cg_class('Decoder', []) - cg.cg_scope('public:') - cg.cg_code('Decoder();') - cg.cg_code('~Decoder();') - cg.cg_newline() - - cg.cg_code('GPUStaticInst* decode(MachInst);') - cg.cg_newline() - - cg.cg_method('GPUStaticInst*', '', 'decode', ['RawMachInst inst'], []) - cg.cg_code('return inst < decodedInsts.size() ? decodedInsts'\ - '.at(inst) : nullptr;') - cg.cg_end(None) - cg.cg_newline() - cg.cg_newline() - - cg.cg_method('RawMachInst', '', - 'saveInst', [ 'GPUStaticInst *decodedInst' ], []) - cg.cg_code('decodedInsts.push_back(decodedInst);') - cg.cg_code('return decodedInsts.size() - 1;') - cg.cg_end(None) - cg.cg_newline() - cg.cg_newline() - - cg.cg_scope('private:') - cg.cg_code('static std::vector decodedInsts;') - cg.cg_newline() - - methods = [] - for key in sorted(self.decode_tables.keys()): - table = self.decode_tables[key] - for m in table: - if m not in methods: - methods.append(m) - size = len(table) - cg.cg_code('static IsaDecodeMethod %s[%d];' % (key, size)) - - cg.cg_newline() - - for m in sorted(methods): - cg.cg_code('GPUStaticInst* %s(MachInst);' % m) - cg.cg_code('GPUStaticInst* decode_invalid(MachInst);') - cg.cg_end('class Decoder') # cg_class - - for key in sorted(self.inst_formats.keys()): - cg.cg_newline() - cg.cg_struct('InFmt_' + key, self.inst_formats[key]) - - cg.cg_newline() - cg.cg_union('InstFormat') - max = 0 - for key in sorted(self.inst_formats.keys()): - sz = len(key) - if max < sz: - max = sz - for key in sorted(self.inst_formats.keys()): - pad = ' ' * (max - len(key)) - cg.cg_code('InFmt_%s %siFmt_%s;' % (key, pad, key)) - dtyp = 'unsigned int' - dfld = 'imm_u32' - pad = ' ' * (max - len(dtyp)) - cg.cg_code('%s %s%s;' % (dtyp, pad, dfld)) - dtyp = 'float' - dfld = 'imm_f32' - pad = ' ' * (max - len(dtyp)) - cg.cg_code('%s %s%s;' % (dtyp, pad, dfld)) - cg.cg_end('union InstFormat') # cg_union - - cg.cg_end('namespace ViISA') # cg_namespace - cg.cg_newline() - - cg.cg_code('#endif // __GPU_INTERNAL_ARCH_VI_DECODER_HH__') - cg.generate() - - # decoder.cc base - def generate_decoder_cc(self, output_dir): - file = os.path.join(output_dir, 'decoder.cc') - cg = CodeGen(file) - - cg.cg_include('') - cg.cg_newline() - - cg.cg_include('gpu-internal/arch/vi/gpu_decoder.hh') - cg.cg_include('gpu-internal/arch/vi/gpu_static_inst.hh') - cg.cg_include('gpu-internal/arch/vi/instructions.hh') - cg.cg_newline() - - cg.cg_namespace('ViISA') - - cg.cg_method(None, 'Decoder', 'Decoder', [], []) - cg.cg_end('Decoder') # cg_method - cg.cg_newline() - - cg.cg_method(None, 'Decoder', '~Decoder', [], []) - cg.cg_end('~Decoder') # cg_method - cg.cg_newline() - - for key in sorted(self.decode_tables.keys()): - table = self.decode_tables[key] - cg.cg_table('IsaDecodeMethod', 'Decoder', key, table) - - cg.cg_method('GPUStaticInst*', 'Decoder', - 'decode', [ 'MachInst iFmt' ], []) - cg.cg_code('InFmt_SOP1 *enc = &iFmt->iFmt_SOP1;') - cg.cg_code('IsaDecodeMethod method = ' + - 'tableDecodePrimary[enc->ENCODING];') - cg.cg_code('return (this->*method)(iFmt);') - cg.cg_end('decode') # cg_method - - decoders = [] - sub_decoders = [] - for key in sorted(self.decode_tables.keys()): - table = self.decode_tables[key] - for m in table: - if m[0:7] == 'decode_': - if m not in decoders: - decoders.append(m) - elif m[0:10] == 'subDecode_': - if m not in sub_decoders: - sub_decoders.append(m) - - for m in sub_decoders: - cg.cg_newline() - cg.cg_method('GPUStaticInst*', 'Decoder', \ - m, ['MachInst iFmt'], []) - if m == 'subDecode_invalid': - cg.cg_code('return decode_invalid(iFmt);') - else: - o = m[10:] - e = self.inst_by_optype[o] - t = 'tableSubDecode_' + o - cg.cg_code('InFmt_' + e + ' *enc = &iFmt->iFmt_' + e + ';') - cg.cg_code('IsaDecodeMethod method = ' + t + '[enc->OP];') - cg.cg_code('return (this->*method)(iFmt);') - cg.cg_end(m) # cg_method - - for m in decoders: - cg.cg_newline() - cg.cg_method('GPUStaticInst*', 'Decoder', - m, ['MachInst iFmt'], []) - [ op_type, t ] = self.decode_info[m] - op_enc = re.sub('OP[U]?_', '', op_type) - op_fmt = 'iFmt_%s' % op_enc - if op_fmt == 'iFmt_VOP3': - vccd = 'OPF_VCCD' in t.flags - vopc = 'OPF_PEN_VOPC' in t.flags - if vccd or vopc: - op_fmt = 'iFmt_VOP3_SDST_ENC' - op_inst = 'Inst_%s__%s' % (op_enc, t.name) - cg.cg_code('return new %s(&iFmt->%s);' % (op_inst, op_fmt)) - cg.cg_end(m) # cg_method - - cg.cg_newline() - cg.cg_method('GPUStaticInst*', 'Decoder', - 'decode_invalid', [ 'MachInst iFmt' ], []) - cg.cg_code('return new Inst_invalid(iFmt);') - cg.cg_end('decode_invalid') # cg_method - - cg.cg_code('std::vector Decoder::decodedInsts;') - cg.cg_newline() - - cg.cg_end('namespace ViISA') # cg_namespace - - cg.generate() - - # instructions.hh - def generate_instructions_hh(self, output_dir): - file = os.path.join(output_dir, 'instructions.hh') - cg = CodeGen(file) - - cg.cg_code('#ifndef __GPU_INTERNAL_ARCH_VI_INSTRUCTIONS_HH__') - cg.cg_code('#define __GPU_INTERNAL_ARCH_VI_INSTRUCTIONS_HH__') - cg.cg_newline() - - cg.cg_include('gpu-internal/arch/vi/gpu_decoder.hh') - cg.cg_include('gpu-internal/arch/vi/gpu_static_inst.hh') - cg.cg_include('gpu-internal/arch/vi/op_encodings.hh') - cg.cg_newline() - - cg.cg_namespace('ViISA') - - for info in self.refined_op_info: - op_op = re.sub('.*__', '', info.name) - op_enc = re.sub('__.*', '', info.name) - op_inst = 'Inst_%s__%s' % (op_enc, op_op) - op_base = 'Inst_%s' % op_enc - op_fmt = 'InFmt_%s' % op_enc - if op_enc == 'VOP3': - vccd = 'OPF_VCCD' in info.flags - vopc = 'OPF_PEN_VOPC' in info.flags - if vccd or vopc: - op_base = 'Inst_VOP3_SDST_ENC' - op_fmt = 'InFmt_VOP3_SDST_ENC' - - cg.cg_class(op_inst, [ op_base ]) - cg.cg_scope('public:') - cg.cg_code('%s(%s*);' % (op_inst, op_fmt)) - - cg.cg_code('~%s();' % op_inst) - cg.cg_newline() - - n_dst = 0 - n_src = 0 - - if info.sub_enc != 'SEN_NODST' and info.sub_enc != 'SEN_G_FORK': - n_dst = info.num_dst - - if info.sub_enc != 'SEN_NOSRC': - n_src = info.num_src - - if 'OPF_RDVCC' in info.flags: - n_src += 1 - - cg.cg_method('int', None, 'getNumOperands', None, None, - 'override') - cg.cg_code('return numDstRegOperands() + numSrcRegOperands();') - cg.cg_end('getNumOperands') - - cg.cg_newline() - cg.cg_code('int numDstRegOperands() override { return %i; }' - % n_dst) - cg.cg_code('int numSrcRegOperands() override { return %i; }' - % n_src) - - # int getOperandSize(int opIdx); - op_idx = 0 - cg.cg_newline() - cg.cg_method('int', None, 'getOperandSize', ['int opIdx'], None, - 'override') - cg.cg_code('switch (opIdx) {') - for src_op in info.src: - if ((src_op.name == 'carryin' or src_op.name == 'vcc') and - 'OPF_VCCS' not in info.flags): - continue - if src_op.name == 'vgpr_d0' and 'OPF_DS1D' not in info.flags: - continue - if src_op.name == 'vgpr_d1' and 'OPF_DS2D' not in info.flags: - continue - if not src_op.fmt: - op_size = (src_op.size * 32) / 8 - elif src_op.fmt == 'RSRC_TYPED' or src_op.fmt == 'SAMP': - op_size = 4 - else: - op_size = self.fmt_to_details(src_op.fmt)[1] / 8 - cg.cg_code(' case %i: //%s' % (op_idx, src_op.name)) - cg.cg_code(' return %i;' % op_size) - op_idx += 1 - if 'OPF_RDVCC' in info.flags: - cg.cg_code(' case %i:' % op_idx) - cg.cg_code(' return 8;') - op_idx += 1 - for dst_op in info.dst: - if ((dst_op.name == 'carryout' or dst_op.name == 'vcc') and - 'OPF_VCCD' not in info.flags and op_enc != 'VOPC'): - continue - if dst_op.name == 'vgpr_rtn' and 'OPF_DSRTN' not in info.flags: - continue - if (op_inst == 'Inst_SMEM__S_LOAD_DWORD' - or op_inst == 'Inst_FLAT__FLAT_LOAD_DWORD'): - op_size = 4 - elif not dst_op.fmt: - op_size = (dst_op.size * 32) / 8 - else: - op_size = self.fmt_to_details(dst_op.fmt)[1] / 8 - cg.cg_code(' case %i: //%s' % (op_idx, dst_op.name)) - cg.cg_code(' return %i;' % op_size) - op_idx += 1 - cg.cg_code(' default:') - cg.cg_code(r' fatal("op idx %i out of bounds\n", opIdx);') - cg.cg_code(' return -1;') - cg.cg_code('}') - cg.cg_end('getOperandSize') - - # bool isSrcOperand(int opIdx); - op_idx = 0 - cg.cg_newline() - cg.cg_method('bool', None, 'isSrcOperand', ['int opIdx'], None, - 'override') - cg.cg_code('switch (opIdx) {') - for src_op in info.src: - if ((src_op.name == 'carryin' or src_op.name == 'vcc') and - 'OPF_VCCS' not in info.flags): - continue - if src_op.name == 'vgpr_d0' and 'OPF_DS1D' not in info.flags: - continue - if src_op.name == 'vgpr_d1' and 'OPF_DS2D' not in info.flags: - continue - cg.cg_code(' case %i: //%s' % (op_idx, src_op.name)) - cg.cg_code(' return true;') - op_idx += 1 - if 'OPF_RDVCC' in info.flags: - cg.cg_code(' case %i:' % op_idx) - cg.cg_code(' return true;') - op_idx += 1 - for dst_op in info.dst: - if ((dst_op.name == 'carryout' or dst_op.name == 'vcc') and - 'OPF_VCCD' not in info.flags): - continue - if dst_op.name == 'vgpr_rtn' and 'OPF_DSRTN' not in info.flags: - continue - cg.cg_code(' case %i: //%s' % (op_idx, dst_op.name)) - cg.cg_code(' return false;') - op_idx += 1 - cg.cg_code(' default:') - cg.cg_code(r' fatal("op idx %i out of bounds\n", opIdx);') - cg.cg_code(' return false;') - cg.cg_code('}') - cg.cg_end('isSrcOperand') - - # bool isDstOperand(int opIdx); - op_idx = 0 - cg.cg_newline() - cg.cg_method('bool', None, 'isDstOperand', ['int opIdx'], None, - 'override') - cg.cg_code('switch (opIdx) {') - for src_op in info.src: - if ((src_op.name == 'carryin' or src_op.name == 'vcc') and - 'OPF_VCCS' not in info.flags): - continue - if src_op.name == 'vgpr_d0' and 'OPF_DS1D' not in info.flags: - continue - if src_op.name == 'vgpr_d1' and 'OPF_DS2D' not in info.flags: - continue - cg.cg_code(' case %i: //%s' % (op_idx, src_op.name)) - cg.cg_code(' return false;') - op_idx += 1 - if 'OPF_RDVCC' in info.flags: - cg.cg_code(' case %i:' % op_idx) - cg.cg_code(' return false;') - op_idx += 1 - for dst_op in info.dst: - if ((dst_op.name == 'carryout' or dst_op.name == 'vcc') and - 'OPF_VCCD' not in info.flags): - continue - if dst_op.name == 'vgpr_rtn' and 'OPF_DSRTN' not in info.flags: - continue - cg.cg_code(' case %i: //%s' % (op_idx, dst_op.name)) - cg.cg_code(' return true;') - op_idx += 1 - cg.cg_code(' default:') - cg.cg_code(r' fatal("op idx %i out of bounds\n", opIdx);') - cg.cg_code(' return false;') - cg.cg_code('}') - cg.cg_end('isDstOperand') - - # void execute(GPUDynInstPtr gpuDynInst); - cg.cg_newline() - cg.cg_code('void execute(GPUDynInstPtr) override;') - if ('OPF_MEM_STORE' in info.flags or 'LOAD' in op_op or - op_op == 'DS_WRITE_B32' or op_op == 'DS_WRITE_B64' or - op_op == 'DS_READ_B32' or op_op == 'DS_READ_B64'): - cg.cg_code('void initiateAcc(GPUDynInstPtr) override;') - cg.cg_code('void completeAcc(GPUDynInstPtr) override;') - - #if op_enc == 'SMEM': - #info.decl.append('SregU64 offset(extData.OFFSET);') - #info.decl.append('SregU64 offset(665);') - - if op_inst in HandCodedDecl.keys(): - cg.cg_newline() - cg.cg_scope('private:') - cg.cg_block(HandCodedDecl[op_inst]) - elif info.decl: - cg.cg_newline() - cg.cg_scope('private:') - cg.cg_block(info.decl) - - cg.cg_end(op_inst) # cg_class - cg.cg_newline() - - for op_enc in self.inst_with_encodings: - if op_enc == 'EXP': - op_op = 'default' - else: - op_op = 'invalid' - op_inst = 'Inst_%s__%s' % (op_enc, op_op) - op_fmt = 'InFmt_%s' % op_enc - cg.cg_newline() - cg.cg_class(op_inst, ['Inst_%s' % op_enc ]) - cg.cg_scope('public:') - cg.cg_code('%s(%s*);' % (op_inst, op_fmt)) - cg.cg_code('~%s();' % op_inst) - cg.cg_newline() - - cg.cg_code('bool isValid() const override;') - cg.cg_code('int getNumOperands() override { return -1; }') - cg.cg_code('int numDstRegOperands() override { return -1; }') - cg.cg_code('int numSrcRegOperands() override { return -1; }') - cg.cg_code('void execute(GPUDynInstPtr) override;') - if ('OPF_MEM_STORE' in info.flags or 'LOAD' in op_op or - op_op == 'DS_WRITE_B32' or op_op == 'DS_WRITE_B64' or - op_op == 'DS_READ_B32' or op_op == 'DS_READ_B64'): - cg.cg_code('void initiateAcc(GPUDynInstPtr) override;') - cg.cg_end(op_inst) # cg_class - - cg.cg_newline() - op_inst = 'Inst_invalid' - op_fmt = 'InstFormat' - cg.cg_class(op_inst, ['ViGPUStaticInst']) - cg.cg_scope('public:') - cg.cg_code('%s(%s*);' % (op_inst, op_fmt)) - cg.cg_code('~%s();' % op_inst) - cg.cg_newline() - cg.cg_code('int getNumOperands() override { return -1; }') - cg.cg_code('int numDstRegOperands() override { return -1; }') - cg.cg_code('int numSrcRegOperands() override { return -1; }') - cg.cg_code('void execute(GPUDynInstPtr gpuDynInst) { }') - cg.cg_code('bool isValid() const override;') - cg.cg_code('uint32_t instSize();') - cg.cg_end(op_inst) # cg_class - - cg.cg_end('namespace ViISA') # cg_namespace - - cg.cg_code('#endif // __GPU_INTERNAL_ARCH_VI_INSTRUCTIONS_HH__') - cg.generate() - - def find_opr_info(self, oi_list, opr, idx): - assert type(oi_list) is list - assert type(opr) is str - assert type(idx) is int - for oi in oi_list: - assert type(oi) is OpInfo - if oi.opr == opr and oi.index == idx: - return oi - import pdb; pdb.set_trace() - return None - - def fmt_to_details(self, fmt): - if fmt in FmtToDetails.keys(): - return FmtToDetails[fmt] - if fmt == '': - return ('unknown', -1) - import pdb; pdb.set_trace() - return ('unknown', -1) - - def type_to_details(self, typ): - if typ in TypeToDetails.keys(): - return TypeToDetails[typ] - # caller can handle 'unknown' - return ('unknown', -1) - - def size_to_details(self, size): - if size > 0: - bits = 32 * size - return ('SregU%d' % bits, bits) - import pdb; pdb.set_trace() - return ('unknown', -1) - - def reg_info_to_field(self, reg, info, op_info): - assert type(reg) is str - assert type(op_info) is OpInfo - key = '%s:%s:%s:%s' % (info.enc, reg, op_info.iseq, op_info.name) - if key in EncRegInfoToField.keys(): - return EncRegInfoToField[key] - key = '%s:%s:%s' % (reg, op_info.iseq, op_info.name) - if key in RegInfoToField.keys(): - return RegInfoToField[key] - import pdb; pdb.set_trace() - return '' - - def typ_to_dtyp_dsiz(self, typ, op_info): - assert type(typ) is list - assert type(op_info) is OpInfo - # instruction desc info gets priority - details = self.type_to_details(typ[0]) - dtyp = details[0] - if dtyp == 'unknown': - details = self.fmt_to_details(op_info.fmt) - dtyp = details[0] - if dtyp == 'unknown': - details = self.size_to_details(op_info.size) - dtyp = details[0] - dsiz = details[1] - if dsiz < 0: - dsiz = op_info.size - return (dtyp, dsiz) - - def spec_reg_to_frag(self, reg, info, key): - frag = CodeFrag(key) - details = SpecRegToDetails[reg] - frag.setup(details) - if frag.ctx == '' and frag.fld == '': - op_info = self.find_opr_info(info.dst, 'dst', 0) - no_typ = ['unknown', -1] - (dtyp, dsiz) = self.typ_to_dtyp_dsiz(no_typ, op_info) - frag.typ = dtyp - return frag - - def reg_access_fragment(self, reg, info, op_info, vop, key): - assert type(reg) is DataRegClause - assert type(info) is RefinedOpInfo - assert type(op_info) is OpInfo - assert type(vop) is str - assert type(key) is str - (dtyp, dsiz) = self.typ_to_dtyp_dsiz(reg.typ, op_info) - field = self.reg_info_to_field(reg.reg, info, op_info) - if field in self.inst_fields[info.enc].keys(): - data = self.inst_fields[info.enc][field] - word = '%s.%s' % (data, field) - else: - word = field - if reg.reg in DataRegisters: - if reg.reg[-2:] == '_1': - word += ' + 1' - elif reg.reg[-2:] == '_2': - word += ' + 2' - if field and field[0] == '-': - vop = '' - var = op_info.name - codeFrag = CodeFrag(key) - codeFrag.ctx = op_info.iseq # context accessor - codeFrag.fld = word # field reference - codeFrag.var = var # variable name - codeFrag.typ = dtyp # variable type - codeFrag.exp = '' # general expression - codeFrag.vec = vop # vector index - return codeFrag - - def dst_fragment(self, reg, info): - assert type(reg) is DataRegClause - assert type(info) is RefinedOpInfo - vop = '' - if reg.reg == 'D': - op_info = self.find_opr_info(info.dst, 'dst', 0) - elif reg.reg in DataRegisters: - op_info = self.find_opr_info(info.dst, 'dst', 0) - elif reg.reg in SpecRegToDetails.keys(): - return self.spec_reg_to_frag(reg.reg, info, 'dst') - else: - import pdb; pdb.set_trace() - return None - assert type(op_info) is OpInfo - if 'OPF_VECTOR' in info.flags: - if op_info.iseq != 'SREG': # VOP3_VOPC uses a scalar dst - vop = '[t]' - return self.reg_access_fragment(reg, info, op_info, vop, 'dst') - - def get_addr_op_info(self, info): - assert type(info) is RefinedOpInfo - if info.enc in ['SMEM', 'MUBUF']: - if 'OPF_MEM_STORE' in info.flags: - return self.find_opr_info(info.src, 'src', 1) - return self.find_opr_info(info.src, 'src', 0) - - def get_data_op_info(self, info): - assert type(info) is RefinedOpInfo - if info.enc in ['SMEM', 'MUBUF']: - if 'OPF_MEM_STORE' in info.flags: - return self.find_opr_info(info.src, 'src', 0) - if 'OPF_MEM_ATOMIC' in info.flags: - return self.find_opr_info(info.dst, 'dst', 0) - return self.find_opr_info(info.src, 'src', 1) - - def src_fragment(self, reg, info): - assert type(reg) is DataRegClause - assert type(info) is RefinedOpInfo - vop = '' - if reg.reg == 'S0' or reg.reg == 'S': - op_info = self.find_opr_info(info.src, 'src', 0) - elif reg.reg == 'S1': - op_info = self.find_opr_info(info.src, 'src', 1) - elif reg.reg == 'S2': - op_info = self.find_opr_info(info.src, 'src', 2) - elif reg.reg == 'D': - op_info = self.find_opr_info(info.dst, 'dst', 0) - elif reg.reg == 'ADDR': - op_info = self.get_addr_op_info(info) - elif reg.reg == 'ADDR_BASE': - op_info = self.find_opr_info(info.src, 'src', 0) - elif reg.reg == 'DATA2': - op_info = self.find_opr_info(info.src, 'src', 2) - elif reg.reg in DataRegisters: - op_info = self.get_data_op_info(info) - elif reg.reg in SpecRegToDetails.keys(): - return self.spec_reg_to_frag(reg.reg, info, 'src') - else: - import pdb; pdb.set_trace() - return None - assert type(op_info) is OpInfo - if 'OPF_VECTOR' in info.flags: - if op_info.iseq != 'SREG': # VOP3_VOPC uses a scalar dst - vop = '[t]' - return self.reg_access_fragment(reg, info, op_info, vop, 'src') - - def unary_expr(self, clause, info): - assert type(clause) is UnaryClause - assert type(info) is RefinedOpInfo - (src_set, operand) = self.expression(clause.oprnd, info) - exp = '%s%s' % (clause.op, operand) - return (src_set, exp) - - def binary_expr(self, clause, info): - assert type(clause) is BinaryClause - assert type(info) is RefinedOpInfo - (src_set, lex) = self.expression(clause.left, info) - (rex_ss, rex) = self.expression(clause.right, info) - src_set.extend(rex_ss) - exp = '%s %s %s' % (lex, clause.op, rex) - return (src_set, exp) - - def function_expr(self, clause, info): - assert type(clause) is FunctionClause - assert type(info) is RefinedOpInfo - if clause.args: - (src_set, arg_exp) = self.expression(clause.args, info) - else: - src_set = [] - arg_exp = '' - exp = '%s(%s)' % (clause.func, arg_exp) - return (src_set, exp) - - def cond_expr(self, clause, info): - assert isinstance(clause, Clause) - assert type(info) is RefinedOpInfo - (src_set, cond_exp) = self.expression(clause.cond, info) - (true_ss, true_exp) = self.expression(clause.true, info) - (false_ss, false_exp) = self.expression(clause.false, info) - src_set.extend(true_ss) - src_set.extend(false_ss) - exp = '%s ? %s : %s' % (cond_exp, true_exp, false_exp) - return (src_set, exp) - - def const_expr(self, clause, info): - assert type(clause) is ConstantClause - assert type(info) is RefinedOpInfo - if type(clause.value) is float: - exp = '%f' % clause.value - elif clause.value < 1000: - exp = '%d' % clause.value - else: - exp = '0x%x' % clause.value - return ([], exp) - - def cast_expr(self, clause, info): - assert type(clause) is CastClause - assert type(info) is RefinedOpInfo - (src_set, var_exp) = self.expression(clause.var, info) - exp = '(%s)%s' % (clause.typ, var_exp) - return (src_set, exp) - - def func_expr(self, clause, info): - assert type(clause) is FunctionClause - assert type(info) is RefinedOpInfo - if clause.args == []: - src_set = [] - exp = '%s()' % clause.func - else: - (src_set, arg_exp) = self.expression(clause.args[0], info) - exp = '%s(%s' % (clause.func, arg_exp) - for a in clause.args[1:]: - (arg_ss, arg_exp) = self.expression(a, info) - exp += ', %s' % (arg_exp) - src_set.extend(arg_ss) - exp += ')' - return (src_set, exp) - - def comma_expr(self, clause, info): - assert type(clause) is CommaClause - assert type(info) is RefinedOpInfo - (src_set, lex) = self.expression(clause.left, info) - (right_ss, rex) = self.expression(clause.right, info) - src_set.extend(right_ss) - exp = '%s, %s' % (lex, rex) - return (src_set, exp) - - def src_gpr_expr(self, clause, info): - assert type(clause) is GprClause - assert type(info) is RefinedOpInfo - # use the S0 op_info as a reference - op_info = self.find_opr_info(info.src, 'src', 0) - (dtyp, dsiz) = self.typ_to_dtyp_dsiz(clause.typ, op_info) - if type(clause.idx) is BinaryClause: - (src_set, rex) = self.expression(clause.idx.right, info) - (left_ss, lex) = self.src_operand(clause.idx.left, info) - left_ss[0].fld += ' %s %s' % (clause.idx.op, rex) - src_set.extend(left_ss) - return (src_set, lex) - elif type(clause.idx) is DataRegClause: - return self.src_operand(clause.idx, info) - else: - import pdb; pdb.set_trace() - return ([], '') - - def dst_gpr_expr(self, clause, info): - assert type(clause) is GprClause - assert type(info) is RefinedOpInfo - # use the D0 op_info as a reference - op_info = self.find_opr_info(info.dst, 'dst', 0) - (dtyp, dsiz) = self.typ_to_dtyp_dsiz(clause.typ, op_info) - if type(clause.idx) is BinaryClause: - (src_set, rex) = self.expression(clause.idx.right, info) - (left_ss, lex) = self.dst_operand(clause.idx.left, info) - left_ss[0].fld += ' %s %s' % (clause.idx.op, rex) - src_set.extend(left_ss) - return (src_set, lex) - elif type(clause.idx) is DataRegClause: - return self.dst_operand(clause.idx, info) - else: - import pdb; pdb.set_trace() - return ([], '') - return (src_set, exp) - - def range_expr(self, range, info, var): - assert type(info) is RefinedOpInfo - if range: - if type(range) is list: - (src_set, lex) = self.expression(range[0], info) - (rex_ss, rex) = self.expression(range[1], info) - src_set.extend(rex_ss) - exp = '%s(%s, %s)' % (var, lex, rex) - else: - (src_set, lex) = self.expression(range, info) - exp = '%s(%s)' % (var, lex) - else: - src_set = [] - exp = var - return (src_set, exp) - - def src_mem_expr(self, clause, info): - assert type(clause) is MemClause - assert type(info) is RefinedOpInfo - if self.prefix: - dtyp = self.prefix - else: - if info.enc == 'SMEM': - if info.name[-5:] == 'DWORD': - # fixup hack - dst:0 size is wrong - op_info = OpInfo() - op_info.size = 1 - else: - # use the D0 op_info as a reference - op_info = self.find_opr_info(info.dst, 'dst', 0) - elif info.enc == 'FLAT': - if info.name[-5:] == 'DWORD': - # fixup hack - dst:0 size is wrong - op_info = OpInfo() - op_info.size = 1 - else: - # use the D0 op_info as a reference - op_info = self.find_opr_info(info.dst, 'dst', 0) - elif info.enc == 'MUBUF': - if info.name[-5:] == 'DWORD': - # fixup hack - dst:0 size is wrong - op_info = OpInfo() - op_info.size = 1 - else: - # use the D0 op_info as a reference - op_info = self.find_opr_info(info.dst, 'dst', 0) - else: - # use the S1 op_info as a reference - op_info = self.find_opr_info(info.src, 'src', 1) - no_typ = ['unknown', -1] - (dtyp, dsiz) = self.typ_to_dtyp_dsiz(no_typ, op_info) - (src_set, addr_exp) = self.expression(clause.addr, info) - for addr_frag in src_set: - if 'ADDR' in addr_frag.fld: - break - mem_frag = CodeFrag('src') - mem_frag.ctx = clause.mem - mem_frag.fld = addr_frag.var - mem_frag.var = '' - mem_frag.typ = dtyp - mem_frag.exp = addr_exp - mem_frag.vec = addr_frag.vec - mem_frag.scn = 'mem' - src_set.append(mem_frag) - exp = 'vmem_$%s$%s' % (mem_frag.exp, mem_frag.vec) - (rng_ss, exp) = self.range_expr(clause.rng, info, exp) - src_set.extend(rng_ss) - return (src_set, exp) - - def dst_mem_expr(self, clause, info): - assert type(clause) is MemClause - assert type(info) is RefinedOpInfo - if self.prefix: - dtyp = self.prefix - else: - if info.enc == 'SMEM': - if info.name[-5:] == 'DWORD': - # fixup hack - src:0 size is wrong - op_info = OpInfo() - op_info.size = 1 - else: - # use the S0 op_info as a reference - op_info = self.find_opr_info(info.src, 'src', 0) - elif info.enc == 'FLAT': - if info.name[-5:] == 'DWORD': - # fixup hack - src:0 size is wrong - op_info = OpInfo() - op_info.size = 1 - else: - # use the S1 op_info as a reference - op_info = self.find_opr_info(info.src, 'src', 1) - elif info.enc == 'MUBUF': - if info.name[-5:] == 'DWORD': - # fixup hack - src:0 size is wrong - op_info = OpInfo() - op_info.size = 1 - else: - # use the S0 op_info as a reference - op_info = self.find_opr_info(info.src, 'src', 0) - elif info.dst: - # use the D0 op_info as a reference - op_info = self.find_opr_info(info.dst, 'dst', 0) - else: - import pdb; pdb.set_trace() - # use the S0 op_info as a reference - op_info = self.find_opr_info(info.src, 'src', 0) - no_typ = ['unknown', -1] - (dtyp, dsiz) = self.typ_to_dtyp_dsiz(no_typ, op_info) - (src_set, addr_exp) = self.expression(clause.addr, info) - for addr_frag in src_set: - if 'ADDR' in addr_frag.fld: - break - mem_frag = CodeFrag('dst') - mem_frag.ctx = clause.mem - mem_frag.fld = addr_frag.var - mem_frag.var = '' - mem_frag.typ = dtyp - mem_frag.exp = addr_exp - mem_frag.vec = addr_frag.vec - mem_frag.scn = 'mem' - src_set.append(mem_frag) - exp = 'vmem_$%s$%s' % (mem_frag.exp, mem_frag.vec) - return (src_set, exp) - - def group_expr(self, clause, info): - assert type(clause) is GroupClause - assert type(info) is RefinedOpInfo - (src_set, grp_exp) = self.expression(clause.group[0], info) - exp = 'Group(' - comma = '' - src_set = [] - for grp in clause.group: - (grp_ss, grp_exp) = self.expression(grp, info) - src_set.extend(grp_ss) - exp += comma + grp_exp - comma = ', ' - exp += ')' - return (src_set, exp) - - def paren_expr(self, clause, info): - assert type(clause) is ParenClause - assert type(info) is RefinedOpInfo - (src_set, par_exp) = self.expression(clause.parexp, info) - exp = '(%s)' % par_exp - return (src_set, exp) - - def dst_operand(self, clause, info): - assert type(clause) is DataRegClause - assert type(info) is RefinedOpInfo - frag = self.dst_fragment(clause, info) - if not type(frag) is CodeFrag: - import pdb; pdb.set_trace() - var = frag.var + frag.vec - - if clause.idx: - (idx_ss, idx_exp) = self.expression(clause.idx, info) - frag.exp = idx_exp - else: - idx_ss = [] - - (rng_ss, var) = self.range_expr(clause.rng, info, var) - - # dst frag comes first - src_set = [ frag ] - src_set.extend(idx_ss) - src_set.extend(rng_ss) - return (src_set, var) - - def src_operand(self, clause, info): - assert type(clause) is DataRegClause - assert type(info) is RefinedOpInfo - frag = self.src_fragment(clause, info) - var = frag.var + frag.vec - - if clause.idx: - (idx_ss, idx_exp) = self.expression(clause.idx, info) - frag.exp = idx_exp - else: - idx_ss = [] - - (rng_ss, var) = self.range_expr(clause.rng, info, var) - - # src frag comes last - src_set = idx_ss - src_set.extend(rng_ss) - src_set.append(frag) - return (src_set, var) - - def expression(self, clause, info): - if not isinstance(clause, Clause): - import pdb; pdb.set_trace() - assert isinstance(clause, Clause) - assert type(info) is RefinedOpInfo - if type(clause) is DataRegClause: - (src_set, exp) = self.src_operand(clause, info) - elif type(clause) is BinaryClause: - (src_set, exp) = self.binary_expr(clause, info) - elif type(clause) is ConditionalClause: - (src_set, exp) = self.cond_expr(clause, info) - elif type(clause) is UnaryClause: - (src_set, exp) = self.unary_expr(clause, info) - elif type(clause) is FunctionClause: - (src_set, exp) = self.function_expr(clause, info) - elif type(clause) is ConstantClause: - (src_set, exp) = self.const_expr(clause, info) - elif type(clause) is CastClause: - (src_set, exp) = self.cast_expr(clause, info) - elif type(clause) is FunctionClause: - (src_set, exp) = self.func_expr(clause, info) - elif type(clause) is CommaClause: - (src_set, exp) = self.comma_expr(clause, info) - elif type(clause) is GprClause: - (src_set, exp) = self.src_gpr_expr(clause, info) - elif type(clause) is MemClause: - (src_set, exp) = self.src_mem_expr(clause, info) - elif type(clause) is GroupClause: - (src_set, exp) = self.group_expr(clause, info) - elif type(clause) is ParenClause: - (src_set, exp) = self.paren_expr(clause, info) - else: - exp = 'error' - import pdb; pdb.set_trace() - return (src_set, exp) - - def assignment(self, clause, info, g): - assert type(clause) is AssignmentClause - assert type(info) is RefinedOpInfo - assert type(g) is GenOne - - dst_regs = [] - # process the left hand side - if type(clause.dst) is DataRegClause: - (dst_set, dst_var) = self.dst_operand(clause.dst, info) - g.add_dst_set(dst_set) - for d in dst_set: - if d.key == 'dst' or d.key == 'mem': - dst_regs.append(d.var) - elif type(clause.dst) is GprClause: - (dst_set, dst_var) = self.dst_gpr_expr(clause.dst, info) - g.add_dst_set(dst_set) - for d in dst_set: - if d.key == 'dst' or d.key == 'mem': - dst_regs.append(d.var) - elif type(clause.dst) is MemClause: - (dst_set, dst_var) = self.dst_mem_expr(clause.dst, info) - g.add_dst_set(dst_set) - for d in dst_set: - if d.key == 'dst' or d.key == 'mem': - dst_regs.append(d.var) - elif type(clause.dst) is GroupClause: - dst_var = 'Group(' - comma = '' - for grp in clause.dst.group: - if type(grp) is DataRegClause: - (dst_set, grp_var) = self.dst_operand(grp, info) - elif type(grp) is MemClause: - (dst_set, grp_var) = self.dst_mem_expr(grp, info) - else: - import pdb; pdb.set_trace() - g.add_dst_set(dst_set) - for d in dst_set: - if d.key == 'dst' or d.key == 'mem': - dst_regs.append(d.var) - dst_var += comma + grp_var - comma = ', ' - dst_var += ')' - else: - assert False, 'unexpected clause' - - # process the right hand side - (src_set, src_exp) = self.expression(clause.src, info) - g.add_src_set(src_set) - - # main assignment string - g.add_math('%s %s %s;' % (dst_var, clause.op, src_exp)) - - # mark dst regs as modified so we don't load them later - g.modified.extend(dst_regs) - - def ifthenelse(self, clause, info, g): - assert type(clause) is IfThenElseClause - assert type(info) is RefinedOpInfo - assert type(g) is GenOne - (cond_ss, cond_exp) = self.expression(clause.cond, info) - g.add_src_set(cond_ss) - g.add_math('if (%s) {' % cond_exp) - g.inc_indent() - for stmt in clause.then_stmt: - if type(stmt) is AssignmentClause: - self.assignment(stmt, info, g) - elif type(stmt) is CommentClause: - pass - else: - (then_ss, then_exp) = self.expression(stmt, info) - g.add_src_set(then_ss) - g.add_math('%s;' % then_exp) - if clause.else_stmt: - g.dec_indent() - g.add_math('} else {') - g.inc_indent() - for stmt in clause.else_stmt: - if type(stmt) is AssignmentClause: - self.assignment(stmt, info, g) - elif type(stmt) is CommentClause: - pass - else: - (else_ss, else_exp) = self.expression(stmt, info) - g.add_src_set(else_ss) - g.add_math('%s;' % else_exp) - g.dec_indent() - g.add_math('}') - - def if_clause(self, clause, info, g): - assert type(clause) is IfClause - assert type(info) is RefinedOpInfo - assert type(g) is GenOne - - def tab_clause(self, clause, info, g): - assert type(clause) is TabClause - assert type(info) is RefinedOpInfo - assert type(g) is GenOne - - def else_clause(self, clause, info, g): - assert type(clause) is ElseClause - assert type(info) is RefinedOpInfo - assert type(g) is GenOne - - def chain_clause(self, clause, info, g): - assert type(clause) is ChainClause - assert type(info) is RefinedOpInfo - assert type(g) is GenOne - if type(clause.right) is AssignmentClause: - self.assignment(clause.right, info, g) - right_dst = copy.deepcopy(clause.right.dst) - right_dst.rng = None - assign = AssignmentClause() - assign.dst = clause.left - assign.op = '=' - assign.src = right_dst - g.set_vector(False) - self.assignment(assign, info, g) - g.set_vector('OPF_VECTOR' in info.flags) - - def generate_execute_code(self, op_inst, info, ast, cg): - assert type(info) is RefinedOpInfo - assert type(ast) is list - assert type(cg) is CodeGen - # fix a bug in the sq_uc.arch source - if 'OPF_MOVRELS' in info.flags: - for si in info.src: - if si.iseq == 'SREG' and si.name == 'sdst': - si.name = 'ssrc' - is_vec = 'OPF_VECTOR' in info.flags - gen_one = GenOne(op_inst, cg, is_vec, self.methods, info) - self.prefix = '' - for clause in ast: - if type(clause) is AssignmentClause: - self.assignment(clause, info, gen_one) - elif type(clause) is IfThenElseClause: - self.ifthenelse(clause, info, gen_one) - elif type(clause) is IfClause: - self.if_clause(clause, info, gen_one) - elif type(clause) is TabClause: - self.tab_clause(clause, info, gen_one) - elif type(clause) is ElseClause: - self.else_clause(clause, info, gen_one) - elif type(clause) is ChainClause: - self.chain_clause(clause, info, gen_one) - elif type(clause) is SizeClause: - if 'OPF_MEM_ATOMIC' in info.flags: - #import pdb; pdb.set_trace() - self.prefix = 'SregU%d' % clause.size - info_copy = copy.deepcopy(info) - info_copy.dst[0].size = clause.size / 32 - info = info_copy - elif type(clause) is CommentClause: - pass - else: - import pdb; pdb.set_trace() - assert False, 'should not get here' - return gen_one.finish() - - def parse_and_generate(self, op_inst, info, cg): - assert type(op_inst) is str - assert type(info) is RefinedOpInfo - assert type(cg) is CodeGen - try: - ast = self.desc_parser.parse_description(info.desc) - # print '--------------------------\n%s' % (op_inst) - # pprint(info.desc) - # pprint(ast) - if not self.generate_execute_code(op_inst, info, ast, cg): - cg.cg_comment('Could not parse sq_uc.arch desc field') - cg.cg_code('//gpuDynInst->warnUnimplemented("TBD: %s");' - % op_inst) - return 'empty' - except ParseError: - # print '--------------------------\n%s' % (op_inst) - # pprint(info.desc) - cg.cg_comment('Could not parse sq_uc.arch desc field') - cg.cg_code('//gpuDynInst->warnUnimplemented("TBD: %s");' - % op_inst) - return 'except' - except: - raise - return 'success' - - def setOpTypeFlags(self, info, op_enc, op_op, cg): - # Op type flags: - # Nop - op_op contains NOP - # ALU - # Branch - op_op contains BRANCH or CBRANCH - # Conditional Branch - op_op contains CBRANCH - # Return - not implemented - # MemFence - no matching VI ISA operations - # MemBarrier - S_BARRIER - # Flat - op_enc = FLAT - # SpecialOp - not implemented - if 'CBRANCH' in op_op: - cg.cg_code('setFlag(CondBranch);') - if op_op == 'S_BARRIER': - cg.cg_code('setFlag(MemBarrier);') - elif op_op == 'S_WAITCNT': - cg.cg_code('setFlag(ALU);') - cg.cg_code('setFlag(Waitcnt);') - elif op_op == 'S_ENDPGM': - cg.cg_code('setFlag(ALU);') - elif 'NOP' in op_op: - cg.cg_code('setFlag(Nop);') - if op_op == 'V_NOP': - cg.cg_code('setFlag(ALU);') - elif 'BRANCH' in op_op: - cg.cg_code('setFlag(Branch);') - elif op_op in ['S_SETPC', 'S_SWAPPC', 'S_SETVSKIP']: - cg.cg_code('setFlag(UnconditionalJump);') - # set ALU flag for each encoding - elif (op_enc == 'SOP2' and not op_op in - ['S_CBRANCH_G_FORK', 'S_RFE_RESTORE_B64']): - cg.cg_code('setFlag(ALU);') - elif (op_enc == 'SOPK' and not op_op in - ['S_GETREG_B32', 'S_SETREG_B32', 'S_SETREG_IMM32_B32']): - cg.cg_code('setFlag(ALU);') - elif (op_enc == 'SOP1' and not op_op in - ['S_GETPC_B64', 'S_SETPC_B64', 'S_SWAPPC_B64', 'S_RFE_B64', - 'S_SET_GPR_IDX_IDX']): - cg.cg_code('setFlag(ALU);') - elif (op_enc == 'SOPC' and not op_op in - ['S_SETVSKIP', 'S_SET_GPR_IDX_ON']): - cg.cg_code('setFlag(ALU);') - elif op_enc == 'VOP2': - cg.cg_code('setFlag(ALU);') - elif op_enc == 'VOP1' and not op_op in ['V_READFIRSTLANE_B32']: - cg.cg_code('setFlag(ALU);') - elif op_enc == 'VOPC': - cg.cg_code('setFlag(ALU);') - elif op_enc == 'VINTRP': - cg.cg_code('setFlag(ALU);') - elif (op_enc == 'VOP3' and not op_op in - ['V_CLREXCP', 'V_READLANE_B32', 'V_WRITELANE_B32']): - cg.cg_code('setFlag(ALU);') - elif (op_enc in ['SOPP', 'SMEM', 'DS', 'MUBUF', 'MTBUF', 'MIMG', 'EXP', - 'FLAT']): - # remaining opcodes in these encodings are - # considered ALU operations - pass - - def setMemoryAccessFlags(self, info, op_enc, op_op, cg): - # set memory access flags for non-atomic operations - if 'OPF_MEM_STORE' in info.flags or 'DS_WRITE' in op_op: - cg.cg_code('setFlag(MemoryRef);') - cg.cg_code('setFlag(Store);') - elif 'LOAD' in op_op or 'DS_READ' in op_op: - cg.cg_code('setFlag(MemoryRef);') - cg.cg_code('setFlag(Load);') - - def setSegmentAccessFlags(self, info, op_enc, op_op, cg): - if op_enc in ['MUBUF', 'MTBUF', 'MIMG']: - cg.cg_code('setFlag(GlobalSegment);') - - def setAtomicFlags(self, info, op_enc, op_op, cg): - ops = {'AND' : 'AtomicAnd', - 'OR' : 'AtomicOr', - 'XOR' : 'AtomicXor', - 'CMPSWAP' : 'AtomicCAS', - 'ADD' : 'AtomicAdd', - 'SUB' : 'AtomicSub', - 'INC' : 'AtomicInc', - 'DEC' : 'AtomicDec', - 'MAX' : 'AtomicMax', - 'SMAX' : 'AtomicMax', - 'UMAX' : 'AtomicMax', - 'MIN' : 'AtomicMin', - 'SMIN' : 'AtomicMin', - 'UMIN' : 'AtomicMin', - 'SWAP' : 'AtomicExch' - } - atomic_op = re.sub('.*ATOMIC_', '', op_op) - atomic_op = re.sub('_.*', '', atomic_op) - - if atomic_op in ops.keys(): - cg.cg_code('setFlag(%s);' % ops[atomic_op]) - # for atomics, the GLC bit determines if - # an atomic returns the pre-op value - cg.cg_if('instData.GLC') - cg.cg_code('setFlag(AtomicReturn);') - cg.cg_else() - cg.cg_code('setFlag(AtomicNoReturn);') - cg.cg_end('if') - cg.cg_code('setFlag(MemoryRef);') - - - def setModeFlags(self, info, op_op, cg): - if ('S_SETVSKIP' in op_op or 'S_SETREG' in op_op - or 'S_SET_GPR' in op_op): - cg.cg_code('setFlag(WritesMode);') - if 'S_GETREG' in op_op: - cg.cg_code('setFlag(ReadsMode);') - - def setEXECFlags(self, info, cg): - if 'OPF_RDEX' in info.flags: - cg.cg_code('setFlag(ReadsEXEC);') - if 'OPF_WREX' in info.flags: - cg.cg_code('setFlag(WritesEXEC);') - - def setVCCFlags(self, info, cg): - if 'OPF_VCCD' in info.flags: - cg.cg_code('setFlag(WritesVCC);') - if 'OPF_VCCS' in info.flags or 'OPF_RDVCC' in info.flags: - cg.cg_code('setFlag(ReadsVCC);') - - def setFlags(self, info, op_inst, op_enc, op_op, cg): - self.setOpTypeFlags(info, op_enc, op_op, cg) - self.setVCCFlags(info, cg) - self.setEXECFlags(info, cg) - self.setModeFlags(info, op_op, cg) - if 'OPF_MEM_ATOMIC' in info.flags: - self.setAtomicFlags(info, op_enc, op_op, cg) - else: - self.setMemoryAccessFlags(info, op_enc, op_op, cg) - self.setSegmentAccessFlags(info, op_enc, op_op, cg) - - # instructions.cc - def generate_instructions_cc(self, output_dir): - file = os.path.join(output_dir, 'instructions.cc') - cg = CodeGen(file) - - cg.cg_include('') - cg.cg_newline() - - cg.cg_include('gpu-compute/shader.hh') - cg.cg_include('gpu-internal/arch/vi/instructions.hh') - cg.cg_include('gpu-internal/arch/vi/inst_util.hh') - cg.cg_newline() - - cg.cg_namespace('ViISA') - - instruction_index = 0 - empty_count = 0 - exception_count = 0 - found_exceptions = [] - known_except = copy.deepcopy(KnownExceptions) - found_empty = [] - known_empty = copy.deepcopy(KnownEmpty) - - for info in self.refined_op_info: - op_op = re.sub('.*__', '', info.name) - op_enc = re.sub('__.*', '', info.name) - op_inst = 'Inst_%s__%s' % (op_enc, op_op) - op_base = 'Inst_%s' % op_enc - op_fmt = 'InFmt_%s' % op_enc - if op_fmt == 'InFmt_VOP3': - vccd = 'OPF_VCCD' in info.flags - vopc = 'OPF_PEN_VOPC' in info.flags - if vccd or vopc: - op_base = 'Inst_VOP3_SDST_ENC' - op_fmt = 'InFmt_VOP3_SDST_ENC' - arg = '%s *iFmt' % op_fmt - ini = '%s(iFmt, "%s")' % (op_base, op_op.lower()) - - cg.cg_comment('--- %s class methods ---' % op_inst) - cg.cg_newline() - cg.cg_method(None, op_inst, op_inst, [arg], [ini]) - self.setFlags(info, op_inst, op_enc, op_op, cg) # set Flags - cg.cg_end(op_inst) # cg_method - cg.cg_newline() - cg.cg_method(None, op_inst, '~%s' % op_inst, [], []) - cg.cg_end('~%s' % op_inst) # cg_method - cg.cg_newline() - - cg.cg_comment('--- description from .arch file ---') - edited = [] - for d in info.desc: - edited.extend(d.split('\\n')) - for e in edited: - if e: - line = e.replace('\\t', ' ') - lead = '' - abs_max = 80 - 3 # cg_comment prepends '// ' - len_max = abs_max - len(lead) - while len(line) > len_max: - brk = line.rfind(' ', 0, len_max) - cg.cg_comment(lead + line[0:brk]) - line = line[brk:] - lead = '--- ' - len_max = abs_max - len(lead) - cg.cg_comment(lead + line) - cg.cg_method('void', op_inst, 'execute', - ['GPUDynInstPtr gpuDynInst'], []) - # breakpoint - #if op_inst == 'Inst_MUBUF__BUFFER_ATOMIC_SWAP': - # import pdb; pdb.set_trace() - if op_inst in HandCodedExecMethods.keys(): - cg.cg_block(HandCodedExecMethods[op_inst]) - cg.cg_end('execute') # cg_method - else: - result = self.parse_and_generate(op_inst, info, cg) - if result == 'success': - pass - elif result == 'empty': - empty_count += 1 - if op_inst not in known_empty: - found_empty.append(op_inst) - print('Parse Empty') - pprint(found_empty) - import pdb; pdb.set_trace() - else: - known_empty.remove(op_inst) - cg.cg_end('execute') # cg_method - elif result == 'except': - exception_count += 1 - if op_inst not in known_except: - found_exceptions.append(op_inst) - print('Parse Error') - pprint(found_exceptions) - import pdb; pdb.set_trace() - else: - known_except.remove(op_inst) - cg.cg_end('execute') # cg_method - instruction_index += 1 - if known_empty: - print('Problems in instructions %s are no longer seen.' % ( - repr(known_empty))) - if known_except: - print('Exceptions in instructions %s are no longer seen.' % ( - repr(known_except))) - i = instruction_index - e = empty_count - print('Found no pseudo code in %d of %d instructions' % (e, i)) - e = exception_count - print('Found exceptions in %d of %d instructions' % (e, i)) - - for op_enc in self.inst_with_encodings: - if op_enc == 'EXP': - op_op = 'default' - else: - op_op = 'invalid' - op_inst = 'Inst_%s__%s' % (op_enc, op_op) - cg.cg_newline() - cg.cg_comment('--- %s class methods ---' % op_inst) - arg = 'InFmt_%s *iFmt' % op_enc - ini = 'Inst_%s(iFmt, "%s_%s")' % (op_enc, op_enc, op_op) - cg.cg_method(None, op_inst, op_inst, [arg], [ini]) - cg.cg_end(op_inst) # cg_method - cg.cg_method(None, op_inst, '~%s' % op_inst, [], []) - cg.cg_end('~%s' % op_inst) # cg_method - cg.cg_newline() - cg.cg_method('bool', op_inst, 'isValid', [], [], 'const') - cg.cg_code('return false;') - cg.cg_end('isValid') # cg_method - cg.cg_method('void', op_inst, 'execute', - ['GPUDynInstPtr gpuDynInst'], []) - cg.cg_code('//gpuDynInst->warnUnimplemented("%s");' % op_inst) - cg.cg_end('execute') # cg_method - - op_inst = 'Inst_invalid' - cg.cg_newline() - cg.cg_comment('--- %s class methods ---' % op_inst) - cg.cg_method(None, op_inst, op_inst, - ['MachInst'], - ['ViGPUStaticInst("Inst_invalid")']) - cg.cg_end(op_inst) # cg_method - cg.cg_method(None, op_inst, '~%s' % op_inst, [], []) - cg.cg_end('~%s' % op_inst) # cg_method - cg.cg_newline() - cg.cg_method('uint32_t', op_inst, 'instSize', [], []) - cg.cg_code('return 4;') - cg.cg_end('instSize') # cg_method - cg.cg_method('bool', op_inst, 'isValid', [], [], 'const') - cg.cg_code('return false;') - cg.cg_end('isValid') # cg_method - - cg.cg_end('namespace ViISA') # cg_namespace - - cg.generate() - - def generate_code(self, output_dir): - # pprint(self.refined_op_info) - self.generate_decoder_hh(output_dir) - self.generate_decoder_cc(output_dir) - self.generate_instructions_cc(output_dir) - self.generate_instructions_hh(output_dir) diff --git a/src/arch/amdgpu/gcn3/ast_objects.py b/src/arch/amdgpu/gcn3/ast_objects.py deleted file mode 100644 index c658f31ff5..0000000000 --- a/src/arch/amdgpu/gcn3/ast_objects.py +++ /dev/null @@ -1,865 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -class Statement(object): - def __init__(self): - self.keyword = '' - -class ImportStatement(Statement): - def __init__(self): - self.keyword = 'import' - self.what = '' - self.name = '' - -class FlagBlock(Statement): - def __init__(self): - self.keyword = 'flag' - self.name = '' - self.desc = [] - - def update(self, ref): - if ref.tag == 'name': - self.name = ref.name - elif ref.tag == 'desc': - self.desc = ref.desc - elif ref.tag == 'desc+': - self.desc = self.desc + ref.desc - else: - assert (False), 'error: unexpected FlagBlock.tag' + ref.tag - self.tag = 'updated' - -class FlagsField(object): - def __init__(self): - self.tag = '' - self.name = '' - self.private = 0 - self.desc = [] - self.group = '' - - def update(self, ref): - if ref.tag == 'name': - self.name = ref.name - elif ref.tag == 'private': - self.private = ref.private - elif ref.tag == 'desc': - self.desc = ref.desc - elif ref.tag == 'desc+': - self.desc = self.desc + ref.desc - elif ref.tag == 'group': - self.group = ref.group - else: - assert (False), 'error: unexpected FlagsField.tag ' + ref.tag - self.tag = 'updated' - -class FlagsBlock(Statement): - def __init__(self): - self.keyword = 'flags' - self.clauses = [] - -class OpInfo(object): - def __init__(self): - self.tag = '' - self.opr = '' - self.index = -1 - self.iseq = '' - self.name = '' - self.fmt = '' - self.size = -1 - self.inout = -1 - - def __repr__(self): - text = '\n [\n' - text += '\topr: ' + repr(self.opr) + ',\n' - text += '\tindex: ' + repr(self.index) + ',\n' - text += '\tiseq: ' + repr(self.iseq) + ',\n' - text += '\tname: ' + repr(self.name) + ',\n' - text += '\tfmt: ' + repr(self.fmt) + ',\n' - text += '\tsize: ' + repr(self.size) + ',\n' - text += '\tinout: ' + repr(self.inout) + '\n' - text += '\n ]\n' - return text - - def update(self, ref): - if ref.tag == 'dst': - self.opr = ref.opr - self.index = ref.index - self.iseq = ref.iseq - elif ref.tag == 'src': - self.opr = ref.opr - self.index = ref.index - self.iseq = ref.iseq - elif ref.tag == 'name': - self.name = ref.name - elif ref.tag == 'fmt': - self.fmt = ref.fmt - elif ref.tag == 'size': - self.size = ref.size - elif ref.tag == 'inout': - self.inout = ref.inout - else: - assert (False), 'error: unexpected OpInfo.tag ' + ref.tag - self.tag = 'updated' - - def match(self, ref): - if self.opr != ref.opr: - return False - if self.index != ref.index: - return False - return True - - def override(self, ref): - if ref.iseq: - self.iseq = ref.iseq - if ref.name: - self.name = ref.name - if ref.fmt: - self.fmt = ref.fmt - if ref.size >= 0: - self.size = ref.size - if ref.inout >= 0: - self.inout = ref.inout - -class Operand(object): - def __init__(self): - self.tag = '' - self.num_dst = -1 - self.num_src = -1 - self.parent_enc = '' - self.sub_enc = '' - self.flags = [] - self.dst = [] - self.src = [] - self.when = [] - self.operands = [] - - def __repr__(self): - text = '\tnum_dst: ' + repr(self.num_dst) + ',\n' - text += '\tnum_src: ' + repr(self.num_src) + ',\n' - text += '\tparent_enc: ' + repr(self.parent_enc) + ',\n' - text += '\tsub_enc: ' + repr(self.sub_enc) + ',\n' - text += '\tflags: ' + repr(self.flags) + ',\n' - text += '\tdst: ' + repr(self.dst) + ',\n' - text += '\tsrc: ' + repr(self.src) + ',\n' - text += '\twhen: ' + repr(self.when) + ',\n' - text += '\toperands: ' + repr(self.operands) + '\n' - return text - - def update(self, ref): - if ref.tag == 'num_dst': - self.num_dst = ref.num_dst - elif ref.tag == 'num_src': - self.num_src = ref.num_src - elif ref.tag == 'parent_enc': - self.parent_enc = ref.parent_enc - elif ref.tag == 'sub_enc': - self.sub_enc = ref.sub_enc - elif ref.tag == 'flags': - self.flags = self.flags + ref.flags - elif ref.tag == 'dst': - self.dst = self.dst + ref.dst - elif ref.tag == 'src': - self.src = self.src + ref.src - elif ref.tag == 'when': - self.when = self.when + ref.when - elif ref.tag == 'operands': - self.operands = self.operands + ref.operands - else: - assert (False), 'error: unexpected Operand.tag ' + ref.tag - self.tag = 'updated' - - def override(self, ref): - if ref.num_dst > 0: - self.num_dst = ref.num_dst - if ref.num_src > 0: - self.num_src = ref.num_src - for r in ref.dst: - for s in self.dst: - if s.match(r): - s.override(r) - for r in ref.src: - for s in self.src: - if s.match(r): - s.override(r) - -class WhenBlock(object): - def __init__(self): - self.left = '' - self.right = [] - self.operand = None - -class EncodingBlock(Statement): - def __init__(self): - self.keyword = 'encoding' - self.tag = '' - self.name = '' - self.bits = '' - self.size = -1 - self.desc = [] - self.operands = [] - - def update(self, ref): - if ref.tag == 'name': - self.name = ref.name - elif ref.tag == 'bits': - self.bits = ref.bits - elif ref.tag == 'size': - self.size = ref.size - elif ref.tag == 'desc': - self.desc = self.desc + ref.desc - elif ref.tag == 'operands': - self.operands = self.operands + ref.operands - else: - assert (False), 'error: unexpected EncodingBlock.tag ' + ref.tag - self.tag = 'updated' - -class ConstClause(object): - def __init__(self): - self.name = '' - self.value = 0 - -class ConstBlock(Statement): - def __init__(self): - self.keyword = 'const' - self.clauses = [] - -class TypeClause(object): - def __init__(self): - self.tag = '' - self.name = '' - self.v_max = 0 - self.value = 0 - self.dp_only = 0 - self.size = -1 - self.var = False - self.desc = [] - self.flags = [] - self.src_flags = '' - self.sp3_desc = [] - self.sp3_name = '' - self.sp3_ncomp = 0 - self.sp3_num = '' - self.parent_enc = '' - self.sub_enc = '' - self.op_type = '' - self.fmt = '' - self.type = '' - self.range = [] - self.size_bits = -1 - - def update(self, ref): - if ref.tag == 'id_range': - self.name = ref.name - self.v_max = ref.v_max - self.value = ref.value - elif ref.tag == 'id_number': - self.name = ref.name - self.value = ref.value - elif ref.tag == 'id_var_number': - self.name = ref.name - self.value = ref.value - self.var = ref.var - elif ref.tag == 'desc': - self.desc = ref.desc + self.desc - elif ref.tag == 'desc+': - self.desc = self.desc + ref.desc - elif ref.tag == 'flags': - self.flags = ref.flags + self.flags - elif ref.tag == 'flags+': - self.flags = self.flags + ref.flags - elif ref.tag == 'src_flags': - self.src_flags = ref.src_flags - elif ref.tag == 'sp3_desc': - self.sp3_desc = ref.sp3_desc + self.sp3_desc - elif ref.tag == 'sp3_desc+': - self.sp3_desc = self.sp3_desc + ref.sp3_desc - elif ref.tag == 'sp3_name': - self.sp3_name = ref.sp3_name - elif ref.tag == 'sp3_ncomp': - self.sp3_ncomp = ref.sp3_ncomp - elif ref.tag == 'sp3_num': - self.sp3_num = ref.sp3_num - elif ref.tag == 'parent_enc': - self.parent_enc = ref.parent_enc - elif ref.tag == 'sub_enc': - self.sub_enc = ref.sub_enc - elif ref.tag == 'op_type': - self.op_type = ref.op_type - elif ref.tag == 'dp_only': - self.dp_only = ref.dp_only - elif ref.tag == 'size': - self.size = ref.size - elif ref.tag == 'fmt': - self.fmt = ref.fmt - elif ref.tag == 'type': - self.type = ref.type - elif ref.tag == 'range': - self.range = ref.range - else: - assert (False), 'error: unexpected TypeClause.tag ' + ref.tag - self.tag = 'updated' - -class TypeBlock(Statement): - def __init__(self): - self.keyword = 'type' - self.name = '' - self.clauses = [] - -class InstField(object): - def __init__(self): - self.tag = '' - self.name = '' - self.v_max = 0 - self.value = 0 - self.desc = '' - self.type = '' - self.enc = '' - - def update(self, ref): - if ref.tag == 'id_range': - self.name = ref.name - self.v_max = ref.v_max - self.value = ref.value - elif ref.tag == 'id_number': - self.name = ref.name - self.value = ref.value - elif ref.tag == 'desc': - self.desc = ref.desc - elif ref.tag == 'type': - self.type = ref.type - elif ref.tag == 'enc': - self.enc = ref.enc - else: - assert (False), 'error: unexpected InstField.tag ' + ref.tag - self.tag = 'updated' - -class InstBlock(Statement): - def __init__(self): - self.keyword = 'inst' - self.tag = '' - self.name = '' - self.desc = '' - self.fields = [] - - def update(self, ref): - if ref.tag == 'name': - self.name = ref.name - elif ref.tag == 'desc': - self.desc = ref.desc - elif ref.tag == 'fields': - self.fields = ref.fields - else: - assert (False), 'error: unexpected InstBlock.tag ' + ref.tag - self.tag = 'updated' - -FmtToDetails = { - 'NUM_B8' : ( 'SregU8', 8 ), - 'NUM_I8' : ( 'SregI8', 8 ), - 'NUM_B16' : ( 'SregU16', 16 ), - 'NUM_F16' : ( 'SregF16', 16 ), - 'NUM_B32' : ( 'SregU32', 32 ), - 'NUM_F32' : ( 'SregF32', 32 ), - 'NUM_I32' : ( 'SregI32', 32 ), - 'NUM_U32' : ( 'SregU32', 32 ), - 'NUM_B64' : ( 'SregU64', 64 ), - 'NUM_I64' : ( 'SregI64', 64 ), - 'NUM_F64' : ( 'SregF64', 64 ), - 'NUM_U64' : ( 'SregU64', 64 ), - 'BUF' : ( 'SregU64', 64 ), - 'NUM_B96' : ( 'SregU96', 96 ), - 'NUM_B128' : ( 'SregU128', 128 ), - 'RSRC_SCRATCH' : ( 'SregU128', 128 ), - 'RSRC_SCALAR' : ( 'SregU128', 128 ), - 'IMG' : ( 'SregU256', 256 ), -} - -# which get method is used to retrieve -# or set data -TypeToAccessMethod = { - # scalar reg file get - 'SregU8' : 'ScalarReg', - 'SregI8' : 'ScalarReg', - 'SregU16' : 'ScalarReg', - 'SregI16' : 'ScalarReg', - 'SregU32' : 'ScalarReg', - 'SregI32' : 'ScalarReg', - 'SregU64' : 'ScalarReg', - 'SregI64' : 'ScalarReg', - 'SregU96' : 'ScalarReg', - 'SregU128' : 'ScalarReg', - 'SregU256' : 'ScalarReg', - 'SregU512' : 'ScalarReg', - 'SregF16' : 'ScalarReg', - 'SregF32' : 'ScalarReg', - 'SregF64' : 'ScalarReg', - - # vector reg file get - 'VregU8' : 'VectorReg', - 'VregI8' : 'VectorReg', - 'VregU16' : 'VectorReg', - 'VregI16' : 'VectorReg', - 'VregU32' : 'VectorReg', - 'VregI32' : 'VectorReg', - 'VregU64' : 'VectorReg', - 'VregI64' : 'VectorReg', - 'VregU96' : 'VectorReg', - 'VregU128' : 'VectorReg', - 'VregU256' : 'VectorReg', - 'VregU512' : 'VectorReg', - 'VregF16' : 'VectorReg', - 'VregF32' : 'VectorReg', - 'VregF64' : 'VectorReg', -} - -SpecialCtx = { - 'SRC_NOLIT' : 'SrcReg', - 'SRC' : 'SrcReg', - 'SRC_NOLDS' : 'SrcReg', - 'SRC_SIMPLE' : 'SrcReg', - 'EXEC' : 'SpecialReg', - 'VCC' : 'SpecialReg', - 'SCC' : 'SpecialReg', - 'PC' : 'SpecialReg', - 'PRIV' : 'SpecialReg', - 'INST_ATC' : 'SpecialReg', - 'M0' : 'SpecialReg', - 'VSKIP' : 'SpecialReg', - 'PI' : 'SpecialReg', - 'NAN' : 'SpecialReg', - 'INF' : 'SpecialReg', - 'P0' : 'SpecialReg', - 'P10' : 'SpecialReg', - 'P20' : 'SpecialReg', - 'TBA' : 'SpecialReg', -} - -# for DS fixup -SuffixToFmt = { - '_I8' : 'NUM_I8', - 'I32' : 'NUM_I32', - 'I64' : 'NUM_I64' -} - -EncRegInfoToField = { - 'DS:ADDR:VGPR:vgpr_a' : 'ADDR', - 'MUBUF:ADDR:VGPR:vgpr_a' : 'VADDR', - 'MIMG:ADDR:VGPR:vgpr_a' : 'VADDR', -} - -RegInfoToField = { - 'D:SDST:sdst' : 'SDST', - 'D:SREG:sdst' : 'SDST', - 'S0:SDST:ssrc' : 'SDST', - 'S:SSRC:ssrc' : 'SSRC0', - 'S0:SREG:ssrc' : 'SSRC0', - 'S0:SSRC:ssrc' : 'SSRC0', - 'S0:SSRC:ssrc_0' : 'SSRC0', - 'S1:SSRC:ssrc_1' : 'SSRC1', - 'SGPR:SREG:sgpr' : '', - 'D:VGPR:vdst' : 'VDST', - 'D:VGPR:vgpr_dst' : 'VDST', - 'S0:SRC:src' : 'SRC0', - 'S0:SRC:src_0' : 'SRC0', - 'S0:SRC_NOLDS:src_0' : 'SRC0', - 'S0:SRC_NOLIT:src_0' : 'SRC0', - 'S0:SRC_NOLIT:src' : 'SRC0', - 'S0:SRC_VGPR:src' : 'SRC0', - 'S:SRC:src' : 'SRC0', - 'S:SRC_NOLIT:src' : 'SRC0', - 'S0:SRC_SIMPLE:src_0' : 'SRC0', - 'S1:SRC_SIMPLE:src_1' : 'SRC1', - 'S2:SRC_SIMPLE:src_2' : 'SRC2', - 'S1:VGPR:src_1' : 'VSRC1', - 'S:VGPR:vgpr_ij' : 'VSRC', - 'S:SRC_VGPR:vgpr_ij' : 'SRC0', - 'S0:SRC_VGPR:vgpr_ij' : 'SRC0', - 'S2:SRC_VGPR:vgpr_add' : 'SRC2', - 'S2:VGPR:src_2' : 'VSRC1', - 'VGPR:VGPR:vgpr' : '', - 'VGPR:SRC:vgpr' : '', - 'VGPR:SRC_VGPR:vgpr' : '', - 'VGPR:SRC_NOLIT:vgpr' : '', - 'MEM:MEM:Mem()' : '', - 'A:VGPR:vgpr_a' : '', - 'B:VGPR:vgpr_a' : '', - 'ADDR:SREG:sgpr_base' : 'SBASE', - 'DATA:SMWR_OFFSET:offset' : 'OFFSET', - 'DATA:SREG:sgpr_data' : 'SDATA', - 'RETURN_DATA:SREG:sgpr_data' : 'SDATA', - 'ADDR_BASE:VGPR:vgpr_a' : 'ADDR', - 'DATA:VGPR:vgpr_d0' : 'DATA0', - 'DATA_0:VGPR:vgpr_d0' : 'DATA0', - 'DATA_1:VGPR:vgpr_d0' : 'DATA0', - 'DATA_2:VGPR:vgpr_d0' : 'DATA0', - 'RETURN_DATA:VGPR:vgpr_rtn' : 'VDST', - 'RETURN_DATA_0:VGPR:vgpr_rtn' : 'VDST', - 'RETURN_DATA_1:VGPR:vgpr_rtn' : 'VDST', - 'DATA2:VGPR:vgpr_d1' : 'DATA1', - 'DATA:SREG:sgpr_r' : 'SRSRC', - 'DATA_0:SREG:sgpr_r' : 'SRSRC', - 'DATA_1:SREG:sgpr_r' : 'SRSRC', - 'DATA_2:SREG:sgpr_r' : 'SRSRC', - 'DATA:SREG:sgpr_dst' : 'SDATA', - 'DATA:VGPR:vgpr_d' : 'VDATA', - 'DATA_0:VGPR:vgpr_d' : 'VDATA', - 'DATA_1:VGPR:vgpr_d' : 'VDATA', - 'DATA_2:VGPR:vgpr_d' : 'VDATA', - 'RETURN_DATA:VGPR:vgpr_d' : 'VDATA', - 'RETURN_DATA_0:VGPR:vgpr_d' : 'VDATA', - 'RETURN_DATA_1:VGPR:vgpr_d' : 'VDATA', - 'ADDR:VGPR:vgpr_addr' : 'ADDR', - 'ADDR:VGPR:vgpr_src' : 'ADDR', - 'DATA:VGPR:vgpr_src' : 'DATA', - 'DATA_0:VGPR:vgpr_src' : 'DATA', - 'DATA_1:VGPR:vgpr_src' : 'DATA', - 'DATA_2:VGPR:vgpr_src' : 'DATA', - 'DATA:VGPR:vgpr_dst' : 'VDST', - 'DATA_0:VGPR:vgpr_dst' : 'VDST', - 'DATA_1:VGPR:vgpr_dst' : 'VDST', - 'DATA_2:VGPR:vgpr_dst' : 'VDST', - 'RETURN_DATA:VGPR:vgpr_dst' : 'VDST', - 'RETURN_DATA_0:VGPR:vgpr_dst' : 'VDST', - 'RETURN_DATA_1:VGPR:vgpr_dst' : 'VDST', - 'D:VCC:vcc' : '-VCC', -} - -DataRegisters = ['DATA', 'DATA_0', 'DATA_1', 'DATA_2', 'RETURN_DATA', - 'RETURN_DATA_0', 'RETURN_DATA_1'] - -SpecRegToDetails = { - 'SCC' : ['SCC', '', 'scc', 'SregU32', '', ''], - 'M0' : ['M0', '', 'm0', 'SregU32', '', ''], - 'PRIV' : ['PRIV', '', 'priv', 'SregU32', '', ''], - 'VSKIP' : ['VSKIP', '', 'vskip', 'SregU32', '', ''], - 'INST_ATC' : ['INST_ATC', '', 'atc', 'SregU32', '', ''], - 'VCC' : ['VCC', '', 'vcc', 'SregU64', '', ''], - 'PC' : ['PC', '', 'pc', 'SregU64', '', ''], - 'TBA' : ['TBA', '', 'tba', 'SregU64', '', ''], - 'EXEC' : ['EXEC', '', 'exec', 'SregU64', '', ''], - 'PI' : ['PI', '', 'pi', 'SregF32', '', ''], - 'INF' : ['INF', '', 'inf', 'SregF32', '', ''], - 'NAN' : ['NAN', '', 'nan', 'SregF32', '', ''], - 'P0' : ['P0', '', 'p0', 'SregF32', '', ''], - 'P10' : ['P10', '', 'p10', 'SregF32', '', ''], - 'P20' : ['P20', '', 'p20', 'SregF32', '', ''], - 'offset0' : ['', 'instData.OFFSET0', 'offset0', 'SregU16', '', ''], - 'OFFSET0' : ['', 'instData.OFFSET0', 'offset0', 'SregU16', '', ''], - 'offset1' : ['', 'instData.OFFSET1', 'offset1', 'SregU16', '', ''], - 'OFFSET1' : ['', 'instData.OFFSET1', 'offset1', 'SregU16', '', ''], - 'SIMM16' : ['', 'instData.SIMM16', 'simm16', 'SregI16', '', ''], - 'SIMM4' : ['', 'instData.SSRC1', 'simm4', 'SregU16', '', ''], - 'threadID' : ['', '', 't', 'SregU32', '', ''], - 'cmp' : ['', '', 'cmp', 'SregU64', '', ''], - 'src' : ['', '', 'src', 'SregU64', '', ''], - 'tmp' : ['', '', 'tmp', 'SregU64', '', ''], - 'attr_word' : ['ATTR', '', 'attr_word', 'SregU32', '', ''], - 'K' : ['', 'extData.imm_u32', 'k', 'SregU32', '', ''] -} - -CoreMethodMap = { - 'getSRC_NOLDS_U32' : 'getSRC_U32', - 'getSRC_NOLDS_I32' : 'getSRC_I32', - 'getSRC_NOLDS_F16' : 'getSRC_F16', - 'getSRC_NOLDS_U16' : 'getSRC_U16', - 'getSRC_NOLIT_F16' : 'getSRC_F16', - 'getSRC_SIMPLE_F16' : 'getSRC_F16', - 'getSRC_NOLIT_F32' : 'getSRC_F32', - 'getSRC_SIMPLE_F32' : 'getSRC_F32', - 'getSRC_NOLIT_F64' : 'getSRC_F64', - 'getSRC_SIMPLE_F64' : 'getSRC_F64', - 'getSRC_NOLIT_U16' : 'getSRC_U16', - 'getSRC_SIMPLE_U16' : 'getSRC_U16', - 'getSRC_NOLIT_U32' : 'getSRC_U32', - 'getSRC_SIMPLE_U32' : 'getSRC_U32', - 'getSRC_NOLIT_U64' : 'getSRC_U64', - 'getSRC_SIMPLE_U64' : 'getSRC_U64', - 'getSRC_NOLIT_I32' : 'getSRC_I32', - 'getSRC_SIMPLE_I32' : 'getSRC_I32', - 'getSRC_VGPR_F32' : 'getSRC_F32', - 'getSRC_SIMPLE_I64' : 'getSRC_I64' -} - -KnownExceptions = [ - 'Inst_SOP2__S_CBRANCH_G_FORK', - 'Inst_SOPK__S_ADDK_I32', - 'Inst_SOPK__S_CBRANCH_I_FORK', - 'Inst_SOPK__S_GETREG_B32', - 'Inst_SOP1__S_CBRANCH_JOIN', - 'Inst_SOPP__S_CBRANCH_CDBGSYS', - 'Inst_SOPP__S_CBRANCH_CDBGUSER', - 'Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER', - 'Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER', - 'Inst_SOPP__S_SET_GPR_IDX_MODE', - 'Inst_VOP1__V_CVT_OFF_F32_I4', - 'Inst_VOP1__V_FFBH_U32', - 'Inst_VOP1__V_FFBL_B32', - 'Inst_VOP1__V_FFBH_I32', - 'Inst_VOPC__V_CMP_CLASS_F32', - 'Inst_VOPC__V_CMPX_CLASS_F32', - 'Inst_VOPC__V_CMP_CLASS_F64', - 'Inst_VOPC__V_CMPX_CLASS_F64', - 'Inst_VOPC__V_CMP_CLASS_F16', - 'Inst_VOPC__V_CMPX_CLASS_F16', - 'Inst_VINTRP__V_INTERP_MOV_F32', - 'Inst_VOP3__V_CMP_CLASS_F32', - 'Inst_VOP3__V_CMPX_CLASS_F32', - 'Inst_VOP3__V_CMP_CLASS_F64', - 'Inst_VOP3__V_CMPX_CLASS_F64', - 'Inst_VOP3__V_CMP_CLASS_F16', - 'Inst_VOP3__V_CMPX_CLASS_F16', - 'Inst_VOP3__V_CVT_OFF_F32_I4', - 'Inst_VOP3__V_FFBH_U32', - 'Inst_VOP3__V_FFBL_B32', - 'Inst_VOP3__V_FFBH_I32', - 'Inst_VOP3__V_CUBEID_F32', - 'Inst_VOP3__V_CUBESC_F32', - 'Inst_VOP3__V_CUBETC_F32', - 'Inst_VOP3__V_CUBEMA_F32', - 'Inst_VOP3__V_DIV_FIXUP_F32', - 'Inst_VOP3__V_DIV_FIXUP_F64', - 'Inst_VOP3__V_DIV_SCALE_F32', - 'Inst_VOP3__V_DIV_SCALE_F64', - 'Inst_VOP3__V_DIV_FMAS_F32', - 'Inst_VOP3__V_DIV_FMAS_F64', - 'Inst_VOP3__V_MSAD_U8', - 'Inst_VOP3__V_QSAD_PK_U16_U8', - 'Inst_VOP3__V_MQSAD_PK_U16_U8', - 'Inst_VOP3__V_MQSAD_U32_U8', - 'Inst_VOP3__V_PERM_B32', - 'Inst_VOP3__V_DIV_FIXUP_F16', - 'Inst_VOP3__V_CVT_PKACCUM_U8_F32', - 'Inst_VOP3__V_INTERP_MOV_F32', - 'Inst_VOP3__V_INTERP_P1LV_F16', - 'Inst_VOP3__V_MBCNT_LO_U32_B32', - 'Inst_VOP3__V_MBCNT_HI_U32_B32', - 'Inst_VOP3__V_TRIG_PREOP_F64', - 'Inst_VOP3__V_CVT_PKNORM_I16_F32', - 'Inst_VOP3__V_CVT_PKNORM_U16_F32', - 'Inst_VOP3__V_CVT_PKRTZ_F16_F32', - 'Inst_VOP3__V_CVT_PK_U16_U32', - 'Inst_VOP3__V_CVT_PK_I16_I32', - 'Inst_DS__DS_READ_U8', - 'Inst_DS__DS_READ_U16', - 'Inst_DS__DS_SWIZZLE_B32', - 'Inst_DS__DS_GWS_BARRIER', - 'Inst_DS__DS_CONSUME', - 'Inst_DS__DS_APPEND', - 'Inst_DS__DS_ORDERED_COUNT', - 'Inst_MIMG__IMAGE_GATHER4', - 'Inst_MIMG__IMAGE_GATHER4_CL', - 'Inst_MIMG__IMAGE_GATHER4_L', - 'Inst_MIMG__IMAGE_GATHER4_B', - 'Inst_MIMG__IMAGE_GATHER4_B_CL', - 'Inst_MIMG__IMAGE_GATHER4_LZ', - 'Inst_MIMG__IMAGE_GATHER4_C', - 'Inst_MIMG__IMAGE_GATHER4_C_CL', - 'Inst_MIMG__IMAGE_GATHER4_C_L', - 'Inst_MIMG__IMAGE_GATHER4_C_B', - 'Inst_MIMG__IMAGE_GATHER4_C_B_CL', - 'Inst_MIMG__IMAGE_GATHER4_C_LZ' -] - -KnownEmpty = [ - 'Inst_SOPK__S_SETREG_B32', - 'Inst_SOPK__S_SETREG_IMM32_B32', - 'Inst_SOPP__S_WAKEUP', - 'Inst_SOPP__S_BARRIER', - 'Inst_SOPP__S_SETKILL', - 'Inst_SOPP__S_WAITCNT', - 'Inst_SOPP__S_SETHALT', - 'Inst_SOPP__S_SLEEP', - 'Inst_SOPP__S_SETPRIO', - 'Inst_SOPP__S_SENDMSG', - 'Inst_SOPP__S_SENDMSGHALT', - 'Inst_SOPP__S_ICACHE_INV', - 'Inst_SOPP__S_INCPERFLEVEL', - 'Inst_SOPP__S_DECPERFLEVEL', - 'Inst_SOPP__S_TTRACEDATA', - 'Inst_SOPP__S_SET_GPR_IDX_OFF', - 'Inst_SMEM__S_DCACHE_INV', - 'Inst_SMEM__S_DCACHE_WB', - 'Inst_SMEM__S_DCACHE_INV_VOL', - 'Inst_SMEM__S_DCACHE_WB_VOL', - 'Inst_SMEM__S_MEMTIME', - 'Inst_SMEM__S_MEMREALTIME', - 'Inst_SMEM__S_ATC_PROBE', - 'Inst_SMEM__S_ATC_PROBE_BUFFER', - 'Inst_VOP1__V_READFIRSTLANE_B32', - 'Inst_VOP1__V_FREXP_EXP_I32_F64', - 'Inst_VOP1__V_FREXP_MANT_F64', - 'Inst_VOP1__V_FRACT_F64', - 'Inst_VOP1__V_CLREXCP', - 'Inst_VOP1__V_RCP_F16', - 'Inst_VOP1__V_SQRT_F16', - 'Inst_VOP1__V_RSQ_F16', - 'Inst_VOP1__V_LOG_F16', - 'Inst_VOP1__V_EXP_F16', - 'Inst_VOP1__V_FREXP_MANT_F16', - 'Inst_VOP1__V_FREXP_EXP_I16_F16', - 'Inst_VOP3__V_FREXP_EXP_I32_F64', - 'Inst_VOP3__V_FREXP_MANT_F64', - 'Inst_VOP3__V_FRACT_F64', - 'Inst_VOP3__V_CLREXCP', - 'Inst_VOP3__V_RCP_F16', - 'Inst_VOP3__V_SQRT_F16', - 'Inst_VOP3__V_RSQ_F16', - 'Inst_VOP3__V_LOG_F16', - 'Inst_VOP3__V_EXP_F16', - 'Inst_VOP3__V_FREXP_MANT_F16', - 'Inst_VOP3__V_FREXP_EXP_I16_F16', - 'Inst_VOP3__V_READLANE_B32', - 'Inst_VOP3__V_WRITELANE_B32', - 'Inst_DS__DS_WRXCHG2_RTN_B32', - 'Inst_DS__DS_WRXCHG2ST64_RTN_B32', - 'Inst_DS__DS_PERMUTE_B32', - 'Inst_DS__DS_BPERMUTE_B32', - 'Inst_DS__DS_WRXCHG2_RTN_B64', - 'Inst_DS__DS_WRXCHG2ST64_RTN_B64', - 'Inst_DS__DS_CONDXCHG32_RTN_B64', - 'Inst_DS__DS_GWS_SEMA_RELEASE_ALL', - 'Inst_DS__DS_GWS_INIT', - 'Inst_DS__DS_GWS_SEMA_V', - 'Inst_DS__DS_GWS_SEMA_BR', - 'Inst_DS__DS_GWS_SEMA_P', - 'Inst_DS__DS_READ_B96', - 'Inst_DS__DS_READ_B128', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_X', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_XY', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_X', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_XY', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ', - 'Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ', - 'Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW', - 'Inst_MUBUF__BUFFER_LOAD_UBYTE', - 'Inst_MUBUF__BUFFER_LOAD_SBYTE', - 'Inst_MUBUF__BUFFER_LOAD_USHORT', - 'Inst_MUBUF__BUFFER_LOAD_SSHORT', - 'Inst_MUBUF__BUFFER_STORE_BYTE', - 'Inst_MUBUF__BUFFER_STORE_SHORT', - 'Inst_MUBUF__BUFFER_STORE_LDS_DWORD', - 'Inst_MUBUF__BUFFER_WBINVL1', - 'Inst_MUBUF__BUFFER_WBINVL1_VOL', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_X', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_X', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_XY', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ', - 'Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ', - 'Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW', - 'Inst_MIMG__IMAGE_LOAD', - 'Inst_MIMG__IMAGE_LOAD_MIP', - 'Inst_MIMG__IMAGE_LOAD_PCK', - 'Inst_MIMG__IMAGE_LOAD_PCK_SGN', - 'Inst_MIMG__IMAGE_LOAD_MIP_PCK', - 'Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN', - 'Inst_MIMG__IMAGE_STORE', - 'Inst_MIMG__IMAGE_STORE_MIP', - 'Inst_MIMG__IMAGE_STORE_PCK', - 'Inst_MIMG__IMAGE_STORE_MIP_PCK', - 'Inst_MIMG__IMAGE_GET_RESINFO', - 'Inst_MIMG__IMAGE_SAMPLE', - 'Inst_MIMG__IMAGE_SAMPLE_CL', - 'Inst_MIMG__IMAGE_SAMPLE_D', - 'Inst_MIMG__IMAGE_SAMPLE_D_CL', - 'Inst_MIMG__IMAGE_SAMPLE_L', - 'Inst_MIMG__IMAGE_SAMPLE_B', - 'Inst_MIMG__IMAGE_SAMPLE_B_CL', - 'Inst_MIMG__IMAGE_SAMPLE_LZ', - 'Inst_MIMG__IMAGE_SAMPLE_C', - 'Inst_MIMG__IMAGE_SAMPLE_C_CL', - 'Inst_MIMG__IMAGE_SAMPLE_C_D', - 'Inst_MIMG__IMAGE_SAMPLE_C_D_CL', - 'Inst_MIMG__IMAGE_SAMPLE_C_L', - 'Inst_MIMG__IMAGE_SAMPLE_C_B', - 'Inst_MIMG__IMAGE_SAMPLE_C_B_CL', - 'Inst_MIMG__IMAGE_SAMPLE_C_LZ', - 'Inst_MIMG__IMAGE_SAMPLE_O', - 'Inst_MIMG__IMAGE_SAMPLE_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_D_O', - 'Inst_MIMG__IMAGE_SAMPLE_D_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_L_O', - 'Inst_MIMG__IMAGE_SAMPLE_B_O', - 'Inst_MIMG__IMAGE_SAMPLE_B_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_LZ_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_D_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_L_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_B_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_LZ_O', - 'Inst_MIMG__IMAGE_GATHER4_O', - 'Inst_MIMG__IMAGE_GATHER4_CL_O', - 'Inst_MIMG__IMAGE_GATHER4_L_O', - 'Inst_MIMG__IMAGE_GATHER4_B_O', - 'Inst_MIMG__IMAGE_GATHER4_B_CL_O', - 'Inst_MIMG__IMAGE_GATHER4_LZ_O', - 'Inst_MIMG__IMAGE_GATHER4_C_O', - 'Inst_MIMG__IMAGE_GATHER4_C_CL_O', - 'Inst_MIMG__IMAGE_GATHER4_C_L_O', - 'Inst_MIMG__IMAGE_GATHER4_C_B_O', - 'Inst_MIMG__IMAGE_GATHER4_C_B_CL_O', - 'Inst_MIMG__IMAGE_GATHER4_C_LZ_O', - 'Inst_MIMG__IMAGE_GET_LOD', - 'Inst_MIMG__IMAGE_SAMPLE_CD', - 'Inst_MIMG__IMAGE_SAMPLE_CD_CL', - 'Inst_MIMG__IMAGE_SAMPLE_C_CD', - 'Inst_MIMG__IMAGE_SAMPLE_C_CD_CL', - 'Inst_MIMG__IMAGE_SAMPLE_CD_O', - 'Inst_MIMG__IMAGE_SAMPLE_CD_CL_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_CD_O', - 'Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O', - 'Inst_EXP__EXP', - 'Inst_FLAT__FLAT_LOAD_UBYTE', - 'Inst_FLAT__FLAT_LOAD_SBYTE', - 'Inst_FLAT__FLAT_LOAD_USHORT', - 'Inst_FLAT__FLAT_LOAD_SSHORT', - 'Inst_FLAT__FLAT_STORE_BYTE', - 'Inst_FLAT__FLAT_STORE_SHORT', -] diff --git a/src/arch/amdgpu/gcn3/description_objects.py b/src/arch/amdgpu/gcn3/description_objects.py deleted file mode 100644 index f174203a5e..0000000000 --- a/src/arch/amdgpu/gcn3/description_objects.py +++ /dev/null @@ -1,367 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -class Clause(object): - def __init__(self): - self.keyword = '' - -class CommentClause(Clause): - def __init__(self): - self.keyword = 'comment' - self.content = [] - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' content: %s ]' % repr(self.content) - return text - -class AssignmentClause(Clause): - def __init__(self): - self.keyword = 'assignment' - self.dst = None - self.op = None - self.src = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' dst: %s,' % repr(self.dst) - text += ' op: %s,' % repr(self.op) - text += ' src: %s ]' % repr(self.src) - return text - -class BinaryClause(Clause): - def __init__(self): - self.keyword = 'binary' - self.left = None - self.op = None - self.right = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' left: %s,' % repr(self.left) - text += ' op: %s,' % repr(self.op) - text += ' right: %s ]' % repr(self.right) - return text - -class UnaryClause(Clause): - def __init__(self): - self.keyword = 'unary' - self.op = None - self.oprnd = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' op: %s,' % repr(self.op) - text += ' oprnd: %s ]' % repr(self.oprnd) - return text - -class ConditionalClause(Clause): - def __init__(self): - self.keyword = 'conditional' - self.cond = None - self.true = None - self.false = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' cond: %s,' % repr(self.cond) - text += ' true: %s,' % repr(self.true) - text += ' false: %s ]' % repr(self.false) - return text - -class VariableClause(Clause): - def __init__(self): - self.keyword = 'variable' - self.name = '' - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' name: %s ]' % repr(self.name) - return text - -class ConstantClause(Clause): - def __init__(self): - self.keyword = 'constant' - self.value = 0 - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - if type(self.value) is 'float': - text += ' value: %f ]' % (self.value) - else: - text += ' value: 0x%x ]' % (self.value) - - return text - -class DataRegClause(Clause): - def __init__(self): - self.keyword = 'data_reg' - self.reg = None - self.idx = None - self.typ = [ 'default', -1 ] - self.rng = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' reg: %s,' % repr(self.reg) - if self.typ: - text += ' typ: %s,' % repr(self.typ) - else: - text += ' typ: None,' - if self.idx: - text += ' idx: %s,' % repr(self.idx) - else: - text += ' idx: None,' - if self.rng: - text += ' rng: %s ]' % repr(self.rng) - else: - text += ' rng: None ]' - return text - -class FunctionClause(Clause): - def __init__(self): - self.keyword = 'function' - self.func = '' - self.args = [] - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' func: %s,' % repr(self.func) - text += ' args: %s ]' % repr(self.args) - return text - -class IfThenElseClause(Clause): - def __init__(self): - self.keyword = 'ifthenelse' - self.cond = None - self.then_stmt = None - self.else_stmt = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - if self.cond: - text += ' cond: %s,' % repr(self.cond) - else: - text += ' cond: None,' - if self.then_stmt: - text += ' then: %s,' % repr(self.then_stmt) - else: - text += ' then: None,' - if self.else_stmt: - text += ' else: %s ]' % repr(self.else_stmt) - else: - text += ' else: None ]' - return text - -class IfClause(Clause): - def __init__(self): - self.keyword = 'if' - self.cond = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - if self.cond: - text += ' cond: %s ]' % repr(self.cond) - else: - text += ' cond: None ]' - return text - -class ForClause(Clause): - def __init__(self): - self.keyword = 'for' - self.variable = None - self.start = None - self.end = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' variable: %s,' % repr(self.variable) - text += ' start: %s,' % repr(self.start) - text += ' end: %s ]' % repr(self.end) - return text - -class ElseClause(Clause): - def __init__(self): - self.keyword = 'else' - - def __repr__(self): - text = '[ kw: %s ]' % self.keyword - return text - -class EndClause(Clause): - def __init__(self): - self.keyword = 'end' - - def __repr__(self): - text = '[ kw: %s ]' % self.keyword - return text - -class ElseIfClause(Clause): - def __init__(self): - self.keyword = 'elseif' - self.cond = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - if self.cond: - text += ' cond: %s ]' % repr(self.cond) - else: - text += ' cond: None ]' - return text - -class TabClause(Clause): - def __init__(self): - self.keyword = 'tab' - self.stmt = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - if self.stmt: - text += ' stmt: %s ]' % repr(self.stmt) - else: - text += ' stmt: None ]' - return text - -class GroupClause(Clause): - def __init__(self): - self.keyword = 'group' - self.group = [] - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' group: %s ]' % repr(self.group) - return text - -class CastClause(Clause): - def __init__(self): - self.keyword = 'cast' - self.typ = '' - self.var = '' - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' typ: %s,' % repr(self.typ) - text += ' var: %s ]' % repr(self.var) - return text - -class CommaClause(Clause): - def __init__(self): - self.keyword = 'comma' - self.left = None - self.right = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' left: %s,' % repr(self.left) - text += ' right: %s ]' % repr(self.right) - return text - -class ChainClause(Clause): - def __init__(self): - self.keyword = 'chain' - self.left = None - self.right = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' left: %s,' % repr(self.left) - text += ' right: %s ]' % repr(self.right) - return text - -class MemClause(Clause): - def __init__(self): - self.keyword = 'mem' - self.mem = None - self.addr = None - self.rng = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' mem: %s,' % repr(self.mem) - text += ' addr: %s,' % repr(self.addr) - if self.rng: - text += ' rng: %s ]' % repr(self.rng) - else: - text += ' rng: None ]' - return text - -class GprClause(Clause): - def __init__(self): - self.keyword = 'gpr' - self.gpr = None - self.idx = None - self.typ = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' gpr: %s,' % repr(self.gpr) - text += ' idx: %s,' % repr(self.idx) - text += ' typ: %s ]' % repr(self.typ) - return text - -class ParenClause(Clause): - def __init__(self): - self.keyword = 'paren' - self.parexp = None - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' parexp: %s ]' % repr(self.parexp) - return text - -class SizeClause(Clause): - def __init__(self): - self.keyword = 'size' - self.size = 0 - - def __repr__(self): - text = '[ kw: %s,' % self.keyword - text += ' size: %d ]' % self.size - return text - -TypeToDetails = { - 'f16' : ( 'SregF16', 16 ), - 'i16' : ( 'SregU16', 16 ), - 'u16' : ( 'SregU16', 16 ), - 'f' : ( 'SregF32', 32 ), - 'f32' : ( 'SregF32', 32 ), - 'i' : ( 'SregI32', 32 ), - 'i32' : ( 'SregI32', 32 ), - 'u' : ( 'SregU32', 32 ), - 'u32' : ( 'SregU32', 32 ), - 'd' : ( 'SregF64', 64 ), - 'i64' : ( 'SregI64', 64 ), - 'u64' : ( 'SregU64', 64 ), - 'u96' : ( 'SregU96', 96 ), - 'u128' : ( 'SregU128', 128 ), - 'u256' : ( 'SregU256', 256 ), - 'u512' : ( 'SregU512', 512 ) -} diff --git a/src/arch/amdgpu/gcn3/description_parser.py b/src/arch/amdgpu/gcn3/description_parser.py deleted file mode 100644 index 8ac6a46f93..0000000000 --- a/src/arch/amdgpu/gcn3/description_parser.py +++ /dev/null @@ -1,1327 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import sys - -from description_objects import * -from m5.util.grammar import Grammar -from pprint import pprint, pformat - -class ParseError(Exception): - pass - -class DescriptionParser(Grammar): - def __init__(self): - super(DescriptionParser, self).__init__() - self.in_text = False - self.single_subs = [ - [ '1 if S0 is chosen as the minimum value.', - '(S0 < S1) ? 1 : 0;' ], - [ '1 if S0 is chosen as the maximum value.', - '(S0 > S1) ? 1 : 0;' ], - [ '1 if result is non-zero.', - '(D != 0) ? 1 : 0;' ], - [ '(SCC) then D.u = S0.u;', - 'if(SCC) then D.u = S0.u;' ], - [ 'SCC = 1 if the new value of EXEC is non-zero.', - 'SCC = (EXEC != 0) ? 1 : 0;' ], - [ 'D.u = (VCC[i] ? S1.u : S0.u) (i = threadID in wave); ' - 'VOP3: specify VCC as a scalar GPR in S2.', - 'D.u = (VCC[threadID] ? S1.u : S0.u);' ], - [ 'D.u = QuadMask(S0.u):', - 'D.u = QuadMask(S0.u);' ], - [ 'D.u64 = QuadMask(S0.u64):', - 'D.u64 = QuadMask(S0.u64);' ], - [ 'A = ADDR_BASE;', - '' ], - [ 'B = A + 4*(offset1[7] ? {A[31],A[31:17]} : ' - '{offset1[6],offset1[6:0],offset0});', - '' ], - [ 'MEM_ADDR', - 'MEM' ], - [ 'Untyped buffer load dword.', - 'DATA.u32 = MEM[ADDR];' ], - [ 'Untyped buffer load 2 dwords.', - 'DATA.u64 = MEM[ADDR];' ], - [ 'Untyped buffer load 3 dwords.', - 'DATA.u96 = MEM[ADDR];' ], - [ 'Untyped buffer load 4 dwords.', - 'DATA.u128 = MEM[ADDR];' ], - [ 'Untyped buffer store dword.', - 'MEM[ADDR] = DATA.u32;' ], - [ 'Untyped buffer store 2 dwords.', - 'MEM[ADDR] = DATA.u64;' ], - [ 'Untyped buffer store 3 dwords.', - 'MEM[ADDR] = DATA.u96;' ], - [ 'Untyped buffer store 4 dwords.', - 'MEM[ADDR] = DATA.u128;' ], - [ 'Read 1 dword from scalar data cache.', - 'DATA.u32 = MEM[ADDR];' ], - [ 'Read 2 dwords from scalar data cache.', - 'DATA.u64 = MEM[ADDR];' ], - [ 'Read 4 dwords from scalar data cache.', - 'DATA.u128 = MEM[ADDR];' ], - [ 'Read 8 dwords from scalar data cache.', - 'DATA.u256 = MEM[ADDR];' ], - [ 'Read 16 dwords from scalar data cache.', - 'DATA.u512 = MEM[ADDR];' ], - [ 'Write 1 dword to scalar data cache.', - 'MEM[ADDR] = DATA.u32;' ], - [ 'Write 2 dwords to scalar data cache.', - 'MEM[ADDR] = DATA.u64;' ], - [ 'Write 4 dwords to scalar data cache.', - 'MEM[ADDR] = DATA.u128;' ], - [ 'D[0] = OR(S0[3:0]),', - '# D[0] = OR(S0[3:0]),' ], - [ '(unsigned 16-bit integer domain)', - 'in the unsigned 16-bit integer domain' ], - [ ' (unsigned compare);', - '; # (unsigned compare)' ], - [ '2s_complement', - 'TwosComplement' ], - [ 'floor(S0.f16) is even', - 'floor_is_even(S0.f16)' ], - [ 'D.u[31:0] = S0.u[0:31],', - 'D.u[31:0] = S0.u[0:31];' ], - [ 'D.d = trunc(S0.d), return', - 'D.d = trunc(S0.d); return' ], - [ 'D.f = trunc(S0.f), return', - 'D.f = trunc(S0.f); return' ], - [ 'D[i] = (S0[(i & ~3):(i | 3)] != 0)', - 'D = whole_quad_mode(S0)' ], - [ 'M0[15:12] = SIMM4.', - 'M0[15:12] = SIMM16.' ], - [ 'D = VCC in VOPC encoding.', - '# D = VCC in VOPC encoding.' ], - [ 'S0.u64 is a', - '# S0.u64 is a' ], - [ 'D.f = S0.f * K + S1.f; K is a', - 'D.f = S0.f * K + S2.f; # K is a' ], - [ 'D.f16 = S0.f16 * K.f16 + S1.f16; K is a', - 'D.f16 = S0.f16 * K.f16 + S2.f16; # K is a' ], - [ 'K is a', - '# K is a' ], - [ '(2 ** S1.i16)', - 'pow(2.0, S1.i16)' ], - [ 'original', - '# original' ], - [ 'attr_word selects', - '# attr_word selects' ], - [ '; S0 is ', - '; # S0 is ' ], - [ '. S0 is ', - '. # S0 is ' ], - [ 'SIMM16 = ', - '# SIMM16 = ' ], - [ 'SIMM16[3:0] = ', - '# SIMM16[3:0] = ' ], - [ 'SIMM16[6:4] = ', - '# SIMM16[6:4] = ' ], - [ 'SIMM16[12:8] = ', - '# SIMM16[12:8] = ' ], - [ 'SIMM16[9:0] contains', - '# SIMM16[9:0] contains' ], - [ 'Exponent', - 'exponent' ], - [ 'Mantissa', - 'mantissa' ], - [ 'Corrupted', - 'corrupted' ], - [ 'threadId', - 'threadID' ], - [ '16\'h0', - 'zeros(16)' ], - [ '24\'h0', - 'zeros(24)' ], - [ 'DATA.', - 'DATA;' ], - [ 'DATA2.', - 'DATA2;' ], - [ 'tmp.', - 'tmp;' ], - [ 'vcc_out', - 'VCC[threadID]' ], - [ '].\n', - '];\n' ], - [ '\\t tD', - '\\t D' ] - ] - self.repeat_subs = [ - ['MEM[A]', 'MEM[ADDR]'], - ['MEM[B]', 'MEM[ADDR, offset1, offset0]'], - ['DATA[0]', 'DATA_0'], - ['DATA[1]', 'DATA_1'], - ['DATA[0:1]', 'DATA_0'], - ['DATA[2:3]', 'DATA_2'], - ['0x800000000ULL', '0x100000000ULL'], - ['<>', '!='] - ] - - # lexer - states = ( - ('comment', 'exclusive'), - ('notes', 'exclusive'), - ) - - reserved = ( - 'A', - 'ABS', - 'ADDR', - 'ADDR_BASE', - 'ATTR_WORD', - 'APPROXIMATE2TOX', - 'APPROXIMATELOG2', - 'APPROXIMATERECIP', - 'APPROXIMATERECIPSQRT', - 'APPROXIMATESQRT', - 'B', - 'CMP', - 'COUNTONEBITS', - 'COUNTZEROBITS', - 'CORRUPTED', - 'COS', - 'D', - 'DATA', - 'DATA2', - 'DATA_0', - 'DATA_1', - 'DATA_2', - 'DOUBLE', - 'ELSE', - 'ELSIF', - 'END', - 'EXEC', - 'EXPONENT', - 'F', - 'F16', - 'F32', - 'FINDFIRSTONE', - 'FINDFIRSTZERO', - 'FIRSTOPPOSITESIGNBIT', - 'FLOAT', - 'FLOOR', - 'FLOOR_IS_EVEN', - 'FLT16_TO_FLT32', - 'FLT16_TO_INT16', - 'FLT16_TO_UINT16', - 'FLT32_TO_FLT16', - 'FLT32_TO_FLT64', - 'FLT32_TO_INT32', - 'FLT32_TO_UINT32', - 'FLT32_TO_UINT8', - 'FLT64_TO_INT32', - 'FLT64_TO_FLT32', - 'FLT64_TO_UINT32', - 'FRACT', - 'I', - 'I16', - 'I32', - 'INF', - 'INT', - 'INT16_TO_FLT16', - 'INT32_FLOOR', - 'INT32_TO_FLT32', - 'INT32_TO_FLT64', - 'I64', - 'IF', - 'INST_ATC', - 'ISNAN', - 'K', - 'LOG2', - 'MANTISSA', - 'MAX', - 'MEDIAN', - 'MEM', - 'MIN', - 'M0', - 'NAN', - 'NOP', - 'OFFSET0', - 'OFFSET1', - 'OPCODE_SIZE_IN_BITS', - 'PC', - 'PI', - 'POW', - 'POWER2', - 'PRIV', - 'P0', - 'P10', - 'P20', - 'QUADMASK', - 'RETURN_DATA', - 'RETURN_DATA_0', - 'RETURN_DATA_1', - 'ROUND_NEAREST_EVEN', - 'QUOTE', - 'S', - 'S0', - 'S1', - 'S2', - 'SAD_U8', - 'SCC', - 'SGPR', - 'SIGNEXT', - 'SIN', - 'SIMM16', - 'SIMM4', - 'SNORM', - 'SQRT', - 'SRC', - 'TBA', - 'THEN', - 'THREADID', - 'TMP', - 'TRUNC', - 'TWOSCOMPLEMENT', - 'U', - 'U16', - 'U32', - 'U64', - 'U96', - 'U128', - 'U256', - 'U512', - 'UINT16_TO_FLT16', - 'UINT32_TO_FLT32', - 'UINT32_TO_FLT64', - 'UINT8_TO_FLT32', - 'UNORM', - 'UNSIGNED', - 'VCC', - 'VGPR', - 'VSKIP', - 'WHOLE_QUAD_MODE', - 'ZEROS' - ) - - tokens = reserved + ( - 'ADD', - 'ADDEQ', - 'ADDADD', - 'AND', - 'ANDAND', - 'ANDEQ', - 'COLON', - 'COMMA', - 'COMMENT', - 'DIVEQ', - 'DIV', - 'DO', - 'DOT', - 'DOTDOTDOT', - 'EQ', - 'EQUALS', - 'FOR', - 'GE', - 'GT', - 'IN', - 'INV', - 'LBRACE', - 'LBRACKET', - 'LE', - 'LG', - 'LPAREN', - 'LSH', - 'LSHEQ', - 'LT', - 'MODEQ', - 'MOD', - 'MUL', - 'MULEQ', - 'MULMUL', - 'NE', - 'NEWLINE', - 'NOT', - 'NUMBER', - 'OR', - 'OREQ', - 'OROR', - 'RBRACE', - 'RBRACKET', - 'RPAREN', - 'RSH', - 'RSHEQ', - 'QUESTION', - 'SEMI', - 'SUB', - 'SUBEQ', - 'SUBSUB', - 'TAB', - 'XOR', - 'XOREQ', - 'ID', - ) - - t_ADD = r'\+' - t_ADDADD = r'\+\+' - t_ADDEQ = r'\+=' - t_AND = r'&' - t_ANDAND = r'&&' - t_ANDEQ = r'&=' - t_COLON = r':' - t_COMMA = r',' - t_DIV = r'/' - t_DIVEQ = r'/=' - t_DOT = r'\.' - t_DOTDOTDOT = r'\.\.\.' - t_EQ = r'==' - t_EQUALS = r'=' - t_GE = r'>=' - t_GT = r'>' - t_INV = r'~' - t_LBRACE = r'\{' - t_LBRACKET = r'\[' - t_LE = r'<=' - t_LPAREN = r'\(' - t_LSH = r'<<' - t_LSHEQ = r'<<=' - t_LT = r'<' - t_LG = r'<>' - t_MOD = r'%' - t_MODEQ = r'%=' - t_MUL = r'\*' - t_MULMUL = r'\*\*' - t_NE = r'!=' - t_NOT = r'!' - t_OR = r'\|' - t_OREQ = r'\|=' - t_OROR = r'\|\|' - t_RBRACE = r'\}' - t_RBRACKET = r'\]' - t_RPAREN = r'\)' - t_RSH = r'>>' - t_RSHEQ = r'>>=' - t_QUESTION = r'\?' - t_QUOTE = r'\'' - t_SEMI = r';' - t_SUB = r'-' - t_SUBEQ = r'-=' - t_SUBSUB = r'--' - t_TAB = r'\\t' - t_XOR = r'\^' - t_XOREQ = r'\^=' - - reserved_map = { } - for r in reserved: - reserved_map[r.lower()] = r - - def t_HASH(self, t): - r'\#' - t.lexer.begin('comment') - text = '' - while True: - tok = t.lexer.token() - if not tok: - break; - text += tok.value - if tok.type == 'NEWLINE': - break; - t.lexer.begin('INITIAL') - t.type = 'COMMENT' - t.value = text - return t - - def t_DIVDIV(self, t): - r'//' - t.lexer.begin('comment') - text = '' - while True: - tok = t.lexer.token() - if not tok: - break; - text += tok.value - if tok.type == 'NEWLINE': - break; - t.lexer.begin('INITIAL') - t.type = 'COMMENT' - t.value = text - return t - - def t_CODE(self, t): - r'@code' - t.lexer.begin('INITIAL') - pass - - def t_TEXT(self, t): - r'@text' - t.lexer.begin('comment') - text = '' - while True: - tok = t.lexer.token() - if not tok: - break; - text += tok.value - t.lexer.begin('INITIAL') - t.type = 'COMMENT' - t.value = text - return t - - def t_ID(self, t): - r'[a-zA-Z_][a-zA-Z0-9_]*' - if t.value[0].isupper() and t.value[1:].islower(): - t.lexer.begin('comment') - else: - t.type = self.reserved_map.get(t.value.lower(), 'ID') - if t.type == 'ID': - t.lexer.begin('notes') - return t - - # comment state lexer tokens - # --- consume everything up to the next NEWLINE - def t_comment_COMMENT(self, t): - r'[^\n]+' - return t - - def t_comment_NEWLINE(self, t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - t.lexer.begin('INITIAL') - return t - - t_comment_ignore = ' \t\x0c' - - def t_comment_error(self, t): - sys.exit('%d: illegal character "%s"' % (t.lexer.lineno, t.value[0])) - - # notes state lexer tokens - # -- consume everything but '(' and ')' up to the next NEWLINE - def t_notes_COMMENT(self, t): - r'[^\(\)\n]+' - return t - - def t_notes_LPAREN(self, t): - r'\(' - t.lexer.begin('INITIAL') - return t - - def t_notes_RPAREN(self, t): - r'\)' - t.lexer.begin('INITIAL') - return t - - def t_notes_NEWLINE(self, t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - t.lexer.begin('INITIAL') - return t - - t_notes_ignore = ' \t\x0c' - - def t_notes_error(self, t): - sys.exit('%d: illegal character "%s"' % (t.lexer.lineno, t.value[0])) - - def t_NEWLINE(self, t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - return t - - def t_HEXADECIMAL(self, t): - r'0[xX][0-9a-fA-F]+(ULL)?' - t.value = int(t.value.replace('ULL', ''), 16) - t.type = 'NUMBER' - return t - - def t_FLOAT(self, t): - r'[0-9][0-9]*\.[0-9][0-9]*(f)?' - t.value = float(t.value.replace('f', '')) - t.type = 'NUMBER' - return t - - def t_DECIMAL(self, t): - r'[0-9][0-9]*(ULL)?' - t.value = int(t.value.replace('ULL', ''), 10) - t.type = 'NUMBER' - return t - - t_ignore = ' \t\x0c' - - def t_error(self, t): - sys.exit('%d: illegal character "%s"' % (t.lexer.lineno, t.value[0])) - - - ## parser - start = 'specification' - - precedence = ( - ('left', 'OROR', 'ANDAND'), - ('left', 'OR', 'XOR', 'AND'), - ('left', 'EQ', 'NE'), - ('left', 'GE', 'GT', 'LE', 'LG', 'LT'), - ('left', 'LSH', 'RSH'), - ('left', 'ADD', 'SUB'), - ('left', 'DIV', 'MUL'), - ('left', 'MOD', 'MULMUL') - ) - - # empty rule - def p_empty_0(self, t): - ''' - empty : - ''' - pass - - # comment rule - def p_comment_0(self, t): - ''' - comment : COMMENT - | ID - | QUOTE - ''' - clause = CommentClause() - clause.content = [t[1]] - t[0] = clause - - def p_comment_1(self, t): - ''' - comment : LPAREN comment RPAREN - ''' - clause = CommentClause() - clause.content = [t[1], t[2], t[3]] - t[0] = clause - - def p_comment_2(self, t): - ''' - comment : LPAREN comment RPAREN COMMA - ''' - clause = CommentClause() - clause.content = [t[1], t[2], t[3], t[4]] - t[0] = clause - - def p_comment_3(self, t): - ''' - comment : comment COMMENT - ''' - t[1].content.append(t[2]) - t[0] = t[1] - - # data_reg rules - def p_data_reg_0(self, t): - ''' - data_reg : D - | S - | S0 - | S1 - | S2 - ''' - t[0] = t[1] - - # spec_reg rules - def p_spec_reg_0(self, t): - ''' - spec_reg : A - | ADDR - | ADDR_BASE - | ATTR_WORD - | B - | CMP - | DATA - | DATA2 - | DATA_0 - | DATA_1 - | DATA_2 - | EXEC - | I - | INF - | INST_ATC - | K - | M0 - | NAN - | OFFSET0 - | OFFSET1 - | OPCODE_SIZE_IN_BITS - | P0 - | P10 - | P20 - | PC - | PI - | PRIV - | RETURN_DATA - | RETURN_DATA_0 - | RETURN_DATA_1 - | SCC - | SIMM16 - | SIMM4 - | SRC - | TBA - | THREADID - | TMP - | VCC - | VSKIP - ''' - t[0] = t[1] - - # function rules - def p_function_0(self, t): - ''' - function : ABS - | APPROXIMATE2TOX - | APPROXIMATELOG2 - | APPROXIMATERECIP - | APPROXIMATERECIPSQRT - | APPROXIMATESQRT - | COUNTONEBITS - | COUNTZEROBITS - | CORRUPTED - | COS - | EXPONENT - | FINDFIRSTONE - | FINDFIRSTZERO - | FIRSTOPPOSITESIGNBIT - | FLOOR - | FLOOR_IS_EVEN - | FLT16_TO_FLT32 - | FLT16_TO_INT16 - | FLT16_TO_UINT16 - | FLT32_TO_FLT16 - | FLT32_TO_FLT64 - | FLT32_TO_INT32 - | FLT32_TO_UINT32 - | FLT32_TO_UINT8 - | FLT64_TO_FLT32 - | FLT64_TO_INT32 - | FLT64_TO_UINT32 - | FRACT - | INT16_TO_FLT16 - | INT32_FLOOR - | INT32_TO_FLT32 - | INT32_TO_FLT64 - | ISNAN - | LOG2 - | MANTISSA - | MAX - | MEDIAN - | MIN - | POWER2 - | QUADMASK - | POW - | ROUND_NEAREST_EVEN - | SAD_U8 - | SIGNEXT - | SIN - | SQRT - | TRUNC - | TWOSCOMPLEMENT - | UINT16_TO_FLT16 - | UINT32_TO_FLT32 - | UINT32_TO_FLT64 - | UINT8_TO_FLT32 - | WHOLE_QUAD_MODE - | ZEROS - ''' - t[0] = t[1] - - # data_type rules - def p_data_type_0(self, t): - ''' - data_type : empty - ''' - t[0] = ['empty', -1] - - def p_data_type_1(self, t): - ''' - data_type : DOT I16 - | DOT F16 - | DOT U16 - ''' - t[0] = [t[2], 16] - - def p_data_type_2(self, t): - ''' - data_type : DOT I - | DOT F - | DOT U - | DOT I32 - | DOT F32 - | DOT U32 - ''' - t[0] = [t[2], 32] - - def p_data_type_3(self, t): - ''' - data_type : DOT D - | DOT I64 - | DOT U64 - ''' - t[0] = [t[2], 64] - - def p_data_type_4(self, t): - ''' - data_type : DOT U96 - ''' - t[0] = [t[2], 96] - - def p_data_type_5(self, t): - ''' - data_type : DOT U128 - ''' - t[0] = [t[2], 128] - - def p_data_type_6(self, t): - ''' - data_type : DOT U256 - ''' - t[0] = [t[2], 256] - - def p_data_type_7(self, t): - ''' - data_type : DOT U512 - ''' - t[0] = [t[2], 512] - - # data_range rules - def p_data_range_0(self, t): - ''' - data_range : empty - ''' - t[0] = None - - def p_data_range_1(self, t): - ''' - data_range : LBRACKET expression RBRACKET - ''' - t[0] = t[2] - - def p_data_range_2(self, t): - ''' - data_range : LBRACKET expression COLON expression RBRACKET - ''' - t[0] = [t[2], t[4]] - - # reg_desc rules - def p_reg_desc_0(self, t): - ''' - reg_desc : data_reg data_type data_range - ''' - clause = DataRegClause() - clause.reg = t[1] - clause.typ = t[2] - clause.rng = t[3] - t[0] = clause - - def p_reg_desc_1(self, t): - ''' - reg_desc : spec_reg data_range data_type data_range - ''' - clause = DataRegClause() - clause.reg = t[1] - clause.typ = t[3] - if t[1] == 'SGPR' or t[1] == 'VGPR' or t[1] == 'MEM': - clause.idx = t[2] - clause.rng = t[4] - elif t[4]: - clause.idx = t[2] - clause.rng = t[4] - else: - clause.idx = None - clause.rng = t[2] - t[0] = clause - - def p_reg_desc_2(self, t): - ''' - reg_desc : LBRACE reg_desc COMMA reg_desc RBRACE - ''' - clause = GroupClause() - clause.group = [t[2], t[4]] - t[0] = clause - - def p_reg_desc_3(self, t): - ''' - reg_desc : LBRACE reg_desc COMMA reg_desc COMMA reg_desc RBRACE - ''' - clause = GroupClause() - clause.group = [t[2], t[4], t[6]] - t[0] = clause - - def p_reg_desc_4(self, t): - ''' - reg_desc : LBRACE reg_desc COMMA reg_desc COMMA reg_desc \ - COMMA reg_desc RBRACE - ''' - clause = GroupClause() - clause.group = [t[2], t[4], t[6], t[8]] - t[0] = clause - - def p_mem_desc_0(self, t): - ''' - mem_desc : MEM LBRACKET clist RBRACKET data_range - ''' - clause = MemClause() - clause.mem = t[1] - clause.addr = t[3] - clause.rng = t[5] - t[0] = clause - - def p_mem_desc_1(self, t): - ''' - mem_desc : LBRACE mem_desc COMMA mem_desc RBRACE - ''' - clause = GroupClause() - clause.group = [t[2], t[4]] - t[0] = clause - - def p_mem_desc_2(self, t): - ''' - mem_desc : LBRACE mem_desc COMMA mem_desc COMMA mem_desc RBRACE - ''' - clause = GroupClause() - clause.group = [t[2], t[4], t[6]] - t[0] = clause - - def p_mem_desc_3(self, t): - ''' - mem_desc : LBRACE mem_desc COMMA mem_desc COMMA mem_desc \ - COMMA mem_desc RBRACE - ''' - clause = GroupClause() - clause.group = [t[2], t[4], t[6], t[8]] - t[0] = clause - - def p_gpr_desc_0(self, t): - ''' - gpr_desc : SGPR LBRACKET expression RBRACKET data_type - | VGPR LBRACKET expression RBRACKET data_type - ''' - clause = GprClause() - clause.gpr = t[1] - clause.idx = t[3] - clause.typ = t[5] - t[0] = clause - - # clist rules - def p_clist_0(self, t): - ''' - clist : empty - ''' - pass - - def p_clist_1(self, t): - ''' - clist : expression - ''' - t[0] = t[1] - - def p_clist_2(self, t): - ''' - clist : clist COMMA expression - ''' - clause = CommaClause() - clause.left = t[1] - clause.right = t[3] - t[0] = clause - - # operand rules - def p_operand_0(self, t): - ''' - operand : NUMBER - ''' - clause = ConstantClause() - clause.value = t[1] - t[0] = clause - - def p_operand_1(self, t): - ''' - operand : reg_desc - | mem_desc - | gpr_desc - ''' - t[0] = t[1] - - def p_operand_2(self, t): - ''' - operand : function LPAREN clist RPAREN - ''' - clause = FunctionClause() - clause.func = t[1] - clause.args = t[3] - t[0] = clause - - - # unary rules - def p_unary_0(self, t): - ''' - unary : operand - ''' - t[0] = t[1] - - def p_unary_1(self, t): - ''' - unary : ADD expression - | INV expression - | NOT expression - | SUB expression - | ADDADD expression - | SUBSUB expression - ''' - clause = UnaryClause() - clause.op = t[1] - clause.oprnd = t[2] - t[0] = clause - - def p_unary_2(self, t): - ''' - unary : LPAREN expression RPAREN - ''' - clause = ParenClause() - clause.parexp = t[2] - t[0] = clause - - def p_unary_3(self, t): - ''' - unary : NOP - ''' - clause = FunctionClause() - clause.func = t[1] - clause.arg = None - t[0] = clause - - def p_type_name_0(self, t): - ''' - type_name : DOUBLE - | FLOAT - | INT - | UNSIGNED - | SNORM - | UNORM - ''' - t[0] = t[1] - - def p_cast_0(self, t): - ''' - cast : unary - ''' - t[0] = t[1] - - def p_cast_1(self, t): - ''' - cast : LPAREN type_name RPAREN cast - ''' - clause = CastClause() - clause.typ = t[2] - clause.var = t[4] - t[0] = clause - - def p_binary_0(self, t): - ''' - binary : cast - ''' - t[0] = t[1] - - def p_binary_1(self, t): - ''' - binary : binary MUL binary - | binary DIV binary - | binary MULMUL binary - | binary MOD binary - | binary ADD binary - | binary SUB binary - | binary LSH binary - | binary RSH binary - | binary LE binary - | binary LG binary - | binary LT binary - | binary GE binary - | binary GT binary - | binary EQ binary - | binary NE binary - | binary OR binary - | binary XOR binary - | binary AND binary - | binary ANDAND binary - | binary OROR binary - ''' - clause = BinaryClause() - clause.left = t[1] - clause.op = t[2] - clause.right = t[3] - t[0] = clause - - # conditional rules - def p_conditional_0(self, t): - ''' - conditional : binary - ''' - t[0] = t[1] - - def p_conditional_1(self, t): - ''' - conditional : binary QUESTION expression COLON conditional - ''' - clause = ConditionalClause() - clause.cond = t[1] - clause.true = t[3] - clause.false = t[5] - t[0] = clause - - # assignment rules - def p_assignment_0(self, t): - ''' - assignment : conditional - ''' - t[0] = t[1] - - def p_assignment_1(self, t): - ''' - assignment : operand EQUALS assignment - | operand ADDEQ assignment - | operand ANDEQ assignment - | operand DIVEQ assignment - | operand LSHEQ assignment - | operand MODEQ assignment - | operand MULEQ assignment - | operand OREQ assignment - | operand RSHEQ assignment - | operand SUBEQ assignment - | operand XOREQ assignment - ''' - clause = AssignmentClause() - clause.dst = t[1] - clause.op = t[2] - clause.src = t[3] - t[0] = clause - - # ifthenelse rules - def p_then_stmt_0(self, t): - ''' - then_stmt : empty - ''' - t[0] = [] - - def p_then_stmt_1(self, t): - ''' - then_stmt : statement - ''' - t[0] = t[1] - - def p_then_stmt_2(self, t): - ''' - then_stmt : THEN statement - ''' - t[0] = t[2] - - def p_then_stmt_3(self, t): - ''' - then_stmt : THEN statement terminator - ''' - t[0] = t[2] - - def p_else_stmt_0(self, t): - ''' - else_stmt : empty - ''' - t[0] = [] - - def p_else_stmt_1(self, t): - ''' - else_stmt : ELSE statement - ''' - t[0] = t[2] - - def p_else_stmt_2(self, t): - ''' - else_stmt : ELSE statement terminator - ''' - t[0] = t[2] - - # expression rules - def p_expression_0(self, t): - ''' - expression : assignment - ''' - t[0] = t[1] - - # terminator rules - def p_terminator_0(self, t): - ''' - terminator : NEWLINE - | SEMI - | DOT - | comment - ''' - if type(t[1]) is CommentClause: - clause = t[1] - else: - clause = CommentClause() - clause.content = [ t[1] ] - t[0] = clause - - # statement rules - def p_statement_0(self, t): - ''' - statement : assignment terminator - ''' - t[0] = [t[1], t[2]] - - def p_statement_2(self, t): - ''' - statement : assignment COMMA assignment - ''' - clause = ChainClause() - clause.left = t[1] - clause.right = t[3] - t[0] = [clause] - - def p_statement_3(self, t): - ''' - statement : IF LPAREN conditional RPAREN then_stmt else_stmt - ''' - clause = IfThenElseClause() - clause.cond = t[3] - clause.then_stmt = t[5] - clause.else_stmt = t[6] - t[0] = [clause] - - def p_statement_4(self, t): - ''' - statement : IF LPAREN conditional RPAREN terminator - ''' - clause = IfClause() - clause.cond = t[3] - t[0] = [clause] - - def p_statement_5(self, t): - ''' - statement : ELSE terminator - ''' - clause = ElseClause() - t[0] = [clause] - - def p_statement_6(self, t): - ''' - statement : ELSIF LPAREN conditional RPAREN terminator - ''' - clause = ElseIfClause() - clause.cond = t[3] - t[0] = [clause] - - def p_statement_7(self, t): - ''' - statement : FOR I IN expression DOTDOTDOT expression DO terminator - ''' - clause = ForClause() - clause.variable = t[2] - clause.start = t[4] - clause.end = t[6] - t[0] = [clause] - - def p_statement_8(self, t): - ''' - statement : END terminator - ''' - clause = EndClause() - t[0] = [clause] - - def p_statement_9(self, t): - ''' - statement : TAB statement terminator - ''' - clause = TabClause() - clause.stmt = t[2] - t[0] = [clause] - - def p_statement_10(self, t): - ''' - statement : NUMBER B COLON - | NUMBER B DOT - ''' - clause = SizeClause() - clause.size = t[1] - t[0] = [clause] - - def p_statement_11(self, t): - ''' - statement : terminator - ''' - t[0] = [t[1]] - - # statements rules - def p_statements_0(self, t): - ''' - statements : statement - ''' - t[0] = t[1] - - def p_statements_1(self, t): - ''' - statements : statements statement - ''' - t[1].extend(t[2]) - t[0] = t[1] - - # specification rule - def p_specification(self, t): - ''' - specification : statements - ''' - t[0] = t[1] - - - # error rule - def p_error(self, t): - if t: - # sys.exit('%d: syntax error at "%s"' % (t.lexer.lineno, t.value)) - pass - else: - # sys.exit('unknown syntax error') - pass - self.yacc.errok() - raise ParseError('p_error') - - # end rules - def cleanup_substitute(self, desc): - for sub in self.repeat_subs: - if sub[0] in desc: - desc = desc.replace(sub[0], sub[1]) - for sub in self.single_subs: - if sub[0] in desc: - return desc.replace(sub[0], sub[1]) - return desc - - def cleanup_description(self, desc_list): - edited = [] - for d in desc_list: - if d: - lines = d.split('\\n') - for l in lines: - if l: - e = self.cleanup_substitute(l + '\n') - edited.append(e) - return ''.join(edited) - - def parse_description(self, desc_list): - ''' - Parse the description strings - ''' - assert(type(desc_list) is list) - self.in_text = False - desc_string = self.cleanup_description(desc_list) - # import pdb; pdb.set_trace() - # print 'desc_string=%s' % repr(desc_string) - return self.parse_string(desc_string, '', debug=False) diff --git a/src/arch/amdgpu/gcn3/gpu_isa_main.py b/src/arch/amdgpu/gcn3/gpu_isa_main.py deleted file mode 100644 index 493372db7a..0000000000 --- a/src/arch/amdgpu/gcn3/gpu_isa_main.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import sys - -sys.path.append('../../../../gem5/ext/ply') -sys.path.append('../../../../gem5/src/python') - -from gpu_isa_parser import GpuIsaParser -from ast_interpreter import AstInterpreter - -# Get args from command line. -# Args are: -if __name__ == '__main__': - ast = GpuIsaParser(sys.argv[1], sys.argv[2]).parse_isa_desc() - interpreter = AstInterpreter() - interpreter.process_statements(ast) - interpreter.generate_code(sys.argv[2]) diff --git a/src/arch/amdgpu/gcn3/gpu_isa_parser.py b/src/arch/amdgpu/gcn3/gpu_isa_parser.py deleted file mode 100644 index 14025b8614..0000000000 --- a/src/arch/amdgpu/gcn3/gpu_isa_parser.py +++ /dev/null @@ -1,1263 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import re -import sys - -from ast_objects import * -from m5.util.grammar import Grammar - -class GpuIsaParser(Grammar): - def __init__(self, input_file, output_dir): - super(GpuIsaParser, self).__init__() - self.input_file = input_file - self.output_dir = output_dir - - # lexer - - states = ( - ( 'qstring', 'exclusive' ), - ) - - reserved = ( - 'BITS', - 'CONST', - 'DESC', - 'DP_ONLY', - 'DST_0', - 'DST_1', - 'ENC', - 'ENCODING', - 'ENUM', - 'FIELDS', - 'FLAG', - 'FLAGS', - 'FMT', - 'GROUP', - 'IMPORT', - 'INOUT', - 'INST', - 'NAME', - 'NUM_DST', - 'NUM_SRC', - 'OP_TYPE', - 'OPERANDS', - 'PARENT_ENC', - 'PRIVATE', - 'RANGE', - 'REG', - 'SIZE', - 'SIZE_BITS', - 'SP3_DESC', - 'SP3_NAME', - 'SP3_NCOMP', - 'SP3_NUM', - 'SRC_0', - 'SRC_1', - 'SRC_2', - 'SRC_3', - 'SRC_FLAGS', - 'SUB_ENC', - 'TYPE', - 'WHEN' - ) - - # list token names - tokens = reserved + ( - 'ID', - 'STRING', - 'QSTRING', - 'NUMBER', - 'COLON', - 'SEMI', - 'DOLLAR', - 'EQUAL', - 'LBRACE', - 'RBRACE', - 'LPAREN', - 'RPAREN', - 'PLUS', - ) - - # regular expressions for simple tokens - t_COLON = r':' - t_SEMI = r';' - t_DOLLAR = r'\$' - t_EQUAL = r'=' - t_LBRACE = r'\{' - t_RBRACE = r'\}' - t_LPAREN = r'\(' - t_RPAREN = r'\)' - t_PLUS = r'\+' - - reserved_map = { } - for r in reserved: - reserved_map[r.lower()] = r - - def t_QSTRING(self, t): - r'q{' - nesting = 0 - t.lexer.begin('qstring') - while True: - tok = t.lexer.token() - if not tok: - break - t.value += tok.value - if tok.type == 'LBRACE': - nesting += 1 - if tok.type == 'RBRACE': - if nesting > 0: - nesting -= 1 - else: - break - t.lexer.begin('INITIAL') - t.lexer.lineno += t.value.count('\n') - return t - - t_qstring_LBRACE = r'{' - t_qstring_RBRACE = r'}' - t_qstring_STRING = r'[^}{]+' - - t_qstring_ignore = ' \t\x0c' - - def t_qstring_error(self, t): - sys.exit('%d: illegal character "%s"' % (t.lexer.lineno, t.value[0])) - - def t_ID(self, t): - r'[a-zA-Z_][a-zA-Z0-9_]*' - t.type = self.reserved_map.get(t.value, 'ID') - return t - - def t_STRING(self, t): - r'(?m)"([^"])+"' - t.value = t.value[1:-1] - t.lexer.lineno += t.value.count('\n') - return t - - def t_NEWLINE(self, t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - - def t_BINARY(self, t): - r'0[bB][0-1]+' - t.value = int(t.value, 2) - t.type = 'NUMBER' - return t - - def t_OCTAL(self, t): - r'0[oO]?[0-7]+' - t.value = int(t.value, 8) - t.type = 'NUMBER' - return t - - def t_HEXADECIMAL(self, t): - r'0[xX][0-9a-fA-F]+' - t.value = int(t.value, 16) - t.type = 'NUMBER' - return t - - def t_DECIMAL(self, t): - r'[0-9][0-9]*' - t.value = int(t.value, 10) - t.type = 'NUMBER' - return t - - def t_COMMENT(self, t): - r'\#[^\n]*\n' - t.lexer.lineno += 1 - - t_ignore = ' \t\x0c' - - def t_error(self, t): - sys.exit('%d: illegal character "%s"' % (t.lexer.lineno, t.value[0])) - - ## parser - - start = 'specification' - - # enum_or_reg rules - - def p_enum_or_reg_0(self, t): - ''' - enum_or_reg : ENUM - ''' - t[0] = t[1] - - def p_enum_or_reg_1(self, t): - ''' - enum_or_reg : REG - ''' - t[0] = t[1] - - # statement(import_statement) rules - def p_import_statement(self, t): - ''' - statement : IMPORT enum_or_reg ID SEMI - ''' - stmnt = ImportStatement() - stmnt.what = t[2] - stmnt.name = t[3] - t[0] = stmnt - - # flags_clause rules - def p_flags_field_0(self, t): - ''' - flags_field : DESC COLON STRING - ''' - info = FlagsField() - info.tag = 'desc' - info.desc = [t[3]] - t[0] = info - - def p_flags_field_1(self, t): - ''' - flags_field : DESC PLUS COLON STRING - ''' - info = FlagsField() - info.tag = 'desc+' - info.desc = [t[4]] - t[0] = info - - def p_flags_field_2(self, t): - ''' - flags_field : PRIVATE COLON NUMBER - ''' - info = FlagsField() - info.tag = 'private' - info.private = t[3] - t[0] = info - - def p_flags_field_3(self, t): - ''' - flags_field : GROUP COLON ID - ''' - info = FlagsField() - info.tag = 'group' - info.group = t[3] - t[0] = info - - # flags_clauses rules - def p_flags_fields_0(self, t): - ''' - flags_fields : flags_field - ''' - t[0] = t[1] - - def p_flags_fields_1(self, t): - ''' - flags_fields : flags_fields flags_field - ''' - t[1].update(t[2]) - t[0] = t[1] - - # flags_clause rules - def p_flags_clause(self, t): - ''' - flags_clause : ID COLON flags_fields SEMI - ''' - field = FlagsField() - field.tag = 'name' - field.name = t[1] - t[3].update(field) - t[0] = t[3] - - # flags_clauses rules - def p_flags_clauses_0(self, t): - ''' - flags_clauses : flags_clause - ''' - t[0] = [t[1]] - - def p_flags_clauses_1(self, t): - ''' - flags_clauses : flags_clauses flags_clause - ''' - t[1].append(t[2]) - t[0] = t[1] - - # flag_clause rules - # FlagBlock: - def p_flag_clause(self, t): - ''' - flag_clause : DESC EQUAL STRING SEMI - ''' - block = FlagBlock() - block.tag = 'desc' - block.desc = [t[3]] - t[0] = block - - # flag_clauses rules - # FlagBlock: - def p_flag_clauses_0(self, t): - ''' - flag_clauses : flag_clause - ''' - t[0] = t[1] - - def p_flag_clauses_1(self, t): - ''' - flag_clauses : flag_clauses flag_clause - ''' - t[1].update(t[2]) - t[0] = t[1] - - # statement(flag_block) rules - # FlagBlock: - def p_flag_block(self, t): - ''' - statement : FLAG ID LBRACE flag_clauses RBRACE - ''' - block = FlagBlock() - block.tag = 'name' - block.name = t[2] - t[4].update(block) - t[0] = t[4] - - # statement(flags_block) rules - # FlagsBlock: - # clauses: [ FlagsFields, ... ] - def p_flags_block(self, t): - ''' - statement : FLAGS LBRACE flags_clauses RBRACE - ''' - block = FlagsBlock() - block.clauses = t[3] - t[0] = block - - # dst_X rules - def p_dst_0(self, t): - ''' - dst_X : DST_0 - ''' - t[0] = 0 - - def p_dst_1(self, t): - ''' - dst_X : DST_1 - ''' - t[0] = 1 - - # src_X rules - def p_src_0(self, t): - ''' - src_X : SRC_0 - ''' - t[0] = 0 - - def p_src_1(self, t): - ''' - src_X : SRC_1 - ''' - t[0] = 1 - - def p_src_2(self, t): - ''' - src_X : SRC_2 - ''' - t[0] = 2 - - def p_src_3(self, t): - ''' - src_X : SRC_3 - ''' - t[0] = 3 - - # operands_phrase rules - # OpInfo - def p_operands_phrase_0(self, t): - ''' - operands_phrase : dst_X EQUAL ID - ''' - phrase = OpInfo() - phrase.tag = 'dst' - phrase.opr = 'dst' - phrase.index = t[1] - phrase.iseq = t[3] - t[0] = phrase - - def p_operands_phrase_1(self, t): - ''' - operands_phrase : dst_X COLON - ''' - phrase = OpInfo() - phrase.tag = 'dst' - phrase.opr = 'dst' - phrase.index = t[1] - phrase.iseq = None - t[0] = phrase - - def p_operands_phrase_2(self, t): - ''' - operands_phrase : src_X EQUAL ID - ''' - phrase = OpInfo() - phrase.tag = 'src' - phrase.opr = 'src' - phrase.index = t[1] - phrase.iseq = t[3] - t[0] = phrase - - def p_operands_phrase_3(self, t): - ''' - operands_phrase : src_X COLON - ''' - phrase = OpInfo() - phrase.tag = 'src' - phrase.opr = 'src' - phrase.index = t[1] - phrase.iseq = None - t[0] = phrase - - def p_operands_phrase_4(self, t): - ''' - operands_phrase : NAME COLON STRING - ''' - phrase = OpInfo() - phrase.tag = 'name' - phrase.name = t[3] - t[0] = phrase - - def p_operands_phrase_5(self, t): - ''' - operands_phrase : FMT COLON ID - ''' - phrase = OpInfo() - phrase.tag = 'fmt' - phrase.fmt = t[3] - t[0] = phrase - - def p_operands_phrase_6(self, t): - ''' - operands_phrase : SIZE COLON NUMBER - ''' - phrase = OpInfo() - phrase.tag = 'size' - phrase.size = t[3] - t[0] = phrase - - def p_operands_phrase_7(self, t): - ''' - operands_phrase : INOUT COLON NUMBER - ''' - phrase = OpInfo() - phrase.tag = 'inout' - phrase.inout = t[3] - t[0] = phrase - - # operands_phrases rules - # OpInfo - def p_operands_phrases_0(self, t): - ''' - operands_phrases : operands_phrase - ''' - t[0] = t[1] - - def p_operands_phrases_1(self, t): - ''' - operands_phrases : operands_phrases operands_phrase - ''' - t[1].update(t[2]) - t[0] = t[1] - - # operands_clause rules - # Operand: - # dst: [ OpInfo, ... ] - # src: [ OpInfo, ... ] - # when: [ WhenBlock, ... ] - # operands: [ Operand, ... ] - def p_operands_clause_0(self, t): - ''' - operands_clause : NUM_DST EQUAL NUMBER SEMI - ''' - clause = Operand() - clause.tag = 'num_dst' - clause.num_dst = t[3] - t[0] = clause - - def p_operands_clause_1(self, t): - ''' - operands_clause : NUM_SRC EQUAL NUMBER SEMI - ''' - clause = Operand() - clause.tag = 'num_src' - clause.num_src = t[3] - t[0] = clause - - def p_operands_clause_2(self, t): - ''' - operands_clause : PARENT_ENC EQUAL ID SEMI - ''' - clause = Operand() - clause.tag = 'parent_enc' - clause.parent_enc = t[3] - t[0] = clause - - def p_operands_clause_3(self, t): - ''' - operands_clause : SUB_ENC EQUAL ID SEMI - ''' - clause = Operand() - clause.tag = 'sub_enc' - clause.sub_enc = t[3] - t[0] = clause - - def p_operands_clause_4(self, t): - ''' - operands_clause : FLAGS EQUAL ID SEMI - ''' - clause = Operand() - clause.tag = 'flags' - clause.flags = [t[3]] - t[0] = clause - - def p_operands_clause_5(self, t): - ''' - operands_clause : FLAGS EQUAL STRING SEMI - ''' - clause = Operand() - clause.tag = 'flags' - # handle flags = 'flag1 flag2' - regexp = re.compile('\w+') - clause.flags = regexp.findall(t[3]) - t[0] = clause - - def p_operands_clause_6(self, t): - ''' - operands_clause : operands_phrases SEMI - ''' - clause = Operand() - clause.tag = t[1].opr - if clause.tag == 'dst': - clause.dst = [t[1]] - elif clause.tag == 'src': - clause.src = [t[1]] - else: - assert (False), 'p_operands_clause_6: unexpected tag ' + clause.tag - t[0] = clause - - def p_operands_clause_7(self, t): - ''' - operands_clause : when_block - ''' - clause = Operand() - clause.tag = 'when' - clause.when = [t[1]] - t[0] = clause - - def p_operands_clause_8(self, t): - ''' - operands_clause : operands_block - ''' - clause = Operand() - clause.tag = 'operands' - clause.operands = [t[1]] - t[0] = clause - - # operands_clauses rules - # Operand - def p_operands_clauses_0(self, t): - ''' - operands_clauses : operands_clause - ''' - t[0] = t[1] - - def p_operands_clauses_1(self, t): - ''' - operands_clauses : operands_clauses operands_clause - ''' - t[1].update(t[2]) - t[0] = t[1] - - # when_block rules - # WhenBlock: - # operands: [ Operand, ... ] - def p_when_block_0(self, t): - ''' - when_block : WHEN FLAGS EQUAL ID LBRACE operands_clauses RBRACE - ''' - block = WhenBlock() - block.left = 'flags' - block.right = [t[4]] - block.operand = t[6] - t[0] = block - - def p_when_block_1(self, t): - ''' - when_block : WHEN FLAGS EQUAL STRING LBRACE operands_clauses RBRACE - ''' - block = WhenBlock() - block.left = 'flags' - # handle when flags = 'flag1 flag2' - regexp = re.compile('\w+') - block.right = regexp.findall(t[4]) - block.operand = t[6] - t[0] = block - - def p_when_block_2(self, t): - ''' - when_block : WHEN SUB_ENC EQUAL STRING LBRACE operands_clauses RBRACE - ''' - block = WhenBlock() - block.left = 'sub_enc' - block.right = [t[4]] - block.operand = t[6] - t[0] = block - - # operands_block rules - # Operand - def p_operands_block(self, t): - ''' - operands_block : OPERANDS LBRACE operands_clauses RBRACE - ''' - t[0] = t[3] - - # encoding_clause rules - # EncodingBlock: - # operands: [ Operand, ... ] - def p_encoding_clause_0(self, t): - ''' - encoding_clause : BITS EQUAL STRING SEMI - ''' - clause = EncodingBlock() - clause.tag = 'bits' - clause.bits = t[3] - t[0] = clause - - def p_encoding_clause_1(self, t): - ''' - encoding_clause : SIZE EQUAL NUMBER SEMI - ''' - clause = EncodingBlock() - clause.tag = 'size' - clause.size = t[3] - t[0] = clause - - def p_encoding_clause_2(self, t): - ''' - encoding_clause : DESC EQUAL STRING SEMI - ''' - clause = EncodingBlock() - clause.tag = 'desc' - clause.desc = [t[3]] - t[0] = clause - - def p_encoding_clause_3(self, t): - ''' - encoding_clause : DESC PLUS EQUAL STRING SEMI - ''' - clause = EncodingBlock() - clause.tag = 'desc+' - clause.desc = [t[4]] - t[0] = clause - - def p_encoding_clause_4(self, t): - ''' - encoding_clause : operands_block - ''' - clause = EncodingBlock() - clause.tag = 'operands' - clause.operands = [t[1]] - t[0] = clause - - # encoding clauses rules - # EncodingBlock: - # operands: [ Operand, ... ] - def p_encoding_clauses_0(self, t): - ''' - encoding_clauses : encoding_clause - ''' - t[0] = t[1] - - def p_encoding_clauses_1(self, t): - ''' - encoding_clauses : encoding_clauses encoding_clause - ''' - t[1].update(t[2]) - t[0] = t[1] - - # encoding_block rules - # EncodingBlock: - # operands: [ Operand, ... ] - - def p_encoding_block(self, t): - ''' - statement : ENCODING ID LBRACE encoding_clauses RBRACE - ''' - clause = EncodingBlock() - clause.tag = 'name' - clause.name = t[2] - t[4].update(clause) - t[0] = t[4] - - # const_clauses rules - def p_const_clause(self, t): - ''' - const_clause : ID EQUAL NUMBER SEMI - ''' - clause = ConstClause() - clause.name = t[1] - clause.value = t[3] - t[0] = clause - - # const_clauses rules - def p_const_clauses_0(self, t): - ''' - const_clauses : const_clause - ''' - t[0] = [t[1]] - - def p_const_clauses_1(self, t): - ''' - const_clauses : const_clauses const_clause - ''' - t[1].append(t[2]) - t[0] = t[1] - - # statement(const_block) rules - def p_const_block(self, t): - ''' - statement : CONST LBRACE const_clauses RBRACE - ''' - stmnt = ConstBlock() - stmnt.clauses = t[3] - t[0] = stmnt - - # type_phrase rules - def p_type_phrase_0(self, t): - ''' - type_phrase : ID EQUAL NUMBER COLON NUMBER - ''' - field = TypeClause() - field.tag = 'id_range' - field.name = t[1] - field.value = t[3] - field.v_max = t[5] - t[0] = field - - def p_type_phrase_1(self, t): - ''' - type_phrase : ID EQUAL NUMBER - ''' - field = TypeClause() - field.tag = 'id_number' - field.name = t[1] - field.value = t[3] - t[0] = field - - def p_type_phrase_2(self, t): - ''' - type_phrase : ID DOLLAR LBRACE ID RBRACE ID EQUAL NUMBER - ''' - field = TypeClause() - field.tag = 'id_var_number' - field.name = t[1] + '${' + t[4] + '}' + t[6] - field.value = t[8] - field.var = True - t[0] = field - - def p_type_phrase_3(self, t): - ''' - type_phrase : ID DOLLAR LBRACE ID RBRACE EQUAL NUMBER - ''' - field = TypeClause() - field.tag = 'id_var_number' - field.name = t[1] + '${' + t[4] + '}' - field.value = t[7] - field.var = True - t[0] = field - - def p_type_phrase_4(self, t): - ''' - type_phrase : DESC COLON STRING - ''' - field = TypeClause() - field.tag = 'desc' - field.desc = [t[3]] - t[0] = field - - def p_type_phrase_5(self, t): - ''' - type_phrase : DESC COLON ID LPAREN ID RPAREN - ''' - field = TypeClause() - field.tag = 'desc' - field.desc = [ t[3] + '(' + t[5] + ')' ] - t[0] = field - - def p_type_phrase_6(self, t): - ''' - type_phrase : DESC PLUS COLON ID LPAREN ID RPAREN - ''' - field = TypeClause() - field.tag = 'desc+' - field.desc = [ t[4] + '(' + t[6] + ')' ] - t[0] = field - - def p_type_phrase_7(self, t): - ''' - type_phrase : DESC PLUS COLON STRING - ''' - field = TypeClause() - field.tag = 'desc+' - field.desc = [t[4]] - t[0] = field - - def p_type_phrase_8a(self, t): - ''' - type_phrase : DESC COLON QSTRING - ''' - field = TypeClause() - field.tag = 'desc' - field.desc = t[3][2:-1].strip().split('\n') - t[0] = field - - def p_type_phrase_8b(self, t): - ''' - type_phrase : DESC PLUS COLON QSTRING - ''' - field = TypeClause() - field.tag = 'desc+' - field.desc = t[4][2:-1].strip().split('\n') - t[0] = field - - def p_type_phrase_9(self, t): - ''' - type_phrase : FLAGS COLON ID - ''' - field = TypeClause() - field.tag = 'flags' - field.flags = [t[3]] - t[0] = field - - def p_type_phrase_10(self, t): - ''' - type_phrase : FLAGS COLON STRING - ''' - field = TypeClause() - field.tag = 'flags' - # handle flags: 'flag1 flag2' - regexp = re.compile('\w+') - field.flags = regexp.findall(t[3]) - t[0] = field - - def p_type_phrase_11(self, t): - ''' - type_phrase : FLAGS PLUS COLON ID - ''' - field = TypeClause() - field.tag = 'flags+' - field.flags = [t[4]] - t[0] = field - - def p_type_phrase_12(self, t): - ''' - type_phrase : FLAGS PLUS COLON STRING - ''' - field = TypeClause() - field.tag = 'flags+' - # handle flags+: 'flag1 flag2' - regexp = re.compile('\w+') - field.flags = regexp.findall(t[4]) - t[0] = field - - def p_type_phrase_13(self, t): - ''' - type_phrase : SRC_FLAGS COLON ID - ''' - field = TypeClause() - field.tag = 'src_flags' - field.src_flags = t[3] - t[0] = field - - def p_type_phrase_14(self, t): - ''' - type_phrase : SRC_FLAGS COLON STRING - ''' - field = TypeClause() - field.tag = 'src_flags' - field.src_flags = t[3] - t[0] = field - - def p_type_phrase_15(self, t): - ''' - type_phrase : SP3_DESC COLON STRING - ''' - field = TypeClause() - field.tag = 'sp3_desc' - field.sp3_desc = [t[3]] - t[0] = field - - def p_type_phrase_16(self, t): - ''' - type_phrase : SP3_DESC PLUS COLON STRING - ''' - field = TypeClause() - field.tag = 'sp3_desc+' - field.sp3_desc = [t[4]] - t[0] = field - - def p_type_phrase_17(self, t): - ''' - type_phrase : SP3_NAME COLON STRING - ''' - field = TypeClause() - field.tag = 'sp3_name' - field.sp3_name = t[3] - t[0] = field - - def p_type_phrase_18(self, t): - ''' - type_phrase : SP3_NCOMP COLON NUMBER - ''' - field = TypeClause() - field.tag = 'sp3_ncomp' - field.sp3_ncomp = t[3] - t[0] = field - - def p_type_phrase_19(self, t): - ''' - type_phrase : SP3_NUM COLON STRING - ''' - field = TypeClause() - field.tag = 'sp3_num' - field.sp3_num = t[3] - t[0] = field - - def p_type_phrase_20(self, t): - ''' - type_phrase : SUB_ENC COLON ID - ''' - field = TypeClause() - field.tag = 'sub_enc' - field.sub_enc = t[3] - t[0] = field - - def p_type_phrase_21(self, t): - ''' - type_phrase : OP_TYPE COLON ID - ''' - field = TypeClause() - field.tag = 'op_type' - field.op_type = t[3] - t[0] = field - - def p_type_phrase_22(self, t): - ''' - type_phrase : DP_ONLY COLON NUMBER - ''' - field = TypeClause() - field.tag = 'dp_only' - field.sub_enc = t[3] - t[0] = field - - def p_type_phrase_23(self, t): - ''' - type_phrase : SIZE COLON NUMBER - ''' - field = TypeClause() - field.tag = 'size' - field.size = t[3] - t[0] = field - - def p_type_phrase_24(self, t): - ''' - type_phrase : FMT COLON ID - ''' - field = TypeClause() - field.tag = 'fmt' - field.fmt = t[3] - t[0] = field - - def p_type_phrase_25(self, t): - ''' - type_phrase : TYPE ID - ''' - field = TypeClause() - field.tag = 'type' - field.type = t[2] - t[0] = field - - def p_type_phrase_26(self, t): - ''' - type_phrase : RANGE NUMBER COLON NUMBER - ''' - field = TypeClause() - field.tag = 'range' - field.range = [ t[2], t[4] ] - t[0] = field - - def p_type_phrase_27(self, t): - ''' - type_phrase : SIZE_BITS NUMBER - ''' - field = TypeClause() - field.tag = 'size_bits' - field.size_bits = t[2] - t[0] = field - - # type_phrases rules - # [ TypeClause, ... ] - def p_type_phrases_0(self, t): - ''' - type_phrases : type_phrase - ''' - t[0] = t[1] - - def p_type_phrases_1(self, t): - ''' - type_phrases : type_phrases type_phrase - ''' - t[1].update(t[2]) - t[0] = t[1] - - # type_clause rules - # [ TypeClause, ... ] - def p_type_clause(self, t): - ''' - type_clause : type_phrases SEMI - ''' - t[0] = t[1] - - # type_clauses rules - def p_type_clauses_0(self, t): - ''' - type_clauses : type_clause - ''' - t[0] = [t[1]] - - def p_type_clauses_1(self, t): - ''' - type_clauses : type_clauses type_clause - ''' - t[1].append(t[2]) - t[0] = t[1] - - # statement(type_block) rules - # TypeBlock: - # clauses: [ TypeClause, ... ] - def p_type_block(self, t): - ''' - statement : TYPE ID LBRACE type_clauses RBRACE - ''' - stmnt = TypeBlock() - stmnt.name = t[2] - stmnt.clauses = t[4] - t[0] = stmnt - - # inst_field rules - def p_inst_field_0(self, t): - ''' - inst_field : ID EQUAL NUMBER COLON NUMBER - ''' - field = InstField() - field.tag = 'id_range' - field.name = t[1] - field.v_max = t[3] - field.value = t[5] - t[0] = field - - def p_inst_field_1(self, t): - ''' - inst_field : ID EQUAL NUMBER - ''' - field = InstField() - field.tag = 'id_number' - field.name = t[1] - field.v_max = t[3] - field.value = t[3] - t[0] = field - - def p_inst_field_2(self, t): - ''' - inst_field : DESC COLON STRING - ''' - field = InstField() - field.tag = 'desc' - field.desc = t[3] - t[0] = field - - def p_inst_field_3(self, t): - ''' - inst_field : TYPE COLON ID - ''' - field = InstField() - field.tag = 'type' - field.type = t[3] - t[0] = field - - def p_inst_field_4(self, t): - ''' - inst_field : ENC COLON ID - ''' - field = InstField() - field.tag = 'enc' - field.enc = t[3] - t[0] = field - - # fields_phrases rules - # [ InstFields, ... ] - def p_fields_phrases_0(self, t): - ''' - fields_phrases : inst_field - ''' - t[0] = t[1] - - def p_fields_phrases_1(self, t): - ''' - fields_phrases : fields_phrases inst_field - ''' - t[1].update(t[2]) - t[0] = t[1] - - # inst_fields rules - # [ InstFields, ... ] - def p_fields_clause(self, t): - ''' - fields_clause : fields_phrases SEMI - ''' - t[0] = t[1] - - # fields_clauses rules - def p_fields_clauses_0(self, t): - ''' - fields_clauses : fields_clause - ''' - t[0] = [t[1]] - - def p_fields_clauses_1(self, t): - ''' - fields_clauses : fields_clauses fields_clause - ''' - t[1].append(t[2]) - t[0] = t[1] - - # fields_block rule - # [ InstFields, ... ] - def p_fields_block(self, t): - ''' - fields_block : FIELDS LBRACE fields_clauses RBRACE - ''' - t[0] = t[3] - - # inst_clause rules - # InstBlock: - # fields: [ InstFields, ... ] - def p_inst_clause_0(self, t): - ''' - inst_clause : DESC EQUAL STRING SEMI - ''' - clause = InstBlock() - clause.tag = 'desc' - clause.desc = t[3] - t[0] = clause - - def p_inst_clause_1(self, t): - ''' - inst_clause : fields_block - ''' - clause = InstBlock() - clause.tag = 'fields' - clause.fields = t[1] - t[0] = clause - - # inst_clauses rules - # InstBlock: - # fields: [ InstField, ... ] - def p_inst_clauses_0(self, t): - ''' - inst_clauses : inst_clause - ''' - t[0] = t[1] - - def p_inst_clauses_1(self, t): - ''' - inst_clauses : inst_clauses inst_clause - ''' - t[1].update(t[2]) - t[0] = t[1] - - # statement(inst_block) rules - # InstBlock: - # fields: [ InstFields, ... ] - def p_inst_block(self, t): - ''' - statement : INST ID LBRACE inst_clauses RBRACE - ''' - block = InstBlock() - block.tag = 'name' - # drop '_0' to simplify matches with encodings - n = t[2] - if '_0' in n: - n = n.replace('_0', '') - block.name = n - t[4].update(block) - t[0] = t[4] - - # statements rules - def p_statements_0(self, t): - ''' - statements : statement - ''' - t[0] = [t[1]] - - def p_statements_1(self, t): - ''' - statements : statements statement - ''' - t[1].append(t[2]) - t[0] = t[1] - - # specification rule - def p_specification(self, t): - ''' - specification : statements - ''' - t[0] = t[1] - - # error rule - def p_error(self, t): - if t: - print('%d: syntax error at "%s"' % (t.lexer.lineno, t.value)) - else: - print('unknown syntax error') - import pdb; pdb.set_trace() - - # end rules - def parse_isa_desc(self): - ''' - Read in and parse the ISA description - ''' - try: - contents = open(self.input_file).read() - except IOError: - error('Error with file "%s"' % self.input_file) - - return self.parse_string(contents, '', debug=False) diff --git a/src/arch/amdgpu/gcn3/hand_coded.py b/src/arch/amdgpu/gcn3/hand_coded.py deleted file mode 100644 index 6b6680ea39..0000000000 --- a/src/arch/amdgpu/gcn3/hand_coded.py +++ /dev/null @@ -1,414 +0,0 @@ -# Copyright (c) 2015-2021 Advanced Micro Devices, Inc. -# All rights reserved. -# -# For use for simulation and test purposes only -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -HandCodedExecMethods = { - 'Inst_SOPP__S_NOP' : [ - 'ExecNOP(gpuDynInst, instData.SIMM16);' - ], - 'Inst_VOP1__V_NOP' : [ - 'ExecNOP(gpuDynInst, 1);' - ], - 'Inst_VOP3__V_NOP' : [ - 'ExecNOP(gpuDynInst, 1);' - ], - 'Inst_DS__DS_NOP' : [ - 'ExecNOP(gpuDynInst, 1);' - ], - 'Inst_SOPP__S_ENDPGM' : [ - 'ExecEndPgm(gpuDynInst);' - ], - 'Inst_SOPP__S_ENDPGM_SAVED' : [ - 'ExecEndPgmSaved(gpuDynInst);' - ], - 'Inst_VOP2__V_MUL_HI_I32_I24' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, instData.SRC0);', - 'src_1 = readVectorReg(gpuDynInst, instData.VSRC1);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' int64_t s0 = (int64_t)src_0[t](23, 0);', - ' int64_t s1 = (int64_t)src_1[t](23, 0);', - ' vdst[t] = (int32_t)((s0 * s1) >> 32);', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP2__V_MUL_HI_U32_U24' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, instData.SRC0);', - 'src_1 = readVectorReg(gpuDynInst, instData.VSRC1);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' uint64_t s0 = (uint64_t)src_0[t](23, 0);', - ' uint64_t s1 = (uint64_t)src_1[t](23, 0);', - ' vdst[t] = (uint32_t)((s0 * s1) >> 32);', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - - # stuff below here should eventually get fixed in the parser - 'Inst_SOP1__S_MOVRELS_B64' : [ - 'm0 = readSpecialReg(gpuDynInst, REG_M0);', - 'ssrc = readScalarReg(gpuDynInst, instData.SSRC0 + m0);', - 'sdst = ssrc;', - 'writeScalarReg(gpuDynInst, instData.SDST, sdst);' - ], - 'Inst_SOP1__S_MOVRELD_B64' : [ - 'm0 = readSpecialReg(gpuDynInst, REG_M0);', - 'ssrc = readScalarReg(gpuDynInst, instData.SSRC0);', - 'sdst = ssrc;', - 'writeScalarReg(gpuDynInst, instData.SDST + m0, sdst);' - ], - 'Inst_SOPC__S_SET_GPR_IDX_ON' : [ - 'ssrc_0 = readScalarReg(gpuDynInst, instData.SSRC0);', - 'simm4 = instData.SSRC1;', - 'm0(7, 0) = ssrc_0(7, 0);', - 'm0(15, 12) = (uint32_t)simm4;', - 'writeSpecialReg(gpuDynInst, REG_M0, m0);' - ], - 'Inst_VOP2__V_MADMK_F32' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, instData.SRC0);', - 'k = extData.imm_f32;', - 'src_2 = readVectorReg(gpuDynInst, instData.VSRC1);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vdst[t] = src_0[t] * k + src_2[t];', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP2__V_MADAK_F32' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, instData.SRC0);', - 'src_1 = readVectorReg(gpuDynInst, instData.VSRC1);', - 'k = extData.imm_f32;', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vdst[t] = src_0[t] * src_1[t] + k;', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP2__V_MADMK_F16' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, instData.SRC0);', - 'k = extData.imm_f32;', - 'src_2 = readVectorReg(gpuDynInst, instData.VSRC1);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vdst[t] = src_0[t] * k + src_2[t];', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP2__V_MADAK_F16' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, instData.SRC0);', - 'src_1 = readVectorReg(gpuDynInst, instData.VSRC1);', - 'k = extData.imm_f32;', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vdst[t] = src_0[t] * src_1[t] + k;', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP3__V_MUL_HI_I32_I24' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, extData.SRC0);', - 'src_1 = readSrcReg(gpuDynInst, extData.SRC1);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' int64_t s0 = (int64_t)(int32_t)src_0[t](23, 0);', - ' int64_t s1 = (int64_t)(int32_t)src_1[t](23, 0);', - ' vdst[t] = (int32_t)((s0 * s1) >> 32);', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP3__V_MUL_HI_U32_U24' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, extData.SRC0);', - 'src_1 = readSrcReg(gpuDynInst, extData.SRC1);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' uint64_t s0 = (uint64_t)(uint32_t)src_0[t](23, 0);', - ' uint64_t s1 = (uint64_t)(uint32_t)src_1[t](23, 0);', - ' vdst[t] = (int32_t)((s0 * s1) >> 32);', - ' }', - '}', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP3__V_MAD_U64_U32' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, extData.SRC0);', - 'src_1 = readSrcReg(gpuDynInst, extData.SRC1);', - 'src_2 = readSrcReg(gpuDynInst, extData.SRC2);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vcc(t) = muladd(vdst[t], src_0[t], src_1[t], src_2[t]);', - ' }', - '}', - 'writeSpecialReg(gpuDynInst, REG_VCC, vcc);', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_VOP3__V_MAD_I64_I32' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vdst = readVectorReg(gpuDynInst, instData.VDST);', - 'src_0 = readSrcReg(gpuDynInst, extData.SRC0);', - 'src_1 = readSrcReg(gpuDynInst, extData.SRC1);', - 'src_2 = readSrcReg(gpuDynInst, extData.SRC2);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vcc(t) = muladd(vdst[t], src_0[t], src_1[t], src_2[t]);', - ' }', - '}', - 'writeSpecialReg(gpuDynInst, REG_VCC, vcc);', - 'writeVectorReg(gpuDynInst, instData.VDST, vdst);' - ], - 'Inst_DS__DS_WRITE_B96' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vgpr_a = readVectorReg(gpuDynInst, extData.ADDR);', - 'calculateAddr(gpuDynInst, vgpr_a, 8, 0);', - 'calculateAddr(gpuDynInst, vgpr_a, 4, 0);', - 'calculateAddr(gpuDynInst, vgpr_a, 0, 0);', - 'vgpr_d0 = readVectorReg(gpuDynInst, extData.DATA0);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vmem_0[t] = vgpr_d0[t].getDword(2);', - ' vmem_1[t] = vgpr_d0[t].getDword(1);', - ' vmem_2[t] = vgpr_d0[t].getDword(0);', - ' }', - '}', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_0);', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_1);', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_2);' - ], - 'Inst_DS__DS_WRITE_B128' : [ - 'exec = readSpecialReg(gpuDynInst, REG_EXEC);', - 'vgpr_a = readVectorReg(gpuDynInst, extData.ADDR);', - 'calculateAddr(gpuDynInst, vgpr_a, 12, 0);', - 'calculateAddr(gpuDynInst, vgpr_a, 8, 0);', - 'calculateAddr(gpuDynInst, vgpr_a, 4, 0);', - 'calculateAddr(gpuDynInst, vgpr_a, 0, 0);', - 'vgpr_d0 = readVectorReg(gpuDynInst, extData.DATA0);', - 'for (unsigned t = 0; exec != 0; t++, exec >>= 1) {', - ' if ((exec & 1) != 0) {', - ' vmem_0[t] = vgpr_d0[t].getDword(3);', - ' vmem_1[t] = vgpr_d0[t].getDword(2);', - ' vmem_2[t] = vgpr_d0[t].getDword(1);', - ' vmem_3[t] = vgpr_d0[t].getDword(0);', - ' }', - '}', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_0);', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_1);', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_2);', - 'writeMem(gpuDynInst, vgpr_a, 0, vmem_3);' - ], - 'Inst_SOPP__S_WAITCNT' : [ - 'int vm_cnt = 0;', - 'int lgkm_cnt = 0;', - 'vm_cnt = bits(instData.SIMM16, 3, 0);', - 'lgkm_cnt = bits(instData.SIMM16, 11, 8);', - 'gpuDynInst->wavefront()->setWaitCnts(vm_cnt, lgkm_cnt);' - ] -} - -HandCodedDecl = { - 'Inst_VOP2__V_MUL_HI_I32_I24' : [ - 'SregU64 exec;', - 'VregI32 vdst;', - 'VregI32 src_0;', - 'VregI32 src_1;' - ], - 'Inst_VOP2__V_MUL_HI_U32_U24' : [ - 'SregU64 exec;', - 'VregI32 vdst;', - 'VregU32 src_0;', - 'VregU32 src_1;' - ], - 'Inst_VOP3__V_MUL_HI_I32_I24' : [ - 'SregU64 exec;', - 'VregI32 vdst;', - 'VregI32 src_0;', - 'VregI32 src_1;' - ], - 'Inst_VOP3__V_MUL_HI_U32_U24' : [ - 'SregU64 exec;', - 'VregI32 vdst;', - 'VregU32 src_0;', - 'VregU32 src_1;' - ], - 'Inst_SOPC__S_SET_GPR_IDX_ON' : [ - 'SregU32 m0;', - 'SregU32 ssrc_0;', - 'SregU16 simm4;' - ], - 'Inst_SOP1__S_MOVRELS_B64' : [ - 'SregU64 sdst;', - 'SregU32 m0;', - 'SregU64 ssrc;' - ], - 'Inst_SOP1__S_MOVRELD_B64' : [ - 'SregU64 sdst;', - 'SregU32 m0;', - 'SregU64 ssrc;' - ], - 'Inst_VOP2__V_MADMK_F32' : [ - 'SregU64 exec;', - 'VregF32 vdst;', - 'VregF32 src_0;', - 'SregF32 k;', - 'VregF32 src_2;' - ], - 'Inst_VOP2__V_MADAK_F32' : [ - 'SregU64 exec;', - 'VregF32 vdst;', - 'VregF32 src_0;', - 'VregF32 src_1;', - 'SregF32 k;' - ], - 'Inst_VOP2__V_MADMK_F16' : [ - 'SregU64 exec;', - 'VregF16 vdst;', - 'VregF16 src_0;', - 'SregF16 k;', - 'VregF16 src_2;' - ], - 'Inst_VOP2__V_MADAK_F16' : [ - 'SregU64 exec;', - 'VregF16 vdst;', - 'VregF16 src_0;', - 'VregF16 src_1;', - 'SregF16 k;' - ], - 'Inst_VOP3__V_MAD_U64_U32' : [ - 'SregU64 exec;', - 'SregU64 vcc;', - 'VregU64 vdst;', - 'VregU32 src_0;', - 'VregU32 src_1;', - 'VregU64 src_2;' - ], - 'Inst_VOP3__V_MAD_I64_I32' : [ - 'SregU64 exec;', - 'SregU64 vcc;', - 'VregI64 vdst;', - 'VregI32 src_0;', - 'VregI32 src_1;', - 'VregI64 src_2;' - ], - 'Inst_DS__DS_WRITE_B96' : [ - 'SregU64 exec;', - 'VregU32 vmem_0;', - 'VregU32 vgpr_a;', - 'VregU32 vmem_1;', - 'VregU32 vmem_2;', - 'VregU96 vgpr_d0;' - ], - 'Inst_DS__DS_WRITE_B128' : [ - 'SregU64 exec;', - 'VregU32 vmem_0;', - 'VregU32 vgpr_a;', - 'VregU32 vmem_1;', - 'VregU32 vmem_2;', - 'VregU32 vmem_3;', - 'VregU128 vgpr_d0;' - ] -} - -HandCodedPrototypes = [ - ['void', 'ExecNOP', 'GPUDynInstPtr', 'uint32_t'], - ['void', 'ExecEndPgm', 'GPUDynInstPtr'], - ['void', 'ExecEndPgmSaved', 'GPUDynInstPtr'], - ['VregI64&', 'getSRC_SIMPLE_I64', 'GPUDynInstPtr', 'uint32_t'] -] - -HandCodedStaticInstMethods = [ - ['SregI32&', 'ViGPUStaticInst', 'getSSrcLiteral_I32', [], [], - [ - 'static SregI32 sreg;', - 'sreg = 0;', - 'return sreg;' - ] - ], - [ 'SregU32 &', 'ViGPUStaticInst', 'getSSrcLiteral_U32', [], [], - [ - 'static SregU32 sreg;', - 'sreg = 0;', - 'return sreg;' - ] - ], - [ 'VregI32 &', 'ViGPUStaticInst', 'getVSrcLiteral_I32', [], [], - [ - 'static VregI32 vreg;', - 'vreg = getSSrcLiteral_I32();', - 'return vreg;' - ] - ], - [ 'VregU32 &', 'ViGPUStaticInst', 'getVSrcLiteral_U32', [], [], - [ - 'static VregU32 vreg;', - 'vreg = getSSrcLiteral_U32();', - 'return vreg;' - ] - ] -] - -HandCodedInstProlog = { - 'getSSRC_I32' : [ - 'if (arg2 == REG_SRC_LITERAL)', - ' return getSSrcLiteral_I32();' - ], - 'getSSRC_U32' : [ - 'if (arg2 == REG_SRC_LITERAL)', - ' return getSSrcLiteral_U32();' - ], - 'getSRC_I32' : [ - 'if (arg2 == REG_SRC_LITERAL)', - ' return getVSrcLiteral_I32();' - ], - 'getSRC_U32' : [ - 'if (arg2 == REG_SRC_LITERAL)', - ' return getVSrcLiteral_U32();' - ] -}