arch: Split the operand types out of the ISA parser.
authorGabe Black <gabeblack@google.com>
Tue, 29 Sep 2020 07:49:22 +0000 (00:49 -0700)
committerGabe Black <gabeblack@google.com>
Mon, 12 Oct 2020 04:28:37 +0000 (04:28 +0000)
These conceptually go together and don't depend on any other parts of
the parser.

Change-Id: Ia8bff0d0ec210bdeeb080808968faf9528ee03dd
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35278
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/isa_parser/isa_parser.py
src/arch/isa_parser/operand_types.py [new file with mode: 0755]

index 955d4e276f6fbb3a1a664147ec448665757453eb..c147caf6223487d5e88af192ff95c5b61af92ee9 100755 (executable)
@@ -46,6 +46,7 @@ import inspect, traceback
 from types import *
 
 from m5.util.grammar import Grammar
+from .operand_types import *
 
 debug=False
 
@@ -390,737 +391,6 @@ def makeList(arg):
     else:
         return [ arg ]
 
-class Operand(object):
-    '''Base class for operand descriptors.  An instance of this class
-    (or actually a class derived from this one) represents a specific
-    operand for a code block (e.g, "Rc.sq" as a dest). Intermediate
-    derived classes encapsulates the traits of a particular operand
-    type (e.g., "32-bit integer register").'''
-
-    def buildReadCode(self, func = None):
-        subst_dict = {"name": self.base_name,
-                      "func": func,
-                      "reg_idx": self.reg_spec,
-                      "ctype": self.ctype}
-        if hasattr(self, 'src_reg_idx'):
-            subst_dict['op_idx'] = self.src_reg_idx
-        code = self.read_code % subst_dict
-        return '%s = %s;\n' % (self.base_name, code)
-
-    def buildWriteCode(self, func = None):
-        subst_dict = {"name": self.base_name,
-                      "func": func,
-                      "reg_idx": self.reg_spec,
-                      "ctype": self.ctype,
-                      "final_val": self.base_name}
-        if hasattr(self, 'dest_reg_idx'):
-            subst_dict['op_idx'] = self.dest_reg_idx
-        code = self.write_code % subst_dict
-        return '''
-        {
-            %s final_val = %s;
-            %s;
-            if (traceData) { traceData->setData(final_val); }
-        }''' % (self.dflt_ctype, self.base_name, code)
-
-    def __init__(self, parser, full_name, ext, is_src, is_dest):
-        self.full_name = full_name
-        self.ext = ext
-        self.is_src = is_src
-        self.is_dest = is_dest
-        # The 'effective extension' (eff_ext) is either the actual
-        # extension, if one was explicitly provided, or the default.
-        if ext:
-            self.eff_ext = ext
-        elif hasattr(self, 'dflt_ext'):
-            self.eff_ext = self.dflt_ext
-
-        if hasattr(self, 'eff_ext'):
-            self.ctype = parser.operandTypeMap[self.eff_ext]
-
-    # Finalize additional fields (primarily code fields).  This step
-    # is done separately since some of these fields may depend on the
-    # register index enumeration that hasn't been performed yet at the
-    # time of __init__(). The register index enumeration is affected
-    # by predicated register reads/writes. Hence, we forward the flags
-    # that indicate whether or not predication is in use.
-    def finalize(self, predRead, predWrite):
-        self.flags = self.getFlags()
-        self.constructor = self.makeConstructor(predRead, predWrite)
-        self.op_decl = self.makeDecl()
-
-        if self.is_src:
-            self.op_rd = self.makeRead(predRead)
-            self.op_src_decl = self.makeDecl()
-        else:
-            self.op_rd = ''
-            self.op_src_decl = ''
-
-        if self.is_dest:
-            self.op_wb = self.makeWrite(predWrite)
-            self.op_dest_decl = self.makeDecl()
-        else:
-            self.op_wb = ''
-            self.op_dest_decl = ''
-
-    def isMem(self):
-        return 0
-
-    def isReg(self):
-        return 0
-
-    def isFloatReg(self):
-        return 0
-
-    def isIntReg(self):
-        return 0
-
-    def isCCReg(self):
-        return 0
-
-    def isControlReg(self):
-        return 0
-
-    def isVecReg(self):
-        return 0
-
-    def isVecElem(self):
-        return 0
-
-    def isVecPredReg(self):
-        return 0
-
-    def isPCState(self):
-        return 0
-
-    def isPCPart(self):
-        return self.isPCState() and self.reg_spec
-
-    def hasReadPred(self):
-        return self.read_predicate != None
-
-    def hasWritePred(self):
-        return self.write_predicate != None
-
-    def getFlags(self):
-        # note the empty slice '[:]' gives us a copy of self.flags[0]
-        # instead of a reference to it
-        my_flags = self.flags[0][:]
-        if self.is_src:
-            my_flags += self.flags[1]
-        if self.is_dest:
-            my_flags += self.flags[2]
-        return my_flags
-
-    def makeDecl(self):
-        # Note that initializations in the declarations are solely
-        # to avoid 'uninitialized variable' errors from the compiler.
-        return self.ctype + ' ' + self.base_name + ' = 0;\n';
-
-
-src_reg_constructor = '\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s);'
-dst_reg_constructor = '\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s);'
-
-
-class IntRegOperand(Operand):
-    reg_class = 'IntRegClass'
-
-    def isReg(self):
-        return 1
-
-    def isIntReg(self):
-        return 1
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        if self.is_src:
-            c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
-            if self.hasReadPred():
-                c_src = '\n\tif (%s) {%s\n\t}' % \
-                        (self.read_predicate, c_src)
-
-        if self.is_dest:
-            c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
-            c_dest += '\n\t_numIntDestRegs++;'
-            if self.hasWritePred():
-                c_dest = '\n\tif (%s) {%s\n\t}' % \
-                         (self.write_predicate, c_dest)
-
-        return c_src + c_dest
-
-    def makeRead(self, predRead):
-        if (self.ctype == 'float' or self.ctype == 'double'):
-            error('Attempt to read integer register as FP')
-        if self.read_code != None:
-            return self.buildReadCode('readIntRegOperand')
-
-        int_reg_val = ''
-        if predRead:
-            int_reg_val = 'xc->readIntRegOperand(this, _sourceIndex++)'
-            if self.hasReadPred():
-                int_reg_val = '(%s) ? %s : 0' % \
-                              (self.read_predicate, int_reg_val)
-        else:
-            int_reg_val = 'xc->readIntRegOperand(this, %d)' % self.src_reg_idx
-
-        return '%s = %s;\n' % (self.base_name, int_reg_val)
-
-    def makeWrite(self, predWrite):
-        if (self.ctype == 'float' or self.ctype == 'double'):
-            error('Attempt to write integer register as FP')
-        if self.write_code != None:
-            return self.buildWriteCode('setIntRegOperand')
-
-        if predWrite:
-            wp = 'true'
-            if self.hasWritePred():
-                wp = self.write_predicate
-
-            wcond = 'if (%s)' % (wp)
-            windex = '_destIndex++'
-        else:
-            wcond = ''
-            windex = '%d' % self.dest_reg_idx
-
-        wb = '''
-        %s
-        {
-            %s final_val = %s;
-            xc->setIntRegOperand(this, %s, final_val);\n
-            if (traceData) { traceData->setData(final_val); }
-        }''' % (wcond, self.ctype, self.base_name, windex)
-
-        return wb
-
-class FloatRegOperand(Operand):
-    reg_class = 'FloatRegClass'
-
-    def isReg(self):
-        return 1
-
-    def isFloatReg(self):
-        return 1
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        if self.is_src:
-            c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
-
-        if self.is_dest:
-            c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
-            c_dest += '\n\t_numFPDestRegs++;'
-
-        return c_src + c_dest
-
-    def makeRead(self, predRead):
-        if self.read_code != None:
-            return self.buildReadCode('readFloatRegOperandBits')
-
-        if predRead:
-            rindex = '_sourceIndex++'
-        else:
-            rindex = '%d' % self.src_reg_idx
-
-        code = 'xc->readFloatRegOperandBits(this, %s)' % rindex
-        if self.ctype == 'float':
-            code = 'bitsToFloat32(%s)' % code
-        elif self.ctype == 'double':
-            code = 'bitsToFloat64(%s)' % code
-        return '%s = %s;\n' % (self.base_name, code)
-
-    def makeWrite(self, predWrite):
-        if self.write_code != None:
-            return self.buildWriteCode('setFloatRegOperandBits')
-
-        if predWrite:
-            wp = '_destIndex++'
-        else:
-            wp = '%d' % self.dest_reg_idx
-
-        val = 'final_val'
-        if self.ctype == 'float':
-            val = 'floatToBits32(%s)' % val
-        elif self.ctype == 'double':
-            val = 'floatToBits64(%s)' % val
-
-        wp = 'xc->setFloatRegOperandBits(this, %s, %s);' % (wp, val)
-
-        wb = '''
-        {
-            %s final_val = %s;
-            %s\n
-            if (traceData) { traceData->setData(final_val); }
-        }''' % (self.ctype, self.base_name, wp)
-        return wb
-
-class VecRegOperand(Operand):
-    reg_class = 'VecRegClass'
-
-    def __init__(self, parser, full_name, ext, is_src, is_dest):
-        Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
-        self.elemExt = None
-        self.parser = parser
-
-    def isReg(self):
-        return 1
-
-    def isVecReg(self):
-        return 1
-
-    def makeDeclElem(self, elem_op):
-        (elem_name, elem_ext) = elem_op
-        (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
-        if elem_ext:
-            ext = elem_ext
-        else:
-            ext = dflt_elem_ext
-        ctype = self.parser.operandTypeMap[ext]
-        return '\n\t%s %s = 0;' % (ctype, elem_name)
-
-    def makeDecl(self):
-        if not self.is_dest and self.is_src:
-            c_decl = '\t/* Vars for %s*/' % (self.base_name)
-            if hasattr(self, 'active_elems'):
-                if self.active_elems:
-                    for elem in self.active_elems:
-                        c_decl += self.makeDeclElem(elem)
-            return c_decl + '\t/* End vars for %s */\n' % (self.base_name)
-        else:
-            return ''
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        numAccessNeeded = 1
-
-        if self.is_src:
-            c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
-
-        if self.is_dest:
-            c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
-            c_dest += '\n\t_numVecDestRegs++;'
-
-        return c_src + c_dest
-
-    # Read destination register to write
-    def makeReadWElem(self, elem_op):
-        (elem_name, elem_ext) = elem_op
-        (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
-        if elem_ext:
-            ext = elem_ext
-        else:
-            ext = dflt_elem_ext
-        ctype = self.parser.operandTypeMap[ext]
-        c_read = '\t\t%s& %s = %s[%s];\n' % \
-                  (ctype, elem_name, self.base_name, elem_spec)
-        return c_read
-
-    def makeReadW(self, predWrite):
-        func = 'getWritableVecRegOperand'
-        if self.read_code != None:
-            return self.buildReadCode(func)
-
-        if predWrite:
-            rindex = '_destIndex++'
-        else:
-            rindex = '%d' % self.dest_reg_idx
-
-        c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n'\
-                % ('TheISA::VecRegContainer', rindex, func, rindex)
-        if self.elemExt:
-            c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
-                        rindex, self.parser.operandTypeMap[self.elemExt])
-        if self.ext:
-            c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
-                        rindex, self.parser.operandTypeMap[self.ext])
-        if hasattr(self, 'active_elems'):
-            if self.active_elems:
-                for elem in self.active_elems:
-                    c_readw += self.makeReadWElem(elem)
-        return c_readw
-
-    # Normal source operand read
-    def makeReadElem(self, elem_op, name):
-        (elem_name, elem_ext) = elem_op
-        (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
-
-        if elem_ext:
-            ext = elem_ext
-        else:
-            ext = dflt_elem_ext
-        ctype = self.parser.operandTypeMap[ext]
-        c_read = '\t\t%s = %s[%s];\n' % \
-                  (elem_name, name, elem_spec)
-        return c_read
-
-    def makeRead(self, predRead):
-        func = 'readVecRegOperand'
-        if self.read_code != None:
-            return self.buildReadCode(func)
-
-        if predRead:
-            rindex = '_sourceIndex++'
-        else:
-            rindex = '%d' % self.src_reg_idx
-
-        name = self.base_name
-        if self.is_dest and self.is_src:
-            name += '_merger'
-
-        c_read =  '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' \
-                % ('const TheISA::VecRegContainer', rindex, func, rindex)
-        # If the parser has detected that elements are being access, create
-        # the appropriate view
-        if self.elemExt:
-            c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
-                 (name, rindex, self.parser.operandTypeMap[self.elemExt])
-        if self.ext:
-            c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
-                 (name, rindex, self.parser.operandTypeMap[self.ext])
-        if hasattr(self, 'active_elems'):
-            if self.active_elems:
-                for elem in self.active_elems:
-                    c_read += self.makeReadElem(elem, name)
-        return c_read
-
-    def makeWrite(self, predWrite):
-        func = 'setVecRegOperand'
-        if self.write_code != None:
-            return self.buildWriteCode(func)
-
-        wb = '''
-        if (traceData) {
-            traceData->setData(tmp_d%d);
-        }
-        ''' % self.dest_reg_idx
-        return wb
-
-    def finalize(self, predRead, predWrite):
-        super(VecRegOperand, self).finalize(predRead, predWrite)
-        if self.is_dest:
-            self.op_rd = self.makeReadW(predWrite) + self.op_rd
-
-class VecElemOperand(Operand):
-    reg_class = 'VecElemClass'
-
-    def isReg(self):
-        return 1
-
-    def isVecElem(self):
-        return 1
-
-    def makeDecl(self):
-        if self.is_dest and not self.is_src:
-            return '\n\t%s %s;' % (self.ctype, self.base_name)
-        else:
-            return ''
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        numAccessNeeded = 1
-
-        if self.is_src:
-            c_src = ('\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s, %s);' %
-                    (self.reg_class, self.reg_spec, self.elem_spec))
-
-        if self.is_dest:
-            c_dest = ('\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s, %s);' %
-                    (self.reg_class, self.reg_spec, self.elem_spec))
-            c_dest += '\n\t_numVecElemDestRegs++;'
-        return c_src + c_dest
-
-    def makeRead(self, predRead):
-        c_read = 'xc->readVecElemOperand(this, %d)' % self.src_reg_idx
-
-        if self.ctype == 'float':
-            c_read = 'bitsToFloat32(%s)' % c_read
-        elif self.ctype == 'double':
-            c_read = 'bitsToFloat64(%s)' % c_read
-
-        return '\n\t%s %s = %s;\n' % (self.ctype, self.base_name, c_read)
-
-    def makeWrite(self, predWrite):
-        if self.ctype == 'float':
-            c_write = 'floatToBits32(%s)' % self.base_name
-        elif self.ctype == 'double':
-            c_write = 'floatToBits64(%s)' % self.base_name
-        else:
-            c_write = self.base_name
-
-        c_write = ('\n\txc->setVecElemOperand(this, %d, %s);' %
-                  (self.dest_reg_idx, c_write))
-
-        return c_write
-
-class VecPredRegOperand(Operand):
-    reg_class = 'VecPredRegClass'
-
-    def __init__(self, parser, full_name, ext, is_src, is_dest):
-        Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
-        self.parser = parser
-
-    def isReg(self):
-        return 1
-
-    def isVecPredReg(self):
-        return 1
-
-    def makeDecl(self):
-        return ''
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        if self.is_src:
-            c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
-
-        if self.is_dest:
-            c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
-            c_dest += '\n\t_numVecPredDestRegs++;'
-
-        return c_src + c_dest
-
-    def makeRead(self, predRead):
-        func = 'readVecPredRegOperand'
-        if self.read_code != None:
-            return self.buildReadCode(func)
-
-        if predRead:
-            rindex = '_sourceIndex++'
-        else:
-            rindex = '%d' % self.src_reg_idx
-
-        c_read =  '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' % (
-                'const TheISA::VecPredRegContainer', rindex, func, rindex)
-        if self.ext:
-            c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % (
-                    self.base_name, rindex,
-                    self.parser.operandTypeMap[self.ext])
-        return c_read
-
-    def makeReadW(self, predWrite):
-        func = 'getWritableVecPredRegOperand'
-        if self.read_code != None:
-            return self.buildReadCode(func)
-
-        if predWrite:
-            rindex = '_destIndex++'
-        else:
-            rindex = '%d' % self.dest_reg_idx
-
-        c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n' % (
-                'TheISA::VecPredRegContainer', rindex, func, rindex)
-        if self.ext:
-            c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (
-                    self.base_name, rindex,
-                    self.parser.operandTypeMap[self.ext])
-        return c_readw
-
-    def makeWrite(self, predWrite):
-        func = 'setVecPredRegOperand'
-        if self.write_code != None:
-            return self.buildWriteCode(func)
-
-        wb = '''
-        if (traceData) {
-            traceData->setData(tmp_d%d);
-        }
-        ''' % self.dest_reg_idx
-        return wb
-
-    def finalize(self, predRead, predWrite):
-        super(VecPredRegOperand, self).finalize(predRead, predWrite)
-        if self.is_dest:
-            self.op_rd = self.makeReadW(predWrite) + self.op_rd
-
-class CCRegOperand(Operand):
-    reg_class = 'CCRegClass'
-
-    def isReg(self):
-        return 1
-
-    def isCCReg(self):
-        return 1
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        if self.is_src:
-            c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
-            if self.hasReadPred():
-                c_src = '\n\tif (%s) {%s\n\t}' % \
-                        (self.read_predicate, c_src)
-
-        if self.is_dest:
-            c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
-            c_dest += '\n\t_numCCDestRegs++;'
-            if self.hasWritePred():
-                c_dest = '\n\tif (%s) {%s\n\t}' % \
-                         (self.write_predicate, c_dest)
-
-        return c_src + c_dest
-
-    def makeRead(self, predRead):
-        if (self.ctype == 'float' or self.ctype == 'double'):
-            error('Attempt to read condition-code register as FP')
-        if self.read_code != None:
-            return self.buildReadCode('readCCRegOperand')
-
-        int_reg_val = ''
-        if predRead:
-            int_reg_val = 'xc->readCCRegOperand(this, _sourceIndex++)'
-            if self.hasReadPred():
-                int_reg_val = '(%s) ? %s : 0' % \
-                              (self.read_predicate, int_reg_val)
-        else:
-            int_reg_val = 'xc->readCCRegOperand(this, %d)' % self.src_reg_idx
-
-        return '%s = %s;\n' % (self.base_name, int_reg_val)
-
-    def makeWrite(self, predWrite):
-        if (self.ctype == 'float' or self.ctype == 'double'):
-            error('Attempt to write condition-code register as FP')
-        if self.write_code != None:
-            return self.buildWriteCode('setCCRegOperand')
-
-        if predWrite:
-            wp = 'true'
-            if self.hasWritePred():
-                wp = self.write_predicate
-
-            wcond = 'if (%s)' % (wp)
-            windex = '_destIndex++'
-        else:
-            wcond = ''
-            windex = '%d' % self.dest_reg_idx
-
-        wb = '''
-        %s
-        {
-            %s final_val = %s;
-            xc->setCCRegOperand(this, %s, final_val);\n
-            if (traceData) { traceData->setData(final_val); }
-        }''' % (wcond, self.ctype, self.base_name, windex)
-
-        return wb
-
-class ControlRegOperand(Operand):
-    reg_class = 'MiscRegClass'
-
-    def isReg(self):
-        return 1
-
-    def isControlReg(self):
-        return 1
-
-    def makeConstructor(self, predRead, predWrite):
-        c_src = ''
-        c_dest = ''
-
-        if self.is_src:
-            c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
-
-        if self.is_dest:
-            c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
-
-        return c_src + c_dest
-
-    def makeRead(self, predRead):
-        bit_select = 0
-        if (self.ctype == 'float' or self.ctype == 'double'):
-            error('Attempt to read control register as FP')
-        if self.read_code != None:
-            return self.buildReadCode('readMiscRegOperand')
-
-        if predRead:
-            rindex = '_sourceIndex++'
-        else:
-            rindex = '%d' % self.src_reg_idx
-
-        return '%s = xc->readMiscRegOperand(this, %s);\n' % \
-            (self.base_name, rindex)
-
-    def makeWrite(self, predWrite):
-        if (self.ctype == 'float' or self.ctype == 'double'):
-            error('Attempt to write control register as FP')
-        if self.write_code != None:
-            return self.buildWriteCode('setMiscRegOperand')
-
-        if predWrite:
-            windex = '_destIndex++'
-        else:
-            windex = '%d' % self.dest_reg_idx
-
-        wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \
-             (windex, self.base_name)
-        wb += 'if (traceData) { traceData->setData(%s); }' % \
-              self.base_name
-
-        return wb
-
-class MemOperand(Operand):
-    def isMem(self):
-        return 1
-
-    def makeConstructor(self, predRead, predWrite):
-        return ''
-
-    def makeDecl(self):
-        # Declare memory data variable.
-        return '%s %s = {};\n' % (self.ctype, self.base_name)
-
-    def makeRead(self, predRead):
-        if self.read_code != None:
-            return self.buildReadCode()
-        return ''
-
-    def makeWrite(self, predWrite):
-        if self.write_code != None:
-            return self.buildWriteCode()
-        return ''
-
-class PCStateOperand(Operand):
-    def makeConstructor(self, predRead, predWrite):
-        return ''
-
-    def makeRead(self, predRead):
-        if self.reg_spec:
-            # A component of the PC state.
-            return '%s = __parserAutoPCState.%s();\n' % \
-                (self.base_name, self.reg_spec)
-        else:
-            # The whole PC state itself.
-            return '%s = xc->pcState();\n' % self.base_name
-
-    def makeWrite(self, predWrite):
-        if self.reg_spec:
-            # A component of the PC state.
-            return '__parserAutoPCState.%s(%s);\n' % \
-                (self.reg_spec, self.base_name)
-        else:
-            # The whole PC state itself.
-            return 'xc->pcState(%s);\n' % self.base_name
-
-    def makeDecl(self):
-        ctype = 'TheISA::PCState'
-        if self.isPCPart():
-            ctype = self.ctype
-        # Note that initializations in the declarations are solely
-        # to avoid 'uninitialized variable' errors from the compiler.
-        return '%s %s = 0;\n' % (ctype, self.base_name)
-
-    def isPCState(self):
-        return 1
-
 class OperandList(object):
     '''Find all the operands in the given code block.  Returns an operand
     descriptor list (instance of class OperandList).'''
diff --git a/src/arch/isa_parser/operand_types.py b/src/arch/isa_parser/operand_types.py
new file mode 100755 (executable)
index 0000000..cd341d0
--- /dev/null
@@ -0,0 +1,768 @@
+# Copyright (c) 2014, 2016, 2018-2019 ARM Limited
+# All rights reserved
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Copyright (c) 2003-2005 The Regents of The University of Michigan
+# Copyright (c) 2013,2015 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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 Operand(object):
+    '''Base class for operand descriptors.  An instance of this class
+    (or actually a class derived from this one) represents a specific
+    operand for a code block (e.g, "Rc.sq" as a dest). Intermediate
+    derived classes encapsulates the traits of a particular operand
+    type (e.g., "32-bit integer register").'''
+
+    src_reg_constructor = '\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s);'
+    dst_reg_constructor = '\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s);'
+
+    def buildReadCode(self, func = None):
+        subst_dict = {"name": self.base_name,
+                      "func": func,
+                      "reg_idx": self.reg_spec,
+                      "ctype": self.ctype}
+        if hasattr(self, 'src_reg_idx'):
+            subst_dict['op_idx'] = self.src_reg_idx
+        code = self.read_code % subst_dict
+        return '%s = %s;\n' % (self.base_name, code)
+
+    def buildWriteCode(self, func = None):
+        subst_dict = {"name": self.base_name,
+                      "func": func,
+                      "reg_idx": self.reg_spec,
+                      "ctype": self.ctype,
+                      "final_val": self.base_name}
+        if hasattr(self, 'dest_reg_idx'):
+            subst_dict['op_idx'] = self.dest_reg_idx
+        code = self.write_code % subst_dict
+        return '''
+        {
+            %s final_val = %s;
+            %s;
+            if (traceData) { traceData->setData(final_val); }
+        }''' % (self.dflt_ctype, self.base_name, code)
+
+    def __init__(self, parser, full_name, ext, is_src, is_dest):
+        self.full_name = full_name
+        self.ext = ext
+        self.is_src = is_src
+        self.is_dest = is_dest
+        # The 'effective extension' (eff_ext) is either the actual
+        # extension, if one was explicitly provided, or the default.
+        if ext:
+            self.eff_ext = ext
+        elif hasattr(self, 'dflt_ext'):
+            self.eff_ext = self.dflt_ext
+
+        if hasattr(self, 'eff_ext'):
+            self.ctype = parser.operandTypeMap[self.eff_ext]
+
+    # Finalize additional fields (primarily code fields).  This step
+    # is done separately since some of these fields may depend on the
+    # register index enumeration that hasn't been performed yet at the
+    # time of __init__(). The register index enumeration is affected
+    # by predicated register reads/writes. Hence, we forward the flags
+    # that indicate whether or not predication is in use.
+    def finalize(self, predRead, predWrite):
+        self.flags = self.getFlags()
+        self.constructor = self.makeConstructor(predRead, predWrite)
+        self.op_decl = self.makeDecl()
+
+        if self.is_src:
+            self.op_rd = self.makeRead(predRead)
+            self.op_src_decl = self.makeDecl()
+        else:
+            self.op_rd = ''
+            self.op_src_decl = ''
+
+        if self.is_dest:
+            self.op_wb = self.makeWrite(predWrite)
+            self.op_dest_decl = self.makeDecl()
+        else:
+            self.op_wb = ''
+            self.op_dest_decl = ''
+
+    def isMem(self):
+        return 0
+
+    def isReg(self):
+        return 0
+
+    def isFloatReg(self):
+        return 0
+
+    def isIntReg(self):
+        return 0
+
+    def isCCReg(self):
+        return 0
+
+    def isControlReg(self):
+        return 0
+
+    def isVecReg(self):
+        return 0
+
+    def isVecElem(self):
+        return 0
+
+    def isVecPredReg(self):
+        return 0
+
+    def isPCState(self):
+        return 0
+
+    def isPCPart(self):
+        return self.isPCState() and self.reg_spec
+
+    def hasReadPred(self):
+        return self.read_predicate != None
+
+    def hasWritePred(self):
+        return self.write_predicate != None
+
+    def getFlags(self):
+        # note the empty slice '[:]' gives us a copy of self.flags[0]
+        # instead of a reference to it
+        my_flags = self.flags[0][:]
+        if self.is_src:
+            my_flags += self.flags[1]
+        if self.is_dest:
+            my_flags += self.flags[2]
+        return my_flags
+
+    def makeDecl(self):
+        # Note that initializations in the declarations are solely
+        # to avoid 'uninitialized variable' errors from the compiler.
+        return self.ctype + ' ' + self.base_name + ' = 0;\n';
+
+
+class IntRegOperand(Operand):
+    reg_class = 'IntRegClass'
+
+    def isReg(self):
+        return 1
+
+    def isIntReg(self):
+        return 1
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = self.src_reg_constructor % (self.reg_class, self.reg_spec)
+            if self.hasReadPred():
+                c_src = '\n\tif (%s) {%s\n\t}' % \
+                        (self.read_predicate, c_src)
+
+        if self.is_dest:
+            c_dest = self.dst_reg_constructor % (self.reg_class, self.reg_spec)
+            c_dest += '\n\t_numIntDestRegs++;'
+            if self.hasWritePred():
+                c_dest = '\n\tif (%s) {%s\n\t}' % \
+                         (self.write_predicate, c_dest)
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to read integer register as FP')
+        if self.read_code != None:
+            return self.buildReadCode('readIntRegOperand')
+
+        int_reg_val = ''
+        if predRead:
+            int_reg_val = 'xc->readIntRegOperand(this, _sourceIndex++)'
+            if self.hasReadPred():
+                int_reg_val = '(%s) ? %s : 0' % \
+                              (self.read_predicate, int_reg_val)
+        else:
+            int_reg_val = 'xc->readIntRegOperand(this, %d)' % self.src_reg_idx
+
+        return '%s = %s;\n' % (self.base_name, int_reg_val)
+
+    def makeWrite(self, predWrite):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to write integer register as FP')
+        if self.write_code != None:
+            return self.buildWriteCode('setIntRegOperand')
+
+        if predWrite:
+            wp = 'true'
+            if self.hasWritePred():
+                wp = self.write_predicate
+
+            wcond = 'if (%s)' % (wp)
+            windex = '_destIndex++'
+        else:
+            wcond = ''
+            windex = '%d' % self.dest_reg_idx
+
+        wb = '''
+        %s
+        {
+            %s final_val = %s;
+            xc->setIntRegOperand(this, %s, final_val);\n
+            if (traceData) { traceData->setData(final_val); }
+        }''' % (wcond, self.ctype, self.base_name, windex)
+
+        return wb
+
+class FloatRegOperand(Operand):
+    reg_class = 'FloatRegClass'
+
+    def isReg(self):
+        return 1
+
+    def isFloatReg(self):
+        return 1
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = self.src_reg_constructor % (self.reg_class, self.reg_spec)
+
+        if self.is_dest:
+            c_dest = self.dst_reg_constructor % (self.reg_class, self.reg_spec)
+            c_dest += '\n\t_numFPDestRegs++;'
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        if self.read_code != None:
+            return self.buildReadCode('readFloatRegOperandBits')
+
+        if predRead:
+            rindex = '_sourceIndex++'
+        else:
+            rindex = '%d' % self.src_reg_idx
+
+        code = 'xc->readFloatRegOperandBits(this, %s)' % rindex
+        if self.ctype == 'float':
+            code = 'bitsToFloat32(%s)' % code
+        elif self.ctype == 'double':
+            code = 'bitsToFloat64(%s)' % code
+        return '%s = %s;\n' % (self.base_name, code)
+
+    def makeWrite(self, predWrite):
+        if self.write_code != None:
+            return self.buildWriteCode('setFloatRegOperandBits')
+
+        if predWrite:
+            wp = '_destIndex++'
+        else:
+            wp = '%d' % self.dest_reg_idx
+
+        val = 'final_val'
+        if self.ctype == 'float':
+            val = 'floatToBits32(%s)' % val
+        elif self.ctype == 'double':
+            val = 'floatToBits64(%s)' % val
+
+        wp = 'xc->setFloatRegOperandBits(this, %s, %s);' % (wp, val)
+
+        wb = '''
+        {
+            %s final_val = %s;
+            %s\n
+            if (traceData) { traceData->setData(final_val); }
+        }''' % (self.ctype, self.base_name, wp)
+        return wb
+
+class VecRegOperand(Operand):
+    reg_class = 'VecRegClass'
+
+    def __init__(self, parser, full_name, ext, is_src, is_dest):
+        Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
+        self.elemExt = None
+        self.parser = parser
+
+    def isReg(self):
+        return 1
+
+    def isVecReg(self):
+        return 1
+
+    def makeDeclElem(self, elem_op):
+        (elem_name, elem_ext) = elem_op
+        (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
+        if elem_ext:
+            ext = elem_ext
+        else:
+            ext = dflt_elem_ext
+        ctype = self.parser.operandTypeMap[ext]
+        return '\n\t%s %s = 0;' % (ctype, elem_name)
+
+    def makeDecl(self):
+        if not self.is_dest and self.is_src:
+            c_decl = '\t/* Vars for %s*/' % (self.base_name)
+            if hasattr(self, 'active_elems'):
+                if self.active_elems:
+                    for elem in self.active_elems:
+                        c_decl += self.makeDeclElem(elem)
+            return c_decl + '\t/* End vars for %s */\n' % (self.base_name)
+        else:
+            return ''
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        numAccessNeeded = 1
+
+        if self.is_src:
+            c_src = self.src_reg_constructor % (self.reg_class, self.reg_spec)
+
+        if self.is_dest:
+            c_dest = self.dst_reg_constructor % (self.reg_class, self.reg_spec)
+            c_dest += '\n\t_numVecDestRegs++;'
+
+        return c_src + c_dest
+
+    # Read destination register to write
+    def makeReadWElem(self, elem_op):
+        (elem_name, elem_ext) = elem_op
+        (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
+        if elem_ext:
+            ext = elem_ext
+        else:
+            ext = dflt_elem_ext
+        ctype = self.parser.operandTypeMap[ext]
+        c_read = '\t\t%s& %s = %s[%s];\n' % \
+                  (ctype, elem_name, self.base_name, elem_spec)
+        return c_read
+
+    def makeReadW(self, predWrite):
+        func = 'getWritableVecRegOperand'
+        if self.read_code != None:
+            return self.buildReadCode(func)
+
+        if predWrite:
+            rindex = '_destIndex++'
+        else:
+            rindex = '%d' % self.dest_reg_idx
+
+        c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n'\
+                % ('TheISA::VecRegContainer', rindex, func, rindex)
+        if self.elemExt:
+            c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
+                        rindex, self.parser.operandTypeMap[self.elemExt])
+        if self.ext:
+            c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
+                        rindex, self.parser.operandTypeMap[self.ext])
+        if hasattr(self, 'active_elems'):
+            if self.active_elems:
+                for elem in self.active_elems:
+                    c_readw += self.makeReadWElem(elem)
+        return c_readw
+
+    # Normal source operand read
+    def makeReadElem(self, elem_op, name):
+        (elem_name, elem_ext) = elem_op
+        (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
+
+        if elem_ext:
+            ext = elem_ext
+        else:
+            ext = dflt_elem_ext
+        ctype = self.parser.operandTypeMap[ext]
+        c_read = '\t\t%s = %s[%s];\n' % \
+                  (elem_name, name, elem_spec)
+        return c_read
+
+    def makeRead(self, predRead):
+        func = 'readVecRegOperand'
+        if self.read_code != None:
+            return self.buildReadCode(func)
+
+        if predRead:
+            rindex = '_sourceIndex++'
+        else:
+            rindex = '%d' % self.src_reg_idx
+
+        name = self.base_name
+        if self.is_dest and self.is_src:
+            name += '_merger'
+
+        c_read =  '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' \
+                % ('const TheISA::VecRegContainer', rindex, func, rindex)
+        # If the parser has detected that elements are being access, create
+        # the appropriate view
+        if self.elemExt:
+            c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
+                 (name, rindex, self.parser.operandTypeMap[self.elemExt])
+        if self.ext:
+            c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
+                 (name, rindex, self.parser.operandTypeMap[self.ext])
+        if hasattr(self, 'active_elems'):
+            if self.active_elems:
+                for elem in self.active_elems:
+                    c_read += self.makeReadElem(elem, name)
+        return c_read
+
+    def makeWrite(self, predWrite):
+        func = 'setVecRegOperand'
+        if self.write_code != None:
+            return self.buildWriteCode(func)
+
+        wb = '''
+        if (traceData) {
+            traceData->setData(tmp_d%d);
+        }
+        ''' % self.dest_reg_idx
+        return wb
+
+    def finalize(self, predRead, predWrite):
+        super(VecRegOperand, self).finalize(predRead, predWrite)
+        if self.is_dest:
+            self.op_rd = self.makeReadW(predWrite) + self.op_rd
+
+class VecElemOperand(Operand):
+    reg_class = 'VecElemClass'
+
+    def isReg(self):
+        return 1
+
+    def isVecElem(self):
+        return 1
+
+    def makeDecl(self):
+        if self.is_dest and not self.is_src:
+            return '\n\t%s %s;' % (self.ctype, self.base_name)
+        else:
+            return ''
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        numAccessNeeded = 1
+
+        if self.is_src:
+            c_src = ('\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s, %s);' %
+                    (self.reg_class, self.reg_spec, self.elem_spec))
+
+        if self.is_dest:
+            c_dest = ('\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s, %s);' %
+                    (self.reg_class, self.reg_spec, self.elem_spec))
+            c_dest += '\n\t_numVecElemDestRegs++;'
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        c_read = 'xc->readVecElemOperand(this, %d)' % self.src_reg_idx
+
+        if self.ctype == 'float':
+            c_read = 'bitsToFloat32(%s)' % c_read
+        elif self.ctype == 'double':
+            c_read = 'bitsToFloat64(%s)' % c_read
+
+        return '\n\t%s %s = %s;\n' % (self.ctype, self.base_name, c_read)
+
+    def makeWrite(self, predWrite):
+        if self.ctype == 'float':
+            c_write = 'floatToBits32(%s)' % self.base_name
+        elif self.ctype == 'double':
+            c_write = 'floatToBits64(%s)' % self.base_name
+        else:
+            c_write = self.base_name
+
+        c_write = ('\n\txc->setVecElemOperand(this, %d, %s);' %
+                  (self.dest_reg_idx, c_write))
+
+        return c_write
+
+class VecPredRegOperand(Operand):
+    reg_class = 'VecPredRegClass'
+
+    def __init__(self, parser, full_name, ext, is_src, is_dest):
+        Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
+        self.parser = parser
+
+    def isReg(self):
+        return 1
+
+    def isVecPredReg(self):
+        return 1
+
+    def makeDecl(self):
+        return ''
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = self.src_reg_constructor % (self.reg_class, self.reg_spec)
+
+        if self.is_dest:
+            c_dest = self.dst_reg_constructor % (self.reg_class, self.reg_spec)
+            c_dest += '\n\t_numVecPredDestRegs++;'
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        func = 'readVecPredRegOperand'
+        if self.read_code != None:
+            return self.buildReadCode(func)
+
+        if predRead:
+            rindex = '_sourceIndex++'
+        else:
+            rindex = '%d' % self.src_reg_idx
+
+        c_read =  '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' % (
+                'const TheISA::VecPredRegContainer', rindex, func, rindex)
+        if self.ext:
+            c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % (
+                    self.base_name, rindex,
+                    self.parser.operandTypeMap[self.ext])
+        return c_read
+
+    def makeReadW(self, predWrite):
+        func = 'getWritableVecPredRegOperand'
+        if self.read_code != None:
+            return self.buildReadCode(func)
+
+        if predWrite:
+            rindex = '_destIndex++'
+        else:
+            rindex = '%d' % self.dest_reg_idx
+
+        c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n' % (
+                'TheISA::VecPredRegContainer', rindex, func, rindex)
+        if self.ext:
+            c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (
+                    self.base_name, rindex,
+                    self.parser.operandTypeMap[self.ext])
+        return c_readw
+
+    def makeWrite(self, predWrite):
+        func = 'setVecPredRegOperand'
+        if self.write_code != None:
+            return self.buildWriteCode(func)
+
+        wb = '''
+        if (traceData) {
+            traceData->setData(tmp_d%d);
+        }
+        ''' % self.dest_reg_idx
+        return wb
+
+    def finalize(self, predRead, predWrite):
+        super(VecPredRegOperand, self).finalize(predRead, predWrite)
+        if self.is_dest:
+            self.op_rd = self.makeReadW(predWrite) + self.op_rd
+
+class CCRegOperand(Operand):
+    reg_class = 'CCRegClass'
+
+    def isReg(self):
+        return 1
+
+    def isCCReg(self):
+        return 1
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = self.src_reg_constructor % (self.reg_class, self.reg_spec)
+            if self.hasReadPred():
+                c_src = '\n\tif (%s) {%s\n\t}' % \
+                        (self.read_predicate, c_src)
+
+        if self.is_dest:
+            c_dest = self.dst_reg_constructor % (self.reg_class, self.reg_spec)
+            c_dest += '\n\t_numCCDestRegs++;'
+            if self.hasWritePred():
+                c_dest = '\n\tif (%s) {%s\n\t}' % \
+                         (self.write_predicate, c_dest)
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to read condition-code register as FP')
+        if self.read_code != None:
+            return self.buildReadCode('readCCRegOperand')
+
+        int_reg_val = ''
+        if predRead:
+            int_reg_val = 'xc->readCCRegOperand(this, _sourceIndex++)'
+            if self.hasReadPred():
+                int_reg_val = '(%s) ? %s : 0' % \
+                              (self.read_predicate, int_reg_val)
+        else:
+            int_reg_val = 'xc->readCCRegOperand(this, %d)' % self.src_reg_idx
+
+        return '%s = %s;\n' % (self.base_name, int_reg_val)
+
+    def makeWrite(self, predWrite):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to write condition-code register as FP')
+        if self.write_code != None:
+            return self.buildWriteCode('setCCRegOperand')
+
+        if predWrite:
+            wp = 'true'
+            if self.hasWritePred():
+                wp = self.write_predicate
+
+            wcond = 'if (%s)' % (wp)
+            windex = '_destIndex++'
+        else:
+            wcond = ''
+            windex = '%d' % self.dest_reg_idx
+
+        wb = '''
+        %s
+        {
+            %s final_val = %s;
+            xc->setCCRegOperand(this, %s, final_val);\n
+            if (traceData) { traceData->setData(final_val); }
+        }''' % (wcond, self.ctype, self.base_name, windex)
+
+        return wb
+
+class ControlRegOperand(Operand):
+    reg_class = 'MiscRegClass'
+
+    def isReg(self):
+        return 1
+
+    def isControlReg(self):
+        return 1
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = self.src_reg_constructor % (self.reg_class, self.reg_spec)
+
+        if self.is_dest:
+            c_dest = self.dst_reg_constructor % (self.reg_class, self.reg_spec)
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        bit_select = 0
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to read control register as FP')
+        if self.read_code != None:
+            return self.buildReadCode('readMiscRegOperand')
+
+        if predRead:
+            rindex = '_sourceIndex++'
+        else:
+            rindex = '%d' % self.src_reg_idx
+
+        return '%s = xc->readMiscRegOperand(this, %s);\n' % \
+            (self.base_name, rindex)
+
+    def makeWrite(self, predWrite):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to write control register as FP')
+        if self.write_code != None:
+            return self.buildWriteCode('setMiscRegOperand')
+
+        if predWrite:
+            windex = '_destIndex++'
+        else:
+            windex = '%d' % self.dest_reg_idx
+
+        wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \
+             (windex, self.base_name)
+        wb += 'if (traceData) { traceData->setData(%s); }' % \
+              self.base_name
+
+        return wb
+
+class MemOperand(Operand):
+    def isMem(self):
+        return 1
+
+    def makeConstructor(self, predRead, predWrite):
+        return ''
+
+    def makeDecl(self):
+        # Declare memory data variable.
+        return '%s %s = {};\n' % (self.ctype, self.base_name)
+
+    def makeRead(self, predRead):
+        if self.read_code != None:
+            return self.buildReadCode()
+        return ''
+
+    def makeWrite(self, predWrite):
+        if self.write_code != None:
+            return self.buildWriteCode()
+        return ''
+
+class PCStateOperand(Operand):
+    def makeConstructor(self, predRead, predWrite):
+        return ''
+
+    def makeRead(self, predRead):
+        if self.reg_spec:
+            # A component of the PC state.
+            return '%s = __parserAutoPCState.%s();\n' % \
+                (self.base_name, self.reg_spec)
+        else:
+            # The whole PC state itself.
+            return '%s = xc->pcState();\n' % self.base_name
+
+    def makeWrite(self, predWrite):
+        if self.reg_spec:
+            # A component of the PC state.
+            return '__parserAutoPCState.%s(%s);\n' % \
+                (self.reg_spec, self.base_name)
+        else:
+            # The whole PC state itself.
+            return 'xc->pcState(%s);\n' % self.base_name
+
+    def makeDecl(self):
+        ctype = 'TheISA::PCState'
+        if self.isPCPart():
+            ctype = self.ctype
+        # Note that initializations in the declarations are solely
+        # to avoid 'uninitialized variable' errors from the compiler.
+        return '%s %s = 0;\n' % (ctype, self.base_name)
+
+    def isPCState(self):
+        return 1