IS_T32()
{
	printf("Thumb2\n");
	return;
}

UNDEFINED()
{
	printf("Undefined instruction\n");
	return;
}

UNALLOCATED_HINT()
{
	printf("Unallocated hint\n");
	return;
}

PERMA_UNDEFINED()
{
	printf("Undefined instruction\n");
	return;
}

ADC_reg_T1(Rdn,Rm)
{
	op_reg_reg("ADC",Rdn,Rm);
	return;
}

ADD_imm_T1(Rd,Rn,imm3)
{
	op_reg_reg_imm("ADD",Rd,Rn,imm3);
	return;
}

ADD_imm_T2(Rdn,imm8)
{
	op_reg_imm("ADD",Rdn,imm8);
	return;
}

ADD_reg_T1(Rd,Rn,Rm)
{
	op_reg_reg_reg("ADD",Rd,Rn,Rm);
	return;
}

ADD_reg_T2a(Rdn,Rm,DN)
{
	op_reg_reg("ADD",Rdn|(DN<<3),Rm);
	comment("ARMv6T2 or later");
	return;
}

ADD_reg_T2b(Rdn,Rm,DN)
{
	op_reg_reg("ADD",Rdn|(DN<<3),Rm);
	return;
}

ADD_sp_imm_T1(Rd,imm8)
{
	op_reg_reg_imm("ADD",Rd,13,imm8<<2);
	return;
}

ADD_sp_imm_T2(imm7)
{
	op_reg_reg_imm("ADD",13,13,imm7<<2);
	return;
}

ADD_sp_reg_T1(Rdm,DM)
{
	op_reg_reg_reg("ADD",Rdm|(DM<<3),13,Rdm|(DM<<3));
	return;
}

ADD_sp_reg_T2(Rm)
{
	op_reg_reg("ADD",13,Rm);
	return;
}

ADR_T1(Rd,imm8)
{
	op_reg_hex("ADR",Rd,(imm8<<2)+4,8);
	return;
}

AND_reg_T1(Rdn,Rm)
{
	op_reg_reg("AND",Rdn,Rm);
	return;
}

ASR_imm_T1(Rd,Rm,imm5)
{
	op_reg_reg_int("ASR",Rd,Rm,(imm5?imm5:32));
	return;
}

ASR_reg_T1(Rdn,Rm)
{
	op_reg_reg("ASR",Rdn,Rm);
	return;
}

B_T1(cond,imm8)
{
	op_cond_hex("B",cond,(sextend(imm8,8)<<1)+4,8);
	return;
}

B_T2(imm11)
{
	op_hex("B",(sextend(imm11,11)<<1)+4,8);
	return;
}

BIC_reg_T1(Rdn,Rm)
{
	op_reg_reg("BIC",Rdn,Rm);
	return;
}

BKPT_T1(imm8)
{
	op_hex("BKPT",imm8,2);
	comment("ARMv5 or later");
	return;
}

BLX_reg_T1(Rm,nonstandard)
{
	if(nonstandard)
		printf("Unpredictable instruction\n");
	else
	{
		op_reg("BLX",Rm);
		comment("ARMv5 or later");
	}
	return;
}

BX_T1(Rm,nonstandard)
{
	if(nonstandard)
		printf("Unpredictable instruction\n");
	else
	{
		op_reg("BX",Rm);
	}
	return;
}

CBNZ_CBZ_T1(op,Rn,imm5,i)
{
	op_reg_hex((op?"CBNZ":"CBZ"),Rn,(i<<7)|(imm5<<1),8);
	comment("ARMv6T2 or later");
	return;
}

CMN_reg_T1(Rn,Rm)
{
	op_reg_reg("CMN",Rn,Rm);
	return;
}

CMP_imm_T1(Rn,imm8)
{
	op_reg_imm("CMP",Rn,imm8);
	return;
}

CMP_reg_T1(Rn,Rm)
{
	op_reg_reg("CMP",Rn,Rm);
	return;
}

CMP_reg_T2(Rn,N,Rm)
{
	if(((!N)&&(Rm<8))||((Rn|(N<<3))==15)||(Rm==15))
		printf("Unpredictable instruction\n");
	else
	{
		op_reg_reg("CMP",Rn|(N<<3),Rm);
	}
	return;
}

EOR_reg_T1(Rdn,Rm)
{
	op_reg_reg("EOR",Rdn,Rm);
	return;
}

IT_T1(mask,firstcond)
{
	if((firstcond == 15) || ((firstcond==14) && ((mask!=1)||(mask!=2)||(mask!=4)||(mask!=8)))) /* ugly! */
		printf("Unpredictable instruction\n");
	else
	{
		char op[8];
		op[0] = 'I';
		op[1] = 'T';
		uint32_t bit = firstcond & 1;
		if(mask==8)
			op[2] = 0;
		else if((mask & 7)==4)
		{
			op[2] = ((((mask>>3)&1)==bit)?'T':'E');
			op[3] = 0;
		}
		else if((mask & 3)==2)
		{
			op[2] = ((((mask>>3)&1)==bit)?'T':'E');
			op[3] = ((((mask>>2)&1)==bit)?'T':'E');
			op[4] = 0;
		}
		else
		{
			op[2] = ((((mask>>3)&1)==bit)?'T':'E');
			op[3] = ((((mask>>2)&1)==bit)?'T':'E');
			op[4] = ((((mask>>1)&1)==bit)?'T':'E');
			op[5] = 0;
		}
		op_str(op,conditions[firstcond]);
	}
	return;
}

LDR_imm_T1(Rt,Rn,imm5)
{
	ldrstr_imm("LDR",Rt,Rn,imm5<<2);
	return;
}

LDR_imm_T2(Rt,imm8)
{
	ldrstr_imm("LDR",Rt,13,imm8<<2);
	return;
}

LDR_lit_T1(Rt,imm8)
{
	op_reg_hex("LDR",Rt,(imm8<<2)+4,8);
	return;
}

LDR_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("LDR",Rt,Rn,Rm);
	return;
}

LDRB_imm_T1(Rt,Rn,imm5)
{
	ldrstr_imm("LDRB",Rt,Rn,imm5);
	return;
}

LDRB_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("LDRB",Rt,Rn,Rm);
	return;
}

LDRH_imm_T1(Rt,Rn,imm5)
{
	ldrstr_imm("LDRH",Rt,Rn,imm5<<1);
	return;
}

LDRH_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("LDRH",Rt,Rn,Rm);
	return;
}

LDRSB_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("LDRSB",Rt,Rn,Rm);
	return;
}

LDRSH_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("LDRSH",Rt,Rn,Rm);
	return;
}

LSL_imm_T1(Rd,Rm,imm5)
{
	op_reg_reg_int("LSL",Rd,Rm,imm5);
	return;
}

LSL_reg_T1(Rdn,Rm)
{
	op_reg_reg("LSL",Rdn,Rm);
	return;
}

LSR_imm_T1(Rd,Rm,imm5)
{
	op_reg_reg_int("LSR",Rd,Rm,(imm5?imm5:32));
	return;
}

LSR_reg_T1(Rdn,Rm)
{
	op_reg_reg("LSR",Rdn,Rm);
	return;
}

MOV_imm_T1(Rd,imm8)
{
	op_reg_imm("MOV",Rd,imm8);
	return;
}

MOV_reg_T1a(Rd,Rm)
{
	op_reg_reg("MOV",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

MOV_reg_T1b(Rd,Rm,D)
{
	op_reg_reg("MOV",Rd|(D<<3),Rm);
	return;
}

MOV_reg_T2(Rd,Rm)
{
	op_reg_reg("MOVS",Rd,Rm);
	return;
}

MUL_T1(Rdm,Rn)
{
	op_reg_reg("MUL",Rdm,Rn);
	return;
}

MVN_reg_T1(Rd,Rm)
{
	op_reg_reg("MVN",Rd,Rm);
	return;
}

NOP_T1()
{
	do_op("NOP");
	comment("ARMv6T2 or later");
	return;
}

ORR_reg_T1(Rdn,Rm)
{
	op_reg_reg("ORR",Rdn,Rm);
	return;
}

POP_T1(reglist,P)
{
	op_reglist("POP",reglist|(P<<15));
	return;
}

PUSH_T1(reglist,M)
{
	op_reglist("PUSH",reglist|(M<<14));
	return;
}

REV_T1(Rd,Rm)
{
	op_reg_reg("REV",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

REV16_T1(Rd,Rm)
{
	op_reg_reg("REV16",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

REVSH_T1(Rd,Rm)
{
	op_reg_reg("REVSH",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

ROR_reg_T1(Rdn,Rm)
{
	op_reg_reg("ROR",Rdn,Rm);
	return;
}

RSB_imm_T1(Rd,Rn)
{
	op_reg_reg_imm("RSB",Rd,Rn,0);
	return;
}

SBC_reg_T1(Rdn,Rm)
{
	op_reg_reg("SBC",Rdn,Rm);
	return;
}

SETEND_T1(E,nonstandard)
{
	if(nonstandard)
		printf("Unpredictable instruction\n");
	else
	{
		op_str("SETEND",(E?"BE":"LE"));
		comment("ARMv6 or later");
	}
	return;
}

SEV_T1()
{
	do_op("SEV");
	comment("ARMv7 or later");
	return;
}

STR_imm_T1(Rt,Rn,imm5)
{
	ldrstr_imm("STR",Rt,Rn,imm5<<2);
	return;
}

STR_imm_T2(Rt,imm8)
{
	ldrstr_imm("STR",Rt,13,imm8<<2);
	return;
}

STR_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("STR",Rt,Rn,Rm);
	return;
}

STRB_imm_T1(Rt,Rn,imm5)
{
	ldrstr_imm("STRB",Rt,Rn,imm5);
	return;
}

STRB_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("STRB",Rt,Rn,Rm);
	return;
}

STRH_imm_T1(Rt,Rn,imm5)
{
	ldrstr_imm("STRH",Rt,Rn,imm5<<1);
	return;
}

STRH_reg_T1(Rt,Rn,Rm)
{
	ldrstr_reg("STRH",Rt,Rn,Rm);
	return;
}

SUB_imm_T1(Rd,Rn,imm3)
{
	op_reg_reg_imm("SUB",Rd,Rn,imm3);
	return;
}

SUB_imm_T2(Rdn,imm8)
{
	op_reg_imm("SUB",Rdn,imm8);
	return;
}

SUB_reg_T1(Rd,Rn,Rm)
{
	op_reg_reg_reg("SUB",Rd,Rn,Rm);
	return;
}

SUB_sp_imm_T1(imm7)
{
	op_reg_reg_imm("SUB",13,13,imm7<<2);
	return;
}

SVC_T1(imm8)
{
	op_hex("SVC",imm8,2);
	return;
}

SXTB_T1(Rd,Rm)
{
	op_reg_reg("SXTB",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

SXTH_T1(Rd,Rm)
{
	op_reg_reg("SXTH",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

TST_reg_T1(Rn,Rm)
{
	op_reg_reg("TST",Rn,Rm);
	return;
}

UDF_T1(imm8)
{
	op_hex("UDF",imm8,2);
	comment("Undefined instruction");
	return;
}

UXTB_T1(Rd,Rm)
{
	op_reg_reg("UXTB",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

UXTH_T1(Rd,Rm)
{
	op_reg_reg("UXTH",Rd,Rm);
	comment("ARMv6 or later");
	return;
}

WFE_T1()
{
	do_op("WFE");
	comment("ARMv7 or later");
	return;
}

WFI_T1()
{
	do_op("WFI");
	comment("ARMv7 or later");
	return;
}

YIELD_T1()
{
	do_op("YIELD");
	comment("ARMv7 or later");
	return;
}

CPS_T1(im,A,I,F,nonstandard)
{
	if(nonstandard)
		printf("Unpredictable instruction\n");
	else
	{
		char str[4];
		char *s = str;
		if(A)
			*s++ = 'a';
		if(I)
			*s++ = 'i';
		if(F)
			*s++ = 'f';
		*s = 0;
		op_str((im?"CPSID":"CPSIE"),str);
		comment("ARMv6 or later");
	}
	return;
}

LDMIA_T1(Rn,reglist)
{
	op_reg_reglist("LDMIA",Rn,!(reglist&(1<<Rn)),reglist);
	return;
}

STMIA_T1(Rn,reglist)
{
	op_reg_reglist("STMIA",Rn,true,reglist);
	return;
}
