2412 lines
61 KiB
Plaintext
2412 lines
61 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) neglegal(a) && (a < 0)
|
|
#define minillegal(a) !neglegal(a) && (a < 0)
|
|
|
|
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 legal(%ind) && (%ind > 0) 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 illegal(%ind) to GENREG
|
|
gen move {const4, %1.ind}, R11
|
|
LDR %2, {lb_regregrel, LB, R11}
|
|
|
|
from lb_local legal(%ind) to GENREG
|
|
gen LDR %2, {lb_regrel, LB, %1.ind}
|
|
|
|
from GENREG to lb_local illegal(%ind)
|
|
gen move {const4, %2.ind}, R11
|
|
STR %1, {lb_regregrel, LB, R11}
|
|
|
|
from GENREG to lb_local legal(%ind)
|
|
gen STR %1, {lb_regrel, LB, %2.ind}
|
|
|
|
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(%1.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(%1.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 legal(%1.ind) && (%ind > 0) 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 illegal(%ind)
|
|
uses GENREG
|
|
gen move {const4, %1.ind}, R11
|
|
LDR %a, {lb_regregrel, LB, R11} yields %a
|
|
|
|
from lb_local legal(%ind)
|
|
uses GENREG
|
|
gen LDR %a, {lb_regrel, LB, %1.ind} yields %a
|
|
|
|
from const4 %1.num < 0
|
|
uses GENREG
|
|
gen move {const4, 0-%1.num}, %a
|
|
RSB %a, %a, {fitcon, 0} yields %a
|
|
|
|
from const4 illegal(%1.num) && (%1.num >= 0)
|
|
uses GENREG
|
|
gen move %1, %a yields %a
|
|
|
|
from const4 legal(%1.num) && %1.num >= 0 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(%1.ind)
|
|
uses GENREG
|
|
gen ADD %a, LB, {fitcon, %1.ind} yields %a
|
|
|
|
from addr_local illegal(%1.ind)
|
|
uses GENREG
|
|
gen move {const4, %1.ind}, %a
|
|
ADD %a, LB, %a yields %a
|
|
|
|
from naddr_local legal(%1.ind)
|
|
uses GENREG
|
|
gen SUB %a, LB, {fitcon, %1.ind} yields %a
|
|
|
|
from naddr_local illegal(%1.ind)
|
|
uses GENREG
|
|
gen move {const4, %1.ind}, %a
|
|
SUB %a, LB, %a yields %a
|
|
|
|
from regconst legal(%1.ind) && (%1.ind > 0)
|
|
uses GENREG
|
|
gen ADD %a, %1 yields %a
|
|
|
|
from regconst minlegal(%1.ind)
|
|
uses GENREG
|
|
gen SUB %a, %1.reg, {fitcon, 0-%1.ind} yields %a
|
|
|
|
from regconst minillegal(%1.ind)
|
|
uses GENREG
|
|
gen move {const4, 0-%1.ind}, %a
|
|
SUB %a, %a, %1.reg yields %a
|
|
|
|
from regconst illegal(%1.ind)
|
|
uses GENREG
|
|
gen move {const4, %1.ind}, %a
|
|
ADD %a, %a, %1.reg yields %a
|
|
|
|
from regplusreg
|
|
uses GENREG
|
|
gen ADD %a, %1.reg1, %1.reg2
|
|
yields %a
|
|
|
|
from regminreg
|
|
uses GENREG
|
|
gen SUB %a, %1.reg1, %1.reg2
|
|
yields %a
|
|
|
|
from regplusiSreg
|
|
uses GENREG
|
|
gen ADD %a, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
|
|
yields %a
|
|
|
|
from regminiSreg
|
|
uses GENREG
|
|
gen SUB %a, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
|
|
yields %a
|
|
|
|
from regplusrSreg
|
|
uses GENREG
|
|
gen ADD %a, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
|
|
yields %a
|
|
|
|
from regminrSreg
|
|
uses GENREG
|
|
gen SUB %a, %1.reg1, {regS, %1.reg2, %1.S, %1.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")
|
|
|
|
/* 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 lil adp sil loi $1==$2 && $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 lil adp sil sti $1==$2 && $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 lil adp sil loi $1==$2 && $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 lil adp sil sti $1==$2 && $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 illegal($1) && $1 >= 0 yields {const4, $1}
|
|
|
|
pat loc legal($1) yields {fitcon, $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==8
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".adf8" asp 16 lfr 4 loi 8
|
|
pat adf $1==4
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".adf4" asp 8 lfr 4
|
|
|
|
pat sbf $1==8
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".sbf8" asp 16 lfr 4 loi 8
|
|
pat sbf $1==4
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".sbf4" asp 8 lfr 4
|
|
|
|
pat mlf $1==8
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".mlf8" asp 16 lfr 4 loi 8
|
|
pat mlf $1==4
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".mlf4" asp 8 lfr 4
|
|
|
|
pat dvf $1==8
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".dvf8" asp 8
|
|
pat dvf $1==4
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".dvf4" asp 4
|
|
|
|
pat ngf $1==8
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".ngf8"
|
|
pat ngf $1==4
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".ngf4"
|
|
|
|
pat fif $1==8
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".fif8"
|
|
pat fif $1==4
|
|
with STACK
|
|
kills ALL
|
|
leaving cal ".fif4"
|
|
|
|
/* the next two need a 4 byte hole on the stack */
|
|
pat ldl fef $2==8
|
|
with STACK
|
|
kills ALL
|
|
leaving loc 0 ldl $1 cal ".fef8"
|
|
pat lol fef $2==4
|
|
with STACK
|
|
kills ALL
|
|
leaving loc 0 lol $1 cal ".fef4"
|
|
|
|
/************************************************************************
|
|
* *
|
|
* 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 8 lfr 4
|
|
pat loc loc cif $1==4 && $2==8 leaving loc 4 cal ".cif8" asp 8 lfr 4 loi 8
|
|
|
|
pat loc loc cuf $1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 8 lfr 4
|
|
pat loc loc cuf $1==4 && $2==8 leaving loc 4 cal ".cuf8"
|
|
|
|
pat loc loc cfi $1==8 && $2==4
|
|
leaving loc $1 loc $2 cal ".cfi" asp 16 lfr 4
|
|
pat loc loc cfi $1==4 && $2==4
|
|
leaving loc $1 loc $2 cal ".cfi" asp 12 lfr 4
|
|
|
|
pat loc loc cfu $1==8 && $2==4
|
|
leaving loc $1 loc $2 cal ".cfu" asp 16 lfr 4
|
|
pat loc loc cfu $1==4 && $2==4
|
|
leaving loc $1 loc $2 cal ".cfu" asp 12 lfr 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 illegal($1)
|
|
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
|
|
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 lol adp stl loi $1==$2 && $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 lol adp stl sti $1==$2 && $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 lol adp stl loi $1==$2 && $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 lol adp stl sti $1==$2 && $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 lil adp sil loi $1==$2 && $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 lil adp sil sti $1==$2 && $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 lil adp sil loi $1==$2 && $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 lil adp sil sti $1==$2 && $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
|
|
*/
|