12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963 |
- /*
- * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- rscid = "$Id$"
- /*
- * Back end tables for Intel 80386
- *
- * Author : Ceriel J.H. Jacobs
- *
- * Partly adapted from Intel 8086 table
- *
- * wordsize = 4 bytes, pointersize = 4 bytes.
- *
- * Register ebp is used as LB, esp is used for SP.
- * Some global variables are used:
- * - .reghp : the heap pointer
- * - .ignmask : trap ignore mask
- * - .trppc : address of user defined trap handler
- *
- */
- #define WS 4
- #define PS 4
- SL = 8
- SSL = "8"
- EM_WSIZE = WS
- EM_PSIZE = PS
- EM_BSIZE = 8
- SIZEFACTOR = 5/1
- #define REGVARS
- #define EXACT exact /* to improve code but slow down code generator,
- define it to nothing
- */
- /*****************************************************************/
- PROPERTIES
- /*****************************************************************/
- REG1 /* general 1 byte register */
- REG2 /* general 2 byte register */
- ACC1 /* 1 byte accumulator */
- ACC2 /* 2 byte accumulator */
- REG /* allocatable register */
- GENREG /* register with sub-registers */
- ACC /* accumulator */
- SHIFT_CREG /* shift count register */
- BXREG /* ebx register */
- AREG /* address register */
- ADDREG /* allocatable address register */
- CXREG /* ecx register */
- DXREG /* edx register */
- IREG /* index register */
- RREG /* register variable, or register without subregs */
- /*****************************************************************/
- REGISTERS
- /*****************************************************************/
- al : REG1 , ACC1 .
- ah,bl, bh, ch,dl,dh : REG1 .
- cl : REG1 , SHIFT_CREG .
- ax = al + ah : REG2 , ACC2 .
- bx = bl + bh : REG2 .
- cx = cl + ch : REG2 .
- dx = dl + dh : REG2 .
- eax = al + ah : REG, GENREG, IREG, ACC, ADDREG, AREG.
- ebx = bl + bh : REG, GENREG, IREG, BXREG, ADDREG, AREG.
- ecx = cl + ch : REG, GENREG, IREG, CXREG, SHIFT_CREG, ADDREG , AREG .
- edx = dl + dh : REG, GENREG, IREG, DXREG, ADDREG, AREG .
- #ifndef REGVARS
- esi : REG, RREG, IREG, AREG, ADDREG .
- edi : REG, RREG, IREG, AREG, ADDREG .
- #else
- esi : AREG , IREG , RREG regvar(reg_any) .
- edi : AREG , IREG , RREG regvar(reg_any) .
- #endif
- ebp : AREG , IREG .
- esp : AREG .
- /*****************************************************************/
- TOKENS
- /*****************************************************************/
- ANYCON = { INT val; } 4 cost(4,0) val .
- CONSTR = { ADDR off; } 4 cost(4,0) off .
- ADDR_EXTERN = { ADDR off; } 4 cost(4,0) off .
- EXTERN1 = { ADDR off; } 4 cost(4,5) "(" off ")" .
- EXTERN2 = { ADDR off; } 4 cost(4,5) "(" off ")" .
- EXTERN = { ADDR off; } 4 cost(4,5) "(" off ")" .
- ADDR_LOCAL = { INT ind; } 4 cost(1,0) ind "(ebp)" .
- LOCAL = { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
- LOCAL1 = { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
- LOCAL2 = { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
- Rreg_off = { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
- Xreg_off = { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
- indexed_r_off = { AREG reg; IREG reg2; INT scale; ADDR off;}
- 4 cost(5,0) off "(" reg ")" "(" reg2 "*" scale ")" .
- indexed_off = { IREG reg; INT scale; ADDR off;}
- 4 cost(5,0) off "(" reg "*" scale ")" .
- indir_r = { AREG reg;} 4 cost(0,5) "(" reg ")" .
- indir_r1 = { AREG reg;} 4 cost(0,5) "(" reg ")" .
- indir_r2 = { AREG reg;} 4 cost(0,5) "(" reg ")" .
- indir_r_off = { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
- indir_r_off1 = { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
- indir_r_off2 = { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
- indir_indexed_r_off =
- { AREG reg; IREG reg2; INT scale; ADDR off;}
- 4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
- indir_indexed_r_off1 =
- { AREG reg; IREG reg2; INT scale; ADDR off;}
- 4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
- indir_indexed_r_off2 =
- { AREG reg; IREG reg2; INT scale; ADDR off;}
- 4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
- indir_indexed_off =
- { IREG reg; INT scale; ADDR off;}
- 4 cost(5,5) off "(" reg "*" scale ")" .
- indir_indexed_off1 =
- { IREG reg; INT scale; ADDR off;}
- 4 cost(5,5) off "(" reg "*" scale ")" .
- indir_indexed_off2 =
- { IREG reg; INT scale; ADDR off;}
- 4 cost(5,5) off "(" reg "*" scale ")" .
- label = { ADDR off;} 4 off .
- /*****************************************************************/
- SETS
- /*****************************************************************/
- /* Mode refering to a word in memory */
- memory2 = EXTERN2 + indir_r2 + indir_r_off2 + LOCAL2 +
- indir_indexed_r_off2 + indir_indexed_off2 .
- memory1 = EXTERN1 + indir_r1 + indir_r_off1 + LOCAL1 +
- indir_indexed_r_off1 + indir_indexed_off1 .
- memory = EXTERN + indir_r + indir_r_off + LOCAL +
- indir_indexed_r_off + indir_indexed_off .
- noacc = EXTERN + LOCAL + BXREG + CXREG + RREG .
- const = ANYCON + ADDR_EXTERN + CONSTR .
- register = REG + ADDREG + RREG + IREG .
- addreg = ADDREG + RREG .
- anyreg = register + AREG .
- rm = anyreg + memory .
- rmorconst = const + rm .
- regorconst = const + anyreg .
- dest = register + memory .
- rm1 = REG1 + memory1 .
- rmorconst1 = const + rm1 .
- rm2 = REG2 + memory2 .
- rmorconst2 = const + rm2 .
- regorconst124 = REG1 + REG2 + GENREG + const .
- regorconst24 = REG2 + GENREG + const .
- dest1 = REG1 + memory1 .
- dest2 = REG2 + memory2 .
- /* Modes used to indicate tokens to be removed from the fakestack */
- reg_indir = indir_r1 + indir_r2 + indir_r_off1 + indir_r_off2 + indir_r +
- indir_r_off .
- indexed = indir_indexed_r_off1 + indir_indexed_r_off2 +
- indir_indexed_r_off + indir_indexed_off1 +
- indir_indexed_off2 + indir_indexed_off .
- indir = reg_indir + indexed .
- externals = EXTERN2 + EXTERN1 + EXTERN .
- locals = LOCAL2 + LOCAL1 + LOCAL .
- mem_nonlocals = externals + reg_indir .
- all_mems = mem_nonlocals + locals .
- /* Miscellaneous */
- reg_off = Xreg_off + Rreg_off .
- halfindir = reg_off + ADDR_LOCAL + indexed_r_off + indexed_off .
- some_off = halfindir + ADDR_EXTERN + AREG .
- a_word = rmorconst + halfindir .
- /*****************************************************************/
- INSTRUCTIONS
- /*****************************************************************/
- cost(2,2)
- adc rm:rw:cc, regorconst:ro.
- adc anyreg:rw:cc, rmorconst:ro.
- #ifdef REGVARS
- add LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
- #endif
- add anyreg:rw:cc, rmorconst:ro.
- add rm:rw:cc, regorconst:ro.
- #ifdef REGVARS
- axx "syntax error" LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
- #endif
- axx "syntax error" anyreg:rw:cc, rmorconst:ro.
- axx "syntax error" rm:rw:cc, regorconst:ro.
- #ifdef REGVARS
- and LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
- #endif
- and rm:rw:cc, regorconst:ro.
- and anyreg:rw:cc, rmorconst:ro.
- cdq kills edx cost(1,3).
- cmp rm:ro, regorconst:ro kills :cc.
- cmp anyreg:ro, rmorconst:ro kills :cc.
- cmpb rm1:rw, const:ro kills :cc.
- cmpw "o16 cmp" rm2:rw, const:ro kills :cc cost(3,2).
- dec anyreg:rw:cc cost(1,2).
- dec rm:rw:cc.
- div rm:ro kills:cc eax edx cost(2,43).
- idiv rm:ro kills:cc eax edx cost(2,43).
- imul rm:rw, anyreg:ro kills:cc cost(3,41).
- imul anyreg:rw, rm:ro kills:cc cost(3,41).
- imul anyreg:wo, rm:ro, const:ro kills :cc cost(2,38).
- inc anyreg:rw:cc cost(1,2).
- inc rm:rw:cc.
- ja label cost(1,4).
- jae label cost(1,4).
- jb label cost(1,4).
- jbe label cost(1,4).
- jcxz label cost(1,4).
- je label cost(1,4).
- jg label cost(1,4).
- jge label cost(1,4).
- jl label cost(1,4).
- jle label cost(1,4).
- jne label cost(1,4).
- jmp label cost(1,4).
- proccall "call" label+rm cost(1,8).
- jxx "syntax error" label cost(1,4).
- setxx "syntax error" REG1:rw cost(2,4).
- setle REG1:rw cost(2,4).
- setg REG1:rw cost(2,4).
- lea anyreg:rw, halfindir:ro.
- lea LOCAL:rw, halfindir:ro. /* only for register variables, UNSAFE!!! */
- leave cost(1,4).
- loop label kills ecx.
- #ifdef REGVARS
- mov LOCAL:wo, rmorconst:ro. /* only for register variables, UNSAFE!!! */
- #endif
- mov a_word:wo, regorconst:ro.
- mov anyreg:wo, rmorconst:ro.
- movb rm1:wo, regorconst124:ro.
- movb REG1:wo, rm1:ro.
- movw "o16 mov" rm2:wo, regorconst124:ro cost(3,2).
- movw "o16 mov" REG2:wo, rmorconst2:ro cost(3,2).
- movsxb anyreg:wo, REG+rm1:ro.
- movsx anyreg:wo, REG+rm2:ro.
- movzxb anyreg:wo, REG+rm1:ro.
- movzx anyreg:wo, REG+rm2:ro.
- mul rmorconst:ro kills :cc eax edx cost(2,41).
- neg rmorconst:rw:cc.
- not rmorconst:rw.
- #ifdef REGVARS
- or LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
- #endif
- or rm:rw:cc, regorconst:ro.
- or anyreg:rw:cc, rmorconst:ro.
- pop anyreg:wo cost(1,4).
- pop rm:wo.
- push anyreg:ro cost(1,2).
- push const:ro cost(1,2).
- push rm:ro cost(2,5).
- rcl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
- rcr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
- ret cost(1,10).
- rol rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
- ror rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
- sal rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
- sar rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
- sbb rm:rw:cc, regorconst:ro.
- sbb anyreg:rw:cc, rmorconst:ro.
- shl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
- shr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
- #ifdef REGVARS
- sub LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
- #endif
- sub rm:rw:cc, regorconst:ro.
- sub anyreg:rw:cc, rmorconst+halfindir:ro.
- check "test" rm:ro, regorconst:ro kills :cc.
- check "test" anyreg:ro, rmorconst:ro kills :cc.
- testb "testb" rm1:ro, regorconst124:ro kills :cc.
- testb "testb" REG1:ro, rmorconst1:ro kills :cc.
- testw "o16 test" rm2:ro, regorconst24:ro kills :cc.
- testw "o16 test" REG2:ro, rmorconst2:ro kills :cc.
- testl "test" rm:ro, regorconst:ro kills :cc.
- testl "test" REG:ro, rmorconst:ro kills :cc.
- uxx "syntax error" rm:rw:cc.
- xchg rm:rw, anyreg:rw.
- xchg anyreg:rw, rm:rw.
- xor rm:rw:cc, regorconst:ro.
- xor anyreg:rw:cc, rmorconst:ro.
- xorb rm1:rw:cc, regorconst124:ro.
- xorb anyreg:rw:cc, rmorconst1:ro.
- xorw "o16 xor" rm2:rw:cc, regorconst124:ro.
- xorw "o16 xor" anyreg:rw:cc, rmorconst2:ro.
- killreg "! kill" anyreg:wo cost(0,0).
- killcc "! kill cc" kills:cc cost(0,0).
- /*****************************************************************/
- MOVES
- /*****************************************************************/
- #ifdef REGVARS
- from rmorconst to LOCAL /* unsafe !!! */
- gen mov %2,%1
- #endif
- from rm to register
- gen mov %2,%1
- from anyreg to dest
- gen mov %2,%1
- from halfindir to register+AREG
- gen lea %2,%1
- from halfindir to LOCAL /* unsafe !!! */
- gen lea %2,%1
- from rm1 to REG1
- gen movb %2,%1
- from rm2 to REG2
- gen movw %2,%1
- from GENREG to rm1
- gen movb %2,%1.1
- from GENREG to rm2
- gen movw %2,%1
- from REG2 to rm1
- gen movb %2,%1.1
- from ANYCON %val==0 to register
- gen xor %2,%2
- from ANYCON %val==0 to REG1
- gen xorb %2,%2
- from ANYCON %val==0 to REG2
- gen xorw %2,%2
- from const to dest
- gen mov %2,%1
- from const+REG1 to rm1
- gen movb %2,%1
- from const+REG2 to rm2
- gen movw %2,%1
- /*****************************************************************/
- TESTS
- /*****************************************************************/
- to test anyreg
- gen testl %1,%1
- to test memory
- gen cmp %1, {ANYCON,0}
- to test REG1
- gen testb %1,%1
- to test memory1
- gen cmpb %1, {ANYCON,0}
- to test REG2
- gen testw %1,%1
- to test memory2
- gen cmpw %1, {ANYCON,0}
- /*****************************************************************/
- STACKINGRULES
- /*****************************************************************/
- from rm to STACK
- gen push %1
- from const to STACK
- gen push %1
- from rm1 to STACK
- uses REG
- gen movzxb %a,%1
- push %a
- from rm1 to STACK
- gen push eax
- movzxb eax,%1
- xchg {indir_r,esp},eax
- from rm2 to STACK
- uses REG
- gen movzx %a,%1
- push %a
- from rm2 to STACK
- gen push eax
- movzx eax,%1
- xchg {indir_r,esp},eax
- from Xreg_off to STACK
- gen add %1.reg,{CONSTR,%1.off}
- push %1.reg
- from ADDR_LOCAL %ind==0 to STACK
- gen push ebp
- from halfindir to STACK
- uses REG
- gen move %1,%a
- push %a
- from halfindir to STACK
- gen push eax
- lea eax,%1
- xchg {indir_r,esp},eax
- /*****************************************************************/
- COERCIONS
- /*****************************************************************/
- /***************************
- * From source to register *
- ***************************/
- from rmorconst
- uses reusing %1,REG=%1 yields %a
- from rmorconst
- uses reusing %1,IREG=%1 yields %a
- from Xreg_off
- gen add %1.reg,{CONSTR,%1.off} yields %1.reg
- from halfindir
- uses reusing %1,ADDREG
- gen move %1,%a yields %a
- from halfindir
- uses reusing %1,REG
- gen move %1,%a yields %a
- from halfindir
- uses reusing %1,IREG
- gen move %1,%a yields %a
- /************************
- * From source to token *
- ************************/
- from ANYCON yields {ADDR_EXTERN,%1.val}
- /****************
- * From source1 *
- ****************/
- from rm1
- uses reusing %1,REG1=%1 yields %a
- from rm1
- uses GENREG
- gen
- movzxb %a,%1 yields %a
- /****************
- * From source2 *
- ****************/
- from rm2
- uses reusing %1,REG2=%1 yields %a
- from rm2
- uses GENREG
- gen
- movzx %a,%1 yields %a
- /************************
- * From STACK coercions *
- ************************/
- from STACK
- uses REG
- gen pop %a yields %a
- /*****************************************************************/
- PATTERNS
- /*****************************************************************/
- /******************************************************************
- * Group 1 : Load Instructions *
- ******************************************************************/
- pat loc yields {ANYCON,$1}
- pat ldc leaving loc 18 trp
- pat lol yields {LOCAL,$1,4}
- pat stl lol $1==$2
- #ifdef REGVARS
- && inreg($1) <= 0
- #endif
- leaving dup 4 stl $1
- pat sdl ldl $1==$2 leaving dup 8 sdl $1
- #ifdef REGVARS
- pat lol dup stl $2==4 && inreg($1) <= 0 && inreg($3) > 0
- kills regvar($3)
- gen move {LOCAL,$1,4}, {LOCAL,$3,4}
- yields {LOCAL,$3,4}
- #endif
- pat loe yields {EXTERN,$1}
- pat ste loe $1==$2 leaving dup 4 ste $1
- pat sde lde $1==$2 leaving dup 8 sde $1
- #ifdef REGVARS
- pat loe dup stl $2==4 && inreg($3) > 0
- kills regvar($3)
- gen move {EXTERN,$1}, {LOCAL,$3,4}
- yields {LOCAL,$3,4}
- #endif
- #ifdef REGVARS
- pat lil inreg($1) > 0 yields {indir_r, regvar($1)}
- #endif
- pat lil
- uses ADDREG={indir_r_off,ebp,$1} yields {indir_r,%a}
- pat lil dup stl $2==4 leaving lil $1 stl $3 lol $3
- pat sil lil $1==$2 leaving dup 4 sil $1
- pat lof
- with exact indexed_r_off yields {indir_indexed_r_off,%1.reg,%1.reg2,
- %1.scale,%1.off+$1}
- with exact indexed_off yields {indir_indexed_off,%1.reg,
- %1.scale,%1.off+$1}
- with exact reg_off yields {indir_r_off,%1.reg,%1.off+$1}
- with exact ADDR_EXTERN yields {EXTERN,%1.off+$1}
- with exact ADDR_LOCAL yields {LOCAL,%1.ind + $1,4}
- with addreg yields {indir_r_off,%1,$1}
- pat lal yields {ADDR_LOCAL,$1}
- pat lae yields {ADDR_EXTERN,$1}
- pat lpb leaving adp SL
- pat lxl $1==0 yields {ADDR_LOCAL,0}
- pat lxl $1==1 yields {LOCAL,SL,4}
- pat lxl $1==2
- uses ADDREG={indir_r_off,ebp,SSL} yields {indir_r_off,%a,SSL}
- pat lxl $1>2
- uses ADDREG={indir_r_off,ebp,SSL},
- CXREG={ANYCON,$1-1}
- gen 1:
- mov %a,{indir_r_off,%a,SSL}
- loop {label,1b} yields %a
- pat lxa $1==0 yields {ADDR_LOCAL,SL}
- pat lxa $1==1
- uses ADDREG={indir_r_off,ebp,SSL} yields {Xreg_off,%a,SSL}
- pat lxa $1==2
- uses ADDREG={indir_r_off,ebp,SSL}
- gen move {indir_r_off,%a,SSL},%a yields {Xreg_off,%a,SSL}
- pat lxa $1>2
- uses ADDREG={indir_r_off,ebp,SSL},
- CXREG={ANYCON,$1-1}
- gen 1:
- mov %a,{indir_r_off,%a,SSL}
- loop {label,1b} yields {Xreg_off,%a,SSL}
- pat dch leaving loi 4
- pat loi $1==2
- with addreg yields {indir_r2,%1}
- with exact indexed_r_off yields {indir_indexed_r_off2, %1.reg, %1.reg2,
- %1.scale, %1.off}
- with exact indexed_off yields {indir_indexed_off2, %1.reg,
- %1.scale, %1.off}
- with exact reg_off yields {indir_r_off2,%1.reg,%1.off}
- with exact ADDR_EXTERN yields {EXTERN2,%1.off}
- with exact ADDR_LOCAL yields {LOCAL2,%1.ind,2}
- pat loi $1==1
- with addreg yields {indir_r1,%1}
- with exact indexed_r_off yields {indir_indexed_r_off1, %1.reg, %1.reg2,
- %1.scale, %1.off}
- with exact indexed_off yields {indir_indexed_off1, %1.reg,
- %1.scale, %1.off}
- with exact reg_off yields {indir_r_off1,%1.reg,%1.off}
- with exact ADDR_EXTERN yields {EXTERN1,%1.off}
- with exact ADDR_LOCAL yields {LOCAL1,%1.ind,1}
- pat loi $1==4
- with addreg yields {indir_r,%1}
- with exact indexed_r_off yields {indir_indexed_r_off, %1.reg, %1.reg2,
- %1.scale, %1.off}
- with exact indexed_off yields {indir_indexed_off, %1.reg,
- %1.scale, %1.off}
- with exact reg_off yields {indir_r_off,%1.reg,%1.off}
- with exact ADDR_EXTERN yields {EXTERN,%1.off}
- with exact ADDR_LOCAL yields {LOCAL,%1.ind,4}
- pat loi $1==8
- with addreg yields {indir_r_off,%1,4}
- {indir_r,%1}
- with exact indexed_r_off yields {indir_indexed_r_off, %1.reg, %1.reg2,
- %1.scale, %1.off+4}
- {indir_indexed_r_off, %1.reg, %1.reg2,
- %1.scale, %1.off}
- with exact indexed_off yields {indir_indexed_off, %1.reg,
- %1.scale, %1.off+4}
- {indir_indexed_off, %1.reg,
- %1.scale, %1.off}
- with exact reg_off yields {indir_r_off,%1.reg,%1.off+4}
- {indir_r_off,%1.reg,%1.off}
- with exact ADDR_LOCAL yields {LOCAL,%1.ind+4,4}
- {LOCAL,%1.ind,4}
- with exact ADDR_EXTERN yields {EXTERN,%1.off + 4}
- {EXTERN,%1.off}
- pat loi
- with BXREG
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label,".loi"}
- pat los $1==4
- with CXREG BXREG
- kills ALL
- gen proccall {label,".los"}
- pat ldl yields {LOCAL,$1+4,4}
- {LOCAL,$1,4}
- pat lde yields {EXTERN,$1+4}
- {EXTERN,$1}
- pat ldf
- with exact reg_off yields {indir_r_off,%1.reg,
- %1.off + 4 + $1}
- {indir_r_off,%1.reg,
- %1.off + $1}
- with exact indexed_r_off yields {indir_indexed_r_off, %1.reg, %1.reg2,
- %1.scale, %1.off+$1+4}
- {indir_indexed_r_off, %1.reg, %1.reg2,
- %1.scale, %1.off+$1}
- with exact indexed_off yields {indir_indexed_off, %1.reg,
- %1.scale, %1.off+$1+4}
- {indir_indexed_off, %1.reg,
- %1.scale, %1.off+$1}
- with addreg yields {indir_r_off,%1,$1+4}
- {indir_r_off,%1,$1}
- with exact ADDR_EXTERN yields {EXTERN,%1.off+4+$1}
- {EXTERN,%1.off+$1}
- with exact ADDR_LOCAL yields {LOCAL,%1.ind + $1 + 4,4}
- {LOCAL,%1.ind + $1,4}
- pat lpi yields {ADDR_EXTERN,$1}
- /* this code sequence is generated by the C-compiler to tackle
- char parameters, on the 80386 it reduces to nil */
- pat lol lal sti $1==$2 && $3<=4
- /*******************************************************************
- * Group 2 : Store Instructions *
- *******************************************************************/
- #ifdef REGVARS
- pat stl inreg($1)==reg_any
- with rmorconst
- kills regvar($1)
- gen move %1, {LOCAL,$1,4}
- with exact halfindir
- kills regvar($1)
- gen move %1, {LOCAL,$1,4}
- with exact STACK
- kills regvar($1)
- gen pop {LOCAL, $1, 4}
- #endif
- pat stl
- with regorconst
- kills indir,locals %ind+%size > $1 && %ind < $1+4
- gen move %1,{LOCAL,$1,4}
- with exact STACK
- kills ALL
- gen pop {indir_r_off,ebp,$1}
- pat ste
- with regorconst
- kills mem_nonlocals
- gen move %1,{EXTERN,$1}
- with exact STACK
- kills ALL
- gen pop {EXTERN,$1}
- #ifdef REGVARS
- pat sil inreg($1)==reg_any
- with regorconst
- kills all_mems
- gen move %1,{indir_r,regvar($1)}
- with exact STACK
- kills ALL
- gen pop {indir_r,regvar($1)}
- #endif
- pat sil
- with regorconst
- kills all_mems
- uses ADDREG={indir_r_off,ebp,$1}
- gen move %1,{indir_r,%a}
- killreg %a
- with exact STACK
- kills ALL
- uses ADDREG={indir_r_off,ebp,$1}
- gen pop {indir_r,%a}
- killreg %a
- pat stf
- with addreg regorconst
- kills all_mems
- gen move %2,{indir_r_off,%1,$1}
- with exact addreg STACK
- kills ALL
- gen pop {indir_r_off, %1,$1}
- with reg_off regorconst
- kills all_mems
- gen move %2,{indir_r_off,%1.reg,%1.off+$1}
- with exact reg_off STACK
- gen pop {indir_r_off,%1.reg,$1+%1.off}
- with indexed_r_off regorconst
- kills all_mems
- gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- with exact indexed_r_off STACK
- kills all_mems
- gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- with indexed_off regorconst
- kills all_mems
- gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
- with exact indexed_off STACK
- kills all_mems
- gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
- with ADDR_LOCAL regorconst
- kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
- gen move %2,{LOCAL,%1.ind+$1,4}
- with exact ADDR_LOCAL STACK
- kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
- gen pop {LOCAL,%1.ind+$1,4}
- with ADDR_EXTERN regorconst
- kills mem_nonlocals
- gen move %2,{EXTERN,%1.off+$1}
- with exact ADDR_EXTERN STACK
- kills mem_nonlocals
- gen pop {EXTERN,%1.off+$1}
- pat sti $1==4
- with addreg regorconst
- kills all_mems
- gen move %2,{indir_r,%1}
- with exact addreg STACK
- kills all_mems
- gen pop {indir_r,%1}
- with reg_off regorconst
- kills all_mems
- gen move %2,{indir_r_off,%1.reg,%1.off}
- with exact reg_off STACK
- kills all_mems
- gen pop {indir_r_off,%1.reg,%1.off}
- with indexed_r_off regorconst
- kills all_mems
- gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
- with exact indexed_r_off STACK
- kills all_mems
- gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
- with indexed_off regorconst
- kills all_mems
- gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off}
- with exact indexed_off STACK
- kills all_mems
- gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off}
- with ADDR_LOCAL regorconst
- kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
- gen move %2,{LOCAL,%1.ind,4}
- with exact ADDR_LOCAL STACK
- kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
- gen pop {LOCAL,%1.ind,4}
- with ADDR_EXTERN regorconst
- kills mem_nonlocals
- gen move %2,{EXTERN,%1.off}
- with exact ADDR_EXTERN STACK
- kills mem_nonlocals
- gen pop {EXTERN,%1.off}
- pat sti $1==1
- with addreg regorconst124
- kills all_mems
- gen move %2,{indir_r1,%1}
- with reg_off regorconst124
- kills all_mems
- gen move %2,{indir_r_off1,%1.reg,%1.off}
- with indexed_r_off regorconst124
- kills all_mems
- gen move %2,{indir_indexed_r_off1,%1.reg,%1.reg2,%1.scale,%1.off}
- with indexed_off regorconst124
- kills all_mems
- gen move %2,{indir_indexed_off1,%1.reg,%1.scale,%1.off}
- with ADDR_EXTERN regorconst124
- kills mem_nonlocals
- gen move %2,{EXTERN1,%1.off}
- with ADDR_LOCAL regorconst124
- kills indir,locals %ind<%1.ind+1 && %ind+%size>%1.ind
- gen move %2,{indir_r_off1,ebp,%1.ind}
- pat sti $1==2
- with addreg regorconst24
- kills all_mems
- gen move %2,{indir_r2,%1}
- with reg_off regorconst24
- kills all_mems
- gen move %2,{indir_r_off2,%1.reg,%1.off}
- with indexed_r_off regorconst24
- kills all_mems
- gen move %2,{indir_indexed_r_off2,%1.reg,%1.reg2,%1.scale,%1.off}
- with indexed_off regorconst24
- kills all_mems
- gen move %2,{indir_indexed_off2,%1.reg,%1.scale,%1.off}
- with ADDR_EXTERN regorconst24
- kills mem_nonlocals
- gen move %2,{EXTERN2,%1.off}
- with ADDR_LOCAL regorconst24
- kills indir,locals %ind<%1.ind+2 && %ind+%size>%1.ind
- gen move %2,{indir_r_off2,ebp,%1.ind}
- pat sti $1==8 leaving sdf 0
- pat sti
- with BXREG
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".sti"}
- /* this sort of construction gives problems in the codegenerator
- because of the potential very large lookahead
- with addreg
- kills ALL
- gen pop (%1)
- add %1,{ANYCON,2} yields %1 leaving sti $1-4
- */
- pat sts $1==4
- with CXREG BXREG
- kills ALL
- gen proccall {label,".sts"}
- pat sdl
- with regorconst regorconst yields %2 %1
- leaving stl $1 stl $1+4
- with exact STACK leaving stl $1 stl $1+4
- pat sde
- with regorconst regorconst yields %2 %1
- leaving ste $1 ste $1+4
- with exact STACK leaving ste $1 ste $1+4
- pat sdf
- with addreg regorconst regorconst
- kills all_mems
- gen move %2,{indir_r_off,%1,$1}
- move %3,{indir_r_off,%1,$1+4}
- with exact addreg STACK
- kills all_mems
- gen pop {indir_r_off,%1,$1}
- pop {indir_r_off,%1,$1+4}
- with reg_off regorconst regorconst
- kills all_mems
- gen move %2,{indir_r_off,%1.reg,%1.off+$1}
- move %3,{indir_r_off,%1.reg,%1.off+$1+4}
- with exact reg_off STACK
- kills all_mems
- gen pop {indir_r_off,%1.reg,$1+%1.off}
- pop {indir_r_off,%1.reg,$1+%1.off+4}
- with indexed_r_off regorconst regorconst
- kills all_mems
- gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- move %3,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
- with exact indexed_r_off STACK
- kills all_mems
- gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
- with indexed_off regorconst regorconst
- kills all_mems
- gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
- move %3,{indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
- with exact indexed_off STACK
- kills all_mems
- gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
- pop {indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
- with ADDR_LOCAL regorconst regorconst
- kills indir,locals %ind+%size > $1 && %ind < $1+8
- gen move %2,{LOCAL,%1.ind+$1,4}
- move %3,{LOCAL,%1.ind+$1+4,4}
- with exact ADDR_LOCAL STACK
- kills indir,locals %ind+%size > $1 && %ind < $1+8
- gen pop {LOCAL,%1.ind+$1,4}
- pop {LOCAL,%1.ind+$1+4,4}
- with ADDR_EXTERN regorconst regorconst
- kills mem_nonlocals
- gen move %2,{EXTERN,%1.off+$1}
- move %3,{EXTERN,%1.off+$1+4}
- with exact ADDR_EXTERN STACK
- kills mem_nonlocals
- gen pop {EXTERN,%1.off+$1}
- pop {EXTERN,%1.off+$1+4}
- /****************************************************************
- * Group 3 : Integer Arithmetic. *
- * *
- * Implemented (sometimes with the use of subroutines) : *
- * 4 byte arithmetic. *
- ****************************************************************/
- pat adi $1==4
- #ifdef REGVARS
- with exact ANYCON RREG
- yields {Rreg_off,%2,%1.val}
- with exact RREG ANYCON
- yields {Rreg_off,%1,%2.val}
- #endif
- with REG rmorconst
- gen add %1,%2 yields %1
- with rmorconst REG
- gen add %2,%1 yields %2
- with EXACT rmorconst const
- uses reusing %1,REG=%1
- gen add %a,%2 yields %a
- /*
- pat adi !defined($1)
- with CXREG ACC
- kills ALL
- gen proccall {label,".adi"} yields eax
- */
- pat sbi $1==4
- with rmorconst REG
- gen sub %2,%1 yields %2
- with EXACT REG rmorconst
- gen sub %1,%2
- neg %1 yields %1
- /*
- pat sbi !defined($1)
- with CXREG ACC
- kills ALL
- gen proccall {label,".sbi"} yields eax
- */
- pat mli $1==4
- with rm REG
- gen imul %2,%1 yields %2
- with REG rm
- gen imul %1,%2 yields %1
- with const rm
- uses reusing %2,REG
- gen imul %a,%2,%1 yields %a
- with rm const
- uses reusing %1,REG
- gen imul %a,%1,%2 yields %a
- /*
- pat mli !defined($1)
- with ACC
- kills ALL
- gen proccall {label,".mli"}
- */
- pat dvi $1==4
- with noacc ACC
- uses DXREG
- gen cdq.
- idiv %1 yields eax
- /*
- pat dvi !defined($1)
- with ACC
- kills ALL
- gen proccall {label,".dvi"}
- */
- pat rmi $1==4
- with noacc ACC
- uses DXREG
- gen cdq.
- idiv %1 yields edx
- /*
- pat rmi !defined($1)
- with ACC
- kills ALL
- gen proccall {label,".rmi"}
- */
- pat ngi $1==4
- with REG
- gen neg %1 yields %1
- /*
- pat ngi !defined($1)
- with ACC
- kills ALL
- gen proccall {label,".ngi"}
- */
- pat sli $1==4
- with ANYCON REG
- gen sal %2,%1 yields %2
- with SHIFT_CREG REG
- gen sal %2,cl yields %2
- /*
- pat sli !defined($1)
- with ACC
- kills ALL
- gen proccall {label,".sli"}
- */
- pat sri $1==4
- with SHIFT_CREG REG
- gen sar %2,cl yields %2
- with ANYCON REG
- gen sar %2,%1 yields %2
- /*
- pat sri !defined($1)
- with ACC
- kills ALL
- gen proccall {label,".sri"}
- */
- /*******************************************************************
- * Group 4: Unsigned Arithmetic *
- *******************************************************************/
- pat adu leaving adi $1
- pat loc lol adu stl $1==1 && $3==4 && $2==$4 leaving inl $2
- pat loc loe adu ste $1==1 && $3==4 && $2==$4 leaving ine $2
- pat loc lol adu $1==1 && $3==4 leaving lol $2 inc
- pat loc loe adu $1==1 && $3==4 leaving loe $2 inc
- pat loc lil adu $1==1 && $3==4 leaving lil $2 inc
- pat loc lol adu stl $1==0-1 && $3==4 && $2==$4 leaving del $2
- pat loc loe adu ste $1==0-1 && $3==4 && $2==$4 leaving dee $2
- pat loc lol adu $1==0-1 && $3==4 leaving lol $2 dec
- pat loc loe adu $1==0-1 && $3==4 leaving loe $2 dec
- pat loc lil adu $1==0-1 && $3==4 leaving lil $2 dec
- pat sbu leaving sbi $1
- pat lol loc sbu stl $1==$4 && $2==1 && $3==4 leaving del $1
- pat loe loc sbu ste $1==$4 && $2==1 && $3==4 leaving dee $1
- pat lol loc sbu $2==1 && $3==4 leaving lol $1 dec
- pat loe loc sbu $2==1 && $3==4 leaving loe $1 dec
- pat lil loc sbu $2==1 && $3==4 leaving lil $1 dec
- pat lol loc sbu stl $1==$4 && $2==0-1 && $3==4 leaving inl $1
- pat loe loc sbu ste $1==$4 && $2==0-1 && $3==4 leaving ine $1
- pat lol loc sbu $2==0-1 && $3==4 leaving lol $1 inc
- pat loe loc sbu $2==0-1 && $3==4 leaving loe $1 inc
- pat lil loc sbu $2==0-1 && $3==4 leaving lil $1 inc
- pat mlu leaving mli $1
- pat loe loc loe adu ste $1==$3 && $1==$5 && $4==4
- uses REG = {EXTERN, $1}
- yields %a leaving loc $2 loe $3 adu 4 ste $3
- pat lol loc lol adu stl $1==$3 && $1==$5 && $4==4
- uses REG = {LOCAL, $1, 4}
- yields %a leaving loc $2 lol $3 adu 4 stl $3
- pat loe loc loe adi ste $1==$3 && $1==$5 && $4==4
- uses REG = {EXTERN, $1}
- yields %a leaving loc $2 loe $3 adi 4 ste $3
- pat lol loc lol adi stl $1==$3 && $1==$5 && $4==4
- uses REG = {LOCAL, $1, 4}
- yields %a leaving loc $2 lol $3 adi 4 stl $3
- pat dvu $1==4
- with noacc ACC
- uses DXREG={ANYCON,0}
- gen div %1 yields eax
- /*
- pat dvu !defined($1)
- with ACC STACK
- kills ALL
- gen proccall {label,".dvu"}
- */
- pat rmu $1==4
- with noacc ACC
- uses DXREG={ANYCON,0}
- gen div %1 yields edx
- /*
- pat rmu !defined($1)
- with ACC STACK
- kills ALL
- gen proccall {label,".rmu"}
- */
- pat slu leaving sli $1
- pat loc slu leaving loc $1 sli $2
- pat sru $1==4
- with SHIFT_CREG REG
- gen shr %2,cl yields %2
- with ANYCON REG
- gen shr %2,%1 yields %2
- /*
- pat sru !defined($1)
- with ACC STACK
- kills ALL
- gen proccall {label,".sru"}
- */
- /*******************************************************************
- * Group 5: Floating Point Instructions *
- *******************************************************************/
- 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 6: Pointer Arithmetic *
- ******************************************************************/
- pat adp $1==1
- with exact Xreg_off yields {Xreg_off,%1.reg,%1.off+$1}
- with exact Rreg_off yields {Rreg_off,%1.reg,%1.off+$1}
- with exact indexed_r_off
- yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- with exact indexed_off yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
- with exact ADDR_EXTERN yields {ADDR_EXTERN,%1.off+$1}
- with exact ADDR_LOCAL yields {ADDR_LOCAL,%1.ind+$1}
- with REG
- gen inc %1 yields %1
- with ADDREG
- gen killreg %1
- yields {Xreg_off, %1, $1}
- with exact RREG yields {Rreg_off, %1, $1}
- pat adp $1==0-1
- with exact Xreg_off yields {Xreg_off,%1.reg,%1.off+$1}
- with exact Rreg_off yields {Rreg_off,%1.reg,%1.off+$1}
- with exact indexed_r_off
- yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- with exact indexed_off yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
- with exact ADDR_EXTERN yields {ADDR_EXTERN,%1.off+$1}
- with exact ADDR_LOCAL yields {ADDR_LOCAL,%1.ind+$1}
- with REG
- gen dec %1 yields %1
- with ADDREG
- gen killreg %1
- yields {Xreg_off, %1, $1}
- with exact RREG yields {Rreg_off, %1, $1}
- pat adp
- with exact Xreg_off yields {Xreg_off,%1.reg,%1.off+$1}
- with exact Rreg_off yields {Rreg_off,%1.reg,%1.off+$1}
- with exact indexed_r_off
- yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
- with exact indexed_off yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
- with exact ADDR_EXTERN yields {ADDR_EXTERN,%1.off+$1}
- with exact ADDR_LOCAL yields {ADDR_LOCAL,%1.ind+$1}
- with ADDREG
- gen killreg %1
- yields {Xreg_off,%1,$1}
- with exact RREG yields {Rreg_off, %1, $1}
- with REG
- gen add %1,{ANYCON,$1} yields %1
- pat ads stl $1==4 leaving adi 4 stl $2
- pat ads ste $1==4 leaving adi 4 ste $2
- pat ads sil $1==4 leaving adi 4 sil $2
- pat ads lol stf $1==4 leaving adi 4 lol $2 stf $3
- pat ads loe stf $1==4 leaving adi 4 loe $2 stf $3
- pat ads $1==4
- with exact ANYCON Rreg_off
- yields {Rreg_off,%2.reg,%2.off+%1.val}
- with exact ANYCON Xreg_off
- yields {Xreg_off,%2.reg,%2.off+%1.val}
- with exact ANYCON indexed_r_off
- yields {indexed_r_off,%2.reg,%2.reg2,
- %2.scale,%2.off+%1.val}
- with exact ANYCON indexed_off
- yields {indexed_off,%2.reg,%2.scale,%2.off+%1.val}
- with exact ADDR_EXTERN Rreg_off
- yields {Rreg_off,%2.reg,%2.off+%1.off}
- with exact ADDR_EXTERN Xreg_off
- yields {Xreg_off,%2.reg,%2.off+%1.off}
- with exact ADDR_EXTERN indexed_r_off
- yields {indexed_r_off,%2.reg,%2.reg2,
- %2.scale,%2.off+%1.off}
- with exact ADDR_EXTERN indexed_off
- yields {indexed_off,%2.reg,%2.scale,%2.off+%1.off}
- with exact IREG reg_off
- yields {indexed_r_off,%2.reg,%1,1,%2.off}
- with exact reg_off IREG
- yields {indexed_r_off,%1.reg,%2,1,%1.off}
- with exact IREG ADDR_LOCAL
- yields {indexed_r_off,ebp,%1,1,%2.ind}
- with exact ADDR_LOCAL IREG
- yields {indexed_r_off,ebp,%2,1,%1.ind}
- with rmorconst Xreg_off
- gen add %2.reg,%1 yields %2
- with Xreg_off rmorconst
- gen add %1.reg,%2 yields %1
- with exact Xreg_off ANYCON
- yields {Xreg_off,%1.reg,%1.off+%2.val}
- with exact Rreg_off ANYCON
- yields {Rreg_off,%1.reg,%1.off+%2.val}
- with exact indexed_r_off ANYCON
- yields {indexed_r_off,%1.reg,%1.reg2,
- %1.scale,%1.off+%2.val}
- with exact indexed_off ANYCON
- yields {indexed_off,%1.reg,%1.scale,%1.off+%2.val}
- with exact Xreg_off ADDR_EXTERN
- yields {Xreg_off,%1.reg,%1.off+%2.off}
- with exact Rreg_off ADDR_EXTERN
- yields {Rreg_off,%1.reg,%1.off+%2.off}
- with exact indexed_r_off ADDR_EXTERN
- yields {indexed_r_off,%1.reg,%1.reg2,
- %1.scale,%1.off+%2.off}
- with exact indexed_off ADDR_EXTERN
- yields {indexed_off,%1.reg,%1.scale,%1.off+%2.off}
- with exact Xreg_off reg_off
- gen add %1.reg,%2.reg
- yields {Xreg_off,%1.reg,%1.off+%2.off}
- with exact RREG ADDR_EXTERN
- yields {Rreg_off, %1, %2.off}
- with exact ADDR_EXTERN RREG
- yields {Rreg_off,%2,%1.off}
- with exact rmorconst ADDR_EXTERN
- uses reusing %1,ADDREG=%1
- yields {Xreg_off,%a,%2.off}
- with exact ADDR_EXTERN rmorconst
- uses reusing %2,ADDREG=%2
- yields {Xreg_off,%a,%1.off}
- with rmorconst ADDREG
- gen add %2,%1 yields %2
- with ADDREG rmorconst
- gen add %1,%2 yields %1
- pat sbs $1==4
- with exact ANYCON Xreg_off
- yields {Xreg_off,%2.reg,%2.off+"-"+%1.val}
- with exact ANYCON Rreg_off
- yields {Rreg_off,%2.reg,%2.off+"-"+%1.val}
- with exact ANYCON indexed_r_off
- yields {indexed_r_off,%2.reg,%2.reg2,%2.scale,
- %2.off+"-"+%1.val}
- with exact ANYCON indexed_off
- yields {indexed_off,%2.reg,%2.scale,%2.off+"-"+%1.val}
- with exact ANYCON ADDR_LOCAL
- yields {ADDR_LOCAL,%2.ind-%1.val}
- with rm Xreg_off
- gen sub %2.reg,%1 yields {Xreg_off,%2.reg,%2.off}
- /* Should not occur
- with exact reg_off ANYCON
- yields {reg_off,%1.reg,%1.off-%2.val}
- with ANYCON ADDR_EXTERN
- yields {ADDR_EXTERN,%2.off+%1.val}
- with exact ANYCON ADDR_LOCAL
- yields {ADDR_LOCAL,%1.val+%2.ind}
- */
- with rm REG
- gen sub %2,%1 yields %2
- with const ACC
- gen sub %2,%1 yields %2
- /*******************************************************************
- * Group 7 : Increment/Decrement Zero *
- *******************************************************************/
- pat inc
- with REG
- gen inc %1 yields %1
- #ifdef REGVARS
- pat inl inreg($1)==reg_any
- kills regvar($1)
- gen inc {LOCAL,$1,4}
- #endif
- pat inl
- kills indir, locals %ind + %size>$1 && %ind<$1+4
- gen inc {LOCAL,$1,4}
- pat ine
- kills mem_nonlocals
- gen inc {EXTERN,$1}
- pat dec
- with REG
- gen dec %1 yields %1
- #ifdef REGVARS
- pat del inreg($1)==reg_any
- kills regvar($1)
- gen dec {LOCAL,$1,4}
- #endif
- pat del
- kills indir, locals %ind+%size>$1 && %ind<$1+4
- gen dec {LOCAL, $1, 4}
- pat dee
- kills mem_nonlocals
- gen dec {EXTERN, $1}
- #ifdef REGVARS
- pat zrl inreg($1)==reg_any
- kills regvar($1)
- gen move {ANYCON, 0}, {LOCAL,$1,4}
- #endif
- pat zrl
- kills indir, locals %ind+%size>$1 && %ind<$1+4
- gen move {ANYCON, 0}, {LOCAL,$1,4}
- pat zre
- kills mem_nonlocals
- gen move {ANYCON, 0}, {EXTERN, $1}
- pat zrf leaving zer $1
- pat zer $1==4 yields {ANYCON, 0}
- pat zer $1==8 yields {ANYCON, 0} {ANYCON, 0}
- pat zer $1==12 yields {ANYCON, 0} {ANYCON, 0}
- {ANYCON, 0}
- pat zer $1==16 yields {ANYCON, 0} {ANYCON, 0}
- {ANYCON, 0} {ANYCON, 0}
- pat zer defined($1)
- with STACK
- gen move {ANYCON, $1/4}, ecx
- move {ANYCON, 0}, ebx
- 1:
- push ebx
- loop {label,1b}
- pat zer !defined($1)
- with CXREG STACK
- gen move {ANYCON, $1/4}, ebx
- sar ecx,{ANYCON, 1}
- 1:
- push ebx
- loop {label,1b}
- #ifdef REGVARS
- proc lolrxxxstl example lol adi stl
- with rmorconst
- kills regvar($1)
- gen axx* {LOCAL, $1, 4}, %1
- proc lilrxxxsil example lil adi sil
- with regorconst
- kills all_mems
- gen axx* {indir_r, regvar($1)}, %1
- proc xxxrstl example adi stl
- with rmorconst regorconst-RREG
- kills regvar($2)
- gen move %1, {LOCAL, $2, 4}
- axx* {LOCAL, $2, 4}, %2
- pat lol adi stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("add")
- pat lol adu stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("add")
- pat lol ads stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("add")
- pat lol and stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("and")
- pat lol ior stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("or")
- pat lol xor stl $1==$3 && $2==4 && inreg($1)==reg_any call lolrxxxstl("xor")
- pat lil adi sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("add")
- pat lil adu sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("add")
- pat lil ads sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("add")
- pat lil and sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("and")
- pat lil ior sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("or")
- pat lil xor sil $1==$3 && $2==4 && inreg($1)==reg_any call lilrxxxsil("xor")
- pat adi stl $1==4 && inreg($2)==reg_any call xxxrstl("add")
- pat adu stl $1==4 && inreg($2)==reg_any call xxxrstl("add")
- pat ads stl $1==4 && inreg($2)==reg_any call xxxrstl("add")
- pat and stl $1==4 && inreg($2)==reg_any call xxxrstl("and")
- pat ior stl $1==4 && inreg($2)==reg_any call xxxrstl("or")
- pat xor stl $1==4 && inreg($2)==reg_any call xxxrstl("xor")
- #endif
- proc lolxxxstl example lol adi stl
- with regorconst
- kills indir, locals %ind+%size>$1 && %ind<$1+4
- gen axx* {LOCAL, $1, 4}, %1
- pat lol adi stl $1==$3 && $2==4 call lolxxxstl("add")
- pat lol adu stl $1==$3 && $2==4 call lolxxxstl("add")
- pat lol ads stl $1==$3 && $2==4 call lolxxxstl("add")
- pat lol and stl $1==$3 && $2==4 call lolxxxstl("and")
- pat lol ior stl $1==$3 && $2==4 call lolxxxstl("or")
- pat lol xor stl $1==$3 && $2==4 call lolxxxstl("xor")
- proc lilxxxsil example lil adi sil
- with regorconst
- kills all_mems
- uses ADDREG={LOCAL, $1, 4}
- gen axx* {indir_r, %a}, %1
- killreg %a
- pat lil adi sil $1==$3 && $2==4 call lilxxxsil("add")
- pat lil adu sil $1==$3 && $2==4 call lilxxxsil("add")
- pat lil ads sil $1==$3 && $2==4 call lilxxxsil("add")
- pat lil and sil $1==$3 && $2==4 call lilxxxsil("and")
- pat lil ior sil $1==$3 && $2==4 call lilxxxsil("or")
- pat lil xor sil $1==$3 && $2==4 call lilxxxsil("xor")
- #ifdef REGVARS
- proc lilruxxsil example lil ngi sil
- kills all_mems
- gen uxx* {indir_r, regvar($1)}
- pat lil ngi sil $1==$3 && $2==4 && inreg($1)==reg_any call lilruxxsil("neg")
- pat lil com sil $1==$3 && $2==4 && inreg($1)==reg_any call lilruxxsil("not")
- pat lil dec sil $1==$3 && inreg($1)==reg_any call lilruxxsil("dec")
- pat lil inc sil $1==$3 && inreg($1)==reg_any call lilruxxsil("inc")
- pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==1 call lilruxxsil("inc")
- pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==(0-1)
- call lilruxxsil("dec")
- #endif
- proc liluxxsil example lil ngi sil
- kills all_mems
- uses ADDREG={LOCAL, $1, 4}
- gen uxx* {indir_r, %a}
- killreg %a
- pat lil ngi sil $1==$3 && $2==4 call liluxxsil("neg")
- pat lil com sil $1==$3 && $2==4 call liluxxsil("not")
- pat lil dec sil $1==$3 call liluxxsil("dec")
- pat lil inc sil $1==$3 call liluxxsil("inc")
- pat lil adp sil $1==$3 && $2==1 call liluxxsil("inc")
- pat lil adp sil $1==$3 && $2==(0-1) call liluxxsil("dec")
- proc loexxxste example loe adi ste
- with regorconst
- kills mem_nonlocals
- gen axx* {EXTERN, $1}, %1
- pat loe adi ste $1==$3 && $2==4 call loexxxste("add")
- pat loe adu ste $1==$3 && $2==4 call loexxxste("add")
- pat loe ads ste $1==$3 && $2==4 call loexxxste("add")
- pat loe and ste $1==$3 && $2==4 call loexxxste("and")
- pat loe ior ste $1==$3 && $2==4 call loexxxste("or")
- pat loe xor ste $1==$3 && $2==4 call loexxxste("xor")
- #ifdef REGVARS
- proc lofrxxxsof example lol lof adi lol stf
- with regorconst
- kills all_mems
- gen axx* {indir_r_off, regvar($1), $2}, %1
- pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofrxxxsof("add")
- pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofrxxxsof("add")
- pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofrxxxsof("add")
- pat lol lof and lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofrxxxsof("and")
- pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofrxxxsof("or")
- pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofrxxxsof("xor")
- proc lofruxxsof example lol lof inc lol stf
- kills all_mems
- gen uxx* {indir_r_off, regvar($1), $2}
- pat lol lof inc lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
- call lofruxxsof("inc")
- pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==1
- call lofruxxsof("inc")
- pat lol lof dec lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
- call lofruxxsof("dec")
- pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==(0-1)
- call lofruxxsof("dec")
- pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofruxxsof("neg")
- pat lol lof com lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
- call lofruxxsof("not")
- pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
- kills all_mems
- uses ADDREG={indir_r_off, regvar($1), $2}
- gen add {indir_r_off, regvar($1), $2}, {ANYCON, $4} yields %a
- #endif
- proc lofuxxsof example lol lof inc lol stf
- kills all_mems
- uses ADDREG={LOCAL,$1,4}
- gen uxx* {indir_r_off, %a, $2}
- killreg %a
- pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4 call lofuxxsof("neg")
- pat lol lof com lol stf $1==$4 && $2==$5 && $3==4 call lofuxxsof("not")
- pat lol lof dec lol stf $1==$4 && $2==$5 call lofuxxsof("dec")
- pat lol lof inc lol stf $1==$4 && $2==$5 call lofuxxsof("inc")
- pat lol lof adp lol stf $1==$4 && $2==$5 && $3==1 call lofuxxsof("inc")
- pat lol lof adp lol stf $1==$4 && $2==$5 && $3==(0-1) call lofuxxsof("dec")
- proc lofxxxsof example lol lof adi lol stf
- with regorconst
- kills all_mems
- uses ADDREG={LOCAL,$1,4}
- gen axx* {indir_r_off, %a, $2}, %1
- killreg %a
- pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("add")
- pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("add")
- pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("add")
- pat lol lof and lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("and")
- pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("or")
- pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4 call lofxxxsof("xor")
- pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4
- kills all_mems
- uses ADDREG={LOCAL,$1,4},ADDREG
- gen mov %b, {indir_r_off, %a, $2}
- add {indir_r_off, %a, $2}, {ANYCON, $4}
- killreg %a yields %b
- proc lefuxxsef example loe lof inc loe stf
- kills all_mems
- uses ADDREG={EXTERN,$1}
- gen uxx* {indir_r_off, %a, $2}
- killreg %a
- pat loe lof ngi loe stf $1==$4 && $2==$5 && $3==4 call lefuxxsef("neg")
- pat loe lof com loe stf $1==$4 && $2==$5 && $3==4 call lefuxxsef("not")
- pat loe lof dec loe stf $1==$4 && $2==$5 call lefuxxsef("dec")
- pat loe lof inc loe stf $1==$4 && $2==$5 call lefuxxsef("inc")
- pat loe lof adp loe stf $1==$4 && $2==$5 && $3==1 call lefuxxsef("inc")
- pat loe lof adp loe stf $1==$4 && $2==$5 && $3==(0-1) call lefuxxsef("dec")
- proc lefxxxsef example loe lof adi loe stf
- with regorconst
- kills all_mems
- uses ADDREG={EXTERN,$1}
- gen axx* {indir_r_off, %a, $2}, %1
- killreg %a
- pat loe lof adi loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("add")
- pat loe lof adu loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("add")
- pat loe lof ads loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("add")
- pat loe lof and loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("and")
- pat loe lof ior loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("or")
- pat loe lof xor loe stf $1==$4 && $2==$5 && $3==4 call lefxxxsef("xor")
- pat loe lof dup adp loe stf $1==$5 && $2==$6 && $3==4
- kills all_mems
- uses ADDREG={EXTERN,$1},ADDREG
- gen mov %b, {indir_r_off, %a, $2}
- add {indir_r_off, %a, $2}, {ANYCON, $4}
- killreg %a yields %b
- proc leiuxxsei example loe loi inc loe sti
- kills all_mems
- uses ADDREG={EXTERN,$1}
- gen uxx* {indir_r, %a}
- killreg %a
- pat loe loi ngi loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leiuxxsei("neg")
- pat loe loi com loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leiuxxsei("not")
- pat loe loi dec loe sti $1==$4 && $2==4 && $5==4
- call leiuxxsei("dec")
- pat loe loi inc loe sti $1==$4 && $2==4 && $5==4
- call leiuxxsei("inc")
- pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==1
- call leiuxxsei("inc")
- pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==(0-1)
- call leiuxxsei("dec")
- proc leixxxsei example loe loi adi loe sti
- with regorconst
- kills all_mems
- uses ADDREG={EXTERN,$1}
- gen axx* {indir_r, %a}, %1
- killreg %a
- pat loe loi adi loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leixxxsei("add")
- pat loe loi adu loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leixxxsei("add")
- pat loe loi ads loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leixxxsei("add")
- pat loe loi and loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leixxxsei("and")
- pat loe loi ior loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leixxxsei("or")
- pat loe loi xor loe sti $1==$4 && $2==4 && $5==4 && $3==4
- call leixxxsei("xor")
- #ifdef REGVARS
- proc lifuxxsif example lil lof inc lil stf
- kills all_mems
- uses ADDREG={indir_r,regvar($1)}
- gen uxx* {indir_r_off, %a, $2}
- killreg %a
- pat lil lof ngi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifuxxsif("neg")
- pat lil lof com lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifuxxsif("not")
- pat lil lof dec lil stf $1==$4 && $2==$5 && inreg($1)>0
- call lifuxxsif("dec")
- pat lil lof inc lil stf $1==$4 && $2==$5 && inreg($1)>0
- call lifuxxsif("inc")
- proc lifxxxsif example lil lof adi lil stf
- with regorconst
- kills all_mems
- uses ADDREG={indir_r,regvar($1)}
- gen axx* {indir_r_off, %a, $2}, %1
- killreg %a
- pat lil lof adi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifxxxsif("add")
- pat lil lof adu lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifxxxsif("add")
- pat lil lof ads lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifxxxsif("add")
- pat lil lof and lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifxxxsif("and")
- pat lil lof ior lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifxxxsif("or")
- pat lil lof xor lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
- call lifxxxsif("xor")
- proc liiuxxsii example lil loi inc lil sti
- kills all_mems
- uses ADDREG={indir_r,regvar($1)}
- gen uxx* {indir_r, %a}
- killreg %a
- pat lil loi ngi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liiuxxsii("neg")
- pat lil loi com lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liiuxxsii("not")
- pat lil loi dec lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
- call liiuxxsii("dec")
- pat lil loi inc lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
- call liiuxxsii("inc")
- pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==1
- call liiuxxsii("inc")
- pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==(0-1)
- call liiuxxsii("dec")
- proc liixxxsii example lil loi adi lil sti
- with regorconst
- kills all_mems
- uses ADDREG={indir_r,regvar($1)}
- gen axx* {indir_r, %a}, %1
- killreg %a
- pat lil loi adi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liixxxsii("add")
- pat lil loi adu lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liixxxsii("add")
- pat lil loi ads lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liixxxsii("add")
- pat lil loi and lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liixxxsii("and")
- pat lil loi ior lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liixxxsii("or")
- pat lil loi xor lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
- call liixxxsii("xor")
- proc lolcrxxstl example lol loc sbi stl
- kills regvar($1)
- gen axx* {LOCAL,$1,4},{ANYCON,$2}
- pat lol loc sbi stl $1==$4 && $3==4 && inreg($1)==reg_any
- call lolcrxxstl("sub")
- pat lol loc sbu stl $1==$4 && $3==4 && inreg($1)==reg_any
- call lolcrxxstl("sub")
- pat lol loc sli stl $1==$4 && $3==4 && inreg($1)==reg_any
- call lolcrxxstl("sal")
- pat lol loc slu stl $1==$4 && $3==4 && inreg($1)==reg_any
- call lolcrxxstl("sal")
- pat lol loc sri stl $1==$4 && $3==4 && inreg($1)==reg_any
- call lolcrxxstl("sar")
- pat lol loc sru stl $1==$4 && $3==4 && inreg($1)==reg_any
- call lolcrxxstl("shr")
- #endif
- proc lolcxxstl example lol loc sbi stl
- kills indir, locals %ind+%size>$1 && %ind<$1+4
- gen axx* {LOCAL,$1,4},{ANYCON,$2}
- pat lol loc sbi stl $1==$4 && $3==4 call lolcxxstl("sub")
- pat lol loc sbu stl $1==$4 && $3==4 call lolcxxstl("sub")
- pat lol loc adi stl $1==$4 && $3==4 call lolcxxstl("add")
- pat lol loc adi stl $1==$4 && $3==4 call lolcxxstl("add")
- pat lol loc sli stl $1==$4 && $3==4 call lolcxxstl("sal")
- pat lol loc slu stl $1==$4 && $3==4 call lolcxxstl("sal")
- pat lol loc sri stl $1==$4 && $3==4 call lolcxxstl("sar")
- pat lol loc sru stl $1==$4 && $3==4 call lolcxxstl("shr")
- proc loecxxste example loe loc sbi ste
- kills mem_nonlocals
- gen axx* {EXTERN,$1},{ANYCON,$2}
- pat loe loc sbi ste $1==$4 && $3==4 call loecxxste("sub")
- pat loe loc sbu ste $1==$4 && $3==4 call loecxxste("sub")
- pat loe loc adu ste $1==$4 && $3==4 call loecxxste("add")
- pat loe loc adi ste $1==$4 && $3==4 call loecxxste("add")
- pat loe loc sli ste $1==$4 && $3==4 call loecxxste("sal")
- pat loe loc slu ste $1==$4 && $3==4 call loecxxste("sal")
- pat loe loc sri ste $1==$4 && $3==4 call loecxxste("sar")
- pat loe loc sru ste $1==$4 && $3==4 call loecxxste("shr")
- #ifdef REGVARS
- proc lilcxxsil example lil loc sbi sil
- kills mem_nonlocals
- gen axx* {indir_r,regvar($1)},{ANYCON,$2}
- pat lil loc sbi sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sub")
- pat lil loc sbu sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sub")
- pat lil loc adu sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("add")
- pat lil loc adi sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("add")
- pat lil loc sli sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sal")
- pat lil loc slu sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sal")
- pat lil loc sri sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("sar")
- pat lil loc sru sil $1==$4 && $3==4 && inreg($1)>0 call lilcxxsil("shr")
- pat lol ngi stl $1==$3 && $2==4 && inreg($1)==reg_any
- kills regvar($1)
- gen neg {LOCAL, $1, 4}
- #endif
- pat lol ngi stl $1==$3 && $2==4
- kills indir, locals %ind+%size>$1 && %ind<$1+4
- gen neg {LOCAL, $1, 4}
- pat lol dup adp stl loi stl $1==$4 && $2==4 && $5<=4
- leaving lol $1 loi $5 stl $6 lol $1 adp $3 stl $4
- #ifdef REGVARS
- pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==1 && inreg($1) > 0 && $6==1 && $7==4
- uses REG
- gen movsxb %a,{indir_r1, regvar($1)}
- yields %a
- leaving lol $1 adp $3 stl $4
- pat lol dup adp stl loi $1==$4 && $2==4 && $5==1 && inreg($1) > 0
- uses REG1 = {indir_r1, regvar($1)}
- yields %a
- leaving lol $1 adp $3 stl $4
- pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==2 && inreg($1) > 0 && $6==2 && $7==4
- uses REG
- gen movsx %a,{indir_r2, regvar($1)}
- yields %a
- leaving lol $1 adp $3 stl $4
- pat lol dup adp stl loi $1==$4 && $2==4 && $5==2 && inreg($1) > 0
- uses REG2 = {indir_r2, regvar($1)}
- yields %a
- leaving lol $4 adp $3 stl $4
- pat lol dup adp stl loi $1==$4 && $2==4 && $5==4 && inreg($1) > 0
- uses REG = {indir_r, regvar($1)}
- yields %a
- leaving lol $4 adp $3 stl $4
- pat adp stl inreg($2) > 0 leaving stl $2 lol $2 adp $1 stl $2
- #endif
- pat lol dup adp stl $1==$4 && $2==4
- uses ADDREG={LOCAL,$1,4} yields %a
- leaving lol $4 adp $3 stl $4
- pat lol inl $1==$2
- uses REG={LOCAL,$1,4} yields %a
- leaving inl $1
- pat lol del $1==$2
- uses REG={LOCAL,$1,4} yields %a
- leaving del $1
- pat lol adp stl $1==$3 && $2==1 leaving inl $1
- pat lol adp stl $1==$3 && $2==0-1 leaving del $1
- pat lol adp stl $1==$3 leaving loc $2 lol $1 adi 4 stl $3
- #ifdef REGVARS
- pat lol com stl $1==$3 && $2==4 && inreg($1)==reg_any
- kills regvar($1)
- gen not {LOCAL,$1,4}
- #endif
- pat lol com stl $1==$3 && $2==4
- kills indir, locals %ind+%size>$1 && %ind<$1+4
- gen not {LOCAL, $1, 4}
- #ifdef REGVARS
- pat lil dup adp sil $1==$4 && $2==4 && inreg($1)==reg_any
- uses ADDREG={indir_r, regvar($1)}
- yields %a
- leaving lil $4 adp $3 sil $4
- pat lil dup inc sil $1==$4 && $2==4 && inreg($1)==reg_any
- uses REG={indir_r, regvar($1)}
- yields %a
- leaving lil $4 inc sil $4
- pat lil dup dec sil $1==$4 && $2==4 && inreg($1)==reg_any
- uses REG={indir_r, regvar($1)}
- yields %a
- leaving lil $4 dec sil $4
- #endif
- pat lil adp sil $1==$3 && $2==1 leaving lil $1 inc sil $1
- pat lil adp sil $1==$3 && $2==0-1 leaving lil $1 dec sil $1
- pat lil adp sil $1==$3 leaving loc $2 lil $1 adi 4 sil $3
- #ifdef REGVARS
- pat lol lof lol lof adp lol stf
- $1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
- uses ADDREG={indir_r_off, regvar($1), $2}
- yields %a
- leaving lol $1 lof $2 adp $5 lol $6 stf $7
- pat lol lof lol lof inc lol stf
- $1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
- uses REG={indir_r_off, regvar($1), $2}
- yields %a
- leaving lol $1 lof $2 inc lol $6 stf $7
- pat lol lof lol lof dec lol stf
- $1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
- uses REG={indir_r_off, regvar($1), $2}
- yields %a
- leaving lol $1 lof $2 dec lol $6 stf $7
- pat lol lof dup adp lol stf
- $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
- uses REG={indir_r_off, regvar($1), $2}
- yields %a
- leaving lol $1 lof $2 adp $4 lol $1 stf
- $2
- pat lol lof dup inc lol stf
- $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
- uses REG={indir_r_off, regvar($1), $2}
- yields %a
- leaving lol $1 lof $2 inc lol $1 stf $2
- pat lol lof dup dec lol stf
- $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
- uses REG={indir_r_off, regvar($1), $2}
- yields %a
- leaving lol $1 lof $2 dec lol $1 stf $2
- #endif
- pat lol lof adp lol stf $1==$4 && $2==$5
- leaving loc $3 lol $1 lof $2 adi 4 lol $4 stf $5
- pat lol lof dup adp lol stf
- $1==$5 && $2==$6 && $3==4 && $4==1
- kills all_mems
- uses REG={LOCAL,$1,4}, REG
- gen move {indir_r_off, %a, $2},%b
- inc {indir_r_off, %a, $2}
- yields %b
- pat loe lof dup adp loe stf
- $1==$5 && $2==$6 && $3==4 && $4==1
- kills all_mems
- uses REG={EXTERN,$1}, REG
- gen move {indir_r_off, %a, $2},%b
- inc {indir_r_off, %a, $2}
- yields %b
- pat loe loi dup adp loe sti
- $1==$5 && $2==$6 && $3==4 && $2==4 && $4==1
- kills all_mems
- uses REG={EXTERN,$1}, REG
- gen move {indir_r, %a},%b
- inc {indir_r, %a}
- yields %b
- pat lol lof dup adp lol stf
- $1==$5 && $2==$6 && $3==4 && $4==(0-1)
- kills all_mems
- uses REG={LOCAL,$1,4}, REG
- gen move {indir_r_off, %a, $2},%b
- dec {indir_r_off, %a, $2}
- yields %b
- pat loe lof dup adp loe stf
- $1==$5 && $2==$6 && $3==4 && $4==(0-1)
- kills all_mems
- uses REG={EXTERN,$1}, REG
- gen move {indir_r_off, %a, $2},%b
- dec {indir_r_off, %a, $2}
- yields %b
- pat loe loi dup adp loe sti
- $1==$5 && $2==$6 && $3==4 && $2==4 && $4==(0-1)
- kills all_mems
- uses REG={EXTERN,$1}, REG
- gen move {indir_r, %a},%b
- dec {indir_r, %a}
- yields %b
- pat lol lof dup adp lol stf
- $1==$5 && $2==$6 && $3==4
- kills all_mems
- uses REG={LOCAL,$1,4}, REG
- gen move {indir_r_off, %a, $2},%b
- add {indir_r_off, %a, $2}, {ANYCON, $4}
- yields %b
- pat loe lof dup adp loe stf
- $1==$5 && $2==$6 && $3==4
- kills all_mems
- uses REG={EXTERN,$1}, REG
- gen move {indir_r_off, %a, $2},%b
- add {indir_r_off, %a, $2}, {ANYCON, $4}
- yields %b
- pat loe loi dup adp loe sti
- $1==$5 && $2==$6 && $3==4 && $2==4
- kills all_mems
- uses REG={EXTERN,$1}, REG
- gen move {indir_r, %a},%b
- add {indir_r, %a}, {ANYCON, $4}
- yields %b
- pat loe ngi ste $1==$3 && $2==4
- kills mem_nonlocals
- gen neg {EXTERN, $1}
- pat loe dup adp ste $1==$4 && $2==4
- uses REG={EXTERN,$1} yields %a
- leaving loe $1 adp $3 ste $1
- pat loe ine $1==$2
- uses REG={EXTERN,$1} yields %a
- leaving ine $1
- pat loe dee $1==$2
- uses REG={EXTERN,$1} yields %a
- leaving dee $1
- pat loe adp ste $1==$3 && $2==1 leaving ine $1
- pat loe adp ste $1==$3 && $2==0-1 leaving dee $1
- pat loe adp ste $1==$3 leaving loc $2 loe $1 adi 4 ste $3
- pat loe com ste $1==$3 && $2==4
- kills mem_nonlocals
- gen not {EXTERN, $1}
- pat loe lof adp loe stf $1==$4 && $2==$5
- leaving loc $3 loe $1 lof $2 adi 4 loe $1 stf $2
- pat loe loi adp loe sti $1==$4 && $2==$5 && $2==4
- leaving loc $3 loe $1 loi $2 adi 4 loe $1 sti $2
- pat lil lof adp lil stf $1==$4 && $2==$5 && $3==1
- leaving lil $1 lof $2 inc lil $1 stf $2
- pat lil lof adp lil stf $1==$4 && $2==$5 && $3==0-1
- leaving lil $1 lof $2 dec lil $1 stf $2
- pat lil lof adp lil stf $1==$4 && $2==$5
- leaving loc $3 lil $1 lof $2 adi 4 lil $1 stf $2
- pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==1
- leaving lil $1 loi $2 inc lil $1 sti $2
- pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==0-1
- leaving lil $1 loi $2 dec lil $1 sti $2
- pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4
- leaving loc $3 lil $1 loi $2 adi 4 lil $1 sti $2
- /*******************************************************************
- * Group 8: Convert Instructions *
- *******************************************************************/
- pat cii
- with CXREG DXREG ACC
- kills ALL
- gen proccall {label,".cii"} yields %3
- pat ciu leaving cuu
- pat cui leaving cuu
- pat cuu
- pat loc loc cii zeq $1==1
- with GENREG STACK
- gen test %1.1
- je {label, $4}
- pat loc loc cii zne $1==1
- with GENREG STACK
- gen test %1.1
- jne {label, $4}
- pat loc loc cii loc and zeq $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
- leaving loc $4 and $5 zeq $6
- pat loc loc cii loc and zne $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
- leaving loc $4 and $5 zne $6
- pat loc loc cii loc and zeq $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
- leaving loc $4 and $5 zeq $6
- pat loc loc cii loc and zne $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
- leaving loc $4 and $5 zne $6
- pat loc loc cii $1==1 && $2==4
- with ACC
- gen movsxb %1,%1 yields eax
- with exact rm1
- uses reusing %1, GENREG
- gen movsxb %a,%1 yields %a
- pat loc loc cii $1==2 && $2==4
- with ACC
- gen movsx %1,%1 yields eax
- with exact rm2
- uses reusing %1,GENREG
- gen movsx %a,%1 yields %a
- pat loc loc ciu leaving loc $1 loc $2 cuu
- pat loc loc cui leaving loc $1 loc $2 cuu
- pat loc loc cuu $1==$2
- 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
- pat loc loc cff $1==4 && $2==8
- with REG
- kills ALL
- gen push {ANYCON,0}
- push %1 leaving cal ".cff8"
- /********************************************************************
- * Group 9 : Logical Instructions *
- ********************************************************************/
- pat and $1==4
- with REG rmorconst
- gen and %1,%2 yields %1
- with rmorconst REG
- gen and %2,%1 yields %2
- pat loc and $1==255 && $2==4
- with GENREG yields %1.1
- pat and $1==8
- with EXACT REG REG rmorconst rmorconst
- gen and %1,%3
- and %2,%4 yields %2 %1
- with rmorconst rmorconst REG REG
- gen and %3,%1
- and %4,%2 yields %4 %3
- pat and defined($1)
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".and"}
- pat and !defined($1)
- with CXREG
- kills ALL
- gen proccall {label, ".and"}
- pat ior $1==4
- with REG rmorconst
- gen or %1,%2 yields %1
- with rmorconst REG
- gen or %2,%1 yields %2
- pat ior $1==8
- with EXACT REG REG rmorconst rmorconst
- gen or %1,%3
- or %2,%4 yields %2 %1
- with rmorconst rmorconst REG REG
- gen or %3,%1
- or %4,%2 yields %4 %3
- pat ior defined($1)
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".ior"}
- pat ior !defined($1)
- with CXREG
- kills ALL
- gen proccall {label, ".ior"}
- pat xor $1==4
- with REG rmorconst
- gen xor %1,%2 yields %1
- with rmorconst REG
- gen xor %2,%1 yields %2
- pat xor $1==8
- with EXACT REG REG rmorconst rmorconst
- gen xor %1,%3
- xor %2,%4 yields %2 %1
- with rmorconst rmorconst REG REG
- gen xor %3,%1
- xor %4,%2 yields %4 %3
- pat xor defined($1)
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".xor"}
- pat xor !defined($1)
- with CXREG
- kills ALL
- gen proccall {label, ".xor"}
- pat com $1==4
- with REG
- gen not %1 yields %1
- pat com $1==8
- with REG REG
- gen not %2
- not %1 yields %2 %1
- pat com defined($1)
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".com"}
- pat com !defined($1)
- with CXREG
- kills ALL
- gen proccall {label, ".com"}
- pat rol $1==4
- with SHIFT_CREG REG
- gen rol %2,cl yields %2
- with ANYCON REG
- gen rol %2,%1 yields %2
- pat ror $1==4
- with SHIFT_CREG REG
- gen ror %2,cl yields %2
- with ANYCON REG
- gen ror %2,%1 yields %2
- /*******************************************************************
- * Group 10 : Set Instructions *
- *******************************************************************/
- pat inn $1==4
- with SHIFT_CREG REG
- gen shr %2,cl
- and %2,{ANYCON, 1} yields %2
- with ANYCON REG
- gen shr %2,%1
- and %2,{ANYCON, 1} yields %2
- pat loc inn $1==0 && $2==4
- with REG
- gen and %1,{ANYCON, 1} yields %1
- pat inn defined($1)
- with ACC
- kills ALL
- gen mov ecx,{ANYCON, $1}
- proccall {label,".inn"} yields eax
- pat inn !defined($1)
- with CXREG ACC
- kills ALL
- gen proccall {label,".inn"} yields eax
- pat loc inn zeq $2==4
- with rm STACK
- gen check %1,{ANYCON,1<<$1}
- je {label,$3}
- pat loc inn zne $2==4
- with rm STACK
- gen check %1,{ANYCON,1<<$1}
- jne {label,$3}
- pat set $1==4
- with SHIFT_CREG
- uses REG={ANYCON, 1}
- gen shl %a,cl yields %a
- pat set defined($1)
- with ACC
- kills ALL
- gen mov ecx,{ANYCON, $1}
- proccall {label,".set"}
- pat set !defined($1)
- with CXREG ACC
- kills ALL
- gen proccall {label,".set"}
- /********************************************************************
- * Group 11 : Array Instructions *
- ********************************************************************/
- pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0
- leaving ads 4
- pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
- leaving adp 0-rom($1,1) ads 4
- pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)==0
- leaving loc 1 sli 4 ads 4
- pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)!=0
- leaving adp 0-rom($1,1) loc 1 sli 4 ads 4
- pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
- leaving loc 2 sli 4 ads 4
- pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
- leaving adp 0-rom($1,1) loc 2 sli 4 ads 4
- pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)==0
- leaving loc 3 sli 4 ads 4
- pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)!=0
- leaving adp 0-rom($1,1) loc 3 sli 4 ads 4
- pat lae aar $2==4 && rom($1,1)==0
- with ADDREG
- gen imul %1,%1,{ANYCON,rom($1,3)} yields %1 leaving ads 4
- pat lae aar $2==4 && defined(rom($1,1))
- with ADDREG
- gen imul %1,%1,{ANYCON,rom($1,3)} yields %1
- leaving adp 0-rom($1,1)*rom($1,3) ads 4
- /* when followed by an LOI or STI instruction, use indexed mode */
- pat loc sli ads loi ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
- with IREG ADDR_LOCAL yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
- leaving loi $4
- with IREG ADDR_EXTERN yields {indexed_off,%1,1<<$1,%2.off}
- leaving loi $4
- with IREG ADDREG yields {indexed_r_off,%2,%1,1<<$1,0}
- leaving loi $4
- pat loc sli ads sti ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
- with IREG ADDR_LOCAL yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
- leaving sti $4
- with IREG ADDR_EXTERN yields {indexed_off,%1,1<<$1,%2.off}
- leaving sti $4
- with IREG ADDREG yields {indexed_r_off,%2,%1,1<<$1,0}
- leaving sti $4
- pat loc sli ads ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
- with IREG ADDR_LOCAL yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
- with IREG ADDR_EXTERN yields {indexed_off,%1,1<<$1,%2.off}
- with IREG ADDREG yields {indexed_r_off,%2,%1,1<<$1,0}
- with REG rmorconst
- gen sal %1,{ANYCON,$1} yields %2 %1 leaving ads 4
- pat aar $1==4
- with AREG REG
- gen sub %2,{indir_r,%1}
- imul %2,{indir_r_off,%1,8} yields %2 leaving ads 4
- with reg_off REG
- gen sub %2,{indir_r_off, %1.reg, %1.off}
- imul %2,{indir_r_off, %1.reg, 8+%1.off}
- yields %2 leaving ads 4
- with ADDR_LOCAL REG
- gen sub %2,{LOCAL,%1.ind,4}
- imul %2,{LOCAL,8+%1.ind,4} yields %2 leaving ads 4
- with ADDR_EXTERN REG
- gen sub %2,{EXTERN,%1.off}
- imul %2,{EXTERN,8+%1.off} yields %2 leaving ads 4
- pat lae lar defined(rom($1,3)) leaving lae $1 aar $2 loi rom($1,3)
- pat lae sar defined(rom($1,3)) leaving lae $1 aar $2 sti rom($1,3)
- pat aar !defined($1)
- kills ALL
- gen proccall {label,".iaar"} yields ebx
- pat sar $1==4
- with BXREG ACC
- kills ALL
- gen proccall {label,".sar4"}
- pat sar !defined($1)
- kills ALL
- gen proccall {label,".isar"}
- pat lar $1==4
- with BXREG ACC
- kills ALL
- gen proccall {label,".lar4"}
- pat lar !defined($1)
- kills ALL
- gen proccall {label,".ilar"}
- /*******************************************************************
- * Group 12 : Compare Instructions *
- *******************************************************************/
- pat cmi $1==4
- with register rmorconst
- uses REG={ANYCON,0}
- gen cmp %1,%2
- je {label,2f}
- jl {label,1f}
- inc %a
- jmp {label,2f}
- 1:
- dec %a
- 2: yields %a
- with rmorconst register
- uses REG={ANYCON,0}
- gen cmp %2,%1
- je {label,2f}
- jg {label,1f}
- inc %a
- jmp {label,2f}
- 1:
- dec %a
- 2: yields %a
- pat cmu $1==4 leaving cmp
- pat cms $1==4
- with REG rmorconst
- gen sub %1,%2 yields %1
- with rmorconst REG
- gen sub %2,%1 yields %2
- pat cms $1==8
- with rmorconst rmorconst REG REG
- gen sub %3,%1
- sbb %4,%2
- or %4,%3 yields %4
- with REG REG rmorconst rmorconst
- gen sub %1,%3
- sbb %2,%4
- or %2,%1 yields %2
- pat cms defined($1)
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label,".cms"} yields ecx
- pat cms !defined($1)
- with CXREG
- kills ALL
- gen proccall {label,".cms"} yields ecx
- pat cmf $1==4
- kills ALL
- gen proccall {label,".cmf4"} leaving asp 8 lfr 4
- pat cmf $1==8
- kills ALL
- gen proccall {label,".cmf8"} leaving asp 16 lfr 4
- pat cmp
- with register rmorconst
- uses REG = {ANYCON,0}
- gen cmp %1,%2
- je {label,2f}
- jb {label,1f}
- inc %a
- jmp {label,2f}
- 1: dec %a
- 2: yields %a
- with rmorconst register
- uses REG = {ANYCON,0}
- gen cmp %2,%1
- je {label,2f}
- ja {label,1f}
- inc %a
- jmp {label,2f}
- 1: dec %a
- 2: yields %a
- proc txx
- with rm
- uses GENREG = {ANYCON,0}
- gen test %1
- setxx* %a.1 yields %a
- pat tlt call txx("sets")
- pat teq call txx("sete")
- pat tne call txx("setne")
- pat tge call txx("setns")
- /* Explicit test for TLE and TGT. We must make sure that the OC
- flag is cleared.
- */
- pat tle
- with rm
- uses GENREG = {ANYCON,0}
- gen
- killcc.
- test %1
- setle %a.1
- yields %a
- pat tgt
- with rm
- uses GENREG = {ANYCON,0}
- gen
- killcc.
- test %1
- setg %a.1
- yields %a
- proc txxior
- with rm REG
- gen test %1
- jxx* {label,1f}
- or %2,{ANYCON,1}
- 1: yields %2
- pat tlt ior $2==4 call txxior("jge")
- pat tle ior $2==4 call txxior("jg")
- pat teq ior $2==4 call txxior("jne")
- pat tne ior $2==4 call txxior("je")
- pat tge ior $2==4 call txxior("jl")
- pat tgt ior $2==4 call txxior("jle")
- proc cmixxior
- with regorconst rm REG
- gen cmp %2,%1
- jxx* {label,1f}
- or %3,{ANYCON,1}
- 1: yields %3
- pat cmi tlt ior $1==4 && $3==4 call cmixxior("jge")
- pat cmi tle ior $1==4 && $3==4 call cmixxior("jg")
- pat cmi teq ior $1==4 && $3==4 call cmixxior("jne")
- pat cmi tne ior $1==4 && $3==4 call cmixxior("je")
- pat cmi tge ior $1==4 && $3==4 call cmixxior("jl")
- pat cmi tgt ior $1==4 && $3==4 call cmixxior("jle")
- proc cmxtxx
- with regorconst rm
- uses REG = {ANYCON,0}
- gen cmp %2,%1
- jxx[1] {label,1f}
- inc %a
- 1: yields %a
- with rm regorconst
- uses REG = {ANYCON,0}
- gen cmp %1,%2
- jxx[2] {label,1f}
- inc %a
- 1: yields %a
- pat cmi tlt $1==4 call cmxtxx("jge","jle")
- pat cmi tle $1==4 call cmxtxx("jg","jl")
- pat cmi teq $1==4 call cmxtxx("jne","jne")
- pat cmi tne $1==4 call cmxtxx("je","je")
- pat cmi tge $1==4 call cmxtxx("jl","jg")
- pat cmi tgt $1==4 call cmxtxx("jle","jge")
- pat cmp tlt call cmxtxx("jae","jbe")
- pat cmp tle call cmxtxx("ja","jb")
- pat cmp teq call cmxtxx("jne","jne")
- pat cmp tne call cmxtxx("je","je")
- pat cmp tge call cmxtxx("jb","ja")
- pat cmp tgt call cmxtxx("jbe","jae")
- pat cms teq $1==4 call cmxtxx("jne","jne")
- pat cms tne $1==4 call cmxtxx("je","je")
- proc cmxzxx example cmp zlt
- with regorconst rm STACK
- gen cmp %2,%1
- jxx[1] {label,$2}
- with rm regorconst STACK
- gen cmp %1,%2
- jxx[2] {label,$2}
- pat cmp zlt call cmxzxx("jb","ja")
- pat cmp zle call cmxzxx("jbe","jae")
- pat cmp zeq call cmxzxx("je","je")
- pat cmp zne call cmxzxx("jne","jne")
- pat cmp zge call cmxzxx("jae","jbe")
- pat cmp zgt call cmxzxx("ja","jb")
- pat cms zeq $1==4 call cmxzxx("je","je")
- pat cms zne $1==4 call cmxzxx("jne","jne")
- pat cms zne $1==8
- with regorconst regorconst rm rm STACK
- gen cmp %3,%1
- jne {label,$2}
- cmp %4,%2
- jne {label,$2}
- with rm rm regorconst regorconst STACK
- kills ALL
- gen cmp %1,%3
- jne {label,$2}
- cmp %2,%4
- jne {label,$2}
- pat cms zeq $1==8
- with regorconst regorconst rm rm STACK
- gen cmp %3,%1
- jne {label, 1f}
- cmp %4,%2
- je {label,$2}
- 1:
- with rm rm regorconst regorconst STACK
- kills ALL
- gen cmp %1,%3
- jne {label,1f}
- cmp %2,%4
- je {label,$2}
- 1:
- proc andzxx example and zeq
- with regorconst rm STACK
- gen check %2,%1
- jxx* {label,$2}
- with exact rm regorconst
- kills ALL
- gen check %1,%2
- jxx* {label,$2}
- pat and zeq $1==4 call andzxx("je")
- pat and zne $1==4 call andzxx("jne")
- proc locandzxx example loc and zeq
- with rm1 STACK
- gen testb %1,{ANYCON,$1}
- jxx* {label,$3}
- with GENREG STACK
- gen testb %1.1,{ANYCON,$1}
- jxx* {label,$3}
- with exact RREG
- kills ALL
- gen check %1,{ANYCON,$1}
- jxx* {label,$3}
- pat loc and zeq $1<256 && $1>=0 && $2==4 call locandzxx("je")
- pat loc and zne $1<256 && $1>=0 && $2==4 call locandzxx("jne")
- proc locbxx example loc beq
- with rm1 STACK
- gen cmpb %1,{ANYCON,$1}
- jxx* {label,$2}
- with rm STACK
- gen cmp %1,{ANYCON,$1}
- jxx* {label,$2}
- pat loc beq $1<256 && $1>=0 call locbxx("je")
- pat loc bne $1<256 && $1>=0 call locbxx("jne")
- proc loccmuzxx example loc cmu zeq
- with rm1 STACK
- gen cmpb %1,{ANYCON,$1}
- jxx* {label,$3}
- with rm STACK
- gen cmp %1,{ANYCON,$1}
- jxx* {label,$3}
- pat loc cmu zeq $1<256 && $1>=0 && $2==4 call loccmuzxx("je")
- pat loc cmu zne $1<256 && $1>=0 && $2==4 call loccmuzxx("jne")
- /*******************************************************************
- * Group 13 : Branch Instructions *
- *******************************************************************/
- pat lab topeltsize($1)==4 && !fallthrough($1)
- with STACK
- kills ALL
- gen labeldef $1 yields eax
- pat lab topeltsize($1)==4 && fallthrough($1)
- with ACC STACK
- kills ALL
- gen labeldef $1 yields eax
- pat lab topeltsize($1)!=4
- with STACK
- kills ALL
- gen labeldef $1
- pat bra topeltsize($1)==4
- with ACC STACK
- gen jmp {label,$1}
- pat bra topeltsize($1)!=4
- with STACK
- gen jmp {label,$1}
- proc bxx example blt
- with regorconst rm STACK
- gen cmp %2,%1
- jxx[1] {label,$1}
- with rm regorconst STACK
- gen cmp %1,%2
- jxx[2] {label,$1}
- pat blt call bxx("jl","jg")
- pat ble call bxx("jle","jge")
- pat beq call bxx("je","je")
- pat bne call bxx("jne","jne")
- pat bge call bxx("jge","jle")
- pat bgt call bxx("jg","jl")
- proc zxx example zlt
- with rm STACK
- gen test %1
- jxx* {label,$1}
- pat zlt call zxx("js")
- pat zge call zxx("jns")
- /* Explicit test for ZLE and ZGT. We must make sure that the OC
- flag is cleared.
- */
- pat zle
- with rm STACK
- gen
- killcc.
- test %1
- jle {label,$1}
- pat zgt
- with rm STACK
- gen
- killcc.
- test %1
- jg {label, $1}
- pat zne
- with rm+rm1 STACK
- gen test %1
- jne {label,$1}
- pat zeq
- with rm+rm1 STACK
- gen test %1
- je {label,$1}
- /*******************************************************************
- * Group 14 : Procedure-call Instructions *
- *******************************************************************/
- pat cal
- kills ALL
- gen proccall {label,$1}
- pat cai
- with rm
- kills ALL
- gen proccall %1
- #ifdef REGVARS
- pat lfr adi stl $1==4 && $2==4 && inreg($3) > 0
- kills ALL
- gen pop {LOCAL,$3,4}
- add {LOCAL,$3,4}, eax
- #endif
- pat lfr $1==4 yields eax
- pat lfr $1==8 yields edx eax
- pat ret $1==0
- kills ALL
- gen
- #ifdef REGVARS
- return
- #else
- leave.
- ret.
- #endif
- pat ret $1==4
- with ACC
- kills ALL
- gen
- #ifdef REGVARS
- return
- #else
- leave.
- ret.
- #endif
- pat ret $1==8
- with ACC DXREG
- kills ALL
- gen
- #ifdef REGVARS
- return
- #else
- leave.
- ret.
- #endif
- /********************************************************************
- * Group 15 : Miscellaneous Instructions *
- ********************************************************************/
- pat asp $1==4
- with exact a_word
- with STACK
- uses CXREG /* GENREG may contain lfr area */
- gen pop %a
- pat asp $1==8
- with exact a_word a_word
- with STACK
- uses CXREG /* GENREG may contain lfr area */
- gen pop %a
- pop %a
- pat asp $1==0-4
- with STACK yields ebp
- pat asp
- with STACK
- gen add esp,{ANYCON,$1}
- pat ass $1==4
- with rmorconst STACK
- gen add esp,%1
- pat ass !defined($1)
- with rm rmorconst STACK
- gen cmp %1,{ANYCON,4}
- jne {label, ".unknown"}
- add esp,%2
- pat blm $1==0 leaving asp 4
- pat blm $1>0
- kills ALL
- gen mov ecx,{ANYCON,$1/4}
- proccall {label, ".blm"}
- pat bls $1==4
- with CXREG
- kills ALL
- gen sar ecx,{ANYCON,2}
- proccall {label, ".blm"}
- pat bls !defined($1)
- with rm-CXREG CXREG
- kills ALL
- gen cmp %1,{ANYCON,4}
- jne {label, ".unknown"}
- sar ecx,{ANYCON,2}
- proccall {label, ".blm"}
- pat csa $1==4
- with BXREG ACC
- kills ALL
- gen jmp {label, ".csa4"}
- pat csa !defined($1)
- with rm-BXREG-ACC BXREG ACC
- kills ALL
- gen cmp %1,{ANYCON,4}
- jne {label, ".unknown"}
- jmp {label, ".csa4"}
- pat csb $1==4
- with BXREG ACC
- kills ALL
- gen jmp {label, ".csb4"}
- pat csb !defined($1)
- with rm-BXREG-ACC BXREG ACC
- gen cmp %1,{ANYCON,4}
- jne {label, ".unknown"}
- jmp {label, ".csb4"}
- pat dup $1==4
- with anyreg yields %1 %1
- with ACC1 yields %1 %1
- pat dup $1==8
- with regorconst regorconst yields %2 %1 %2 %1
- pat dup
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".dup"}
- pat dus $1==4
- with CXREG
- kills ALL
- gen proccall {label, ".dup"}
- pat dus !defined($1)
- with rm-CXREG CXREG
- kills ALL
- gen cmp %1,{ANYCON,4}
- jne {label, ".unknown"}
- proccall {label, ".dup"}
- pat exg $1==4
- with a_word a_word yields %1 %2
- pat exg $1==8
- with a_word a_word a_word a_word yields %2 %1 %4 %3
- pat exg defined($1)
- kills ALL
- gen mov ecx,{ANYCON,$1}
- proccall {label, ".exg"}
- pat exg
- with CXREG
- kills ALL
- gen proccall {label, ".exg"}
- pat gto
- kills ALL
- gen mov ebx,{ADDR_EXTERN,$1}
- jmp {label, ".gto"}
- pat fil
- gen mov {EXTERN,"hol0+4"},{ADDR_EXTERN,$1}
- pat lim
- uses REG
- gen mov %a,{EXTERN,".ignmask"} yields %a
- pat lin
- gen mov {EXTERN,"hol0"},{ANYCON,$1}
- pat lni
- gen inc {EXTERN,"hol0"}
- pat lor $1==0 yields ebp
- pat lor $1==1
- with STACK
- uses REG
- gen mov %a,esp yields %a
- pat lor $1==2
- uses REG
- gen mov %a,{EXTERN,".reghp"} yields %a
- pat mon
- with ACC
- kills ALL
- gen proccall {label, ".mon"}
- pat nop
- kills ALL
- #ifdef DEBUG
- gen proccall {label, ".nop"}
- #endif
- pat rck $1==4
- with BXREG ACC
- kills ALL
- gen proccall {label, ".rck"} yields eax
- pat rck !defined($1)
- with rm-BXREG-ACC BXREG ACC
- kills ALL
- gen cmp %1,{ANYCON,4}
- jne {label, ".unknown"}
- proccall {label, ".rck"} yields eax
- pat rtt leaving ret 0
- pat sig
- with REG
- gen xchg {EXTERN,".trppc"},%1 yields %1
- pat sim
- with regorconst
- gen mov {EXTERN,".ignmask"},%1
- pat str $1==0
- with rmorconst
- gen mov ebp,%1
- pat str $1==1
- with rmorconst STACK
- gen mov esp,%1
- pat str $1==2
- kills ALL
- gen proccall {label, ".strhp"}
- pat trp
- with ACC
- kills ALL
- gen proccall {label, ".Xtrp"}
|