diff options
author | jjanzen <jjanzen@jjanzen.ca> | 2025-02-26 23:23:37 -0600 |
---|---|---|
committer | jjanzen <jjanzen@jjanzen.ca> | 2025-02-26 23:23:37 -0600 |
commit | 0c7ae37e3f482255c80796414b708c8bc9f6ee87 (patch) | |
tree | 43f539a08842b5d04bda4f25cbe5984ef388aa22 /src/opcodes.zig |
initial commit
Diffstat (limited to 'src/opcodes.zig')
-rw-r--r-- | src/opcodes.zig | 1100 |
1 files changed, 1100 insertions, 0 deletions
diff --git a/src/opcodes.zig b/src/opcodes.zig new file mode 100644 index 0000000..7f43547 --- /dev/null +++ b/src/opcodes.zig @@ -0,0 +1,1100 @@ +const std = @import("std"); + +pub const PseudoOp = enum { + IS, + GREG, + LOC, + BYTE, + WYDE, + TETRA, + OCTA, +}; + +pub const Opcode = enum(u8) { + TRAP, + FCMP, + FUN, + FEQL, + FADD, + FIX, + FSUB, + FIXU, + FLOT, + FLOTI, + FLOTU, + FLOTUI, + SFLOT, + SFLOTI, + SFLOTU, + SFLOTUI, + FMUL, + FCMPE, + FUNE, + FEQLE, + FDIV, + FSQRT, + FREM, + FINT, + MUL, + MULI, + MULU, + MULUI, + DIV, + DIVI, + DIVU, + DIVUI, + ADD, + ADDI, + ADDU, + ADDUI, + SUB, + SUBI, + SUBU, + SUBUI, + _2ADDU, + _2ADDUI, + _4ADDU, + _4ADDUI, + _8ADDU, + _8ADDUI, + _16ADDU, + _16ADDUI, + CMP, + CMPI, + CMPU, + CMPUI, + NEG, + NEGI, + NEGU, + NEGUI, + SL, + SLI, + SLU, + SLUI, + SR, + SRI, + SRU, + SRUI, + BN, + BNB, + BZ, + BZB, + BP, + BPB, + BOD, + BODB, + BNN, + BNNB, + BNZ, + BNZB, + BNP, + BNPB, + BEV, + BEVB, + PBN, + PBNB, + PBZ, + PBZB, + PBP, + PBPB, + PBOD, + PBODB, + PBNN, + PBNNB, + PBNZ, + PBNZB, + PBNP, + PBNPB, + PBEV, + PBEVB, + CSN, + CSNI, + CSZ, + CSZI, + CSP, + CSPI, + CSOD, + CSODI, + CSNN, + CSNNI, + CSNZ, + CSNZI, + CSNP, + CSNPI, + CSEV, + CSEVI, + ZSN, + ZSNI, + ZSZ, + ZSZI, + ZSP, + ZSPI, + ZSOD, + ZSODI, + ZSNN, + ZSNNI, + ZSNZ, + ZSNZI, + ZSNP, + ZSNPI, + ZSEV, + ZSEVI, + LDB, + LDBI, + LDBU, + LDBUI, + LDW, + LDWI, + LDWU, + LDWUI, + LDT, + LDTI, + LDTU, + LDTUI, + LDO, + LDOI, + LDOU, + LDOUI, + LDSF, + LDSFI, + LDHT, + LDHTI, + CSWAP, + CSWAPI, + LDUNC, + LDUNCI, + LDVTS, + LDVTSI, + PRELD, + PRELDI, + PREGO, + PREGOI, + GO, + GOI, + STB, + STBI, + STBU, + STBUI, + STW, + STWI, + STWU, + STWUI, + STT, + STTI, + STTU, + STTUI, + STO, + STOI, + STOU, + STOUI, + STSF, + STSFI, + STHT, + STHTI, + STCO, + STCOI, + STUNC, + STUNCI, + SYNCD, + SYNCDI, + PREST, + PRESTI, + SYNCID, + SYNCIDI, + PUSHGO, + PUSHGOI, + OR, + ORI, + ORN, + ORNI, + NOR, + NORI, + XOR, + XORI, + AND, + ANDI, + ANDN, + ANDNI, + NAND, + NANDI, + NXOR, + NXORI, + BDIF, + BDIFI, + WDIF, + WDIFI, + TDIF, + TDIFI, + ODIF, + ODIFI, + MUX, + MUXI, + SADD, + SADDI, + MOR, + MORI, + MXOR, + MXORI, + SETH, + SETMH, + SETML, + SETL, + INCH, + INCMH, + INCML, + INCL, + ORH, + ORMH, + ORML, + ORL, + ANDNH, + ANDNMH, + ANDNML, + ANDNL, + JMP, + JMPB, + PUSHJ, + PUSHJB, + GETA, + GETAB, + PUT, + PUTI, + POP, + RESUME, + SAVE, + UNSAVE, + SYNC, + SWYM, + GET, + TRIP, +}; + +pub const OperationType = enum { + pseudo_op, + opcode, +}; + +pub const Operation = union(OperationType) { + pseudo_op: PseudoOp, + opcode: Opcode, +}; + +pub fn parseOp(allocator: std.mem.Allocator, text: []const u8) !Operation { + const upper_str = try std.ascii.allocUpperString(allocator, text); + + var out: Operation = undefined; + const opcode = getOpcode(upper_str) catch |err| { + if (err == error.NoOpcode) { + if (std.mem.eql(u8, upper_str, "IS")) { + out = Operation{ .pseudo_op = PseudoOp.IS }; + } else if (std.mem.eql(u8, upper_str, "GREG")) { + out = Operation{ .pseudo_op = PseudoOp.GREG }; + } else if (std.mem.eql(u8, upper_str, "LOC")) { + out = Operation{ .pseudo_op = PseudoOp.LOC }; + } else if (std.mem.eql(u8, upper_str, "BYTE")) { + out = Operation{ .pseudo_op = PseudoOp.BYTE }; + } else if (std.mem.eql(u8, upper_str, "WYDE")) { + out = Operation{ .pseudo_op = PseudoOp.WYDE }; + } else if (std.mem.eql(u8, upper_str, "TETRA")) { + out = Operation{ .pseudo_op = PseudoOp.TETRA }; + } else if (std.mem.eql(u8, upper_str, "OCTA")) { + out = Operation{ .pseudo_op = PseudoOp.OCTA }; + } else { + allocator.free(upper_str); + return err; + } + + allocator.free(upper_str); + + return out; + } + allocator.free(upper_str); + + return err; + }; + + allocator.free(upper_str); + return Operation{ .opcode = opcode }; +} + +fn getOpcode(upper_str: []const u8) !Opcode { + if (std.mem.eql(u8, upper_str, "TRAP")) { + return Opcode.TRAP; + } + if (std.mem.eql(u8, upper_str, "FCMP")) { + return Opcode.FCMP; + } + if (std.mem.eql(u8, upper_str, "FUN")) { + return Opcode.FUN; + } + if (std.mem.eql(u8, upper_str, "FEQL")) { + return Opcode.FEQL; + } + if (std.mem.eql(u8, upper_str, "FADD")) { + return Opcode.FADD; + } + if (std.mem.eql(u8, upper_str, "FIX")) { + return Opcode.FIX; + } + if (std.mem.eql(u8, upper_str, "FSUB")) { + return Opcode.FSUB; + } + if (std.mem.eql(u8, upper_str, "FIXU")) { + return Opcode.FIXU; + } + if (std.mem.eql(u8, upper_str, "FLOT")) { + return Opcode.FLOT; + } + if (std.mem.eql(u8, upper_str, "FLOTU")) { + return Opcode.FLOTU; + } + if (std.mem.eql(u8, upper_str, "SFLOT")) { + return Opcode.SFLOT; + } + if (std.mem.eql(u8, upper_str, "SFLOTU")) { + return Opcode.SFLOTU; + } + if (std.mem.eql(u8, upper_str, "FMUL")) { + return Opcode.FMUL; + } + if (std.mem.eql(u8, upper_str, "FCMPE")) { + return Opcode.FCMPE; + } + if (std.mem.eql(u8, upper_str, "FUNE")) { + return Opcode.FUNE; + } + if (std.mem.eql(u8, upper_str, "FEQLE")) { + return Opcode.FEQLE; + } + if (std.mem.eql(u8, upper_str, "FDIV")) { + return Opcode.FDIV; + } + if (std.mem.eql(u8, upper_str, "FSQRT")) { + return Opcode.FSQRT; + } + if (std.mem.eql(u8, upper_str, "FREM")) { + return Opcode.FREM; + } + if (std.mem.eql(u8, upper_str, "FINT")) { + return Opcode.FINT; + } + if (std.mem.eql(u8, upper_str, "MUL")) { + return Opcode.MUL; + } + if (std.mem.eql(u8, upper_str, "MULU")) { + return Opcode.MULU; + } + if (std.mem.eql(u8, upper_str, "DIV")) { + return Opcode.DIV; + } + if (std.mem.eql(u8, upper_str, "DIVU")) { + return Opcode.DIVU; + } + if (std.mem.eql(u8, upper_str, "ADD")) { + return Opcode.ADD; + } + if (std.mem.eql(u8, upper_str, "ADDU")) { + return Opcode.ADDU; + } + if (std.mem.eql(u8, upper_str, "SUB")) { + return Opcode.SUB; + } + if (std.mem.eql(u8, upper_str, "SUBU")) { + return Opcode.SUBU; + } + if (std.mem.eql(u8, upper_str, "2ADDU")) { + return Opcode._2ADDU; + } + if (std.mem.eql(u8, upper_str, "4ADDU")) { + return Opcode._4ADDU; + } + if (std.mem.eql(u8, upper_str, "8ADDU")) { + return Opcode._8ADDU; + } + if (std.mem.eql(u8, upper_str, "16ADDU")) { + return Opcode._16ADDU; + } + if (std.mem.eql(u8, upper_str, "CMP")) { + return Opcode.CMP; + } + if (std.mem.eql(u8, upper_str, "CMPU")) { + return Opcode.CMPU; + } + if (std.mem.eql(u8, upper_str, "NEG")) { + return Opcode.NEG; + } + if (std.mem.eql(u8, upper_str, "NEGU")) { + return Opcode.NEGU; + } + if (std.mem.eql(u8, upper_str, "SL")) { + return Opcode.SL; + } + if (std.mem.eql(u8, upper_str, "SLU")) { + return Opcode.SLU; + } + if (std.mem.eql(u8, upper_str, "SR")) { + return Opcode.SR; + } + if (std.mem.eql(u8, upper_str, "SRU")) { + return Opcode.SRU; + } + if (std.mem.eql(u8, upper_str, "BN")) { + return Opcode.BN; + } + if (std.mem.eql(u8, upper_str, "BZ")) { + return Opcode.BZ; + } + if (std.mem.eql(u8, upper_str, "BP")) { + return Opcode.BP; + } + if (std.mem.eql(u8, upper_str, "BOD")) { + return Opcode.BOD; + } + if (std.mem.eql(u8, upper_str, "BNN")) { + return Opcode.BNN; + } + if (std.mem.eql(u8, upper_str, "BNZ")) { + return Opcode.BNZ; + } + if (std.mem.eql(u8, upper_str, "BNP")) { + return Opcode.BNP; + } + if (std.mem.eql(u8, upper_str, "BEV")) { + return Opcode.BEV; + } + if (std.mem.eql(u8, upper_str, "PBN")) { + return Opcode.PBN; + } + if (std.mem.eql(u8, upper_str, "PBZ")) { + return Opcode.PBZ; + } + if (std.mem.eql(u8, upper_str, "PBP")) { + return Opcode.PBP; + } + if (std.mem.eql(u8, upper_str, "PBOD")) { + return Opcode.PBOD; + } + if (std.mem.eql(u8, upper_str, "PBNN")) { + return Opcode.PBNN; + } + if (std.mem.eql(u8, upper_str, "PBNZ")) { + return Opcode.PBNZ; + } + if (std.mem.eql(u8, upper_str, "PBNP")) { + return Opcode.PBNP; + } + if (std.mem.eql(u8, upper_str, "PBEV")) { + return Opcode.PBEV; + } + if (std.mem.eql(u8, upper_str, "CSN")) { + return Opcode.CSN; + } + if (std.mem.eql(u8, upper_str, "CSZ")) { + return Opcode.CSZ; + } + if (std.mem.eql(u8, upper_str, "CSP")) { + return Opcode.CSP; + } + if (std.mem.eql(u8, upper_str, "CSOD")) { + return Opcode.CSOD; + } + if (std.mem.eql(u8, upper_str, "CSNN")) { + return Opcode.CSNN; + } + if (std.mem.eql(u8, upper_str, "CSNZ")) { + return Opcode.CSNZ; + } + if (std.mem.eql(u8, upper_str, "CSNP")) { + return Opcode.CSNP; + } + if (std.mem.eql(u8, upper_str, "CSEV")) { + return Opcode.CSEV; + } + if (std.mem.eql(u8, upper_str, "ZSN")) { + return Opcode.ZSN; + } + if (std.mem.eql(u8, upper_str, "ZSZ")) { + return Opcode.ZSZ; + } + if (std.mem.eql(u8, upper_str, "ZSP")) { + return Opcode.ZSP; + } + if (std.mem.eql(u8, upper_str, "ZSOD")) { + return Opcode.ZSOD; + } + if (std.mem.eql(u8, upper_str, "ZSNN")) { + return Opcode.ZSNN; + } + if (std.mem.eql(u8, upper_str, "ZSNZ")) { + return Opcode.ZSNZ; + } + if (std.mem.eql(u8, upper_str, "ZSNP")) { + return Opcode.ZSNP; + } + if (std.mem.eql(u8, upper_str, "ZSEV")) { + return Opcode.ZSEV; + } + if (std.mem.eql(u8, upper_str, "LDB")) { + return Opcode.LDB; + } + if (std.mem.eql(u8, upper_str, "LDBU")) { + return Opcode.LDBU; + } + if (std.mem.eql(u8, upper_str, "LDW")) { + return Opcode.LDW; + } + if (std.mem.eql(u8, upper_str, "LDWU")) { + return Opcode.LDWU; + } + if (std.mem.eql(u8, upper_str, "LDT")) { + return Opcode.LDT; + } + if (std.mem.eql(u8, upper_str, "LDTU")) { + return Opcode.LDTU; + } + if (std.mem.eql(u8, upper_str, "LDO")) { + return Opcode.LDO; + } + if (std.mem.eql(u8, upper_str, "LDOU")) { + return Opcode.LDOU; + } + if (std.mem.eql(u8, upper_str, "LDSF")) { + return Opcode.LDSF; + } + if (std.mem.eql(u8, upper_str, "LDHT")) { + return Opcode.LDHT; + } + if (std.mem.eql(u8, upper_str, "CSWAP")) { + return Opcode.CSWAP; + } + if (std.mem.eql(u8, upper_str, "LDUNC")) { + return Opcode.LDUNC; + } + if (std.mem.eql(u8, upper_str, "LDVTS")) { + return Opcode.LDVTS; + } + if (std.mem.eql(u8, upper_str, "PRELD")) { + return Opcode.PRELD; + } + if (std.mem.eql(u8, upper_str, "PREGO")) { + return Opcode.PREGO; + } + if (std.mem.eql(u8, upper_str, "GO")) { + return Opcode.GO; + } + if (std.mem.eql(u8, upper_str, "STB")) { + return Opcode.STB; + } + if (std.mem.eql(u8, upper_str, "STBU")) { + return Opcode.STBU; + } + if (std.mem.eql(u8, upper_str, "STW")) { + return Opcode.STW; + } + if (std.mem.eql(u8, upper_str, "STWU")) { + return Opcode.STWU; + } + if (std.mem.eql(u8, upper_str, "STT")) { + return Opcode.STT; + } + if (std.mem.eql(u8, upper_str, "STTU")) { + return Opcode.STTU; + } + if (std.mem.eql(u8, upper_str, "STO")) { + return Opcode.STO; + } + if (std.mem.eql(u8, upper_str, "STOU")) { + return Opcode.STOU; + } + if (std.mem.eql(u8, upper_str, "STSF")) { + return Opcode.STSF; + } + if (std.mem.eql(u8, upper_str, "STHT")) { + return Opcode.STHT; + } + if (std.mem.eql(u8, upper_str, "STCO")) { + return Opcode.STCO; + } + if (std.mem.eql(u8, upper_str, "STUNC")) { + return Opcode.STUNC; + } + if (std.mem.eql(u8, upper_str, "SYNCD")) { + return Opcode.SYNCD; + } + if (std.mem.eql(u8, upper_str, "PREST")) { + return Opcode.PREST; + } + if (std.mem.eql(u8, upper_str, "SYNCID")) { + return Opcode.SYNCID; + } + if (std.mem.eql(u8, upper_str, "PUSHGO")) { + return Opcode.PUSHGO; + } + if (std.mem.eql(u8, upper_str, "OR")) { + return Opcode.OR; + } + if (std.mem.eql(u8, upper_str, "ORN")) { + return Opcode.ORN; + } + if (std.mem.eql(u8, upper_str, "NOR")) { + return Opcode.NOR; + } + if (std.mem.eql(u8, upper_str, "XOR")) { + return Opcode.XOR; + } + if (std.mem.eql(u8, upper_str, "AND")) { + return Opcode.AND; + } + if (std.mem.eql(u8, upper_str, "ANDN")) { + return Opcode.ANDN; + } + if (std.mem.eql(u8, upper_str, "NAND")) { + return Opcode.NAND; + } + if (std.mem.eql(u8, upper_str, "NXOR")) { + return Opcode.NXOR; + } + if (std.mem.eql(u8, upper_str, "BDIF")) { + return Opcode.BDIF; + } + if (std.mem.eql(u8, upper_str, "WDIF")) { + return Opcode.WDIF; + } + if (std.mem.eql(u8, upper_str, "TDIF")) { + return Opcode.TDIF; + } + if (std.mem.eql(u8, upper_str, "ODIF")) { + return Opcode.ODIF; + } + if (std.mem.eql(u8, upper_str, "MUX")) { + return Opcode.MUX; + } + if (std.mem.eql(u8, upper_str, "SADD")) { + return Opcode.SADD; + } + if (std.mem.eql(u8, upper_str, "MOR")) { + return Opcode.MOR; + } + if (std.mem.eql(u8, upper_str, "MXOR")) { + return Opcode.MXOR; + } + if (std.mem.eql(u8, upper_str, "SETH")) { + return Opcode.SETH; + } + if (std.mem.eql(u8, upper_str, "SETMH")) { + return Opcode.SETMH; + } + if (std.mem.eql(u8, upper_str, "SETML")) { + return Opcode.SETML; + } + if (std.mem.eql(u8, upper_str, "SETL")) { + return Opcode.SETL; + } + if (std.mem.eql(u8, upper_str, "INCH")) { + return Opcode.INCH; + } + if (std.mem.eql(u8, upper_str, "INCMH")) { + return Opcode.INCMH; + } + if (std.mem.eql(u8, upper_str, "INCML")) { + return Opcode.INCML; + } + if (std.mem.eql(u8, upper_str, "INCL")) { + return Opcode.INCL; + } + if (std.mem.eql(u8, upper_str, "ORH")) { + return Opcode.ORH; + } + if (std.mem.eql(u8, upper_str, "ORMH")) { + return Opcode.ORMH; + } + if (std.mem.eql(u8, upper_str, "ORML")) { + return Opcode.ORML; + } + if (std.mem.eql(u8, upper_str, "ORL")) { + return Opcode.ORL; + } + if (std.mem.eql(u8, upper_str, "ANDNH")) { + return Opcode.ANDNH; + } + if (std.mem.eql(u8, upper_str, "ANDNMH")) { + return Opcode.ANDNMH; + } + if (std.mem.eql(u8, upper_str, "ANDNML")) { + return Opcode.ANDNML; + } + if (std.mem.eql(u8, upper_str, "ANDNL")) { + return Opcode.ANDNL; + } + if (std.mem.eql(u8, upper_str, "JMP")) { + return Opcode.JMP; + } + if (std.mem.eql(u8, upper_str, "PUSHJ")) { + return Opcode.PUSHJ; + } + if (std.mem.eql(u8, upper_str, "GETA")) { + return Opcode.GETA; + } + if (std.mem.eql(u8, upper_str, "PUT")) { + return Opcode.PUT; + } + if (std.mem.eql(u8, upper_str, "POP")) { + return Opcode.POP; + } + if (std.mem.eql(u8, upper_str, "RESUME")) { + return Opcode.RESUME; + } + if (std.mem.eql(u8, upper_str, "SAVE")) { + return Opcode.SAVE; + } + if (std.mem.eql(u8, upper_str, "UNSAVE")) { + return Opcode.UNSAVE; + } + if (std.mem.eql(u8, upper_str, "SYNC")) { + return Opcode.SYNC; + } + if (std.mem.eql(u8, upper_str, "SWYM")) { + return Opcode.SWYM; + } + if (std.mem.eql(u8, upper_str, "GET")) { + return Opcode.GET; + } + if (std.mem.eql(u8, upper_str, "TRIP")) { + return Opcode.TRIP; + } + + return error.NoOpcode; +} + +test "Opcodes encode correctly" { + const test_cases = [_][]const u8{ + // opcodes + "TRAP", + "FCMP", + "FUN", + "FEQL", + "FADD", + "FIX", + "FSUB", + "FIXU", + "FLOT", + "FLOTU", + "SFLOT", + "SFLOTU", + "FMUL", + "FCMPE", + "FUNE", + "FEQLE", + "FDIV", + "FSQRT", + "FREM", + "FINT", + "MUL", + "MULU", + "DIV", + "DIVU", + "ADD", + "ADDU", + "SUB", + "SUBU", + "2ADDU", + "4ADDU", + "8ADDU", + "16ADDU", + "CMP", + "CMPU", + "NEG", + "NEGU", + "SL", + "SLU", + "SR", + "SRU", + "BN", + "BZ", + "BP", + "BOD", + "BNN", + "BNZ", + "BNP", + "BEV", + "PBN", + "PBZ", + "PBP", + "PBOD", + "PBNN", + "PBNZ", + "PBNP", + "PBEV", + "CSN", + "CSZ", + "CSP", + "CSOD", + "CSNN", + "CSNZ", + "CSNP", + "CSEV", + "ZSN", + "ZSZ", + "ZSP", + "ZSOD", + "ZSNN", + "ZSNZ", + "ZSNP", + "ZSEV", + "LDB", + "LDBU", + "LDW", + "LDWU", + "LDT", + "LDTU", + "LDO", + "LDOU", + "LDSF", + "LDHT", + "CSWAP", + "LDUNC", + "LDVTS", + "PRELD", + "PREGO", + "GO", + "STB", + "STBU", + "STW", + "STWU", + "STT", + "STTU", + "STO", + "STOU", + "STSF", + "STHT", + "STCO", + "STUNC", + "SYNCD", + "PREST", + "SYNCID", + "PUSHGO", + "OR", + "ORN", + "NOR", + "XOR", + "AND", + "ANDN", + "NAND", + "NXOR", + "BDIF", + "WDIF", + "TDIF", + "ODIF", + "MUX", + "SADD", + "MOR", + "MXOR", + "SETH", + "SETMH", + "SETML", + "SETL", + "INCH", + "INCMH", + "INCML", + "INCL", + "ORH", + "ORMH", + "ORML", + "ORL", + "ANDNH", + "ANDNMH", + "ANDNML", + "ANDNL", + "JMP", + "PUSHJ", + "GETA", + "PUT", + "POP", + "RESUME", + "SAVE", + "UNSAVE", + "SYNC", + "SWYM", + "GET", + "TRIP", + + // pseudo ops + "IS", + "GREG", + "LOC", + "BYTE", + "WYDE", + "TETRA", + "OCTA", + }; + + const expected = [_]Operation{ + Operation{ .opcode = Opcode.TRAP }, + Operation{ .opcode = Opcode.FCMP }, + Operation{ .opcode = Opcode.FUN }, + Operation{ .opcode = Opcode.FEQL }, + Operation{ .opcode = Opcode.FADD }, + Operation{ .opcode = Opcode.FIX }, + Operation{ .opcode = Opcode.FSUB }, + Operation{ .opcode = Opcode.FIXU }, + Operation{ .opcode = Opcode.FLOT }, + Operation{ .opcode = Opcode.FLOTU }, + Operation{ .opcode = Opcode.SFLOT }, + Operation{ .opcode = Opcode.SFLOTU }, + Operation{ .opcode = Opcode.FMUL }, + Operation{ .opcode = Opcode.FCMPE }, + Operation{ .opcode = Opcode.FUNE }, + Operation{ .opcode = Opcode.FEQLE }, + Operation{ .opcode = Opcode.FDIV }, + Operation{ .opcode = Opcode.FSQRT }, + Operation{ .opcode = Opcode.FREM }, + Operation{ .opcode = Opcode.FINT }, + Operation{ .opcode = Opcode.MUL }, + Operation{ .opcode = Opcode.MULU }, + Operation{ .opcode = Opcode.DIV }, + Operation{ .opcode = Opcode.DIVU }, + Operation{ .opcode = Opcode.ADD }, + Operation{ .opcode = Opcode.ADDU }, + Operation{ .opcode = Opcode.SUB }, + Operation{ .opcode = Opcode.SUBU }, + Operation{ .opcode = Opcode._2ADDU }, + Operation{ .opcode = Opcode._4ADDU }, + Operation{ .opcode = Opcode._8ADDU }, + Operation{ .opcode = Opcode._16ADDU }, + Operation{ .opcode = Opcode.CMP }, + Operation{ .opcode = Opcode.CMPU }, + Operation{ .opcode = Opcode.NEG }, + Operation{ .opcode = Opcode.NEGU }, + Operation{ .opcode = Opcode.SL }, + Operation{ .opcode = Opcode.SLU }, + Operation{ .opcode = Opcode.SR }, + Operation{ .opcode = Opcode.SRU }, + Operation{ .opcode = Opcode.BN }, + Operation{ .opcode = Opcode.BZ }, + Operation{ .opcode = Opcode.BP }, + Operation{ .opcode = Opcode.BOD }, + Operation{ .opcode = Opcode.BNN }, + Operation{ .opcode = Opcode.BNZ }, + Operation{ .opcode = Opcode.BNP }, + Operation{ .opcode = Opcode.BEV }, + Operation{ .opcode = Opcode.PBN }, + Operation{ .opcode = Opcode.PBZ }, + Operation{ .opcode = Opcode.PBP }, + Operation{ .opcode = Opcode.PBOD }, + Operation{ .opcode = Opcode.PBNN }, + Operation{ .opcode = Opcode.PBNZ }, + Operation{ .opcode = Opcode.PBNP }, + Operation{ .opcode = Opcode.PBEV }, + Operation{ .opcode = Opcode.CSN }, + Operation{ .opcode = Opcode.CSZ }, + Operation{ .opcode = Opcode.CSP }, + Operation{ .opcode = Opcode.CSOD }, + Operation{ .opcode = Opcode.CSNN }, + Operation{ .opcode = Opcode.CSNZ }, + Operation{ .opcode = Opcode.CSNP }, + Operation{ .opcode = Opcode.CSEV }, + Operation{ .opcode = Opcode.ZSN }, + Operation{ .opcode = Opcode.ZSZ }, + Operation{ .opcode = Opcode.ZSP }, + Operation{ .opcode = Opcode.ZSOD }, + Operation{ .opcode = Opcode.ZSNN }, + Operation{ .opcode = Opcode.ZSNZ }, + Operation{ .opcode = Opcode.ZSNP }, + Operation{ .opcode = Opcode.ZSEV }, + Operation{ .opcode = Opcode.LDB }, + Operation{ .opcode = Opcode.LDBU }, + Operation{ .opcode = Opcode.LDW }, + Operation{ .opcode = Opcode.LDWU }, + Operation{ .opcode = Opcode.LDT }, + Operation{ .opcode = Opcode.LDTU }, + Operation{ .opcode = Opcode.LDO }, + Operation{ .opcode = Opcode.LDOU }, + Operation{ .opcode = Opcode.LDSF }, + Operation{ .opcode = Opcode.LDHT }, + Operation{ .opcode = Opcode.CSWAP }, + Operation{ .opcode = Opcode.LDUNC }, + Operation{ .opcode = Opcode.LDVTS }, + Operation{ .opcode = Opcode.PRELD }, + Operation{ .opcode = Opcode.PREGO }, + Operation{ .opcode = Opcode.GO }, + Operation{ .opcode = Opcode.STB }, + Operation{ .opcode = Opcode.STBU }, + Operation{ .opcode = Opcode.STW }, + Operation{ .opcode = Opcode.STWU }, + Operation{ .opcode = Opcode.STT }, + Operation{ .opcode = Opcode.STTU }, + Operation{ .opcode = Opcode.STO }, + Operation{ .opcode = Opcode.STOU }, + Operation{ .opcode = Opcode.STSF }, + Operation{ .opcode = Opcode.STHT }, + Operation{ .opcode = Opcode.STCO }, + Operation{ .opcode = Opcode.STUNC }, + Operation{ .opcode = Opcode.SYNCD }, + Operation{ .opcode = Opcode.PREST }, + Operation{ .opcode = Opcode.SYNCID }, + Operation{ .opcode = Opcode.PUSHGO }, + Operation{ .opcode = Opcode.OR }, + Operation{ .opcode = Opcode.ORN }, + Operation{ .opcode = Opcode.NOR }, + Operation{ .opcode = Opcode.XOR }, + Operation{ .opcode = Opcode.AND }, + Operation{ .opcode = Opcode.ANDN }, + Operation{ .opcode = Opcode.NAND }, + Operation{ .opcode = Opcode.NXOR }, + Operation{ .opcode = Opcode.BDIF }, + Operation{ .opcode = Opcode.WDIF }, + Operation{ .opcode = Opcode.TDIF }, + Operation{ .opcode = Opcode.ODIF }, + Operation{ .opcode = Opcode.MUX }, + Operation{ .opcode = Opcode.SADD }, + Operation{ .opcode = Opcode.MOR }, + Operation{ .opcode = Opcode.MXOR }, + Operation{ .opcode = Opcode.SETH }, + Operation{ .opcode = Opcode.SETMH }, + Operation{ .opcode = Opcode.SETML }, + Operation{ .opcode = Opcode.SETL }, + Operation{ .opcode = Opcode.INCH }, + Operation{ .opcode = Opcode.INCMH }, + Operation{ .opcode = Opcode.INCML }, + Operation{ .opcode = Opcode.INCL }, + Operation{ .opcode = Opcode.ORH }, + Operation{ .opcode = Opcode.ORMH }, + Operation{ .opcode = Opcode.ORML }, + Operation{ .opcode = Opcode.ORL }, + Operation{ .opcode = Opcode.ANDNH }, + Operation{ .opcode = Opcode.ANDNMH }, + Operation{ .opcode = Opcode.ANDNML }, + Operation{ .opcode = Opcode.ANDNL }, + Operation{ .opcode = Opcode.JMP }, + Operation{ .opcode = Opcode.PUSHJ }, + Operation{ .opcode = Opcode.GETA }, + Operation{ .opcode = Opcode.PUT }, + Operation{ .opcode = Opcode.POP }, + Operation{ .opcode = Opcode.RESUME }, + Operation{ .opcode = Opcode.SAVE }, + Operation{ .opcode = Opcode.UNSAVE }, + Operation{ .opcode = Opcode.SYNC }, + Operation{ .opcode = Opcode.SWYM }, + Operation{ .opcode = Opcode.GET }, + Operation{ .opcode = Opcode.TRIP }, + Operation{ .pseudo_op = PseudoOp.IS }, + Operation{ .pseudo_op = PseudoOp.GREG }, + Operation{ .pseudo_op = PseudoOp.LOC }, + Operation{ .pseudo_op = PseudoOp.BYTE }, + Operation{ .pseudo_op = PseudoOp.WYDE }, + Operation{ .pseudo_op = PseudoOp.TETRA }, + Operation{ .pseudo_op = PseudoOp.OCTA }, + }; + + for (0..test_cases.len) |i| { + const operation = try parseOp(std.testing.allocator, test_cases[i]); + try std.testing.expectEqual(expected[i], operation); + } +} + +test "Invalid opcodes return error" { + var operation = parseOp(std.testing.allocator, "ALKSFDJ"); + try std.testing.expectEqual(error.NoOpcode, operation); + operation = parseOp(std.testing.allocator, "ADDI"); + try std.testing.expectEqual(error.NoOpcode, operation); +} |