# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import re
from typing import List, Optional, Tuple

from serialize.parse_helpers import (check_bool, check_keys, check_str,
                                     get_optional_str)

from .encoding import Encoding
from .encoding_scheme import EncSchemeField


class OperandType:
    '''The base class for some sort of operand type

    There are three representations of an operand:

        - String
        - Operand value
        - Encoded value

    The string representation is the string that you expect to see in an
    assembly listing (either fed into otbn_as.py, or generated by
    otbn_objdump.py). The encoded value is the non-negative integer value that
    is encoded in the bits of the instruction.

    The operand value is the notional value of the operand. This might be a
    signed value (represented 2's complement in the encoded value). It might be
    shifted left by some places. This is the "value of the operand" that is
    described in the documentation.

    For a register operand, the string value might be "x3" and the operand
    value and encoded value would both be 3. Similarly, for an enum or option
    operand, the operand value and encoded value are equal.

    For an immediate operand that isn't PC-relative, converting between the
    string and operand value is essentially a call to Python's int() or str().
    The interesting conversion is between operand value and encoded value.

    '''

    def __init__(self, width: Optional[int]) -> None:
        assert width is None or width > 0
        self.width = width

    def markdown_doc(self) -> Optional[str]:
        '''Generate any (markdown) documentation for this operand type

        The base class returns None, but subclasses might return something
        useful.

        '''
        return None

    @staticmethod
    def _describe_bits_lst(bits_lst: List[str]) -> str:
        assert bits_lst
        if len(bits_lst) == 1:
            return bits_lst[0]
        else:
            return '{{{}}}'.format(', '.join(bits_lst))

    def describe_decode(self, bits_lst: List[str]) -> str:
        '''Return string saying how to interpret the raw bits of bits_str

        bits_lst is a nonempty list of string describing which bits are used to
        get the raw value.

        Overridden in subclasses if they do something non-trivial.

        '''
        return 'unsigned({})'.format(OperandType._describe_bits_lst(bits_lst))

    def syntax_determines_value(self) -> bool:
        '''Can the value of this operand always be inferred from asm syntax?

        This is true for things like registers (the value "5" only comes from
        "r5", for example), but false for arbitrary immediates: an immediate
        operand might have a value that comes from a relocation. If this is
        true, neither str_to_op_val nor op_val_to_enc_val may return None.

        '''
        return False

    def str_to_op_val(self, as_str: str) -> Optional[int]:
        '''Read the given syntax and convert it to an operand value

        See the class docstring for what "operand value" means. Raises a
        ValueError on definite failure ("found cabbage when I expected a
        register name"). Returns None on a soft failure: "this is a complicated
        looking expression, but it might be a sensible immediate".

        This function doesn't check that the result will be encodable: chain it
        with op_val_to_enc_val for that.

        '''
        raise NotImplementedError()

    def op_val_to_enc_val(self, op_val: int,
                          cur_pc: Optional[int]) -> Optional[int]:
        '''Convert the operand value to an encoded value

        This expects a current PC in cur_pc. If we don't know that (because
        this is otbn_as.py, and we don't know our eventual current address), a
        pc_rel immediate will return None. Similarly, if we don't know our
        width, we should return None.

        Otherwise, function must check that the operand value can be
        successfully encoded (with any required shift, in self.width bits, and
        with 2's complement if signed). If not, it must raise a ValueError.

        The default implementation returns op_val (for values that are encoded
        with no shift, signedness or other cleverness) so long as the width is
        known.

        '''
        if self.width is None:
            return None

        if op_val < 0:
            raise ValueError('Negative operand value {} for a basic operand '
                             'that expects to encode an unsigned value in '
                             '{} bits.'.format(op_val, self.width))
        if op_val >> self.width:
            raise ValueError('Operand value {} is too large for a basic '
                             'operand of {} bits.'.format(op_val, self.width))

        return op_val

    def enc_val_to_op_val(self, enc_val: int, cur_pc: int) -> Optional[int]:
        '''Convert the encoded value to an operand value

        This needs the current PC (for pc_rel immediates) and returns the
        logical op_val. The default implementation works for values that are
        encoded with no shift, signedness or similar and returns enc_val.

        If we have a width, this function must not return None.

        '''
        return enc_val

    def op_val_to_str(self, op_val: int, cur_pc: Optional[int]) -> str:
        '''Render an operand value as a string'''
        raise NotImplementedError()

    def get_max_enc_val(self) -> Optional[int]:
        '''Return the range of valid encoded values for this operand type

        The default implementation returns None if there is no width, and
        otherwise returns the maximum value that fits in width bits.

        '''
        if self.width is None:
            return None

        return (1 << self.width) - 1

    def get_op_val_range(self, cur_pc: int) -> Optional[Tuple[int, int]]:
        '''Return the range of representable operand values

        Returns None if this isn't known, for some reason.

        The default implementation uses get_max_enc_val and applies
        enc_val_to_op_val, assuming that the function is affine linear (so the
        endpoints of the encoded range map to the endpoints of the operand
        value range). Note that this doesn't hold for 2's complement signed
        integers.

        '''
        enc_hi = self.get_max_enc_val()
        if enc_hi is None:
            return None

        op_lo = self.enc_val_to_op_val(0, cur_pc)
        assert op_lo is not None
        op_hi = self.enc_val_to_op_val(enc_hi, cur_pc)
        assert op_hi is not None

        return (min(op_lo, op_hi), max(op_lo, op_hi))


class RegOperandType(OperandType):
    '''A class representing a register operand type'''
    TYPE_FMTS = {
        'gpr': (5, 'x'),
        'wdr': (5, 'w'),
    }

    def __init__(self, reg_type: str, is_src: bool, is_dest: bool) -> None:
        fmt = RegOperandType.TYPE_FMTS.get(reg_type)
        assert fmt is not None
        width, _ = fmt

        super().__init__(width)

        self.reg_type = reg_type
        self._is_src = is_src
        self._is_dest = is_dest

    @staticmethod
    def make(reg_type: str, is_src: bool, is_dest: bool, what: str,
             scheme_field: Optional[EncSchemeField]) -> 'RegOperandType':
        if scheme_field is not None:
            fmt = RegOperandType.TYPE_FMTS.get(reg_type)
            assert fmt is not None
            width, _ = fmt

            if scheme_field.bits.width != width:
                raise ValueError(
                    'In {}, there is an encoding scheme that '
                    'allocates {} bits, but the operand has '
                    'register type {!r}, which expects {} bits.'.format(
                        what, scheme_field.bits.width, reg_type, width))

        return RegOperandType(reg_type, is_src, is_dest)

    def syntax_determines_value(self) -> bool:
        return True

    def str_to_op_val(self, as_str: str) -> int:
        width, pfx = RegOperandType.TYPE_FMTS[self.reg_type]

        re_pfx = '' if pfx is None else re.escape(pfx)
        match = re.match(re_pfx + '([0-9]+)$', as_str)
        if match is None:
            raise ValueError("Expression {!r} can't be parsed as a {}.".format(
                as_str, self.reg_type))

        idx = int(match.group(1))
        assert 0 <= idx
        if idx >> width:
            raise ValueError("Invalid register of type {}: {!r}.".format(
                self.reg_type, as_str))

        return idx

    def op_val_to_str(self, op_val: int, cur_pc: Optional[int]) -> str:
        fmt = RegOperandType.TYPE_FMTS.get(self.reg_type)
        assert fmt is not None
        _, pfx = fmt

        if pfx is None:
            pfx = ''

        return '{}{}'.format(pfx, op_val)

    def is_src(self) -> bool:
        '''True if this operand is considered a source'''
        return self._is_src or self.reg_type in ['csr', 'wsr']

    def is_dest(self) -> bool:
        '''True if this operand is considered a destination'''
        return self._is_dest or self.reg_type in ['csr', 'wsr']


class ImmOperandType(OperandType):
    '''A class representing an immediate operand type'''

    def __init__(self, width: Optional[int], enc_offset: int, shift: int,
                 signed: bool, pc_rel: bool) -> None:
        assert shift >= 0

        super().__init__(width)
        self.enc_offset = enc_offset
        self.shift = shift
        self.signed = signed
        self.pc_rel = pc_rel

    @staticmethod
    def make(width: Optional[int], enc_offset: int, shift: int, signed: bool,
             pc_rel: bool, what: str,
             scheme_field: Optional[EncSchemeField]) -> 'ImmOperandType':
        if scheme_field is not None:
            # If there is an encoding scheme, check its width is compatible
            # with the operand type. If the operand type doesn't specify a
            # width, get one from the encoding scheme.
            if width is None:
                width = scheme_field.bits.width
            if scheme_field.bits.width != width:
                raise ValueError(
                    'In {}, there is an encoding scheme that '
                    'allocates {} bits to the immediate operand '
                    'but the operand claims to have width {}.'.format(
                        what, scheme_field.bits.width, width))

        return ImmOperandType(width, enc_offset, shift, signed, pc_rel)

    @staticmethod
    def _doc_rel_to_abs(value: int) -> str:
        '''Turn X to . + X or . - X, as appropriate.'''
        if value < 0:
            return '.-{}'.format(-value)
        elif value == 0:
            return '.'
        else:
            return '.+{}'.format(value)

    def markdown_doc(self) -> Optional[str]:
        # Override from OperandType base class
        rng = self.get_doc_range()
        if rng is None:
            return None

        lo, hi = rng
        if self.shift == 0:
            stp_msg = ''
        else:
            stp_msg = ' in steps of `{}`'.format(1 << self.shift)

        rel_suffix = ''
        if self.pc_rel:
            rel_suffix = (' This is encoded PC-relative but appears '
                          'as an absolute value in assembly. To write a raw '
                          'value in an assembly file, write something in the '
                          'range `{}` to `{}`.'.format(
                              ImmOperandType._doc_rel_to_abs(lo),
                              ImmOperandType._doc_rel_to_abs(hi)))

        return ('Valid range: `{}` to `{}`{}.{}'.format(
            lo, hi, stp_msg, rel_suffix))

    def describe_decode(self, bits_lst: List[str]) -> str:
        # The "most general" result is something like this:
        #
        #   PC + (signed({A, B, C} + enc_offset) << shift)
        #
        # But if enc_offset is zero and shift is positive, we'd like results
        # that look like
        #
        #   PC + signed({A, B, C, 2'b0})

        # Show shift with a concatenation if there is no offset
        shift = self.shift
        if shift and not self.enc_offset:
            bits_lst = bits_lst + ["{}'b0".format(shift)]
            shift = 0

        # Render as a concatenation and make the conversion to an integer
        # explicit.
        xsigned = 'signed' if self.signed else 'unsigned'
        acc = '{}({})'.format(xsigned,
                              OperandType._describe_bits_lst(bits_lst))
        acc_prec = 2

        if self.enc_offset:
            acc = '{} + {}'.format(acc, self.enc_offset)
            if shift:
                # Although a + b << c is logically the same as (a + b) << c, we
                # add the parentheses to make it easier to read.
                acc = '({}) << {}'.format(acc, self.shift)
                acc_prec = 0
        else:
            assert not shift

        if self.pc_rel:
            if acc_prec < 1:
                acc = '({})'.format(acc)

            acc = 'PC + {}'.format(acc)

        return acc

    def str_to_op_val(self, as_str: str) -> Optional[int]:
        # Try to parse the literal as an integer. Give up safely if we can't
        # decipher the immediate here. It might be a label which binutils' as
        # can deal with for us.
        try:
            return int(as_str, 0)
        except ValueError:
            return None

    def op_val_to_str(self, op_val: int, cur_pc: Optional[int]) -> str:
        if self.pc_rel and cur_pc is not None:
            # When we're generating code to be assembled (in the random
            # instruction generator), we need to make write PC-relative
            # addresses as offsets. Otherwise the assembler can't know they'll
            # fit (since *it* doesn't know PC).
            #
            # The other time this is used is objdump, where either version
            # works fine.
            return ImmOperandType._doc_rel_to_abs(op_val - cur_pc)
        else:
            return str(op_val)

    def op_val_to_enc_val(self, op_val: int,
                          cur_pc: Optional[int]) -> Optional[int]:
        # Give up immediately if we don't know our width
        if self.width is None:
            return None

        if self.pc_rel:
            # If the operand is PC-relative and we don't have cur_pc, give up.
            if cur_pc is None:
                return None

            # Otherwise, we need to encode the offset.
            pc_relative_val = op_val - cur_pc
        else:
            pc_relative_val = op_val

        # Try to shift right. Check that we won't clobber any low bits.
        shift_mask = (1 << self.shift) - 1
        if pc_relative_val & shift_mask:
            raise ValueError('Cannot encode the value {}: the operand has a '
                             'shift of {}, but that would clobber some bits '
                             '(because {} & {} = {}, not zero).'.format(
                                 pc_relative_val, self.shift, pc_relative_val,
                                 shift_mask, pc_relative_val & shift_mask))

        # Compute offset encoded value by applying shift and enc_offset
        shifted = pc_relative_val >> self.shift
        offset_val = shifted - self.enc_offset

        # Check offset encoded value sits in the allowable range for encoded
        # values
        enc_rng = self.get_enc_range()
        assert enc_rng is not None
        enc_lo, enc_hi = enc_rng

        if not (enc_lo <= offset_val <= enc_hi):
            doc_rng = self.get_doc_range()
            assert doc_rng is not None
            doc_lo, doc_hi = doc_rng

            encoded_msg = (', which encodes to {},'.format(offset_val)
                           if self.shift != 0 or self.enc_offset != 0 else '')
            raise ValueError('Cannot encode the value {}{} as a {}-bit '
                             '{}signed value. Possible range: {}..{}.'.format(
                                 pc_relative_val, encoded_msg, self.width,
                                 '' if self.signed else 'un', doc_lo, doc_hi))

        if self.signed:
            encoded = ((1 << self.width) +
                       offset_val if offset_val < 0 else offset_val)
        else:
            assert offset_val >= 0
            encoded = offset_val

        assert (encoded >> self.width) == 0
        return encoded

    def enc_val_to_op_val(self, enc_val: int, cur_pc: int) -> Optional[int]:
        # If this immediate is signed and we have a valid width, we need to
        # convert the value to a 2's-complement signed number. (There's not
        # much we can do if we don't know our width!)
        signed_val = enc_val
        if self.signed:
            if self.width is None:
                return None

            assert (enc_val >> self.width) == 0
            assert self.width >= 1
            if enc_val >> (self.width - 1):
                signed_val -= 1 << self.width
                assert signed_val < 0

        signed_val += self.enc_offset

        shifted = signed_val << self.shift

        # If this value is PC-relative, add the current PC. The point is that
        # something encoded as "10" means "10 + pc", and is written that way in
        # assembly code. If we don't actually know our current PC, we can write
        # it as ". + <shifted>", but we do better than that if we can.
        rel_val = shifted + (cur_pc if self.pc_rel else 0)

        return rel_val

    def get_enc_range(self) -> Optional[Tuple[int, int]]:
        '''Gets range of allowable encoded values'''
        if self.width is None:
            return None

        if self.signed:
            sgn_lo = -((1 << self.width) // 2)
            sgn_hi = max(-(sgn_lo + 1), 0)
        else:
            sgn_lo = 0
            sgn_hi = (1 << self.width) - 1

        return (sgn_lo, sgn_hi)

    def get_doc_range(self) -> Optional[Tuple[int, int]]:
        '''Gets range of allowable values as they will appear in
        documentation
        '''

        enc_range = self.get_enc_range()
        if enc_range is None:
            return None

        sgn_lo, sgn_hi = enc_range

        sgn_lo += self.enc_offset
        sgn_hi += self.enc_offset

        return (sgn_lo << self.shift, sgn_hi << self.shift)

    def get_op_val_range(self, cur_pc: int) -> Optional[Tuple[int, int]]:
        rel_rng = self.get_doc_range()
        if rel_rng is None:
            return None

        rel_lo, rel_hi = rel_rng
        pc_off = cur_pc if self.pc_rel else 0
        return (rel_lo + pc_off, rel_hi + pc_off)


class EnumOperandType(OperandType):
    '''A class representing an enum operand type

    Enum operands are case-insensitive: the names are stored lower case, and
    are matched with case-folding in read_index.

    '''

    def __init__(self, items: List[str], what: str,
                 scheme_field: Optional[EncSchemeField]) -> None:
        assert items

        # The number of items gives a minimum width for the field. If there is
        # an encoding, use that width, but check that it's enough to hold all
        # the items.
        min_width = int.bit_length(len(items) - 1)
        if scheme_field is None:
            width = min_width
        else:
            if scheme_field.bits.width < min_width:
                raise ValueError('In {}, there is an encoding scheme that '
                                 'assigns {} bits to the field. But this '
                                 'field is an enum with {} items, so needs '
                                 'at least {} bits.'.format(
                                     what, scheme_field.bits.width, len(items),
                                     min_width))
            width = scheme_field.bits.width

        super().__init__(width)
        self.items = [item.lower() for item in items]

    def markdown_doc(self) -> Optional[str]:
        # Override from OperandType base class
        parts = [
            '| Assembly Syntax | Value |\n'
            '|-----------------|-------|\n'
        ]
        for idx, item in enumerate(self.items):
            parts.append('| `{}` | `{}` |\n'.format(item, idx))
        return ''.join(parts)

    def syntax_determines_value(self) -> bool:
        return True

    def str_to_op_val(self, as_str: str) -> int:
        low_str = as_str.lower()
        for idx, item in enumerate(self.items):
            if low_str == item:
                return idx

        known_vals = ', '.join(repr(item) for item in self.items)
        raise ValueError('Invalid enum value, {!r}. '
                         'Supported values: {}.'.format(as_str, known_vals))

    def op_val_to_str(self, op_val: int, cur_pc: Optional[int]) -> str:
        # On a bad value, we have to return *something*. Since this is just
        # going into disassembly, let's be vaguely helpful and return something
        # that looks clearly bogus.
        #
        # Note that if the number of items in the enum is not a power of 2,
        # this could happen with a bad binary, despite good tools.
        if op_val < 0 or op_val >= len(self.items):
            return '???'

        return self.items[op_val]

    def get_max_enc_val(self) -> int:
        return len(self.items) - 1


class OptionOperandType(OperandType):
    '''A class representing an option operand type

    Option operands are case-insensitive: the option name is stored lower case,
    and is matched with case-folding in read_index.

    '''

    def __init__(self, option: str, what: str,
                 scheme_field: Optional[EncSchemeField]) -> None:

        width = 1
        if scheme_field is not None:
            assert width <= scheme_field.bits.width
            width = scheme_field.bits.width

        super().__init__(width)
        self.option = option.lower()

    def markdown_doc(self) -> Optional[str]:
        # Override from OperandType base class
        return 'To specify, use the literal syntax `{}`\n'.format(self.option)

    def syntax_determines_value(self) -> bool:
        return True

    def str_to_op_val(self, as_str: str) -> int:
        if as_str.lower() == self.option:
            return 1

        raise ValueError('Invalid option value, {!r}. '
                         'If specified, it should have been {!r}.'.format(
                             as_str, self.option))

    def op_val_to_str(self, op_val: int, cur_pc: Optional[int]) -> str:
        assert op_val in [0, 1]
        return self.option if op_val else ''

    def get_max_enc_val(self) -> int:
        return 1


def parse_operand_type(fmt: str, pc_rel: bool, what: str,
                       scheme_field: Optional[EncSchemeField]) -> OperandType:
    '''Make sense of the operand type syntax'''
    # Registers
    reg_fmts = {
        'grs': ('gpr', True, False),
        'grd': ('gpr', False, True),
        'wrs': ('wdr', True, False),
        'wrd': ('wdr', False, True),
        'wrb': ('wdr', True, True),
    }
    reg_match = reg_fmts.get(fmt)
    if reg_match is not None:
        if pc_rel:
            raise ValueError(
                'In {}, the operand has type {!r} which is a '
                'type of register operand. It also has pc_rel '
                'set, which is only allowed for immediates.'.format(what, fmt))
        reg_type, is_src, is_dest = reg_match
        return RegOperandType.make(reg_type, is_src, is_dest, what,
                                   scheme_field)

    # CSR and WSR indices. These are treated like unsigned immediates, with
    # width 12 and 8, respectively.
    xsr_fmts = {'csr': 12, 'wsr': 8}
    xsr_match = xsr_fmts.get(fmt)
    if xsr_match is not None:
        assert not pc_rel
        return ImmOperandType.make(xsr_match, 0, 0, False, False, what,
                                   scheme_field)

    # Immediates
    for base, signed in [('simm', True), ('uimm', False)]:
        # The type of an immediate operand is encoded as
        #
        #   BASE WIDTH? (+ENC_OFFSET)? (<<SHIFT)?
        #
        # where BASE is 'simm' or 'uimm', WIDTH is a positive integer and
        # ENC_OFFSET and SHIFT are non-negative integers. The regex below
        # captures WIDTH as group 1, OFFSET as group 2 and SHIFT as group 3.
        m = re.match(base + r'([1-9][0-9]*)?(?:\+([0-9]+))?(?:<<([0-9]+))?$',
                     fmt)
        if m is not None:
            width = int(m.group(1)) if m.group(1) is not None else None
            enc_offset = int(m.group(2)) if m.group(2) is not None else 0
            shift = int(m.group(3)) if m.group(3) is not None else 0
            return ImmOperandType.make(width, enc_offset, shift, signed,
                                       pc_rel, what, scheme_field)

    m = re.match(r'enum\(([^\)]+)\)$', fmt)
    if m:
        if pc_rel:
            raise ValueError('In {}, the operand is an enumeration, but also '
                             'has pc_rel set, which is only allowed for bare '
                             'immediates.'.format(what))

        return EnumOperandType(
            [item.strip() for item in m.group(1).split(',')], what,
            scheme_field)
    m = re.match(r'option\(([^\)]+)\)$', fmt)
    if m:
        if pc_rel:
            raise ValueError('In {}, the operand is an option, but also '
                             'has pc_rel set, which is only allowed for bare '
                             'immediates.'.format(what))

        return OptionOperandType(m.group(1).strip(), what, scheme_field)

    raise ValueError("In {}, operand type description {!r} "
                     "didn't match any recognised format.".format(what, fmt))


def infer_operand_type(name: str, pc_rel: bool, what: str,
                       scheme_field: Optional[EncSchemeField]) -> OperandType:
    '''Try to guess an operand's type from its name'''

    op_type_name = None
    if re.match(r'grs[0-9]*$', name):
        op_type_name = 'grs'
    elif name in ['grd', 'wrd', 'csr', 'wsr']:
        op_type_name = name
    elif re.match(r'wrs[0-9]*$', name):
        op_type_name = 'wrs'
    elif re.match(r'imm[0-9]*$', name) or name == 'offset':
        op_type_name = 'simm'

    if op_type_name is None:
        raise ValueError(
            "Operand name {!r} doesn't imply an operand type: "
            "you'll have to set the type explicitly.".format(name))

    return parse_operand_type(op_type_name, pc_rel, what, scheme_field)


def make_operand_type(op_type_name: Optional[str], pc_rel: bool,
                      operand_name: str, mnemonic: str,
                      scheme_field: Optional[EncSchemeField]) -> OperandType:
    '''Construct a type for an operand

    This is either based on the type, if given, or inferred from the name
    otherwise. If scheme_field is not None, this is the encoding scheme field
    that will be used.

    '''
    what = ('the type for the {!r} operand of instruction {!r}'.format(
        operand_name, mnemonic))
    return (parse_operand_type(op_type_name, pc_rel, what, scheme_field)
            if op_type_name is not None else infer_operand_type(
                operand_name, pc_rel, what, scheme_field))


class Operand:

    def __init__(self, yml: object, mnemonic: str,
                 insn_encoding: Optional[Encoding]) -> None:
        # The YAML representation should be a string (a bare operand name) or a
        # dict.
        what = 'operand for {!r} instruction'.format(mnemonic)
        if isinstance(yml, str):
            name = yml.lower()
            abbrev = None
            op_type = None
            doc = None
            pc_rel = False
            op_what = '{!r} {}'.format(name, what)
        elif isinstance(yml, dict):
            yd = check_keys(yml, what, ['name'],
                            ['type', 'pc-rel', 'doc', 'abbrev'])
            name = check_str(yd['name'], 'name of ' + what).lower()

            op_what = '{!r} {}'.format(name, what)
            abbrev = get_optional_str(yd, 'abbrev', op_what)
            if abbrev is not None:
                abbrev = abbrev.lower()
            op_type = get_optional_str(yd, 'type', op_what)
            pc_rel = check_bool(yd.get('pc-rel', False),
                                'pc-rel field of ' + op_what)
            doc = get_optional_str(yd, 'doc', op_what)

        # If there is an encoding, look up the encoding scheme field that
        # corresponds to this operand.
        enc_scheme_field = None
        if insn_encoding is not None:
            field_name = insn_encoding.op_to_field_name.get(name)
            if field_name is None:
                raise ValueError('The {!r} instruction has an operand called '
                                 '{!r}, but the associated encoding has no '
                                 'field that encodes it.'.format(
                                     mnemonic, name))
            enc_scheme_field = insn_encoding.fields[field_name].scheme_field

        if abbrev is not None:
            if name == abbrev:
                raise ValueError('Operand {!r} of the {!r} instruction has '
                                 'an abbreviated name the same as its '
                                 'actual name.'.format(name, mnemonic))
        self.name = name
        self.abbrev = abbrev
        self.op_type = make_operand_type(op_type, pc_rel, name, mnemonic,
                                         enc_scheme_field)
        self.doc = doc
