2 * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
6 rscid = "$Id: table,v 1.18 1995/09/12 12:09:08 ceriel Exp $"
9 * Back end tables for Intel 80386
11 * Author : Ceriel J.H. Jacobs
13 * Partly adapted from Intel 8086 table
15 * wordsize = 4 bytes, pointersize = 4 bytes.
17 * Register ebp is used as LB, esp is used for SP.
18 * Some global variables are used:
19 * - .reghp : the heap pointer
20 * - .ignmask : trap ignore mask
21 * - .trppc : address of user defined trap handler
39 #define EXACT exact /* to improve code but slow down code generator,
43 /*****************************************************************/
45 /*****************************************************************/
47 REG1 /* general 1 byte register */
48 REG2 /* general 2 byte register */
49 ACC1 /* 1 byte accumulator */
50 ACC2 /* 2 byte accumulator */
51 REG /* allocatable register */
52 GENREG /* register with sub-registers */
54 SHIFT_CREG /* shift count register */
55 BXREG /* ebx register */
56 AREG /* address register */
57 ADDREG /* allocatable address register */
58 CXREG /* ecx register */
59 DXREG /* edx register */
60 IREG /* index register */
61 RREG /* register variable, or register without subregs */
63 /*****************************************************************/
65 /*****************************************************************/
68 ah,bl, bh, ch,dl,dh : REG1 .
69 cl : REG1 , SHIFT_CREG .
70 ax = al + ah : REG2 , ACC2 .
74 eax = al + ah : REG, GENREG, IREG, ACC, ADDREG, AREG.
75 ebx = bl + bh : REG, GENREG, IREG, BXREG, ADDREG, AREG.
76 ecx = cl + ch : REG, GENREG, IREG, CXREG, SHIFT_CREG, ADDREG , AREG .
77 edx = dl + dh : REG, GENREG, IREG, DXREG, ADDREG, AREG .
79 esi : REG, RREG, IREG, AREG, ADDREG .
80 edi : REG, RREG, IREG, AREG, ADDREG .
82 esi : AREG , IREG , RREG regvar(reg_any) .
83 edi : AREG , IREG , RREG regvar(reg_any) .
88 /*****************************************************************/
90 /*****************************************************************/
92 ANYCON = { INT val; } 4 cost(4,0) val .
93 CONSTR = { ADDR off; } 4 cost(4,0) off .
94 ADDR_EXTERN = { ADDR off; } 4 cost(4,0) off .
95 EXTERN1 = { ADDR off; } 4 cost(4,5) "(" off ")" .
96 EXTERN2 = { ADDR off; } 4 cost(4,5) "(" off ")" .
97 EXTERN = { ADDR off; } 4 cost(4,5) "(" off ")" .
98 ADDR_LOCAL = { INT ind; } 4 cost(1,0) ind "(ebp)" .
99 LOCAL = { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
100 LOCAL1 = { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
101 LOCAL2 = { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
103 Rreg_off = { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
104 Xreg_off = { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
105 indexed_r_off = { AREG reg; IREG reg2; INT scale; ADDR off;}
106 4 cost(5,0) off "(" reg ")" "(" reg2 "*" scale ")" .
107 indexed_off = { IREG reg; INT scale; ADDR off;}
108 4 cost(5,0) off "(" reg "*" scale ")" .
110 indir_r = { AREG reg;} 4 cost(0,5) "(" reg ")" .
111 indir_r1 = { AREG reg;} 4 cost(0,5) "(" reg ")" .
112 indir_r2 = { AREG reg;} 4 cost(0,5) "(" reg ")" .
113 indir_r_off = { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
114 indir_r_off1 = { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
115 indir_r_off2 = { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
117 indir_indexed_r_off =
118 { AREG reg; IREG reg2; INT scale; ADDR off;}
119 4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
120 indir_indexed_r_off1 =
121 { AREG reg; IREG reg2; INT scale; ADDR off;}
122 4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
123 indir_indexed_r_off2 =
124 { AREG reg; IREG reg2; INT scale; ADDR off;}
125 4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
127 { IREG reg; INT scale; ADDR off;}
128 4 cost(5,5) off "(" reg "*" scale ")" .
130 { IREG reg; INT scale; ADDR off;}
131 4 cost(5,5) off "(" reg "*" scale ")" .
133 { IREG reg; INT scale; ADDR off;}
134 4 cost(5,5) off "(" reg "*" scale ")" .
136 label = { ADDR off;} 4 off .
138 /*****************************************************************/
140 /*****************************************************************/
142 /* Mode refering to a word in memory */
143 memory2 = EXTERN2 + indir_r2 + indir_r_off2 + LOCAL2 +
144 indir_indexed_r_off2 + indir_indexed_off2 .
145 memory1 = EXTERN1 + indir_r1 + indir_r_off1 + LOCAL1 +
146 indir_indexed_r_off1 + indir_indexed_off1 .
147 memory = EXTERN + indir_r + indir_r_off + LOCAL +
148 indir_indexed_r_off + indir_indexed_off .
149 noacc = EXTERN + LOCAL + BXREG + CXREG + RREG .
150 const = ANYCON + ADDR_EXTERN + CONSTR .
151 register = REG + ADDREG + RREG + IREG .
152 addreg = ADDREG + RREG .
153 anyreg = register + AREG .
154 rm = anyreg + memory .
155 rmorconst = const + rm .
156 regorconst = const + anyreg .
157 dest = register + memory .
159 rm1 = REG1 + memory1 .
160 rmorconst1 = const + rm1 .
161 rm2 = REG2 + memory2 .
162 rmorconst2 = const + rm2 .
163 regorconst124 = REG1 + REG2 + GENREG + const .
164 regorconst24 = REG2 + GENREG + const .
165 dest1 = REG1 + memory1 .
166 dest2 = REG2 + memory2 .
168 /* Modes used to indicate tokens to be removed from the fakestack */
169 reg_indir = indir_r1 + indir_r2 + indir_r_off1 + indir_r_off2 + indir_r +
171 indexed = indir_indexed_r_off1 + indir_indexed_r_off2 +
172 indir_indexed_r_off + indir_indexed_off1 +
173 indir_indexed_off2 + indir_indexed_off .
174 indir = reg_indir + indexed .
175 externals = EXTERN2 + EXTERN1 + EXTERN .
176 locals = LOCAL2 + LOCAL1 + LOCAL .
177 mem_nonlocals = externals + reg_indir .
178 all_mems = mem_nonlocals + locals .
181 reg_off = Xreg_off + Rreg_off .
182 halfindir = reg_off + ADDR_LOCAL + indexed_r_off + indexed_off .
183 some_off = halfindir + ADDR_EXTERN + AREG .
184 a_word = rmorconst + halfindir .
186 /*****************************************************************/
188 /*****************************************************************/
191 adc rm:rw:cc, regorconst:ro.
192 adc anyreg:rw:cc, rmorconst:ro.
194 add LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
196 add anyreg:rw:cc, rmorconst:ro.
197 add rm:rw:cc, regorconst:ro.
199 axx "syntax error" LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
201 axx "syntax error" anyreg:rw:cc, rmorconst:ro.
202 axx "syntax error" rm:rw:cc, regorconst:ro.
204 and LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
206 and rm:rw:cc, regorconst:ro.
207 and anyreg:rw:cc, rmorconst:ro.
208 cdq kills edx cost(1,3).
209 cmp rm:ro, regorconst:ro kills :cc.
210 cmp anyreg:ro, rmorconst:ro kills :cc.
211 cmpb rm1:rw, const:ro kills :cc.
212 cmpw "o16 cmp" rm2:rw, const:ro kills :cc cost(3,2).
213 dec anyreg:rw:cc cost(1,2).
215 div rm:ro kills:cc eax edx cost(2,43).
216 idiv rm:ro kills:cc eax edx cost(2,43).
217 imul rm:rw, anyreg:ro kills:cc cost(3,41).
218 imul anyreg:rw, rm:ro kills:cc cost(3,41).
219 imul anyreg:wo, rm:ro, const:ro kills :cc cost(2,38).
220 inc anyreg:rw:cc cost(1,2).
226 jcxz label cost(1,4).
234 proccall "call" label+rm cost(1,8).
235 jxx "syntax error" label cost(1,4).
236 setxx "syntax error" REG1:rw cost(2,4).
237 setle REG1:rw cost(2,4).
238 setg REG1:rw cost(2,4).
239 lea anyreg:rw, halfindir:ro.
240 lea LOCAL:rw, halfindir:ro. /* only for register variables, UNSAFE!!! */
242 loop label kills ecx.
244 mov LOCAL:wo, rmorconst:ro. /* only for register variables, UNSAFE!!! */
246 mov a_word:wo, regorconst:ro.
247 mov anyreg:wo, rmorconst:ro.
248 movb rm1:wo, regorconst124:ro.
249 movb REG1:wo, rm1:ro.
250 movw "o16 mov" rm2:wo, regorconst124:ro cost(3,2).
251 movw "o16 mov" REG2:wo, rmorconst2:ro cost(3,2).
252 movsxb anyreg:wo, REG+rm1:ro.
253 movsx anyreg:wo, REG+rm2:ro.
254 movzxb anyreg:wo, REG+rm1:ro.
255 movzx anyreg:wo, REG+rm2:ro.
256 mul rmorconst:ro kills :cc eax edx cost(2,41).
260 or LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
262 or rm:rw:cc, regorconst:ro.
263 or anyreg:rw:cc, rmorconst:ro.
264 pop anyreg:wo cost(1,4).
266 push anyreg:ro cost(1,2).
267 push const:ro cost(1,2).
268 push rm:ro cost(2,5).
269 rcl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
270 rcr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
272 rol rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
273 ror rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
274 sal rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
275 sar rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
276 sbb rm:rw:cc, regorconst:ro.
277 sbb anyreg:rw:cc, rmorconst:ro.
278 shl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
279 shr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
281 sub LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
283 sub rm:rw:cc, regorconst:ro.
284 sub anyreg:rw:cc, rmorconst+halfindir:ro.
285 check "test" rm:ro, regorconst:ro kills :cc.
286 check "test" anyreg:ro, rmorconst:ro kills :cc.
287 testb "testb" rm1:ro, regorconst124:ro kills :cc.
288 testb "testb" REG1:ro, rmorconst1:ro kills :cc.
289 testw "o16 test" rm2:ro, regorconst24:ro kills :cc.
290 testw "o16 test" REG2:ro, rmorconst2:ro kills :cc.
291 testl "test" rm:ro, regorconst:ro kills :cc.
292 testl "test" REG:ro, rmorconst:ro kills :cc.
293 uxx "syntax error" rm:rw:cc.
294 xchg rm:rw, anyreg:rw.
295 xchg anyreg:rw, rm:rw.
296 xor rm:rw:cc, regorconst:ro.
297 xor anyreg:rw:cc, rmorconst:ro.
298 xorb rm1:rw:cc, regorconst124:ro.
299 xorb anyreg:rw:cc, rmorconst1:ro.
300 xorw "o16 xor" rm2:rw:cc, regorconst124:ro.
301 xorw "o16 xor" anyreg:rw:cc, rmorconst2:ro.
303 killreg "! kill" anyreg:wo cost(0,0).
304 killcc "! kill cc" kills:cc cost(0,0).
307 /*****************************************************************/
309 /*****************************************************************/
312 from rmorconst to LOCAL /* unsafe !!! */
322 from halfindir to register+AREG
325 from halfindir to LOCAL /* unsafe !!! */
343 from ANYCON %val==0 to register
346 from ANYCON %val==0 to REG1
349 from ANYCON %val==0 to REG2
355 from const+REG1 to rm1
358 from const+REG2 to rm2
361 /*****************************************************************/
363 /*****************************************************************/
369 gen cmp %1, {ANYCON,0}
375 gen cmpb %1, {ANYCON,0}
381 gen cmpw %1, {ANYCON,0}
384 /*****************************************************************/
386 /*****************************************************************/
402 xchg {indir_r,esp},eax
412 xchg {indir_r,esp},eax
414 from Xreg_off to STACK
415 gen add %1.reg,{CONSTR,%1.off}
418 from ADDR_LOCAL %ind==0 to STACK
421 from halfindir to STACK
426 from halfindir to STACK
429 xchg {indir_r,esp},eax
432 /*****************************************************************/
434 /*****************************************************************/
436 /***************************
437 * From source to register *
438 ***************************/
441 uses reusing %1,REG=%1 yields %a
443 uses reusing %1,IREG=%1 yields %a
446 gen add %1.reg,{CONSTR,%1.off} yields %1.reg
449 uses reusing %1,ADDREG
450 gen move %1,%a yields %a
454 gen move %1,%a yields %a
458 gen move %1,%a yields %a
460 /************************
461 * From source to token *
462 ************************/
464 from ANYCON yields {ADDR_EXTERN,%1.val}
471 uses reusing %1,REG1=%1 yields %a
476 movzxb %a,%1 yields %a
483 uses reusing %1,REG2=%1 yields %a
488 movzx %a,%1 yields %a
490 /************************
491 * From STACK coercions *
492 ************************/
499 /*****************************************************************/
501 /*****************************************************************/
503 /******************************************************************
504 * Group 1 : Load Instructions *
505 ******************************************************************/
507 pat loc yields {ANYCON,$1}
509 pat ldc leaving loc 18 trp
511 pat lol yields {LOCAL,$1,4}
519 pat sdl ldl $1==$2 leaving dup 8 sdl $1
522 pat lol dup stl $2==4 && inreg($1) <= 0 && inreg($3) > 0
524 gen move {LOCAL,$1,4}, {LOCAL,$3,4}
528 pat loe yields {EXTERN,$1}
530 pat ste loe $1==$2 leaving dup 4 ste $1
532 pat sde lde $1==$2 leaving dup 8 sde $1
535 pat loe dup stl $2==4 && inreg($3) > 0
537 gen move {EXTERN,$1}, {LOCAL,$3,4}
542 pat lil inreg($1) > 0 yields {indir_r, regvar($1)}
545 uses ADDREG={indir_r_off,ebp,$1} yields {indir_r,%a}
547 pat lil dup stl $2==4 leaving lil $1 stl $3 lol $3
549 pat sil lil $1==$2 leaving dup 4 sil $1
552 with exact indexed_r_off yields {indir_indexed_r_off,%1.reg,%1.reg2,
554 with exact indexed_off yields {indir_indexed_off,%1.reg,
556 with exact reg_off yields {indir_r_off,%1.reg,%1.off+$1}
557 with exact ADDR_EXTERN yields {EXTERN,%1.off+$1}
558 with exact ADDR_LOCAL yields {LOCAL,%1.ind + $1,4}
559 with addreg yields {indir_r_off,%1,$1}
561 pat lal yields {ADDR_LOCAL,$1}
563 pat lae yields {ADDR_EXTERN,$1}
565 pat lpb leaving adp SL
567 pat lxl $1==0 yields {ADDR_LOCAL,0}
569 pat lxl $1==1 yields {LOCAL,SL,4}
572 uses ADDREG={indir_r_off,ebp,SSL} yields {indir_r_off,%a,SSL}
575 uses ADDREG={indir_r_off,ebp,SSL},
578 mov %a,{indir_r_off,%a,SSL}
579 loop {label,1b} yields %a
581 pat lxa $1==0 yields {ADDR_LOCAL,SL}
584 uses ADDREG={indir_r_off,ebp,SSL} yields {Xreg_off,%a,SSL}
587 uses ADDREG={indir_r_off,ebp,SSL}
588 gen move {indir_r_off,%a,SSL},%a yields {Xreg_off,%a,SSL}
591 uses ADDREG={indir_r_off,ebp,SSL},
594 mov %a,{indir_r_off,%a,SSL}
595 loop {label,1b} yields {Xreg_off,%a,SSL}
597 pat dch leaving loi 4
600 with addreg yields {indir_r2,%1}
601 with exact indexed_r_off yields {indir_indexed_r_off2, %1.reg, %1.reg2,
603 with exact indexed_off yields {indir_indexed_off2, %1.reg,
605 with exact reg_off yields {indir_r_off2,%1.reg,%1.off}
606 with exact ADDR_EXTERN yields {EXTERN2,%1.off}
607 with exact ADDR_LOCAL yields {LOCAL2,%1.ind,2}
610 with addreg yields {indir_r1,%1}
611 with exact indexed_r_off yields {indir_indexed_r_off1, %1.reg, %1.reg2,
613 with exact indexed_off yields {indir_indexed_off1, %1.reg,
615 with exact reg_off yields {indir_r_off1,%1.reg,%1.off}
616 with exact ADDR_EXTERN yields {EXTERN1,%1.off}
617 with exact ADDR_LOCAL yields {LOCAL1,%1.ind,1}
620 with addreg yields {indir_r,%1}
621 with exact indexed_r_off yields {indir_indexed_r_off, %1.reg, %1.reg2,
623 with exact indexed_off yields {indir_indexed_off, %1.reg,
625 with exact reg_off yields {indir_r_off,%1.reg,%1.off}
626 with exact ADDR_EXTERN yields {EXTERN,%1.off}
627 with exact ADDR_LOCAL yields {LOCAL,%1.ind,4}
630 with addreg yields {indir_r_off,%1,4}
632 with exact indexed_r_off yields {indir_indexed_r_off, %1.reg, %1.reg2,
634 {indir_indexed_r_off, %1.reg, %1.reg2,
636 with exact indexed_off yields {indir_indexed_off, %1.reg,
638 {indir_indexed_off, %1.reg,
640 with exact reg_off yields {indir_r_off,%1.reg,%1.off+4}
641 {indir_r_off,%1.reg,%1.off}
642 with exact ADDR_LOCAL yields {LOCAL,%1.ind+4,4}
644 with exact ADDR_EXTERN yields {EXTERN,%1.off + 4}
649 gen mov ecx,{ANYCON,$1}
650 proccall {label,".loi"}
655 gen proccall {label,".los"}
657 pat ldl yields {LOCAL,$1+4,4}
660 pat lde yields {EXTERN,$1+4}
664 with exact reg_off yields {indir_r_off,%1.reg,
668 with exact indexed_r_off yields {indir_indexed_r_off, %1.reg, %1.reg2,
669 %1.scale, %1.off+$1+4}
670 {indir_indexed_r_off, %1.reg, %1.reg2,
672 with exact indexed_off yields {indir_indexed_off, %1.reg,
673 %1.scale, %1.off+$1+4}
674 {indir_indexed_off, %1.reg,
676 with addreg yields {indir_r_off,%1,$1+4}
678 with exact ADDR_EXTERN yields {EXTERN,%1.off+4+$1}
680 with exact ADDR_LOCAL yields {LOCAL,%1.ind + $1 + 4,4}
681 {LOCAL,%1.ind + $1,4}
683 pat lpi yields {ADDR_EXTERN,$1}
685 /* this code sequence is generated by the C-compiler to tackle
686 char parameters, on the 80386 it reduces to nil */
688 pat lol lal sti $1==$2 && $3<=4
690 /*******************************************************************
691 * Group 2 : Store Instructions *
692 *******************************************************************/
695 pat stl inreg($1)==reg_any
698 gen move %1, {LOCAL,$1,4}
701 gen move %1, {LOCAL,$1,4}
704 gen pop {LOCAL, $1, 4}
708 kills indir,locals %ind+%size > $1 && %ind < $1+4
709 gen move %1,{LOCAL,$1,4}
712 gen pop {indir_r_off,ebp,$1}
717 gen move %1,{EXTERN,$1}
723 pat sil inreg($1)==reg_any
726 gen move %1,{indir_r,regvar($1)}
729 gen pop {indir_r,regvar($1)}
734 uses ADDREG={indir_r_off,ebp,$1}
735 gen move %1,{indir_r,%a}
739 uses ADDREG={indir_r_off,ebp,$1}
744 with addreg regorconst
746 gen move %2,{indir_r_off,%1,$1}
747 with exact addreg STACK
749 gen pop {indir_r_off, %1,$1}
750 with reg_off regorconst
752 gen move %2,{indir_r_off,%1.reg,%1.off+$1}
753 with exact reg_off STACK
754 gen pop {indir_r_off,%1.reg,$1+%1.off}
755 with indexed_r_off regorconst
757 gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
758 with exact indexed_r_off STACK
760 gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
761 with indexed_off regorconst
763 gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
764 with exact indexed_off STACK
766 gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
767 with ADDR_LOCAL regorconst
768 kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
769 gen move %2,{LOCAL,%1.ind+$1,4}
770 with exact ADDR_LOCAL STACK
771 kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
772 gen pop {LOCAL,%1.ind+$1,4}
773 with ADDR_EXTERN regorconst
775 gen move %2,{EXTERN,%1.off+$1}
776 with exact ADDR_EXTERN STACK
778 gen pop {EXTERN,%1.off+$1}
781 with addreg regorconst
783 gen move %2,{indir_r,%1}
784 with exact addreg STACK
787 with reg_off regorconst
789 gen move %2,{indir_r_off,%1.reg,%1.off}
790 with exact reg_off STACK
792 gen pop {indir_r_off,%1.reg,%1.off}
793 with indexed_r_off regorconst
795 gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
796 with exact indexed_r_off STACK
798 gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
799 with indexed_off regorconst
801 gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off}
802 with exact indexed_off STACK
804 gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off}
805 with ADDR_LOCAL regorconst
806 kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
807 gen move %2,{LOCAL,%1.ind,4}
808 with exact ADDR_LOCAL STACK
809 kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
810 gen pop {LOCAL,%1.ind,4}
811 with ADDR_EXTERN regorconst
813 gen move %2,{EXTERN,%1.off}
814 with exact ADDR_EXTERN STACK
816 gen pop {EXTERN,%1.off}
819 with addreg regorconst124
821 gen move %2,{indir_r1,%1}
822 with reg_off regorconst124
824 gen move %2,{indir_r_off1,%1.reg,%1.off}
825 with indexed_r_off regorconst124
827 gen move %2,{indir_indexed_r_off1,%1.reg,%1.reg2,%1.scale,%1.off}
828 with indexed_off regorconst124
830 gen move %2,{indir_indexed_off1,%1.reg,%1.scale,%1.off}
831 with ADDR_EXTERN regorconst124
833 gen move %2,{EXTERN1,%1.off}
834 with ADDR_LOCAL regorconst124
835 kills indir,locals %ind<%1.ind+1 && %ind+%size>%1.ind
836 gen move %2,{indir_r_off1,ebp,%1.ind}
839 with addreg regorconst24
841 gen move %2,{indir_r2,%1}
842 with reg_off regorconst24
844 gen move %2,{indir_r_off2,%1.reg,%1.off}
845 with indexed_r_off regorconst24
847 gen move %2,{indir_indexed_r_off2,%1.reg,%1.reg2,%1.scale,%1.off}
848 with indexed_off regorconst24
850 gen move %2,{indir_indexed_off2,%1.reg,%1.scale,%1.off}
851 with ADDR_EXTERN regorconst24
853 gen move %2,{EXTERN2,%1.off}
854 with ADDR_LOCAL regorconst24
855 kills indir,locals %ind<%1.ind+2 && %ind+%size>%1.ind
856 gen move %2,{indir_r_off2,ebp,%1.ind}
858 pat sti $1==8 leaving sdf 0
863 gen mov ecx,{ANYCON,$1}
864 proccall {label, ".sti"}
866 /* this sort of construction gives problems in the codegenerator
867 because of the potential very large lookahead
872 add %1,{ANYCON,2} yields %1 leaving sti $1-4
879 gen proccall {label,".sts"}
882 with regorconst regorconst yields %2 %1
883 leaving stl $1 stl $1+4
884 with exact STACK leaving stl $1 stl $1+4
887 with regorconst regorconst yields %2 %1
888 leaving ste $1 ste $1+4
889 with exact STACK leaving ste $1 ste $1+4
892 with addreg regorconst regorconst
894 gen move %2,{indir_r_off,%1,$1}
895 move %3,{indir_r_off,%1,$1+4}
896 with exact addreg STACK
898 gen pop {indir_r_off,%1,$1}
899 pop {indir_r_off,%1,$1+4}
900 with reg_off regorconst regorconst
902 gen move %2,{indir_r_off,%1.reg,%1.off+$1}
903 move %3,{indir_r_off,%1.reg,%1.off+$1+4}
904 with exact reg_off STACK
906 gen pop {indir_r_off,%1.reg,$1+%1.off}
907 pop {indir_r_off,%1.reg,$1+%1.off+4}
908 with indexed_r_off regorconst regorconst
910 gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
911 move %3,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
912 with exact indexed_r_off STACK
914 gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
915 pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
916 with indexed_off regorconst regorconst
918 gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
919 move %3,{indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
920 with exact indexed_off STACK
922 gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
923 pop {indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
924 with ADDR_LOCAL regorconst regorconst
925 kills indir,locals %ind+%size > $1 && %ind < $1+8
926 gen move %2,{LOCAL,%1.ind+$1,4}
927 move %3,{LOCAL,%1.ind+$1+4,4}
928 with exact ADDR_LOCAL STACK
929 kills indir,locals %ind+%size > $1 && %ind < $1+8
930 gen pop {LOCAL,%1.ind+$1,4}
931 pop {LOCAL,%1.ind+$1+4,4}
932 with ADDR_EXTERN regorconst regorconst
934 gen move %2,{EXTERN,%1.off+$1}
935 move %3,{EXTERN,%1.off+$1+4}
936 with exact ADDR_EXTERN STACK
938 gen pop {EXTERN,%1.off+$1}
939 pop {EXTERN,%1.off+$1+4}
942 /****************************************************************
943 * Group 3 : Integer Arithmetic. *
945 * Implemented (sometimes with the use of subroutines) : *
946 * 4 byte arithmetic. *
947 ****************************************************************/
951 with exact ANYCON RREG
952 yields {Rreg_off,%2,%1.val}
953 with exact RREG ANYCON
954 yields {Rreg_off,%1,%2.val}
957 gen add %1,%2 yields %1
959 gen add %2,%1 yields %2
960 with EXACT rmorconst const
961 uses reusing %1,REG=%1
962 gen add %a,%2 yields %a
968 gen proccall {label,".adi"} yields eax
974 gen sub %2,%1 yields %2
975 with EXACT REG rmorconst
983 gen proccall {label,".sbi"} yields eax
988 gen imul %2,%1 yields %2
990 gen imul %1,%2 yields %1
993 gen imul %a,%2,%1 yields %a
996 gen imul %a,%1,%2 yields %a
1002 gen proccall {label,".mli"}
1012 pat dvi !defined($1)
1015 gen proccall {label,".dvi"}
1025 pat rmi !defined($1)
1028 gen proccall {label,".rmi"}
1033 gen neg %1 yields %1
1036 pat ngi !defined($1)
1039 gen proccall {label,".ngi"}
1044 gen sal %2,%1 yields %2
1046 gen sal %2,cl yields %2
1049 pat sli !defined($1)
1052 gen proccall {label,".sli"}
1057 gen sar %2,cl yields %2
1059 gen sar %2,%1 yields %2
1062 pat sri !defined($1)
1065 gen proccall {label,".sri"}
1068 /*******************************************************************
1069 * Group 4: Unsigned Arithmetic *
1070 *******************************************************************/
1072 pat adu leaving adi $1
1073 pat loc lol adu stl $1==1 && $3==4 && $2==$4 leaving inl $2
1074 pat loc loe adu ste $1==1 && $3==4 && $2==$4 leaving ine $2
1075 pat loc lol adu $1==1 && $3==4 leaving lol $2 inc
1076 pat loc loe adu $1==1 && $3==4 leaving loe $2 inc
1077 pat loc lil adu $1==1 && $3==4 leaving lil $2 inc
1078 pat loc lol adu stl $1==0-1 && $3==4 && $2==$4 leaving del $2
1079 pat loc loe adu ste $1==0-1 && $3==4 && $2==$4 leaving dee $2
1080 pat loc lol adu $1==0-1 && $3==4 leaving lol $2 dec
1081 pat loc loe adu $1==0-1 && $3==4 leaving loe $2 dec
1082 pat loc lil adu $1==0-1 && $3==4 leaving lil $2 dec
1083 pat sbu leaving sbi $1
1084 pat lol loc sbu stl $1==$4 && $2==1 && $3==4 leaving del $1
1085 pat loe loc sbu ste $1==$4 && $2==1 && $3==4 leaving dee $1
1086 pat lol loc sbu $2==1 && $3==4 leaving lol $1 dec
1087 pat loe loc sbu $2==1 && $3==4 leaving loe $1 dec
1088 pat lil loc sbu $2==1 && $3==4 leaving lil $1 dec
1089 pat lol loc sbu stl $1==$4 && $2==0-1 && $3==4 leaving inl $1
1090 pat loe loc sbu ste $1==$4 && $2==0-1 && $3==4 leaving ine $1
1091 pat lol loc sbu $2==0-1 && $3==4 leaving lol $1 inc
1092 pat loe loc sbu $2==0-1 && $3==4 leaving loe $1 inc
1093 pat lil loc sbu $2==0-1 && $3==4 leaving lil $1 inc
1094 pat mlu leaving mli $1
1096 pat loe loc loe adu ste $1==$3 && $1==$5 && $4==4
1097 uses REG = {EXTERN, $1}
1098 yields %a leaving loc $2 loe $3 adu 4 ste $3
1100 pat lol loc lol adu stl $1==$3 && $1==$5 && $4==4
1101 uses REG = {LOCAL, $1, 4}
1102 yields %a leaving loc $2 lol $3 adu 4 stl $3
1104 pat loe loc loe adi ste $1==$3 && $1==$5 && $4==4
1105 uses REG = {EXTERN, $1}
1106 yields %a leaving loc $2 loe $3 adi 4 ste $3
1108 pat lol loc lol adi stl $1==$3 && $1==$5 && $4==4
1109 uses REG = {LOCAL, $1, 4}
1110 yields %a leaving loc $2 lol $3 adi 4 stl $3
1114 uses DXREG={ANYCON,0}
1115 gen div %1 yields eax
1118 pat dvu !defined($1)
1121 gen proccall {label,".dvu"}
1126 uses DXREG={ANYCON,0}
1127 gen div %1 yields edx
1130 pat rmu !defined($1)
1133 gen proccall {label,".rmu"}
1136 pat slu leaving sli $1
1137 pat loc slu leaving loc $1 sli $2
1141 gen shr %2,cl yields %2
1143 gen shr %2,%1 yields %2
1146 pat sru !defined($1)
1149 gen proccall {label,".sru"}
1152 /*******************************************************************
1153 * Group 5: Floating Point Instructions *
1154 *******************************************************************/
1156 pat adf $1==4 leaving cal ".adf4" asp 4
1157 pat adf $1==8 leaving cal ".adf8" asp 8
1158 pat sbf $1==4 leaving cal ".sbf4" asp 4
1159 pat sbf $1==8 leaving cal ".sbf8" asp 8
1160 pat mlf $1==4 leaving cal ".mlf4" asp 4
1161 pat mlf $1==8 leaving cal ".mlf8" asp 8
1162 pat dvf $1==4 leaving cal ".dvf4" asp 4
1163 pat dvf $1==8 leaving cal ".dvf8" asp 8
1164 pat ngf $1==4 leaving cal ".ngf4"
1165 pat ngf $1==8 leaving cal ".ngf8"
1166 pat fif $1==4 leaving lor 1 cal ".fif4" asp 4
1167 pat fif $1==8 leaving lor 1 cal ".fif8" asp 4
1168 pat fef $1==4 leaving lor 1 adp 0-4 cal ".fef4"
1169 pat fef $1==8 leaving lor 1 adp 0-4 cal ".fef8"
1171 /******************************************************************
1172 * Group 6: Pointer Arithmetic *
1173 ******************************************************************/
1176 with exact Xreg_off yields {Xreg_off,%1.reg,%1.off+$1}
1177 with exact Rreg_off yields {Rreg_off,%1.reg,%1.off+$1}
1178 with exact indexed_r_off
1179 yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
1180 with exact indexed_off yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
1181 with exact ADDR_EXTERN yields {ADDR_EXTERN,%1.off+$1}
1182 with exact ADDR_LOCAL yields {ADDR_LOCAL,%1.ind+$1}
1184 gen inc %1 yields %1
1187 yields {Xreg_off, %1, $1}
1188 with exact RREG yields {Rreg_off, %1, $1}
1191 with exact Xreg_off yields {Xreg_off,%1.reg,%1.off+$1}
1192 with exact Rreg_off yields {Rreg_off,%1.reg,%1.off+$1}
1193 with exact indexed_r_off
1194 yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
1195 with exact indexed_off yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
1196 with exact ADDR_EXTERN yields {ADDR_EXTERN,%1.off+$1}
1197 with exact ADDR_LOCAL yields {ADDR_LOCAL,%1.ind+$1}
1199 gen dec %1 yields %1
1202 yields {Xreg_off, %1, $1}
1203 with exact RREG yields {Rreg_off, %1, $1}
1206 with exact Xreg_off yields {Xreg_off,%1.reg,%1.off+$1}
1207 with exact Rreg_off yields {Rreg_off,%1.reg,%1.off+$1}
1208 with exact indexed_r_off
1209 yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
1210 with exact indexed_off yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
1211 with exact ADDR_EXTERN yields {ADDR_EXTERN,%1.off+$1}
1212 with exact ADDR_LOCAL yields {ADDR_LOCAL,%1.ind+$1}
1215 yields {Xreg_off,%1,$1}
1216 with exact RREG yields {Rreg_off, %1, $1}
1218 gen add %1,{ANYCON,$1} yields %1
1220 pat ads stl $1==4 leaving adi 4 stl $2
1221 pat ads ste $1==4 leaving adi 4 ste $2
1222 pat ads sil $1==4 leaving adi 4 sil $2
1223 pat ads lol stf $1==4 leaving adi 4 lol $2 stf $3
1224 pat ads loe stf $1==4 leaving adi 4 loe $2 stf $3
1227 with exact ANYCON Rreg_off
1228 yields {Rreg_off,%2.reg,%2.off+%1.val}
1229 with exact ANYCON Xreg_off
1230 yields {Xreg_off,%2.reg,%2.off+%1.val}
1231 with exact ANYCON indexed_r_off
1232 yields {indexed_r_off,%2.reg,%2.reg2,
1233 %2.scale,%2.off+%1.val}
1234 with exact ANYCON indexed_off
1235 yields {indexed_off,%2.reg,%2.scale,%2.off+%1.val}
1236 with exact ADDR_EXTERN Rreg_off
1237 yields {Rreg_off,%2.reg,%2.off+%1.off}
1238 with exact ADDR_EXTERN Xreg_off
1239 yields {Xreg_off,%2.reg,%2.off+%1.off}
1240 with exact ADDR_EXTERN indexed_r_off
1241 yields {indexed_r_off,%2.reg,%2.reg2,
1242 %2.scale,%2.off+%1.off}
1243 with exact ADDR_EXTERN indexed_off
1244 yields {indexed_off,%2.reg,%2.scale,%2.off+%1.off}
1245 with exact IREG reg_off
1246 yields {indexed_r_off,%2.reg,%1,1,%2.off}
1247 with exact reg_off IREG
1248 yields {indexed_r_off,%1.reg,%2,1,%1.off}
1249 with exact IREG ADDR_LOCAL
1250 yields {indexed_r_off,ebp,%1,1,%2.ind}
1251 with exact ADDR_LOCAL IREG
1252 yields {indexed_r_off,ebp,%2,1,%1.ind}
1253 with rmorconst Xreg_off
1254 gen add %2.reg,%1 yields %2
1255 with Xreg_off rmorconst
1256 gen add %1.reg,%2 yields %1
1257 with exact Xreg_off ANYCON
1258 yields {Xreg_off,%1.reg,%1.off+%2.val}
1259 with exact Rreg_off ANYCON
1260 yields {Rreg_off,%1.reg,%1.off+%2.val}
1261 with exact indexed_r_off ANYCON
1262 yields {indexed_r_off,%1.reg,%1.reg2,
1263 %1.scale,%1.off+%2.val}
1264 with exact indexed_off ANYCON
1265 yields {indexed_off,%1.reg,%1.scale,%1.off+%2.val}
1266 with exact Xreg_off ADDR_EXTERN
1267 yields {Xreg_off,%1.reg,%1.off+%2.off}
1268 with exact Rreg_off ADDR_EXTERN
1269 yields {Rreg_off,%1.reg,%1.off+%2.off}
1270 with exact indexed_r_off ADDR_EXTERN
1271 yields {indexed_r_off,%1.reg,%1.reg2,
1272 %1.scale,%1.off+%2.off}
1273 with exact indexed_off ADDR_EXTERN
1274 yields {indexed_off,%1.reg,%1.scale,%1.off+%2.off}
1275 with exact Xreg_off reg_off
1276 gen add %1.reg,%2.reg
1277 yields {Xreg_off,%1.reg,%1.off+%2.off}
1278 with exact RREG ADDR_EXTERN
1279 yields {Rreg_off, %1, %2.off}
1280 with exact ADDR_EXTERN RREG
1281 yields {Rreg_off,%2,%1.off}
1283 with exact rmorconst ADDR_EXTERN
1284 uses reusing %1,ADDREG=%1
1285 yields {Xreg_off,%a,%2.off}
1286 with exact ADDR_EXTERN rmorconst
1287 uses reusing %2,ADDREG=%2
1288 yields {Xreg_off,%a,%1.off}
1289 with rmorconst ADDREG
1290 gen add %2,%1 yields %2
1291 with ADDREG rmorconst
1292 gen add %1,%2 yields %1
1295 with exact ANYCON Xreg_off
1296 yields {Xreg_off,%2.reg,%2.off+"-"+%1.val}
1297 with exact ANYCON Rreg_off
1298 yields {Rreg_off,%2.reg,%2.off+"-"+%1.val}
1299 with exact ANYCON indexed_r_off
1300 yields {indexed_r_off,%2.reg,%2.reg2,%2.scale,
1302 with exact ANYCON indexed_off
1303 yields {indexed_off,%2.reg,%2.scale,%2.off+"-"+%1.val}
1304 with exact ANYCON ADDR_LOCAL
1305 yields {ADDR_LOCAL,%2.ind-%1.val}
1307 gen sub %2.reg,%1 yields {Xreg_off,%2.reg,%2.off}
1310 with exact reg_off ANYCON
1311 yields {reg_off,%1.reg,%1.off-%2.val}
1312 with ANYCON ADDR_EXTERN
1313 yields {ADDR_EXTERN,%2.off+%1.val}
1314 with exact ANYCON ADDR_LOCAL
1315 yields {ADDR_LOCAL,%1.val+%2.ind}
1319 gen sub %2,%1 yields %2
1321 gen sub %2,%1 yields %2
1323 /*******************************************************************
1324 * Group 7 : Increment/Decrement Zero *
1325 *******************************************************************/
1329 gen inc %1 yields %1
1332 pat inl inreg($1)==reg_any
1334 gen inc {LOCAL,$1,4}
1338 kills indir, locals %ind + %size>$1 && %ind<$1+4
1339 gen inc {LOCAL,$1,4}
1347 gen dec %1 yields %1
1350 pat del inreg($1)==reg_any
1352 gen dec {LOCAL,$1,4}
1356 kills indir, locals %ind+%size>$1 && %ind<$1+4
1357 gen dec {LOCAL, $1, 4}
1361 gen dec {EXTERN, $1}
1364 pat zrl inreg($1)==reg_any
1366 gen move {ANYCON, 0}, {LOCAL,$1,4}
1370 kills indir, locals %ind+%size>$1 && %ind<$1+4
1371 gen move {ANYCON, 0}, {LOCAL,$1,4}
1375 gen move {ANYCON, 0}, {EXTERN, $1}
1377 pat zrf leaving zer $1
1379 pat zer $1==4 yields {ANYCON, 0}
1380 pat zer $1==8 yields {ANYCON, 0} {ANYCON, 0}
1381 pat zer $1==12 yields {ANYCON, 0} {ANYCON, 0}
1383 pat zer $1==16 yields {ANYCON, 0} {ANYCON, 0}
1384 {ANYCON, 0} {ANYCON, 0}
1388 gen move {ANYCON, $1/4}, ecx
1389 move {ANYCON, 0}, ebx
1394 pat zer !defined($1)
1396 gen move {ANYCON, $1/4}, ebx
1403 proc lolrxxxstl example lol adi stl
1406 gen axx* {LOCAL, $1, 4}, %1
1408 proc lilrxxxsil example lil adi sil
1411 gen axx* {indir_r, regvar($1)}, %1
1413 proc xxxrstl example adi stl
1414 with rmorconst regorconst-RREG
1416 gen move %1, {LOCAL, $2, 4}
1417 axx* {LOCAL, $2, 4}, %2
1419 pat lol adi stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("add")
1420 pat lol adu stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("add")
1421 pat lol ads stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("add")
1422 pat lol and stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("and")
1423 pat lol ior stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("or")
1424 pat lol xor stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("xor")
1426 pat lil adi sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("add")
1427 pat lil adu sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("add")
1428 pat lil ads sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("add")
1429 pat lil and sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("and")
1430 pat lil ior sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("or")
1431 pat lil xor sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("xor")
1433 pat adi stl $1==4 && inreg($2)==reg_any call xxxrstl("add")
1434 pat adu stl $1==4 && inreg($2)==reg_any call xxxrstl("add")
1435 pat ads stl $1==4 && inreg($2)==reg_any call xxxrstl("add")
1436 pat and stl $1==4 && inreg($2)==reg_any call xxxrstl("and")
1437 pat ior stl $1==4 && inreg($2)==reg_any call xxxrstl("or")
1438 pat xor stl $1==4 && inreg($2)==reg_any call xxxrstl("xor")
1441 proc lolxxxstl example lol adi stl
1443 kills indir, locals %ind+%size>$1 && %ind<$1+4
1444 gen axx* {LOCAL, $1, 4}, %1
1446 pat lol adi stl $1==$3 && $2==4 call lolxxxstl("add")
1447 pat lol adu stl $1==$3 && $2==4 call lolxxxstl("add")
1448 pat lol ads stl $1==$3 && $2==4 call lolxxxstl("add")
1449 pat lol and stl $1==$3 && $2==4 call lolxxxstl("and")
1450 pat lol ior stl $1==$3 && $2==4 call lolxxxstl("or")
1451 pat lol xor stl $1==$3 && $2==4 call lolxxxstl("xor")
1453 proc lilxxxsil example lil adi sil
1456 uses ADDREG={LOCAL, $1, 4}
1457 gen axx* {indir_r, %a}, %1
1460 pat lil adi sil $1==$3 && $2==4 call lilxxxsil("add")
1461 pat lil adu sil $1==$3 && $2==4 call lilxxxsil("add")
1462 pat lil ads sil $1==$3 && $2==4 call lilxxxsil("add")
1463 pat lil and sil $1==$3 && $2==4 call lilxxxsil("and")
1464 pat lil ior sil $1==$3 && $2==4 call lilxxxsil("or")
1465 pat lil xor sil $1==$3 && $2==4 call lilxxxsil("xor")
1468 proc lilruxxsil example lil ngi sil
1470 gen uxx* {indir_r, regvar($1)}
1472 pat lil ngi sil $1==$3 && $2==4 && inreg($1)==reg_any call lilruxxsil("neg")
1473 pat lil com sil $1==$3 && $2==4 && inreg($1)==reg_any call lilruxxsil("not")
1474 pat lil dec sil $1==$3 && inreg($1)==reg_any call lilruxxsil("dec")
1475 pat lil inc sil $1==$3 && inreg($1)==reg_any call lilruxxsil("inc")
1476 pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==1 call lilruxxsil("inc")
1477 pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==(0-1)
1478 call lilruxxsil("dec")
1481 proc liluxxsil example lil ngi sil
1483 uses ADDREG={LOCAL, $1, 4}
1484 gen uxx* {indir_r, %a}
1487 pat lil ngi sil $1==$3 && $2==4 call liluxxsil("neg")
1488 pat lil com sil $1==$3 && $2==4 call liluxxsil("not")
1489 pat lil dec sil $1==$3 call liluxxsil("dec")
1490 pat lil inc sil $1==$3 call liluxxsil("inc")
1491 pat lil adp sil $1==$3 && $2==1 call liluxxsil("inc")
1492 pat lil adp sil $1==$3 && $2==(0-1) call liluxxsil("dec")
1494 proc loexxxste example loe adi ste
1497 gen axx* {EXTERN, $1}, %1
1499 pat loe adi ste $1==$3 && $2==4 call loexxxste("add")
1500 pat loe adu ste $1==$3 && $2==4 call loexxxste("add")
1501 pat loe ads ste $1==$3 && $2==4 call loexxxste("add")
1502 pat loe and ste $1==$3 && $2==4 call loexxxste("and")
1503 pat loe ior ste $1==$3 && $2==4 call loexxxste("or")
1504 pat loe xor ste $1==$3 && $2==4 call loexxxste("xor")
1507 proc lofrxxxsof example lol lof adi lol stf
1510 gen axx* {indir_r_off, regvar($1), $2}, %1
1512 pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1513 call lofrxxxsof("add")
1514 pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1515 call lofrxxxsof("add")
1516 pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1517 call lofrxxxsof("add")
1518 pat lol lof and lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1519 call lofrxxxsof("and")
1520 pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1521 call lofrxxxsof("or")
1522 pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1523 call lofrxxxsof("xor")
1525 proc lofruxxsof example lol lof inc lol stf
1527 gen uxx* {indir_r_off, regvar($1), $2}
1529 pat lol lof inc lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
1530 call lofruxxsof("inc")
1531 pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==1
1532 call lofruxxsof("inc")
1533 pat lol lof dec lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
1534 call lofruxxsof("dec")
1535 pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==(0-1)
1536 call lofruxxsof("dec")
1537 pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1538 call lofruxxsof("neg")
1539 pat lol lof com lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
1540 call lofruxxsof("not")
1542 pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
1544 uses ADDREG={indir_r_off, regvar($1), $2}
1545 gen add {indir_r_off, regvar($1), $2}, {ANYCON, $4} yields %a
1549 proc lofuxxsof example lol lof inc lol stf
1551 uses ADDREG={LOCAL,$1,4}
1552 gen uxx* {indir_r_off, %a, $2}
1555 pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4 call lofuxxsof("neg")
1556 pat lol lof com lol stf $1==$4 && $2==$5 && $3==4 call lofuxxsof("not")
1557 pat lol lof dec lol stf $1==$4 && $2==$5 call lofuxxsof("dec")
1558 pat lol lof inc lol stf $1==$4 && $2==$5 call lofuxxsof("inc")
1559 pat lol lof adp lol stf $1==$4 && $2==$5 && $3==1 call lofuxxsof("inc")
1560 pat lol lof adp lol stf $1==$4 && $2==$5 && $3==(0-1) call lofuxxsof("dec")
1562 proc lofxxxsof example lol lof adi lol stf
1565 uses ADDREG={LOCAL,$1,4}
1566 gen axx* {indir_r_off, %a, $2}, %1
1569 pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("add")
1570 pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("add")
1571 pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("add")
1572 pat lol lof and lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("and")
1573 pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("or")
1574 pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("xor")
1576 pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4
1578 uses ADDREG={LOCAL,$1,4},ADDREG
1579 gen mov %b, {indir_r_off, %a, $2}
1580 add {indir_r_off, %a, $2}, {ANYCON, $4}
1581 killreg %a yields %b
1583 proc lefuxxsef example loe lof inc loe stf
1585 uses ADDREG={EXTERN,$1}
1586 gen uxx* {indir_r_off, %a, $2}
1589 pat loe lof ngi loe stf $1==$4 && $2==$5 && $3==4 call lefuxxsef("neg")
1590 pat loe lof com loe stf $1==$4 && $2==$5 && $3==4 call lefuxxsef("not")
1591 pat loe lof dec loe stf $1==$4 && $2==$5 call lefuxxsef("dec")
1592 pat loe lof inc loe stf $1==$4 && $2==$5 call lefuxxsef("inc")
1593 pat loe lof adp loe stf $1==$4 && $2==$5 && $3==1 call lefuxxsef("inc")
1594 pat loe lof adp loe stf $1==$4 && $2==$5 && $3==(0-1) call lefuxxsef("dec")
1596 proc lefxxxsef example loe lof adi loe stf
1599 uses ADDREG={EXTERN,$1}
1600 gen axx* {indir_r_off, %a, $2}, %1
1603 pat loe lof adi loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("add")
1604 pat loe lof adu loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("add")
1605 pat loe lof ads loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("add")
1606 pat loe lof and loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("and")
1607 pat loe lof ior loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("or")
1608 pat loe lof xor loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("xor")
1610 pat loe lof dup adp loe stf $1==$5 && $2==$6 && $3==4
1612 uses ADDREG={EXTERN,$1},ADDREG
1613 gen mov %b, {indir_r_off, %a, $2}
1614 add {indir_r_off, %a, $2}, {ANYCON, $4}
1615 killreg %a yields %b
1617 proc leiuxxsei example loe loi inc loe sti
1619 uses ADDREG={EXTERN,$1}
1620 gen uxx* {indir_r, %a}
1623 pat loe loi ngi loe sti $1==$4 && $2==4 && $5==4 && $3==4
1624 call leiuxxsei("neg")
1625 pat loe loi com loe sti $1==$4 && $2==4 && $5==4 && $3==4
1626 call leiuxxsei("not")
1627 pat loe loi dec loe sti $1==$4 && $2==4 && $5==4
1628 call leiuxxsei("dec")
1629 pat loe loi inc loe sti $1==$4 && $2==4 && $5==4
1630 call leiuxxsei("inc")
1631 pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==1
1632 call leiuxxsei("inc")
1633 pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==(0-1)
1634 call leiuxxsei("dec")
1636 proc leixxxsei example loe loi adi loe sti
1639 uses ADDREG={EXTERN,$1}
1640 gen axx* {indir_r, %a}, %1
1643 pat loe loi adi loe sti $1==$4 && $2==4 && $5==4 && $3==4
1644 call leixxxsei("add")
1645 pat loe loi adu loe sti $1==$4 && $2==4 && $5==4 && $3==4
1646 call leixxxsei("add")
1647 pat loe loi ads loe sti $1==$4 && $2==4 && $5==4 && $3==4
1648 call leixxxsei("add")
1649 pat loe loi and loe sti $1==$4 && $2==4 && $5==4 && $3==4
1650 call leixxxsei("and")
1651 pat loe loi ior loe sti $1==$4 && $2==4 && $5==4 && $3==4
1652 call leixxxsei("or")
1653 pat loe loi xor loe sti $1==$4 && $2==4 && $5==4 && $3==4
1654 call leixxxsei("xor")
1657 proc lifuxxsif example lil lof inc lil stf
1659 uses ADDREG={indir_r,regvar($1)}
1660 gen uxx* {indir_r_off, %a, $2}
1663 pat lil lof ngi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1664 call lifuxxsif("neg")
1665 pat lil lof com lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1666 call lifuxxsif("not")
1667 pat lil lof dec lil stf $1==$4 && $2==$5 && inreg($1)>0
1668 call lifuxxsif("dec")
1669 pat lil lof inc lil stf $1==$4 && $2==$5 && inreg($1)>0
1670 call lifuxxsif("inc")
1672 proc lifxxxsif example lil lof adi lil stf
1675 uses ADDREG={indir_r,regvar($1)}
1676 gen axx* {indir_r_off, %a, $2}, %1
1679 pat lil lof adi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1680 call lifxxxsif("add")
1681 pat lil lof adu lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1682 call lifxxxsif("add")
1683 pat lil lof ads lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1684 call lifxxxsif("add")
1685 pat lil lof and lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1686 call lifxxxsif("and")
1687 pat lil lof ior lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1688 call lifxxxsif("or")
1689 pat lil lof xor lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
1690 call lifxxxsif("xor")
1692 proc liiuxxsii example lil loi inc lil sti
1694 uses ADDREG={indir_r,regvar($1)}
1695 gen uxx* {indir_r, %a}
1698 pat lil loi ngi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1699 call liiuxxsii("neg")
1700 pat lil loi com lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1701 call liiuxxsii("not")
1702 pat lil loi dec lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
1703 call liiuxxsii("dec")
1704 pat lil loi inc lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
1705 call liiuxxsii("inc")
1706 pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==1
1707 call liiuxxsii("inc")
1708 pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==(0-1)
1709 call liiuxxsii("dec")
1711 proc liixxxsii example lil loi adi lil sti
1714 uses ADDREG={indir_r,regvar($1)}
1715 gen axx* {indir_r, %a}, %1
1718 pat lil loi adi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1719 call liixxxsii("add")
1720 pat lil loi adu lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1721 call liixxxsii("add")
1722 pat lil loi ads lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1723 call liixxxsii("add")
1724 pat lil loi and lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1725 call liixxxsii("and")
1726 pat lil loi ior lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1727 call liixxxsii("or")
1728 pat lil loi xor lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
1729 call liixxxsii("xor")
1731 proc lolcrxxstl example lol loc sbi stl
1733 gen axx* {LOCAL,$1,4},{ANYCON,$2}
1735 pat lol loc sbi stl $1==$4 && $3==4 && inreg($1)==reg_any
1736 call lolcrxxstl("sub")
1737 pat lol loc sbu stl $1==$4 && $3==4 && inreg($1)==reg_any
1738 call lolcrxxstl("sub")
1739 pat lol loc sli stl $1==$4 && $3==4 && inreg($1)==reg_any
1740 call lolcrxxstl("sal")
1741 pat lol loc slu stl $1==$4 && $3==4 && inreg($1)==reg_any
1742 call lolcrxxstl("sal")
1743 pat lol loc sri stl $1==$4 && $3==4 && inreg($1)==reg_any
1744 call lolcrxxstl("sar")
1745 pat lol loc sru stl $1==$4 && $3==4 && inreg($1)==reg_any
1746 call lolcrxxstl("shr")
1749 proc lolcxxstl example lol loc sbi stl
1750 kills indir, locals %ind+%size>$1 && %ind<$1+4
1751 gen axx* {LOCAL,$1,4},{ANYCON,$2}
1753 pat lol loc sbi stl $1==$4 && $3==4 call lolcxxstl("sub")
1754 pat lol loc sbu stl $1==$4 && $3==4 call lolcxxstl("sub")
1755 pat lol loc adi stl $1==$4 && $3==4 call lolcxxstl("add")
1756 pat lol loc adi stl $1==$4 && $3==4 call lolcxxstl("add")
1757 pat lol loc sli stl $1==$4 && $3==4 call lolcxxstl("sal")
1758 pat lol loc slu stl $1==$4 && $3==4 call lolcxxstl("sal")
1759 pat lol loc sri stl $1==$4 && $3==4 call lolcxxstl("sar")
1760 pat lol loc sru stl $1==$4 && $3==4 call lolcxxstl("shr")
1762 proc loecxxste example loe loc sbi ste
1764 gen axx* {EXTERN,$1},{ANYCON,$2}
1766 pat loe loc sbi ste $1==$4 && $3==4 call loecxxste("sub")
1767 pat loe loc sbu ste $1==$4 && $3==4 call loecxxste("sub")
1768 pat loe loc adu ste $1==$4 && $3==4 call loecxxste("add")
1769 pat loe loc adi ste $1==$4 && $3==4 call loecxxste("add")
1770 pat loe loc sli ste $1==$4 && $3==4 call loecxxste("sal")
1771 pat loe loc slu ste $1==$4 && $3==4 call loecxxste("sal")
1772 pat loe loc sri ste $1==$4 && $3==4 call loecxxste("sar")
1773 pat loe loc sru ste $1==$4 && $3==4 call loecxxste("shr")
1776 proc lilcxxsil example lil loc sbi sil
1778 gen axx* {indir_r,regvar($1)},{ANYCON,$2}
1780 pat lil loc sbi sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sub")
1781 pat lil loc sbu sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sub")
1782 pat lil loc adu sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("add")
1783 pat lil loc adi sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("add")
1784 pat lil loc sli sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sal")
1785 pat lil loc slu sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sal")
1786 pat lil loc sri sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sar")
1787 pat lil loc sru sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("shr")
1789 pat lol ngi stl $1==$3 && $2==4 && inreg($1)==reg_any
1791 gen neg {LOCAL, $1, 4}
1794 pat lol ngi stl $1==$3 && $2==4
1795 kills indir, locals %ind+%size>$1 && %ind<$1+4
1796 gen neg {LOCAL, $1, 4}
1798 pat lol dup adp stl loi stl $1==$4 && $2==4 && $5<=4
1799 leaving lol $1 loi $5 stl $6 lol $1 adp $3 stl $4
1802 pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==1 && inreg($1) > 0 && $6==1 && $7==4
1804 gen movsxb %a,{indir_r1, regvar($1)}
1806 leaving lol $1 adp $3 stl $4
1808 pat lol dup adp stl loi $1==$4 && $2==4 && $5==1 && inreg($1) > 0
1809 uses REG1 = {indir_r1, regvar($1)}
1811 leaving lol $1 adp $3 stl $4
1813 pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==2 && inreg($1) > 0 && $6==2 && $7==4
1815 gen movsx %a,{indir_r2, regvar($1)}
1817 leaving lol $1 adp $3 stl $4
1819 pat lol dup adp stl loi $1==$4 && $2==4 && $5==2 && inreg($1) > 0
1820 uses REG2 = {indir_r2, regvar($1)}
1822 leaving lol $4 adp $3 stl $4
1824 pat lol dup adp stl loi $1==$4 && $2==4 && $5==4 && inreg($1) > 0
1825 uses REG = {indir_r, regvar($1)}
1827 leaving lol $4 adp $3 stl $4
1828 pat adp stl inreg($2) > 0 leaving stl $2 lol $2 adp $1 stl $2
1831 pat lol dup adp stl $1==$4 && $2==4
1832 uses ADDREG={LOCAL,$1,4} yields %a
1833 leaving lol $4 adp $3 stl $4
1836 uses REG={LOCAL,$1,4} yields %a
1840 uses REG={LOCAL,$1,4} yields %a
1843 pat lol adp stl $1==$3 && $2==1 leaving inl $1
1844 pat lol adp stl $1==$3 && $2==0-1 leaving del $1
1845 pat lol adp stl $1==$3 leaving loc $2 lol $1 adi 4 stl $3
1848 pat lol com stl $1==$3 && $2==4 && inreg($1)==reg_any
1850 gen not {LOCAL,$1,4}
1853 pat lol com stl $1==$3 && $2==4
1854 kills indir, locals %ind+%size>$1 && %ind<$1+4
1855 gen not {LOCAL, $1, 4}
1858 pat lil dup adp sil $1==$4 && $2==4 && inreg($1)==reg_any
1859 uses ADDREG={indir_r, regvar($1)}
1861 leaving lil $4 adp $3 sil $4
1863 pat lil dup inc sil $1==$4 && $2==4 && inreg($1)==reg_any
1864 uses REG={indir_r, regvar($1)}
1866 leaving lil $4 inc sil $4
1868 pat lil dup dec sil $1==$4 && $2==4 && inreg($1)==reg_any
1869 uses REG={indir_r, regvar($1)}
1871 leaving lil $4 dec sil $4
1874 pat lil adp sil $1==$3 && $2==1 leaving lil $1 inc sil $1
1876 pat lil adp sil $1==$3 && $2==0-1 leaving lil $1 dec sil $1
1878 pat lil adp sil $1==$3 leaving loc $2 lil $1 adi 4 sil $3
1881 pat lol lof lol lof adp lol stf
1882 $1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
1883 uses ADDREG={indir_r_off, regvar($1), $2}
1885 leaving lol $1 lof $2 adp $5 lol $6 stf $7
1887 pat lol lof lol lof inc lol stf
1888 $1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
1889 uses REG={indir_r_off, regvar($1), $2}
1891 leaving lol $1 lof $2 inc lol $6 stf $7
1893 pat lol lof lol lof dec lol stf
1894 $1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
1895 uses REG={indir_r_off, regvar($1), $2}
1897 leaving lol $1 lof $2 dec lol $6 stf $7
1899 pat lol lof dup adp lol stf
1900 $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
1901 uses REG={indir_r_off, regvar($1), $2}
1903 leaving lol $1 lof $2 adp $4 lol $1 stf
1906 pat lol lof dup inc lol stf
1907 $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
1908 uses REG={indir_r_off, regvar($1), $2}
1910 leaving lol $1 lof $2 inc lol $1 stf $2
1912 pat lol lof dup dec lol stf
1913 $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
1914 uses REG={indir_r_off, regvar($1), $2}
1916 leaving lol $1 lof $2 dec lol $1 stf $2
1920 pat lol lof adp lol stf $1==$4 && $2==$5
1921 leaving loc $3 lol $1 lof $2 adi 4 lol $4 stf $5
1923 pat lol lof dup adp lol stf
1924 $1==$5 && $2==$6 && $3==4 && $4==1
1926 uses REG={LOCAL,$1,4}, REG
1927 gen move {indir_r_off, %a, $2},%b
1928 inc {indir_r_off, %a, $2}
1931 pat loe lof dup adp loe stf
1932 $1==$5 && $2==$6 && $3==4 && $4==1
1934 uses REG={EXTERN,$1}, REG
1935 gen move {indir_r_off, %a, $2},%b
1936 inc {indir_r_off, %a, $2}
1939 pat loe loi dup adp loe sti
1940 $1==$5 && $2==$6 && $3==4 && $2==4 && $4==1
1942 uses REG={EXTERN,$1}, REG
1943 gen move {indir_r, %a},%b
1947 pat lol lof dup adp lol stf
1948 $1==$5 && $2==$6 && $3==4 && $4==(0-1)
1950 uses REG={LOCAL,$1,4}, REG
1951 gen move {indir_r_off, %a, $2},%b
1952 dec {indir_r_off, %a, $2}
1955 pat loe lof dup adp loe stf
1956 $1==$5 && $2==$6 && $3==4 && $4==(0-1)
1958 uses REG={EXTERN,$1}, REG
1959 gen move {indir_r_off, %a, $2},%b
1960 dec {indir_r_off, %a, $2}
1962 pat loe loi dup adp loe sti
1963 $1==$5 && $2==$6 && $3==4 && $2==4 && $4==(0-1)
1965 uses REG={EXTERN,$1}, REG
1966 gen move {indir_r, %a},%b
1970 pat lol lof dup adp lol stf
1971 $1==$5 && $2==$6 && $3==4
1973 uses REG={LOCAL,$1,4}, REG
1974 gen move {indir_r_off, %a, $2},%b
1975 add {indir_r_off, %a, $2}, {ANYCON, $4}
1978 pat loe lof dup adp loe stf
1979 $1==$5 && $2==$6 && $3==4
1981 uses REG={EXTERN,$1}, REG
1982 gen move {indir_r_off, %a, $2},%b
1983 add {indir_r_off, %a, $2}, {ANYCON, $4}
1986 pat loe loi dup adp loe sti
1987 $1==$5 && $2==$6 && $3==4 && $2==4
1989 uses REG={EXTERN,$1}, REG
1990 gen move {indir_r, %a},%b
1991 add {indir_r, %a}, {ANYCON, $4}
1995 pat loe ngi ste $1==$3 && $2==4
1997 gen neg {EXTERN, $1}
1999 pat loe dup adp ste $1==$4 && $2==4
2000 uses REG={EXTERN,$1} yields %a
2001 leaving loe $1 adp $3 ste $1
2004 uses REG={EXTERN,$1} yields %a
2008 uses REG={EXTERN,$1} yields %a
2011 pat loe adp ste $1==$3 && $2==1 leaving ine $1
2013 pat loe adp ste $1==$3 && $2==0-1 leaving dee $1
2015 pat loe adp ste $1==$3 leaving loc $2 loe $1 adi 4 ste $3
2017 pat loe com ste $1==$3 && $2==4
2019 gen not {EXTERN, $1}
2021 pat loe lof adp loe stf $1==$4 && $2==$5
2022 leaving loc $3 loe $1 lof $2 adi 4 loe $1 stf $2
2024 pat loe loi adp loe sti $1==$4 && $2==$5 && $2==4
2025 leaving loc $3 loe $1 loi $2 adi 4 loe $1 sti $2
2027 pat lil lof adp lil stf $1==$4 && $2==$5 && $3==1
2028 leaving lil $1 lof $2 inc lil $1 stf $2
2029 pat lil lof adp lil stf $1==$4 && $2==$5 && $3==0-1
2030 leaving lil $1 lof $2 dec lil $1 stf $2
2031 pat lil lof adp lil stf $1==$4 && $2==$5
2032 leaving loc $3 lil $1 lof $2 adi 4 lil $1 stf $2
2033 pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==1
2034 leaving lil $1 loi $2 inc lil $1 sti $2
2035 pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==0-1
2036 leaving lil $1 loi $2 dec lil $1 sti $2
2037 pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4
2038 leaving loc $3 lil $1 loi $2 adi 4 lil $1 sti $2
2040 /*******************************************************************
2041 * Group 8: Convert Instructions *
2042 *******************************************************************/
2045 with CXREG DXREG ACC
2047 gen proccall {label,".cii"} yields %3
2054 pat loc loc cii zeq $1==1
2059 pat loc loc cii zne $1==1
2064 pat loc loc cii loc and zeq $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
2065 leaving loc $4 and $5 zeq $6
2066 pat loc loc cii loc and zne $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
2067 leaving loc $4 and $5 zne $6
2068 pat loc loc cii loc and zeq $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
2069 leaving loc $4 and $5 zeq $6
2070 pat loc loc cii loc and zne $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
2071 leaving loc $4 and $5 zne $6
2073 pat loc loc cii $1==1 && $2==4
2075 gen movsxb %1,%1 yields eax
2077 uses reusing %1, GENREG
2078 gen movsxb %a,%1 yields %a
2080 pat loc loc cii $1==2 && $2==4
2082 gen movsx %1,%1 yields eax
2084 uses reusing %1,GENREG
2085 gen movsx %a,%1 yields %a
2087 pat loc loc ciu leaving loc $1 loc $2 cuu
2088 pat loc loc cui leaving loc $1 loc $2 cuu
2090 pat loc loc cuu $1==$2
2092 pat loc loc cif $1==4 && $2==4 leaving loc 4 cal ".cif4" asp 4
2093 pat loc loc cif $1==4 && $2==8 leaving loc 4 cal ".cif8"
2094 pat loc loc cuf $1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 4
2095 pat loc loc cuf $1==4 && $2==8 leaving loc 4 cal ".cuf8"
2096 pat loc loc cfi leaving loc $1 loc $2 cal ".cfi" asp 8+($1-4)
2097 pat loc loc cfu leaving loc $1 loc $2 cal ".cfu" asp 8+($1-4)
2098 pat loc loc cff $1==8 && $2==4 leaving cal ".cff4" asp 4
2099 pat loc loc cff $1==4 && $2==8
2103 push %1 leaving cal ".cff8"
2105 /********************************************************************
2106 * Group 9 : Logical Instructions *
2107 ********************************************************************/
2111 gen and %1,%2 yields %1
2113 gen and %2,%1 yields %2
2115 pat loc and $1==255 && $2==4
2116 with GENREG yields %1.1
2119 with EXACT REG REG rmorconst rmorconst
2121 and %2,%4 yields %2 %1
2122 with rmorconst rmorconst REG REG
2124 and %4,%2 yields %4 %3
2128 gen mov ecx,{ANYCON,$1}
2129 proccall {label, ".and"}
2131 pat and !defined($1)
2134 gen proccall {label, ".and"}
2138 gen or %1,%2 yields %1
2140 gen or %2,%1 yields %2
2143 with EXACT REG REG rmorconst rmorconst
2145 or %2,%4 yields %2 %1
2146 with rmorconst rmorconst REG REG
2148 or %4,%2 yields %4 %3
2152 gen mov ecx,{ANYCON,$1}
2153 proccall {label, ".ior"}
2155 pat ior !defined($1)
2158 gen proccall {label, ".ior"}
2162 gen xor %1,%2 yields %1
2164 gen xor %2,%1 yields %2
2167 with EXACT REG REG rmorconst rmorconst
2169 xor %2,%4 yields %2 %1
2170 with rmorconst rmorconst REG REG
2172 xor %4,%2 yields %4 %3
2176 gen mov ecx,{ANYCON,$1}
2177 proccall {label, ".xor"}
2179 pat xor !defined($1)
2182 gen proccall {label, ".xor"}
2186 gen not %1 yields %1
2195 gen mov ecx,{ANYCON,$1}
2196 proccall {label, ".com"}
2198 pat com !defined($1)
2201 gen proccall {label, ".com"}
2205 gen rol %2,cl yields %2
2207 gen rol %2,%1 yields %2
2211 gen ror %2,cl yields %2
2213 gen ror %2,%1 yields %2
2215 /*******************************************************************
2216 * Group 10 : Set Instructions *
2217 *******************************************************************/
2222 and %2,{ANYCON, 1} yields %2
2225 and %2,{ANYCON, 1} yields %2
2227 pat loc inn $1==0 && $2==4
2229 gen and %1,{ANYCON, 1} yields %1
2234 gen mov ecx,{ANYCON, $1}
2235 proccall {label,".inn"} yields eax
2237 pat inn !defined($1)
2240 gen proccall {label,".inn"} yields eax
2242 pat loc inn zeq $2==4
2244 gen check %1,{ANYCON,1<<$1}
2247 pat loc inn zne $2==4
2249 gen check %1,{ANYCON,1<<$1}
2254 uses REG={ANYCON, 1}
2255 gen shl %a,cl yields %a
2260 gen mov ecx,{ANYCON, $1}
2261 proccall {label,".set"}
2263 pat set !defined($1)
2266 gen proccall {label,".set"}
2268 /********************************************************************
2269 * Group 11 : Array Instructions *
2270 ********************************************************************/
2272 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0
2275 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
2276 leaving adp 0-rom($1,1) ads 4
2278 pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)==0
2279 leaving loc 1 sli 4 ads 4
2281 pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)!=0
2282 leaving adp 0-rom($1,1) loc 1 sli 4 ads 4
2284 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
2285 leaving loc 2 sli 4 ads 4
2287 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
2288 leaving adp 0-rom($1,1) loc 2 sli 4 ads 4
2290 pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)==0
2291 leaving loc 3 sli 4 ads 4
2293 pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)!=0
2294 leaving adp 0-rom($1,1) loc 3 sli 4 ads 4
2296 pat lae aar $2==4 && rom($1,1)==0
2298 gen imul %1,%1,{ANYCON,rom($1,3)} yields %1 leaving ads 4
2300 pat lae aar $2==4 && defined(rom($1,1))
2302 gen imul %1,%1,{ANYCON,rom($1,3)} yields %1
2303 leaving adp 0-rom($1,1)*rom($1,3) ads 4
2305 /* when followed by an LOI or STI instruction, use indexed mode */
2306 pat loc sli ads loi ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
2307 with IREG ADDR_LOCAL yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
2309 with IREG ADDR_EXTERN yields {indexed_off,%1,1<<$1,%2.off}
2311 with IREG ADDREG yields {indexed_r_off,%2,%1,1<<$1,0}
2314 pat loc sli ads sti ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
2315 with IREG ADDR_LOCAL yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
2317 with IREG ADDR_EXTERN yields {indexed_off,%1,1<<$1,%2.off}
2319 with IREG ADDREG yields {indexed_r_off,%2,%1,1<<$1,0}
2322 pat loc sli ads ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
2323 with IREG ADDR_LOCAL yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
2324 with IREG ADDR_EXTERN yields {indexed_off,%1,1<<$1,%2.off}
2325 with IREG ADDREG yields {indexed_r_off,%2,%1,1<<$1,0}
2327 gen sal %1,{ANYCON,$1} yields %2 %1 leaving ads 4
2331 gen sub %2,{indir_r,%1}
2332 imul %2,{indir_r_off,%1,8} yields %2 leaving ads 4
2334 gen sub %2,{indir_r_off, %1.reg, %1.off}
2335 imul %2,{indir_r_off, %1.reg, 8+%1.off}
2336 yields %2 leaving ads 4
2338 gen sub %2,{LOCAL,%1.ind,4}
2339 imul %2,{LOCAL,8+%1.ind,4} yields %2 leaving ads 4
2340 with ADDR_EXTERN REG
2341 gen sub %2,{EXTERN,%1.off}
2342 imul %2,{EXTERN,8+%1.off} yields %2 leaving ads 4
2344 pat lae lar defined(rom($1,3)) leaving lae $1 aar $2 loi rom($1,3)
2346 pat lae sar defined(rom($1,3)) leaving lae $1 aar $2 sti rom($1,3)
2348 pat aar !defined($1)
2350 gen proccall {label,".iaar"} yields ebx
2355 gen proccall {label,".sar4"}
2357 pat sar !defined($1)
2359 gen proccall {label,".isar"}
2364 gen proccall {label,".lar4"}
2366 pat lar !defined($1)
2368 gen proccall {label,".ilar"}
2370 /*******************************************************************
2371 * Group 12 : Compare Instructions *
2372 *******************************************************************/
2375 with register rmorconst
2385 with rmorconst register
2396 pat cmu $1==4 leaving cmp
2400 gen sub %1,%2 yields %1
2402 gen sub %2,%1 yields %2
2405 with rmorconst rmorconst REG REG
2409 with REG REG rmorconst rmorconst
2416 gen mov ecx,{ANYCON,$1}
2417 proccall {label,".cms"} yields ecx
2419 pat cms !defined($1)
2422 gen proccall {label,".cms"} yields ecx
2426 gen proccall {label,".cmf4"} leaving asp 8 lfr 4
2430 gen proccall {label,".cmf8"} leaving asp 16 lfr 4
2433 with register rmorconst
2434 uses REG = {ANYCON,0}
2442 with rmorconst register
2443 uses REG = {ANYCON,0}
2454 uses GENREG = {ANYCON,0}
2456 setxx* %a.1 yields %a
2458 pat tlt call txx("sets")
2459 pat teq call txx("sete")
2460 pat tne call txx("setne")
2461 pat tge call txx("setns")
2463 /* Explicit test for TLE and TGT. We must make sure that the OC
2468 uses GENREG = {ANYCON,0}
2477 uses GENREG = {ANYCON,0}
2491 pat tlt ior $2==4 call txxior("jge")
2492 pat tle ior $2==4 call txxior("jg")
2493 pat teq ior $2==4 call txxior("jne")
2494 pat tne ior $2==4 call txxior("je")
2495 pat tge ior $2==4 call txxior("jl")
2496 pat tgt ior $2==4 call txxior("jle")
2499 with regorconst rm REG
2505 pat cmi tlt ior $1==4 && $3==4 call cmixxior("jge")
2506 pat cmi tle ior $1==4 && $3==4 call cmixxior("jg")
2507 pat cmi teq ior $1==4 && $3==4 call cmixxior("jne")
2508 pat cmi tne ior $1==4 && $3==4 call cmixxior("je")
2509 pat cmi tge ior $1==4 && $3==4 call cmixxior("jl")
2510 pat cmi tgt ior $1==4 && $3==4 call cmixxior("jle")
2514 uses REG = {ANYCON,0}
2520 uses REG = {ANYCON,0}
2526 pat cmi tlt $1==4 call cmxtxx("jge","jle")
2527 pat cmi tle $1==4 call cmxtxx("jg","jl")
2528 pat cmi teq $1==4 call cmxtxx("jne","jne")
2529 pat cmi tne $1==4 call cmxtxx("je","je")
2530 pat cmi tge $1==4 call cmxtxx("jl","jg")
2531 pat cmi tgt $1==4 call cmxtxx("jle","jge")
2532 pat cmp tlt call cmxtxx("jae","jbe")
2533 pat cmp tle call cmxtxx("ja","jb")
2534 pat cmp teq call cmxtxx("jne","jne")
2535 pat cmp tne call cmxtxx("je","je")
2536 pat cmp tge call cmxtxx("jb","ja")
2537 pat cmp tgt call cmxtxx("jbe","jae")
2538 pat cms teq $1==4 call cmxtxx("jne","jne")
2539 pat cms tne $1==4 call cmxtxx("je","je")
2541 proc cmxzxx example cmp zlt
2542 with regorconst rm STACK
2545 with rm regorconst STACK
2549 pat cmp zlt call cmxzxx("jb","ja")
2550 pat cmp zle call cmxzxx("jbe","jae")
2551 pat cmp zeq call cmxzxx("je","je")
2552 pat cmp zne call cmxzxx("jne","jne")
2553 pat cmp zge call cmxzxx("jae","jbe")
2554 pat cmp zgt call cmxzxx("ja","jb")
2555 pat cms zeq $1==4 call cmxzxx("je","je")
2556 pat cms zne $1==4 call cmxzxx("jne","jne")
2559 with regorconst regorconst rm rm STACK
2564 with rm rm regorconst regorconst STACK
2572 with regorconst regorconst rm rm STACK
2578 with rm rm regorconst regorconst STACK
2586 proc andzxx example and zeq
2587 with regorconst rm STACK
2590 with exact rm regorconst
2595 pat and zeq $1==4 call andzxx("je")
2596 pat and zne $1==4 call andzxx("jne")
2598 proc locandzxx example loc and zeq
2600 gen testb %1,{ANYCON,$1}
2603 gen testb %1.1,{ANYCON,$1}
2607 gen check %1,{ANYCON,$1}
2610 pat loc and zeq $1<256 && $1>=0 && $2==4 call locandzxx("je")
2611 pat loc and zne $1<256 && $1>=0 && $2==4 call locandzxx("jne")
2613 proc locbxx example loc beq
2615 gen cmpb %1,{ANYCON,$1}
2618 gen cmp %1,{ANYCON,$1}
2621 pat loc beq $1<256 && $1>=0 call locbxx("je")
2622 pat loc bne $1<256 && $1>=0 call locbxx("jne")
2624 proc loccmuzxx example loc cmu zeq
2626 gen cmpb %1,{ANYCON,$1}
2629 gen cmp %1,{ANYCON,$1}
2632 pat loc cmu zeq $1<256 && $1>=0 && $2==4 call loccmuzxx("je")
2633 pat loc cmu zne $1<256 && $1>=0 && $2==4 call loccmuzxx("jne")
2635 /*******************************************************************
2636 * Group 13 : Branch Instructions *
2637 *******************************************************************/
2639 pat lab topeltsize($1)==4 && !fallthrough($1)
2642 gen labeldef $1 yields eax
2644 pat lab topeltsize($1)==4 && fallthrough($1)
2647 gen labeldef $1 yields eax
2649 pat lab topeltsize($1)!=4
2654 pat bra topeltsize($1)==4
2658 pat bra topeltsize($1)!=4
2662 proc bxx example blt
2663 with regorconst rm STACK
2666 with rm regorconst STACK
2670 pat blt call bxx("jl","jg")
2671 pat ble call bxx("jle","jge")
2672 pat beq call bxx("je","je")
2673 pat bne call bxx("jne","jne")
2674 pat bge call bxx("jge","jle")
2675 pat bgt call bxx("jg","jl")
2677 proc zxx example zlt
2682 pat zlt call zxx("js")
2683 pat zge call zxx("jns")
2685 /* Explicit test for ZLE and ZGT. We must make sure that the OC
2712 /*******************************************************************
2713 * Group 14 : Procedure-call Instructions *
2714 *******************************************************************/
2718 gen proccall {label,$1}
2726 pat lfr adi stl $1==4 && $2==4 && inreg($3) > 0
2728 gen pop {LOCAL,$3,4}
2729 add {LOCAL,$3,4}, eax
2732 pat lfr $1==4 yields eax
2734 pat lfr $1==8 yields edx eax
2768 /********************************************************************
2769 * Group 15 : Miscellaneous Instructions *
2770 ********************************************************************/
2775 uses CXREG /* GENREG may contain lfr area */
2779 with exact a_word a_word
2781 uses CXREG /* GENREG may contain lfr area */
2786 with STACK yields ebp
2790 gen add esp,{ANYCON,$1}
2793 with rmorconst STACK
2796 pat ass !defined($1)
2797 with rm rmorconst STACK
2798 gen cmp %1,{ANYCON,4}
2799 jne {label, ".unknown"}
2802 pat blm $1==0 leaving asp 4
2806 gen mov ecx,{ANYCON,$1/4}
2807 proccall {label, ".blm"}
2812 gen sar ecx,{ANYCON,2}
2813 proccall {label, ".blm"}
2815 pat bls !defined($1)
2818 gen cmp %1,{ANYCON,4}
2819 jne {label, ".unknown"}
2821 proccall {label, ".blm"}
2826 gen jmp {label, ".csa4"}
2828 pat csa !defined($1)
2829 with rm-BXREG-ACC BXREG ACC
2831 gen cmp %1,{ANYCON,4}
2832 jne {label, ".unknown"}
2833 jmp {label, ".csa4"}
2838 gen jmp {label, ".csb4"}
2840 pat csb !defined($1)
2841 with rm-BXREG-ACC BXREG ACC
2842 gen cmp %1,{ANYCON,4}
2843 jne {label, ".unknown"}
2844 jmp {label, ".csb4"}
2847 with anyreg yields %1 %1
2848 with ACC1 yields %1 %1
2851 with regorconst regorconst yields %2 %1 %2 %1
2855 gen mov ecx,{ANYCON,$1}
2856 proccall {label, ".dup"}
2861 gen proccall {label, ".dup"}
2863 pat dus !defined($1)
2866 gen cmp %1,{ANYCON,4}
2867 jne {label, ".unknown"}
2868 proccall {label, ".dup"}
2871 with a_word a_word yields %1 %2
2874 with a_word a_word a_word a_word yields %2 %1 %4 %3
2878 gen mov ecx,{ANYCON,$1}
2879 proccall {label, ".exg"}
2884 gen proccall {label, ".exg"}
2888 gen mov ebx,{ADDR_EXTERN,$1}
2892 gen mov {EXTERN,"hol0+4"},{ADDR_EXTERN,$1}
2896 gen mov %a,{EXTERN,".ignmask"} yields %a
2899 gen mov {EXTERN,"hol0"},{ANYCON,$1}
2902 gen inc {EXTERN,"hol0"}
2904 pat lor $1==0 yields ebp
2909 gen mov %a,esp yields %a
2913 gen mov %a,{EXTERN,".reghp"} yields %a
2918 gen proccall {label, ".mon"}
2923 gen proccall {label, ".nop"}
2929 gen proccall {label, ".rck"} yields eax
2931 pat rck !defined($1)
2932 with rm-BXREG-ACC BXREG ACC
2934 gen cmp %1,{ANYCON,4}
2935 jne {label, ".unknown"}
2936 proccall {label, ".rck"} yields eax
2938 pat rtt leaving ret 0
2942 gen xchg {EXTERN,".trppc"},%1 yields %1
2946 gen mov {EXTERN,".ignmask"},%1
2953 with rmorconst STACK
2958 gen proccall {label, ".strhp"}
2963 gen proccall {label, ".Xtrp"}