From 00e94d3630b1f79dd41df8bd2f983e171a4e7b70 Mon Sep 17 00:00:00 2001 From: vyuuui Date: Fri, 27 Jan 2023 04:37:39 -0800 Subject: [PATCH] Added tests --- Source/UnitTests/Common/AssemblerTest.cpp | 2225 +++++++++++++++++++++ Source/UnitTests/Common/CMakeLists.txt | 1 + 2 files changed, 2226 insertions(+) create mode 100644 Source/UnitTests/Common/AssemblerTest.cpp diff --git a/Source/UnitTests/Common/AssemblerTest.cpp b/Source/UnitTests/Common/AssemblerTest.cpp new file mode 100644 index 0000000000..965c645cd5 --- /dev/null +++ b/Source/UnitTests/Common/AssemblerTest.cpp @@ -0,0 +1,2225 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include +#include + +#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 ''") + << GetFailure(res).message; + res = Assemble(missing_paren_0, 0); + EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected ')' but found ''") + << GetFailure(res).message; + res = Assemble(missing_paren_1, 0); + EXPECT_TRUE(IsFailure(res) && GetFailure(res).message == "Expected '`' but found ''") + << 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; + } +} diff --git a/Source/UnitTests/Common/CMakeLists.txt b/Source/UnitTests/Common/CMakeLists.txt index a4c9a67ade..7cbee2a3f3 100644 --- a/Source/UnitTests/Common/CMakeLists.txt +++ b/Source/UnitTests/Common/CMakeLists.txt @@ -1,3 +1,4 @@ +add_dolphin_test(AssemblerTest AssemblerTest.cpp) add_dolphin_test(BitFieldTest BitFieldTest.cpp) add_dolphin_test(BitSetTest BitSetTest.cpp) add_dolphin_test(BitUtilsTest BitUtilsTest.cpp)