dolphin/Source/UnitTests/Common/AssemblerTest.cpp

2226 lines
125 KiB
C++

// 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;
}
}