1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161 |
- 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"}
-
-
|