/**************************************************************************** * 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 */