/* Copyright (c) 2013-2024 Jeffrey Pfau
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef EMITTER_ARM_H
#define EMITTER_ARM_H

#include "emitter-inlines.h"

#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \
	EMITTER ## NAME

#define DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ALU) \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I)), \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I))

#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4) \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, EX2), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, EX3), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
	DECLARE_INSTRUCTION_ARM(EMITTER, EX4)

#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W) \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W)), \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W))

#define DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, NAME, P, U, W) \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \
	DECLARE_INSTRUCTION_ARM(EMITTER, ILL)

#define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, NAME, MODE, W) \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W)), \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W))

#define DECLARE_ARM_BRANCH_BLOCK(EMITTER, NAME) \
	DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))

// TODO: Support coprocessors
#define DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, NAME, P, U, N, W) \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)), \
	DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))

#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2, NAME3) \
	DO_8(DO_INTERLACE( \
		DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))), \
		DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME3)))))

#define DECLARE_ARM_SWI_BLOCK(EMITTER) \
	DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI))

#define DECLARE_ARM_EMITTER_BLOCK(EMITTER) \
	/* -00---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \
	/* -01---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \
	/* -02---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \
	/* -03---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \
	/* -04---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \
	/* -05---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \
	/* -06---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \
	/* -07---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \
	/* -08---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \
	/* -09---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \
	/* -0A---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \
	/* -0B---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \
	/* -0C---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \
	/* -0D---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \
	/* -0E---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \
	/* -0F---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \
	/* -10---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \
	/* -10---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \
	/* -10---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \
	/* -10---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -10---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -11---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \
	/* -12---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \
	/* -12---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, BX), \
	/* -12---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \
	/* -12---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \
	/* -12---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -12---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -13---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \
	/* -14---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \
	/* -14---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \
	/* -14---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \
	/* -14---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -14---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -15---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \
	/* -16---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \
	/* -16---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \
	/* -16---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -16---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
	/* -17---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \
	/* -18---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, ILL, STRHPU, ILL, ILL), \
	/* -19---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, ILL, LDRHPU, LDRSBPU, LDRSHPU), \
	/* -1A---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, ILL, STRHPUW, ILL, ILL), \
	/* -1B---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, ILL, LDRHPUW, LDRSBPUW, LDRSHPUW), \
	/* -1C---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, ILL, STRHIPU, ILL, ILL), \
	/* -1D---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, ILL, LDRHIPU, LDRSBIPU, LDRSHIPU), \
	/* -1E---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, ILL, STRHIPUW, ILL, ILL), \
	/* -1F---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, ILL, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \
	/* -20---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \
	/* -21---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \
	/* -22---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \
	/* -23---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \
	/* -24---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \
	/* -25---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \
	/* -26---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \
	/* -27---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \
	/* -28---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \
	/* -29---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \
	/* -2A---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \
	/* -2B---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \
	/* -2C---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \
	/* -2D---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \
	/* -2E---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \
	/* -2F---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \
	/* -30---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \
	/* -31---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \
	/* -32---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \
	/* -33---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \
	/* -34---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \
	/* -35---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \
	/* -36---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \
	/* -37---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \
	/* -38---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \
	/* -39---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \
	/* -3A---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \
	/* -3B---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \
	/* -3C---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \
	/* -3D---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \
	/* -3E---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \
	/* -3F---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \
	/* -40---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \
	/* -41---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \
	/* -42---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \
	/* -43---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \
	/* -44---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \
	/* -45---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \
	/* -46---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \
	/* -47---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \
	/* -48---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \
	/* -49---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \
	/* -4A---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \
	/* -4B---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \
	/* -4C---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \
	/* -4D---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \
	/* -4E---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \
	/* -4F---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \
	/* -50---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \
	/* -51---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \
	/* -52---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \
	/* -53---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \
	/* -54---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \
	/* -55---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \
	/* -56---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \
	/* -57---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \
	/* -58---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \
	/* -59---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \
	/* -5A---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \
	/* -5B---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \
	/* -5C---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \
	/* -5D---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \
	/* -5E---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \
	/* -5F---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \
	/* -60---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \
	/* -61---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \
	/* -62---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \
	/* -63---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \
	/* -64---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \
	/* -65---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \
	/* -66---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \
	/* -67---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \
	/* -68---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \
	/* -69---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \
	/* -6A---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \
	/* -6B---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \
	/* -6C---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \
	/* -6D---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \
	/* -6E---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \
	/* -6F---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \
	/* -70---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \
	/* -71---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \
	/* -72---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \
	/* -73---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \
	/* -74---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \
	/* -75---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \
	/* -76---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \
	/* -77---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \
	/* -78---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \
	/* -79---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \
	/* -7A---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \
	/* -7B---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \
	/* -7C---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \
	/* -7D---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \
	/* -7E---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \
	/* -7F---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \
	/* -80---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \
	/* -81---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \
	/* -82---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \
	/* -83---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \
	/* -84---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \
	/* -85---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \
	/* -86---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \
	/* -87---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \
	/* -88---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \
	/* -89---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \
	/* -8A---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \
	/* -8B---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \
	/* -8C---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \
	/* -8D---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \
	/* -8E---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \
	/* -8F---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \
	/* -90---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \
	/* -91---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \
	/* -92---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \
	/* -93---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \
	/* -94---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \
	/* -95---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \
	/* -96---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \
	/* -97---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \
	/* -98---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \
	/* -99---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \
	/* -9A---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \
	/* -9B---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \
	/* -9C---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \
	/* -9D---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \
	/* -9E---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \
	/* -9F---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \
	/* -AX---X- */ DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \
	/* -BX---X- */ DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \
	/* -C0---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \
	/* -C1---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \
	/* -C2---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \
	/* -C3---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \
	/* -C4---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \
	/* -C5---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \
	/* -C6---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \
	/* -C7---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \
	/* -C8---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \
	/* -C9---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \
	/* -CA---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \
	/* -CB---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \
	/* -CC---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \
	/* -CD---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \
	/* -CE---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \
	/* -CF---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \
	/* -D0---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \
	/* -D1---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \
	/* -D2---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \
	/* -D3---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \
	/* -D4---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \
	/* -D5---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \
	/* -D6---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
	/* -D7---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
	/* -D8---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \
	/* -D9---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \
	/* -DA---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \
	/* -DB---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \
	/* -DC---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \
	/* -DD---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \
	/* -DE---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
	/* -DF---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
	/* -EX---X- */ DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR, MRC), \
	/* -FX---X- */ DECLARE_ARM_SWI_BLOCK(EMITTER)

#endif
