// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <gtest/gtest.h>

#include <string_view>
#include <vector>

#include "Common/Assembler/GekkoAssembler.h"

using namespace Common::GekkoAssembler;

constexpr char instructions[] = "add r3, r4, r5\n"
                                "add. r3, r4, r5\n"
                                "addo r3, r4, r5\n"
                                "addo. r3, r4, r5\n"
                                "addc r3, r4, r5\n"
                                "addc. r3, r4, r5\n"
                                "addco r3, r4, r5\n"
                                "addco. r3, r4, r5\n"
                                "adde r3, r4, r5\n"
                                "adde. r3, r4, r5\n"
                                "addeo r3, r4, r5\n"
                                "addeo. r3, r4, r5\n"
                                "addme r3, r4\n"
                                "addme. r3, r4\n"
                                "addmeo r3, r4\n"
                                "addmeo. r3, r4\n"
                                "addze r3, r4\n"
                                "addze. r3, r4\n"
                                "addzeo r3, r4\n"
                                "addzeo. r3, r4\n"
                                "divw r3, r4, r5\n"
                                "divw. r3, r4, r5\n"
                                "divwo r3, r4, r5\n"
                                "divwo. r3, r4, r5\n"
                                "divwu r3, r4, r5\n"
                                "divwu. r3, r4, r5\n"
                                "divwuo r3, r4, r5\n"
                                "divwuo. r3, r4, r5\n"
                                "mullw r3, r4, r5\n"
                                "mullw. r3, r4, r5\n"
                                "mullwo r3, r4, r5\n"
                                "mullwo. r3, r4, r5\n"
                                "neg r3, r4\n"
                                "neg. r3, r4\n"
                                "nego r3, r4\n"
                                "nego. r3, r4\n"
                                "subf r3, r4, r5\n"
                                "subf. r3, r4, r5\n"
                                "subfo r3, r4, r5\n"
                                "subfo. r3, r4, r5\n"
                                "subfc r3, r4, r5\n"
                                "subfc. r3, r4, r5\n"
                                "subfco r3, r4, r5\n"
                                "subfco. r3, r4, r5\n"
                                "subfe r3, r4, r5\n"
                                "subfe. r3, r4, r5\n"
                                "subfeo r3, r4, r5\n"
                                "subfeo. r3, r4, r5\n"
                                "subfme r3, r4\n"
                                "subfme. r3, r4\n"
                                "subfmeo r3, r4\n"
                                "subfmeo. r3, r4\n"
                                "subfze r3, r4\n"
                                "subfze. r3, r4\n"
                                "subfzeo r3, r4\n"
                                "subfzeo. r3, r4\n"
                                "addi r3, r4, 1000\n"
                                "addic r3, r4, 1000\n"
                                "addic. r3, r4, 1000\n"
                                "addis r3, r4, 1000\n"
                                "mulli r3, r4, 1000\n"
                                "subfic r3, r4, 1000\n"
                                "cmpi cr1, 0, r4, 1000\n"
                                "cmpli cr1, 0, r4, 1000\n"
                                "andi. r4, r6, 1000\n"
                                "andis. r4, r6, 1000\n"
                                "ori r4, r6, 1000\n"
                                "oris r4, r6, 1000\n"
                                "xori r4, r6, 1000\n"
                                "xoris r4, r6, 1000\n"
                                "lbz r3, 100(r4)\n"
                                "lbzu r3, 100( r4)\n"
                                "lha r3, 100( r4)\n"
                                "lhau r3, 100( r4)\n"
                                "lhz r3, 100( r4)\n"
                                "lhzu r3, 100( r4)\n"
                                "lwz r3, 100( r4)\n"
                                "lwzu r3, 100( r4)\n"
                                "stb r6, 100( r4)\n"
                                "stbu r6, 100( r4)\n"
                                "sth r6, 100( r4)\n"
                                "sthu r6, 100( r4)\n"
                                "stw r6, 100( r4)\n"
                                "stwu r6, 100( r4)\n"
                                "lmw r6, 100( r4)\n"
                                "stmw r6, 100( r4)\n"
                                "lfd r3, 100( r4)\n"
                                "lfdu r3, 100( r4)\n"
                                "lfs r3, 100( r4)\n"
                                "lfsu r3, 100( r4)\n"
                                "stfd r6, 100( r4)\n"
                                "stfdu r6, 100( r4)\n"
                                "stfs r6, 100( r4)\n"
                                "stfsu r6, 100( r4)\n"
                                "twi 8, r4, 1000\n"
                                "psq_l r3, 200( r4), 0, 2\n"
                                "psq_lu r3, 200( r4), 0, 2\n"
                                "psq_st r6, 200( r4), 0, 2\n"
                                "psq_stu r6, 200( r4), 0, 2\n"
                                "mulhw r3, r4, r5\n"
                                "mulhw. r3, r4, r5\n"
                                "mulhwu r3, r4, r5\n"
                                "mulhwu. r3, r4, r5\n"
                                "and r4, r6, r5\n"
                                "and. r4, r6, r5\n"
                                "andc r4, r6, r5\n"
                                "andc. r4, r6, r5\n"
                                "cntlzw r4, r6\n"
                                "cntlzw. r4, r6\n"
                                "eqv r4, r6, r5\n"
                                "eqv. r4, r6, r5\n"
                                "extsb r4, r6\n"
                                "extsb. r4, r6\n"
                                "extsh r4, r6\n"
                                "extsh. r4, r6\n"
                                "nand r4, r6, r5\n"
                                "nand. r4, r6, r5\n"
                                "nor r4, r6, r5\n"
                                "nor. r4, r6, r5\n"
                                "or r4, r6, r5\n"
                                "or. r4, r6, r5\n"
                                "orc r4, r6, r5\n"
                                "orc. r4, r6, r5\n"
                                "xor r4, r6, r5\n"
                                "xor. r4, r6, r5\n"
                                "rlwimi r4, r6, 0, 10, 15\n"
                                "rlwimi. r4, r6, 0, 10, 15\n"
                                "rlwinm r4, r6, 0, 10, 15\n"
                                "rlwinm. r4, r6, 0, 10, 15\n"
                                "rlwnm r4, r6, r5, 10, 15\n"
                                "rlwnm. r4, r6, r5, 10, 15\n"
                                "slw r4, r6, r5\n"
                                "slw. r4, r6, r5\n"
                                "sraw r4, r6, r5\n"
                                "sraw. r4, r6, r5\n"
                                "srawi r4, r6, 0\n"
                                "srawi. r4, r6, 0\n"
                                "srw r4, r6, r5\n"
                                "srw. r4, r6, r5\n"
                                "fadd r3, r4, r5\n"
                                "fadd. r3, r4, r5\n"
                                "fadds r3, r4, r5\n"
                                "fadds. r3, r4, r5\n"
                                "fdiv r3, r4, r5\n"
                                "fdiv. r3, r4, r5\n"
                                "fdivs r3, r4, r5\n"
                                "fdivs. r3, r4, r5\n"
                                "fmul r3, r4, r7\n"
                                "fmul. r3, r4, r7\n"
                                "fmuls r3, r4, r7\n"
                                "fmuls. r3, r4, r7\n"
                                "fres r3, r5\n"
                                "fres. r3, r5\n"
                                "frsqrte r3, r5\n"
                                "frsqrte. r3, r5\n"
                                "fsub r3, r4, r5\n"
                                "fsub. r3, r4, r5\n"
                                "fsubs r3, r4, r5\n"
                                "fsubs. r3, r4, r5\n"
                                "fsel r3, r4, r7, r5\n"
                                "fsel. r3, r4, r7, r5\n"
                                "fmadd r3, r4, r7, r5\n"
                                "fmadd. r3, r4, r7, r5\n"
                                "fmadds r3, r4, r7, r5\n"
                                "fmadds. r3, r4, r7, r5\n"
                                "fmsub r3, r4, r7, r5\n"
                                "fmsub. r3, r4, r7, r5\n"
                                "fmsubs r3, r4, r7, r5\n"
                                "fmsubs. r3, r4, r7, r5\n"
                                "fnmadd r3, r4, r7, r5\n"
                                "fnmadd. r3, r4, r7, r5\n"
                                "fnmadds r3, r4, r7, r5\n"
                                "fnmadds. r3, r4, r7, r5\n"
                                "fnmsub r3, r4, r7, r5\n"
                                "fnmsub. r3, r4, r7, r5\n"
                                "fnmsubs r3, r4, r7, r5\n"
                                "fnmsubs. r3, r4, r7, r5\n"
                                "fctiw r3, r5\n"
                                "fctiw. r3, r5\n"
                                "fctiwz r3, r5\n"
                                "fctiwz. r3, r5\n"
                                "frsp r3, r5\n"
                                "frsp. r3, r5\n"
                                "mffs r3\n"
                                "mffs. r3\n"
                                "mtfsb0 21\n"
                                "mtfsb0. 21\n"
                                "mtfsb1 21\n"
                                "mtfsb1. 21\n"
                                "mtfsf 255, r5\n"
                                "mtfsf. 255, r5\n"
                                "mtfsfi cr1, 5\n"
                                "mtfsfi. cr1, 5\n"
                                "fabs r3, r5\n"
                                "fabs. r3, r5\n"
                                "fmr r3, r5\n"
                                "fmr. r3, r5\n"
                                "fnabs r3, r5\n"
                                "fnabs. r3, r5\n"
                                "fneg r3, r5\n"
                                "fneg. r3, r5\n"
                                "ps_div r3, r4, r5\n"
                                "ps_div. r3, r4, r5\n"
                                "ps_sub r3, r4, r5\n"
                                "ps_sub. r3, r4, r5\n"
                                "ps_add r3, r4, r5\n"
                                "ps_add. r3, r4, r5\n"
                                "ps_sel r3, r4, r7, r5\n"
                                "ps_sel. r3, r4, r7, r5\n"
                                "ps_res r3, r5\n"
                                "ps_res. r3, r5\n"
                                "ps_mul r3, r4, r7\n"
                                "ps_mul. r3, r4, r7\n"
                                "ps_rsqrte r3, r5\n"
                                "ps_rsqrte. r3, r5\n"
                                "ps_msub r3, r4, r7, r5\n"
                                "ps_msub. r3, r4, r7, r5\n"
                                "ps_madd r3, r4, r7, r5\n"
                                "ps_madd. r3, r4, r7, r5\n"
                                "ps_nmsub r3, r4, r7, r5\n"
                                "ps_nmsub. r3, r4, r7, r5\n"
                                "ps_nmadd r3, r4, r7, r5\n"
                                "ps_nmadd. r3, r4, r7, r5\n"
                                "ps_neg r3, r5\n"
                                "ps_neg. r3, r5\n"
                                "ps_mr r3, r5\n"
                                "ps_mr. r3, r5\n"
                                "ps_nabs r3, r5\n"
                                "ps_nabs. r3, r5\n"
                                "ps_abs r3, r5\n"
                                "ps_abs. r3, r5\n"
                                "ps_sum0 r3, r4, r7, r5\n"
                                "ps_sum0. r3, r4, r7, r5\n"
                                "ps_sum1 r3, r4, r7, r5\n"
                                "ps_sum1. r3, r4, r7, r5\n"
                                "ps_muls0 r3, r4, r7\n"
                                "ps_muls0. r3, r4, r7\n"
                                "ps_muls1 r3, r4, r7\n"
                                "ps_muls1. r3, r4, r7\n"
                                "ps_madds0 r3, r4, r7, r5\n"
                                "ps_madds0. r3, r4, r7, r5\n"
                                "ps_madds1 r3, r4, r7, r5\n"
                                "ps_madds1. r3, r4, r7, r5\n"
                                "ps_merge00 r3, r4, r5\n"
                                "ps_merge00. r3, r4, r5\n"
                                "ps_merge01 r3, r4, r5\n"
                                "ps_merge01. r3, r4, r5\n"
                                "ps_merge10 r3, r4, r5\n"
                                "ps_merge10. r3, r4, r5\n"
                                "ps_merge11 r3, r4, r5\n"
                                "ps_merge11. r3, r4, r5\n"
                                "cmp cr1, 0, r4, r5\n"
                                "cmpl cr1, 0, r4, r5\n"
                                "fcmpo cr1, r4, r5\n"
                                "fcmpu cr1, r4, r5\n"
                                "mcrfs cr1, 7\n"
                                "lbzux r3, r4, r5\n"
                                "lbzx r3, r4, r5\n"
                                "lhaux r3, r4, r5\n"
                                "lhax r3, r4, r5\n"
                                "lhzux r3, r4, r5\n"
                                "lhzx r3, r4, r5\n"
                                "lwzux r3, r4, r5\n"
                                "lwzx r3, r4, r5\n"
                                "stbux r6, r4, r5\n"
                                "stbx r6, r4, r5\n"
                                "sthux r6, r4, r5\n"
                                "sthx r6, r4, r5\n"
                                "stwux r6, r4, r5\n"
                                "stwx r6, r4, r5\n"
                                "lhbrx r3, r4, r5\n"
                                "lwbrx r3, r4, r5\n"
                                "sthbrx r6, r4, r5\n"
                                "stwbrx r6, r4, r5\n"
                                "lswi r5, r4, 1\n"
                                "lswx r3, r4, r5\n"
                                "stswi r6, r4, 1\n"
                                "stswx r6, r4, r5\n"
                                "lwarx r3, r4, r5\n"
                                "stwcx. r6, r4, r5\n"
                                "lfdux r3, r4, r5\n"
                                "lfdx r3, r4, r5\n"
                                "lfsux r3, r4, r5\n"
                                "lfsx r3, r4, r5\n"
                                "stfdux r6, r4, r5\n"
                                "stfdx r6, r4, r5\n"
                                "stfiwx r6, r4, r5\n"
                                "stfsux r6, r4, r5\n"
                                "stfsx r6, r4, r5\n"
                                "crand 21, 22, 23\n"
                                "crandc 21, 22, 23\n"
                                "creqv 21, 22, 23\n"
                                "crnand 21, 22, 23\n"
                                "crnor 21, 22, 23\n"
                                "cror 21, 22, 23\n"
                                "crorc 21, 22, 23\n"
                                "crxor 21, 22, 23\n"
                                "mcrf cr1, 7\n"
                                "tw 8, r4, r5\n"
                                "mcrxr cr1\n"
                                "mfcr r3\n"
                                "mfmsr r3\n"
                                "mfspr r3, LR\n"
                                "mftb r3, 268\n"
                                "mtcrf 255, r6\n"
                                "mtmsr r6\n"
                                "mtspr LR, r3\n"
                                "dcbf r4, r5\n"
                                "dcbi r4, r5\n"
                                "dcbst r4, r5\n"
                                "dcbt r4, r5\n"
                                "dcbtst r4, r5\n"
                                "dcbz r4, r5\n"
                                "icbi r4, r5\n"
                                "mfsr r3, 0\n"
                                "mfsrin r3, r5\n"
                                "mtsr 0, r6\n"
                                "mtsrin r6, r5\n"
                                "tlbie r5\n"
                                "eciwx r3, r4, r5\n"
                                "ecowx r6, r4, r5\n"
                                "psq_lx r3, r4, r5, 0, 2\n"
                                "psq_stx r6, r4, r5, 0, 2\n"
                                "psq_lux r3, r4, r5, 0, 2\n"
                                "psq_stux r6, r4, r5, 0, 2\n"
                                "ps_cmpu0 cr1, r4, r5\n"
                                "ps_cmpo0 cr1, r4, r5\n"
                                "ps_cmpu1 cr1, r4, r5\n"
                                "ps_cmpo1 cr1, r4, r5\n"
                                "dcbz_l r4, r5\n"
                                "b 0x1000\n"
                                "ba 0x1000\n"
                                "bl 0x1000\n"
                                "bla 0x1000\n"
                                "bc 12, 2, -0xc\n"
                                "bca 12, 2, -0xc\n"
                                "bcl 12, 2, -0xc\n"
                                "bcla 12, 2, -0xc\n"
                                "bcctr 12, 2\n"
                                "bcctrl 12, 2\n"
                                "bclr 12, 2\n"
                                "bclrl 12, 2\n";

constexpr u8 expected_instructions[] = {
    0x7c, 0x64, 0x2a, 0x14, 0x7c, 0x64, 0x2a, 0x15, 0x7c, 0x64, 0x2e, 0x14, 0x7c, 0x64, 0x2e, 0x15,
    0x7c, 0x64, 0x28, 0x14, 0x7c, 0x64, 0x28, 0x15, 0x7c, 0x64, 0x2c, 0x14, 0x7c, 0x64, 0x2c, 0x15,
    0x7c, 0x64, 0x29, 0x14, 0x7c, 0x64, 0x29, 0x15, 0x7c, 0x64, 0x2d, 0x14, 0x7c, 0x64, 0x2d, 0x15,
    0x7c, 0x64, 0x01, 0xd4, 0x7c, 0x64, 0x01, 0xd5, 0x7c, 0x64, 0x05, 0xd4, 0x7c, 0x64, 0x05, 0xd5,
    0x7c, 0x64, 0x01, 0x94, 0x7c, 0x64, 0x01, 0x95, 0x7c, 0x64, 0x05, 0x94, 0x7c, 0x64, 0x05, 0x95,
    0x7c, 0x64, 0x2b, 0xd6, 0x7c, 0x64, 0x2b, 0xd7, 0x7c, 0x64, 0x2f, 0xd6, 0x7c, 0x64, 0x2f, 0xd7,
    0x7c, 0x64, 0x2b, 0x96, 0x7c, 0x64, 0x2b, 0x97, 0x7c, 0x64, 0x2f, 0x96, 0x7c, 0x64, 0x2f, 0x97,
    0x7c, 0x64, 0x29, 0xd6, 0x7c, 0x64, 0x29, 0xd7, 0x7c, 0x64, 0x2d, 0xd6, 0x7c, 0x64, 0x2d, 0xd7,
    0x7c, 0x64, 0x00, 0xd0, 0x7c, 0x64, 0x00, 0xd1, 0x7c, 0x64, 0x04, 0xd0, 0x7c, 0x64, 0x04, 0xd1,
    0x7c, 0x64, 0x28, 0x50, 0x7c, 0x64, 0x28, 0x51, 0x7c, 0x64, 0x2c, 0x50, 0x7c, 0x64, 0x2c, 0x51,
    0x7c, 0x64, 0x28, 0x10, 0x7c, 0x64, 0x28, 0x11, 0x7c, 0x64, 0x2c, 0x10, 0x7c, 0x64, 0x2c, 0x11,
    0x7c, 0x64, 0x29, 0x10, 0x7c, 0x64, 0x29, 0x11, 0x7c, 0x64, 0x2d, 0x10, 0x7c, 0x64, 0x2d, 0x11,
    0x7c, 0x64, 0x01, 0xd0, 0x7c, 0x64, 0x01, 0xd1, 0x7c, 0x64, 0x05, 0xd0, 0x7c, 0x64, 0x05, 0xd1,
    0x7c, 0x64, 0x01, 0x90, 0x7c, 0x64, 0x01, 0x91, 0x7c, 0x64, 0x05, 0x90, 0x7c, 0x64, 0x05, 0x91,
    0x38, 0x64, 0x03, 0xe8, 0x30, 0x64, 0x03, 0xe8, 0x34, 0x64, 0x03, 0xe8, 0x3c, 0x64, 0x03, 0xe8,
    0x1c, 0x64, 0x03, 0xe8, 0x20, 0x64, 0x03, 0xe8, 0x2c, 0x84, 0x03, 0xe8, 0x28, 0x84, 0x03, 0xe8,
    0x70, 0xc4, 0x03, 0xe8, 0x74, 0xc4, 0x03, 0xe8, 0x60, 0xc4, 0x03, 0xe8, 0x64, 0xc4, 0x03, 0xe8,
    0x68, 0xc4, 0x03, 0xe8, 0x6c, 0xc4, 0x03, 0xe8, 0x88, 0x64, 0x00, 0x64, 0x8c, 0x64, 0x00, 0x64,
    0xa8, 0x64, 0x00, 0x64, 0xac, 0x64, 0x00, 0x64, 0xa0, 0x64, 0x00, 0x64, 0xa4, 0x64, 0x00, 0x64,
    0x80, 0x64, 0x00, 0x64, 0x84, 0x64, 0x00, 0x64, 0x98, 0xc4, 0x00, 0x64, 0x9c, 0xc4, 0x00, 0x64,
    0xb0, 0xc4, 0x00, 0x64, 0xb4, 0xc4, 0x00, 0x64, 0x90, 0xc4, 0x00, 0x64, 0x94, 0xc4, 0x00, 0x64,
    0xb8, 0xc4, 0x00, 0x64, 0xbc, 0xc4, 0x00, 0x64, 0xc8, 0x64, 0x00, 0x64, 0xcc, 0x64, 0x00, 0x64,
    0xc0, 0x64, 0x00, 0x64, 0xc4, 0x64, 0x00, 0x64, 0xd8, 0xc4, 0x00, 0x64, 0xdc, 0xc4, 0x00, 0x64,
    0xd0, 0xc4, 0x00, 0x64, 0xd4, 0xc4, 0x00, 0x64, 0x0d, 0x04, 0x03, 0xe8, 0xe0, 0x64, 0x20, 0xc8,
    0xe4, 0x64, 0x20, 0xc8, 0xf0, 0xc4, 0x20, 0xc8, 0xf4, 0xc4, 0x20, 0xc8, 0x7c, 0x64, 0x28, 0x96,
    0x7c, 0x64, 0x28, 0x97, 0x7c, 0x64, 0x28, 0x16, 0x7c, 0x64, 0x28, 0x17, 0x7c, 0xc4, 0x28, 0x38,
    0x7c, 0xc4, 0x28, 0x39, 0x7c, 0xc4, 0x28, 0x78, 0x7c, 0xc4, 0x28, 0x79, 0x7c, 0xc4, 0x00, 0x34,
    0x7c, 0xc4, 0x00, 0x35, 0x7c, 0xc4, 0x2a, 0x38, 0x7c, 0xc4, 0x2a, 0x39, 0x7c, 0xc4, 0x07, 0x74,
    0x7c, 0xc4, 0x07, 0x75, 0x7c, 0xc4, 0x07, 0x34, 0x7c, 0xc4, 0x07, 0x35, 0x7c, 0xc4, 0x2b, 0xb8,
    0x7c, 0xc4, 0x2b, 0xb9, 0x7c, 0xc4, 0x28, 0xf8, 0x7c, 0xc4, 0x28, 0xf9, 0x7c, 0xc4, 0x2b, 0x78,
    0x7c, 0xc4, 0x2b, 0x79, 0x7c, 0xc4, 0x2b, 0x38, 0x7c, 0xc4, 0x2b, 0x39, 0x7c, 0xc4, 0x2a, 0x78,
    0x7c, 0xc4, 0x2a, 0x79, 0x50, 0xc4, 0x02, 0x9e, 0x50, 0xc4, 0x02, 0x9f, 0x54, 0xc4, 0x02, 0x9e,
    0x54, 0xc4, 0x02, 0x9f, 0x5c, 0xc4, 0x2a, 0x9e, 0x5c, 0xc4, 0x2a, 0x9f, 0x7c, 0xc4, 0x28, 0x30,
    0x7c, 0xc4, 0x28, 0x31, 0x7c, 0xc4, 0x2e, 0x30, 0x7c, 0xc4, 0x2e, 0x31, 0x7c, 0xc4, 0x06, 0x70,
    0x7c, 0xc4, 0x06, 0x71, 0x7c, 0xc4, 0x2c, 0x30, 0x7c, 0xc4, 0x2c, 0x31, 0xfc, 0x64, 0x28, 0x2a,
    0xfc, 0x64, 0x28, 0x2b, 0xec, 0x64, 0x28, 0x2a, 0xec, 0x64, 0x28, 0x2b, 0xfc, 0x64, 0x28, 0x24,
    0xfc, 0x64, 0x28, 0x25, 0xec, 0x64, 0x28, 0x24, 0xec, 0x64, 0x28, 0x25, 0xfc, 0x64, 0x01, 0xf2,
    0xfc, 0x64, 0x01, 0xf3, 0xec, 0x64, 0x01, 0xf2, 0xec, 0x64, 0x01, 0xf3, 0xec, 0x60, 0x28, 0x30,
    0xec, 0x60, 0x28, 0x31, 0xfc, 0x60, 0x28, 0x34, 0xfc, 0x60, 0x28, 0x35, 0xfc, 0x64, 0x28, 0x28,
    0xfc, 0x64, 0x28, 0x29, 0xec, 0x64, 0x28, 0x28, 0xec, 0x64, 0x28, 0x29, 0xfc, 0x64, 0x29, 0xee,
    0xfc, 0x64, 0x29, 0xef, 0xfc, 0x64, 0x29, 0xfa, 0xfc, 0x64, 0x29, 0xfb, 0xec, 0x64, 0x29, 0xfa,
    0xec, 0x64, 0x29, 0xfb, 0xfc, 0x64, 0x29, 0xf8, 0xfc, 0x64, 0x29, 0xf9, 0xec, 0x64, 0x29, 0xf8,
    0xec, 0x64, 0x29, 0xf9, 0xfc, 0x64, 0x29, 0xfe, 0xfc, 0x64, 0x29, 0xff, 0xec, 0x64, 0x29, 0xfe,
    0xec, 0x64, 0x29, 0xff, 0xfc, 0x64, 0x29, 0xfc, 0xfc, 0x64, 0x29, 0xfd, 0xec, 0x64, 0x29, 0xfc,
    0xec, 0x64, 0x29, 0xfd, 0xfc, 0x60, 0x28, 0x1c, 0xfc, 0x60, 0x28, 0x1d, 0xfc, 0x60, 0x28, 0x1e,
    0xfc, 0x60, 0x28, 0x1f, 0xfc, 0x60, 0x28, 0x18, 0xfc, 0x60, 0x28, 0x19, 0xfc, 0x60, 0x04, 0x8e,
    0xfc, 0x60, 0x04, 0x8f, 0xfe, 0xa0, 0x00, 0x8c, 0xfe, 0xa0, 0x00, 0x8d, 0xfe, 0xa0, 0x00, 0x4c,
    0xfe, 0xa0, 0x00, 0x4d, 0xfd, 0xfe, 0x2d, 0x8e, 0xfd, 0xfe, 0x2d, 0x8f, 0xfc, 0x80, 0x51, 0x0c,
    0xfc, 0x80, 0x51, 0x0d, 0xfc, 0x60, 0x2a, 0x10, 0xfc, 0x60, 0x2a, 0x11, 0xfc, 0x60, 0x28, 0x90,
    0xfc, 0x60, 0x28, 0x91, 0xfc, 0x60, 0x29, 0x10, 0xfc, 0x60, 0x29, 0x11, 0xfc, 0x60, 0x28, 0x50,
    0xfc, 0x60, 0x28, 0x51, 0x10, 0x64, 0x28, 0x24, 0x10, 0x64, 0x28, 0x25, 0x10, 0x64, 0x28, 0x28,
    0x10, 0x64, 0x28, 0x29, 0x10, 0x64, 0x28, 0x2a, 0x10, 0x64, 0x28, 0x2b, 0x10, 0x64, 0x29, 0xee,
    0x10, 0x64, 0x29, 0xef, 0x10, 0x60, 0x28, 0x30, 0x10, 0x60, 0x28, 0x31, 0x10, 0x64, 0x01, 0xf2,
    0x10, 0x64, 0x01, 0xf3, 0x10, 0x60, 0x28, 0x34, 0x10, 0x60, 0x28, 0x35, 0x10, 0x64, 0x29, 0xf8,
    0x10, 0x64, 0x29, 0xf9, 0x10, 0x64, 0x29, 0xfa, 0x10, 0x64, 0x29, 0xfb, 0x10, 0x64, 0x29, 0xfc,
    0x10, 0x64, 0x29, 0xfd, 0x10, 0x64, 0x29, 0xfe, 0x10, 0x64, 0x29, 0xff, 0x10, 0x60, 0x28, 0x50,
    0x10, 0x60, 0x28, 0x51, 0x10, 0x60, 0x28, 0x90, 0x10, 0x60, 0x28, 0x91, 0x10, 0x60, 0x29, 0x10,
    0x10, 0x60, 0x29, 0x11, 0x10, 0x60, 0x2a, 0x10, 0x10, 0x60, 0x2a, 0x11, 0x10, 0x64, 0x29, 0xd4,
    0x10, 0x64, 0x29, 0xd5, 0x10, 0x64, 0x29, 0xd6, 0x10, 0x64, 0x29, 0xd7, 0x10, 0x64, 0x01, 0xd8,
    0x10, 0x64, 0x01, 0xd9, 0x10, 0x64, 0x01, 0xda, 0x10, 0x64, 0x01, 0xdb, 0x10, 0x64, 0x29, 0xdc,
    0x10, 0x64, 0x29, 0xdd, 0x10, 0x64, 0x29, 0xde, 0x10, 0x64, 0x29, 0xdf, 0x10, 0x64, 0x2c, 0x20,
    0x10, 0x64, 0x2c, 0x21, 0x10, 0x64, 0x2c, 0x60, 0x10, 0x64, 0x2c, 0x61, 0x10, 0x64, 0x2c, 0xa0,
    0x10, 0x64, 0x2c, 0xa1, 0x10, 0x64, 0x2c, 0xe0, 0x10, 0x64, 0x2c, 0xe1, 0x7c, 0x84, 0x28, 0x00,
    0x7c, 0x84, 0x28, 0x40, 0xfc, 0x84, 0x28, 0x40, 0xfc, 0x84, 0x28, 0x00, 0xfc, 0x9c, 0x00, 0x80,
    0x7c, 0x64, 0x28, 0xee, 0x7c, 0x64, 0x28, 0xae, 0x7c, 0x64, 0x2a, 0xee, 0x7c, 0x64, 0x2a, 0xae,
    0x7c, 0x64, 0x2a, 0x6e, 0x7c, 0x64, 0x2a, 0x2e, 0x7c, 0x64, 0x28, 0x6e, 0x7c, 0x64, 0x28, 0x2e,
    0x7c, 0xc4, 0x29, 0xee, 0x7c, 0xc4, 0x29, 0xae, 0x7c, 0xc4, 0x2b, 0x6e, 0x7c, 0xc4, 0x2b, 0x2e,
    0x7c, 0xc4, 0x29, 0x6e, 0x7c, 0xc4, 0x29, 0x2e, 0x7c, 0x64, 0x2e, 0x2c, 0x7c, 0x64, 0x2c, 0x2c,
    0x7c, 0xc4, 0x2f, 0x2c, 0x7c, 0xc4, 0x2d, 0x2c, 0x7c, 0xa4, 0x0c, 0xaa, 0x7c, 0x64, 0x2c, 0x2a,
    0x7c, 0xc4, 0x0d, 0xaa, 0x7c, 0xc4, 0x2d, 0x2a, 0x7c, 0x64, 0x28, 0x28, 0x7c, 0xc4, 0x29, 0x2d,
    0x7c, 0x64, 0x2c, 0xee, 0x7c, 0x64, 0x2c, 0xae, 0x7c, 0x64, 0x2c, 0x6e, 0x7c, 0x64, 0x2c, 0x2e,
    0x7c, 0xc4, 0x2d, 0xee, 0x7c, 0xc4, 0x2d, 0xae, 0x7c, 0xc4, 0x2f, 0xae, 0x7c, 0xc4, 0x2d, 0x6e,
    0x7c, 0xc4, 0x2d, 0x2e, 0x4e, 0xb6, 0xba, 0x02, 0x4e, 0xb6, 0xb9, 0x02, 0x4e, 0xb6, 0xba, 0x42,
    0x4e, 0xb6, 0xb9, 0xc2, 0x4e, 0xb6, 0xb8, 0x42, 0x4e, 0xb6, 0xbb, 0x82, 0x4e, 0xb6, 0xbb, 0x42,
    0x4e, 0xb6, 0xb9, 0x82, 0x4c, 0x9c, 0x00, 0x00, 0x7d, 0x04, 0x28, 0x08, 0x7c, 0x80, 0x04, 0x00,
    0x7c, 0x60, 0x00, 0x26, 0x7c, 0x60, 0x00, 0xa6, 0x7c, 0x68, 0x02, 0xa6, 0x7c, 0x6c, 0x42, 0xe6,
    0x7c, 0xcf, 0xf1, 0x20, 0x7c, 0xc0, 0x01, 0x24, 0x7c, 0x68, 0x03, 0xa6, 0x7c, 0x04, 0x28, 0xac,
    0x7c, 0x04, 0x2b, 0xac, 0x7c, 0x04, 0x28, 0x6c, 0x7c, 0x04, 0x2a, 0x2c, 0x7c, 0x04, 0x29, 0xec,
    0x7c, 0x04, 0x2f, 0xec, 0x7c, 0x04, 0x2f, 0xac, 0x7c, 0x60, 0x04, 0xa6, 0x7c, 0x60, 0x2d, 0x26,
    0x7c, 0xc0, 0x01, 0xa4, 0x7c, 0xc0, 0x29, 0xe4, 0x7c, 0x00, 0x2a, 0x64, 0x7c, 0x64, 0x2a, 0x6c,
    0x7c, 0xc4, 0x2b, 0x6c, 0x10, 0x64, 0x29, 0x0c, 0x10, 0xc4, 0x29, 0x0e, 0x10, 0x64, 0x29, 0x4c,
    0x10, 0xc4, 0x29, 0x4e, 0x10, 0x84, 0x28, 0x00, 0x10, 0x84, 0x28, 0x40, 0x10, 0x84, 0x28, 0x80,
    0x10, 0x84, 0x28, 0xc0, 0x10, 0x04, 0x2f, 0xec, 0x48, 0x00, 0x10, 0x00, 0x48, 0x00, 0x10, 0x02,
    0x48, 0x00, 0x10, 0x01, 0x48, 0x00, 0x10, 0x03, 0x41, 0x82, 0xff, 0xf4, 0x41, 0x82, 0xff, 0xf6,
    0x41, 0x82, 0xff, 0xf5, 0x41, 0x82, 0xff, 0xf7, 0x4d, 0x82, 0x04, 0x20, 0x4d, 0x82, 0x04, 0x21,
    0x4d, 0x82, 0x00, 0x20, 0x4d, 0x82, 0x00, 0x21,
};

TEST(Assembler, AllInstructions)
{
  auto res = Assemble(instructions, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expected_instructions));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expected_instructions[i]) << " -> i=" << i;
  }
}

constexpr char extended_instructions[] = "subi 0, 4, 8\n"
                                         "subis 0, 4, 8\n"
                                         "subic 0, 4, 8\n"
                                         "subic. 0, 4, 8\n"
                                         "cmpwi 0, 4\n"
                                         "cmpwi 0, 4, 8\n"
                                         "cmpw 0, 4\n"
                                         "cmpw 0, 4, 8\n"
                                         "cmplwi 0, 4\n"
                                         "cmplwi 0, 4, 8\n"
                                         "cmplw 0, 4\n"
                                         "cmplw 0, 4, 8\n"
                                         "crset 0\n"
                                         "crclr 0\n"
                                         "crmove 0, 4\n"
                                         "crnot 0, 4\n"
                                         "twlt 0, 4\n"
                                         "twlti 0, 4\n"
                                         "twle 0, 4\n"
                                         "twlei 0, 4\n"
                                         "tweq 0, 4\n"
                                         "tweqi 0, 4\n"
                                         "twge 0, 4\n"
                                         "twgei 0, 4\n"
                                         "twgt 0, 4\n"
                                         "twgti 0, 4\n"
                                         "twnl 0, 4\n"
                                         "twnli 0, 4\n"
                                         "twne 0, 4\n"
                                         "twnei 0, 4\n"
                                         "twng 0, 4\n"
                                         "twngi 0, 4\n"
                                         "twllt 0, 4\n"
                                         "twllti 0, 4\n"
                                         "twlle 0, 4\n"
                                         "twllei 0, 4\n"
                                         "twlge 0, 4\n"
                                         "twlgei 0, 4\n"
                                         "twlgt 0, 4\n"
                                         "twlgti 0, 4\n"
                                         "twlnl 0, 4\n"
                                         "twlnli 0, 4\n"
                                         "twlng 0, 4\n"
                                         "twlngi 0, 4\n"
                                         "trap \n"
                                         "mtxer 0\n"
                                         "mfxer 0\n"
                                         "mtlr 0\n"
                                         "mflr 0\n"
                                         "mtctr 0\n"
                                         "mfctr 0\n"
                                         "mtdsisr 0\n"
                                         "mfdsisr 0\n"
                                         "mtdar 0\n"
                                         "mfdar 0\n"
                                         "mtdec 0\n"
                                         "mfdec 0\n"
                                         "mtsdr1 0\n"
                                         "mfsdr1 0\n"
                                         "mtsrr0 0\n"
                                         "mfsrr0 0\n"
                                         "mtsrr1 0\n"
                                         "mfsrr1 0\n"
                                         "mtear 0\n"
                                         "mfear 0\n"
                                         "mttbl 0\n"
                                         "mftbl 0\n"
                                         "mttbu 0\n"
                                         "mftbu 0\n"
                                         "mtsprg 0, 4\n"
                                         "mfsprg 0, 1\n"
                                         "mtibatu 0, 1\n"
                                         "mfibatu 0, 1\n"
                                         "mtibatl 0, 1\n"
                                         "mfibatl 0, 1\n"
                                         "mtdbatu 0, 1\n"
                                         "mfdbatu 0, 1\n"
                                         "mtdbatl 0, 1\n"
                                         "mfdbatl 0, 1\n"
                                         "nop \n"
                                         "li 0, 4\n"
                                         "lis 0, 4\n"
                                         "la 0, 4(8)\n"
                                         "mtcr 0\n"
                                         "mfspr 0, 4\n"
                                         "mftb 0, 268\n"
                                         "mtspr 0, 4\n"
                                         "sub 0, 4, 8\n"
                                         "sub. 0, 4, 8\n"
                                         "subo 0, 4, 8\n"
                                         "subo. 0, 4, 8\n"
                                         "subc 0, 4, 8\n"
                                         "subc. 0, 4, 8\n"
                                         "subco 0, 4, 8\n"
                                         "subco. 0, 4, 8\n"
                                         "extlwi 0, 4, 8, 12\n"
                                         "extlwi. 0, 4, 8, 12\n"
                                         "extrwi 0, 4, 8, 12\n"
                                         "extrwi. 0, 4, 8, 12\n"
                                         "inslwi 0, 4, 8, 12\n"
                                         "inslwi. 0, 4, 8, 12\n"
                                         "insrwi 0, 4, 8, 12\n"
                                         "insrwi. 0, 4, 8, 12\n"
                                         "rotlwi 0, 4, 8\n"
                                         "rotlwi. 0, 4, 8\n"
                                         "rotrwi 0, 4, 8\n"
                                         "rotrwi. 0, 4, 8\n"
                                         "rotlw 0, 4, 8\n"
                                         "rotlw. 0, 4, 8\n"
                                         "slwi 0, 4, 8\n"
                                         "slwi. 0, 4, 8\n"
                                         "srwi 0, 4, 8\n"
                                         "srwi. 0, 4, 8\n"
                                         "clrlwi 0, 4, 8\n"
                                         "clrlwi. 0, 4, 8\n"
                                         "clrrwi 0, 4, 8\n"
                                         "clrrwi. 0, 4, 8\n"
                                         "clrlslwi 0, 4, 12, 8\n"
                                         "clrlslwi. 0, 4, 12, 8\n"
                                         "mr 0, 4\n"
                                         "mr. 0, 4\n"
                                         "not 0, 4\n"
                                         "not. 0, 4\n"
                                         "bt 0, 4\n"
                                         "btl 0, 4\n"
                                         "bta 0, 4\n"
                                         "btla 0, 4\n"
                                         "bt- 0, 4\n"
                                         "btl- 0, 4\n"
                                         "bta- 0, 4\n"
                                         "btla- 0, 4\n"
                                         "bt+ 0, 4\n"
                                         "btl+ 0, 4\n"
                                         "bta+ 0, 4\n"
                                         "btla+ 0, 4\n"
                                         "bf 0, 4\n"
                                         "bfl 0, 4\n"
                                         "bfa 0, 4\n"
                                         "bfla 0, 4\n"
                                         "bf- 0, 4\n"
                                         "bfl- 0, 4\n"
                                         "bfa- 0, 4\n"
                                         "bfla- 0, 4\n"
                                         "bf+ 0, 4\n"
                                         "bfl+ 0, 4\n"
                                         "bfa+ 0, 4\n"
                                         "bfla+ 0, 4\n"
                                         "bdnz 0\n"
                                         "bdnzl 0\n"
                                         "bdnza 0\n"
                                         "bdnzla 0\n"
                                         "bdnz- 0\n"
                                         "bdnzl- 0\n"
                                         "bdnza- 0\n"
                                         "bdnzla- 0\n"
                                         "bdnz+ 0\n"
                                         "bdnzl+ 0\n"
                                         "bdnza+ 0\n"
                                         "bdnzla+ 0\n"
                                         "bdnzt 0, 4\n"
                                         "bdnztl 0, 4\n"
                                         "bdnzta 0, 4\n"
                                         "bdnztla 0, 4\n"
                                         "bdnzt- 0, 4\n"
                                         "bdnztl- 0, 4\n"
                                         "bdnzta- 0, 4\n"
                                         "bdnztla- 0, 4\n"
                                         "bdnzt+ 0, 4\n"
                                         "bdnztl+ 0, 4\n"
                                         "bdnzta+ 0, 4\n"
                                         "bdnztla+ 0, 4\n"
                                         "bdnzf 0, 4\n"
                                         "bdnzfl 0, 4\n"
                                         "bdnzfa 0, 4\n"
                                         "bdnzfla 0, 4\n"
                                         "bdnzf- 0, 4\n"
                                         "bdnzfl- 0, 4\n"
                                         "bdnzfa- 0, 4\n"
                                         "bdnzfla- 0, 4\n"
                                         "bdnzf+ 0, 4\n"
                                         "bdnzfl+ 0, 4\n"
                                         "bdnzfa+ 0, 4\n"
                                         "bdnzfla+ 0, 4\n"
                                         "bdz 0\n"
                                         "bdzl 0\n"
                                         "bdza 0\n"
                                         "bdzla 0\n"
                                         "bdz- 0\n"
                                         "bdzl- 0\n"
                                         "bdza- 0\n"
                                         "bdzla- 0\n"
                                         "bdz+ 0\n"
                                         "bdzl+ 0\n"
                                         "bdza+ 0\n"
                                         "bdzla+ 0\n"
                                         "bdzt 0, 4\n"
                                         "bdztl 0, 4\n"
                                         "bdzta 0, 4\n"
                                         "bdztla 0, 4\n"
                                         "bdzt- 0, 4\n"
                                         "bdztl- 0, 4\n"
                                         "bdzta- 0, 4\n"
                                         "bdztla- 0, 4\n"
                                         "bdzt+ 0, 4\n"
                                         "bdztl+ 0, 4\n"
                                         "bdzta+ 0, 4\n"
                                         "bdztla+ 0, 4\n"
                                         "bdzf 0, 4\n"
                                         "bdzfl 0, 4\n"
                                         "bdzfa 0, 4\n"
                                         "bdzfla 0, 4\n"
                                         "bdzf- 0, 4\n"
                                         "bdzfl- 0, 4\n"
                                         "bdzfa- 0, 4\n"
                                         "bdzfla- 0, 4\n"
                                         "bdzf+ 0, 4\n"
                                         "bdzfl+ 0, 4\n"
                                         "bdzfa+ 0, 4\n"
                                         "bdzfla+ 0, 4\n"
                                         "blt 0 \n"
                                         "blt 0, 4\n"
                                         "bltl 0 \n"
                                         "bltl 0, 4\n"
                                         "blta 0 \n"
                                         "blta 0, 4\n"
                                         "bltla 0 \n"
                                         "bltla 0, 4\n"
                                         "blt- 0 \n"
                                         "blt- 0, 4\n"
                                         "bltl- 0 \n"
                                         "bltl- 0, 4\n"
                                         "blta- 0 \n"
                                         "blta- 0, 4\n"
                                         "bltla- 0 \n"
                                         "bltla- 0, 4\n"
                                         "blt+ 0 \n"
                                         "blt+ 0, 4\n"
                                         "bltl+ 0 \n"
                                         "bltl+ 0, 4\n"
                                         "blta+ 0 \n"
                                         "blta+ 0, 4\n"
                                         "bltla+ 0 \n"
                                         "bltla+ 0, 4\n"
                                         "ble 0 \n"
                                         "ble 0, 4\n"
                                         "blel 0 \n"
                                         "blel 0, 4\n"
                                         "blea 0 \n"
                                         "blea 0, 4\n"
                                         "blela 0 \n"
                                         "blela 0, 4\n"
                                         "ble- 0 \n"
                                         "ble- 0, 4\n"
                                         "blel- 0 \n"
                                         "blel- 0, 4\n"
                                         "blea- 0 \n"
                                         "blea- 0, 4\n"
                                         "blela- 0 \n"
                                         "blela- 0, 4\n"
                                         "ble+ 0 \n"
                                         "ble+ 0, 4\n"
                                         "blel+ 0 \n"
                                         "blel+ 0, 4\n"
                                         "blea+ 0 \n"
                                         "blea+ 0, 4\n"
                                         "blela+ 0 \n"
                                         "blela+ 0, 4\n"
                                         "beq 0 \n"
                                         "beq 0, 4\n"
                                         "beql 0 \n"
                                         "beql 0, 4\n"
                                         "beqa 0 \n"
                                         "beqa 0, 4\n"
                                         "beqla 0 \n"
                                         "beqla 0, 4\n"
                                         "beq- 0 \n"
                                         "beq- 0, 4\n"
                                         "beql- 0 \n"
                                         "beql- 0, 4\n"
                                         "beqa- 0 \n"
                                         "beqa- 0, 4\n"
                                         "beqla- 0 \n"
                                         "beqla- 0, 4\n"
                                         "beq+ 0 \n"
                                         "beq+ 0, 4\n"
                                         "beql+ 0 \n"
                                         "beql+ 0, 4\n"
                                         "beqa+ 0 \n"
                                         "beqa+ 0, 4\n"
                                         "beqla+ 0 \n"
                                         "beqla+ 0, 4\n"
                                         "bge 0 \n"
                                         "bge 0, 4\n"
                                         "bgel 0 \n"
                                         "bgel 0, 4\n"
                                         "bgea 0 \n"
                                         "bgea 0, 4\n"
                                         "bgela 0 \n"
                                         "bgela 0, 4\n"
                                         "bge- 0 \n"
                                         "bge- 0, 4\n"
                                         "bgel- 0 \n"
                                         "bgel- 0, 4\n"
                                         "bgea- 0 \n"
                                         "bgea- 0, 4\n"
                                         "bgela- 0 \n"
                                         "bgela- 0, 4\n"
                                         "bge+ 0 \n"
                                         "bge+ 0, 4\n"
                                         "bgel+ 0 \n"
                                         "bgel+ 0, 4\n"
                                         "bgea+ 0 \n"
                                         "bgea+ 0, 4\n"
                                         "bgela+ 0 \n"
                                         "bgela+ 0, 4\n"
                                         "bgt 0 \n"
                                         "bgt 0, 4\n"
                                         "bgtl 0 \n"
                                         "bgtl 0, 4\n"
                                         "bgta 0 \n"
                                         "bgta 0, 4\n"
                                         "bgtla 0 \n"
                                         "bgtla 0, 4\n"
                                         "bgt- 0 \n"
                                         "bgt- 0, 4\n"
                                         "bgtl- 0 \n"
                                         "bgtl- 0, 4\n"
                                         "bgta- 0 \n"
                                         "bgta- 0, 4\n"
                                         "bgtla- 0 \n"
                                         "bgtla- 0, 4\n"
                                         "bgt+ 0 \n"
                                         "bgt+ 0, 4\n"
                                         "bgtl+ 0 \n"
                                         "bgtl+ 0, 4\n"
                                         "bgta+ 0 \n"
                                         "bgta+ 0, 4\n"
                                         "bgtla+ 0 \n"
                                         "bgtla+ 0, 4\n"
                                         "bnl 0 \n"
                                         "bnl 0, 4\n"
                                         "bnll 0 \n"
                                         "bnll 0, 4\n"
                                         "bnla 0 \n"
                                         "bnla 0, 4\n"
                                         "bnlla 0 \n"
                                         "bnlla 0, 4\n"
                                         "bnl- 0 \n"
                                         "bnl- 0, 4\n"
                                         "bnll- 0 \n"
                                         "bnll- 0, 4\n"
                                         "bnla- 0 \n"
                                         "bnla- 0, 4\n"
                                         "bnlla- 0 \n"
                                         "bnlla- 0, 4\n"
                                         "bnl+ 0 \n"
                                         "bnl+ 0, 4\n"
                                         "bnll+ 0 \n"
                                         "bnll+ 0, 4\n"
                                         "bnla+ 0 \n"
                                         "bnla+ 0, 4\n"
                                         "bnlla+ 0 \n"
                                         "bnlla+ 0, 4\n"
                                         "bne 0 \n"
                                         "bne 0, 4\n"
                                         "bnel 0 \n"
                                         "bnel 0, 4\n"
                                         "bnea 0 \n"
                                         "bnea 0, 4\n"
                                         "bnela 0 \n"
                                         "bnela 0, 4\n"
                                         "bne- 0 \n"
                                         "bne- 0, 4\n"
                                         "bnel- 0 \n"
                                         "bnel- 0, 4\n"
                                         "bnea- 0 \n"
                                         "bnea- 0, 4\n"
                                         "bnela- 0 \n"
                                         "bnela- 0, 4\n"
                                         "bne+ 0 \n"
                                         "bne+ 0, 4\n"
                                         "bnel+ 0 \n"
                                         "bnel+ 0, 4\n"
                                         "bnea+ 0 \n"
                                         "bnea+ 0, 4\n"
                                         "bnela+ 0 \n"
                                         "bnela+ 0, 4\n"
                                         "bng 0 \n"
                                         "bng 0, 4\n"
                                         "bngl 0 \n"
                                         "bngl 0, 4\n"
                                         "bnga 0 \n"
                                         "bnga 0, 4\n"
                                         "bngla 0 \n"
                                         "bngla 0, 4\n"
                                         "bng- 0 \n"
                                         "bng- 0, 4\n"
                                         "bngl- 0 \n"
                                         "bngl- 0, 4\n"
                                         "bnga- 0 \n"
                                         "bnga- 0, 4\n"
                                         "bngla- 0 \n"
                                         "bngla- 0, 4\n"
                                         "bng+ 0 \n"
                                         "bng+ 0, 4\n"
                                         "bngl+ 0 \n"
                                         "bngl+ 0, 4\n"
                                         "bnga+ 0 \n"
                                         "bnga+ 0, 4\n"
                                         "bngla+ 0 \n"
                                         "bngla+ 0, 4\n"
                                         "bso 0 \n"
                                         "bso 0, 4\n"
                                         "bsol 0 \n"
                                         "bsol 0, 4\n"
                                         "bsoa 0 \n"
                                         "bsoa 0, 4\n"
                                         "bsola 0 \n"
                                         "bsola 0, 4\n"
                                         "bso- 0 \n"
                                         "bso- 0, 4\n"
                                         "bsol- 0 \n"
                                         "bsol- 0, 4\n"
                                         "bsoa- 0 \n"
                                         "bsoa- 0, 4\n"
                                         "bsola- 0 \n"
                                         "bsola- 0, 4\n"
                                         "bso+ 0 \n"
                                         "bso+ 0, 4\n"
                                         "bsol+ 0 \n"
                                         "bsol+ 0, 4\n"
                                         "bsoa+ 0 \n"
                                         "bsoa+ 0, 4\n"
                                         "bsola+ 0 \n"
                                         "bsola+ 0, 4\n"
                                         "bns 0 \n"
                                         "bns 0, 4\n"
                                         "bnsl 0 \n"
                                         "bnsl 0, 4\n"
                                         "bnsa 0 \n"
                                         "bnsa 0, 4\n"
                                         "bnsla 0 \n"
                                         "bnsla 0, 4\n"
                                         "bns- 0 \n"
                                         "bns- 0, 4\n"
                                         "bnsl- 0 \n"
                                         "bnsl- 0, 4\n"
                                         "bnsa- 0 \n"
                                         "bnsa- 0, 4\n"
                                         "bnsla- 0 \n"
                                         "bnsla- 0, 4\n"
                                         "bns+ 0 \n"
                                         "bns+ 0, 4\n"
                                         "bnsl+ 0 \n"
                                         "bnsl+ 0, 4\n"
                                         "bnsa+ 0 \n"
                                         "bnsa+ 0, 4\n"
                                         "bnsla+ 0 \n"
                                         "bnsla+ 0, 4\n"
                                         "bun 0 \n"
                                         "bun 0, 4\n"
                                         "bunl 0 \n"
                                         "bunl 0, 4\n"
                                         "buna 0 \n"
                                         "buna 0, 4\n"
                                         "bunla 0 \n"
                                         "bunla 0, 4\n"
                                         "bun- 0 \n"
                                         "bun- 0, 4\n"
                                         "bunl- 0 \n"
                                         "bunl- 0, 4\n"
                                         "buna- 0 \n"
                                         "buna- 0, 4\n"
                                         "bunla- 0 \n"
                                         "bunla- 0, 4\n"
                                         "bun+ 0 \n"
                                         "bun+ 0, 4\n"
                                         "bunl+ 0 \n"
                                         "bunl+ 0, 4\n"
                                         "buna+ 0 \n"
                                         "buna+ 0, 4\n"
                                         "bunla+ 0 \n"
                                         "bunla+ 0, 4\n"
                                         "bnu 0 \n"
                                         "bnu 0, 4\n"
                                         "bnul 0 \n"
                                         "bnul 0, 4\n"
                                         "bnua 0 \n"
                                         "bnua 0, 4\n"
                                         "bnula 0 \n"
                                         "bnula 0, 4\n"
                                         "bnu- 0 \n"
                                         "bnu- 0, 4\n"
                                         "bnul- 0 \n"
                                         "bnul- 0, 4\n"
                                         "bnua- 0 \n"
                                         "bnua- 0, 4\n"
                                         "bnula- 0 \n"
                                         "bnula- 0, 4\n"
                                         "bnu+ 0 \n"
                                         "bnu+ 0, 4\n"
                                         "bnul+ 0 \n"
                                         "bnul+ 0, 4\n"
                                         "bnua+ 0 \n"
                                         "bnua+ 0, 4\n"
                                         "bnula+ 0 \n"
                                         "bnula+ 0, 4\n"
                                         "blr \n"
                                         "blrl \n"
                                         "bctr \n"
                                         "bctrl \n"
                                         "btlr 0\n"
                                         "btlrl 0\n"
                                         "btlr- 0\n"
                                         "btlrl- 0\n"
                                         "btlr+ 0\n"
                                         "btlrl+ 0\n"
                                         "btctr 0\n"
                                         "btctrl 0\n"
                                         "btctr- 0\n"
                                         "btctrl- 0\n"
                                         "btctr+ 0\n"
                                         "btctrl+ 0\n"
                                         "bflr 0\n"
                                         "bflrl 0\n"
                                         "bflr- 0\n"
                                         "bflrl- 0\n"
                                         "bflr+ 0\n"
                                         "bflrl+ 0\n"
                                         "bfctr 0\n"
                                         "bfctrl 0\n"
                                         "bfctr- 0\n"
                                         "bfctrl- 0\n"
                                         "bfctr+ 0\n"
                                         "bfctrl+ 0\n"
                                         "bdnzlr \n"
                                         "bdnzlrl \n"
                                         "bdnzlr- \n"
                                         "bdnzlrl- \n"
                                         "bdnzlr+ \n"
                                         "bdnzlrl+ \n"
                                         "bdnztlr 0\n"
                                         "bdnztlrl 0\n"
                                         "bdnztlr- 0\n"
                                         "bdnztlrl- 0\n"
                                         "bdnztlr+ 0\n"
                                         "bdnztlrl+ 0\n"
                                         "bdnzflr 0\n"
                                         "bdnzflrl 0\n"
                                         "bdnzflr- 0\n"
                                         "bdnzflrl- 0\n"
                                         "bdnzflr+ 0\n"
                                         "bdnzflrl+ 0\n"
                                         "bdzlr \n"
                                         "bdzlrl \n"
                                         "bdzlr- \n"
                                         "bdzlrl- \n"
                                         "bdzlr+ \n"
                                         "bdzlrl+ \n"
                                         "bdztlr 0\n"
                                         "bdztlrl 0\n"
                                         "bdztlr- 0\n"
                                         "bdztlrl- 0\n"
                                         "bdztlr+ 0\n"
                                         "bdztlrl+ 0\n"
                                         "bdzflr 0\n"
                                         "bdzflrl 0\n"
                                         "bdzflr- 0\n"
                                         "bdzflrl- 0\n"
                                         "bdzflr+ 0\n"
                                         "bdzflrl+ 0\n"
                                         "bltlr\n"
                                         "bltlr 0\n"
                                         "bltlrl\n"
                                         "bltlrl 0\n"
                                         "bltlr-\n"
                                         "bltlr- 0\n"
                                         "bltlrl-\n"
                                         "bltlrl- 0\n"
                                         "bltlr+\n"
                                         "bltlr+ 0\n"
                                         "bltlrl+\n"
                                         "bltlrl+ 0\n"
                                         "bltctr\n"
                                         "bltctr 0\n"
                                         "bltctrl\n"
                                         "bltctrl 0\n"
                                         "bltctr-\n"
                                         "bltctr- 0\n"
                                         "bltctrl-\n"
                                         "bltctrl- 0\n"
                                         "bltctr+\n"
                                         "bltctr+ 0\n"
                                         "bltctrl+\n"
                                         "bltctrl+ 0\n"
                                         "blelr\n"
                                         "blelr 0\n"
                                         "blelrl\n"
                                         "blelrl 0\n"
                                         "blelr-\n"
                                         "blelr- 0\n"
                                         "blelrl-\n"
                                         "blelrl- 0\n"
                                         "blelr+\n"
                                         "blelr+ 0\n"
                                         "blelrl+\n"
                                         "blelrl+ 0\n"
                                         "blectr\n"
                                         "blectr 0\n"
                                         "blectrl\n"
                                         "blectrl 0\n"
                                         "blectr-\n"
                                         "blectr- 0\n"
                                         "blectrl-\n"
                                         "blectrl- 0\n"
                                         "blectr+\n"
                                         "blectr+ 0\n"
                                         "blectrl+\n"
                                         "blectrl+ 0\n"
                                         "beqlr\n"
                                         "beqlr 0\n"
                                         "beqlrl\n"
                                         "beqlrl 0\n"
                                         "beqlr-\n"
                                         "beqlr- 0\n"
                                         "beqlrl-\n"
                                         "beqlrl- 0\n"
                                         "beqlr+\n"
                                         "beqlr+ 0\n"
                                         "beqlrl+\n"
                                         "beqlrl+ 0\n"
                                         "beqctr\n"
                                         "beqctr 0\n"
                                         "beqctrl\n"
                                         "beqctrl 0\n"
                                         "beqctr-\n"
                                         "beqctr- 0\n"
                                         "beqctrl-\n"
                                         "beqctrl- 0\n"
                                         "beqctr+\n"
                                         "beqctr+ 0\n"
                                         "beqctrl+\n"
                                         "beqctrl+ 0\n"
                                         "bgelr\n"
                                         "bgelr 0\n"
                                         "bgelrl\n"
                                         "bgelrl 0\n"
                                         "bgelr-\n"
                                         "bgelr- 0\n"
                                         "bgelrl-\n"
                                         "bgelrl- 0\n"
                                         "bgelr+\n"
                                         "bgelr+ 0\n"
                                         "bgelrl+\n"
                                         "bgelrl+ 0\n"
                                         "bgectr\n"
                                         "bgectr 0\n"
                                         "bgectrl\n"
                                         "bgectrl 0\n"
                                         "bgectr-\n"
                                         "bgectr- 0\n"
                                         "bgectrl-\n"
                                         "bgectrl- 0\n"
                                         "bgectr+\n"
                                         "bgectr+ 0\n"
                                         "bgectrl+\n"
                                         "bgectrl+ 0\n"
                                         "bgtlr\n"
                                         "bgtlr 0\n"
                                         "bgtlrl\n"
                                         "bgtlrl 0\n"
                                         "bgtlr-\n"
                                         "bgtlr- 0\n"
                                         "bgtlrl-\n"
                                         "bgtlrl- 0\n"
                                         "bgtlr+\n"
                                         "bgtlr+ 0\n"
                                         "bgtlrl+\n"
                                         "bgtlrl+ 0\n"
                                         "bgtctr\n"
                                         "bgtctr 0\n"
                                         "bgtctrl\n"
                                         "bgtctrl 0\n"
                                         "bgtctr-\n"
                                         "bgtctr- 0\n"
                                         "bgtctrl-\n"
                                         "bgtctrl- 0\n"
                                         "bgtctr+\n"
                                         "bgtctr+ 0\n"
                                         "bgtctrl+\n"
                                         "bgtctrl+ 0\n"
                                         "bnllr\n"
                                         "bnllr 0\n"
                                         "bnllrl\n"
                                         "bnllrl 0\n"
                                         "bnllr-\n"
                                         "bnllr- 0\n"
                                         "bnllrl-\n"
                                         "bnllrl- 0\n"
                                         "bnllr+\n"
                                         "bnllr+ 0\n"
                                         "bnllrl+\n"
                                         "bnllrl+ 0\n"
                                         "bnlctr\n"
                                         "bnlctr 0\n"
                                         "bnlctrl\n"
                                         "bnlctrl 0\n"
                                         "bnlctr-\n"
                                         "bnlctr- 0\n"
                                         "bnlctrl-\n"
                                         "bnlctrl- 0\n"
                                         "bnlctr+\n"
                                         "bnlctr+ 0\n"
                                         "bnlctrl+\n"
                                         "bnlctrl+ 0\n"
                                         "bnelr\n"
                                         "bnelr 0\n"
                                         "bnelrl\n"
                                         "bnelrl 0\n"
                                         "bnelr-\n"
                                         "bnelr- 0\n"
                                         "bnelrl-\n"
                                         "bnelrl- 0\n"
                                         "bnelr+\n"
                                         "bnelr+ 0\n"
                                         "bnelrl+\n"
                                         "bnelrl+ 0\n"
                                         "bnectr\n"
                                         "bnectr 0\n"
                                         "bnectrl\n"
                                         "bnectrl 0\n"
                                         "bnectr-\n"
                                         "bnectr- 0\n"
                                         "bnectrl-\n"
                                         "bnectrl- 0\n"
                                         "bnectr+\n"
                                         "bnectr+ 0\n"
                                         "bnectrl+\n"
                                         "bnectrl+ 0\n"
                                         "bnglr\n"
                                         "bnglr 0\n"
                                         "bnglrl\n"
                                         "bnglrl 0\n"
                                         "bnglr-\n"
                                         "bnglr- 0\n"
                                         "bnglrl-\n"
                                         "bnglrl- 0\n"
                                         "bnglr+\n"
                                         "bnglr+ 0\n"
                                         "bnglrl+\n"
                                         "bnglrl+ 0\n"
                                         "bngctr\n"
                                         "bngctr 0\n"
                                         "bngctrl\n"
                                         "bngctrl 0\n"
                                         "bngctr-\n"
                                         "bngctr- 0\n"
                                         "bngctrl-\n"
                                         "bngctrl- 0\n"
                                         "bngctr+\n"
                                         "bngctr+ 0\n"
                                         "bngctrl+\n"
                                         "bngctrl+ 0\n"
                                         "bsolr\n"
                                         "bsolr 0\n"
                                         "bsolrl\n"
                                         "bsolrl 0\n"
                                         "bsolr-\n"
                                         "bsolr- 0\n"
                                         "bsolrl-\n"
                                         "bsolrl- 0\n"
                                         "bsolr+\n"
                                         "bsolr+ 0\n"
                                         "bsolrl+\n"
                                         "bsolrl+ 0\n"
                                         "bsoctr\n"
                                         "bsoctr 0\n"
                                         "bsoctrl\n"
                                         "bsoctrl 0\n"
                                         "bsoctr-\n"
                                         "bsoctr- 0\n"
                                         "bsoctrl-\n"
                                         "bsoctrl- 0\n"
                                         "bsoctr+\n"
                                         "bsoctr+ 0\n"
                                         "bsoctrl+\n"
                                         "bsoctrl+ 0\n"
                                         "bnslr\n"
                                         "bnslr 0\n"
                                         "bnslrl\n"
                                         "bnslrl 0\n"
                                         "bnslr-\n"
                                         "bnslr- 0\n"
                                         "bnslrl-\n"
                                         "bnslrl- 0\n"
                                         "bnslr+\n"
                                         "bnslr+ 0\n"
                                         "bnslrl+\n"
                                         "bnslrl+ 0\n"
                                         "bnsctr\n"
                                         "bnsctr 0\n"
                                         "bnsctrl\n"
                                         "bnsctrl 0\n"
                                         "bnsctr-\n"
                                         "bnsctr- 0\n"
                                         "bnsctrl-\n"
                                         "bnsctrl- 0\n"
                                         "bnsctr+\n"
                                         "bnsctr+ 0\n"
                                         "bnsctrl+\n"
                                         "bnsctrl+ 0\n"
                                         "bunlr\n"
                                         "bunlr 0\n"
                                         "bunlrl\n"
                                         "bunlrl 0\n"
                                         "bunlr-\n"
                                         "bunlr- 0\n"
                                         "bunlrl-\n"
                                         "bunlrl- 0\n"
                                         "bunlr+\n"
                                         "bunlr+ 0\n"
                                         "bunlrl+\n"
                                         "bunlrl+ 0\n"
                                         "bunctr\n"
                                         "bunctr 0\n"
                                         "bunctrl\n"
                                         "bunctrl 0\n"
                                         "bunctr-\n"
                                         "bunctr- 0\n"
                                         "bunctrl-\n"
                                         "bunctrl- 0\n"
                                         "bunctr+\n"
                                         "bunctr+ 0\n"
                                         "bunctrl+\n"
                                         "bunctrl+ 0\n"
                                         "bnulr\n"
                                         "bnulr 0\n"
                                         "bnulrl\n"
                                         "bnulrl 0\n"
                                         "bnulr-\n"
                                         "bnulr- 0\n"
                                         "bnulrl-\n"
                                         "bnulrl- 0\n"
                                         "bnulr+\n"
                                         "bnulr+ 0\n"
                                         "bnulrl+\n"
                                         "bnulrl+ 0\n"
                                         "bnuctr\n"
                                         "bnuctr 0\n"
                                         "bnuctrl\n"
                                         "bnuctrl 0\n"
                                         "bnuctr-\n"
                                         "bnuctr- 0\n"
                                         "bnuctrl-\n"
                                         "bnuctrl- 0\n"
                                         "bnuctr+\n"
                                         "bnuctr+ 0\n"
                                         "bnuctrl+\n"
                                         "bnuctrl+ 0\n";

constexpr u8 extended_expect[] = {
    0x38, 0x04, 0xff, 0xf8, 0x3c, 0x04, 0xff, 0xf8, 0x30, 0x04, 0xff, 0xf8, 0x34, 0x04, 0xff, 0xf8,
    0x2c, 0x00, 0x00, 0x04, 0x2c, 0x04, 0x00, 0x08, 0x7c, 0x00, 0x20, 0x00, 0x7c, 0x04, 0x40, 0x00,
    0x28, 0x00, 0x00, 0x04, 0x28, 0x04, 0x00, 0x08, 0x7c, 0x00, 0x20, 0x40, 0x7c, 0x04, 0x40, 0x40,
    0x4c, 0x00, 0x02, 0x42, 0x4c, 0x00, 0x01, 0x82, 0x4c, 0x04, 0x23, 0x82, 0x4c, 0x04, 0x20, 0x42,
    0x7e, 0x00, 0x20, 0x08, 0x0e, 0x00, 0x00, 0x04, 0x7e, 0x80, 0x20, 0x08, 0x0e, 0x80, 0x00, 0x04,
    0x7c, 0x80, 0x20, 0x08, 0x0c, 0x80, 0x00, 0x04, 0x7d, 0x80, 0x20, 0x08, 0x0d, 0x80, 0x00, 0x04,
    0x7d, 0x00, 0x20, 0x08, 0x0d, 0x00, 0x00, 0x04, 0x7d, 0x80, 0x20, 0x08, 0x0d, 0x80, 0x00, 0x04,
    0x7f, 0x00, 0x20, 0x08, 0x0f, 0x00, 0x00, 0x04, 0x7e, 0x80, 0x20, 0x08, 0x0e, 0x80, 0x00, 0x04,
    0x7c, 0x40, 0x20, 0x08, 0x0c, 0x40, 0x00, 0x04, 0x7c, 0xc0, 0x20, 0x08, 0x0c, 0xc0, 0x00, 0x04,
    0x7c, 0xa0, 0x20, 0x08, 0x0c, 0xa0, 0x00, 0x04, 0x7c, 0x20, 0x20, 0x08, 0x0c, 0x20, 0x00, 0x04,
    0x7c, 0xa0, 0x20, 0x08, 0x0c, 0xa0, 0x00, 0x04, 0x7c, 0xc0, 0x20, 0x08, 0x0c, 0xc0, 0x00, 0x04,
    0x7f, 0xe0, 0x00, 0x08, 0x7c, 0x01, 0x03, 0xa6, 0x7c, 0x01, 0x02, 0xa6, 0x7c, 0x08, 0x03, 0xa6,
    0x7c, 0x08, 0x02, 0xa6, 0x7c, 0x09, 0x03, 0xa6, 0x7c, 0x09, 0x02, 0xa6, 0x7c, 0x12, 0x03, 0xa6,
    0x7c, 0x12, 0x02, 0xa6, 0x7c, 0x13, 0x03, 0xa6, 0x7c, 0x13, 0x02, 0xa6, 0x7c, 0x16, 0x03, 0xa6,
    0x7c, 0x16, 0x02, 0xa6, 0x7c, 0x19, 0x03, 0xa6, 0x7c, 0x19, 0x02, 0xa6, 0x7c, 0x1a, 0x03, 0xa6,
    0x7c, 0x1a, 0x02, 0xa6, 0x7c, 0x1b, 0x03, 0xa6, 0x7c, 0x1b, 0x02, 0xa6, 0x7c, 0x1a, 0x43, 0xa6,
    0x7c, 0x1a, 0x42, 0xa6, 0x7c, 0x1c, 0x43, 0xa6, 0x7c, 0x0c, 0x42, 0xe6, 0x7c, 0x1d, 0x43, 0xa6,
    0x7c, 0x0d, 0x42, 0xe6, 0x7c, 0x90, 0x43, 0xa6, 0x7c, 0x11, 0x42, 0xa6, 0x7c, 0x30, 0x83, 0xa6,
    0x7c, 0x12, 0x82, 0xa6, 0x7c, 0x31, 0x83, 0xa6, 0x7c, 0x13, 0x82, 0xa6, 0x7c, 0x38, 0x83, 0xa6,
    0x7c, 0x1a, 0x82, 0xa6, 0x7c, 0x39, 0x83, 0xa6, 0x7c, 0x1b, 0x82, 0xa6, 0x60, 0x00, 0x00, 0x00,
    0x38, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x04, 0x38, 0x08, 0x00, 0x04, 0x7c, 0x0f, 0xf1, 0x20,
    0x7c, 0x04, 0x02, 0xa6, 0x7c, 0x0c, 0x42, 0xe6, 0x7c, 0x80, 0x03, 0xa6, 0x7c, 0x08, 0x20, 0x50,
    0x7c, 0x08, 0x20, 0x51, 0x7c, 0x08, 0x24, 0x50, 0x7c, 0x08, 0x24, 0x51, 0x7c, 0x08, 0x20, 0x10,
    0x7c, 0x08, 0x20, 0x11, 0x7c, 0x08, 0x24, 0x10, 0x7c, 0x08, 0x24, 0x11, 0x54, 0x80, 0x60, 0x0e,
    0x54, 0x80, 0x60, 0x0f, 0x54, 0x80, 0xa6, 0x3e, 0x54, 0x80, 0xa6, 0x3f, 0x50, 0x80, 0xa3, 0x26,
    0x50, 0x80, 0xa3, 0x27, 0x50, 0x80, 0x63, 0x26, 0x50, 0x80, 0x63, 0x27, 0x54, 0x80, 0x40, 0x3e,
    0x54, 0x80, 0x40, 0x3f, 0x54, 0x80, 0xc0, 0x3e, 0x54, 0x80, 0xc0, 0x3f, 0x5c, 0x80, 0x40, 0x3e,
    0x5c, 0x80, 0x40, 0x3f, 0x54, 0x80, 0x40, 0x2e, 0x54, 0x80, 0x40, 0x2f, 0x54, 0x80, 0xc2, 0x3e,
    0x54, 0x80, 0xc2, 0x3f, 0x54, 0x80, 0x02, 0x3e, 0x54, 0x80, 0x02, 0x3f, 0x54, 0x80, 0x00, 0x2e,
    0x54, 0x80, 0x00, 0x2f, 0x54, 0x80, 0x41, 0x2e, 0x54, 0x80, 0x41, 0x2f, 0x7c, 0x80, 0x23, 0x78,
    0x7c, 0x80, 0x23, 0x79, 0x7c, 0x80, 0x20, 0xf8, 0x7c, 0x80, 0x20, 0xf9, 0x41, 0x80, 0x00, 0x04,
    0x41, 0x80, 0x00, 0x05, 0x41, 0x80, 0x00, 0x06, 0x41, 0x80, 0x00, 0x07, 0x41, 0x80, 0x00, 0x04,
    0x41, 0x80, 0x00, 0x05, 0x41, 0x80, 0x00, 0x06, 0x41, 0x80, 0x00, 0x07, 0x41, 0xa0, 0x00, 0x04,
    0x41, 0xa0, 0x00, 0x05, 0x41, 0xa0, 0x00, 0x06, 0x41, 0xa0, 0x00, 0x07, 0x40, 0x80, 0x00, 0x04,
    0x40, 0x80, 0x00, 0x05, 0x40, 0x80, 0x00, 0x06, 0x40, 0x80, 0x00, 0x07, 0x40, 0x80, 0x00, 0x04,
    0x40, 0x80, 0x00, 0x05, 0x40, 0x80, 0x00, 0x06, 0x40, 0x80, 0x00, 0x07, 0x40, 0xa0, 0x00, 0x04,
    0x40, 0xa0, 0x00, 0x05, 0x40, 0xa0, 0x00, 0x06, 0x40, 0xa0, 0x00, 0x07, 0x42, 0x00, 0x00, 0x00,
    0x42, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x02, 0x42, 0x00, 0x00, 0x03, 0x42, 0x00, 0x00, 0x00,
    0x42, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x02, 0x42, 0x00, 0x00, 0x03, 0x42, 0x20, 0x00, 0x00,
    0x42, 0x20, 0x00, 0x01, 0x42, 0x20, 0x00, 0x02, 0x42, 0x20, 0x00, 0x03, 0x41, 0x00, 0x00, 0x04,
    0x41, 0x00, 0x00, 0x05, 0x41, 0x00, 0x00, 0x06, 0x41, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x04,
    0x41, 0x00, 0x00, 0x05, 0x41, 0x00, 0x00, 0x06, 0x41, 0x00, 0x00, 0x07, 0x41, 0x20, 0x00, 0x04,
    0x41, 0x20, 0x00, 0x05, 0x41, 0x20, 0x00, 0x06, 0x41, 0x20, 0x00, 0x07, 0x40, 0x00, 0x00, 0x04,
    0x40, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x04,
    0x40, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x07, 0x40, 0x20, 0x00, 0x04,
    0x40, 0x20, 0x00, 0x05, 0x40, 0x20, 0x00, 0x06, 0x40, 0x20, 0x00, 0x07, 0x42, 0x40, 0x00, 0x00,
    0x42, 0x40, 0x00, 0x01, 0x42, 0x40, 0x00, 0x02, 0x42, 0x40, 0x00, 0x03, 0x42, 0x40, 0x00, 0x00,
    0x42, 0x40, 0x00, 0x01, 0x42, 0x40, 0x00, 0x02, 0x42, 0x40, 0x00, 0x03, 0x42, 0x60, 0x00, 0x00,
    0x42, 0x60, 0x00, 0x01, 0x42, 0x60, 0x00, 0x02, 0x42, 0x60, 0x00, 0x03, 0x41, 0x40, 0x00, 0x04,
    0x41, 0x40, 0x00, 0x05, 0x41, 0x40, 0x00, 0x06, 0x41, 0x40, 0x00, 0x07, 0x41, 0x40, 0x00, 0x04,
    0x41, 0x40, 0x00, 0x05, 0x41, 0x40, 0x00, 0x06, 0x41, 0x40, 0x00, 0x07, 0x41, 0x60, 0x00, 0x04,
    0x41, 0x60, 0x00, 0x05, 0x41, 0x60, 0x00, 0x06, 0x41, 0x60, 0x00, 0x07, 0x40, 0x40, 0x00, 0x04,
    0x40, 0x40, 0x00, 0x05, 0x40, 0x40, 0x00, 0x06, 0x40, 0x40, 0x00, 0x07, 0x40, 0x40, 0x00, 0x04,
    0x40, 0x40, 0x00, 0x05, 0x40, 0x40, 0x00, 0x06, 0x40, 0x40, 0x00, 0x07, 0x40, 0x60, 0x00, 0x04,
    0x40, 0x60, 0x00, 0x05, 0x40, 0x60, 0x00, 0x06, 0x40, 0x60, 0x00, 0x07, 0x41, 0x80, 0x00, 0x00,
    0x41, 0x80, 0x00, 0x04, 0x41, 0x80, 0x00, 0x01, 0x41, 0x80, 0x00, 0x05, 0x41, 0x80, 0x00, 0x02,
    0x41, 0x80, 0x00, 0x06, 0x41, 0x80, 0x00, 0x03, 0x41, 0x80, 0x00, 0x07, 0x41, 0x80, 0x00, 0x00,
    0x41, 0x80, 0x00, 0x04, 0x41, 0x80, 0x00, 0x01, 0x41, 0x80, 0x00, 0x05, 0x41, 0x80, 0x00, 0x02,
    0x41, 0x80, 0x00, 0x06, 0x41, 0x80, 0x00, 0x03, 0x41, 0x80, 0x00, 0x07, 0x41, 0xa0, 0x00, 0x00,
    0x41, 0xa0, 0x00, 0x04, 0x41, 0xa0, 0x00, 0x01, 0x41, 0xa0, 0x00, 0x05, 0x41, 0xa0, 0x00, 0x02,
    0x41, 0xa0, 0x00, 0x06, 0x41, 0xa0, 0x00, 0x03, 0x41, 0xa0, 0x00, 0x07, 0x40, 0x81, 0x00, 0x00,
    0x40, 0x81, 0x00, 0x04, 0x40, 0x81, 0x00, 0x01, 0x40, 0x81, 0x00, 0x05, 0x40, 0x81, 0x00, 0x02,
    0x40, 0x81, 0x00, 0x06, 0x40, 0x81, 0x00, 0x03, 0x40, 0x81, 0x00, 0x07, 0x40, 0x81, 0x00, 0x00,
    0x40, 0x81, 0x00, 0x04, 0x40, 0x81, 0x00, 0x01, 0x40, 0x81, 0x00, 0x05, 0x40, 0x81, 0x00, 0x02,
    0x40, 0x81, 0x00, 0x06, 0x40, 0x81, 0x00, 0x03, 0x40, 0x81, 0x00, 0x07, 0x40, 0xa1, 0x00, 0x00,
    0x40, 0xa1, 0x00, 0x04, 0x40, 0xa1, 0x00, 0x01, 0x40, 0xa1, 0x00, 0x05, 0x40, 0xa1, 0x00, 0x02,
    0x40, 0xa1, 0x00, 0x06, 0x40, 0xa1, 0x00, 0x03, 0x40, 0xa1, 0x00, 0x07, 0x41, 0x82, 0x00, 0x00,
    0x41, 0x82, 0x00, 0x04, 0x41, 0x82, 0x00, 0x01, 0x41, 0x82, 0x00, 0x05, 0x41, 0x82, 0x00, 0x02,
    0x41, 0x82, 0x00, 0x06, 0x41, 0x82, 0x00, 0x03, 0x41, 0x82, 0x00, 0x07, 0x41, 0x82, 0x00, 0x00,
    0x41, 0x82, 0x00, 0x04, 0x41, 0x82, 0x00, 0x01, 0x41, 0x82, 0x00, 0x05, 0x41, 0x82, 0x00, 0x02,
    0x41, 0x82, 0x00, 0x06, 0x41, 0x82, 0x00, 0x03, 0x41, 0x82, 0x00, 0x07, 0x41, 0xa2, 0x00, 0x00,
    0x41, 0xa2, 0x00, 0x04, 0x41, 0xa2, 0x00, 0x01, 0x41, 0xa2, 0x00, 0x05, 0x41, 0xa2, 0x00, 0x02,
    0x41, 0xa2, 0x00, 0x06, 0x41, 0xa2, 0x00, 0x03, 0x41, 0xa2, 0x00, 0x07, 0x40, 0x80, 0x00, 0x00,
    0x40, 0x80, 0x00, 0x04, 0x40, 0x80, 0x00, 0x01, 0x40, 0x80, 0x00, 0x05, 0x40, 0x80, 0x00, 0x02,
    0x40, 0x80, 0x00, 0x06, 0x40, 0x80, 0x00, 0x03, 0x40, 0x80, 0x00, 0x07, 0x40, 0x80, 0x00, 0x00,
    0x40, 0x80, 0x00, 0x04, 0x40, 0x80, 0x00, 0x01, 0x40, 0x80, 0x00, 0x05, 0x40, 0x80, 0x00, 0x02,
    0x40, 0x80, 0x00, 0x06, 0x40, 0x80, 0x00, 0x03, 0x40, 0x80, 0x00, 0x07, 0x40, 0xa0, 0x00, 0x00,
    0x40, 0xa0, 0x00, 0x04, 0x40, 0xa0, 0x00, 0x01, 0x40, 0xa0, 0x00, 0x05, 0x40, 0xa0, 0x00, 0x02,
    0x40, 0xa0, 0x00, 0x06, 0x40, 0xa0, 0x00, 0x03, 0x40, 0xa0, 0x00, 0x07, 0x41, 0x81, 0x00, 0x00,
    0x41, 0x81, 0x00, 0x04, 0x41, 0x81, 0x00, 0x01, 0x41, 0x81, 0x00, 0x05, 0x41, 0x81, 0x00, 0x02,
    0x41, 0x81, 0x00, 0x06, 0x41, 0x81, 0x00, 0x03, 0x41, 0x81, 0x00, 0x07, 0x41, 0x81, 0x00, 0x00,
    0x41, 0x81, 0x00, 0x04, 0x41, 0x81, 0x00, 0x01, 0x41, 0x81, 0x00, 0x05, 0x41, 0x81, 0x00, 0x02,
    0x41, 0x81, 0x00, 0x06, 0x41, 0x81, 0x00, 0x03, 0x41, 0x81, 0x00, 0x07, 0x41, 0xa1, 0x00, 0x00,
    0x41, 0xa1, 0x00, 0x04, 0x41, 0xa1, 0x00, 0x01, 0x41, 0xa1, 0x00, 0x05, 0x41, 0xa1, 0x00, 0x02,
    0x41, 0xa1, 0x00, 0x06, 0x41, 0xa1, 0x00, 0x03, 0x41, 0xa1, 0x00, 0x07, 0x40, 0x80, 0x00, 0x00,
    0x40, 0x80, 0x00, 0x04, 0x40, 0x80, 0x00, 0x01, 0x40, 0x80, 0x00, 0x05, 0x40, 0x80, 0x00, 0x02,
    0x40, 0x80, 0x00, 0x06, 0x40, 0x80, 0x00, 0x03, 0x40, 0x80, 0x00, 0x07, 0x40, 0x80, 0x00, 0x00,
    0x40, 0x80, 0x00, 0x04, 0x40, 0x80, 0x00, 0x01, 0x40, 0x80, 0x00, 0x05, 0x40, 0x80, 0x00, 0x02,
    0x40, 0x80, 0x00, 0x06, 0x40, 0x80, 0x00, 0x03, 0x40, 0x80, 0x00, 0x07, 0x40, 0xa0, 0x00, 0x00,
    0x40, 0xa0, 0x00, 0x04, 0x40, 0xa0, 0x00, 0x01, 0x40, 0xa0, 0x00, 0x05, 0x40, 0xa0, 0x00, 0x02,
    0x40, 0xa0, 0x00, 0x06, 0x40, 0xa0, 0x00, 0x03, 0x40, 0xa0, 0x00, 0x07, 0x40, 0x82, 0x00, 0x00,
    0x40, 0x82, 0x00, 0x04, 0x40, 0x82, 0x00, 0x01, 0x40, 0x82, 0x00, 0x05, 0x40, 0x82, 0x00, 0x02,
    0x40, 0x82, 0x00, 0x06, 0x40, 0x82, 0x00, 0x03, 0x40, 0x82, 0x00, 0x07, 0x40, 0x82, 0x00, 0x00,
    0x40, 0x82, 0x00, 0x04, 0x40, 0x82, 0x00, 0x01, 0x40, 0x82, 0x00, 0x05, 0x40, 0x82, 0x00, 0x02,
    0x40, 0x82, 0x00, 0x06, 0x40, 0x82, 0x00, 0x03, 0x40, 0x82, 0x00, 0x07, 0x40, 0xa2, 0x00, 0x00,
    0x40, 0xa2, 0x00, 0x04, 0x40, 0xa2, 0x00, 0x01, 0x40, 0xa2, 0x00, 0x05, 0x40, 0xa2, 0x00, 0x02,
    0x40, 0xa2, 0x00, 0x06, 0x40, 0xa2, 0x00, 0x03, 0x40, 0xa2, 0x00, 0x07, 0x40, 0x81, 0x00, 0x00,
    0x40, 0x81, 0x00, 0x04, 0x40, 0x81, 0x00, 0x01, 0x40, 0x81, 0x00, 0x05, 0x40, 0x81, 0x00, 0x02,
    0x40, 0x81, 0x00, 0x06, 0x40, 0x81, 0x00, 0x03, 0x40, 0x81, 0x00, 0x07, 0x40, 0x81, 0x00, 0x00,
    0x40, 0x81, 0x00, 0x04, 0x40, 0x81, 0x00, 0x01, 0x40, 0x81, 0x00, 0x05, 0x40, 0x81, 0x00, 0x02,
    0x40, 0x81, 0x00, 0x06, 0x40, 0x81, 0x00, 0x03, 0x40, 0x81, 0x00, 0x07, 0x40, 0xa1, 0x00, 0x00,
    0x40, 0xa1, 0x00, 0x04, 0x40, 0xa1, 0x00, 0x01, 0x40, 0xa1, 0x00, 0x05, 0x40, 0xa1, 0x00, 0x02,
    0x40, 0xa1, 0x00, 0x06, 0x40, 0xa1, 0x00, 0x03, 0x40, 0xa1, 0x00, 0x07, 0x41, 0x83, 0x00, 0x00,
    0x41, 0x83, 0x00, 0x04, 0x41, 0x83, 0x00, 0x01, 0x41, 0x83, 0x00, 0x05, 0x41, 0x83, 0x00, 0x02,
    0x41, 0x83, 0x00, 0x06, 0x41, 0x83, 0x00, 0x03, 0x41, 0x83, 0x00, 0x07, 0x41, 0x83, 0x00, 0x00,
    0x41, 0x83, 0x00, 0x04, 0x41, 0x83, 0x00, 0x01, 0x41, 0x83, 0x00, 0x05, 0x41, 0x83, 0x00, 0x02,
    0x41, 0x83, 0x00, 0x06, 0x41, 0x83, 0x00, 0x03, 0x41, 0x83, 0x00, 0x07, 0x41, 0xa3, 0x00, 0x00,
    0x41, 0xa3, 0x00, 0x04, 0x41, 0xa3, 0x00, 0x01, 0x41, 0xa3, 0x00, 0x05, 0x41, 0xa3, 0x00, 0x02,
    0x41, 0xa3, 0x00, 0x06, 0x41, 0xa3, 0x00, 0x03, 0x41, 0xa3, 0x00, 0x07, 0x40, 0x83, 0x00, 0x00,
    0x40, 0x83, 0x00, 0x04, 0x40, 0x83, 0x00, 0x01, 0x40, 0x83, 0x00, 0x05, 0x40, 0x83, 0x00, 0x02,
    0x40, 0x83, 0x00, 0x06, 0x40, 0x83, 0x00, 0x03, 0x40, 0x83, 0x00, 0x07, 0x40, 0x83, 0x00, 0x00,
    0x40, 0x83, 0x00, 0x04, 0x40, 0x83, 0x00, 0x01, 0x40, 0x83, 0x00, 0x05, 0x40, 0x83, 0x00, 0x02,
    0x40, 0x83, 0x00, 0x06, 0x40, 0x83, 0x00, 0x03, 0x40, 0x83, 0x00, 0x07, 0x40, 0xa3, 0x00, 0x00,
    0x40, 0xa3, 0x00, 0x04, 0x40, 0xa3, 0x00, 0x01, 0x40, 0xa3, 0x00, 0x05, 0x40, 0xa3, 0x00, 0x02,
    0x40, 0xa3, 0x00, 0x06, 0x40, 0xa3, 0x00, 0x03, 0x40, 0xa3, 0x00, 0x07, 0x41, 0x83, 0x00, 0x00,
    0x41, 0x83, 0x00, 0x04, 0x41, 0x83, 0x00, 0x01, 0x41, 0x83, 0x00, 0x05, 0x41, 0x83, 0x00, 0x02,
    0x41, 0x83, 0x00, 0x06, 0x41, 0x83, 0x00, 0x03, 0x41, 0x83, 0x00, 0x07, 0x41, 0x83, 0x00, 0x00,
    0x41, 0x83, 0x00, 0x04, 0x41, 0x83, 0x00, 0x01, 0x41, 0x83, 0x00, 0x05, 0x41, 0x83, 0x00, 0x02,
    0x41, 0x83, 0x00, 0x06, 0x41, 0x83, 0x00, 0x03, 0x41, 0x83, 0x00, 0x07, 0x41, 0xa3, 0x00, 0x00,
    0x41, 0xa3, 0x00, 0x04, 0x41, 0xa3, 0x00, 0x01, 0x41, 0xa3, 0x00, 0x05, 0x41, 0xa3, 0x00, 0x02,
    0x41, 0xa3, 0x00, 0x06, 0x41, 0xa3, 0x00, 0x03, 0x41, 0xa3, 0x00, 0x07, 0x40, 0x83, 0x00, 0x00,
    0x40, 0x83, 0x00, 0x04, 0x40, 0x83, 0x00, 0x01, 0x40, 0x83, 0x00, 0x05, 0x40, 0x83, 0x00, 0x02,
    0x40, 0x83, 0x00, 0x06, 0x40, 0x83, 0x00, 0x03, 0x40, 0x83, 0x00, 0x07, 0x40, 0x83, 0x00, 0x00,
    0x40, 0x83, 0x00, 0x04, 0x40, 0x83, 0x00, 0x01, 0x40, 0x83, 0x00, 0x05, 0x40, 0x83, 0x00, 0x02,
    0x40, 0x83, 0x00, 0x06, 0x40, 0x83, 0x00, 0x03, 0x40, 0x83, 0x00, 0x07, 0x40, 0xa3, 0x00, 0x00,
    0x40, 0xa3, 0x00, 0x04, 0x40, 0xa3, 0x00, 0x01, 0x40, 0xa3, 0x00, 0x05, 0x40, 0xa3, 0x00, 0x02,
    0x40, 0xa3, 0x00, 0x06, 0x40, 0xa3, 0x00, 0x03, 0x40, 0xa3, 0x00, 0x07, 0x4e, 0x80, 0x00, 0x20,
    0x4e, 0x80, 0x00, 0x21, 0x4e, 0x80, 0x04, 0x20, 0x4e, 0x80, 0x04, 0x21, 0x4d, 0x80, 0x00, 0x20,
    0x4d, 0x80, 0x00, 0x21, 0x4d, 0x80, 0x00, 0x20, 0x4d, 0x80, 0x00, 0x21, 0x4d, 0xa0, 0x00, 0x20,
    0x4d, 0xa0, 0x00, 0x21, 0x4d, 0x80, 0x04, 0x20, 0x4d, 0x80, 0x04, 0x21, 0x4d, 0x80, 0x04, 0x20,
    0x4d, 0x80, 0x04, 0x21, 0x4d, 0xa0, 0x04, 0x20, 0x4d, 0xa0, 0x04, 0x21, 0x4c, 0x80, 0x00, 0x20,
    0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x20, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0xa0, 0x00, 0x20,
    0x4c, 0xa0, 0x00, 0x21, 0x4c, 0x80, 0x04, 0x20, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x20,
    0x4c, 0x80, 0x04, 0x21, 0x4c, 0xa0, 0x04, 0x20, 0x4c, 0xa0, 0x04, 0x21, 0x4e, 0x00, 0x00, 0x20,
    0x4e, 0x00, 0x00, 0x21, 0x4e, 0x00, 0x00, 0x20, 0x4e, 0x00, 0x00, 0x21, 0x4e, 0x20, 0x00, 0x20,
    0x4e, 0x20, 0x00, 0x21, 0x4d, 0x00, 0x00, 0x20, 0x4d, 0x00, 0x00, 0x21, 0x4d, 0x00, 0x00, 0x20,
    0x4d, 0x00, 0x00, 0x21, 0x4d, 0x20, 0x00, 0x20, 0x4d, 0x20, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x20,
    0x4c, 0x00, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x20, 0x4c, 0x00, 0x00, 0x21, 0x4c, 0x20, 0x00, 0x20,
    0x4c, 0x20, 0x00, 0x21, 0x4e, 0x40, 0x00, 0x20, 0x4e, 0x40, 0x00, 0x21, 0x4e, 0x40, 0x00, 0x20,
    0x4e, 0x40, 0x00, 0x21, 0x4e, 0x60, 0x00, 0x20, 0x4e, 0x60, 0x00, 0x21, 0x4d, 0x40, 0x00, 0x20,
    0x4d, 0x40, 0x00, 0x21, 0x4d, 0x40, 0x00, 0x20, 0x4d, 0x40, 0x00, 0x21, 0x4d, 0x60, 0x00, 0x20,
    0x4d, 0x60, 0x00, 0x21, 0x4c, 0x40, 0x00, 0x20, 0x4c, 0x40, 0x00, 0x21, 0x4c, 0x40, 0x00, 0x20,
    0x4c, 0x40, 0x00, 0x21, 0x4c, 0x60, 0x00, 0x20, 0x4c, 0x60, 0x00, 0x21, 0x4d, 0x80, 0x00, 0x20,
    0x4d, 0x80, 0x00, 0x20, 0x4d, 0x80, 0x00, 0x21, 0x4d, 0x80, 0x00, 0x21, 0x4d, 0x80, 0x00, 0x20,
    0x4d, 0x80, 0x00, 0x20, 0x4d, 0x80, 0x00, 0x21, 0x4d, 0x80, 0x00, 0x21, 0x4d, 0xa0, 0x00, 0x20,
    0x4d, 0xa0, 0x00, 0x20, 0x4d, 0xa0, 0x00, 0x21, 0x4d, 0xa0, 0x00, 0x21, 0x4d, 0x80, 0x04, 0x20,
    0x4d, 0x80, 0x04, 0x20, 0x4d, 0x80, 0x04, 0x21, 0x4d, 0x80, 0x04, 0x21, 0x4d, 0x80, 0x04, 0x20,
    0x4d, 0x80, 0x04, 0x20, 0x4d, 0x80, 0x04, 0x21, 0x4d, 0x80, 0x04, 0x21, 0x4d, 0xa0, 0x04, 0x20,
    0x4d, 0xa0, 0x04, 0x20, 0x4d, 0xa0, 0x04, 0x21, 0x4d, 0xa0, 0x04, 0x21, 0x4c, 0x81, 0x00, 0x20,
    0x4c, 0x81, 0x00, 0x20, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0x81, 0x00, 0x20,
    0x4c, 0x81, 0x00, 0x20, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0xa1, 0x00, 0x20,
    0x4c, 0xa1, 0x00, 0x20, 0x4c, 0xa1, 0x00, 0x21, 0x4c, 0xa1, 0x00, 0x21, 0x4c, 0x81, 0x04, 0x20,
    0x4c, 0x81, 0x04, 0x20, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0x81, 0x04, 0x20,
    0x4c, 0x81, 0x04, 0x20, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0xa1, 0x04, 0x20,
    0x4c, 0xa1, 0x04, 0x20, 0x4c, 0xa1, 0x04, 0x21, 0x4c, 0xa1, 0x04, 0x21, 0x4d, 0x82, 0x00, 0x20,
    0x4d, 0x82, 0x00, 0x20, 0x4d, 0x82, 0x00, 0x21, 0x4d, 0x82, 0x00, 0x21, 0x4d, 0x82, 0x00, 0x20,
    0x4d, 0x82, 0x00, 0x20, 0x4d, 0x82, 0x00, 0x21, 0x4d, 0x82, 0x00, 0x21, 0x4d, 0xa2, 0x00, 0x20,
    0x4d, 0xa2, 0x00, 0x20, 0x4d, 0xa2, 0x00, 0x21, 0x4d, 0xa2, 0x00, 0x21, 0x4d, 0x82, 0x04, 0x20,
    0x4d, 0x82, 0x04, 0x20, 0x4d, 0x82, 0x04, 0x21, 0x4d, 0x82, 0x04, 0x21, 0x4d, 0x82, 0x04, 0x20,
    0x4d, 0x82, 0x04, 0x20, 0x4d, 0x82, 0x04, 0x21, 0x4d, 0x82, 0x04, 0x21, 0x4d, 0xa2, 0x04, 0x20,
    0x4d, 0xa2, 0x04, 0x20, 0x4d, 0xa2, 0x04, 0x21, 0x4d, 0xa2, 0x04, 0x21, 0x4c, 0x80, 0x00, 0x20,
    0x4c, 0x80, 0x00, 0x20, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x20,
    0x4c, 0x80, 0x00, 0x20, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0xa0, 0x00, 0x20,
    0x4c, 0xa0, 0x00, 0x20, 0x4c, 0xa0, 0x00, 0x21, 0x4c, 0xa0, 0x00, 0x21, 0x4c, 0x80, 0x04, 0x20,
    0x4c, 0x80, 0x04, 0x20, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x20,
    0x4c, 0x80, 0x04, 0x20, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0xa0, 0x04, 0x20,
    0x4c, 0xa0, 0x04, 0x20, 0x4c, 0xa0, 0x04, 0x21, 0x4c, 0xa0, 0x04, 0x21, 0x4d, 0x81, 0x00, 0x20,
    0x4d, 0x81, 0x00, 0x20, 0x4d, 0x81, 0x00, 0x21, 0x4d, 0x81, 0x00, 0x21, 0x4d, 0x81, 0x00, 0x20,
    0x4d, 0x81, 0x00, 0x20, 0x4d, 0x81, 0x00, 0x21, 0x4d, 0x81, 0x00, 0x21, 0x4d, 0xa1, 0x00, 0x20,
    0x4d, 0xa1, 0x00, 0x20, 0x4d, 0xa1, 0x00, 0x21, 0x4d, 0xa1, 0x00, 0x21, 0x4d, 0x81, 0x04, 0x20,
    0x4d, 0x81, 0x04, 0x20, 0x4d, 0x81, 0x04, 0x21, 0x4d, 0x81, 0x04, 0x21, 0x4d, 0x81, 0x04, 0x20,
    0x4d, 0x81, 0x04, 0x20, 0x4d, 0x81, 0x04, 0x21, 0x4d, 0x81, 0x04, 0x21, 0x4d, 0xa1, 0x04, 0x20,
    0x4d, 0xa1, 0x04, 0x20, 0x4d, 0xa1, 0x04, 0x21, 0x4d, 0xa1, 0x04, 0x21, 0x4c, 0x80, 0x00, 0x20,
    0x4c, 0x80, 0x00, 0x20, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x20,
    0x4c, 0x80, 0x00, 0x20, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0x80, 0x00, 0x21, 0x4c, 0xa0, 0x00, 0x20,
    0x4c, 0xa0, 0x00, 0x20, 0x4c, 0xa0, 0x00, 0x21, 0x4c, 0xa0, 0x00, 0x21, 0x4c, 0x80, 0x04, 0x20,
    0x4c, 0x80, 0x04, 0x20, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x20,
    0x4c, 0x80, 0x04, 0x20, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0x80, 0x04, 0x21, 0x4c, 0xa0, 0x04, 0x20,
    0x4c, 0xa0, 0x04, 0x20, 0x4c, 0xa0, 0x04, 0x21, 0x4c, 0xa0, 0x04, 0x21, 0x4c, 0x82, 0x00, 0x20,
    0x4c, 0x82, 0x00, 0x20, 0x4c, 0x82, 0x00, 0x21, 0x4c, 0x82, 0x00, 0x21, 0x4c, 0x82, 0x00, 0x20,
    0x4c, 0x82, 0x00, 0x20, 0x4c, 0x82, 0x00, 0x21, 0x4c, 0x82, 0x00, 0x21, 0x4c, 0xa2, 0x00, 0x20,
    0x4c, 0xa2, 0x00, 0x20, 0x4c, 0xa2, 0x00, 0x21, 0x4c, 0xa2, 0x00, 0x21, 0x4c, 0x82, 0x04, 0x20,
    0x4c, 0x82, 0x04, 0x20, 0x4c, 0x82, 0x04, 0x21, 0x4c, 0x82, 0x04, 0x21, 0x4c, 0x82, 0x04, 0x20,
    0x4c, 0x82, 0x04, 0x20, 0x4c, 0x82, 0x04, 0x21, 0x4c, 0x82, 0x04, 0x21, 0x4c, 0xa2, 0x04, 0x20,
    0x4c, 0xa2, 0x04, 0x20, 0x4c, 0xa2, 0x04, 0x21, 0x4c, 0xa2, 0x04, 0x21, 0x4c, 0x81, 0x00, 0x20,
    0x4c, 0x81, 0x00, 0x20, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0x81, 0x00, 0x20,
    0x4c, 0x81, 0x00, 0x20, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0x81, 0x00, 0x21, 0x4c, 0xa1, 0x00, 0x20,
    0x4c, 0xa1, 0x00, 0x20, 0x4c, 0xa1, 0x00, 0x21, 0x4c, 0xa1, 0x00, 0x21, 0x4c, 0x81, 0x04, 0x20,
    0x4c, 0x81, 0x04, 0x20, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0x81, 0x04, 0x20,
    0x4c, 0x81, 0x04, 0x20, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0x81, 0x04, 0x21, 0x4c, 0xa1, 0x04, 0x20,
    0x4c, 0xa1, 0x04, 0x20, 0x4c, 0xa1, 0x04, 0x21, 0x4c, 0xa1, 0x04, 0x21, 0x4d, 0x83, 0x00, 0x20,
    0x4d, 0x83, 0x00, 0x20, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0x83, 0x00, 0x20,
    0x4d, 0x83, 0x00, 0x20, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0xa3, 0x00, 0x20,
    0x4d, 0xa3, 0x00, 0x20, 0x4d, 0xa3, 0x00, 0x21, 0x4d, 0xa3, 0x00, 0x21, 0x4d, 0x83, 0x04, 0x20,
    0x4d, 0x83, 0x04, 0x20, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0x83, 0x04, 0x20,
    0x4d, 0x83, 0x04, 0x20, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0xa3, 0x04, 0x20,
    0x4d, 0xa3, 0x04, 0x20, 0x4d, 0xa3, 0x04, 0x21, 0x4d, 0xa3, 0x04, 0x21, 0x4c, 0x83, 0x00, 0x20,
    0x4c, 0x83, 0x00, 0x20, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0x83, 0x00, 0x20,
    0x4c, 0x83, 0x00, 0x20, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0xa3, 0x00, 0x20,
    0x4c, 0xa3, 0x00, 0x20, 0x4c, 0xa3, 0x00, 0x21, 0x4c, 0xa3, 0x00, 0x21, 0x4c, 0x83, 0x04, 0x20,
    0x4c, 0x83, 0x04, 0x20, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0x83, 0x04, 0x20,
    0x4c, 0x83, 0x04, 0x20, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0xa3, 0x04, 0x20,
    0x4c, 0xa3, 0x04, 0x20, 0x4c, 0xa3, 0x04, 0x21, 0x4c, 0xa3, 0x04, 0x21, 0x4d, 0x83, 0x00, 0x20,
    0x4d, 0x83, 0x00, 0x20, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0x83, 0x00, 0x20,
    0x4d, 0x83, 0x00, 0x20, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0x83, 0x00, 0x21, 0x4d, 0xa3, 0x00, 0x20,
    0x4d, 0xa3, 0x00, 0x20, 0x4d, 0xa3, 0x00, 0x21, 0x4d, 0xa3, 0x00, 0x21, 0x4d, 0x83, 0x04, 0x20,
    0x4d, 0x83, 0x04, 0x20, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0x83, 0x04, 0x20,
    0x4d, 0x83, 0x04, 0x20, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0x83, 0x04, 0x21, 0x4d, 0xa3, 0x04, 0x20,
    0x4d, 0xa3, 0x04, 0x20, 0x4d, 0xa3, 0x04, 0x21, 0x4d, 0xa3, 0x04, 0x21, 0x4c, 0x83, 0x00, 0x20,
    0x4c, 0x83, 0x00, 0x20, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0x83, 0x00, 0x20,
    0x4c, 0x83, 0x00, 0x20, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0x83, 0x00, 0x21, 0x4c, 0xa3, 0x00, 0x20,
    0x4c, 0xa3, 0x00, 0x20, 0x4c, 0xa3, 0x00, 0x21, 0x4c, 0xa3, 0x00, 0x21, 0x4c, 0x83, 0x04, 0x20,
    0x4c, 0x83, 0x04, 0x20, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0x83, 0x04, 0x20,
    0x4c, 0x83, 0x04, 0x20, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0x83, 0x04, 0x21, 0x4c, 0xa3, 0x04, 0x20,
    0x4c, 0xa3, 0x04, 0x20, 0x4c, 0xa3, 0x04, 0x21, 0x4c, 0xa3, 0x04, 0x21,
};

TEST(Assembler, AllExtendedInstructions)
{
  auto res = Assemble(extended_instructions, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(extended_expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], extended_expect[i]) << "->i=" << i;
  }
}

TEST(Assembler, ByteDirectivesSimple)
{
  constexpr char assembly[] = ".byte 0\n"
                              ".Byte 0xff\n"
                              ".bYte 0x100\n"
                              ".2bYTe 0\n"
                              ".2bytE 0xff\n"
                              ".2BYte 0x100\n"
                              ".2bYTe 0xffff\n"
                              ".2byTE 0x10000\n"
                              ".4BytE 0\n"
                              ".4BYTe 0xff\n"
                              ".4bYTE 0x100\n"
                              ".4ByTE 0xffff\n"
                              ".4BYtE 0x10000\n"
                              ".4BYTE 0xffffffff\n"
                              ".4ByTe 0x100000000\n"
                              ".8bYtE 0\n"
                              ".8byte 0xff\n"
                              ".8byte 0x100\n"
                              ".8byte 0xffff\n"
                              ".8byte 0x10000\n"
                              ".8byte 0xffffffff\n"
                              ".8byte 0x100000000\n"
                              ".8byte 0xffffffffffffffff\n"
                              ".8byte 0x10000000000000000\n";
  constexpr u8 expect[] = {
      0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
      0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
      0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  };

  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, MultiOperandDirectives)
{
  constexpr char assembly[] = ".byte 0, 1, 2\n"
                              ".2byte 3, 4, 5\n"
                              ".4byte 6, 7, 8\n"
                              ".8byte 9, 10, 11\n";
  constexpr u8 expect[] = {
      0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0,  0, 0, 7, 0, 0, 0, 8, 0,  0,
      0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 11,
  };
  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, OperandExpressionDirectives)
{
  constexpr char assembly[] = ".byte 0 + 1, 1 * 4, 2 * 8\n"
                              ".2byte 3*6*9, 5*5*12, 81/9\n"
                              ".4byte 1<<12, 5>>3, 8^8\n"
                              ".8byte 0b1010 & 0b1101, 0b1010 | 0b0101, 0x12 + 010\n";
  constexpr u8 expect[] = {
      1, 4, 16, 0, 162, 1, 44, 0, 9, 0, 0, 16, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,          0,
      0, 0, 0,  0, 0,   8, 0,  0, 0, 0, 0, 0,  0, 15, 0, 0, 0, 0, 0, 0, 0, 0x12 + 010,
  };
  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, FloatDirectives)
{
  constexpr char assembly[] = ".float 0\n"
                              ".float 1, 2, 3.0\n"
                              ".float 1.25, 1.5e6, -2e-5\n"
                              ".double 0\n"
                              ".double 1, 2, 3.0\n"
                              ".double 1.0000001, 0.0000025, .000006e9\n";
  constexpr u8 expect[] = {
      0,    0,    0,    0,    0x3f, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40,
      0x00, 0x00, 0x3f, 0xa0, 0x00, 0x00, 0x49, 0xb7, 0x1b, 0x00, 0xb7, 0xa7, 0xc5, 0xac,
      0,    0,    0,    0,    0,    0,    0,    0,    0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x1a, 0xd7, 0xf2, 0x9b, 0x3e, 0xc4,
      0xf8, 0xb5, 0x88, 0xe3, 0x68, 0xf1, 0x40, 0xb7, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
  };
  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, ZeroDirectives)
{
  constexpr char assembly[] = ".zeros 0\n"
                              ".zeros 1\n"
                              ".zeros 5 + 5\n";
  constexpr u8 expect[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, StringDirectives)
{
  constexpr char assembly[] = ".ascii \"test string\"\n"
                              ".ascii \"string with \\n escapes \\r\"\n"
                              ".ascii \"string with octals \\123 \\0\"\n"
                              ".ascii \"string with hex \\x12\\x45\\x9912\"\n"
                              ".asciz \"null terminator\"\n";
  constexpr u8 expect[] = {
      't', 'e',  's', 't', ' ', 's',    't', 'r',  'i',    'n',    'g',    's', 't', 'r', 'i', 'n',
      'g', ' ',  'w', 'i', 't', 'h',    ' ', '\n', ' ',    'e',    's',    'c', 'a', 'p', 'e', 's',
      ' ', '\r', 's', 't', 'r', 'i',    'n', 'g',  ' ',    'w',    'i',    't', 'h', ' ', 'o', 'c',
      't', 'a',  'l', 's', ' ', '\123', ' ', '\0', 's',    't',    'r',    'i', 'n', 'g', ' ', 'w',
      'i', 't',  'h', ' ', 'h', 'e',    'x', ' ',  '\x12', '\x45', '\x12', 'n', 'u', 'l', 'l', ' ',
      't', 'e',  'r', 'm', 'i', 'n',    'a', 't',  'o',    'r',    '\0'};
  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));

  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, RelocateDirective)
{
  constexpr char assembly[] = ".zeros 5\n"
                              ".locate 100\n"
                              ".zeros 9\n"
                              ".locate 110\n"
                              ".zeros 10\n"
                              ".locate 120\n"
                              ".zeros 29\n"
                              ".locate 120 + 5*5+4 + 1\n"
                              ".zeros 1\n";
  constexpr u32 expect_addr[] = {0, 100, 110, 120, 150};
  constexpr size_t expect_size[] = {5, 9, 10, 29, 1};

  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), sizeof(expect_size) / sizeof(expect_size[0]));
  for (size_t i = 0; i < code_blocks.size(); i++)
  {
    EXPECT_EQ(code_blocks[i].instructions.size(), expect_size[i]) << " -> i=" << i;
    EXPECT_EQ(code_blocks[i].block_address, expect_addr[i]) << " -> i=" << i;
  }
}

TEST(Assembler, AlignmentDirectives)
{
  constexpr char assembly_align[] = ".zeros 1\n"
                                    ".align 0\n"
                                    ".zeros 1\n"
                                    ".align 1\n"
                                    ".zeros 1\n"
                                    ".align 2\n"
                                    ".zeros 1\n"
                                    ".align 4\n"
                                    ".zeros 1\n"
                                    ".align 4\n"
                                    ".zeros 1\n"
                                    ".align 10\n"
                                    ".byte 1\n"
                                    ".padalign 0\n"
                                    ".byte 1\n"
                                    ".padalign 1\n"
                                    ".byte 1\n"
                                    ".padalign 2\n"
                                    ".byte 1\n"
                                    ".padalign 4\n"
                                    ".byte 1\n"
                                    ".padalign 4\n"
                                    ".byte 1\n"
                                    ".padalign 10\n";
  constexpr u32 expect_addr[] = {0, 4, 16, 32, 1024};

  auto res = Assemble(assembly_align, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), sizeof(expect_addr) / sizeof(expect_addr[0]));
  for (size_t i = 0; i < code_blocks.size(); i++)
  {
    EXPECT_EQ(code_blocks[i].block_address, expect_addr[i]) << " -> i=" << i;
  }

  auto&& last_block = code_blocks.back().instructions;
  ASSERT_EQ(last_block.size(), 1024);
  for (size_t i = 0; i < 3; i++)
  {
    EXPECT_EQ(last_block[i], 1) << " -> i=" << i;
  }
  EXPECT_EQ(last_block[3], 0) << " -> i=4";
  EXPECT_EQ(last_block[4], 1) << " -> i=4";
  for (size_t i = 5; i < 16; i++)
  {
    EXPECT_EQ(last_block[i], 0) << " -> i=" << i;
  }
  EXPECT_EQ(last_block[16], 1) << " -> i=16";
  for (size_t i = 17; i < 32; i++)
  {
    EXPECT_EQ(last_block[i], 0) << " -> i=" << i;
  }
  EXPECT_EQ(last_block[32], 1) << " -> i=32";
  for (size_t i = 33; i < last_block.size(); i++)
  {
    EXPECT_EQ(last_block[i], 0) << " -> i=" << i;
  }
}

TEST(Assembler, SkipDirective)
{
  constexpr char assembly_align[] = ".byte 5\n"
                                    ".skip 0\n"
                                    ".byte 6\n"
                                    ".skip 1\n"
                                    ".byte 7\n"
                                    ".skip 10 * 10\n"
                                    ".byte 8\n";
  constexpr u32 expect_addr[] = {0, 3, 104};

  auto res = Assemble(assembly_align, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), sizeof(expect_addr) / sizeof(expect_addr[0]));

  EXPECT_EQ(code_blocks[0].block_address, expect_addr[0]) << " -> i=0";
  ASSERT_EQ(code_blocks[0].instructions.size(), 2);
  EXPECT_EQ(code_blocks[0].instructions[0], 5) << " -> i=0";
  EXPECT_EQ(code_blocks[0].instructions[1], 6) << " -> i=0";

  EXPECT_EQ(code_blocks[1].block_address, expect_addr[1]) << " -> i=1";
  ASSERT_EQ(code_blocks[1].instructions.size(), 1);
  EXPECT_EQ(code_blocks[1].instructions[0], 7) << " -> i=1";

  EXPECT_EQ(code_blocks[2].block_address, expect_addr[2]) << " -> i=2";
  ASSERT_EQ(code_blocks[2].instructions.size(), 1);
  EXPECT_EQ(code_blocks[2].instructions[0], 8) << " -> i=2";
}

TEST(Assembler, DefvarDirective)
{
  constexpr char assembly[] = ".defvar NewVar, 0\n"
                              ".defvar NewVar2, 123\n"
                              ".defvar __Name, 1*2+3+4\n"
                              ".defvar AB_cd00, 5*5+__Name\n"
                              ".2byte NewVar\n"
                              ".2byte NewVar2\n"
                              ".4byte __Name\n"
                              ".4byte AB_cd00\n"
                              ".4byte AB_cd00 + NewVar2\n";
  constexpr u8 expect[] = {
      0, 0, 0, 123, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 157,
  };

  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, VariousOperandExpressions)
{
  constexpr char assembly[] = ".locate 0x400\n"
                              "b .\n"
                              "b .\n"
                              ".locate 0x800\n"
                              "post_locate:\n"
                              "b `0x900`\n"
                              "b `0x800`\n"
                              "b `. + 0x10`\n"
                              "b post_locate\n"
                              "lis r0, post_locate_2@ha\n"
                              "ori r0, r0, post_locate_2@l\n"
                              "li r0, TestValue\n"
                              ".defvar TestValue, 1234\n"
                              "li r0, TestValue\n"
                              ".locate 0x80001234\n"
                              "post_locate_2:\n";
  constexpr u8 expect_0[] = {
      0x48, 0x00, 0x04, 0x00, 0x48, 0x00, 0x04, 0x04,
  };
  constexpr u8 expect_1[] = {
      0x48, 0x00, 0x01, 0x00, 0x4b, 0xff, 0xff, 0xfc, 0x48, 0x00, 0x00,
      0x10, 0x4b, 0xff, 0xff, 0xf4, 0x3c, 0x00, 0x80, 0x00, 0x60, 0x00,
      0x12, 0x34, 0x38, 0x00, 0x04, 0xd2, 0x38, 0x00, 0x04, 0xd2,
  };

  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 2);

  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect_0));
  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect_0[i]) << " -> i=" << i;
  }

  ASSERT_EQ(code_blocks[1].instructions.size(), sizeof(expect_1));
  for (size_t i = 0; i < code_blocks[1].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[1].instructions[i], expect_1[i]) << " -> i=" << i;
  }
}

TEST(Assembler, AbsRel)
{
  constexpr char assembly[] = ".locate 0x80001234\n"
                              "lbl0:\n"
                              ".defvar abs_loc, lbl0\n"
                              ".4byte lbl0\n"
                              ".2byte lbl0@ha\n"
                              ".2byte lbl0@l\n"
                              ".4byte .\n"
                              "b lbl0\n"
                              "b `abs_loc`\n";
  constexpr u8 expect[] = {
      0x80, 0x00, 0x12, 0x34, 0x80, 0x00, 0x12, 0x34, 0x80, 0x00,
      0x12, 0x3c, 0x4b, 0xff, 0xff, 0xf4, 0x4b, 0xff, 0xff, 0xf0,
  };

  auto res = Assemble(assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);

  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(expect));
  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], expect[i]) << " -> i=" << i;
  }
}

TEST(Assembler, BadTokens)
{
  constexpr char unterminated_str[] = ".ascii \"no terminator";
  constexpr char bad_hex_in_str[] = ".ascii \"\\xnot hex\"";
  constexpr char newline_in_str[] = ".ascii \"abc\nd\"";
  constexpr char bad_float_0[] = ".float";
  constexpr char bad_float_1[] = ".float 1.";
  constexpr char bad_float_2[] = ".float .";
  constexpr char bad_float_3[] = ".float -.5e";
  constexpr char bad_float_4[] = ".float -.6e+";

  EXPECT_TRUE(IsFailure(Assemble(unterminated_str, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bad_hex_in_str, 0)));
  EXPECT_TRUE(IsFailure(Assemble(newline_in_str, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bad_float_0, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bad_float_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bad_float_2, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bad_float_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bad_float_4, 0)));
}

TEST(Assembler, RangeTest)
{
  constexpr char gpr_range_0[] = "mr r3, -1";
  constexpr char gpr_range_1[] = "mr r3, 0";
  constexpr char gpr_range_2[] = "mr r3, 32";
  constexpr char gpr_range_3[] = "mr r3, 31";
  constexpr char crf_range_0[] = "cmpw -1, 0, 0";
  constexpr char crf_range_1[] = "cmpw 0, 0, 0";
  constexpr char crf_range_2[] = "cmpw 8, 0, 0";
  constexpr char crf_range_3[] = "cmpw 7, 0, 0";
  constexpr char bc_range_0[] = "beq 1 << 15";
  constexpr char bc_range_1[] = "beq (1 << 15) - 4";
  constexpr char bc_range_2[] = "beq -(1 << 15) - 4";
  constexpr char bc_range_3[] = "beq -(1 << 15)";
  constexpr char b_range_0[] = "b 1 << 25";
  constexpr char b_range_1[] = "b (1 << 25) - 4";
  constexpr char b_range_2[] = "b -(1 << 25) - 4";
  constexpr char b_range_3[] = "b -(1 << 25)";
  constexpr char crb_range_0[] = "cror -1, -1, -1";
  constexpr char crb_range_1[] = "cror 0, 0, 0";
  constexpr char crb_range_2[] = "cror 32, 32, 32";
  constexpr char crb_range_3[] = "cror 31, 31, 31";
  constexpr char off_range_0[] = "lwz r0, 1 << 15(r3)";
  constexpr char off_range_1[] = "lwz r0, (1 << 15) - 1(r3)";
  constexpr char off_range_2[] = "lwz r0, -(1 << 15) - 1(r3)";
  constexpr char off_range_3[] = "lwz r0, -(1 << 15)(r3)";
  constexpr char psoff_range_0[] = "psq_l f0, 1 << 11(r3), 0, 0";
  constexpr char psoff_range_1[] = "psq_l f0, (1 << 11) - 1(r3), 0, 0";
  constexpr char psoff_range_2[] = "psq_l f0, -(1 << 11) - 1(r3), 0, 0";
  constexpr char psoff_range_3[] = "psq_l f0, -(1 << 11)(r3), 0, 0";
  constexpr char simm_range_0[] = "addi r0, r1, 0x8000";
  constexpr char simm_range_1[] = "addi r0, r1, 0x7fff";
  constexpr char simm_range_2[] = "addi r0, r1, -0x8001";
  constexpr char simm_range_3[] = "addi r0, r1, -0x8000";
  constexpr char uimm_range_0[] = "andi. r0, r1, 0x10000";
  constexpr char uimm_range_1[] = "andi. r0, r1, 0xffff";
  constexpr char uimm_range_2[] = "andi. r0, r1, -1";
  constexpr char uimm_range_3[] = "andi. r0, r1, 0";

  EXPECT_TRUE(IsFailure(Assemble(gpr_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(gpr_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(gpr_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(gpr_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(crf_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(crf_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(crf_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(crf_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bc_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(bc_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(bc_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(bc_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(b_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(b_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(b_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(b_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(crb_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(crb_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(crb_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(crb_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(off_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(off_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(off_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(off_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(psoff_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(psoff_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(psoff_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(psoff_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(psoff_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(psoff_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(psoff_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(psoff_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(simm_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(simm_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(simm_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(simm_range_3, 0)));
  EXPECT_TRUE(IsFailure(Assemble(uimm_range_0, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(uimm_range_1, 0)));
  EXPECT_TRUE(IsFailure(Assemble(uimm_range_2, 0)));
  EXPECT_TRUE(!IsFailure(Assemble(uimm_range_3, 0)));
}

TEST(Assembly, MalformedExpressions)
{
  constexpr char missing_arg[] = "add 0, 1";
  constexpr char missing_paren_0[] = ".4byte (1 + 2), ((3 * 6) + 7";
  constexpr char missing_paren_1[] = ".4byte (1 + 2), `(3 * 6) + 7";
  constexpr char mismatched_paren[] = ".4byte (1 + 2), (`3 * 6) + 7`";
  constexpr char wrong_arg_format[] = "lwz r3, 100, r4";
  constexpr char no_operator[] = "b . .";
  constexpr char no_operand[] = "b 4 + +";

  auto res = Assemble(missing_arg, 0);
  EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected ',' but found '<EOF>'")
      << GetFailure(res).message;
  res = Assemble(missing_paren_0, 0);
  EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected ')' but found '<EOF>'")
      << GetFailure(res).message;
  res = Assemble(missing_paren_1, 0);
  EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected '`' but found '<EOF>'")
      << GetFailure(res).message;
  res = Assemble(mismatched_paren, 0);
  EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected '`' but found ')'")
      << GetFailure(res).message;
  res = Assemble(wrong_arg_format, 0);
  EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected '(' but found ','")
      << GetFailure(res).message;
  res = Assemble(no_operator, 0);
  EXPECT_TRUE(IsFailure(res) &&
              GetFailure(res).message == "Unexpected token '.' where line should have ended")
      << GetFailure(res).message;
  res = Assemble(no_operand, 0);
  EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Unexpected token '+' in expression")
      << GetFailure(res).message;
}

// Modified listing of a subroutine, listing generated by IDA
// Expect bytes are based on disc contents
TEST(Assembly, RealAssembly)
{
  constexpr char real_assembly[] = ".locate 0x8046A690\n"
                                   ".defvar back_chain, -0x30\n"
                                   ".defvar var_28, -0x28\n"
                                   ".defvar pre_back_chain,  0\n"
                                   ".defvar sender_lr,  4\n"
                                   "stwu      r1, back_chain(r1)\n"
                                   "mfspr     r0, LR\n"
                                   "stw       r0, 0x30+sender_lr(r1)\n"
                                   "addi      r11, r1, 0x30+pre_back_chain\n"
                                   "bl        `0x802BCA84`\n"
                                   "li        r0, 0\n"
                                   "mr        r28, r7\n"
                                   "stw       r0, 0(r8)\n"
                                   "mr        r24, r3\n"
                                   "mr        r25, r4\n"
                                   "mr        r26, r5\n"
                                   "mr        r27, r6\n"
                                   "mr        r29, r8\n"
                                   "mr        r30, r9\n"
                                   "mr        r31, r10\n"
                                   "mr        r3, r28\n"
                                   "bl        `0x80468140`\n"
                                   "cmplwi    r3, 0x1A\n"
                                   "bge       loc_8046A6F0\n"
                                   "mulli     r0, r3, 0x14\n"
                                   "lis       r3, -0x7FA4\n"
                                   "addi      r3, r3, 0x870\n"
                                   "add       r3, r3, r0\n"
                                   "b         loc_8046A6F4\n"
                                   "loc_8046A6F0:\n"
                                   "li        r3, 0\n"
                                   "loc_8046A6F4:\n"
                                   "cmpwi     r3, 0\n"
                                   "beq       loc_8046A704\n"
                                   "lwz       r0, 0xC(r3)\n"
                                   "b         loc_8046A708\n"
                                   "loc_8046A704:\n"
                                   "li        r0, 0\n"
                                   "loc_8046A708:\n"
                                   "cmplw     r26, r0\n"
                                   "bge       loc_8046A7EC\n"
                                   "cmpwi     r26, 0\n"
                                   "bne       loc_8046A758\n"
                                   "mr        r12, r30\n"
                                   "mr        r3, r28\n"
                                   "mr        r4, r25\n"
                                   "addi      r5, r1, 0x30+var_28\n"
                                   "mtspr     CTR, r12\n"
                                   "bctrl\n"
                                   "cmpwi     r3, 0\n"
                                   "stw       r3, 0(r29)\n"
                                   "beq       loc_8046A744\n"
                                   "li        r3, 0\n"
                                   "b         loc_8046A7F0\n"
                                   "loc_8046A744:\n"
                                   "stw       r24, 0(r27)\n"
                                   "li        r0, 0\n"
                                   "li        r3, 0\n"
                                   "stw       r0, 0(r29)\n"
                                   "b         loc_8046A7F0\n"
                                   "loc_8046A758:\n"
                                   "cmplwi    r26, 1\n"
                                   "bne       loc_8046A7DC\n"
                                   "mr        r3, r28\n"
                                   "bl        `0x80468140`\n"
                                   "cmplwi    r3, 0x1A\n"
                                   "bge       loc_8046A784\n"
                                   "mulli     r0, r3, 0x14\n"
                                   "lis       r3, -0x7FA4\n"
                                   "addi      r3, r3, 0x870\n"
                                   "add       r3, r3, r0\n"
                                   "b         loc_8046A788\n"
                                   "loc_8046A784:\n"
                                   "li        r3, 0\n"
                                   "loc_8046A788:\n"
                                   "cmpwi     r3, 0\n"
                                   "beq       loc_8046A798\n"
                                   "lwz       r0, 8(r3)\n"
                                   "b         loc_8046A79C\n"
                                   "loc_8046A798:\n"
                                   "li        r0, 1\n"
                                   "loc_8046A79C:\n"
                                   "cmplwi    r0, 2\n"
                                   "bne       loc_8046A7DC\n"
                                   "mr        r12, r31\n"
                                   "mr        r3, r25\n"
                                   "mtspr     CTR, r12\n"
                                   "bctrl\n"
                                   "cmpwi     r3, 0\n"
                                   "stw       r3, 0(r29)\n"
                                   "beq       loc_8046A7C8\n"
                                   "li        r3, 0\n"
                                   "b         loc_8046A7F0\n"
                                   "loc_8046A7C8:\n"
                                   "stw       r24, 0(r27)\n"
                                   "li        r0, 0\n"
                                   "li        r3, 0\n"
                                   "stw       r0, 0(r29)\n"
                                   "b         loc_8046A7F0\n"
                                   "loc_8046A7DC:\n"
                                   "li        r0, -0x16\n"
                                   "li        r3, 0\n"
                                   "stw       r0, 0(r29)\n"
                                   "b         loc_8046A7F0\n"
                                   "loc_8046A7EC:\n"
                                   "li        r3, 1\n"
                                   "loc_8046A7F0:\n"
                                   "addi      r11, r1, 0x30+pre_back_chain\n"
                                   "bl        `0x802BCAD0`\n"
                                   "lwz       r0, 0x30+sender_lr(r1)\n"
                                   "mtspr     LR, r0\n"
                                   "addi      r1, r1, 0x30\n"
                                   "blr\n"
                                   "loc_8046A804:\n";

  constexpr u8 real_expect[] = {
      0x94, 0x21, 0xff, 0xd0, 0x7c, 0x08, 0x02, 0xa6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00,
      0x30, 0x4b, 0xe5, 0x23, 0xe5, 0x38, 0x00, 0x00, 0x00, 0x7c, 0xfc, 0x3b, 0x78, 0x90, 0x08,
      0x00, 0x00, 0x7c, 0x78, 0x1b, 0x78, 0x7c, 0x99, 0x23, 0x78, 0x7c, 0xba, 0x2b, 0x78, 0x7c,
      0xdb, 0x33, 0x78, 0x7d, 0x1d, 0x43, 0x78, 0x7d, 0x3e, 0x4b, 0x78, 0x7d, 0x5f, 0x53, 0x78,
      0x7f, 0x83, 0xe3, 0x78, 0x4b, 0xff, 0xda, 0x71, 0x28, 0x03, 0x00, 0x1a, 0x40, 0x80, 0x00,
      0x18, 0x1c, 0x03, 0x00, 0x14, 0x3c, 0x60, 0x80, 0x5c, 0x38, 0x63, 0x08, 0x70, 0x7c, 0x63,
      0x02, 0x14, 0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0x00, 0x00, 0x2c, 0x03, 0x00, 0x00, 0x41,
      0x82, 0x00, 0x0c, 0x80, 0x03, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00,
      0x7c, 0x1a, 0x00, 0x40, 0x40, 0x80, 0x00, 0xe0, 0x2c, 0x1a, 0x00, 0x00, 0x40, 0x82, 0x00,
      0x44, 0x7f, 0xcc, 0xf3, 0x78, 0x7f, 0x83, 0xe3, 0x78, 0x7f, 0x24, 0xcb, 0x78, 0x38, 0xa1,
      0x00, 0x08, 0x7d, 0x89, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x21, 0x2c, 0x03, 0x00, 0x00, 0x90,
      0x7d, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0c, 0x38, 0x60, 0x00, 0x00, 0x48, 0x00, 0x00, 0xb0,
      0x93, 0x1b, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x90, 0x1d, 0x00,
      0x00, 0x48, 0x00, 0x00, 0x9c, 0x28, 0x1a, 0x00, 0x01, 0x40, 0x82, 0x00, 0x80, 0x7f, 0x83,
      0xe3, 0x78, 0x4b, 0xff, 0xd9, 0xdd, 0x28, 0x03, 0x00, 0x1a, 0x40, 0x80, 0x00, 0x18, 0x1c,
      0x03, 0x00, 0x14, 0x3c, 0x60, 0x80, 0x5c, 0x38, 0x63, 0x08, 0x70, 0x7c, 0x63, 0x02, 0x14,
      0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0x00, 0x00, 0x2c, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00,
      0x0c, 0x80, 0x03, 0x00, 0x08, 0x48, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x01, 0x28, 0x00,
      0x00, 0x02, 0x40, 0x82, 0x00, 0x3c, 0x7f, 0xec, 0xfb, 0x78, 0x7f, 0x23, 0xcb, 0x78, 0x7d,
      0x89, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x21, 0x2c, 0x03, 0x00, 0x00, 0x90, 0x7d, 0x00, 0x00,
      0x41, 0x82, 0x00, 0x0c, 0x38, 0x60, 0x00, 0x00, 0x48, 0x00, 0x00, 0x2c, 0x93, 0x1b, 0x00,
      0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x90, 0x1d, 0x00, 0x00, 0x48, 0x00,
      0x00, 0x18, 0x38, 0x00, 0xff, 0xea, 0x38, 0x60, 0x00, 0x00, 0x90, 0x1d, 0x00, 0x00, 0x48,
      0x00, 0x00, 0x08, 0x38, 0x60, 0x00, 0x01, 0x39, 0x61, 0x00, 0x30, 0x4b, 0xe5, 0x22, 0xdd,
      0x80, 0x01, 0x00, 0x34, 0x7c, 0x08, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x30, 0x4e, 0x80, 0x00,
      0x20,
  };

  auto res = Assemble(real_assembly, 0);
  ASSERT_TRUE(!IsFailure(res));
  auto&& code_blocks = GetT(res);
  ASSERT_EQ(code_blocks.size(), 1);
  ASSERT_EQ(code_blocks[0].instructions.size(), sizeof(real_expect));

  EXPECT_EQ(code_blocks[0].block_address, 0x8046a690);
  for (size_t i = 0; i < code_blocks[0].instructions.size(); i++)
  {
    EXPECT_EQ(code_blocks[0].instructions[i], real_expect[i]) << " -> i=" << i;
  }
}