pysvp64asm: deprecate custom_insn helper
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 6 Nov 2022 09:30:40 +0000 (12:30 +0300)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:16 +0000 (19:51 +0100)
src/openpower/sv/trans/svp64.py

index d3aaa2ebba9a74d8d7a6fc14635c499432585357..d93d988f8a5eeebce64361e37334e08cb554585c 100644 (file)
@@ -37,604 +37,6 @@ from openpower.decoder.power_enums import find_wiki_dir
 from openpower.util import log
 
 
-def instruction(*fields):
-    def instruction(insn, desc):
-        (value, start, end) = desc
-        bits = ((1,) * ((end + 1) - start))
-        mask = 0
-        for bit in bits:
-            mask = ((mask << 1) | bit)
-        return (insn | ((value & mask) << (31 - end)))
-
-    return functools.reduce(instruction, fields, 0)
-
-
-CUSTOM_INSNS = {}
-
-
-def _insn(name, **kwargs):
-    return name, kwargs
-
-
-def _custom_insns(*insns):
-    """ a decorator that adds the function to `CUSTOM_INSNS` """
-
-    def decorator(fn):
-        FIELDS_ARG = object()
-        if len(insns) == 0:
-            insns_ = (fn.__name__, {}),
-        else:
-            insns_ = insns
-        for name, kwargs in insns_:
-            if not isinstance(name, str):
-                raise TypeError("instruction name must be a str: {name!r}")
-            if name in CUSTOM_INSNS:
-                raise ValueError(f"duplicate instruction mnemonic: {name!r}")
-            # use getcallargs to check that arguments work:
-            inspect.getcallargs(fn, FIELDS_ARG, **kwargs)
-            CUSTOM_INSNS[name] = functools.partial(fn, **kwargs)
-        return fn
-    return decorator
-
-
-@_custom_insns(
-    _insn("setvl", Rc=0),
-    _insn("setvl.", Rc=1),
-)
-def setvl(fields, Rc):
-    """
-    setvl is a *32-bit-only* instruction. It controls SVSTATE.
-    It is *not* a 64-bit-prefixed Vector instruction (no sv.setvl, yet),
-    it is a Vector *control* instruction.
-
-    * setvl RT,RA,SVi,vf,vs,ms
-
-    1.6.28 SVL-FORM - from fields.txt
-    |0     |6    |11    |16   |23 |24 |25 |26    |31 |
-    | PO   |  RT |   RA | SVi |ms |vs |vf |   XO |Rc |
-    """
-    PO = 22
-    XO = 0b11011
-    # ARRRGH these are in a non-obvious order in openpower/isa/simplev.mdwn
-    # compared to the SVL-Form above. sigh
-    # setvl RT,RA,SVi,vf,vs,ms
-    (RT, RA, SVi, vf, vs, ms) = fields
-    SVi -= 1
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (SVi, 16, 22),
-        (ms, 23, 23),
-        (vs, 24, 24),
-        (vf, 25, 25),
-        (XO, 26, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns(
-    _insn("svstep", Rc=0),
-    _insn("svstep.", Rc=1),
-)
-def svstep(fields, Rc):
-    """
-    svstep is a 32-bit instruction. It updates SVSTATE.
-    It *can* be SVP64-prefixed, to indicate that its registers
-    are Vectorised.
-
-    * svstep RT,SVi,vf
-
-    # 1.6.28 SVL-FORM - from fields.txt
-    # |0     |6    |11    |16   |23 |24 |25 |26    |31 |
-    # | PO   |  RT | /    | SVi |/  |/  |vf |   XO |Rc |
-
-    """
-    PO = 22
-    XO = 0b10011
-    (RT, SVi, vf) = fields
-    SVi -= 1
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (0, 11, 15),
-        (SVi, 16, 22),
-        (0, 23, 23),
-        (0, 24, 24),
-        (vf, 25, 25),
-        (XO, 26, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns()
-def svshape(fields):
-    """
-    svshape is a *32-bit-only* instruction. It updates SVSHAPE and SVSTATE.
-    It is *not* a 64-bit-prefixed Vector instruction (no sv.svshape, yet),
-    it is a Vector *control* instruction.
-
-    https://libre-soc.org/openpower/sv/remap/#svshape
-
-    * svshape SVxd,SVyd,SVzd,SVrm,vf
-
-    # 1.6.33 SVM-FORM from fields.txt
-    # |0     |6        |11      |16    |21    |25 |26    |31  |
-    # | PO   |  SVxd   |   SVyd | SVzd | SVrm |vf |   XO      |
-
-    note that SVrm is not permitted to be 0b0111, 0b1000 or 0b1001.
-    0b0111 is reserved and 0b100- is for svshape2
-
-    """
-    PO = 22
-    XO = 0b011001
-    (SVxd, SVyd, SVzd, SVrm, vf) = fields
-    SVxd -= 1
-    SVyd -= 1
-    SVzd -= 1
-
-    # check SVrm for reserved (and svshape2) values
-    assert SVrm not in [0b1000, 0b1001], \
-        "svshape reserved SVrm value %s" % bin(SVrm)
-
-    return instruction(
-        (PO, 0, 5),
-        (SVxd, 6, 10),
-        (SVyd, 11, 15),
-        (SVzd, 16, 20),
-        (SVrm, 21, 24),
-        (vf, 25, 25),
-        (XO, 26, 31),
-    )
-
-
-@_custom_insns()
-def svshape2(fields):
-    """
-    svshape2 is a *32-bit-only* instruction. It updates SVSHAPE and SVSTATE.
-    It is *not* a 64-bit-prefixed Vector instruction (no sv.svshape2, yet),
-    it is a Vector *control* instruction, and is a sort-of hybrid of
-    svshape and svindex, with the key important feature being the "offset".
-
-    https://libre-soc.org/openpower/sv/remap/discussion
-
-    * svshape2 SVo,SVM2yx,rmm,SVd,sk,mm
-
-    # 1.6.35.1 SVM2-FORM from fields.txt
-    # |0     |6     |10   |11      |16    |21 |24|25 |26    |31  |
-    # | PO   | SVo  |SVMyx|   rmm  | SVd  |XO |mm|sk |   XO      |
-
-    note that this fits into the space of svshape and that XO is
-    split across 2 areas.
-
-    """
-    PO = 22
-    XO = 0b011001
-    XO2 = 0b100  # not really XO2 but hey
-    (offs, yx, rmm, SVd, sk, mm) = fields
-    SVd -= 1  # offset by one
-
-    return instruction(
-        (PO, 0, 5),
-        (offs, 6, 9),  # offset (the whole point of adding svshape2)
-        (yx, 10, 10),  # like svindex
-        (rmm, 11, 15),  # ditto svindex
-        (SVd, 16, 20),  # ditto svindex
-        (XO2, 21, 23),  # actually XO split across 2 places...
-        (mm, 24, 24),  # ditto svindex
-        (sk, 25, 25),  # ditto svindex
-        (XO, 26, 31),
-    )
-
-
-@_custom_insns()
-def svindex(fields):
-    """
-    svindex is a *32-bit-only* instruction. It is a convenience
-    instruction that reduces instruction count for Indexed REMAP
-    Mode.
-    It is *not* a 64-bit-prefixed Vector instruction (no sv.svindex, yet),
-    it is a Vector *control* instruction.
-
-    1.6.28 SVI-FORM
-      |0     |6    |11    |16   |21 |23|24|25|26    31|
-      | PO   |  SVG|rmm   | SVd |ew |yx|mm|sk|   XO   |
-    """
-    # note that the dimension field one subtracted
-    PO = 22
-    XO = 0b101001
-    (SVG, rmm, SVd, ew, yx, mm, sk) = fields
-    SVd -= 1
-    return instruction(
-        (PO, 0, 5),
-        (SVG, 6, 10),
-        (rmm, 11, 15),
-        (SVd, 16, 20),
-        (ew, 21, 22),
-        (yx, 23, 23),
-        (mm, 24, 24),
-        (sk, 25, 25),
-        (XO, 26, 31),
-    )
-
-
-@_custom_insns()
-def svremap(fields):
-    """
-    this is a *32-bit-only* instruction. It updates the SVSHAPE SPR
-    it is *not* a 64-bit-prefixed Vector instruction (no sv.svremap),
-    it is a Vector *control* instruction.
-
-    * svremap SVme,mi0,mi1,mi2,mo0,mo1,pst
-
-    # 1.6.34 SVRM-FORM
-       |0     |6     |11  |13   |15   |17   |19   |21  |22   |26     |31 |
-       | PO   | SVme |mi0 | mi1 | mi2 | mo0 | mo1 |pst |///  | XO        |
-
-    """
-    PO = 22
-    XO = 0b111001
-    (SVme, mi0, mi1, mi2, mo0, mo1, pst) = fields
-    return instruction(
-        (PO, 0, 5),
-        (SVme, 6, 10),
-        (mi0, 11, 12),
-        (mi1, 13, 14),
-        (mi2, 15, 16),
-        (mo0, 17, 18),
-        (mo1, 19, 20),
-        (pst, 21, 21),
-        (0, 22, 25),
-        (XO, 26, 31),
-    )
-
-
-# ok from here-on down these are added as 32-bit instructions
-# and are here only because binutils (at present) doesn't have
-# them (that's being fixed!)
-# they can - if implementations then choose - be Vectorised
-# because they are general-purpose scalar instructions
-@_custom_insns()
-def bmask(fields):
-    """
-    1.6.2.2 BM2-FORM
-    |0     |6    |11    |16    |21   |26 |27    31|
-    | PO   |  RT |   RA |   RB |bm   |L  |   XO   |
-    """
-    PO = 22
-    XO = 0b010001
-    (RT, RA, RB, bm, L) = fields
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (RB, 16, 20),
-        (bm, 21, 25),
-        (L, 26, 26),
-        (XO, 27, 31),
-    )
-
-
-def _fptrans_insn(name, XO):
-    return [
-        _insn(name, PO=63, Rc=0, XO=XO),
-        _insn(name + ".", PO=63, Rc=1, XO=XO),
-        _insn(name + "s", PO=59, Rc=0, XO=XO),
-        _insn(name + "s.", PO=59, Rc=1, XO=XO),
-    ]
-
-
-@_custom_insns(
-    *_fptrans_insn("fatan2", XO=0b1001001110),
-    *_fptrans_insn("fatan2pi", XO=0b1000001110),
-    *_fptrans_insn("fpow", XO=0b1111101101),
-    *_fptrans_insn("fpown", XO=0b1101101100),
-    *_fptrans_insn("fpowr", XO=0b1111101100),
-    *_fptrans_insn("frootn", XO=0b1101101101),
-    *_fptrans_insn("fhypot", XO=0b1010001110),
-    *_fptrans_insn("fminnum08", XO=0b1011001100),
-    *_fptrans_insn("fmaxnum08", XO=0b1011101100),
-    *_fptrans_insn("fmin19", XO=0b1011001101),
-    *_fptrans_insn("fmax19", XO=0b1011101101),
-    *_fptrans_insn("fminnum19", XO=0b1011001110),
-    *_fptrans_insn("fmaxnum19", XO=0b1011101110),
-    *_fptrans_insn("fminc", XO=0b1011001111),
-    *_fptrans_insn("fmaxc", XO=0b1011101111),
-    *_fptrans_insn("fminmagnum08", XO=0b1100001110),
-    *_fptrans_insn("fmaxmagnum08", XO=0b1100001111),
-    *_fptrans_insn("fminmag19", XO=0b1101101110),
-    *_fptrans_insn("fmaxmag19", XO=0b1101101111),
-    *_fptrans_insn("fminmagnum19", XO=0b1110001110),
-    *_fptrans_insn("fmaxmagnum19", XO=0b1110001111),
-    *_fptrans_insn("fminmagc", XO=0b1111101110),
-    *_fptrans_insn("fmaxmagc", XO=0b1111101111),
-    *_fptrans_insn("fmod", XO=0b1101001111),
-    *_fptrans_insn("fremainder", XO=0b1111001111),
-)
-def fptrans_binary(fields, PO, Rc, XO):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # however we are out of space with opcode 22
-    # 1.6.7 X-FORM
-    # |0   |6    |11   |16   |21  |31 |
-    # | PO | FRT | FRA | FRB | XO |Rc |
-    # | PO | FRT | FRA | RB  | XO |Rc |
-    (FRT, FRA, FRB) = fields
-    return instruction(
-        (PO, 0, 5),
-        (FRT, 6, 10),
-        (FRA, 11, 15),
-        (FRB, 16, 20),
-        (XO, 21, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns(
-    *_fptrans_insn("frsqrt", XO=0b1001001100),
-    *_fptrans_insn("fcbrt", XO=0b1000001100),
-    *_fptrans_insn("frecip", XO=0b1010001100),
-    *_fptrans_insn("fexp2m1", XO=0b1100001100),
-    *_fptrans_insn("flog2p1", XO=0b1100001101),
-    *_fptrans_insn("fexp2", XO=0b1110001100),
-    *_fptrans_insn("flog2", XO=0b1110001101),
-    *_fptrans_insn("fexpm1", XO=0b1100101100),
-    *_fptrans_insn("flogp1", XO=0b1100101101),
-    *_fptrans_insn("fexp", XO=0b1110101100),
-    *_fptrans_insn("flog", XO=0b1110101101),
-    *_fptrans_insn("fexp10m1", XO=0b1101001100),
-    *_fptrans_insn("flog10p1", XO=0b1101001101),
-    *_fptrans_insn("fexp10", XO=0b1111001100),
-    *_fptrans_insn("flog10", XO=0b1111001101),
-    *_fptrans_insn("fsin", XO=0b1001001101),
-    *_fptrans_insn("fcos", XO=0b1001101100),
-    *_fptrans_insn("ftan", XO=0b1001101101),
-    *_fptrans_insn("fasin", XO=0b1001001111),
-    *_fptrans_insn("facos", XO=0b1001101110),
-    *_fptrans_insn("fatan", XO=0b1001101111),
-    *_fptrans_insn("fsinpi", XO=0b1000001101),
-    *_fptrans_insn("fcospi", XO=0b1000101100),
-    *_fptrans_insn("ftanpi", XO=0b1000101101),
-    *_fptrans_insn("fasinpi", XO=0b1000001111),
-    *_fptrans_insn("facospi", XO=0b1000101110),
-    *_fptrans_insn("fatanpi", XO=0b1000101111),
-    *_fptrans_insn("fsinh", XO=0b1010001101),
-    *_fptrans_insn("fcosh", XO=0b1010101100),
-    *_fptrans_insn("ftanh", XO=0b1010101101),
-    *_fptrans_insn("fasinh", XO=0b1010001111),
-    *_fptrans_insn("facosh", XO=0b1010101110),
-    *_fptrans_insn("fatanh", XO=0b1010101111),
-)
-def fptrans_unary(fields, PO, Rc, XO):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # however we are out of space with opcode 22
-    # 1.6.7 X-FORM
-    # |0   |6    |11   |16   |21  |31 |
-    # | PO | FRT | /// | FRB | XO |Rc |
-    (FRT, FRB) = fields
-    return instruction(
-        (PO, 0, 5),
-        (FRT, 6, 10),
-        (0, 11, 15),
-        (FRB, 16, 20),
-        (XO, 21, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns(
-    _insn("ternlogi", Rc=0),
-    _insn("ternlogi.", Rc=1),
-)
-def ternlogi(fields, Rc):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # however we are out of space with opcode 22
-    # 1.6.34 TLI-FORM
-    #   |0   |6   |11   |16   |21   |29  |31 |
-    #   | PO | RT |  RA |  RB | TLI | XO |Rc |
-    PO = 5
-    XO = 0
-    (RT, RA, RB, TLI) = fields
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (RB, 16, 20),
-        (TLI, 21, 28),
-        (XO, 29, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns(
-    _insn("grev", Rc=0, imm=0, word=0),
-    _insn("grevw", Rc=0, imm=0, word=1),
-    _insn("grevi", Rc=0, imm=1, word=0),
-    _insn("grevwi", Rc=0, imm=1, word=1),
-    _insn("grev.", Rc=1, imm=0, word=0),
-    _insn("grevw.", Rc=1, imm=0, word=1),
-    _insn("grevi.", Rc=1, imm=1, word=0),
-    _insn("grevwi.", Rc=1, imm=1, word=1),
-)
-def grev(fields, Rc, imm, word):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # however we are out of space with opcode 22
-    insn = PO = 5
-    # _ matches fields in table at:
-    # https://libre-soc.org/openpower/sv/bitmanip/
-    XO = 0b1_0010_110
-    if word:
-        XO |= 0b100_000
-    if imm:
-        XO |= 0b1000_000
-    (RT, RA, XBI) = fields
-    insn = (insn << 5) | RT
-    insn = (insn << 5) | RA
-    if imm and not word:
-        assert 0 <= XBI < 64
-        insn = (insn << 6) | XBI
-        insn = (insn << 9) | XO
-    else:
-        assert 0 <= XBI < 32
-        insn = (insn << 5) | XBI
-        insn = (insn << 10) | XO
-    insn = (insn << 1) | Rc
-    return insn
-
-
-@_custom_insns(
-    _insn("maxs", XO=0b0111001110, Rc=0),
-    _insn("maxs.", XO=0b0111001110, Rc=1),
-    _insn("maxu", XO=0b0011001110, Rc=0),
-    _insn("maxu.", XO=0b0011001110, Rc=1),
-    _insn("minu", XO=0b0001001110, Rc=0),
-    _insn("minu.", XO=0b0001001110, Rc=1),
-    _insn("mins", XO=0b0101001110, Rc=0),
-    _insn("mins.", XO=0b0101001110, Rc=1),
-    _insn("absdu", XO=0b1011110110, Rc=0),
-    _insn("absdu.", XO=0b1011110110, Rc=1),
-    _insn("absds", XO=0b1001110110, Rc=0),
-    _insn("absds.", XO=0b1001110110, Rc=1),
-    _insn("avgadd", XO=0b1101001110, Rc=0),
-    _insn("avgadd.", XO=0b1101001110, Rc=1),
-    _insn("absdacu", XO=0b1111110110, Rc=0),
-    _insn("absdacu.", XO=0b1111110110, Rc=1),
-    _insn("absdacs", XO=0b0111110110, Rc=0),
-    _insn("absdacs.", XO=0b0111110110, Rc=1),
-    _insn("cprop", XO=0b0110001110, Rc=0),
-    _insn("cprop.", XO=0b0110001110, Rc=1),
-)
-def av(fields, XO, Rc):
-    # 1.6.7 X-FORM
-    #   |0     |6 |7|8|9  |10  |11|12|13  |15|16|17     |20|21    |31  |
-    #   | PO   |       RT      |    RA       |    RB       |   XO |Rc  |
-    PO = 22
-    (RT, RA, RB) = fields
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (RB, 16, 20),
-        (XO, 21, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns()
-def fmvis(fields):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # V3.0B 1.6.6 DX-FORM
-    # |0     |6 |7|8|9  |10  |11|12|13  |15|16|17     |26|27    |31  |
-    # | PO   |   FRS         |     d1      |      d0  |      XO |d2  |
-    PO = 22
-    XO = 0b00011
-    (FRS, imm) = fields
-    # first split imm into d1, d0 and d2. sigh
-    d2 = (imm & 1)  # LSB (0)
-    d1 = (imm >> 1) & 0b11111  # bits 1-5
-    d0 = (imm >> 6)  # MSBs 6-15
-    return instruction(
-        (PO, 0, 5),
-        (FRS, 6, 10),
-        (d1,  11, 15),
-        (d0,  16, 25),
-        (XO, 26, 30),
-        (d2, 31, 31),
-    )
-
-
-@_custom_insns()
-def fishmv(fields):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # V3.0B 1.6.6 DX-FORM
-    # |0     |6 |7|8|9  |10  |11|12|13  |15|16|17     |26|27   |31  |
-    # | PO   |   FRS         |     d1      |      d0  |     XO |d2  |
-    PO = 22
-    XO = 0b01011
-    (FRS, imm) = fields
-    # first split imm into d1, d0 and d2. sigh
-    d2 = (imm & 1)  # LSB (0)
-    d1 = (imm >> 1) & 0b11111  # bits 1-5
-    d0 = (imm >> 6)  # MSBs 6-15
-    return instruction(
-        (PO, 0, 5),
-        (FRS, 6, 10),
-        (d1,  11, 15),
-        (d0,  16, 25),
-        (XO, 26, 30),
-        (d2, 31, 31),
-    )
-
-
-@_custom_insns(
-    _insn("maddedu", XO=50),
-    _insn("maddedus", XO=57),
-    _insn("divmod2du", XO=58),
-    _insn("pcdec.", XO=56),
-)
-def va_form(fields, XO):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # 1.6.21.1 VA-FORM
-    #    |0   |6   |11   |16   |21  |26  |
-    #    | PO | RT |  RA |  RB | RC | XO |
-    PO = 4
-    (RT, RA, RB, RC) = fields
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (RB, 16, 20),
-        (RC, 21, 25),
-        (XO, 26, 31),
-    )
-
-
-@_custom_insns(
-    _insn("shadd",  PO=22, XO=0b01101110, Rc=0),
-    _insn("shadd.", PO=22, XO=0b01101110, Rc=1),
-    _insn("shadduw",  PO=22, XO=0b11101110, Rc=0),
-    _insn("shadduw.", PO=22, XO=0b11101110, Rc=1),
-)   
-def Z23(fields, PO, XO, Rc):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # 1.6.27 Z23-FORM
-    #   |0     |6     |11    |15 |16     |21 |23    |31 |
-    #   | PO   |  RT  |   RA     |   RB  |sm |   XO |Rc |
-    (RT, RA, RB, sm) = fields
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (RB, 16, 20),
-        (sm, 21, 22),
-        (XO, 23, 30),
-        (Rc, 31, 31),
-    )
-
-
-@_custom_insns(
-    _insn("dsld",  XO=26, Rc=0), # minor_4=52 (26<<1 | Rc=0)
-    _insn("dsld.", XO=26, Rc=1), # minor_4=53 (26<<1 | Rc=1)
-    _insn("dsrd",  XO=27, Rc=0), # minor_4=54 (27<<1 | Rc=0)
-    _insn("dsrd.", XO=27, Rc=1), # minor_4=55 (27<<1 | Rc=1)
-)
-def dsld_dsrd(fields, XO, Rc):
-    # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-    # 1.6.21.1 VA2-FORM
-    #    |0   |6   |11   |16   |21  |26  |31|
-    #    | PO | RT |  RA |  RB | RC | XO |Rc|
-    PO = 4
-    (RT, RA, RB, RC) = fields
-    return instruction(
-        (PO, 0, 5),
-        (RT, 6, 10),
-        (RA, 11, 15),
-        (RB, 16, 20),
-        (RC, 21, 25),
-        (XO, 26, 30),
-        (Rc, 31, 31),
-    )
-
-
 # decode GPR into sv extra
 def get_extra_gpr(etype, regmode, field):
     if regmode == 'scalar':
@@ -861,7 +263,9 @@ class SVP64Asm:
         log("opcode, fields substed", ls, opcode, fields)
 
         # identify if it is a word instruction
-        record = DB[opcode]
+        record = None
+        if os.environ.get("INSNDB"):
+            record = DB[opcode]
         if record is not None:
             insn = WordInstruction.assemble(db=DB,
                 opcode=opcode, arguments=fields)
@@ -873,14 +277,6 @@ class SVP64Asm:
             ))
             return
 
-        custom_insn_hook = CUSTOM_INSNS.get(opcode)
-        if custom_insn_hook is not None:
-            fields = tuple(map(to_number, fields))
-            insn_num = custom_insn_hook(fields)
-            log(opcode, bin(insn_num))
-            yield ".long 0x%X # %s" % (insn_num, insn)
-            return
-
         # identify if is a svp64 mnemonic
         if not opcode.startswith('sv.'):
             yield insn  # unaltered
@@ -1537,51 +933,18 @@ class SVP64Asm:
         if not v30b_op.endswith('.'):
             v30b_op_rc += rc
 
-        # svstep is weird
-        # FIXME(lkcl): should sv.svstep be like svstep?
-        if v30b_op_rc in ("svstep", "svstep."):
-            # compensate for `SVi -= 1` in svstep()
-            v30b_newfields[1] = str(int(v30b_newfields[1]) + 1)
-
-        custom_insn_hook = CUSTOM_INSNS.get(v30b_op_rc)
-        if custom_insn_hook is not None:
-            fields = tuple(map(to_number, v30b_newfields))
-            insn_num = custom_insn_hook(fields)
-            log(opcode, bin(insn_num))
-            yield ".long 0x%X # %s" % (insn_num, insn)
-            return
-        # argh, sv.fmadds etc. need to be done manually
-        elif v30b_op == 'ffmadds':
-            opcode = 59 << (32-6)    # bits 0..6 (MSB0)
-            opcode |= int(v30b_newfields[0]) << (32-11)  # FRT
-            opcode |= int(v30b_newfields[1]) << (32-16)  # FRA
-            opcode |= int(v30b_newfields[2]) << (32-21)  # FRB
-            opcode |= int(v30b_newfields[3]) << (32-26)  # FRC
-            opcode |= 0b00101 << (32-31)   # bits 26-30
-            if rc:
-                opcode |= 1  # Rc, bit 31.
-            yield ".long 0x%x" % opcode
-        # argh, sv.fdmadds need to be done manually
-        elif v30b_op == 'fdmadds':
-            opcode = 59 << (32-6)    # bits 0..6 (MSB0)
-            opcode |= int(v30b_newfields[0]) << (32-11)  # FRT
-            opcode |= int(v30b_newfields[1]) << (32-16)  # FRA
-            opcode |= int(v30b_newfields[2]) << (32-21)  # FRB
-            opcode |= int(v30b_newfields[3]) << (32-26)  # FRC
-            opcode |= 0b11011 << (32-31)   # bits 26-30
-            if rc:
-                opcode |= 1  # Rc, bit 31.
-            yield ".long 0x%x" % opcode
-        # argh, sv.ffadds etc. need to be done manually
-        elif v30b_op == 'ffadds':
-            opcode = 59 << (32-6)    # bits 0..6 (MSB0)
-            opcode |= int(v30b_newfields[0]) << (32-11)  # FRT
-            opcode |= int(v30b_newfields[1]) << (32-16)  # FRA
-            opcode |= int(v30b_newfields[2]) << (32-21)  # FRB
-            opcode |= 0b1111100000 << (32-31)   # bits 21-30
-            if rc:
-                opcode |= 1  # Rc, bit 31.
-            yield ".long 0x%x" % opcode
+        record = None
+        if os.environ.get("INSNDB"):
+            record = DB[opcode]
+        if record is not None:
+            insn = WordInstruction.assemble(db=DB,
+                opcode=opcode, arguments=fields)
+            yield " ".join((
+                f".long 0x{int(insn):08X}",
+                "#",
+                opcode,
+                ",".join(fields),
+            ))
         else:
             if not v30b_op.endswith('.'):
                 v30b_op += rc
@@ -1685,7 +1048,8 @@ def asm_process():
             macro = op[4:].split(",")
             (macro, value) = map(str.strip, macro)
             macros[macro] = value
-        if not op.startswith('sv.') and not op.startswith(tuple(CUSTOM_INSNS)):
+        record = DB[op]
+        if not op.startswith('sv.') and record is None:
             outfile.write(line)
             continue