REGISTERS

	r0  GPR RET0;
	r1  GPR RET1;
	r2  GPR;
	r3  GPR;
	r4  GPR;
	r5  GPR;
	r6  GPR;
	r7  GPR;
	r8  GPR;
	r9  GPR;
	r10 GPR;
	r11 GPR;

	cc  CC;

DECLARATIONS

	address   fragment;
	aluparam  fragment;
	reg       allocates(GPR);
	tristate  allocates(CC);

PATTERNS

/* Special */

	reg;

	reg = REG4;

	PAIR(BLOCK4, BLOCK4);


/* Miscellaneous special things */

	PUSH4(in:reg)
		emit "push %in"
		cost 4;

	reg = POP4
		emit "pop %reg"
		cost 4;

	RET
		emit "ret"
		cost 4;

	SETRET4(in:reg)
		emit "mov r0, %in"
		cost 4;


/* Memory operations */

	STORE4(addr:address, value:reg)
		emit "str %value, %addr"
		cost 4;

	reg = LOAD4(addr:address)
		emit "ldr %reg, %addr"
		cost 4;

	reg = LOAD1(addr:address)
		emit "ldrb %reg, %addr"
		cost 4;

	reg = CIU14(LOAD1(addr:address))
		emit "ldrb %reg, %addr"
		cost 4;
	
	reg = CII14(CIU41(CIU14(LOAD1(addr:address))))
		emit "ldrsb %reg, %addr"
		cost 4;


/* Locals */

	reg = in:LOCAL4
		emit "add %reg, fp, #$in"
		cost 4;

	address = in:LOCAL4
		emit "[fp, #$in]";


/* Memory addressing modes */

	address = ADD4(addr:reg, offset:CONST4)
		emit "[%addr, #$offset]";

	address = addr:reg
		emit "[%addr]";


/* Branches */

	JUMP(addr:BLOCK4)
		emit "b $addr"
		cost 4;

	CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
		emit "beq $true"
		emit "b $false"
		cost 8;


/* Comparisons */

	tristate = COMPARES4(left:reg, right:aluparam)
		emit "cmp %left, %right"
		cost 4;

	reg = tristate
		emit "mov %reg, #0"
		emit "movlt %reg, #-1"
		emit "movgt %reg, #1"
		cost 12;


/* Conversions */

	reg = CII14(CIU41(value:reg))
		emit "sxtb %reg, %value"
		cost 4;

	reg = CIU41(in:reg)
		emit "and %reg, %in, #0xff"
		cost 4;


/* ALU operations */

	reg = ADD4(left:reg, right:aluparam)
		emit "add %reg, %left, %right"
		cost 4;

	reg = ADD4(left:aluparam, right:reg)
		emit "add %reg, %right, %left"
		cost 4;

	aluparam = value:CONST4
		emit "#$value";

	aluparam = reg;

	reg = value:aluparam
		emit "mov %reg, %value"
		cost 4;

	reg = value:LABEL4
		emit "adr %reg, $value"
		cost 4;

	reg = value:BLOCK4
		emit "adr %reg, $value"
		cost 4;

	reg = value:CONST4
		emit "ldr %reg, #$value"
		cost 4;