123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160 |
- EM_WSIZE = 4
- EM_PSIZE = 4
- EM_BSIZE = 8 /* two words saved in call frame */
- INT8 = 1 /* Size of values */
- INT16 = 2
- INT32 = 4
- INT64 = 8
- FP_OFFSET = 0 /* Offset of saved FP relative to our FP */
- PC_OFFSET = 4 /* Offset of saved PC relative to our FP */
- #define COMMENT(n) /* noop */
- #define nicesize(x) ((x)==INT8 || (x)==INT16 || (x)==INT32 || (x)==INT64)
- #define smalls(n) sfit(n, 16)
- #define smallu(n) ufit(n, 16)
- #define lo(n) (n & 0xFFFF)
- #define hi(n) ((n>>16) & 0xFFFF)
- /* Use these for instructions that treat the low half as signed --- his()
- * includes a modifier to produce the correct value when the low half gets
- * sign extended. Er, do make sure you load the low half second. */
- #define los(n) (n & 0xFFFF)
- #define his(n) ((hi(n) - (lo(n)>>15)) & 0xFFFF)
- #define IFFALSE {CONST, 4}
- #define IFTRUE {CONST, 12}
- #define ALWAYS {CONST, 20}
- #define DCTRZ {CONST, 34}
- #define LT {CONST, 0}
- #define GT {CONST, 1}
- #define EQ {CONST, 2}
- PROPERTIES
- GPR /* any GPR */
- REG /* any allocatable GPR */
- FPR /* any FPR */
- FREG /* any allocatable FPR */
- SPR /* any SPR */
- CR /* any CR */
-
- GPR0 GPRSP GPRFP GPR3 GPR4 GPR5 GPR6 GPR7
- GPR8 GPR9 GPR10 GPR11 GPR12 GPR13 GPR14 GPR15
- GPR16 GPR17 GPR18 GPR19 GPR20 GPR21 GPR22 GPR23
- GPR24 GPR25 GPR26 GPR27 GPR28 GPR29 GPR30 GPR31
-
- CR0 CR1
- FPR0 FPR1 FPR2 FPR3 FPR4 FPR5 FPR6 FPR7
- FPR8 FPR9 FPR10 FPR11 FPR12 FPR13 FPR14 FPR15
- FPR16 FPR17 FPR18 FPR19 FPR20 FPR21 FPR22 FPR23
- FPR24 FPR25 FPR26 FPR27 FPR28 FPR29 FPR30 FPR31
- REGISTERS
- /* Reverse order to encourage ncg to allocate them from r31 down */
-
- R31("r31") : GPR, REG, GPR31 regvar.
- R30("r30") : GPR, REG, GPR30 regvar.
- R29("r29") : GPR, REG, GPR29 regvar.
- R28("r28") : GPR, REG, GPR28 regvar.
- R27("r27") : GPR, REG, GPR27 regvar.
- R26("r26") : GPR, REG, GPR26 regvar.
- R25("r25") : GPR, REG, GPR25 regvar.
- R24("r24") : GPR, REG, GPR24 regvar.
- R23("r23") : GPR, REG, GPR23 regvar.
- R22("r22") : GPR, REG, GPR22 regvar.
- R21("r21") : GPR, REG, GPR21 regvar.
- R20("r20") : GPR, REG, GPR20 regvar.
- R19("r19") : GPR, REG, GPR19 regvar.
- R18("r18") : GPR, REG, GPR18 regvar.
- R17("r17") : GPR, REG, GPR17 regvar.
- R16("r16") : GPR, REG, GPR16 regvar.
- R15("r15") : GPR, REG, GPR15 regvar.
- R14("r14") : GPR, REG, GPR14 regvar.
- R13("r13") : GPR, REG, GPR13 regvar.
- R12("r12") : GPR, REG, GPR12.
- R11("r11") : GPR, GPR11.
- R10("r10") : GPR, REG, GPR10.
- R9("r9") : GPR, REG, GPR9.
- R8("r8") : GPR, REG, GPR8.
- R7("r7") : GPR, REG, GPR7.
- R6("r6") : GPR, REG, GPR6.
- R5("r5") : GPR, REG, GPR5.
- R4("r4") : GPR, REG, GPR4.
- R3("r3") : GPR, REG, GPR3.
- FP("fp") : GPR, GPRFP.
- SP("sp") : GPR, GPRSP.
- R0("r0") : GPR, GPR0.
- F31("f31") : FPR, FREG, FPR31.
- F30("f30") : FPR, FREG, FPR30.
- F29("f29") : FPR, FREG, FPR29.
- F28("f28") : FPR, FREG, FPR28.
- F27("f27") : FPR, FREG, FPR27.
- F26("f26") : FPR, FREG, FPR26.
- F25("f25") : FPR, FREG, FPR25.
- F24("f24") : FPR, FREG, FPR24.
- F23("f23") : FPR, FREG, FPR23.
- F22("f22") : FPR, FREG, FPR22.
- F21("f21") : FPR, FREG, FPR21.
- F20("f20") : FPR, FREG, FPR20.
- F19("f19") : FPR, FREG, FPR19.
- F18("f18") : FPR, FREG, FPR18.
- F17("f17") : FPR, FREG, FPR17.
- F16("f16") : FPR, FREG, FPR16.
- F15("f15") : FPR, FREG, FPR15.
- F14("f14") : FPR, FREG, FPR14.
- F13("f13") : FPR, FREG, FPR13.
- F12("f12") : FPR, FREG, FPR12.
- F11("f11") : FPR, FREG, FPR11.
- F10("f10") : FPR, FREG, FPR10.
- F9("f9") : FPR, FREG, FPR9.
- F8("f8") : FPR, FREG, FPR8.
- F7("f7") : FPR, FREG, FPR7.
- F6("f6") : FPR, FREG, FPR6.
- F5("f5") : FPR, FREG, FPR5.
- F4("f4") : FPR, FREG, FPR4.
- F3("f3") : FPR, FREG, FPR3.
- F2("f2") : FPR, FREG, FPR2.
- F1("f1") : FPR, FREG, FPR1.
- F0("f0") : FPR, FREG, FPR0.
- LR("lr") : SPR.
- CTR("ctr") : SPR.
- C0("cr0") : CR, CR0.
- #define SCRATCH R11
- #define FSCRATCH F0
- TOKENS
- /* Used only in instruction descriptions (to generate the correct syntax). */
- GPRINDIRECT = { GPR reg; INT off; } 4 off "(" reg ")".
- GPRINDIRECTLO = { GPR reg; ADDR adr; } 4 ">" adr "(" reg ")". /* Warning! Do not use on labels. */
- HILABEL = { ADDR adr; } 4 "<" adr.
- LOLABEL = { ADDR adr; } 4 ">" adr.
- /* Primitives */
- LABEL = { ADDR adr; } 4 adr.
- CONST = { INT val; } 4 val.
- LOCAL = { INT off; } 4.
- /* Allows us to use regvar() to refer to registers */
- GPRE = { GPR reg; } 4 reg.
- /* Expression partial results */
-
- SUM_RC = { GPR reg; INT off; } 4.
- SUM_RR = { GPR reg1; GPR reg2; } 4.
-
- TRISTATE_RC_S = { GPR reg; INT val; } 4.
- TRISTATE_RC_U = { GPR reg; INT val; } 4.
- TRISTATE_RR_S = { GPR reg1; GPR reg2; } 4.
- TRISTATE_RR_U = { GPR reg1; GPR reg2; } 4.
-
- TRISTATE_FF = { FPR reg1; FPR reg2; } 4.
-
- SEX_B = { GPR reg; } 4.
- SEX_H = { GPR reg; } 4.
-
- IND_RC_B = { GPR reg; INT off; } 4.
- IND_RC_H = { GPR reg; INT off; } 4.
- IND_RC_H_S = { GPR reg; INT off; } 4.
- IND_RC_W = { GPR reg; INT off; } 4.
- IND_RR_W = { GPR reg1; GPR reg2; } 4.
- IND_LABEL_W = { ADDR adr; } 4.
- IND_RC_D = { GPR reg; INT off; } 8.
- IND_RR_D = { GPR reg1; GPR reg2; } 8.
- IND_LABEL_D = { ADDR adr; } 8.
-
- NOT_R = { GPR reg; } 4.
-
- AND_RR = { GPR reg1; GPR reg2; } 4.
- AND_RC = { GPR reg; INT val; } 4.
- OR_RR = { GPR reg1; GPR reg2; } 4.
- OR_RC = { GPR reg; INT val; } 4.
- XOR_RR = { GPR reg1; GPR reg2; } 4.
- XOR_RC = { GPR reg; INT val; } 4.
- /* Floats */
- FD = { FPR reg; } 8 reg.
- FS = { FPR reg; } 4 reg.
-
- /* Comments */
- LABELI = { ADDR msg; INT num; } 4 msg " " num.
- SETS
- TOKEN = LABEL + CONST + LOCAL.
- GPRI = GPR + GPRE.
-
- SUM_ALL = SUM_RC + SUM_RR.
-
- TRISTATE_ALL = TRISTATE_RC_S + TRISTATE_RC_U + TRISTATE_RR_S +
- TRISTATE_RR_U + TRISTATE_FF.
-
- SEX_ALL = SEX_B + SEX_H.
-
- LOGICAL_ALL = NOT_R + AND_RR + AND_RC + OR_RR + OR_RC + XOR_RR +
- XOR_RC.
-
- IND_ALL_W = IND_RC_W + IND_RR_W + IND_LABEL_W.
- IND_ALL_D = IND_RC_D + IND_RR_D + IND_LABEL_D.
-
- OP_ALL_W = SUM_ALL + TRISTATE_ALL + SEX_ALL + LOGICAL_ALL +
- IND_ALL_W.
- INSTRUCTIONS
- add GPRI:wo, GPRI:ro, GPRI:ro.
- addX "add." GPRI:wo, GPRI:ro, GPRI:ro.
- addi GPRI:wo, GPRI:ro, CONST:ro.
- addis GPRI:wo, GPRI:ro, CONST+HILABEL:ro.
- and GPRI:wo, GPRI:ro, GPRI:ro.
- andc GPRI:wo, GPRI:ro, GPRI:ro.
- andiX "andi." GPRI:wo, GPRI:ro, CONST:ro kills :cc.
- andisX "andis." GPRI:wo, GPRI:ro, CONST:ro kills :cc.
- b LABEL:ro.
- bc CONST:ro, CONST:ro, LABEL:ro.
- bcctr CONST:ro, CONST:ro, CONST:ro.
- bcctrl CONST:ro, CONST:ro, CONST:ro.
- bclr CONST:ro, CONST:ro, CONST:ro.
- bl LABEL:ro.
- cmp CR:ro, CONST:ro, GPRI:ro, GPR:ro kills :cc.
- cmpi CR:ro, CONST:ro, GPRI:ro, CONST:ro kills :cc.
- cmpl CR:ro, CONST:ro, GPRI:ro, GPR:ro kills :cc.
- cmpli CR:ro, CONST:ro, GPRI:ro, CONST:ro kills :cc.
- divw GPRI:wo, GPRI:ro, GPRI:ro.
- divwu GPRI:wo, GPRI:ro, GPRI:ro.
- eqv GPRI:wo, GPRI:ro, GPRI:ro.
- extsb GPRI:wo, GPRI:ro.
- extsh GPRI:wo, GPRI:ro.
- fadd FD:wo, FD:ro, FD:ro.
- fadds FS:wo, FS:ro, FS:ro.
- fcmpo CR:wo, FD:ro, FD:ro.
- fdiv FD:wo, FD:ro, FD:ro.
- fdivs FS:wo, FS:ro, FS:ro.
- fneg FS+FD:wo, FS+FD:ro.
- fmul FD:wo, FD:ro, FD:ro.
- fmuls FS:wo, FS:ro, FS:ro.
- frsp FS:wo, FD:ro.
- fsub FD:wo, FD:ro, FD:ro.
- fsubs FS:wo, FS:ro, FS:ro.
- fmr FS+FD:wo, FS+FD:ro.
- lbzx GPRI:wo, GPR:ro, GPR:ro.
- lbz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lfd FD:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lfdu FD:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lfdx FD:wo, GPR:ro, GPR:ro.
- lfs FS:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lfsu FS:wo, GPRINDIRECT+GPRINDIRECTLO:rw.
- lfsx FS:wo, GPR:ro, GPR:ro.
- lhzx GPRI:wo, GPR:ro, GPR:ro.
- lhax GPRI:wo, GPR:ro, GPR:ro.
- lha GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lhz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lwzu GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- lwzx GPRI:wo, GPR:ro, GPR:ro.
- lwz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
- nand GPRI:wo, GPRI:ro, GPRI:ro.
- neg GPRI:wo, GPRI:ro.
- nor GPRI:wo, GPRI:ro, GPRI:ro.
- mfcr GPRI:wo.
- mullw GPRI:wo, GPRI:ro, GPRI:ro.
- mfspr GPRI:wo, SPR:ro.
- mtspr SPR:wo, GPRI:ro.
- or GPRI:wo, GPRI:ro, GPRI:ro.
- orc GPRI:wo, GPRI:ro, GPRI:ro.
- ori GPRI:wo, GPRI:ro, CONST+LOLABEL:ro.
- orX "or." GPRI:wo, GPRI:ro, GPRI:ro kills :cc.
- rlwinm GPRI:wo, GPRI:ro, CONST:ro, CONST:ro, CONST:ro.
- slw GPRI:wo, GPRI:ro, GPRI:ro.
- subf GPRI:wo, GPRI:ro, GPRI:ro.
- sraw GPRI:wo, GPRI:ro, GPRI:ro.
- srawi GPRI:wo, GPRI:ro, CONST:ro.
- srw GPRI:wo, GPRI:ro, GPRI:ro.
- stb GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- stbx GPRI:ro, GPR:ro, GPR:ro.
- stfd FD:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- stfdu FD:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- stfdx FD:ro, GPR:ro, GPR:ro.
- stfs FS:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- stfsu FS:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- stfsx FS:ro, GPR:ro, GPR:ro.
- sth GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- sthx GPRI:ro, GPR:ro, GPR:ro.
- stw GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- stwx GPRI:ro, GPR:ro, GPR:ro.
- stwu GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
- xor GPRI:wo, GPRI:ro, GPRI:ro.
- xori GPRI:wo, GPRI:ro, CONST:ro.
- gpr_gpr_gpr GPRI:wo, GPRI:ro, GPRI:ro.
- gpr_gpr_si GPRI:wo, GPRI:ro, CONST:ro.
- gpr_ro_gprindirect GPRI:ro, GPRINDIRECT:rw.
- gpr_ro_gpr_gpr GPRI:ro, GPRI:ro, GPRI:ro.
- gpr_wo_gprindirect GPRI:wo, GPRINDIRECT:ro.
- gpr_wo_gpr_gpr GPRI:wo, GPRI:ro, GPRI:ro.
-
- invalid "invalid".
- comment "!" LABEL+LABELI:ro.
-
- MOVES
- from GPR to GPR
- gen
- COMMENT("move GPR->GPR")
- or %2, %1, %1
- /* GPRE exists solely to allow us to use regvar() (which can only be used in
- an expression) as a register constant. */
-
- from GPR to GPRE
- gen
- COMMENT("move GPR->GPRE")
- or %2, %1, %1
-
- /* Constants */
- from CONST smalls(%val) to GPR
- gen
- COMMENT("move CONST->GPRE")
- addi %2, R0, {CONST, lo(%1.val)}
-
- from CONST to GPR
- gen
- COMMENT("move CONST->GPRE")
- addis %2, R0, {CONST, hi(%1.val)}
- ori %2, %2, {CONST, lo(%1.val)}
-
- from LABEL to GPR
- gen
- COMMENT("move LABEL->GPR")
- addis %2, R0, {HILABEL, %1.adr}
- ori %2, %2, {LOLABEL, %1.adr}
-
- /* Sign extension */
- from SEX_B to GPR
- gen
- COMMENT("move SEX_B->GPR")
- extsb %2, %1.reg
-
- from SEX_H to GPR
- gen
- COMMENT("move SEX_H->GPR")
- extsh %2, %1.reg
-
- /* Register + something */
- from SUM_RC smalls(%off) to GPR
- gen
- COMMENT("move SUM_RC->GPR smalls")
- addi %2, %1.reg, {CONST, lo(%1.off)}
-
- from SUM_RC to GPR
- gen
- COMMENT("move SUM_RC->GPR large")
- addi %2, %1.reg, {CONST, los(%1.off)}
- addis %2, %2, {CONST, his(%1.off)}
-
- from SUM_RR to GPR
- gen
- COMMENT("move SUM_RR->GPR")
- add %2, %1.reg1, %1.reg2
-
- from SUM_RR to GPR
- gen
- COMMENT("move SUM_RR->GPRE")
- add %2, %1.reg1, %1.reg2
-
- /* Read/write byte */
- from IND_RC_B smalls(%off) to GPR
- gen
- COMMENT("move IND_RC_B->GPR small")
- lbz %2, {GPRINDIRECT, %1.reg, %1.off}
-
- from IND_RC_B to GPR
- gen
- COMMENT("move IND_RC_B->GPR large")
- addis SCRATCH, %1.reg, {CONST, his(%1.off)}
- lbz %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
-
- from GPR to IND_RC_B smalls(%off)
- gen
- COMMENT("move GPR->IND_RC_B small")
- stb %1, {GPRINDIRECT, %2.reg, %2.off}
-
- from GPR to IND_RC_B
- gen
- COMMENT("move GPR->IND_RC_B large")
- addis SCRATCH, %2.reg, {CONST, his(%2.off)}
- stb %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
-
- /* Read/write short */
- from IND_RC_H smalls(%off) to GPR
- gen
- COMMENT("move IND_RC_H->GPR small")
- lhz %2, {GPRINDIRECT, %1.reg, %1.off}
-
- from IND_RC_H to GPR
- gen
- COMMENT("move IND_RC_H->GPR large")
- addis SCRATCH, %1.reg, {CONST, his(%1.off)}
- lhz %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
-
- from IND_RC_H_S smalls(%off) to GPR
- gen
- COMMENT("move IND_RC_H_S->GPR small")
- lha %2, {GPRINDIRECT, %1.reg, %1.off}
-
- from IND_RC_H_S to GPR
- gen
- COMMENT("move IND_RC_H_S->GPR large")
- addis SCRATCH, %1.reg, {CONST, his(%1.off)}
- lha %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
-
- from GPR to IND_RC_H smalls(%off)
- gen
- COMMENT("move GPR->IND_RC_H small")
- sth %1, {GPRINDIRECT, %2.reg, %2.off}
-
- from GPR to IND_RC_H
- gen
- COMMENT("move GPR->IND_RC_H large")
- addis SCRATCH, %2.reg, {CONST, his(%2.off)}
- sth %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
-
- /* Read word */
- from IND_RC_W smalls(%off) to GPR
- gen
- COMMENT("move IND_RC_W->GPR small")
- lwz %2, {GPRINDIRECT, %1.reg, %1.off}
-
- from IND_RC_W to GPR
- gen
- COMMENT("move IND_RC_W->GPR large")
- addis %2, %1.reg, {CONST, his(%1.off)}
- lwz %2, {GPRINDIRECT, %2, los(%1.off)}
- from IND_RR_W to GPR
- gen
- COMMENT("move IND_RR_W->GPR")
- lwzx %2, %1.reg1, %1.reg2
-
- from IND_LABEL_W to GPR
- gen
- COMMENT("move IND_LABEL_W->GPR")
- move {LABEL, %1.adr}, SCRATCH
- lwz %2, {GPRINDIRECT, SCRATCH, 0}
-
- from IND_RC_W smalls(%off) to FS
- gen
- COMMENT("move IND_RC_W->FS small")
- lfs %2, {GPRINDIRECT, %1.reg, %1.off}
-
- from IND_RC_W to FS
- gen
- COMMENT("move IND_RC_W->FS large")
- addis SCRATCH, %1.reg, {CONST, his(%1.off)}
- lfs %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
- from IND_RR_W to FS
- gen
- COMMENT("move IND_RR_W->FS")
- lfsx %2, %1.reg1, %1.reg2
-
- from IND_LABEL_W to FS
- gen
- COMMENT("move IND_LABEL_W->FS")
- move {LABEL, %1.adr}, SCRATCH
- lfs %2, {GPRINDIRECT, SCRATCH, 0}
-
- /* Write word */
- from GPR to IND_RC_W smalls(%off)
- gen
- COMMENT("move GPR->IND_RC_W small")
- stw %1, {GPRINDIRECT, %2.reg, %2.off}
-
- from GPR to IND_RC_W
- gen
- COMMENT("move GPR->IND_RC_W large")
- addis SCRATCH, %2.reg, {CONST, his(%2.off)}
- stw %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
- from GPR to IND_RR_W
- gen
- COMMENT("move GPR->IND_RR_W")
- stwx %1, %2.reg1, %2.reg2
-
- from GPR to IND_LABEL_W
- gen
- COMMENT("move GPR->IND_LABEL_D")
- move {LABEL, %2.adr}, SCRATCH
- stw %1, {GPRINDIRECT, SCRATCH, 0}
-
- from FS to IND_RC_W smalls(%off)
- gen
- COMMENT("move FS->IND_RC_W small")
- stfs %1, {GPRINDIRECT, %2.reg, %2.off}
-
- from FS to IND_RC_W
- gen
- COMMENT("move FS->IND_RC_W large")
- addis SCRATCH, %2.reg, {CONST, his(%2.off)}
- stfs %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
- from FS to IND_RR_W
- gen
- COMMENT("move FS->IND_RR_W")
- stfsx %1, %2.reg1, %2.reg2
- from FS to IND_LABEL_W
- gen
- COMMENT("move FS->IND_LABEL_D")
- move {LABEL, %2.adr}, SCRATCH
- stfs %1, {GPRINDIRECT, SCRATCH, 0}
-
- /* Read double */
- from IND_RC_D smalls(%off) to FD
- gen
- COMMENT("move IND_RC_D->FD small")
- lfd %2, {GPRINDIRECT, %1.reg, %1.off}
-
- from IND_RC_D to FD
- gen
- COMMENT("move IND_RC_D->FD large")
- addis SCRATCH, %1.reg, {CONST, his(%1.off)}
- lfd %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
-
- from IND_RR_D to FD
- gen
- COMMENT("move IND_RR_D->FD")
- lfdx %2, %1.reg1, %1.reg2
- from IND_LABEL_D to FD
- gen
- COMMENT("move IND_LABEL_D->FD")
- move {LABEL, %1.adr}, SCRATCH
- lfd %2, {GPRINDIRECT, SCRATCH, 0}
-
- /* Write double */
- from FD to IND_RC_D smalls(%off)
- gen
- COMMENT("move FD->IND_RC_D small")
- stfd %1, {GPRINDIRECT, %2.reg, %2.off}
-
- from FD to IND_RC_D
- gen
- COMMENT("move FD->IND_RC_D large")
- addis SCRATCH, %2.reg, {CONST, his(%2.off)}
- stfd %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
- from FD to IND_RR_D
- gen
- COMMENT("move FD->IND_RR_W")
- stfdx %1, %2.reg1, %2.reg2
-
- from FD to IND_LABEL_D
- gen
- COMMENT("move FD->IND_LABEL_D")
- move {LABEL, %2.adr}, SCRATCH
- stfd %1, {GPRINDIRECT, SCRATCH, 0}
-
- /* Extract condition code field (actually produces (CC&3)<<2) */
- from CR0 to GPR
- gen
- COMMENT("move CR0->GPR")
- mfcr %2
- rlwinm %2, %2, {CONST, 4}, {CONST, 32-4}, {CONST, 31-2}
- /* Comparisons */
- from TRISTATE_RR_S to CR0
- gen
- cmp %2, {CONST, 0}, %1.reg1, %1.reg2
-
- from TRISTATE_RR_U to CR0
- gen
- cmpl %2, {CONST, 0}, %1.reg1, %1.reg2
-
- from TRISTATE_RC_S to CR0
- gen
- COMMENT("move TRISTATE_RC_S->CR0 large")
- move {CONST, %1.val}, SCRATCH
- cmp %2, {CONST, 0}, %1.reg, SCRATCH
-
- from TRISTATE_RC_U smallu(%val) to CR0
- gen
- COMMENT("move TRISTATE_RC_U->CR0 small")
- cmpli %2, {CONST, 0}, %1.reg, {CONST, %1.val}
-
- from TRISTATE_RC_U to CR0
- gen
- COMMENT("move TRISTATE_RC_U->CR0")
- move {CONST, %1.val}, SCRATCH
- cmpl %2, {CONST, 0}, %1.reg, SCRATCH
-
- from TRISTATE_FF to CR0
- gen
- COMMENT("move TRISTATE_FF->CR0")
- fcmpo %2, {FD, %1.reg1}, {FD, %1.reg2}
-
- from GPR to CR0
- gen
- COMMENT("move GPR->CR0")
- orX SCRATCH, %1, %1 /* alas, can't call test */
-
- from TRISTATE_RR_S + TRISTATE_RC_S + TRISTATE_FF to GPR
- gen
- COMMENT("move TRISTATE_R*_S->GPR")
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tristate_s_table"}, %2
- lwzx %2, %2, SCRATCH
- from TRISTATE_RR_U + TRISTATE_RC_U to GPR
- gen
- COMMENT("move TRISTATE_R*_U->GPR")
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tristate_u_table"}, %2
- lwzx %2, %2, SCRATCH
- /* Logicals */
- from NOT_R to GPR
- gen
- COMMENT("move NOT_R->GPR")
- nor %2, %1.reg, %1.reg
- from AND_RR to GPR
- gen
- COMMENT("move AND_RR->GPR")
- and %2, %1.reg1, %1.reg2
- from AND_RC smallu(%val) to GPR
- gen
- COMMENT("move AND_RC->GPR small")
- andiX %2, %1.reg, {CONST, %1.val}
- from AND_RC to GPR
- gen
- COMMENT("move AND_RC->GPR")
- move {CONST, %1.val}, SCRATCH
- and %2, %1.reg, SCRATCH
- from OR_RR to GPR
- gen
- COMMENT("move OR_RR->GPR")
- or %2, %1.reg1, %1.reg2
- from OR_RC smallu(%val) to GPR
- gen
- COMMENT("move OR_RC->GPR small")
- ori %2, %1.reg, {CONST, %1.val}
- from OR_RC to GPR
- gen
- COMMENT("move OR_RC->GPR")
- move {CONST, %1.val}, SCRATCH
- or %2, %1.reg, SCRATCH
- from XOR_RR to GPR
- gen
- COMMENT("move XOR_RR->GPR")
- xor %2, %1.reg1, %1.reg2
- from XOR_RC smallu(%val) to GPR
- gen
- COMMENT("move XOR_RC->GPR small")
- xori %2, %1.reg, {CONST, %1.val}
- from XOR_RC to GPR
- gen
- COMMENT("move XOR_RC->GPR")
- move {CONST, %1.val}, SCRATCH
- xor %2, %1.reg, SCRATCH
- /* Miscellaneous */
- from OP_ALL_W + LABEL + CONST to GPRE
- gen
- move %1, %2.reg
-
- TESTS
-
- to test GPR
- gen
- orX SCRATCH, %1, %1
- STACKINGRULES
-
- from GPR to STACK
- gen
- COMMENT("stack GPR")
- stwu %1, {GPRINDIRECT, SP, 0-4}
-
- from CONST to STACK
- uses REG
- gen
- COMMENT("stack CONST")
- move %1, %a
- stwu %a, {GPRINDIRECT, SP, 0-4}
-
- from LABEL to STACK
- uses REG
- gen
- COMMENT("stack LABEL")
- move %1, {GPRE, %a}
- stwu %a, {GPRINDIRECT, SP, 0-4}
-
- from SEX_B to STACK
- gen
- COMMENT("stack SEX_B")
- extsb SCRATCH, %1.reg
- stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
-
- from SEX_H to STACK
- gen
- COMMENT("stack SEX_H")
- extsh SCRATCH, %1.reg
- stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
-
- from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL to STACK
- gen
- move %1, {GPRE, SCRATCH}
- stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
-
- from IND_ALL_W to STACK
- gen
- move %1, SCRATCH
- stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
-
- from IND_ALL_D to STACK
- gen
- move %1, {FD, FSCRATCH}
- stfdu {FD, FSCRATCH}, {GPRINDIRECT, SP, 0-8}
-
- from FD to STACK
- gen
- COMMENT("stack FD")
- stfdu %1, {GPRINDIRECT, SP, 0-8}
-
- from FS to STACK
- gen
- COMMENT("stack FS")
- stfsu %1, {GPRINDIRECT, SP, 0-4}
-
- from TOKEN to STACK
- gen
- invalid.
-
-
-
- COERCIONS
- from REG
- uses REG
- gen
- COMMENT("coerce REG->REG")
- move %1, %a
- yields %a
-
- from CONST
- uses REG
- gen
- COMMENT("coerce CONST->REG")
- move %1, %a
- yields %a
-
- from LABEL
- uses REG
- gen
- COMMENT("coerce LABEL->REG")
- move %1, {GPRE, %a}
- yields %a
-
- from STACK
- uses REG
- gen
- COMMENT("coerce STACK->REG")
- lwz %a, {GPRINDIRECT, SP, 0}
- addi SP, SP, {CONST, 4}
- yields %a
-
- from SEX_B
- uses REG
- gen
- COMMENT("coerce SEX_B->REG")
- extsb %a, %1.reg
- yields %a
-
- from SEX_H
- uses REG
- gen
- COMMENT("coerce SEX_H->REG")
- extsh %a, %1.reg
- yields %a
-
- from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL
- uses REG
- gen
- move %1, {GPRE, %a}
- yields %a
-
- from FS
- uses FREG
- gen
- fmr {FS, %a}, %1
- yields {FS, %a}
-
- from FD
- uses FREG
- gen
- fmr {FD, %a}, %1
- yields {FD, %a}
-
- from STACK
- uses FREG
- gen
- COMMENT("coerce STACK->FD")
- lfd {FD, %a}, {GPRINDIRECT, SP, 0}
- addi SP, SP, {CONST, 8}
- yields {FD, %a}
- from STACK
- uses FREG
- gen
- COMMENT("coerce STACK->FS")
- lfs {FS, %a}, {GPRINDIRECT, SP, 0}
- addi SP, SP, {CONST, 4}
- yields {FS, %a}
-
- from IND_ALL_W
- uses REG
- gen
- move %1, %a
- yields %a
-
- from IND_ALL_W
- uses FREG
- gen
- move %1, {FS, %a}
- yields {FS, %a}
-
- from IND_ALL_D
- uses FREG
- gen
- move %1, {FD, %a}
- yields {FD, %a}
-
-
- PATTERNS
- /* Intrinsics */
- pat loc /* Load constant */
- yields {CONST, $1}
- pat dup $1==INT32 /* Duplicate word on top of stack */
- with GPR
- yields %1 %1
-
- pat dup $1==INT64 /* Duplicate double-word on top of stack */
- with GPR GPR
- yields %2 %1 %2 %1
-
- pat exg $1==INT32 /* Exchange top two words on stack */
- with GPR GPR
- yields %1 %2
-
- pat stl lol $1==$2 /* Store then load local */
- leaving
- dup 4
- stl $1
-
- pat lal sti lal loi $1==$3 && $2==$4 /* Store then load local, of a different size */
- leaving
- dup INT32
- lal $1
- sti $2
-
- pat ste loe $1==$2 /* Store then load external */
- leaving
- dup 4
- ste $1
-
-
- /* Type conversions */
- pat loc loc cii loc loc cii $1==$4 && $2==$5 /* madness, generated by the C compiler */
- leaving
- loc $1
- loc $2
- cii
-
- pat loc loc cii loc loc cii $2==INT32 && $5==INT32 && $4<$2 /* madness, generated by the C compiler */
- leaving
- loc $4
- loc $5
- cii
-
- pat loc loc ciu /* signed X -> unsigned X */
- leaving
- loc $1
- loc $2
- cuu
-
- pat loc loc cuu $1==$2 /* unsigned X -> unsigned X */
- /* nop */
- pat loc loc cii $1==$2 /* signed X -> signed X */
- /* nop */
- pat loc loc cui $1==$2 /* unsigned X -> signed X */
- /* nop */
-
- pat loc loc cui $1==INT8 && $2==INT32 /* unsigned char -> signed int */
- /* nop */
-
- pat loc loc cui $1==INT16 && $2==INT32 /* unsigned short -> signed int */
- /* nop */
-
- pat loc loc cii $1==INT8 && $2==INT32 /* signed char -> signed int */
- with GPR
- yields {SEX_B, %1}
-
- pat loc loc cii $1==2 && $2==4 /* signed char -> signed short */
- with GPR
- yields {SEX_H, %1}
-
-
-
-
- /* Local variables */
- pat lal /* Load address of local */
- yields {SUM_RC, FP, $1}
- pat lol inreg($1)>0 /* Load from local */
- yields {LOCAL, $1}
-
- pat lol /* Load from local */
- leaving
- lal $1
- loi INT32
- pat ldl /* Load double-word from local */
- leaving
- lal $1
- loi INT32*2
-
- pat stl inreg($1)>0 /* Store to local */
- with CONST + LABEL + GPR + OP_ALL_W
- kills regvar($1), LOCAL %off==$1
- gen
- move %1, {GPRE, regvar($1)}
-
- pat stl /* Store to local */
- leaving
- lal $1
- sti INT32
-
- pat sdl /* Store double-word to local */
- leaving
- lal $1
- sti INT32*2
-
- pat lil inreg($1)>0 /* Load from indirected local */
- uses REG
- gen
- lwz %a, {GPRINDIRECT, regvar($1), 0}
- yields %a
-
- pat lil /* Load from indirected local */
- leaving
- lol $1
- loi INT32
-
- pat sil /* Save to indirected local */
- leaving
- lol $1
- sti INT32
-
- pat stl lol $1==$2 /* Save then load (generated by C compiler) */
- leaving
- dup 4
- stl $1
-
- pat zrl /* Zero local */
- leaving
- loc 0
- stl $1
-
- pat inl /* Increment local */
- leaving
- lol $1
- loc 1
- adi 4
- stl $1
-
- pat del /* Decrement local */
- leaving
- lol $1
- loc 1
- sbi 4
- stl $1
- /* Global variables */
-
- pat lpi /* Load address of external function */
- leaving
- lae $1
-
- pat lae /* Load address of external */
- yields {LABEL, $1}
-
- pat loe /* Load word external */
- leaving
- lae $1
- loi INT32
- pat ste /* Store word external */
- leaving
- lae $1
- sti INT32
-
- pat lde /* Load double-word external */
- leaving
- lae $1
- loi INT64
-
- pat sde /* Store double-word external */
- leaving
- lae $1
- sti INT64
-
- pat zre /* Zero external */
- leaving
- loc 0
- ste $1
-
- pat ine /* Increment external */
- uses REG={LABEL, $1}, REG
- gen
- lwz %b, {GPRINDIRECT, %a, 0}
- addi %b, %b, {CONST, 1}
- stw %b, {GPRINDIRECT, %a, 0}
-
- pat dee /* Decrement external */
- uses REG={LABEL, $1}, REG
- gen
- lwz %b, {GPRINDIRECT, %a, 0}
- addi %b, %b, {CONST, 0-1}
- stw %b, {GPRINDIRECT, %a, 0}
-
- /* Structures */
- pat lof /* Load word offsetted */
- leaving
- adp $1
- loi INT32
-
- pat ldf /* Load double-word offsetted */
- leaving
- adp $1
- loi INT64
-
- pat stf /* Store word offsetted */
- leaving
- adp $1
- sti INT32
-
- pat sdf /* Store double-word offsetted */
- leaving
- adp $1
- sti INT64
-
- /* Loads and stores */
- pat loi $1==INT8 /* Load byte indirect */
- with GPR
- uses REG
- gen
- lbz %a, {GPRINDIRECT, %1, 0}
- yields %a
- with SUM_RR
- uses reusing %1, REG
- gen
- lbzx %a, %1.reg1, %1.reg2
- yields %a
- with SUM_RC
- uses REG
- gen
- move {IND_RC_B, %1.reg, %1.off}, %a
- yields %a
-
- pat loi loc loc cii $1==INT16 && $2==INT16 && $3==INT32 /* Load half-word indirect and sign extend */
- with GPR
- uses REG
- gen
- lha %a, {GPRINDIRECT, %1, 0}
- yields %a
- with SUM_RR
- uses reusing %1, REG
- gen
- lhax %a, %1.reg1, %1.reg2
- yields %a
- with SUM_RC
- uses REG
- gen
- move {IND_RC_H_S, %1.reg, %1.off}, %a
- yields %a
-
- pat loi $1==INT16 /* Load half-word indirect */
- with GPR
- uses REG
- gen
- lhz %a, {GPRINDIRECT, %1, 0}
- yields %a
- with SUM_RR
- uses reusing %1, REG
- gen
- lhzx %a, %1.reg1, %1.reg2
- yields %a
- with SUM_RC
- uses REG
- gen
- move {IND_RC_H, %1.reg, %1.off}, %a
- yields %a
-
- pat loi $1==INT32 /* Load word indirect */
- with GPR
- yields {IND_RC_W, %1, 0}
- with SUM_RC
- yields {IND_RC_W, %1.reg, %1.off}
- with SUM_RR
- yields {IND_RR_W, %1.reg1, %1.reg2}
- with LABEL
- yields {IND_LABEL_W, %1.adr}
- pat loi $1==INT64 /* Load double-word indirect */
- with GPR
- yields {IND_RC_D, %1, 0}
- with SUM_RC
- yields {IND_RC_D, %1.reg, %1.off}
- with SUM_RR
- yields {IND_RR_D, %1.reg1, %1.reg2}
- with LABEL
- yields {IND_LABEL_D, %1.adr}
- pat loi /* Load arbitrary size */
- leaving
- loc $1
- los INT32
-
- pat los /* Load arbitrary size */
- with GPR3 GPR4 STACK
- kills ALL
- gen
- bl {LABEL, ".los"}
-
- pat sti $1==INT8 /* Store byte indirect */
- with GPR GPR
- gen
- stb %2, {GPRINDIRECT, %1, 0}
- with SUM_RR GPR
- gen
- stbx %2, %1.reg1, %1.reg2
- with SUM_RC GPR
- gen
- move %2, {IND_RC_B, %1.reg, %1.off}
- with GPR SEX_B
- gen
- stb %2.reg, {GPRINDIRECT, %1, 0}
- with SUM_RR SEX_B
- gen
- stbx %2.reg, %1.reg1, %1.reg2
- with SUM_RC SEX_B
- gen
- move %2.reg, {IND_RC_B, %1.reg, %1.off}
- pat sti $1==INT16 /* Store half-word indirect */
- with GPR GPR
- gen
- sth %2, {GPRINDIRECT, %1, 0}
- with SUM_RR GPR
- gen
- sthx %2, %1.reg1, %1.reg2
- with SUM_RC GPR
- gen
- move %2, {IND_RC_H, %1.reg, %1.off}
- with GPR SEX_H
- gen
- sth %2.reg, {GPRINDIRECT, %1, 0}
- with SUM_RR SEX_H
- gen
- sthx %2.reg, %1.reg1, %1.reg2
- with SUM_RC SEX_H
- gen
- move %2.reg, {IND_RC_H, %1.reg, %1.off}
- pat sti $1==INT32 /* Store word indirect */
- with GPR GPR+FS
- gen
- move %2, {IND_RC_W, %1, 0}
- with SUM_RR GPR+FS
- gen
- move %2, {IND_RR_W, %1.reg1, %1.reg2}
- with SUM_RC GPR+FS
- gen
- move %2, {IND_RC_W, %1.reg, %1.off}
- with LABEL GPR+FS
- gen
- move %2, {IND_LABEL_W, %1.adr}
- pat sti $1==INT64 /* Store double-word indirect */
- with GPR FD
- gen
- move %2, {IND_RC_D, %1, 0}
- with SUM_RR FD
- gen
- move %2, {IND_RR_D, %1.reg1, %1.reg2}
- with SUM_RC FD
- gen
- move %2, {IND_RC_D, %1.reg, %1.off}
- with GPR GPR GPR
- gen
- stw %2, {GPRINDIRECT, %1, 0}
- stw %3, {GPRINDIRECT, %1, 4}
- with SUM_RC GPR GPR
- gen
- move %2, {IND_RC_W, %1.reg, %1.off}
- move %3, {IND_RC_W, %1.reg, %1.off+4}
- with LABEL FD
- gen
- move %2, {IND_LABEL_D, %1.adr}
-
- pat sti /* Store arbitrary size */
- leaving
- loc $1
- sts INT32
-
- pat sts /* Load arbitrary size */
- with GPR3 GPR4 STACK
- kills ALL
- gen
- bl {LABEL, ".sts"}
-
- /* Arithmetic wrappers */
- pat ads $1==4 /* Add var to pointer */
- leaving adi $1
-
- pat sbs $1==4 /* Subtract var from pointer */
- leaving sbi $1
-
- pat adp /* Add constant to pointer */
- leaving
- loc $1
- adi 4
- pat adu /* Add unsigned */
- leaving
- adi $1
-
- pat sbu /* Subtract unsigned */
- leaving
- sbi $1
-
- pat inc /* Add 1 */
- leaving
- loc 1
- adi 4
-
- pat dec /* Subtract 1 */
- leaving
- loc 1
- sbi 4
-
- pat loc mlu $2==2 /* Unsigned multiply by constant */
- leaving
- loc $1
- mli 4
-
- pat mlu /* Unsigned multiply by var */
- leaving
- mli $1
-
- pat loc slu /* Shift left unsigned by constant amount */
- leaving
- loc $1
- sli $2
-
- pat slu /* Shift left unsigned by variable amount */
- leaving
- sli $1
-
-
- /* Word arithmetic */
- pat adi $1==4 /* Add word (second + top) */
- with REG REG
- yields {SUM_RR, %1, %2}
- with CONST REG
- yields {SUM_RC, %2, %1.val}
- with REG CONST
- yields {SUM_RC, %1, %2.val}
- with CONST SUM_RC
- yields {SUM_RC, %2.reg, %2.off+%1.val}
- with CONST LABEL
- yields {LABEL, %2.adr+%1.val}
-
- pat sbi $1==4 /* Subtract word (second - top) */
- with REG REG
- uses reusing %2, REG
- gen
- subf %a, %1, %2
- yields %a
- with CONST REG
- yields {SUM_RC, %2, 0-%1.val}
- with CONST SUM_RC
- yields {SUM_RC, %2.reg, %2.off-%1.val}
- with CONST LABEL
- yields {LABEL, %2.adr+(0-%1.val)}
-
- pat ngi $1==4 /* Negate word */
- with REG
- uses reusing %1, REG
- gen
- neg %a, %1
- yields %a
-
- pat mli $1==4 /* Multiply word (second * top) */
- with REG REG
- uses reusing %2, REG
- gen
- mullw %a, %2, %1
- yields %a
-
- pat dvi $1==4 /* Divide word (second / top) */
- with REG REG
- uses reusing %2, REG
- gen
- divw %a, %2, %1
- yields %a
-
- pat dvu $1==4 /* Divide unsigned word (second / top) */
- with REG REG
- uses reusing %2, REG
- gen
- divwu %a, %2, %1
- yields %a
- pat rmi $1==4 /* Remainder word (second % top) */
- with REG REG
- uses REG
- gen
- divw %a, %2, %1
- mullw %a, %a, %1
- subf %a, %a, %2
- yields %a
-
- pat rmu $1==4 /* Remainder unsigned word (second % top) */
- with REG REG
- uses REG
- gen
- divwu %a, %2, %1
- mullw %a, %a, %1
- subf %a, %a, %2
- yields %a
- pat and $1==4 /* AND word */
- with GPR NOT_R
- uses reusing %1, REG
- gen
- andc %a, %1, %2.reg
- yields %a
- with NOT_R GPR
- uses reusing %1, REG
- gen
- andc %a, %2, %1.reg
- yields %a
- with GPR GPR
- yields {AND_RR, %1, %2}
- with GPR CONST
- yields {AND_RC, %1, %2.val}
- with CONST GPR
- yields {AND_RC, %2, %1.val}
-
- pat and !defined($1) /* AND set */
- with STACK
- gen
- bl {LABEL, ".and"}
-
- pat ior $1==4 /* OR word */
- with GPR NOT_R
- uses reusing %1, REG
- gen
- orc %a, %1, %2.reg
- yields %a
- with NOT_R GPR
- uses reusing %2, REG
- gen
- orc %a, %2, %1.reg
- yields %a
- with GPR GPR
- yields {OR_RR, %1, %2}
- with GPR CONST
- yields {OR_RC, %1, %2.val}
- with CONST GPR
- yields {OR_RC, %2, %1.val}
-
- pat ior !defined($1) /* OR set */
- with STACK
- gen
- bl {LABEL, ".ior"}
-
- pat xor $1==4 /* XOR word */
- with GPR GPR
- yields {XOR_RR, %1, %2}
- with GPR CONST
- yields {XOR_RC, %1, %2.val}
- with CONST GPR
- yields {XOR_RC, %2, %1.val}
-
- pat xor !defined($1) /* XOR set */
- with STACK
- gen
- bl {LABEL, ".xor"}
-
- pat com $1==INT32 /* NOT word */
- with AND_RR
- uses REG
- gen
- nand %a, %1.reg1, %1.reg2
- yields %a
- with OR_RR
- uses REG
- gen
- nor %a, %1.reg1, %1.reg2
- yields %a
- with XOR_RR
- uses REG
- gen
- eqv %a, %1.reg1, %1.reg2
- yields %a
- with GPR
- yields {NOT_R, %1}
-
- pat com !defined($1) /* NOT set */
- with STACK
- gen
- bl {LABEL, ".com"}
-
- pat sli $1==4 /* Shift left (second << top) */
- with CONST GPR
- uses reusing %2, REG
- gen
- rlwinm %a, %2, {CONST, (%1.val & 0x1F)}, {CONST, 0}, {CONST, 31-(%1.val & 0x1F)}
- yields %a
- with GPR GPR
- uses reusing %2, REG
- gen
- slw %a, %2, %1
- yields %a
-
- pat sri $1==4 /* Shift right signed (second >> top) */
- with CONST GPR
- uses reusing %2, REG
- gen
- srawi %a, %2, {CONST, %1.val & 0x1F}
- yields %a
- with GPR GPR
- uses reusing %2, REG
- gen
- sraw %a, %2, %1
- yields %a
- pat sru $1==4 /* Shift right unsigned (second >> top) */
- with CONST GPR
- uses reusing %2, REG
- gen
- rlwinm %a, %2, {CONST, 32-(%1.val & 0x1F)}, {CONST, (%1.val & 0x1F)}, {CONST, 31}
- yields %a
- with GPR GPR
- uses reusing %2, REG
- gen
- srw %a, %2, %1
- yields %a
-
- /* Arrays */
- pat aar $1==INT32 /* Index array */
- with GPR3 GPR4 GPR5
- gen
- bl {LABEL, ".aar4"}
- yields R3
-
- pat lae lar $2==INT32 && nicesize(rom($1, 3)) /* Load array */
- leaving
- lae $1
- aar INT32
- loi rom($1, 3)
-
- pat lar $1==INT32 /* Load array */
- with GPR3 GPR4 GPR5 STACK
- kills ALL
- gen
- bl {LABEL, ".lar4"}
-
- pat lae sar $2==INT32 && nicesize(rom($1, 3)) /* Store array */
- leaving
- lae $1
- aar INT32
- sti rom($1, 3)
- pat sar $1==INT32 /* Store array */
- with GPR3 GPR4 GPR5 STACK
- kills ALL
- gen
- bl {LABEL, ".sar4"}
-
-
- /* Sets */
- pat set defined($1) /* Create word with set bit */
- leaving
- loc 1
- exg INT32
- sli INT32
-
- pat set !defined($1) /* Create structure with set bit (variable) */
- with GPR3 GPR4 STACK
- gen
- bl {LABEL, ".set"}
-
- pat inn defined($1) /* Test for set bit */
- leaving
- set INT32
- and INT32
-
- pat inn !defined($1) /* Test for set bit (variable) */
- with GPR3 STACK
- gen
- bl {LABEL, ".inn"}
-
-
-
- /* Boolean resolutions */
- pat teq /* top = (top == 0) */
- with TRISTATE_ALL + GPR
- uses reusing %1, REG
- gen
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".teq_table"}, %a
- lwzx %a, %a, SCRATCH
- yields %a
-
- pat tne /* top = (top != 0) */
- with TRISTATE_ALL + GPR
- uses reusing %1, REG
- gen
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tne_table"}, %a
- lwzx %a, %a, SCRATCH
- yields %a
-
- pat tlt /* top = (top < 0) */
- with TRISTATE_ALL + GPR
- uses reusing %1, REG
- gen
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tlt_table"}, %a
- lwzx %a, %a, SCRATCH
- yields %a
-
- pat tle /* top = (top <= 0) */
- with TRISTATE_ALL + GPR
- uses reusing %1, REG
- gen
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tle_table"}, %a
- lwzx %a, %a, SCRATCH
- yields %a
-
- pat tgt /* top = (top > 0) */
- with TRISTATE_ALL + GPR
- uses reusing %1, REG
- gen
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tgt_table"}, %a
- lwzx %a, %a, SCRATCH
- yields %a
- pat tge /* top = (top >= 0) */
- with TRISTATE_ALL + GPR
- uses reusing %1, REG
- gen
- move %1, C0
- move C0, SCRATCH
- move {LABEL, ".tge_table"}, %a
- lwzx %a, %a, SCRATCH
- yields %a
-
- /* Simple branches */
- pat zeq /* Branch if signed top == 0 */
- with TRISTATE_ALL+GPR STACK
- gen
- move %1, C0
- bc IFTRUE, EQ, {LABEL, $1}
- pat beq
- leaving
- cmi INT32
- zeq $1
-
- pat zne /* Branch if signed top != 0 */
- with TRISTATE_ALL+GPR STACK
- gen
- move %1, C0
- bc IFFALSE, EQ, {LABEL, $1}
- pat bne
- leaving
- cmi INT32
- zne $1
-
- pat zgt /* Branch if signed top > 0 */
- with TRISTATE_ALL+GPR STACK
- gen
- move %1, C0
- bc IFTRUE, GT, {LABEL, $1}
- pat bgt
- leaving
- cmi INT32
- zgt $1
-
- pat zge /* Branch if signed top >= 0 */
- with TRISTATE_ALL+GPR STACK
- gen
- move %1, C0
- bc IFFALSE, LT, {LABEL, $1}
- pat bge
- leaving
- cmi INT32
- zge $1
-
- pat zlt /* Branch if signed top < 0 */
- with TRISTATE_ALL+GPR STACK
- gen
- move %1, C0
- bc IFTRUE, LT, {LABEL, $1}
- pat blt
- leaving
- cmi INT32
- zlt $1
-
- pat zle /* Branch if signed top >= 0 */
- with TRISTATE_ALL+GPR STACK
- gen
- move %1, C0
- bc IFFALSE, GT, {LABEL, $1}
- pat ble
- leaving
- cmi INT32
- zle $1
-
- /* Compare and jump */
- pat cmi /* Signed tristate compare */
- with CONST GPR
- yields {TRISTATE_RC_S, %2, %1.val}
- with GPR GPR
- yields {TRISTATE_RR_S, %2, %1}
-
- pat cmu /* Unsigned tristate compare */
- with CONST GPR
- yields {TRISTATE_RC_U, %2, %1.val}
- with GPR GPR
- yields {TRISTATE_RR_U, %2, %1}
-
- pat cmp /* Compare pointers */
- leaving
- cmu INT32
-
- pat cms $1==INT32 /* Compare blocks (word sized) */
- leaving
- cmi INT32
-
-
-
- /* Other branching and labelling */
- pat lab topeltsize($1)==4 && !fallthrough($1)
- gen
- labeldef $1
- yields R3
-
- pat lab topeltsize($1)==4 && fallthrough($1)
- with GPR3
- gen
- labeldef $1
- yields %1
-
- pat lab topeltsize($1)!=4
- with STACK
- kills ALL
- gen
- labeldef $1
-
- pat bra topeltsize($1)==4 /* Unconditional jump with TOS GPRister */
- with GPR3 STACK
- gen
- b {LABEL, $1}
-
- pat bra topeltsize($1)!=4 /* Unconditional jump without TOS GPRister */
- with STACK
- gen
- b {LABEL, $1}
-
-
-
- /* Miscellaneous */
- pat cal /* Call procedure */
- with STACK
- kills ALL
- gen
- bl {LABEL, $1}
- pat cai /* Call procedure indirect */
- with GPR STACK
- kills ALL
- gen
- mtspr CTR, %1
- bcctrl ALWAYS, {CONST, 0}, {CONST, 0}
-
- pat lfr $1==INT32 /* Load function result, word */
- yields R3
-
- pat lfr $1==INT64 /* Load function result, double-word */
- yields R4 R3
-
- pat ret $1==0 /* Return from procedure */
- gen
- return
- b {LABEL, ".ret"}
-
- pat ret $1==INT32 /* Return from procedure, word */
- with GPR3
- gen
- return
- b {LABEL, ".ret"}
- pat ret $1==INT64 /* Return from procedure, double-word */
- with GPR3 GPR4
- gen
- return
- b {LABEL, ".ret"}
- pat blm /* Block move constant length */
- with GPR GPR STACK
- uses REG
- gen
- move {CONST, $1}, %a
- stwu %a, {GPRINDIRECT, SP, 0-4}
- stwu %2, {GPRINDIRECT, SP, 0-4}
- stwu %1, {GPRINDIRECT, SP, 0-4}
- bl {LABEL, "_memmove"}
- addi SP, SP, {CONST, 12}
-
- pat bls /* Block move variable length */
- with GPR GPR GPR STACK
- gen
- stwu %1, {GPRINDIRECT, SP, 0-4}
- stwu %3, {GPRINDIRECT, SP, 0-4}
- stwu %2, {GPRINDIRECT, SP, 0-4}
- bl {LABEL, "_memmove"}
- addi SP, SP, {CONST, 12}
-
- pat csa /* Array-lookup switch */
- with GPR3 GPR4 STACK
- gen
- b {LABEL, ".csa"}
-
- pat csb /* Table-lookup switch */
- with GPR3 GPR4 STACK
- gen
- b {LABEL, ".csb"}
-
- /* EM specials */
- pat fil /* Set current filename */
- leaving
- lae $1
- ste ".filename"
-
- pat lin /* Set current line number */
- leaving
- loc $1
- ste ".linenumber"
- pat lni /* Increment line number */
- leaving
- ine ".linenumber"
-
- pat lim /* Load EM trap ignore mask */
- leaving
- lde ".ignmask"
-
- pat sim /* Store EM trap ignore mask */
- leaving
- ste ".ignmask"
-
- pat trp /* Raise EM trap */
- with GPR3
- gen
- bl {LABEL, ".trap"}
-
- pat sig /* Set trap handler */
- leaving
- ste ".trppc"
-
- pat rtt /* Return from trap */
- leaving
- ret 0
-
- pat lxl $1==0 /* Load FP */
- leaving
- lor 0
-
- pat lxl $1==1 /* Load caller's FP */
- leaving
- lxl 0
- dch
-
- pat dch /* FP -> caller FP */
- with GPR
- uses reusing %1, REG
- gen
- lwz %a, {GPRINDIRECT, %1, FP_OFFSET}
- yields %a
- pat lpb /* Convert FP to argument address */
- leaving
- adp EM_BSIZE
-
- pat lxa /* Load caller's SP */
- leaving
- lxl $1
- lpb
-
- pat gto /* longjmp */
- uses REG
- gen
- move {LABEL, $1}, %a
- move {IND_RC_W, %a, 8}, FP
- move {IND_RC_W, %a, 4}, SP
- move {IND_RC_W, %a, 0}, %a
- mtspr CTR, %a
- bcctr ALWAYS, {CONST, 0}, {CONST, 0}
-
- #if 0
-
- pat gto /* longjmp */
- with STACK
- gen
- ld {LABEL, $1+2}
- wspec {CONST, 1}
- ld {LABEL, $1+4}
- wspec {CONST, 0}
- ld {LABEL, $1+0}
- wspec {CONST, 2}
-
- pat str $1==1 /* Store special GPRister */
- with GPR0
- gen
- wspec {CONST, $1}
-
- #endif
- pat lor $1==0 /* Load FP */
- uses REG
- gen
- move FP, %a
- yields %a
-
- pat lor $1==1 /* Load SP */
- uses REG
- gen
- move SP, %a
- yields %a
-
- pat lor $1==2 /* Load HP */
- leaving
- loe ".reghp"
-
- pat str $1==0 /* Store FP */
- with GPR
- gen
- move %1, FP
-
- pat str $1==1 /* Store SP */
- with GPR
- gen
- move %1, SP
-
- pat str $1==2 /* Store HP */
- leaving
- ste ".reghp"
-
- pat ass /* Adjust stack by variable amount */
- with CONST
- gen
- move {SUM_RC, SP, %1.val}, {GPRE, SP}
- with GPR
- gen
- move {SUM_RR, SP, %1}, {GPRE, SP}
-
- pat asp /* Adjust stack by constant amount */
- leaving
- loc $1
- ass
-
-
-
- /* Floating point support */
- /* All very cheap and nasty --- this needs to be properly integrated into
- * the code generator. ncg doesn't like having separate FPU registers. */
- /* Single-precision */
-
- pat zrf $1==INT32 /* Push zero */
- leaving
- loe ".fs_00000000"
-
- pat adf $1==INT32 /* Add single */
- with FS FS
- uses reusing %1, FREG
- gen
- fadds {FS, %a}, %2, %1
- yields {FS, %a}
-
- pat sbf $1==INT32 /* Subtract single */
- with FS FS
- uses reusing %1, FREG
- gen
- fsubs {FS, %a}, %2, %1
- yields {FS, %a}
-
- pat mlf $1==INT32 /* Multiply single */
- with FS FS
- uses reusing %1, FREG
- gen
- fmuls {FS, %a}, %2, %1
- yields {FS, %a}
- pat dvf $1==INT32 /* Divide single */
- with FS FS
- uses reusing %1, FREG
- gen
- fdivs {FS, %a}, %2, %1
- yields {FS, %a}
- pat ngf $1==INT32 /* Negate single */
- with FS
- uses reusing %1, FREG
- gen
- fneg {FS, %a}, %1
- yields {FS, %a}
- pat cmf $1==INT32 /* Compare single */
- with FS FS
- yields {TRISTATE_FF, %2.reg, %1.reg}
-
- pat loc loc cff $1==INT32 && $2==INT64 /* Convert single to double */
- with FS
- yields {FD, %1.reg}
-
- pat loc loc cfu $1==INT32 && $2==INT32 /* Convert single to unsigned int */
- with STACK
- gen
- bl {LABEL, ".cfu4"}
-
- pat loc loc cfi $1==INT32 && $2==INT32 /* Convert single to signed int */
- with STACK
- gen
- bl {LABEL, ".cfi4"}
-
- pat loc loc cif $1==INT32 && $2==INT32 /* Convert integer to single */
- with STACK
- gen
- bl {LABEL, ".cif4"}
-
- pat loc loc cuf $1==INT32 && $2==INT32 /* Convert unsigned int to single */
- with STACK
- gen
- bl {LABEL, ".cuf4"}
-
- pat fef $1==INT32 /* Split single */
- with STACK
- gen
- bl {LABEL, ".fef4"}
-
- /* Double-precision */
-
- pat zrf $1==INT64 /* Push zero */
- leaving
- lde ".fd_00000000"
-
- pat adf $1==INT64 /* Add double */
- with FD FD
- uses FREG
- gen
- fadd {FD, %a}, %2, %1
- yields {FD, %a}
-
- pat sbf $1==INT64 /* Subtract double */
- with FD FD
- uses FREG
- gen
- fsub {FD, %a}, %2, %1
- yields {FD, %a}
-
- pat mlf $1==INT64 /* Multiply double */
- with FD FD
- uses reusing %1, FREG
- gen
- fmul {FD, %a}, %2, %1
- yields {FD, %a}
- pat dvf $1==INT64 /* Divide double */
- with FD FD
- uses reusing %1, FREG
- gen
- fdiv {FD, %a}, %2, %1
- yields {FD, %a}
- pat ngf $1==INT64 /* Negate double */
- with FD
- uses reusing %1, FREG
- gen
- fneg {FD, %a}, %1
- yields {FD, %a}
- pat cmf $1==INT64 /* Compare double */
- with FD FD
- yields {TRISTATE_FF, %2.reg, %1.reg}
-
- pat loc loc cff $1==INT64 && $2==INT32 /* Convert double to single */
- with FD
- uses reusing %1, FREG
- gen
- frsp {FS, %a}, %1
- yields {FS, %a}
-
- pat loc loc cfu $1==INT64 && $2==INT32 /* Convert double to unsigned int */
- with STACK
- gen
- bl {LABEL, ".cfu8"}
-
- pat loc loc cfi $1==INT64 && $2==INT32 /* Convert double to signed int */
- with STACK
- gen
- bl {LABEL, ".cfi8"}
-
- pat loc loc cif $1==INT32 && $2==INT64 /* Convert integer to double */
- with STACK
- kills ALL
- gen
- bl {LABEL, ".cif8"}
-
- pat loc loc cuf $1==INT32 && $2==INT64 /* Convert unsigned int to double */
- with STACK
- gen
- bl {LABEL, ".cuf8"}
-
- pat fef $1==INT64 /* Split double */
- with FD
- gen
- addi SP, SP, {CONST, 0-8}
- stfd %1, {GPRINDIRECT, SP, 0}
- stwu SP, {GPRINDIRECT, SP, 0-4}
- bl {LABEL, "___fef8"}
- stw R3, {GPRINDIRECT, SP, 0}
-
- pat fif $1==INT64 /* Multiply and split double (?) */
- with STACK
- gen
- bl {LABEL, ".fif8"}
-
|