REGISTERS r0 bytes4 int ret; r1 bytes4 int; r2 bytes4 int; r3 bytes4 int; r4 bytes4 int; r5 bytes4 int; r6 bytes4 int; r7 bytes4 int; r8 bytes4 int; r9 bytes4 int; r10 bytes4 int; r11 bytes4 int; s0 bytes4 float; s1 bytes4 float; s2 bytes4 float; s3 bytes4 float; s4 bytes4 float; s5 bytes4 float; s6 bytes4 float; s7 bytes4 float; s8 bytes4 float; s9 bytes4 float; cc cc; DECLARATIONS reg; cc; address fragment; aluparam fragment; PATTERNS /* Special */ reg; PAIR(BLOCK4, BLOCK4); /* Miscellaneous special things */ PUSH4(in:reg) emit "push %in" cost 4; reg = POP4 with int reg emit "pop %reg" cost 4; RET emit "ret" cost 4; SETRET4(in:reg) with ret reg emit "mov r0, %in" cost 4; STACKADJUST4(delta:aluparam) emit "add sp, sp, %delta" cost 4; reg = in:REG cost 1; reg = NOP(in:reg) cost 1; /* Memory operations */ STORE4(addr:address, value:reg) with int value emit "str %value, %addr" cost 4; STORE1(addr:address, value:reg) with int value emit "strb %value, %addr" cost 4; reg = LOAD4(addr:address) with int reg emit "ldr %reg, %addr" cost 4; reg = LOAD1(addr:address) with int reg emit "ldrb %reg, %addr" cost 4; reg = CIU14(LOAD1(addr:address)) with int reg emit "ldrb %reg, %addr" cost 4; reg = CII14(CIU41(CIU14(LOAD1(addr:address)))) with int reg emit "ldrsb %reg, %addr" cost 4; /* Locals */ reg = in:LOCAL4 with int reg emit "add %reg, fp, #$in" cost 4; address = in:LOCAL4 emit "[fp, #$in]"; /* Memory addressing modes */ address = ADD4(addr:reg, offset:CONST4) with int addr emit "[%addr, #$offset]"; address = ADD4(addr1:reg, addr2:reg) with int addr1, int addr2 emit "[%addr1, %addr2]"; address = addr:reg with int addr emit "[%addr]"; /* Branches */ JUMP(addr:BLOCK4) emit "b $addr" cost 4; CJUMPEQ(value:cc, PAIR(true:BLOCK4, false:BLOCK4)) emit "beq $true" emit "b $false" cost 8; CJUMPLE(value:cc, PAIR(true:BLOCK4, false:BLOCK4)) emit "ble $true" emit "b $false" cost 8; CJUMPLT(value:cc, PAIR(true:BLOCK4, false:BLOCK4)) emit "blt $true" emit "b $false" cost 8; CALL(dest:LABEL4) emit "bl $dest" cost 4; /* Comparisons */ cc = COMPARES4(left:reg, right:aluparam) with cc cc emit "cmp %left, %right" cost 4; cc = COMPARES4(COMPARES4(left:reg, right:aluparam), CONST4) with cc cc emit "cmp %left, %right" cost 4; reg = cc with int reg emit "mov %reg, #0" emit "movlt %reg, #-1" emit "movgt %reg, #1" cost 12; /* Conversions */ reg = CII14(CIU41(value:reg)) with int reg emit "sxtb %reg, %value" cost 4; reg = CIU41(in:reg) with int reg emit "and %reg, %in, #0xff" cost 4; /* ALU operations */ reg = ADD4(left:reg, right:aluparam) with int reg emit "add %reg, %left, %right" cost 4; reg = ADD4(left:aluparam, right:reg) with int reg emit "add %reg, %right, %left" cost 4; reg = MOD4(left:reg, right:reg) with int reg emit "udiv %reg, %left, %right" emit "mls %reg, %reg, %right, %left" cost 8; reg = DIV4(left:reg, right:aluparam) with int reg emit "div %reg, %left, %right" cost 4; aluparam = value:CONST4 emit "#$value"; aluparam = value:reg emit "%value"; reg = value:aluparam with int reg emit "mov %reg, %value" cost 4; reg = value:LABEL4 with int reg emit "adr %reg, $value" cost 4; reg = value:BLOCK4 with int reg emit "adr %reg, $value" cost 4; reg = value:CONST4 with int reg emit "ldr %reg, address-containing-$value" cost 8; reg = value:CONSTF4 with int reg emit "vldr %reg, address-containing-$value" cost 8; /* FPU operations */ reg = ADDF4(left:reg, right:reg) with int reg emit "fadds %reg, %left, %right" cost 4;