ack/mach/arm/ncg/table

2360 lines
60 KiB
Plaintext

/****************************************************************************
* ACK backend for Acorn Risc Machine *
* First version: A.N.Other, Vrije Universiteit, Amsterdam *
* Completed by: Albert Koelmans, University of Newcastle *
* Register variables by Jonathan Hardwick *
* With help from: Andy Michael and Ceriel Jacobs *
****************************************************************************/
#define legal(a) ((a&~0xFF)==0||(a&~0x3FC)==0||(a&~0xFF0)==0||\
(a&~0x3FC0)==0||(a&~0xFF00)==0||(a&~0x3FC00)==0||\
(a&~0xFF000)==0||(a&~0x3FC000)==0||(a&~0xFF0000)==0||\
(a&~0x3FC0000)==0||(a&~0xFF00000)==0||(a&~0x3FC00000)==0||\
(a&~0xFF000000)==0||(a&~0xFC000003)==0||(a&~0xF000000F)==0||\
(a&~0xC000003F)==0||(~a&~0xFF)==0)
#define neglegal(a) (((0-a)&~0xFF)==0||((0-a)&~0x3FC)==0||((0-a)&~0xFF0)==0||\
((0-a)&~0x3FC0)==0||((0-a)&~0xFF00)==0||((0-a)&~0x3FC00)==0||\
((0-a)&~0xFF000)==0||((0-a)&~0x3FC000)==0||((0-a)&~0xFF0000)==0||\
((0-a)&~0x3FC0000)==0||((0-a)&~0xFF00000)==0||((0-a)&~0x3FC00000)==0||\
((0-a)&~0xFF000000)==0||((0-a)&~0xFC000003)==0||((0-a)&~0xF000000F)==0||\
((0-a)&~0xC000003F)==0||(~(0-a)&~0xFF)==0)
#define illegal(a) !legal(a)
#define minlegal(a) (a < 0) && neglegal(a)
#define minillegal(a) (a < 0) && !neglegal(a)
EM_WSIZE=4
EM_PSIZE=4
EM_BSIZE=8
PROPERTIES
GENREG /* All 16 user registers */
REG /* Allocatable registers */
PCPSR /* PSW and PC */
SREG
STACKPOINTER
LOCALBASE
LINKREGISTER
REGISTERS
R0,R1,R2,R3,R8,R9,R10 :GENREG, REG .
R4,R5,R6,R7 :GENREG regvar(reg_any).
R11 :GENREG, SREG .
SP("R12") :STACKPOINTER .
LB("R13") :LOCALBASE .
LR("R14") :LINKREGISTER .
PC("R15") :PCPSR .
TOKENS
const4 = { INT num; } 4 cost(0,4) "#" num .
fitcon = { INT num; } 4 cost(0,4) "#" num .
lb_local = { INT ind; } 4 "[R13,#" ind "]" .
addr_local = { INT ind; } 4 .
naddr_local = { INT ind; } 4 .
absolute = { ADDR add; } 4 add .
addr_external = { ADDR add; } 4 add .
label = { ADDR add; } 4 add .
autoid = { STACKPOINTER reg; } 4 reg "<" .
regexp = { INT exp;} 4 exp .
register = { GENREG exp;} 4 exp .
imS = { GENREG reg; ADDR S; INT shift;} 4
reg "," S "#" shift .
regS = { GENREG reg; ADDR S; GENREG sreg;} 4
reg "," S " "sreg .
regind = { GENREG reg; } 4
"[" reg "]" .
REGrel = { REG reg; ADDR ind; } 4
"[" reg ",#" ind "]" .
regrel = { GENREG reg; ADDR ind; } 4
"[" reg ",#" ind "]" .
st_regrel = { STACKPOINTER reg; ADDR ind; } 4
"[" reg ",#" ind "]" .
lb_regrel = { LOCALBASE reg; ADDR ind; } 4
"[" reg ",#" ind "]" .
regregrel = { GENREG reg1; GENREG reg2; } 4
"[" reg1 "," reg2 "]" .
st_regregrel = { STACKPOINTER reg1; GENREG reg2; } 4
"[" reg1 "," reg2 "]" .
lb_regregrel = { LOCALBASE reg1; GENREG reg2; } 4
"[" reg1 "," reg2 "]" .
regminregrel = { GENREG reg1; GENREG reg2; } 4
"[" reg1 ",-" reg2 "]" .
regiSregrel = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
"[" reg1 "," reg2 "," S "#" shift "]" .
st_regiSregrel = { STACKPOINTER reg1; ADDR S; INT shift; GENREG reg2; } 4
"[" reg1 "," reg2 "," S "#" shift "]" .
regminiSregrel = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
"[" reg1 ",-" reg2 "," S "#" shift "]" .
regminrSregrel = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4
"[" reg1 ",-" reg2 "," S " " sreg "]" .
regrelpi = { GENREG reg; ADDR ind; } 4
"[" reg "],#" ind .
regconst = { GENREG reg; INT ind; } 4
reg ",#" ind .
regplusreg = {GENREG reg1; GENREG reg2;} 4
reg1 "," reg2 .
regplusiSreg = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4
reg1 "," reg2 "," S "#" shift .
regplusrSreg = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4
reg1 "," reg2 "," S "," sreg .
regminreg = {GENREG reg1; GENREG reg2;} 4
reg1 "," reg2 .
regminiSreg = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4
reg1 "," reg2 "," S "#" shift .
regminrSreg = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4
reg1 "," reg2 "," S "," sreg .
REGlist1 = {REG reg1; } 4
"{" reg1 "}" .
reglist1 = {GENREG reg1; } 4
"{" reg1 "}" .
lb_reglist1 = {LOCALBASE reg1; } 4
"{" reg1 "}" .
sp_reglist1 = {STACKPOINTER reg1; } 4
"{" reg1 "}" .
reglist2 = {GENREG reg1; GENREG reg2; } 8
"{" reg1 "," reg2 "}" .
lb_pc_reglist2 = {LOCALBASE reg1; PCPSR reg2; } 8
"{" reg1 "," reg2 "}" .
reglist3 = {GENREG reg1; GENREG reg2; GENREG reg3; } 12
"{" reg1 "," reg2 "," reg3 "}" .
reglist4 = {GENREG reg1; GENREG reg2; GENREG reg3; GENREG reg4; } 16
"{" reg1 "," reg2 "," reg3 "," reg4 "}" .
/* the next 5 are not currently used - perhaps later */
regrelwb = { GENREG reg; ADDR ind; } 4 "[" reg ",#" ind "]<" .
regregrelwb = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "," reg2 "]<" .
regiSregrelwb = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
"[" reg1 "," reg2 "," S "#" shift "]<" .
regrSregrelwb = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4
"[" reg1 "," reg2 "," S " " sreg "]<" .
regregrelpi = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "]," reg2 .
LOCAL = { INT ind;} 4 ">>> BUG IN LOCAL".
stack = { GENREG r;} 4 "R12<,{" r "}".
/* tokens to put shifts and rotates into opcodes */
reglslcon = {GENREG target; INT shift;} 4 target ",LSL#" shift.
reglsrcon = {GENREG target; INT shift;} 4 target ",LSR#" shift.
regasrcon = {GENREG target; INT shift;} 4 target ",ASR#" shift.
regrorcon = {GENREG target; INT shift;} 4 target ",ROR#" shift.
reglslreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",LSL " shift.
reglsrreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",LSR " shift.
regasrreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ASR " shift.
regrorreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ROR " shift.
regrorregr = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ROR " shift.
SETS
address = absolute + regind + regrel + regrelwb + regregrel +
st_regrel + st_regregrel + st_regiSregrel +
lb_regrel + lb_regregrel +
regiSregrel + regiSregrelwb + regrSregrelwb +
regminregrel + regminiSregrel + regminrSregrel +
regregrelwb + regrelpi + regregrelpi + lb_local .
REGcon = GENREG + imS + regS + fitcon .
reglist = reglist1 + reglist2 + reglist3 + reglist4 +
lb_reglist1 + sp_reglist1 + lb_pc_reglist2 +
regexp + REGlist1 .
constant = fitcon + const4 .
local = lb_local + LOCAL.
regshift = reglslreg + reglsrreg + regasrreg + regrorreg + regrorregr +
reglslcon + reglsrcon + regasrcon + regrorcon.
rhs = GENREG + constant + regshift + LOCAL.
mem4 = regregrel + regrel + lb_local.
extern = addr_external + absolute + label.
all_except_con = mem4 + extern + local.
any_data = all_except_con + rhs.
any_data_except_local = any_data - LOCAL.
posshifts = regplusiSreg+regplusrSreg.
negshifts = regminiSreg+regminrSreg.
shifts = posshifts+negshifts.
INSTRUCTIONS
BAL label cost(4,4) .
BAL_L "BAL.L" label cost(4,4) .
BAL_LEQ "BAL.L.EQ" label cost(4,4) .
BNV label cost(4,4) .
BNE label cost(4,4) .
BEQ label cost(4,4) .
BMI label cost(4,4) .
BGT label cost(4,4) .
BLT label cost(4,4) .
BLE label cost(4,4) .
BGE label cost(4,4) .
LDR REG+LOCALBASE+GENREG+address:wo, address:rw cost(4,4) .
LDR LOCAL+GENREG:rw,
mem4+absolute+addr_external:ro cost(4,4) .
STR GENREG+REG:ro, REGrel+address:rw cost(4,4) .
LDR_B "LDR.B" REG+GENREG:wo, address:rw cost(4,4) .
LDR_B LOCAL:rw, rhs+mem4:ro cost(4,4) .
STR_B "STR.B" GENREG+REG:ro, address:rw cost(4,4) .
LDMFD autoid:rw, reglist:wo cost(4,7) .
STMFD autoid:rw, reglist:ro cost(4,7) .
STMFD stack cost(4,4) .
LDMIA GENREG:rw, reglist:wo cost(4,7) .
ADC REG+GENREG:wo, REG+GENREG:ro, REGcon:ro cost(4,1) .
ADD GENREG+REG:wo, GENREG:ro, REGcon+const4:ro cost(4,1) .
ADD GENREG+STACKPOINTER:wo, GENREG+STACKPOINTER:ro,
STACKPOINTER+REGcon+const4:ro cost(4,1) .
ADD LOCAL+GENREG+REG:wo,
regconst+shifts+regminreg+regplusreg:ro cost(4,1) .
ADD LOCAL+GENREG:rw, LOCALBASE+GENREG+LOCAL:ro,
rhs:ro cost(4,1).
ADD_NE "ADD.NE" GENREG+REG:wo, GENREG:ro, REGcon+const4:ro cost(4,1) .
AND REG+GENREG:wo, GENREG:ro, GENREG+REGcon:ro cost(4,1) .
AND_S "AND.S" GENREG+REG:wo, GENREG:ro, REGcon:ro cost(4,1) .
BIC REG+GENREG:wo, GENREG:ro, REGcon:ro cost(4,1) .
CMN GENREG+REG:ro, REGcon:ro kills :cc cost(4,1) .
CMP REG+GENREG:ro, REGcon:ro kills :cc cost(4,1) .
EOR GENREG+REG:wo, GENREG:ro, GENREG+REGcon:ro cost(4,1) .
EOR_S "EOR.S" REG+GENREG:wo:cc, GENREG:ro, REGcon:ro cost(4,1) .
MOV REG:wo, REGcon+const4:ro cost(4,1) .
MOV REG:rw, LOCAL:ro cost(4,1).
MOV LOCALBASE+PCPSR+STACKPOINTER+GENREG:rw,
REGcon+address+LOCALBASE+PCPSR+
STACKPOINTER+GENREG+LOCAL:ro cost(4,1).
MOV LOCAL+GENREG:rw, GENREG+rhs+register+REG:ro cost(4,1).
MOV LOCALBASE+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_MI "MOV.MI" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_HI "MOV.HI" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
MOV_LS "MOV.LS" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_LT "MOV.LT" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
MOV_LE "MOV.LE" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_EQ "MOV.EQ" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
MOV_NE "MOV.NE" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_GE "MOV.GE" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_GT "MOV.GT" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
MOV_NV "MOV.NV" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
MOV_S "MOV.S" GENREG+REG:wo, REGcon+const4+regind:ro
kills :cc cost(4,1) .
MVN LOCAL+GENREG+REG:wo, REGcon:ro cost(4,1) .
ORR REG+GENREG:wo, GENREG:ro, GENREG+REGcon:ro cost(4,1) .
ORR REG+GENREG+LOCAL:wo, imS:ro cost(4,1) .
RSB REG+GENREG+LOCAL:rw, REG+GENREG+LOCAL:ro,
rhs:ro cost(4,1).
RSB GENREG+REG:wo, GENREG:ro, REGcon:ro cost(4,1) .
RSB_S "RSB.S" REG+GENREG:wo:cc, GENREG:ro, REGcon:ro cost(4,1) .
RSC GENREG+REG:wo, GENREG:ro, REGcon:ro cost(4,1) .
SBC REG+GENREG:wo, GENREG:ro, REGcon:ro cost(4,1) .
SUB LOCAL+GENREG:rw,
regconst+shifts+regplusreg+regminreg:ro cost(4,1).
SUB LOCAL:rw, LOCAL:ro, rhs:ro cost(4,1).
SUB LOCAL+REG+GENREG:wo, LOCALBASE+GENREG:ro,
constant+REGcon:ro cost(4,1) .
SUB_S "SUB.S" REG+GENREG:wo:cc, GENREG:ro, REGcon:ro cost(4,1) .
TEQ GENREG+REG:ro, REGcon:ro kills :cc cost(4,1) .
TST REG+GENREG:ro, REGcon:ro kills :cc cost(4,1) .
ADR REG+LINKREGISTER+GENREG:wo,
addr_external+label:ro cost(4,1) .
LABEL "" label kills :cc cost(4,1) .
/* Dummy instructions for ncgg procedures : lxx is logical operator, */
/* mxx is conditional move, bxx is conditional branch, rxx is arith- */
/* metical operator on register variable (LOCAL). */
lxx "lxx : bug in cg" REG:rw, REG:ro, rhs:ro cost(4,1).
mxx "mxx : bug in cg" REG:rw, rhs:ro cost(4,1).
bxx "bxx : bug in cg" addr_external cost(4,4).
rxx "rxx : bug in cg" LOCAL:rw, LOCAL:ro, rhs:ro cost(4,1).
rrx "rrx : bug in cg" LOCAL:rw, LOCAL:ro, LOCAL:ro cost(4,1).
MOVES
from GENREG+STACKPOINTER+LOCALBASE+PCPSR to
GENREG+STACKPOINTER+LOCALBASE+PCPSR
gen MOV %2, %1
from fitcon+GENREG+REG to LOCAL inreg(%ind)==reg_any
gen MOV %2, %1
from LOCAL inreg(%ind)==reg_any to REG+GENREG
gen MOV %2, %1
/* illegal immediate operands */
from const4 minlegal(%num+1) to GENREG+LOCAL
gen MVN %2, {fitcon, 0-%1.num-1}
from const4 (minlegal(%num)) to GENREG+LOCAL
gen MOV %2, {fitcon, 0-%1.num}
RSB %2, %2, {fitcon, 0}
from const4 to GENREG+LOCAL /* general case */
gen MOV %2, { fitcon, %1.num & 0xFF}
ADD %2, %2, { fitcon, %1.num & 0xFF00}
ADD %2, %2, { fitcon, %1.num & 0xFF0000}
ADD %2, %2, { fitcon, %1.num & 0xFF000000}
from regconst (%ind > 0) && legal(%ind) to LOCAL inreg(%ind)==reg_any
gen ADD %2, %1
from regconst minlegal(%ind) to LOCAL inreg(%ind)==reg_any
gen SUB %2, %1.reg, {fitcon, 0-%1.ind}
from lb_local legal(%ind) to GENREG
gen LDR %2, {lb_regrel, LB, %1.ind}
from lb_local to GENREG
gen move {const4, %1.ind}, R11
LDR %2, {lb_regregrel, LB, R11}
from GENREG to lb_local legal(%ind)
gen STR %1, {lb_regrel, LB, %2.ind}
from GENREG to lb_local
gen move {const4, %2.ind}, R11
STR %1, {lb_regregrel, LB, R11}
from GENREG to address
gen STR %1, %2
from address to GENREG+LOCALBASE
gen LDR %2, %1
from GENREG to autoid
gen STMFD %2, {reglist1, %1}
from autoid to GENREG
gen LDMFD %1, {reglist1, %2}
from REGcon to GENREG+LOCALBASE
gen MOV %2, %1
from addr_external to GENREG
gen ADR %2, %1
/* strictly speaking, the following move is impossible.
* what it really means is: move from reg to address!
*/
from GENREG to addr_external
gen ADR R11,%2
STR %1,{regind,R11}
TESTS
to test GENREG
gen CMP %1, {fitcon, 0}
STACKINGRULES
from LOCAL to STACK
gen STMFD {stack, regvar(%1.ind)}
from REG to STACK
gen STMFD {autoid, SP}, {REGlist1, %1}
from GENREG to STACK
gen STMFD {autoid, SP}, {reglist1, %1}
from LOCALBASE to STACK
gen STMFD {autoid, SP}, {lb_reglist1, %1}
from STACKPOINTER to STACK
gen STMFD {autoid, SP}, {sp_reglist1, %1}
from REGcon to STACK
gen move %1, R11
STMFD {autoid, SP}, {reglist1, R11}
from const4 to STACK
gen move %1, R11
STMFD {autoid, SP}, {reglist1, R11}
from addr_local legal(%ind) to STACK
gen ADD R11, LB, {fitcon, %1.ind}
STMFD {autoid, SP}, {reglist1, R11}
from addr_local to STACK
gen move {const4, %1.ind}, R11
ADD R11, LB, R11
STMFD {autoid, SP}, {reglist1, R11}
from naddr_local legal(%ind) to STACK
gen SUB R11, LB, {fitcon, %1.ind}
STMFD {autoid, SP}, {reglist1, R11}
from naddr_local to STACK
gen move {const4, %1.ind}, R11
SUB R11, LB, R11
STMFD {autoid, SP}, {reglist1, R11}
from addr_external to STACK
gen ADR R11, %1
STMFD {autoid, SP}, {reglist1, R11}
from regconst (%ind > 0) && legal(%ind) to STACK
gen ADD R11, %1.reg, {fitcon,%1.ind}
STMFD {autoid, SP}, {reglist1, R11}
from regconst to STACK
gen move {const4, %1.ind}, R11
ADD R11, R11, %1.reg
STMFD {autoid, SP}, {reglist1, R11}
from regplusreg to STACK
gen ADD R11, %1.reg1, %1.reg2
STMFD {autoid, SP}, {reglist1, R11}
from regminreg to STACK
gen SUB R11, %1.reg1, %1.reg2
STMFD {autoid, SP}, {reglist1, R11}
from regplusiSreg to STACK
gen ADD R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
STMFD {autoid, SP}, {reglist1, R11}
from regminiSreg to STACK
gen SUB R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
STMFD {autoid, SP}, {reglist1, R11}
from regplusrSreg to STACK
gen ADD R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
STMFD {autoid, SP}, {reglist1, R11}
from regminrSreg to STACK
gen SUB R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
STMFD {autoid, SP}, {reglist1, R11}
from address to STACK
gen move %1, R11
STMFD {autoid, SP}, {reglist1, R11}
COERCIONS
from LOCAL
uses GENREG
gen MOV %a, %1 yields %a
from lb_local legal(%ind)
uses GENREG
gen LDR %a, {lb_regrel, LB, %ind} yields %a
from lb_local
uses GENREG
gen move {const4, %ind}, R11
LDR %a, {lb_regregrel, LB, R11} yields %a
from const4 %num < 0
uses GENREG
gen move {const4, 0-%num}, %a
RSB %a, %a, {fitcon, 0} yields %a
from const4 illegal(%num)
uses GENREG
gen move %1, %a yields %a
from const4 yields {fitcon, %num}
from STACK
uses GENREG
gen LDMFD {autoid, SP}, {reglist1, %a} yields %a
from address
uses GENREG
gen move %1, %a yields %a
from REGcon
uses GENREG
gen move %1, %a yields %a
from addr_external
uses GENREG
gen move %1, %a
yields %a
from addr_local legal(%ind)
uses GENREG
gen ADD %a, LB, {fitcon, %ind} yields %a
from addr_local
uses GENREG
gen move {const4, %ind}, %a
ADD %a, LB, %a yields %a
from naddr_local legal(%ind)
uses GENREG
gen SUB %a, LB, {fitcon, %ind} yields %a
from naddr_local
uses GENREG
gen move {const4, %ind}, %a
SUB %a, LB, %a yields %a
from regconst (%ind > 0) && legal(%ind)
uses GENREG
gen ADD %a, %1 yields %a
from regconst minlegal(%ind)
uses GENREG
gen SUB %a, %reg, {fitcon, 0-%ind} yields %a
from regconst minillegal(%ind)
uses GENREG
gen move {const4, 0-%ind}, %a
SUB %a, %a, %reg yields %a
from regconst
uses GENREG
gen move {const4, %ind}, %a
ADD %a, %a, %reg yields %a
from regplusreg
uses GENREG
gen ADD %a, %reg1, %reg2
yields %a
from regminreg
uses GENREG
gen SUB %a, %reg1, %reg2
yields %a
from regplusiSreg
uses GENREG
gen ADD %a, %reg1, {imS, %reg2, %S, %shift}
yields %a
from regminiSreg
uses GENREG
gen SUB %a, %reg1, {imS, %reg2, %S, %shift}
yields %a
from regplusrSreg
uses GENREG
gen ADD %a, %reg1, {regS, %reg2, %S, %sreg}
yields %a
from regminrSreg
uses GENREG
gen SUB %a, %reg1, {regS, %reg2, %S, %sreg}
yields %a
PATTERNS
/************************************************************************
* *
* GROUP 0 : Register variables *
* *
************************************************************************/
/* Simple load and store */
pat lol inreg($1)==reg_any
yields {LOCAL, $1}
pat lil inreg($1)==reg_any
yields {regind, regvar($1)}
pat stl inreg($1)==reg_any
with exact const4
kills local %ind==$1
gen move %1, {LOCAL, $1}
with exact fitcon
kills local %ind==$1
gen MOV {LOCAL, $1}, %1
with rhs-constant
kills local %ind==$1
gen MOV {LOCAL, $1}, %1
with mem4+absolute
kills local %ind==$1
gen LDR {LOCAL, $1}, %1
with regminreg
kills local %ind == $1
gen SUB {LOCAL, $1}, %1
with regplusreg+posshifts
kills local %ind == $1
gen ADD {LOCAL, $1}, %1
with negshifts
kills local %ind == $1
gen SUB {LOCAL, $1}, %1
pat stl $1==1 && inreg($1)==reg_any
with rhs
kills local %ind==$1
gen LDR_B {LOCAL, $1}, %1
pat sil inreg($1)==reg_any
with GENREG
kills /*all_except_con*/ address
gen move %1, {regind, regvar($1)}
/* Increment, decrement, zero */
pat inl inreg($1)==reg_any
kills local %ind==$1
gen ADD {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
pat del inreg($1)==reg_any
kills local %ind==$1
gen SUB {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
pat zrl inreg($1)==reg_any
kills local %ind==$1
gen MOV {LOCAL, $1}, {fitcon, 0}
pat lol inc stl inreg($1)==reg_any && inreg($3)==reg_any
kills local %ind==$3
gen ADD {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
pat lol dec stl inreg($1)==reg_any && inreg($3)==reg_any
kills local %ind==$3
gen SUB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
pat lol ngi stl inreg($1)==reg_any && inreg($3)==reg_any
kills local %ind==$3
gen RSB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 0}
/* Procedure : load register, op xx, store register */
proc lol_op_stl example lol adi stl
with rhs
kills local %ind==$3
gen rxx* {LOCAL, $3}, {LOCAL, $1}, %1
pat lol adi stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
call lol_op_stl("ADD")
pat lol adu stl leaving lol $1 adi $2 stl $3
pat lol sbi stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
call lol_op_stl("RSB")
pat lol sbu stl leaving lol $1 sbi $2 stl $3
pat lol and stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
call lol_op_stl("AND")
pat lol ior stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
call lol_op_stl("ORR")
pat lol xor stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
call lol_op_stl("EOR")
/* Procedure : load register, load constant, op xx, store register */
proc lol_loc_op_stl example lol loc adi stl
kills local %ind==$4
gen rxx* {LOCAL, $4}, {LOCAL, $1}, {const4, $2}
pat lol loc adi stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
call lol_loc_op_stl("ADD")
pat lol loc adu stl leaving lol $1 loc $2 adi $3 stl $4
pat lol loc sbi stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
call lol_loc_op_stl("SUB")
pat lol loc sbu stl leaving lol $1 loc $2 sbi $3 stl $4
pat lol loc and stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
call lol_loc_op_stl("AND")
pat lol loc ior stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
call lol_loc_op_stl("ORR")
pat lol loc xor stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
call lol_loc_op_stl("EOR")
pat lol dup inreg($1)==reg_any && $2==4 leaving lol $1 lol $1
/* Procedure : load register, load register, op xx, store register */
proc lol_lol_op_stl example lol lol adi stl
kills local %ind==$4
gen rrx* {LOCAL, $4}, {LOCAL, $1}, {LOCAL, $2}
pat lol lol adi stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
call lol_lol_op_stl("ADD")
pat lol lol adu stl leaving lol $1 lol $2 adi $3 stl $4
pat lol lol sbi stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
call lol_lol_op_stl("SUB")
pat lol lol sbu stl leaving lol $1 lol $2 sbi $3 stl $4
pat lol lol and stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
call lol_lol_op_stl("AND")
pat lol lol ior stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
call lol_lol_op_stl("ORR")
pat lol lol xor stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
call lol_lol_op_stl("EOR")
/* Shifts */
pat lol loc sli stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {reglslcon, regvar($1), $2}
pat lol loc slu stl leaving lol $1 loc $2 sli $3 stl $4
pat lol loc sri stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {regasrcon, regvar($1), $2}
pat lol loc sru stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {reglsrcon, regvar($1), $2}
pat lol lol sli stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {reglslreg, regvar($1), regvar($2)}
pat lol lol slu stl leaving lol $1 lol $2 sli $3 stl $4
pat lol lol sri stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {regasrreg, regvar($1), regvar($2)}
pat lol lol sru stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {reglsrreg, regvar($1), regvar($2)}
/* Rotates */
pat lol loc ror stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {regrorcon, regvar($1), $2}
pat lol lol ror stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {regrorreg, regvar($1), regvar($2)}
pat lol loc rol stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
kills local %ind==$4
gen MOV {LOCAL, $4}, {regrorcon, regvar($1), 32-$2}
pat lol lol ror stl inreg($1)==reg_any && inreg($2)==reg_any &&
inreg($4)==reg_any && $3==4
kills local %ind==$4
gen RSB R11, {LOCAL, $2}, {fitcon, 32}
MOV {LOCAL, $4}, {regrorregr, regvar($1), R11}
/* code for *p++ and *p-- (integers) */
pat lol lol adp stl loi $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
kills GENREG
uses GENREG
gen LDR %a, {regrelpi, regvar($1), $5} yields %a
pat lol lol adp stl sti $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
with GENREG
kills GENREG
gen STR %1, {regrelpi, regvar($1), $5}
/* code for *p++ and *p-- (bytes)*/
pat lol lol adp stl loi $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
kills GENREG
uses GENREG
gen LDR_B %a, {regrelpi, regvar($1), $5} yields %a
pat lol lol adp stl sti $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
with GENREG
kills GENREG
gen STR_B %1, {regrelpi, regvar($1), $5}
/* code for *pp->p++ and *pp->p-- (integers) */
pat lil dup adp sil loi $1==$4 && $2==4 && $5==4 && inreg($1)==reg_any
kills GENREG
uses GENREG,GENREG
gen LDR %a, {regind, regvar($1)}
ADD %b, %a, {fitcon, $3}
STR %b, {regind, regvar($1)}
LDR %b, {regind, %a} yields %b
pat lil dup adp sil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_any
with GENREG
kills GENREG
uses GENREG,GENREG
gen LDR %a, {regind, regvar($1)}
ADD %b, %a, {fitcon, $3}
STR %b, {regind, regvar($1)}
STR %1, {regind, %a}
/* code for *pp->p++ and *pp->p-- (bytes) */
pat lil dup adp sil loi $1==$4 && $2==4 && $5==1 && inreg($1)==reg_any
kills GENREG
uses GENREG,GENREG
gen LDR %a, {regind, regvar($1)}
ADD %b, %a, {fitcon, $3}
STR %b, {regind, regvar($1)}
LDR_B %b, {regind, %a} yields %b
pat lil dup adp sil sti $1==$4 && $2==4 && $5==1 && inreg($1)==reg_any
with GENREG
kills GENREG
uses GENREG,GENREG
gen LDR %a, {regind, regvar($1)}
ADD %b, %a, {fitcon, $3}
STR %b, {regind, regvar($1)}
STR_B %1, {regind, %a}
/************************************************************************
* *
* GROUP I : Load Instructions *
* *
************************************************************************/
pat loc $1 < 0 yields {const4, $1}
pat loc legal($1) yields {fitcon, $1}
pat loc yields {const4, $1}
pat ldc leaving loc 18 trp
pat lol yields {lb_local, $1}
pat loe yields {absolute, $1}
pat lil leaving lol $1 loi 4
pat lof
with GENREG yields {regrel, %1, $1}
with exact addr_local yields {lb_local, %1.ind+$1}
with exact addr_external yields {absolute, %1.add+$1}
with exact regconst yields {regrel, %1.reg, $1+%1.ind}
pat lal $1 > 0 yields {addr_local, $1}
pat lal $1 < 0 yields {naddr_local, 0-$1}
pat lal $1 == 0 yields LB
pat lae yields {addr_external, $1}
pat lae loi lae sti $2==$4 leaving lae $1 lae $3 blm $2
pat lxl $1==0 yields LB
pat lxl $1==1 yields {lb_local,8}
pat lxl $1>1
uses GENREG={const4, $1}, GENREG=LB
gen LABEL {label, "1:"}
move {regrel, %b, 8}, %b
SUB_S %a, %a, {fitcon,1}
BNE {label,"1B"} yields %b
pat lxa $1==0 yields {addr_local,8}
pat lxa $1==1
uses GENREG={lb_local,8} yields {regconst,%a,8}
pat lxa $1>1
uses GENREG={const4, $1}, GENREG=LB
gen LABEL {label, "1:"}
move {regrel, %b, 8}, %b
SUB_S %a, %a, {fitcon,1}
BNE {label,"1B"} yields {regconst, %b, 8}
pat loi $1==1
with GENREG
uses GENREG
gen LDR_B %a, {regind, %1} yields %a
with exact naddr_local
uses GENREG
gen LDR_B %a, {lb_local, 0-%1.ind} yields %a
with exact addr_local
uses GENREG
gen LDR_B %a, {lb_local, %1.ind} yields %a
with exact addr_external
uses GENREG
gen LDR_B %a, {absolute, %1.add} yields %a
with exact regconst
uses GENREG
gen LDR_B %a, {regrel, %1.reg, %1.ind} yields %a
with exact regplusreg
uses GENREG
gen LDR_B %a, {regregrel, %1.reg1, %1.reg2} yields %a
with exact regminreg
uses GENREG
gen LDR_B %a, {regminregrel, %1.reg1, %1.reg2} yields %a
with exact regplusiSreg
uses GENREG
gen LDR_B %a, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2} yields %a
with exact regminiSreg
uses GENREG
gen LDR_B %a, {regminiSregrel,%1.reg1,%1.S,%1.shift,%1.reg2} yields %a
with exact regplusrSreg
uses GENREG,GENREG
gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
LDR_B %a, {regregrel, %1.reg1, %b} yields %a
with exact regminrSreg
uses GENREG
gen LDR_B %a, {regminrSregrel,%1.reg1,%1.S,%1.sreg,%1.reg2} yields %a
pat loi $1==2
with GENREG
uses GENREG, GENREG
gen LDR_B %a, {regind, %1}
LDR_B %b, {regrel, %1, 1}
ADD %a,%a,{imS,%b,"LSL",8} yields %a
pat loi $1==4
with GENREG yields {regind, %1}
with exact addr_local yields {lb_local, %1.ind}
with exact naddr_local yields {lb_local, 0-%1.ind}
with exact addr_external yields {absolute, %1.add}
with exact regconst yields {regrel, %1.reg, %1.ind}
with exact regplusreg yields {regregrel, %1.reg1, %1.reg2}
with exact regminreg yields {regminregrel, %1.reg1, %1.reg2}
with exact regplusiSreg yields {regiSregrel,%1.reg1,%1.S,
%1.shift,%1.reg2}
with exact regminiSreg yields {regminiSregrel,%1.reg1,%1.S,
%1.shift,%1.reg2}
with exact regplusrSreg
uses GENREG,GENREG
gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
LDR %a, {regregrel, %1.reg1, %b} yields %a
with exact regminrSreg yields {regminrSregrel,%1.reg1,
%1.S,%1.sreg,%1.reg2}
pat loi $1==8
with GENREG
uses GENREG, GENREG
gen LDMIA %1, {reglist2, %a, %b} yields %b %a
pat loi defined($1)
with GENREG STACK
uses GENREG = {const4, $1}
gen LABEL {label, "1:"}
SUB_S %a, %a, {fitcon, 4}
move {regregrel, %1, %a}, R11
STMFD {autoid, SP}, {reglist1, R11}
BGT {label, "1b"}
pat loi loc and $1==2 && $2>0 && $2<256 leaving loi 1 loc $2 and $3
pat loi loc loc cii $1==2 && $2==2 && $3==4
with GENREG
uses GENREG,GENREG
gen LDR_B %a, {regind, %1}
LDR_B %b, {regrel, %1, 1}
MOV %b, {imS, %b, "LSL", 24}
ORR %a, %a, {imS, %b, "ASR", 16} yields %a
pat los
with STACK
kills ALL
gen BAL_L {label, ".los"}
pat ldl yields {lb_local, $1+4}
{lb_local, $1}
pat lde yields {absolute, $1+4}
{absolute, $1}
pat ldf
with GENREG yields {regrel, %1, $1+4}
{regrel, %1, $1}
with exact addr_local yields {lb_local, %1.ind+$1+4}
{lb_local, %1.ind+$1}
with exact addr_external yields {absolute, %1.add+$1+4}
{absolute, %1.add+$1}
with exact regconst yields {regrel, %1.reg, $1+%1.ind+4}
{regrel, %1.reg, $1+%1.ind}
pat lpi yields {addr_external,$1}
/************************************************************************
* *
* GROUP II : Store Instructions *
* *
************************************************************************/
pat stl
with GENREG
kills address-(absolute+lb_local), lb_local %ind-4 < $1 && %ind+4 > $1
gen move %1, {lb_local, $1}
pat stl lol $1==$2 leaving dup 4 stl $1
pat ste
with GENREG
kills address
gen move %1, {absolute, $1}
pat ste loe $1==$2
leaving dup 4 ste $1
pat sil leaving lol $1 sti 4
pat stf
with GENREG GENREG
kills address
gen move %2, {regrel, %1, $1}
with addr_local GENREG
kills address
gen move %2, {lb_local, %1.ind + $1}
with addr_external GENREG
kills address
gen move %2, {absolute, %1.add + $1}
with regconst GENREG
kills address
gen move %2, {regrel, %1.reg, $1+%1.ind}
pat sti $1==1
with GENREG GENREG
kills address
gen STR_B %2, {regind, %1}
with addr_local GENREG
kills address
gen STR_B %2, {lb_local, %1.ind}
with addr_external GENREG
kills address
gen STR_B %2, {absolute, %1.add}
with regconst GENREG
kills address
gen STR_B %2, {regrel, %1.reg, %1.ind}
with regplusreg GENREG
kills address
gen STR_B %2, {regregrel, %1.reg1, %1.reg2}
with regminreg GENREG
kills address
gen STR_B %2, {regminregrel, %1.reg1, %1.reg2}
with regplusiSreg GENREG
kills address
gen STR_B %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
with regminiSreg GENREG
kills address
gen STR_B %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
with regplusrSreg GENREG
kills address
uses GENREG
gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
STR_B %2, {regregrel, %1.reg1, %a}
with regminrSreg GENREG
kills address
gen STR_B %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
pat sti $1==2
with GENREG GENREG
kills address
/*uses GENREG
gen move {imS, %2, "LSR", 8}, %a
SUB %2, %2, {imS, %a, "LSL", 8}
STR_B %2, {regind, %1}
STR_B %a, {regrel, %1, 1}
*/
gen STR_B %2, {regind, %1}
MOV %2, {imS, %2, "LSR", 8}
STR_B %2, {regrel, %1, 1}
/*with GENREG fitcon %2.num==0
kills address
gen STR_B %2, {regind, %1}
STR_B %2, {regrel, %1, 1}
*/
pat sti $1==4
with GENREG GENREG
kills address
gen move %2, {regind, %1}
with addr_local GENREG
kills address
gen move %2, {lb_local, %1.ind}
with addr_external GENREG
kills address
gen move %2, {absolute, %1.add}
with regconst GENREG
kills address
gen move %2, {regrel, %1.reg, %1.ind}
with regplusreg GENREG
kills address
gen move %2, {regregrel, %1.reg1, %1.reg2}
with regminreg GENREG
kills address
gen move %2, {regminregrel, %1.reg1, %1.reg2}
with regplusiSreg GENREG
kills address
gen move %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
with regminiSreg GENREG
kills address
gen move %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
with regplusrSreg GENREG
kills address
uses GENREG
gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
STR %2, {regregrel, %1.reg1, %a}
with regminrSreg GENREG
kills address
gen move %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
pat sti defined($1) && legal($1)
with GENREG STACK
kills address
uses GENREG={fitcon, $1}
gen LABEL {label, "1:"}
SUB_S %a, %a, {fitcon, 4}
move {st_regregrel, SP, %a}, R11
move R11, {regregrel, %1, %a}
BGT {label,"1B"}
ADD SP, SP, {fitcon, $1}
pat sti defined($1)
with GENREG STACK
kills address
uses GENREG={const4, $1}, GENREG
gen move %a, %b
LABEL {label, "1:"}
SUB_S %a, %a, {fitcon, 4}
move {st_regregrel, SP, %a}, R11
move R11, {regregrel, %1, %a}
BGT {label,"1B"}
ADD SP, SP, %b
pat sts
with STACK
kills ALL
gen BAL_L {label, ".sts"}
pat sdl
with GENREG GENREG
kills address-absolute
gen move %1, {lb_local,$1}
move %2, {lb_local,$1+4}
pat sde
with GENREG GENREG
kills address
gen move %1, {absolute, $1}
move %2, {absolute, $1+4}
pat sdf
with GENREG GENREG GENREG
kills address
gen move %2, {regrel, %1, $1}
move %3, {regrel, %1, $1+4}
/************************************************************************
* *
* GROUP III : Integer Arithmetic *
* *
************************************************************************/
pat adi $1==4
with GENREG constant yields {regconst, %1, %2.num}
with constant GENREG yields {regconst, %2, %1.num}
with GENREG GENREG yields {regplusreg, %1, %2}
with GENREG imS yields {regplusiSreg,%1, %2.S,
%2.shift, %2.reg}
with imS GENREG yields {regplusiSreg,%2, %1.S,
%1.shift, %1.reg}
with GENREG regS yields {regplusrSreg,%1, %2.S,
%2.sreg, %2.reg}
with regS GENREG yields {regplusrSreg,%2, %1.S,
%1.sreg, %1.reg}
with exact addr_local constant yields {addr_local, %1.ind+%2.num}
with exact constant addr_local yields {addr_local, %2.ind+%1.num}
with exact addr_external constant yields {addr_external, %1.add+%2.num}
with exact constant addr_external yields {addr_external, %2.add+%1.num}
pat sbi $1==4
with GENREG GENREG yields {regminreg, %2, %1}
with imS GENREG yields {regminiSreg,%2,%1.S,
%1.shift,%1.reg}
with regS GENREG yields {regminrSreg,%2,%1.S,
%1.sreg,%1.reg}
with GENREG fitcon
uses GENREG
gen RSB %a, %1, %2 yields %a
with fitcon GENREG
gen SUB %2, %2, %1 yields %2
with GENREG const4
uses GENREG
gen move %2, %a
RSB %1, %1, %a yields %1
with const4 GENREG
uses GENREG
gen move %1, %a
SUB %a, %2, %a yields %a
with GENREG REGcon
uses GENREG
gen RSB %a, %1, %2 yields %a
/*with constant GENREG yields {regconst, %2, 0-%1.num}*/
with exact constant addr_local yields {addr_local, %2.ind-%1.num}
pat loc mli $1<0 && $2==4 leaving loc 0-$1
mli 4
ngi 4
pat loc mli $1==2 && $2==4
with GENREG yields {imS, %1, "LSL", 1}
pat loc mli $1==4 && $2==4
with GENREG yields {imS, %1, "LSL", 2}
pat loc mli $1==8 && $2==4
with GENREG yields {imS, %1, "LSL", 3}
pat loc mli $1==16 && $2==4
with GENREG yields {imS, %1, "LSL", 4}
pat loc mli $1==32 && $2==4
with GENREG yields {imS, %1, "LSL", 5}
pat loc mli $1==3 && $2==4
with GENREG yields {regplusiSreg,%1,"LSL",1,%1}
pat loc mli $1==5 && $2==4
with GENREG yields {regplusiSreg,%1,"LSL",2,%1}
pat loc mli $1==6 && $2==4
with GENREG
uses GENREG
gen MOV %a, {imS,%1,"LSL",2}
ADD %a, %a, {imS,%1,"LSL",1} yields %a
pat loc mli $1==7 && $2==4
with GENREG
uses GENREG
gen RSB %a, %1, {imS, %1, "LSL", 3} yields %a
pat loc mli $1==9 && $2==4
with GENREG yields {regplusiSreg,%1,"LSL",3,%1}
pat loc mli $1==10 && $2==4
with GENREG
uses GENREG
gen MOV %a,{imS, %1, "LSL", 1}
ADD %a, %a, {imS, %1, "LSL", 3} yields %a
pat loc mli $1==12 && $2==4
with GENREG
uses GENREG
gen move {imS, %1, "LSL", 3}, %a yields {regplusiSreg,%a,"LSR",1,%a}
pat mli $1==4
with STACK
kills ALL
gen BAL_L {label, ".mli"} yields R0
pat loc dvi $1<0 && $2==4 leaving loc 0-$1
dvi 4
pat dvi $1==4
with STACK
kills ALL
gen BAL_L {label, ".dvi"} yields R3
pat rmi $1==4
with STACK
kills ALL
gen BAL_L {label, ".dvi"} yields R2
pat ngi $1==4
with GENREG
uses GENREG
gen RSB %a, %1, {fitcon, 0} yields %a
pat sli $1==4
with fitcon GENREG yields {imS, %2, "LSL", %1.num}
with GENREG GENREG yields {regS, %2, "LSL", %1}
pat loc sri $1==0 && $2==4
with address+REGcon yields %1
pat sri $1==4
with fitcon GENREG yields {imS, %2, "ASR", %1.num}
with GENREG GENREG yields {regS, %2, "ASR", %1}
/************************************************************************
* *
* GROUP IV : Unsigned Arithmetic *
* *
************************************************************************/
pat adu leaving adi $1
pat sbu leaving sbi $1
pat loc mlu $1<11 && $1>0 && $2==4 leaving loc $1
mli 4
pat mlu $1==4
with STACK
kills ALL
gen BAL_L {label, ".mlu"} yields R0
pat loc dvu $1<33 && $1>0 && $2==4 leaving loc $1
dvi 4
pat dvu $1==4
with STACK
kills ALL
gen BAL_L {label, ".dvu"} yields R3
pat rmu $1==4
with STACK
kills ALL
gen BAL_L {label, ".dvu"} yields R2
pat slu $1==4
with GENREG GENREG yields {regS, %2, "LSL", %1}
with const4+fitcon GENREG yields {imS, %2, "LSL", %1.num}
pat sru $1==4
with GENREG GENREG yields {regS, %2, "LSR", %1}
with const4+fitcon GENREG yields {imS, %2, "LSR", %1.num}
/************************************************************************
* *
* GROUP V : Floating Point Arithmetic *
* *
************************************************************************/
pat adf $1==4 leaving cal ".adf4" asp 4
pat adf $1==8 leaving cal ".adf8" asp 8
pat sbf $1==4 leaving cal ".sbf4" asp 4
pat sbf $1==8 leaving cal ".sbf8" asp 8
pat mlf $1==4 leaving cal ".mlf4" asp 4
pat mlf $1==8 leaving cal ".mlf8" asp 8
pat dvf $1==4 leaving cal ".dvf4" asp 4
pat dvf $1==8 leaving cal ".dvf8" asp 8
pat ngf $1==4 leaving cal ".ngf4"
pat ngf $1==8 leaving cal ".ngf8"
pat fif $1==4 leaving lor 1 cal ".fif4" asp 4
pat fif $1==8 leaving lor 1 cal ".fif8" asp 4
pat fef $1==4 leaving lor 1 adp 0-4 cal ".fef4"
pat fef $1==8 leaving lor 1 adp 0-4 cal ".fef8"
/************************************************************************
* *
* GROUP VI : Pointer Arithmetic *
* *
************************************************************************/
pat adp
with GENREG yields {regconst, %1, $1}
with exact addr_local yields {addr_local, %1.ind+$1}
with exact addr_external yields {addr_external, %1.add+$1}
with exact regconst yields {regconst, %1.reg, %1.ind+$1}
pat ads $1==4 leaving adi 4
pat sbs $1==4 leaving sbi 4
/************************************************************************
* *
* GROUP VII : Increment/Decrement/Zero *
* *
************************************************************************/
pat inc
with GENREG yields {regconst, %1, 1}
with exact regconst yields {regconst, %1.reg, %1.ind+1}
pat inl
kills address-absolute
uses GENREG={lb_local,$1}
gen ADD %a,%a,{fitcon,1}
move %a,{lb_local,$1}
pat ine
kills address
uses GENREG={absolute,$1}
gen ADD %a,%a,{fitcon,1}
move %a,{absolute,$1}
pat dec
with GENREG yields {regconst, %1, 0-1}
/*gen SUB %a, %1, {fitcon, 1}*/
with exact regconst yields {regconst, %1.reg, %1.ind-1}
pat del
kills address-absolute
uses GENREG={lb_local,$1}
gen SUB %a,%a,{fitcon,1}
move %a,{lb_local,$1}
pat dee
kills address
uses GENREG={absolute,$1}
gen SUB %a,%a,{fitcon,1}
move %a,{absolute,$1}
pat zrl
kills address-absolute
uses GENREG={fitcon,0}
gen move %a,{lb_local,$1}
pat zre
kills address
uses GENREG={fitcon,0}
gen move %a,{absolute,$1}
pat zrf leaving zer $1
pat zer $1==4 yields {fitcon,0}
pat zer $1==8 yields {fitcon,0} {fitcon,0}
pat zer $1==12 yields {fitcon,0} {fitcon,0} {fitcon,0}
pat zer defined($1)
with STACK
kills ALL
uses GENREG={fitcon,0},GENREG={const4,$1}
gen LABEL {label, "1:"}
STMFD {autoid, SP}, {reglist1, %a}
SUB_S %b,%b,{fitcon,4}
BNE {label,"1B"}
/************************************************************************
* *
* GROUP VIII : Convert *
* *
************************************************************************/
/* sign extension short -> integer */
pat loc loc cii $1==2 && $2==4
with GENREG
uses GENREG
gen MOV %a, {imS, %1, "LSL", 16}
MOV %a, {imS, %a, "ASR", 16} yields %a
/* sign extension byte -> integer */
pat loc loc cii $1==1 && $2==4
with GENREG
uses GENREG
gen MOV %a, {imS, %1, "LSL", 24}
MOV %a, {imS, %a, "ASR", 24} yields %a
pat loc loc cii ($1 > 2)
pat cui
with address +REGcon address + REGcon
pat loc loc cif $1==4 && $2==4 leaving loc 4 cal ".cif4" asp 4
pat loc loc cif $1==4 && $2==8 leaving loc 4 cal ".cif8"
pat loc loc cuf $1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 4
pat loc loc cuf $1==4 && $2==8 leaving loc 4 cal ".cuf8"
pat loc loc cfi leaving loc $1 loc $2 cal ".cfi" asp 8+($1-4)
pat loc loc cfu leaving loc $1 loc $2 cal ".cfu" asp 8+($1-4)
pat loc loc cff $1==8 && $2==4 leaving cal ".cff4" asp 4
/* this one expects a 4 byte hole on the stack */
pat loc loc cff $1==4 && $2==8 leaving dup 4 cal ".cff8"
pat ciu
with address +REGcon address + REGcon
pat cuu
with address +REGcon address + REGcon
/************************************************************************
* *
* GROUP IX : Logical *
* *
************************************************************************/
pat and $1==4
with REGcon GENREG
uses GENREG
gen AND %a, %2, %1 yields %a
with GENREG REGcon
uses GENREG
gen AND %a, %1, %2 yields %a
pat ior $1==4
with REGcon GENREG
uses GENREG
gen ORR %a, %2, %1 yields %a
with GENREG REGcon
uses GENREG
gen ORR %a, %1, %2 yields %a
pat xor $1==4
with REGcon GENREG
uses GENREG
gen EOR %a, %2, %1 yields %a
with GENREG REGcon
uses GENREG
gen EOR %a, %1, %2 yields %a
pat com $1==4
with REGcon
uses GENREG
gen MVN %a,%1 yields %a
pat ror $1==4
with constant GENREG yields {imS, %2, "ROR", %1.num}
with GENREG GENREG yields {regS, %2, "ROR", %1}
pat rol $1==4
with constant GENREG yields {imS, %2, "ROR", 32-%1.num}
with GENREG GENREG
uses GENREG
gen RSB %a, %1, {fitcon,32} yields {regS, %2, "ROR", %a}
pat and $1>4
with STACK
kills ALL
uses GENREG,GENREG,GENREG,GENREG
gen move {const4,$1}, %b
move SP, %a
ADD SP, SP, %b
LABEL {label, "1:"}
SUB_S %b, %b, {fitcon, 4}
move {st_regregrel, SP,%b}, %c
move {regregrel, %a, %b}, %d
AND %c, %c, %d
move %c, {st_regregrel, SP, %b}
BNE {label, "1B"}
pat ior $1>4
with STACK
kills ALL
uses GENREG,GENREG,GENREG,GENREG
gen move {const4,$1}, %b
move SP, %a
ADD SP, SP, %b
LABEL {label, "1:"}
SUB_S %b, %b, {fitcon, 4}
move {st_regregrel, SP,%b}, %c
move {regregrel, %a, %b}, %d
ORR %c, %c, %d
move %c, {st_regregrel, SP, %b}
BNE {label, "1B"}
pat ior !defined($1)
with STACK
kills ALL
uses GENREG,GENREG,GENREG,GENREG
gen LDMFD {autoid, SP}, {reglist1, %b}
move SP, %a
ADD SP, SP, %b
LABEL {label, "1:"}
SUB_S %b, %b, {fitcon, 4}
move {st_regregrel, SP, %b}, %c
move {regregrel, %a, %b}, %d
ORR %c, %c, %d
move %c, {st_regregrel, SP, %b}
BNE {label, "1B"}
pat xor $1>4
with STACK
kills ALL
uses GENREG,GENREG,GENREG,GENREG
gen move {const4,$1}, %b
move SP, %a
ADD SP, SP, %b
LABEL {label, "1:"}
SUB_S %b, %b, {fitcon, 4}
move {st_regregrel, SP,%b}, %c
move {regregrel, %a, %b}, %d
EOR %c, %c, %d
move %c, {st_regregrel, SP, %b}
BNE {label, "1B"}
pat com $1>4
with STACK
kills ALL
uses GENREG,GENREG,GENREG
gen move {const4,$1}, %b
LABEL {label, "1:"}
SUB_S %b, %b, {fitcon, 4}
move {st_regregrel, SP, %b}, %c
MVN %c, %c
move %c, {st_regregrel, SP, %b}
BNE {label, "1B"}
/************************************************************************
* *
* GROUP X: Sets *
* *
************************************************************************/
pat loc loc inn !defined($3) leaving loc $1 inn $2
pat loc inn $2==4 && $1>=0 && $1<32
with GENREG
uses GENREG={fitcon,1},GENREG
gen AND %b, %1, {imS,%a,"LSL",$1} yields %b
pat loc inn $2==4 && $1<0
with GENREG
gen move {fitcon,0}, %1 yields %1
pat loc inn $2==4 && $1>31 leaving loc 2 trp
pat loc inn !defined($2) leaving inn $1
pat inn defined($1)
with GENREG STACK
uses GENREG={fitcon,1}, GENREG, GENREG
gen AND %b, %1, {fitcon, 31}
move {regS, %a, "LSL", %b}, %b
move {imS, %1, "LSR", 5}, %1
move {st_regiSregrel, SP, "LSL", 2, %1}, %c
AND_S %b, %b, %c
MOV_NE %b, {fitcon, 1}
ADD SP, SP, {const4, $1} yields %b
pat inn !defined($1)
with GENREG GENREG STACK
uses GENREG={fitcon,1}, GENREG, GENREG
gen AND %b, %2, {fitcon, 31}
move {regS, %a, "LSL", %b}, %b
move {imS, %2, "LSR", 5}, %2
move {st_regiSregrel, SP, "LSL", 2, %2}, %c
AND_S %b, %b, %c
MOV_NE %b, {fitcon, 1}
ADD SP, SP, %1 yields %b
pat loc set !defined($2) leaving set $1
pat set $1==4
with const4
uses GENREG={fitcon,1} yields {imS,%a,"LSL",%1.num}
with GENREG
uses GENREG={fitcon,1} yields {regS,%a,"LSL",%1}
pat set $1>4
with GENREG STACK
uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG={const4,$1}
gen LABEL {label, "2:"}
STMFD {autoid, SP}, {reglist1, %b}
SUB_S %c, %c, {fitcon,4}
BGT {label, "2B"}
CMP %1, {fitcon, 0}
BMI {label, "1F"}
AND %b, %1, {fitcon, 31}
move {regS, %a, "LSL", %b}, %b
move {imS, %1, "LSR", 5}, %1
move %b, {st_regiSregrel, SP, "LSL", 2, %1}
LABEL {label, "1:"}
pat set !defined($1)
with STACK
kills ALL
uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG, GENREG
gen LDMFD {autoid, SP}, {reglist1, %c}
LDMFD {autoid, SP}, {reglist1, %d}
LABEL {label, "2:"}
STMFD {autoid, SP}, {reglist1, %b}
SUB_S %c, %c, {fitcon,4}
BGT {label, "2B"}
CMP %d, {fitcon, 0}
BMI {label, "1F"}
AND %b, %d, {fitcon, 31}
move {regS, %a, "LSL", %b}, %b
move {imS, %d, "LSR", 5}, %d
move %b, {st_regiSregrel, SP, "LSL", 2, %d}
LABEL {label, "1:"}
/************************************************************************
* *
* GROUP XI : Array Instructions *
* *
************************************************************************/
pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0 leaving adi 4
pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)>0 && legal(rom($1,1))
with GENREG
uses GENREG
gen SUB %a,%1,{fitcon,rom($1,1)} yields %a
leaving adi 4
with exact regconst yields {regconst, %1.reg,
%1.ind-rom($1,1)}
leaving adi 4
pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
with GENREG
uses GENREG={const4, 0-rom($1,1)}
gen ADD %a,%1,%a yields %a
leaving adi 4
with exact regconst yields {regconst, %1.reg,
%1.ind-rom($1,1)}
leaving adi 4
pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
with GENREG yields {imS, %1,"LSL", 2}
leaving adi 4
pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)>0 && legal(rom($1,1))
with GENREG
uses GENREG
gen SUB %a,%1,{fitcon, rom($1,1)} yields {imS, %a,"LSL", 2}
leaving adi 4
pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
with GENREG
uses GENREG={const4, 0-rom($1,1)}
gen ADD %a,%1,%a yields {imS, %a,"LSL", 2}
leaving adi 4
pat lae aar $2==4 && rom($1,1)==0
leaving loc rom($1,3)
mli 4 adi 4
pat lae aar $2==4 && rom($1,1)>0 && legal(rom($1,1))
with GENREG
uses GENREG
gen SUB %a,%1,{fitcon,rom($1,1)} yields %a
leaving loc rom($1,3)
mli 4 adi 4
pat lae aar $2==4 && rom($1,1)!=0
with GENREG
uses GENREG={const4, 0-rom($1,1)}
gen ADD %a,%1,%a yields %a
leaving loc rom($1,3)
mli 4 adi 4
pat aar $1==4
with GENREG GENREG
uses GENREG
gen move {regind, %1}, %a
SUB %2, %2, %a yields %2 {regrel, %1, 8}
leaving mli 4 adi 4
pat lae sar $2==4 && defined(rom($1,3)) leaving lae $1 aar 4
sti rom($1,3)
pat lae lar $2==4 && defined(rom($1,3)) leaving lae $1 aar 4
loi rom($1,3)
pat loc aar !defined($2) leaving aar $1
pat lae loc sar !defined($3) && $2==4 && defined(rom($1,3))
leaving lae $1 aar 4
sti rom($1,3)
pat lae loc lar !defined($3) && $2==4 && defined(rom($1,3))
leaving lae $1 aar 4
loi rom($1,3)
/* next two: dynamic arrays in modula2 - not tested */
pat lal sar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 sts
pat lal lar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 los
/************************************************************************
* *
* GROUP XII : Compare Instructions *
* *
************************************************************************/
pat cmi
with GENREG REGcon
uses reusing %1, GENREG=%1
gen RSB_S %a, %1, %2 yields %a
with REGcon GENREG
uses reusing %2, GENREG=%2
gen SUB_S %a, %2, %1 yields %a
pat cmu $1==4
with GENREG REGcon
uses GENREG
gen CMP %1, %2
MOV_HI %a, {fitcon, 0-1}
MOV_LS %a, {fitcon, 1}
MOV_EQ %a, {fitcon, 0} yields %a
with REGcon GENREG
uses GENREG
gen CMP %2, %1
MOV_HI %a, {fitcon, 1}
MOV_LS %a, {fitcon, 0-1}
MOV_EQ %a, {fitcon, 0} yields %a
pat cmp leaving cmu 4
pat cmf $1==4 leaving cal ".cmf4" asp 8 lfr 4
pat cmf $1==8 leaving cal ".cmf8" asp 16 lfr 4
pat loc cms !defined($2) leaving cms $1
pat cms $1==4
with GENREG REGcon
gen EOR_S %1, %1, %2 yields %1
with REGcon GENREG
gen EOR_S %2, %2, %1 yields %2
pat cms $1!=4
with STACK
kills ALL
uses GENREG = {const4, $1}, GENREG, GENREG, GENREG, GENREG
gen move %a, %e
ADD %b, %a, SP
LABEL {label, "1:"}
SUB_S %a, %a, {fitcon, 4}
BLT {label, "2F"}
move {st_regregrel, SP, %a}, %c
move {regregrel, %b, %a}, %d
EOR_S %c, %c, %d
BEQ {label, "1B"}
LABEL {label, "2:"}
ADD SP, %b, %e yields %c
pat cms !defined($1)
with GENREG STACK
uses GENREG, GENREG, GENREG, GENREG
gen move %1, %d
ADD %a, %1, SP
LABEL {label, "1:"}
SUB_S %1, %1, {fitcon, 4}
BLT {label, "2F"}
move {st_regregrel, SP, %1}, %b
move {regregrel, %a, %1}, %c
EOR_S %b, %b, %c
BEQ {label, "1B"}
LABEL {label, "2:"}
ADD SP, %a, %d yields %b
pat tlt
with GENREG
uses reusing %1, GENREG=%1
gen test %1
MOV_LT %a, {fitcon,1}
MOV_GE %a, {fitcon,0} yields %a
pat tle
with GENREG
uses reusing %1, GENREG=%1
gen test %1
MOV_LE %a, {fitcon,1}
MOV_GT %a, {fitcon,0} yields %a
pat teq
with GENREG
uses reusing %1, GENREG=%1
gen test %1
MOV_EQ %a, {fitcon,1}
MOV_NE %a, {fitcon,0} yields %a
pat tne
with GENREG
uses reusing %1, GENREG=%1
gen test %1
MOV_NE %a, {fitcon,1}
MOV_EQ %a, {fitcon,0} yields %a
pat tge
with GENREG
uses reusing %1, GENREG=%1
gen test %1
MOV_GE %a, {fitcon,1}
MOV_LT %a, {fitcon,0} yields %a
pat tgt
with GENREG
uses reusing %1, GENREG=%1
gen test %1
MOV_GT %a, {fitcon,1}
MOV_LE %a, {fitcon,0} yields %a
/************************************************************************
* *
* GROUP XIII : Branch Instructions *
* *
************************************************************************/
pat bra
with STACK
kills ALL
gen BAL {label, $1}
pat bne
with REGcon GENREG STACK
gen CMP %2, %1
BNE {label, $1}
with GENREG REGcon STACK
gen CMP %1, %2
BNE {label, $1}
pat beq
with REGcon GENREG STACK
gen CMP %2, %1
BEQ {label, $1}
with GENREG REGcon STACK
gen CMP %1, %2
BEQ {label, $1}
pat blt
with REGcon GENREG STACK
gen CMP %2, %1
BLT {label, $1}
pat ble
with REGcon GENREG STACK
gen CMP %2, %1
BLE {label, $1}
pat bgt
with REGcon GENREG STACK
gen CMP %2, %1
BGT {label, $1}
pat bge
with REGcon GENREG STACK
gen CMP %2, %1
BGE {label, $1}
pat zlt
with GENREG STACK
gen test %1
BLT {label, $1}
pat zle
with GENREG STACK
gen test %1
BLE {label, $1}
pat zeq
with GENREG STACK
gen test %1
BEQ {label, $1}
pat zne
with GENREG STACK
gen test %1
BNE {label, $1}
pat zge
with GENREG STACK
gen test %1
BGE {label, $1}
pat zgt
with GENREG STACK
gen test %1
BGT {label, $1}
/************************************************************************
* *
* GROUP XIV : Procedure Call *
* *
************************************************************************/
pat cal
with STACK
kills ALL
gen BAL_L {label, $1}
pat cai
with GENREG STACK
kills ALL
gen /* the trick is to set up R14 properly */
ADR LR, {label, "1F"}
MOV PC, %1
LABEL {label, "1:"}
pat lfr $1==4 yields R0
pat lfr $1==8 yields R1 R0
pat lfr $1==12 yields R2 R1 R0
pat ret $1==0
with STACK
kills ALL
gen return
MOV SP, LB
LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
pat ret $1==4
with address STACK
kills ALL
gen move %1, R0
return
move LB, SP
LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
with REGcon STACK
kills ALL
gen move %1, R0
return
move LB, SP
LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
pat ret $1==8
with REGcon REGcon STACK
kills ALL
gen move %1, R0
move %2, R1
return
move LB, SP
LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
pat ret $1==12
with REGcon REGcon REGcon STACK
kills ALL
gen move %1, R0
move %2, R1
move %3, R2
return
move LB, SP
LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
/************************************************************************
* *
* GROUP XV : Miscellaneous *
* *
************************************************************************/
pat asp legal($1)
with STACK
kills ALL
gen ADD SP, SP, {fitcon, $1}
pat asp
with STACK
kills ALL
uses GENREG={const4, $1}
gen ADD SP, SP, %a
pat ass $1==4
with REGcon STACK
gen ADD SP, SP, %1
pat blm $1==0
with address+REGcon address+REGcon
pat blm $1==1
with GENREG GENREG
kills address
uses GENREG
gen LDR_B %a, {regind, %2}
STR_B %a, {regind, %1}
pat blm $1==4
with GENREG GENREG
kills address
uses GENREG
gen move {regind, %2}, %a
move %a, {regind, %1}
pat blm $1>4
with GENREG GENREG
kills address
uses GENREG, GENREG={const4, $1-4}
gen LABEL {label, "1:"}
move {regregrel, %2, %b}, %a
move %a, {regregrel, %1, %b}
SUB_S %b, %b, {fitcon, 4}
BGE {label,"1B"}
pat bls $1==4
with GENREG GENREG GENREG
kills address
uses GENREG
gen LABEL {label, "1:"}
SUB_S %1, %1, {fitcon, 4}
move {regregrel, %3, %1}, %a
move %a, {regregrel, %2, %1}
BGT {label,"1B"}
pat csa $1==4
with STACK
kills ALL
gen BAL_L {label, "_Csa"}
move R2, PC
pat csb $1==4
with STACK
kills ALL
gen BAL_L {label, "_Csb"}
move R3, PC
pat dch leaving loi 4
pat dup $1==4
with address+REGcon yields %1 %1
pat dup $1==8
with address+REGcon address+REGcon yields %2 %1 %2 %1
pat dup $1>8
with STACK
kills ALL
uses GENREG={const4,$1}, GENREG
gen LABEL {label, "1:"}
move {st_regrel, SP, $1-4}, %b
STMFD {autoid, SP}, {reglist1, %b}
SUB_S %a, %a, {fitcon, 4}
BGT {label, "1B"}
pat dus
with GENREG STACK
uses GENREG, GENREG
gen SUB %b, %1, {fitcon, 4}
LABEL {label, "1:"}
move {st_regregrel, SP, %b}, %a
STMFD {autoid, SP}, {reglist1, %a}
SUB_S %1, %1, {fitcon, 4}
BGT {label, "1B"}
pat exg $1==4
with address+REGcon address+REGcon yields %1 %2
pat exg $1==8
with address+REGcon address+REGcon
address+REGcon address+REGcon yields %2 %1 %4 %3
pat exg $1>8
with STACK
kills ALL
uses GENREG, GENREG, GENREG={const4, $1-4}, GENREG, GENREG={const4, $1}
gen ADD %d, SP, %e
LABEL {label, "1:"}
move {st_regregrel, SP,%c}, %a
move {regregrel,%d,%c}, %b
move %a, {regregrel,%d,%c}
move %b, {st_regregrel, SP,%c}
SUB_S %c, %c, {fitcon, 4}
BGE {label, "1B"}
pat fil
uses GENREG
gen move {addr_external,$1}, %a
move %a, {addr_external, "_Filna"}
pat gto /* this code does NOT restore registers */
uses GENREG,GENREG,GENREG,GENREG
gen move {addr_external, $1}, %d
move {regind, %d}, %a
move {regrel, %d, 4}, %b
move {regrel, %d, 8}, %c
MOV LB, %c
MOV SP, %b
MOV PC, %a
pat lin
kills address
uses GENREG={const4,$1}
gen move %a,{addr_external,"_Lineno"}
pat lni
kills address
uses GENREG
gen move {addr_external,"_Lineno"}, %a
LDR %a, {regind, %a}
ADD %a,%a,{fitcon,1}
move %a,{addr_external,"_Lineno"}
pat lor $1==0 yields LB
pat lor $1==1
with STACK
kills ALL yields SP
pat lor $1==2 yields {absolute, "_RegHp"}
pat lpb leaving adp 8
pat nop
kills ALL
gen MOV_NV R0,R0
pat rck
with GENREG REGcon STACK
uses GENREG,GENREG
gen move {regind, %1}, %a
/* for some reason, the code generator expects the value
* to be checked on top of the stack after checking, while
* in fact it is held in %2. This causes mayhem later on, and
* the following two lines rectify this.
*/
move %2,%b
STMFD {autoid, SP}, {reglist1, %b}
CMP %a, %2
BGT {label, "_RckTrap"}
move {regrel, %1, 4}, %a
CMP %a, %2
BLT {label, "_RckTrap"}
pat lim
with STACK
kills ALL
uses GENREG
gen move {addr_external, "_IgnoreMask"}, %a
STMFD {autoid, SP}, {reglist1, %a}
pat mon
with STACK
kills ALL
gen BAL_L {label, "_EmMon"}
pat rtt
leaving ret 0
pat sig
with STACK
kills ALL
uses GENREG,GENREG
gen move {addr_external, "_TrpReg"}, %a
LDR %a, {regind, %a}
LDMFD {autoid, SP}, {reglist1, %b}
move %b, {addr_external, "_TrpReg"}
STMFD {autoid, SP}, {reglist1, %a}
pat sim
with STACK
kills ALL
uses GENREG
gen LDMFD {autoid, SP}, {reglist1, %a}
move %a, {addr_external, "_IgnoreMask"}
pat trp
with STACK
kills ALL
gen BAL_L {label, "_EmTrp"}
pat str $1==0
with address
gen move %1, LB
with REGcon
gen move %1, LB
pat str $1==1
with address
gen MOV SP, %1
with REGcon
gen MOV SP, %1
pat str $1==2
with GENREG
gen move %1, {absolute, "_RegHp"}
/***********************************************************************/
/* code for *p++ and *p-- (integers)*/
pat lol dup adp stl loi $1==$4 && $2==4 && $5==4
kills GENREG
uses GENREG, GENREG
gen move {lb_local, $1}, %a
LDR %b, {regrelpi, %a, $5}
STR %a, {lb_local, $1} yields %b
pat lol dup adp stl sti $1==$4 && $2==4 && $5==4
with GENREG
kills GENREG
uses GENREG
gen move {lb_local,$1}, %a
STR %1, {regrelpi, %a, $5}
STR %a, {lb_local, $1}
/* code for *p++ and *p-- (bytes)*/
pat lol dup adp stl loi $1==$4 && $2==4 && $5==1
kills GENREG
uses GENREG, GENREG
gen move {lb_local, $1}, %a
LDR_B %b, {regrelpi, %a, $5}
STR %a, {lb_local, $1} yields %b
pat lol dup adp stl sti $1==$4 && $2==4 && $5==1
with GENREG
kills GENREG
uses GENREG
gen move {lb_local,$1}, %a
STR_B %1, {regrelpi, %a, $5}
STR %a, {lb_local, $1}
/* code for *pp->p++ and *pp->p-- (integers)*/
pat lil dup adp sil loi $1==$4 && $2==4 && $5==4
kills GENREG
uses GENREG, GENREG, GENREG
gen move {lb_local, $1}, %a
LDR %b, {regind, %a}
ADD %c, %b, {fitcon, $5}
STR %c, {regind, %a}
LDR %c, {regind, %b} yields %c
pat lil dup adp sil sti $1==$4 && $2==4 && $5==4
with GENREG
kills GENREG
uses GENREG, GENREG, GENREG
gen move {lb_local, $1}, %a
LDR %b, {regind, %a}
ADD %c, %b, {fitcon, $5}
STR %c, {regind, %a}
STR %1, {regind, %b}
/* code for *pp->p++ and *pp->p-- (bytes)*/
pat lil dup adp sil loi $1==$4 && $2==4 && $5==1
kills GENREG
uses GENREG, GENREG, GENREG
gen move {lb_local, $1}, %a
LDR %b, {regind, %a}
ADD %c, %b, {fitcon, $5}
STR %c, {regind, %a}
LDR_B %c, {regind, %b} yields %c
pat lil dup adp sil sti $1==$4 && $2==4 && $5==1
with GENREG
kills GENREG
uses GENREG, GENREG, GENREG
gen move {lb_local, $1}, %a
LDR %b, {regind, %a}
ADD %c, %b, {fitcon, $5}
STR %c, {regind, %a}
STR_B %1, {regind, %b}
/* global array access of the form x[y-1] */
pat lol loc mli loc sbi $2==$4 && $3==4 && $5==4
leaving lol $1 dec 4 loc $2 mli 4
/* x[i] = y with large array elements */
pat lae loi lae lol loc mli ads sti $2==$8 && $2 > 4
leaving lae $1 lae $3 lol $4 loc $5 mli $6 ads $7 blm $8
pat lae loi lae lol loc mlu ads sti $2==$8 && $2 > 4
leaving lae $1 lae $3 lol $4 loc $5 mlu $6 ads $7 blm $8
/* prevent double push/pull of $1 */
pat lae lol loc mli ads
leaving lol $2 loc $3 mli $4 lae $1 ads $5
pat lae lol loc mlu ads
leaving lol $2 loc $3 mlu $4 lae $1 ads $5
pat lae lol loc mli ads lol loc mli ads $5==$9 && $4==$8
leaving lol $2 loc $3 mli $4 lol $6 loc $7 mli $8 ads $5 lae $1 ads $9
pat lae lol loc mlu ads lol loc mlu ads $5==$9 && $4==$8
leaving lol $2 loc $3 mlu $4 lol $6 loc $7 mlu $8 ads $5 lae $1 ads $9
pat lae lol adp loi loc mli ads
leaving lol $2 adp $3 loi $4 loc $5 mli $6 lae $1 ads $7
pat lae lol adp loi loc mlu ads
leaving lol $2 adp $3 loi $4 loc $5 mlu $6 lae $1 ads $7
/*
pat lae loi lae lol adp loi loc mli ads sti $2==$10 && $2 > 4
leaving lae $1 lae $3 lol $4 adp $5 loi $6 loc $7 mli $8 ads $9 blm $2
pat lae loi lae lol adp loi loc mlu ads sti $2==$10 && $2 > 4
leaving lae $1 lae $3 lol $4 adp $5 loi $6 loc $7 mlu $8 ads $9 blm $2
*/