table 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160
  1. EM_WSIZE = 4
  2. EM_PSIZE = 4
  3. EM_BSIZE = 8 /* two words saved in call frame */
  4. INT8 = 1 /* Size of values */
  5. INT16 = 2
  6. INT32 = 4
  7. INT64 = 8
  8. FP_OFFSET = 0 /* Offset of saved FP relative to our FP */
  9. PC_OFFSET = 4 /* Offset of saved PC relative to our FP */
  10. #define COMMENT(n) /* noop */
  11. #define nicesize(x) ((x)==INT8 || (x)==INT16 || (x)==INT32 || (x)==INT64)
  12. #define smalls(n) sfit(n, 16)
  13. #define smallu(n) ufit(n, 16)
  14. #define lo(n) (n & 0xFFFF)
  15. #define hi(n) ((n>>16) & 0xFFFF)
  16. /* Use these for instructions that treat the low half as signed --- his()
  17. * includes a modifier to produce the correct value when the low half gets
  18. * sign extended. Er, do make sure you load the low half second. */
  19. #define los(n) (n & 0xFFFF)
  20. #define his(n) ((hi(n) - (lo(n)>>15)) & 0xFFFF)
  21. #define IFFALSE {CONST, 4}
  22. #define IFTRUE {CONST, 12}
  23. #define ALWAYS {CONST, 20}
  24. #define DCTRZ {CONST, 34}
  25. #define LT {CONST, 0}
  26. #define GT {CONST, 1}
  27. #define EQ {CONST, 2}
  28. PROPERTIES
  29. GPR /* any GPR */
  30. REG /* any allocatable GPR */
  31. FPR /* any FPR */
  32. FREG /* any allocatable FPR */
  33. SPR /* any SPR */
  34. CR /* any CR */
  35. GPR0 GPRSP GPRFP GPR3 GPR4 GPR5 GPR6 GPR7
  36. GPR8 GPR9 GPR10 GPR11 GPR12 GPR13 GPR14 GPR15
  37. GPR16 GPR17 GPR18 GPR19 GPR20 GPR21 GPR22 GPR23
  38. GPR24 GPR25 GPR26 GPR27 GPR28 GPR29 GPR30 GPR31
  39. CR0 CR1
  40. FPR0 FPR1 FPR2 FPR3 FPR4 FPR5 FPR6 FPR7
  41. FPR8 FPR9 FPR10 FPR11 FPR12 FPR13 FPR14 FPR15
  42. FPR16 FPR17 FPR18 FPR19 FPR20 FPR21 FPR22 FPR23
  43. FPR24 FPR25 FPR26 FPR27 FPR28 FPR29 FPR30 FPR31
  44. REGISTERS
  45. /* Reverse order to encourage ncg to allocate them from r31 down */
  46. R31("r31") : GPR, REG, GPR31 regvar.
  47. R30("r30") : GPR, REG, GPR30 regvar.
  48. R29("r29") : GPR, REG, GPR29 regvar.
  49. R28("r28") : GPR, REG, GPR28 regvar.
  50. R27("r27") : GPR, REG, GPR27 regvar.
  51. R26("r26") : GPR, REG, GPR26 regvar.
  52. R25("r25") : GPR, REG, GPR25 regvar.
  53. R24("r24") : GPR, REG, GPR24 regvar.
  54. R23("r23") : GPR, REG, GPR23 regvar.
  55. R22("r22") : GPR, REG, GPR22 regvar.
  56. R21("r21") : GPR, REG, GPR21 regvar.
  57. R20("r20") : GPR, REG, GPR20 regvar.
  58. R19("r19") : GPR, REG, GPR19 regvar.
  59. R18("r18") : GPR, REG, GPR18 regvar.
  60. R17("r17") : GPR, REG, GPR17 regvar.
  61. R16("r16") : GPR, REG, GPR16 regvar.
  62. R15("r15") : GPR, REG, GPR15 regvar.
  63. R14("r14") : GPR, REG, GPR14 regvar.
  64. R13("r13") : GPR, REG, GPR13 regvar.
  65. R12("r12") : GPR, REG, GPR12.
  66. R11("r11") : GPR, GPR11.
  67. R10("r10") : GPR, REG, GPR10.
  68. R9("r9") : GPR, REG, GPR9.
  69. R8("r8") : GPR, REG, GPR8.
  70. R7("r7") : GPR, REG, GPR7.
  71. R6("r6") : GPR, REG, GPR6.
  72. R5("r5") : GPR, REG, GPR5.
  73. R4("r4") : GPR, REG, GPR4.
  74. R3("r3") : GPR, REG, GPR3.
  75. FP("fp") : GPR, GPRFP.
  76. SP("sp") : GPR, GPRSP.
  77. R0("r0") : GPR, GPR0.
  78. F31("f31") : FPR, FREG, FPR31.
  79. F30("f30") : FPR, FREG, FPR30.
  80. F29("f29") : FPR, FREG, FPR29.
  81. F28("f28") : FPR, FREG, FPR28.
  82. F27("f27") : FPR, FREG, FPR27.
  83. F26("f26") : FPR, FREG, FPR26.
  84. F25("f25") : FPR, FREG, FPR25.
  85. F24("f24") : FPR, FREG, FPR24.
  86. F23("f23") : FPR, FREG, FPR23.
  87. F22("f22") : FPR, FREG, FPR22.
  88. F21("f21") : FPR, FREG, FPR21.
  89. F20("f20") : FPR, FREG, FPR20.
  90. F19("f19") : FPR, FREG, FPR19.
  91. F18("f18") : FPR, FREG, FPR18.
  92. F17("f17") : FPR, FREG, FPR17.
  93. F16("f16") : FPR, FREG, FPR16.
  94. F15("f15") : FPR, FREG, FPR15.
  95. F14("f14") : FPR, FREG, FPR14.
  96. F13("f13") : FPR, FREG, FPR13.
  97. F12("f12") : FPR, FREG, FPR12.
  98. F11("f11") : FPR, FREG, FPR11.
  99. F10("f10") : FPR, FREG, FPR10.
  100. F9("f9") : FPR, FREG, FPR9.
  101. F8("f8") : FPR, FREG, FPR8.
  102. F7("f7") : FPR, FREG, FPR7.
  103. F6("f6") : FPR, FREG, FPR6.
  104. F5("f5") : FPR, FREG, FPR5.
  105. F4("f4") : FPR, FREG, FPR4.
  106. F3("f3") : FPR, FREG, FPR3.
  107. F2("f2") : FPR, FREG, FPR2.
  108. F1("f1") : FPR, FREG, FPR1.
  109. F0("f0") : FPR, FREG, FPR0.
  110. LR("lr") : SPR.
  111. CTR("ctr") : SPR.
  112. C0("cr0") : CR, CR0.
  113. #define SCRATCH R11
  114. #define FSCRATCH F0
  115. TOKENS
  116. /* Used only in instruction descriptions (to generate the correct syntax). */
  117. GPRINDIRECT = { GPR reg; INT off; } 4 off "(" reg ")".
  118. GPRINDIRECTLO = { GPR reg; ADDR adr; } 4 ">" adr "(" reg ")". /* Warning! Do not use on labels. */
  119. HILABEL = { ADDR adr; } 4 "<" adr.
  120. LOLABEL = { ADDR adr; } 4 ">" adr.
  121. /* Primitives */
  122. LABEL = { ADDR adr; } 4 adr.
  123. CONST = { INT val; } 4 val.
  124. LOCAL = { INT off; } 4.
  125. /* Allows us to use regvar() to refer to registers */
  126. GPRE = { GPR reg; } 4 reg.
  127. /* Expression partial results */
  128. SUM_RC = { GPR reg; INT off; } 4.
  129. SUM_RR = { GPR reg1; GPR reg2; } 4.
  130. TRISTATE_RC_S = { GPR reg; INT val; } 4.
  131. TRISTATE_RC_U = { GPR reg; INT val; } 4.
  132. TRISTATE_RR_S = { GPR reg1; GPR reg2; } 4.
  133. TRISTATE_RR_U = { GPR reg1; GPR reg2; } 4.
  134. TRISTATE_FF = { FPR reg1; FPR reg2; } 4.
  135. SEX_B = { GPR reg; } 4.
  136. SEX_H = { GPR reg; } 4.
  137. IND_RC_B = { GPR reg; INT off; } 4.
  138. IND_RC_H = { GPR reg; INT off; } 4.
  139. IND_RC_H_S = { GPR reg; INT off; } 4.
  140. IND_RC_W = { GPR reg; INT off; } 4.
  141. IND_RR_W = { GPR reg1; GPR reg2; } 4.
  142. IND_LABEL_W = { ADDR adr; } 4.
  143. IND_RC_D = { GPR reg; INT off; } 8.
  144. IND_RR_D = { GPR reg1; GPR reg2; } 8.
  145. IND_LABEL_D = { ADDR adr; } 8.
  146. NOT_R = { GPR reg; } 4.
  147. AND_RR = { GPR reg1; GPR reg2; } 4.
  148. AND_RC = { GPR reg; INT val; } 4.
  149. OR_RR = { GPR reg1; GPR reg2; } 4.
  150. OR_RC = { GPR reg; INT val; } 4.
  151. XOR_RR = { GPR reg1; GPR reg2; } 4.
  152. XOR_RC = { GPR reg; INT val; } 4.
  153. /* Floats */
  154. FD = { FPR reg; } 8 reg.
  155. FS = { FPR reg; } 4 reg.
  156. /* Comments */
  157. LABELI = { ADDR msg; INT num; } 4 msg " " num.
  158. SETS
  159. TOKEN = LABEL + CONST + LOCAL.
  160. GPRI = GPR + GPRE.
  161. SUM_ALL = SUM_RC + SUM_RR.
  162. TRISTATE_ALL = TRISTATE_RC_S + TRISTATE_RC_U + TRISTATE_RR_S +
  163. TRISTATE_RR_U + TRISTATE_FF.
  164. SEX_ALL = SEX_B + SEX_H.
  165. LOGICAL_ALL = NOT_R + AND_RR + AND_RC + OR_RR + OR_RC + XOR_RR +
  166. XOR_RC.
  167. IND_ALL_W = IND_RC_W + IND_RR_W + IND_LABEL_W.
  168. IND_ALL_D = IND_RC_D + IND_RR_D + IND_LABEL_D.
  169. OP_ALL_W = SUM_ALL + TRISTATE_ALL + SEX_ALL + LOGICAL_ALL +
  170. IND_ALL_W.
  171. INSTRUCTIONS
  172. add GPRI:wo, GPRI:ro, GPRI:ro.
  173. addX "add." GPRI:wo, GPRI:ro, GPRI:ro.
  174. addi GPRI:wo, GPRI:ro, CONST:ro.
  175. addis GPRI:wo, GPRI:ro, CONST+HILABEL:ro.
  176. and GPRI:wo, GPRI:ro, GPRI:ro.
  177. andc GPRI:wo, GPRI:ro, GPRI:ro.
  178. andiX "andi." GPRI:wo, GPRI:ro, CONST:ro kills :cc.
  179. andisX "andis." GPRI:wo, GPRI:ro, CONST:ro kills :cc.
  180. b LABEL:ro.
  181. bc CONST:ro, CONST:ro, LABEL:ro.
  182. bcctr CONST:ro, CONST:ro, CONST:ro.
  183. bcctrl CONST:ro, CONST:ro, CONST:ro.
  184. bclr CONST:ro, CONST:ro, CONST:ro.
  185. bl LABEL:ro.
  186. cmp CR:ro, CONST:ro, GPRI:ro, GPR:ro kills :cc.
  187. cmpi CR:ro, CONST:ro, GPRI:ro, CONST:ro kills :cc.
  188. cmpl CR:ro, CONST:ro, GPRI:ro, GPR:ro kills :cc.
  189. cmpli CR:ro, CONST:ro, GPRI:ro, CONST:ro kills :cc.
  190. divw GPRI:wo, GPRI:ro, GPRI:ro.
  191. divwu GPRI:wo, GPRI:ro, GPRI:ro.
  192. eqv GPRI:wo, GPRI:ro, GPRI:ro.
  193. extsb GPRI:wo, GPRI:ro.
  194. extsh GPRI:wo, GPRI:ro.
  195. fadd FD:wo, FD:ro, FD:ro.
  196. fadds FS:wo, FS:ro, FS:ro.
  197. fcmpo CR:wo, FD:ro, FD:ro.
  198. fdiv FD:wo, FD:ro, FD:ro.
  199. fdivs FS:wo, FS:ro, FS:ro.
  200. fneg FS+FD:wo, FS+FD:ro.
  201. fmul FD:wo, FD:ro, FD:ro.
  202. fmuls FS:wo, FS:ro, FS:ro.
  203. frsp FS:wo, FD:ro.
  204. fsub FD:wo, FD:ro, FD:ro.
  205. fsubs FS:wo, FS:ro, FS:ro.
  206. fmr FS+FD:wo, FS+FD:ro.
  207. lbzx GPRI:wo, GPR:ro, GPR:ro.
  208. lbz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  209. lfd FD:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  210. lfdu FD:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  211. lfdx FD:wo, GPR:ro, GPR:ro.
  212. lfs FS:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  213. lfsu FS:wo, GPRINDIRECT+GPRINDIRECTLO:rw.
  214. lfsx FS:wo, GPR:ro, GPR:ro.
  215. lhzx GPRI:wo, GPR:ro, GPR:ro.
  216. lhax GPRI:wo, GPR:ro, GPR:ro.
  217. lha GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  218. lhz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  219. lwzu GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  220. lwzx GPRI:wo, GPR:ro, GPR:ro.
  221. lwz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
  222. nand GPRI:wo, GPRI:ro, GPRI:ro.
  223. neg GPRI:wo, GPRI:ro.
  224. nor GPRI:wo, GPRI:ro, GPRI:ro.
  225. mfcr GPRI:wo.
  226. mullw GPRI:wo, GPRI:ro, GPRI:ro.
  227. mfspr GPRI:wo, SPR:ro.
  228. mtspr SPR:wo, GPRI:ro.
  229. or GPRI:wo, GPRI:ro, GPRI:ro.
  230. orc GPRI:wo, GPRI:ro, GPRI:ro.
  231. ori GPRI:wo, GPRI:ro, CONST+LOLABEL:ro.
  232. orX "or." GPRI:wo, GPRI:ro, GPRI:ro kills :cc.
  233. rlwinm GPRI:wo, GPRI:ro, CONST:ro, CONST:ro, CONST:ro.
  234. slw GPRI:wo, GPRI:ro, GPRI:ro.
  235. subf GPRI:wo, GPRI:ro, GPRI:ro.
  236. sraw GPRI:wo, GPRI:ro, GPRI:ro.
  237. srawi GPRI:wo, GPRI:ro, CONST:ro.
  238. srw GPRI:wo, GPRI:ro, GPRI:ro.
  239. stb GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  240. stbx GPRI:ro, GPR:ro, GPR:ro.
  241. stfd FD:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  242. stfdu FD:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  243. stfdx FD:ro, GPR:ro, GPR:ro.
  244. stfs FS:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  245. stfsu FS:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  246. stfsx FS:ro, GPR:ro, GPR:ro.
  247. sth GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  248. sthx GPRI:ro, GPR:ro, GPR:ro.
  249. stw GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  250. stwx GPRI:ro, GPR:ro, GPR:ro.
  251. stwu GPRI:ro, GPRINDIRECT+GPRINDIRECTLO:rw.
  252. xor GPRI:wo, GPRI:ro, GPRI:ro.
  253. xori GPRI:wo, GPRI:ro, CONST:ro.
  254. gpr_gpr_gpr GPRI:wo, GPRI:ro, GPRI:ro.
  255. gpr_gpr_si GPRI:wo, GPRI:ro, CONST:ro.
  256. gpr_ro_gprindirect GPRI:ro, GPRINDIRECT:rw.
  257. gpr_ro_gpr_gpr GPRI:ro, GPRI:ro, GPRI:ro.
  258. gpr_wo_gprindirect GPRI:wo, GPRINDIRECT:ro.
  259. gpr_wo_gpr_gpr GPRI:wo, GPRI:ro, GPRI:ro.
  260. invalid "invalid".
  261. comment "!" LABEL+LABELI:ro.
  262. MOVES
  263. from GPR to GPR
  264. gen
  265. COMMENT("move GPR->GPR")
  266. or %2, %1, %1
  267. /* GPRE exists solely to allow us to use regvar() (which can only be used in
  268. an expression) as a register constant. */
  269. from GPR to GPRE
  270. gen
  271. COMMENT("move GPR->GPRE")
  272. or %2, %1, %1
  273. /* Constants */
  274. from CONST smalls(%val) to GPR
  275. gen
  276. COMMENT("move CONST->GPRE")
  277. addi %2, R0, {CONST, lo(%1.val)}
  278. from CONST to GPR
  279. gen
  280. COMMENT("move CONST->GPRE")
  281. addis %2, R0, {CONST, hi(%1.val)}
  282. ori %2, %2, {CONST, lo(%1.val)}
  283. from LABEL to GPR
  284. gen
  285. COMMENT("move LABEL->GPR")
  286. addis %2, R0, {HILABEL, %1.adr}
  287. ori %2, %2, {LOLABEL, %1.adr}
  288. /* Sign extension */
  289. from SEX_B to GPR
  290. gen
  291. COMMENT("move SEX_B->GPR")
  292. extsb %2, %1.reg
  293. from SEX_H to GPR
  294. gen
  295. COMMENT("move SEX_H->GPR")
  296. extsh %2, %1.reg
  297. /* Register + something */
  298. from SUM_RC smalls(%off) to GPR
  299. gen
  300. COMMENT("move SUM_RC->GPR smalls")
  301. addi %2, %1.reg, {CONST, lo(%1.off)}
  302. from SUM_RC to GPR
  303. gen
  304. COMMENT("move SUM_RC->GPR large")
  305. addi %2, %1.reg, {CONST, los(%1.off)}
  306. addis %2, %2, {CONST, his(%1.off)}
  307. from SUM_RR to GPR
  308. gen
  309. COMMENT("move SUM_RR->GPR")
  310. add %2, %1.reg1, %1.reg2
  311. from SUM_RR to GPR
  312. gen
  313. COMMENT("move SUM_RR->GPRE")
  314. add %2, %1.reg1, %1.reg2
  315. /* Read/write byte */
  316. from IND_RC_B smalls(%off) to GPR
  317. gen
  318. COMMENT("move IND_RC_B->GPR small")
  319. lbz %2, {GPRINDIRECT, %1.reg, %1.off}
  320. from IND_RC_B to GPR
  321. gen
  322. COMMENT("move IND_RC_B->GPR large")
  323. addis SCRATCH, %1.reg, {CONST, his(%1.off)}
  324. lbz %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
  325. from GPR to IND_RC_B smalls(%off)
  326. gen
  327. COMMENT("move GPR->IND_RC_B small")
  328. stb %1, {GPRINDIRECT, %2.reg, %2.off}
  329. from GPR to IND_RC_B
  330. gen
  331. COMMENT("move GPR->IND_RC_B large")
  332. addis SCRATCH, %2.reg, {CONST, his(%2.off)}
  333. stb %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
  334. /* Read/write short */
  335. from IND_RC_H smalls(%off) to GPR
  336. gen
  337. COMMENT("move IND_RC_H->GPR small")
  338. lhz %2, {GPRINDIRECT, %1.reg, %1.off}
  339. from IND_RC_H to GPR
  340. gen
  341. COMMENT("move IND_RC_H->GPR large")
  342. addis SCRATCH, %1.reg, {CONST, his(%1.off)}
  343. lhz %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
  344. from IND_RC_H_S smalls(%off) to GPR
  345. gen
  346. COMMENT("move IND_RC_H_S->GPR small")
  347. lha %2, {GPRINDIRECT, %1.reg, %1.off}
  348. from IND_RC_H_S to GPR
  349. gen
  350. COMMENT("move IND_RC_H_S->GPR large")
  351. addis SCRATCH, %1.reg, {CONST, his(%1.off)}
  352. lha %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
  353. from GPR to IND_RC_H smalls(%off)
  354. gen
  355. COMMENT("move GPR->IND_RC_H small")
  356. sth %1, {GPRINDIRECT, %2.reg, %2.off}
  357. from GPR to IND_RC_H
  358. gen
  359. COMMENT("move GPR->IND_RC_H large")
  360. addis SCRATCH, %2.reg, {CONST, his(%2.off)}
  361. sth %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
  362. /* Read word */
  363. from IND_RC_W smalls(%off) to GPR
  364. gen
  365. COMMENT("move IND_RC_W->GPR small")
  366. lwz %2, {GPRINDIRECT, %1.reg, %1.off}
  367. from IND_RC_W to GPR
  368. gen
  369. COMMENT("move IND_RC_W->GPR large")
  370. addis %2, %1.reg, {CONST, his(%1.off)}
  371. lwz %2, {GPRINDIRECT, %2, los(%1.off)}
  372. from IND_RR_W to GPR
  373. gen
  374. COMMENT("move IND_RR_W->GPR")
  375. lwzx %2, %1.reg1, %1.reg2
  376. from IND_LABEL_W to GPR
  377. gen
  378. COMMENT("move IND_LABEL_W->GPR")
  379. move {LABEL, %1.adr}, SCRATCH
  380. lwz %2, {GPRINDIRECT, SCRATCH, 0}
  381. from IND_RC_W smalls(%off) to FS
  382. gen
  383. COMMENT("move IND_RC_W->FS small")
  384. lfs %2, {GPRINDIRECT, %1.reg, %1.off}
  385. from IND_RC_W to FS
  386. gen
  387. COMMENT("move IND_RC_W->FS large")
  388. addis SCRATCH, %1.reg, {CONST, his(%1.off)}
  389. lfs %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
  390. from IND_RR_W to FS
  391. gen
  392. COMMENT("move IND_RR_W->FS")
  393. lfsx %2, %1.reg1, %1.reg2
  394. from IND_LABEL_W to FS
  395. gen
  396. COMMENT("move IND_LABEL_W->FS")
  397. move {LABEL, %1.adr}, SCRATCH
  398. lfs %2, {GPRINDIRECT, SCRATCH, 0}
  399. /* Write word */
  400. from GPR to IND_RC_W smalls(%off)
  401. gen
  402. COMMENT("move GPR->IND_RC_W small")
  403. stw %1, {GPRINDIRECT, %2.reg, %2.off}
  404. from GPR to IND_RC_W
  405. gen
  406. COMMENT("move GPR->IND_RC_W large")
  407. addis SCRATCH, %2.reg, {CONST, his(%2.off)}
  408. stw %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
  409. from GPR to IND_RR_W
  410. gen
  411. COMMENT("move GPR->IND_RR_W")
  412. stwx %1, %2.reg1, %2.reg2
  413. from GPR to IND_LABEL_W
  414. gen
  415. COMMENT("move GPR->IND_LABEL_D")
  416. move {LABEL, %2.adr}, SCRATCH
  417. stw %1, {GPRINDIRECT, SCRATCH, 0}
  418. from FS to IND_RC_W smalls(%off)
  419. gen
  420. COMMENT("move FS->IND_RC_W small")
  421. stfs %1, {GPRINDIRECT, %2.reg, %2.off}
  422. from FS to IND_RC_W
  423. gen
  424. COMMENT("move FS->IND_RC_W large")
  425. addis SCRATCH, %2.reg, {CONST, his(%2.off)}
  426. stfs %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
  427. from FS to IND_RR_W
  428. gen
  429. COMMENT("move FS->IND_RR_W")
  430. stfsx %1, %2.reg1, %2.reg2
  431. from FS to IND_LABEL_W
  432. gen
  433. COMMENT("move FS->IND_LABEL_D")
  434. move {LABEL, %2.adr}, SCRATCH
  435. stfs %1, {GPRINDIRECT, SCRATCH, 0}
  436. /* Read double */
  437. from IND_RC_D smalls(%off) to FD
  438. gen
  439. COMMENT("move IND_RC_D->FD small")
  440. lfd %2, {GPRINDIRECT, %1.reg, %1.off}
  441. from IND_RC_D to FD
  442. gen
  443. COMMENT("move IND_RC_D->FD large")
  444. addis SCRATCH, %1.reg, {CONST, his(%1.off)}
  445. lfd %2, {GPRINDIRECT, SCRATCH, los(%1.off)}
  446. from IND_RR_D to FD
  447. gen
  448. COMMENT("move IND_RR_D->FD")
  449. lfdx %2, %1.reg1, %1.reg2
  450. from IND_LABEL_D to FD
  451. gen
  452. COMMENT("move IND_LABEL_D->FD")
  453. move {LABEL, %1.adr}, SCRATCH
  454. lfd %2, {GPRINDIRECT, SCRATCH, 0}
  455. /* Write double */
  456. from FD to IND_RC_D smalls(%off)
  457. gen
  458. COMMENT("move FD->IND_RC_D small")
  459. stfd %1, {GPRINDIRECT, %2.reg, %2.off}
  460. from FD to IND_RC_D
  461. gen
  462. COMMENT("move FD->IND_RC_D large")
  463. addis SCRATCH, %2.reg, {CONST, his(%2.off)}
  464. stfd %1, {GPRINDIRECT, SCRATCH, los(%2.off)}
  465. from FD to IND_RR_D
  466. gen
  467. COMMENT("move FD->IND_RR_W")
  468. stfdx %1, %2.reg1, %2.reg2
  469. from FD to IND_LABEL_D
  470. gen
  471. COMMENT("move FD->IND_LABEL_D")
  472. move {LABEL, %2.adr}, SCRATCH
  473. stfd %1, {GPRINDIRECT, SCRATCH, 0}
  474. /* Extract condition code field (actually produces (CC&3)<<2) */
  475. from CR0 to GPR
  476. gen
  477. COMMENT("move CR0->GPR")
  478. mfcr %2
  479. rlwinm %2, %2, {CONST, 4}, {CONST, 32-4}, {CONST, 31-2}
  480. /* Comparisons */
  481. from TRISTATE_RR_S to CR0
  482. gen
  483. cmp %2, {CONST, 0}, %1.reg1, %1.reg2
  484. from TRISTATE_RR_U to CR0
  485. gen
  486. cmpl %2, {CONST, 0}, %1.reg1, %1.reg2
  487. from TRISTATE_RC_S to CR0
  488. gen
  489. COMMENT("move TRISTATE_RC_S->CR0 large")
  490. move {CONST, %1.val}, SCRATCH
  491. cmp %2, {CONST, 0}, %1.reg, SCRATCH
  492. from TRISTATE_RC_U smallu(%val) to CR0
  493. gen
  494. COMMENT("move TRISTATE_RC_U->CR0 small")
  495. cmpli %2, {CONST, 0}, %1.reg, {CONST, %1.val}
  496. from TRISTATE_RC_U to CR0
  497. gen
  498. COMMENT("move TRISTATE_RC_U->CR0")
  499. move {CONST, %1.val}, SCRATCH
  500. cmpl %2, {CONST, 0}, %1.reg, SCRATCH
  501. from TRISTATE_FF to CR0
  502. gen
  503. COMMENT("move TRISTATE_FF->CR0")
  504. fcmpo %2, {FD, %1.reg1}, {FD, %1.reg2}
  505. from GPR to CR0
  506. gen
  507. COMMENT("move GPR->CR0")
  508. orX SCRATCH, %1, %1 /* alas, can't call test */
  509. from TRISTATE_RR_S + TRISTATE_RC_S + TRISTATE_FF to GPR
  510. gen
  511. COMMENT("move TRISTATE_R*_S->GPR")
  512. move %1, C0
  513. move C0, SCRATCH
  514. move {LABEL, ".tristate_s_table"}, %2
  515. lwzx %2, %2, SCRATCH
  516. from TRISTATE_RR_U + TRISTATE_RC_U to GPR
  517. gen
  518. COMMENT("move TRISTATE_R*_U->GPR")
  519. move %1, C0
  520. move C0, SCRATCH
  521. move {LABEL, ".tristate_u_table"}, %2
  522. lwzx %2, %2, SCRATCH
  523. /* Logicals */
  524. from NOT_R to GPR
  525. gen
  526. COMMENT("move NOT_R->GPR")
  527. nor %2, %1.reg, %1.reg
  528. from AND_RR to GPR
  529. gen
  530. COMMENT("move AND_RR->GPR")
  531. and %2, %1.reg1, %1.reg2
  532. from AND_RC smallu(%val) to GPR
  533. gen
  534. COMMENT("move AND_RC->GPR small")
  535. andiX %2, %1.reg, {CONST, %1.val}
  536. from AND_RC to GPR
  537. gen
  538. COMMENT("move AND_RC->GPR")
  539. move {CONST, %1.val}, SCRATCH
  540. and %2, %1.reg, SCRATCH
  541. from OR_RR to GPR
  542. gen
  543. COMMENT("move OR_RR->GPR")
  544. or %2, %1.reg1, %1.reg2
  545. from OR_RC smallu(%val) to GPR
  546. gen
  547. COMMENT("move OR_RC->GPR small")
  548. ori %2, %1.reg, {CONST, %1.val}
  549. from OR_RC to GPR
  550. gen
  551. COMMENT("move OR_RC->GPR")
  552. move {CONST, %1.val}, SCRATCH
  553. or %2, %1.reg, SCRATCH
  554. from XOR_RR to GPR
  555. gen
  556. COMMENT("move XOR_RR->GPR")
  557. xor %2, %1.reg1, %1.reg2
  558. from XOR_RC smallu(%val) to GPR
  559. gen
  560. COMMENT("move XOR_RC->GPR small")
  561. xori %2, %1.reg, {CONST, %1.val}
  562. from XOR_RC to GPR
  563. gen
  564. COMMENT("move XOR_RC->GPR")
  565. move {CONST, %1.val}, SCRATCH
  566. xor %2, %1.reg, SCRATCH
  567. /* Miscellaneous */
  568. from OP_ALL_W + LABEL + CONST to GPRE
  569. gen
  570. move %1, %2.reg
  571. TESTS
  572. to test GPR
  573. gen
  574. orX SCRATCH, %1, %1
  575. STACKINGRULES
  576. from GPR to STACK
  577. gen
  578. COMMENT("stack GPR")
  579. stwu %1, {GPRINDIRECT, SP, 0-4}
  580. from CONST to STACK
  581. uses REG
  582. gen
  583. COMMENT("stack CONST")
  584. move %1, %a
  585. stwu %a, {GPRINDIRECT, SP, 0-4}
  586. from LABEL to STACK
  587. uses REG
  588. gen
  589. COMMENT("stack LABEL")
  590. move %1, {GPRE, %a}
  591. stwu %a, {GPRINDIRECT, SP, 0-4}
  592. from SEX_B to STACK
  593. gen
  594. COMMENT("stack SEX_B")
  595. extsb SCRATCH, %1.reg
  596. stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
  597. from SEX_H to STACK
  598. gen
  599. COMMENT("stack SEX_H")
  600. extsh SCRATCH, %1.reg
  601. stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
  602. from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL to STACK
  603. gen
  604. move %1, {GPRE, SCRATCH}
  605. stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
  606. from IND_ALL_W to STACK
  607. gen
  608. move %1, SCRATCH
  609. stwu SCRATCH, {GPRINDIRECT, SP, 0-4}
  610. from IND_ALL_D to STACK
  611. gen
  612. move %1, {FD, FSCRATCH}
  613. stfdu {FD, FSCRATCH}, {GPRINDIRECT, SP, 0-8}
  614. from FD to STACK
  615. gen
  616. COMMENT("stack FD")
  617. stfdu %1, {GPRINDIRECT, SP, 0-8}
  618. from FS to STACK
  619. gen
  620. COMMENT("stack FS")
  621. stfsu %1, {GPRINDIRECT, SP, 0-4}
  622. from TOKEN to STACK
  623. gen
  624. invalid.
  625. COERCIONS
  626. from REG
  627. uses REG
  628. gen
  629. COMMENT("coerce REG->REG")
  630. move %1, %a
  631. yields %a
  632. from CONST
  633. uses REG
  634. gen
  635. COMMENT("coerce CONST->REG")
  636. move %1, %a
  637. yields %a
  638. from LABEL
  639. uses REG
  640. gen
  641. COMMENT("coerce LABEL->REG")
  642. move %1, {GPRE, %a}
  643. yields %a
  644. from STACK
  645. uses REG
  646. gen
  647. COMMENT("coerce STACK->REG")
  648. lwz %a, {GPRINDIRECT, SP, 0}
  649. addi SP, SP, {CONST, 4}
  650. yields %a
  651. from SEX_B
  652. uses REG
  653. gen
  654. COMMENT("coerce SEX_B->REG")
  655. extsb %a, %1.reg
  656. yields %a
  657. from SEX_H
  658. uses REG
  659. gen
  660. COMMENT("coerce SEX_H->REG")
  661. extsh %a, %1.reg
  662. yields %a
  663. from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL
  664. uses REG
  665. gen
  666. move %1, {GPRE, %a}
  667. yields %a
  668. from FS
  669. uses FREG
  670. gen
  671. fmr {FS, %a}, %1
  672. yields {FS, %a}
  673. from FD
  674. uses FREG
  675. gen
  676. fmr {FD, %a}, %1
  677. yields {FD, %a}
  678. from STACK
  679. uses FREG
  680. gen
  681. COMMENT("coerce STACK->FD")
  682. lfd {FD, %a}, {GPRINDIRECT, SP, 0}
  683. addi SP, SP, {CONST, 8}
  684. yields {FD, %a}
  685. from STACK
  686. uses FREG
  687. gen
  688. COMMENT("coerce STACK->FS")
  689. lfs {FS, %a}, {GPRINDIRECT, SP, 0}
  690. addi SP, SP, {CONST, 4}
  691. yields {FS, %a}
  692. from IND_ALL_W
  693. uses REG
  694. gen
  695. move %1, %a
  696. yields %a
  697. from IND_ALL_W
  698. uses FREG
  699. gen
  700. move %1, {FS, %a}
  701. yields {FS, %a}
  702. from IND_ALL_D
  703. uses FREG
  704. gen
  705. move %1, {FD, %a}
  706. yields {FD, %a}
  707. PATTERNS
  708. /* Intrinsics */
  709. pat loc /* Load constant */
  710. yields {CONST, $1}
  711. pat dup $1==INT32 /* Duplicate word on top of stack */
  712. with GPR
  713. yields %1 %1
  714. pat dup $1==INT64 /* Duplicate double-word on top of stack */
  715. with GPR GPR
  716. yields %2 %1 %2 %1
  717. pat exg $1==INT32 /* Exchange top two words on stack */
  718. with GPR GPR
  719. yields %1 %2
  720. pat stl lol $1==$2 /* Store then load local */
  721. leaving
  722. dup 4
  723. stl $1
  724. pat lal sti lal loi $1==$3 && $2==$4 /* Store then load local, of a different size */
  725. leaving
  726. dup INT32
  727. lal $1
  728. sti $2
  729. pat ste loe $1==$2 /* Store then load external */
  730. leaving
  731. dup 4
  732. ste $1
  733. /* Type conversions */
  734. pat loc loc cii loc loc cii $1==$4 && $2==$5 /* madness, generated by the C compiler */
  735. leaving
  736. loc $1
  737. loc $2
  738. cii
  739. pat loc loc cii loc loc cii $2==INT32 && $5==INT32 && $4<$2 /* madness, generated by the C compiler */
  740. leaving
  741. loc $4
  742. loc $5
  743. cii
  744. pat loc loc ciu /* signed X -> unsigned X */
  745. leaving
  746. loc $1
  747. loc $2
  748. cuu
  749. pat loc loc cuu $1==$2 /* unsigned X -> unsigned X */
  750. /* nop */
  751. pat loc loc cii $1==$2 /* signed X -> signed X */
  752. /* nop */
  753. pat loc loc cui $1==$2 /* unsigned X -> signed X */
  754. /* nop */
  755. pat loc loc cui $1==INT8 && $2==INT32 /* unsigned char -> signed int */
  756. /* nop */
  757. pat loc loc cui $1==INT16 && $2==INT32 /* unsigned short -> signed int */
  758. /* nop */
  759. pat loc loc cii $1==INT8 && $2==INT32 /* signed char -> signed int */
  760. with GPR
  761. yields {SEX_B, %1}
  762. pat loc loc cii $1==2 && $2==4 /* signed char -> signed short */
  763. with GPR
  764. yields {SEX_H, %1}
  765. /* Local variables */
  766. pat lal /* Load address of local */
  767. yields {SUM_RC, FP, $1}
  768. pat lol inreg($1)>0 /* Load from local */
  769. yields {LOCAL, $1}
  770. pat lol /* Load from local */
  771. leaving
  772. lal $1
  773. loi INT32
  774. pat ldl /* Load double-word from local */
  775. leaving
  776. lal $1
  777. loi INT32*2
  778. pat stl inreg($1)>0 /* Store to local */
  779. with CONST + LABEL + GPR + OP_ALL_W
  780. kills regvar($1), LOCAL %off==$1
  781. gen
  782. move %1, {GPRE, regvar($1)}
  783. pat stl /* Store to local */
  784. leaving
  785. lal $1
  786. sti INT32
  787. pat sdl /* Store double-word to local */
  788. leaving
  789. lal $1
  790. sti INT32*2
  791. pat lil inreg($1)>0 /* Load from indirected local */
  792. uses REG
  793. gen
  794. lwz %a, {GPRINDIRECT, regvar($1), 0}
  795. yields %a
  796. pat lil /* Load from indirected local */
  797. leaving
  798. lol $1
  799. loi INT32
  800. pat sil /* Save to indirected local */
  801. leaving
  802. lol $1
  803. sti INT32
  804. pat stl lol $1==$2 /* Save then load (generated by C compiler) */
  805. leaving
  806. dup 4
  807. stl $1
  808. pat zrl /* Zero local */
  809. leaving
  810. loc 0
  811. stl $1
  812. pat inl /* Increment local */
  813. leaving
  814. lol $1
  815. loc 1
  816. adi 4
  817. stl $1
  818. pat del /* Decrement local */
  819. leaving
  820. lol $1
  821. loc 1
  822. sbi 4
  823. stl $1
  824. /* Global variables */
  825. pat lpi /* Load address of external function */
  826. leaving
  827. lae $1
  828. pat lae /* Load address of external */
  829. yields {LABEL, $1}
  830. pat loe /* Load word external */
  831. leaving
  832. lae $1
  833. loi INT32
  834. pat ste /* Store word external */
  835. leaving
  836. lae $1
  837. sti INT32
  838. pat lde /* Load double-word external */
  839. leaving
  840. lae $1
  841. loi INT64
  842. pat sde /* Store double-word external */
  843. leaving
  844. lae $1
  845. sti INT64
  846. pat zre /* Zero external */
  847. leaving
  848. loc 0
  849. ste $1
  850. pat ine /* Increment external */
  851. uses REG={LABEL, $1}, REG
  852. gen
  853. lwz %b, {GPRINDIRECT, %a, 0}
  854. addi %b, %b, {CONST, 1}
  855. stw %b, {GPRINDIRECT, %a, 0}
  856. pat dee /* Decrement external */
  857. uses REG={LABEL, $1}, REG
  858. gen
  859. lwz %b, {GPRINDIRECT, %a, 0}
  860. addi %b, %b, {CONST, 0-1}
  861. stw %b, {GPRINDIRECT, %a, 0}
  862. /* Structures */
  863. pat lof /* Load word offsetted */
  864. leaving
  865. adp $1
  866. loi INT32
  867. pat ldf /* Load double-word offsetted */
  868. leaving
  869. adp $1
  870. loi INT64
  871. pat stf /* Store word offsetted */
  872. leaving
  873. adp $1
  874. sti INT32
  875. pat sdf /* Store double-word offsetted */
  876. leaving
  877. adp $1
  878. sti INT64
  879. /* Loads and stores */
  880. pat loi $1==INT8 /* Load byte indirect */
  881. with GPR
  882. uses REG
  883. gen
  884. lbz %a, {GPRINDIRECT, %1, 0}
  885. yields %a
  886. with SUM_RR
  887. uses reusing %1, REG
  888. gen
  889. lbzx %a, %1.reg1, %1.reg2
  890. yields %a
  891. with SUM_RC
  892. uses REG
  893. gen
  894. move {IND_RC_B, %1.reg, %1.off}, %a
  895. yields %a
  896. pat loi loc loc cii $1==INT16 && $2==INT16 && $3==INT32 /* Load half-word indirect and sign extend */
  897. with GPR
  898. uses REG
  899. gen
  900. lha %a, {GPRINDIRECT, %1, 0}
  901. yields %a
  902. with SUM_RR
  903. uses reusing %1, REG
  904. gen
  905. lhax %a, %1.reg1, %1.reg2
  906. yields %a
  907. with SUM_RC
  908. uses REG
  909. gen
  910. move {IND_RC_H_S, %1.reg, %1.off}, %a
  911. yields %a
  912. pat loi $1==INT16 /* Load half-word indirect */
  913. with GPR
  914. uses REG
  915. gen
  916. lhz %a, {GPRINDIRECT, %1, 0}
  917. yields %a
  918. with SUM_RR
  919. uses reusing %1, REG
  920. gen
  921. lhzx %a, %1.reg1, %1.reg2
  922. yields %a
  923. with SUM_RC
  924. uses REG
  925. gen
  926. move {IND_RC_H, %1.reg, %1.off}, %a
  927. yields %a
  928. pat loi $1==INT32 /* Load word indirect */
  929. with GPR
  930. yields {IND_RC_W, %1, 0}
  931. with SUM_RC
  932. yields {IND_RC_W, %1.reg, %1.off}
  933. with SUM_RR
  934. yields {IND_RR_W, %1.reg1, %1.reg2}
  935. with LABEL
  936. yields {IND_LABEL_W, %1.adr}
  937. pat loi $1==INT64 /* Load double-word indirect */
  938. with GPR
  939. yields {IND_RC_D, %1, 0}
  940. with SUM_RC
  941. yields {IND_RC_D, %1.reg, %1.off}
  942. with SUM_RR
  943. yields {IND_RR_D, %1.reg1, %1.reg2}
  944. with LABEL
  945. yields {IND_LABEL_D, %1.adr}
  946. pat loi /* Load arbitrary size */
  947. leaving
  948. loc $1
  949. los INT32
  950. pat los /* Load arbitrary size */
  951. with GPR3 GPR4 STACK
  952. kills ALL
  953. gen
  954. bl {LABEL, ".los"}
  955. pat sti $1==INT8 /* Store byte indirect */
  956. with GPR GPR
  957. gen
  958. stb %2, {GPRINDIRECT, %1, 0}
  959. with SUM_RR GPR
  960. gen
  961. stbx %2, %1.reg1, %1.reg2
  962. with SUM_RC GPR
  963. gen
  964. move %2, {IND_RC_B, %1.reg, %1.off}
  965. with GPR SEX_B
  966. gen
  967. stb %2.reg, {GPRINDIRECT, %1, 0}
  968. with SUM_RR SEX_B
  969. gen
  970. stbx %2.reg, %1.reg1, %1.reg2
  971. with SUM_RC SEX_B
  972. gen
  973. move %2.reg, {IND_RC_B, %1.reg, %1.off}
  974. pat sti $1==INT16 /* Store half-word indirect */
  975. with GPR GPR
  976. gen
  977. sth %2, {GPRINDIRECT, %1, 0}
  978. with SUM_RR GPR
  979. gen
  980. sthx %2, %1.reg1, %1.reg2
  981. with SUM_RC GPR
  982. gen
  983. move %2, {IND_RC_H, %1.reg, %1.off}
  984. with GPR SEX_H
  985. gen
  986. sth %2.reg, {GPRINDIRECT, %1, 0}
  987. with SUM_RR SEX_H
  988. gen
  989. sthx %2.reg, %1.reg1, %1.reg2
  990. with SUM_RC SEX_H
  991. gen
  992. move %2.reg, {IND_RC_H, %1.reg, %1.off}
  993. pat sti $1==INT32 /* Store word indirect */
  994. with GPR GPR+FS
  995. gen
  996. move %2, {IND_RC_W, %1, 0}
  997. with SUM_RR GPR+FS
  998. gen
  999. move %2, {IND_RR_W, %1.reg1, %1.reg2}
  1000. with SUM_RC GPR+FS
  1001. gen
  1002. move %2, {IND_RC_W, %1.reg, %1.off}
  1003. with LABEL GPR+FS
  1004. gen
  1005. move %2, {IND_LABEL_W, %1.adr}
  1006. pat sti $1==INT64 /* Store double-word indirect */
  1007. with GPR FD
  1008. gen
  1009. move %2, {IND_RC_D, %1, 0}
  1010. with SUM_RR FD
  1011. gen
  1012. move %2, {IND_RR_D, %1.reg1, %1.reg2}
  1013. with SUM_RC FD
  1014. gen
  1015. move %2, {IND_RC_D, %1.reg, %1.off}
  1016. with GPR GPR GPR
  1017. gen
  1018. stw %2, {GPRINDIRECT, %1, 0}
  1019. stw %3, {GPRINDIRECT, %1, 4}
  1020. with SUM_RC GPR GPR
  1021. gen
  1022. move %2, {IND_RC_W, %1.reg, %1.off}
  1023. move %3, {IND_RC_W, %1.reg, %1.off+4}
  1024. with LABEL FD
  1025. gen
  1026. move %2, {IND_LABEL_D, %1.adr}
  1027. pat sti /* Store arbitrary size */
  1028. leaving
  1029. loc $1
  1030. sts INT32
  1031. pat sts /* Load arbitrary size */
  1032. with GPR3 GPR4 STACK
  1033. kills ALL
  1034. gen
  1035. bl {LABEL, ".sts"}
  1036. /* Arithmetic wrappers */
  1037. pat ads $1==4 /* Add var to pointer */
  1038. leaving adi $1
  1039. pat sbs $1==4 /* Subtract var from pointer */
  1040. leaving sbi $1
  1041. pat adp /* Add constant to pointer */
  1042. leaving
  1043. loc $1
  1044. adi 4
  1045. pat adu /* Add unsigned */
  1046. leaving
  1047. adi $1
  1048. pat sbu /* Subtract unsigned */
  1049. leaving
  1050. sbi $1
  1051. pat inc /* Add 1 */
  1052. leaving
  1053. loc 1
  1054. adi 4
  1055. pat dec /* Subtract 1 */
  1056. leaving
  1057. loc 1
  1058. sbi 4
  1059. pat loc mlu $2==2 /* Unsigned multiply by constant */
  1060. leaving
  1061. loc $1
  1062. mli 4
  1063. pat mlu /* Unsigned multiply by var */
  1064. leaving
  1065. mli $1
  1066. pat loc slu /* Shift left unsigned by constant amount */
  1067. leaving
  1068. loc $1
  1069. sli $2
  1070. pat slu /* Shift left unsigned by variable amount */
  1071. leaving
  1072. sli $1
  1073. /* Word arithmetic */
  1074. pat adi $1==4 /* Add word (second + top) */
  1075. with REG REG
  1076. yields {SUM_RR, %1, %2}
  1077. with CONST REG
  1078. yields {SUM_RC, %2, %1.val}
  1079. with REG CONST
  1080. yields {SUM_RC, %1, %2.val}
  1081. with CONST SUM_RC
  1082. yields {SUM_RC, %2.reg, %2.off+%1.val}
  1083. with CONST LABEL
  1084. yields {LABEL, %2.adr+%1.val}
  1085. pat sbi $1==4 /* Subtract word (second - top) */
  1086. with REG REG
  1087. uses reusing %2, REG
  1088. gen
  1089. subf %a, %1, %2
  1090. yields %a
  1091. with CONST REG
  1092. yields {SUM_RC, %2, 0-%1.val}
  1093. with CONST SUM_RC
  1094. yields {SUM_RC, %2.reg, %2.off-%1.val}
  1095. with CONST LABEL
  1096. yields {LABEL, %2.adr+(0-%1.val)}
  1097. pat ngi $1==4 /* Negate word */
  1098. with REG
  1099. uses reusing %1, REG
  1100. gen
  1101. neg %a, %1
  1102. yields %a
  1103. pat mli $1==4 /* Multiply word (second * top) */
  1104. with REG REG
  1105. uses reusing %2, REG
  1106. gen
  1107. mullw %a, %2, %1
  1108. yields %a
  1109. pat dvi $1==4 /* Divide word (second / top) */
  1110. with REG REG
  1111. uses reusing %2, REG
  1112. gen
  1113. divw %a, %2, %1
  1114. yields %a
  1115. pat dvu $1==4 /* Divide unsigned word (second / top) */
  1116. with REG REG
  1117. uses reusing %2, REG
  1118. gen
  1119. divwu %a, %2, %1
  1120. yields %a
  1121. pat rmi $1==4 /* Remainder word (second % top) */
  1122. with REG REG
  1123. uses REG
  1124. gen
  1125. divw %a, %2, %1
  1126. mullw %a, %a, %1
  1127. subf %a, %a, %2
  1128. yields %a
  1129. pat rmu $1==4 /* Remainder unsigned word (second % top) */
  1130. with REG REG
  1131. uses REG
  1132. gen
  1133. divwu %a, %2, %1
  1134. mullw %a, %a, %1
  1135. subf %a, %a, %2
  1136. yields %a
  1137. pat and $1==4 /* AND word */
  1138. with GPR NOT_R
  1139. uses reusing %1, REG
  1140. gen
  1141. andc %a, %1, %2.reg
  1142. yields %a
  1143. with NOT_R GPR
  1144. uses reusing %1, REG
  1145. gen
  1146. andc %a, %2, %1.reg
  1147. yields %a
  1148. with GPR GPR
  1149. yields {AND_RR, %1, %2}
  1150. with GPR CONST
  1151. yields {AND_RC, %1, %2.val}
  1152. with CONST GPR
  1153. yields {AND_RC, %2, %1.val}
  1154. pat and !defined($1) /* AND set */
  1155. with STACK
  1156. gen
  1157. bl {LABEL, ".and"}
  1158. pat ior $1==4 /* OR word */
  1159. with GPR NOT_R
  1160. uses reusing %1, REG
  1161. gen
  1162. orc %a, %1, %2.reg
  1163. yields %a
  1164. with NOT_R GPR
  1165. uses reusing %2, REG
  1166. gen
  1167. orc %a, %2, %1.reg
  1168. yields %a
  1169. with GPR GPR
  1170. yields {OR_RR, %1, %2}
  1171. with GPR CONST
  1172. yields {OR_RC, %1, %2.val}
  1173. with CONST GPR
  1174. yields {OR_RC, %2, %1.val}
  1175. pat ior !defined($1) /* OR set */
  1176. with STACK
  1177. gen
  1178. bl {LABEL, ".ior"}
  1179. pat xor $1==4 /* XOR word */
  1180. with GPR GPR
  1181. yields {XOR_RR, %1, %2}
  1182. with GPR CONST
  1183. yields {XOR_RC, %1, %2.val}
  1184. with CONST GPR
  1185. yields {XOR_RC, %2, %1.val}
  1186. pat xor !defined($1) /* XOR set */
  1187. with STACK
  1188. gen
  1189. bl {LABEL, ".xor"}
  1190. pat com $1==INT32 /* NOT word */
  1191. with AND_RR
  1192. uses REG
  1193. gen
  1194. nand %a, %1.reg1, %1.reg2
  1195. yields %a
  1196. with OR_RR
  1197. uses REG
  1198. gen
  1199. nor %a, %1.reg1, %1.reg2
  1200. yields %a
  1201. with XOR_RR
  1202. uses REG
  1203. gen
  1204. eqv %a, %1.reg1, %1.reg2
  1205. yields %a
  1206. with GPR
  1207. yields {NOT_R, %1}
  1208. pat com !defined($1) /* NOT set */
  1209. with STACK
  1210. gen
  1211. bl {LABEL, ".com"}
  1212. pat sli $1==4 /* Shift left (second << top) */
  1213. with CONST GPR
  1214. uses reusing %2, REG
  1215. gen
  1216. rlwinm %a, %2, {CONST, (%1.val & 0x1F)}, {CONST, 0}, {CONST, 31-(%1.val & 0x1F)}
  1217. yields %a
  1218. with GPR GPR
  1219. uses reusing %2, REG
  1220. gen
  1221. slw %a, %2, %1
  1222. yields %a
  1223. pat sri $1==4 /* Shift right signed (second >> top) */
  1224. with CONST GPR
  1225. uses reusing %2, REG
  1226. gen
  1227. srawi %a, %2, {CONST, %1.val & 0x1F}
  1228. yields %a
  1229. with GPR GPR
  1230. uses reusing %2, REG
  1231. gen
  1232. sraw %a, %2, %1
  1233. yields %a
  1234. pat sru $1==4 /* Shift right unsigned (second >> top) */
  1235. with CONST GPR
  1236. uses reusing %2, REG
  1237. gen
  1238. rlwinm %a, %2, {CONST, 32-(%1.val & 0x1F)}, {CONST, (%1.val & 0x1F)}, {CONST, 31}
  1239. yields %a
  1240. with GPR GPR
  1241. uses reusing %2, REG
  1242. gen
  1243. srw %a, %2, %1
  1244. yields %a
  1245. /* Arrays */
  1246. pat aar $1==INT32 /* Index array */
  1247. with GPR3 GPR4 GPR5
  1248. gen
  1249. bl {LABEL, ".aar4"}
  1250. yields R3
  1251. pat lae lar $2==INT32 && nicesize(rom($1, 3)) /* Load array */
  1252. leaving
  1253. lae $1
  1254. aar INT32
  1255. loi rom($1, 3)
  1256. pat lar $1==INT32 /* Load array */
  1257. with GPR3 GPR4 GPR5 STACK
  1258. kills ALL
  1259. gen
  1260. bl {LABEL, ".lar4"}
  1261. pat lae sar $2==INT32 && nicesize(rom($1, 3)) /* Store array */
  1262. leaving
  1263. lae $1
  1264. aar INT32
  1265. sti rom($1, 3)
  1266. pat sar $1==INT32 /* Store array */
  1267. with GPR3 GPR4 GPR5 STACK
  1268. kills ALL
  1269. gen
  1270. bl {LABEL, ".sar4"}
  1271. /* Sets */
  1272. pat set defined($1) /* Create word with set bit */
  1273. leaving
  1274. loc 1
  1275. exg INT32
  1276. sli INT32
  1277. pat set !defined($1) /* Create structure with set bit (variable) */
  1278. with GPR3 GPR4 STACK
  1279. gen
  1280. bl {LABEL, ".set"}
  1281. pat inn defined($1) /* Test for set bit */
  1282. leaving
  1283. set INT32
  1284. and INT32
  1285. pat inn !defined($1) /* Test for set bit (variable) */
  1286. with GPR3 STACK
  1287. gen
  1288. bl {LABEL, ".inn"}
  1289. /* Boolean resolutions */
  1290. pat teq /* top = (top == 0) */
  1291. with TRISTATE_ALL + GPR
  1292. uses reusing %1, REG
  1293. gen
  1294. move %1, C0
  1295. move C0, SCRATCH
  1296. move {LABEL, ".teq_table"}, %a
  1297. lwzx %a, %a, SCRATCH
  1298. yields %a
  1299. pat tne /* top = (top != 0) */
  1300. with TRISTATE_ALL + GPR
  1301. uses reusing %1, REG
  1302. gen
  1303. move %1, C0
  1304. move C0, SCRATCH
  1305. move {LABEL, ".tne_table"}, %a
  1306. lwzx %a, %a, SCRATCH
  1307. yields %a
  1308. pat tlt /* top = (top < 0) */
  1309. with TRISTATE_ALL + GPR
  1310. uses reusing %1, REG
  1311. gen
  1312. move %1, C0
  1313. move C0, SCRATCH
  1314. move {LABEL, ".tlt_table"}, %a
  1315. lwzx %a, %a, SCRATCH
  1316. yields %a
  1317. pat tle /* top = (top <= 0) */
  1318. with TRISTATE_ALL + GPR
  1319. uses reusing %1, REG
  1320. gen
  1321. move %1, C0
  1322. move C0, SCRATCH
  1323. move {LABEL, ".tle_table"}, %a
  1324. lwzx %a, %a, SCRATCH
  1325. yields %a
  1326. pat tgt /* top = (top > 0) */
  1327. with TRISTATE_ALL + GPR
  1328. uses reusing %1, REG
  1329. gen
  1330. move %1, C0
  1331. move C0, SCRATCH
  1332. move {LABEL, ".tgt_table"}, %a
  1333. lwzx %a, %a, SCRATCH
  1334. yields %a
  1335. pat tge /* top = (top >= 0) */
  1336. with TRISTATE_ALL + GPR
  1337. uses reusing %1, REG
  1338. gen
  1339. move %1, C0
  1340. move C0, SCRATCH
  1341. move {LABEL, ".tge_table"}, %a
  1342. lwzx %a, %a, SCRATCH
  1343. yields %a
  1344. /* Simple branches */
  1345. pat zeq /* Branch if signed top == 0 */
  1346. with TRISTATE_ALL+GPR STACK
  1347. gen
  1348. move %1, C0
  1349. bc IFTRUE, EQ, {LABEL, $1}
  1350. pat beq
  1351. leaving
  1352. cmi INT32
  1353. zeq $1
  1354. pat zne /* Branch if signed top != 0 */
  1355. with TRISTATE_ALL+GPR STACK
  1356. gen
  1357. move %1, C0
  1358. bc IFFALSE, EQ, {LABEL, $1}
  1359. pat bne
  1360. leaving
  1361. cmi INT32
  1362. zne $1
  1363. pat zgt /* Branch if signed top > 0 */
  1364. with TRISTATE_ALL+GPR STACK
  1365. gen
  1366. move %1, C0
  1367. bc IFTRUE, GT, {LABEL, $1}
  1368. pat bgt
  1369. leaving
  1370. cmi INT32
  1371. zgt $1
  1372. pat zge /* Branch if signed top >= 0 */
  1373. with TRISTATE_ALL+GPR STACK
  1374. gen
  1375. move %1, C0
  1376. bc IFFALSE, LT, {LABEL, $1}
  1377. pat bge
  1378. leaving
  1379. cmi INT32
  1380. zge $1
  1381. pat zlt /* Branch if signed top < 0 */
  1382. with TRISTATE_ALL+GPR STACK
  1383. gen
  1384. move %1, C0
  1385. bc IFTRUE, LT, {LABEL, $1}
  1386. pat blt
  1387. leaving
  1388. cmi INT32
  1389. zlt $1
  1390. pat zle /* Branch if signed top >= 0 */
  1391. with TRISTATE_ALL+GPR STACK
  1392. gen
  1393. move %1, C0
  1394. bc IFFALSE, GT, {LABEL, $1}
  1395. pat ble
  1396. leaving
  1397. cmi INT32
  1398. zle $1
  1399. /* Compare and jump */
  1400. pat cmi /* Signed tristate compare */
  1401. with CONST GPR
  1402. yields {TRISTATE_RC_S, %2, %1.val}
  1403. with GPR GPR
  1404. yields {TRISTATE_RR_S, %2, %1}
  1405. pat cmu /* Unsigned tristate compare */
  1406. with CONST GPR
  1407. yields {TRISTATE_RC_U, %2, %1.val}
  1408. with GPR GPR
  1409. yields {TRISTATE_RR_U, %2, %1}
  1410. pat cmp /* Compare pointers */
  1411. leaving
  1412. cmu INT32
  1413. pat cms $1==INT32 /* Compare blocks (word sized) */
  1414. leaving
  1415. cmi INT32
  1416. /* Other branching and labelling */
  1417. pat lab topeltsize($1)==4 && !fallthrough($1)
  1418. gen
  1419. labeldef $1
  1420. yields R3
  1421. pat lab topeltsize($1)==4 && fallthrough($1)
  1422. with GPR3
  1423. gen
  1424. labeldef $1
  1425. yields %1
  1426. pat lab topeltsize($1)!=4
  1427. with STACK
  1428. kills ALL
  1429. gen
  1430. labeldef $1
  1431. pat bra topeltsize($1)==4 /* Unconditional jump with TOS GPRister */
  1432. with GPR3 STACK
  1433. gen
  1434. b {LABEL, $1}
  1435. pat bra topeltsize($1)!=4 /* Unconditional jump without TOS GPRister */
  1436. with STACK
  1437. gen
  1438. b {LABEL, $1}
  1439. /* Miscellaneous */
  1440. pat cal /* Call procedure */
  1441. with STACK
  1442. kills ALL
  1443. gen
  1444. bl {LABEL, $1}
  1445. pat cai /* Call procedure indirect */
  1446. with GPR STACK
  1447. kills ALL
  1448. gen
  1449. mtspr CTR, %1
  1450. bcctrl ALWAYS, {CONST, 0}, {CONST, 0}
  1451. pat lfr $1==INT32 /* Load function result, word */
  1452. yields R3
  1453. pat lfr $1==INT64 /* Load function result, double-word */
  1454. yields R4 R3
  1455. pat ret $1==0 /* Return from procedure */
  1456. gen
  1457. return
  1458. b {LABEL, ".ret"}
  1459. pat ret $1==INT32 /* Return from procedure, word */
  1460. with GPR3
  1461. gen
  1462. return
  1463. b {LABEL, ".ret"}
  1464. pat ret $1==INT64 /* Return from procedure, double-word */
  1465. with GPR3 GPR4
  1466. gen
  1467. return
  1468. b {LABEL, ".ret"}
  1469. pat blm /* Block move constant length */
  1470. with GPR GPR STACK
  1471. uses REG
  1472. gen
  1473. move {CONST, $1}, %a
  1474. stwu %a, {GPRINDIRECT, SP, 0-4}
  1475. stwu %2, {GPRINDIRECT, SP, 0-4}
  1476. stwu %1, {GPRINDIRECT, SP, 0-4}
  1477. bl {LABEL, "_memmove"}
  1478. addi SP, SP, {CONST, 12}
  1479. pat bls /* Block move variable length */
  1480. with GPR GPR GPR STACK
  1481. gen
  1482. stwu %1, {GPRINDIRECT, SP, 0-4}
  1483. stwu %3, {GPRINDIRECT, SP, 0-4}
  1484. stwu %2, {GPRINDIRECT, SP, 0-4}
  1485. bl {LABEL, "_memmove"}
  1486. addi SP, SP, {CONST, 12}
  1487. pat csa /* Array-lookup switch */
  1488. with GPR3 GPR4 STACK
  1489. gen
  1490. b {LABEL, ".csa"}
  1491. pat csb /* Table-lookup switch */
  1492. with GPR3 GPR4 STACK
  1493. gen
  1494. b {LABEL, ".csb"}
  1495. /* EM specials */
  1496. pat fil /* Set current filename */
  1497. leaving
  1498. lae $1
  1499. ste ".filename"
  1500. pat lin /* Set current line number */
  1501. leaving
  1502. loc $1
  1503. ste ".linenumber"
  1504. pat lni /* Increment line number */
  1505. leaving
  1506. ine ".linenumber"
  1507. pat lim /* Load EM trap ignore mask */
  1508. leaving
  1509. lde ".ignmask"
  1510. pat sim /* Store EM trap ignore mask */
  1511. leaving
  1512. ste ".ignmask"
  1513. pat trp /* Raise EM trap */
  1514. with GPR3
  1515. gen
  1516. bl {LABEL, ".trap"}
  1517. pat sig /* Set trap handler */
  1518. leaving
  1519. ste ".trppc"
  1520. pat rtt /* Return from trap */
  1521. leaving
  1522. ret 0
  1523. pat lxl $1==0 /* Load FP */
  1524. leaving
  1525. lor 0
  1526. pat lxl $1==1 /* Load caller's FP */
  1527. leaving
  1528. lxl 0
  1529. dch
  1530. pat dch /* FP -> caller FP */
  1531. with GPR
  1532. uses reusing %1, REG
  1533. gen
  1534. lwz %a, {GPRINDIRECT, %1, FP_OFFSET}
  1535. yields %a
  1536. pat lpb /* Convert FP to argument address */
  1537. leaving
  1538. adp EM_BSIZE
  1539. pat lxa /* Load caller's SP */
  1540. leaving
  1541. lxl $1
  1542. lpb
  1543. pat gto /* longjmp */
  1544. uses REG
  1545. gen
  1546. move {LABEL, $1}, %a
  1547. move {IND_RC_W, %a, 8}, FP
  1548. move {IND_RC_W, %a, 4}, SP
  1549. move {IND_RC_W, %a, 0}, %a
  1550. mtspr CTR, %a
  1551. bcctr ALWAYS, {CONST, 0}, {CONST, 0}
  1552. #if 0
  1553. pat gto /* longjmp */
  1554. with STACK
  1555. gen
  1556. ld {LABEL, $1+2}
  1557. wspec {CONST, 1}
  1558. ld {LABEL, $1+4}
  1559. wspec {CONST, 0}
  1560. ld {LABEL, $1+0}
  1561. wspec {CONST, 2}
  1562. pat str $1==1 /* Store special GPRister */
  1563. with GPR0
  1564. gen
  1565. wspec {CONST, $1}
  1566. #endif
  1567. pat lor $1==0 /* Load FP */
  1568. uses REG
  1569. gen
  1570. move FP, %a
  1571. yields %a
  1572. pat lor $1==1 /* Load SP */
  1573. uses REG
  1574. gen
  1575. move SP, %a
  1576. yields %a
  1577. pat lor $1==2 /* Load HP */
  1578. leaving
  1579. loe ".reghp"
  1580. pat str $1==0 /* Store FP */
  1581. with GPR
  1582. gen
  1583. move %1, FP
  1584. pat str $1==1 /* Store SP */
  1585. with GPR
  1586. gen
  1587. move %1, SP
  1588. pat str $1==2 /* Store HP */
  1589. leaving
  1590. ste ".reghp"
  1591. pat ass /* Adjust stack by variable amount */
  1592. with CONST
  1593. gen
  1594. move {SUM_RC, SP, %1.val}, {GPRE, SP}
  1595. with GPR
  1596. gen
  1597. move {SUM_RR, SP, %1}, {GPRE, SP}
  1598. pat asp /* Adjust stack by constant amount */
  1599. leaving
  1600. loc $1
  1601. ass
  1602. /* Floating point support */
  1603. /* All very cheap and nasty --- this needs to be properly integrated into
  1604. * the code generator. ncg doesn't like having separate FPU registers. */
  1605. /* Single-precision */
  1606. pat zrf $1==INT32 /* Push zero */
  1607. leaving
  1608. loe ".fs_00000000"
  1609. pat adf $1==INT32 /* Add single */
  1610. with FS FS
  1611. uses reusing %1, FREG
  1612. gen
  1613. fadds {FS, %a}, %2, %1
  1614. yields {FS, %a}
  1615. pat sbf $1==INT32 /* Subtract single */
  1616. with FS FS
  1617. uses reusing %1, FREG
  1618. gen
  1619. fsubs {FS, %a}, %2, %1
  1620. yields {FS, %a}
  1621. pat mlf $1==INT32 /* Multiply single */
  1622. with FS FS
  1623. uses reusing %1, FREG
  1624. gen
  1625. fmuls {FS, %a}, %2, %1
  1626. yields {FS, %a}
  1627. pat dvf $1==INT32 /* Divide single */
  1628. with FS FS
  1629. uses reusing %1, FREG
  1630. gen
  1631. fdivs {FS, %a}, %2, %1
  1632. yields {FS, %a}
  1633. pat ngf $1==INT32 /* Negate single */
  1634. with FS
  1635. uses reusing %1, FREG
  1636. gen
  1637. fneg {FS, %a}, %1
  1638. yields {FS, %a}
  1639. pat cmf $1==INT32 /* Compare single */
  1640. with FS FS
  1641. yields {TRISTATE_FF, %2.reg, %1.reg}
  1642. pat loc loc cff $1==INT32 && $2==INT64 /* Convert single to double */
  1643. with FS
  1644. yields {FD, %1.reg}
  1645. pat loc loc cfu $1==INT32 && $2==INT32 /* Convert single to unsigned int */
  1646. with STACK
  1647. gen
  1648. bl {LABEL, ".cfu4"}
  1649. pat loc loc cfi $1==INT32 && $2==INT32 /* Convert single to signed int */
  1650. with STACK
  1651. gen
  1652. bl {LABEL, ".cfi4"}
  1653. pat loc loc cif $1==INT32 && $2==INT32 /* Convert integer to single */
  1654. with STACK
  1655. gen
  1656. bl {LABEL, ".cif4"}
  1657. pat loc loc cuf $1==INT32 && $2==INT32 /* Convert unsigned int to single */
  1658. with STACK
  1659. gen
  1660. bl {LABEL, ".cuf4"}
  1661. pat fef $1==INT32 /* Split single */
  1662. with STACK
  1663. gen
  1664. bl {LABEL, ".fef4"}
  1665. /* Double-precision */
  1666. pat zrf $1==INT64 /* Push zero */
  1667. leaving
  1668. lde ".fd_00000000"
  1669. pat adf $1==INT64 /* Add double */
  1670. with FD FD
  1671. uses FREG
  1672. gen
  1673. fadd {FD, %a}, %2, %1
  1674. yields {FD, %a}
  1675. pat sbf $1==INT64 /* Subtract double */
  1676. with FD FD
  1677. uses FREG
  1678. gen
  1679. fsub {FD, %a}, %2, %1
  1680. yields {FD, %a}
  1681. pat mlf $1==INT64 /* Multiply double */
  1682. with FD FD
  1683. uses reusing %1, FREG
  1684. gen
  1685. fmul {FD, %a}, %2, %1
  1686. yields {FD, %a}
  1687. pat dvf $1==INT64 /* Divide double */
  1688. with FD FD
  1689. uses reusing %1, FREG
  1690. gen
  1691. fdiv {FD, %a}, %2, %1
  1692. yields {FD, %a}
  1693. pat ngf $1==INT64 /* Negate double */
  1694. with FD
  1695. uses reusing %1, FREG
  1696. gen
  1697. fneg {FD, %a}, %1
  1698. yields {FD, %a}
  1699. pat cmf $1==INT64 /* Compare double */
  1700. with FD FD
  1701. yields {TRISTATE_FF, %2.reg, %1.reg}
  1702. pat loc loc cff $1==INT64 && $2==INT32 /* Convert double to single */
  1703. with FD
  1704. uses reusing %1, FREG
  1705. gen
  1706. frsp {FS, %a}, %1
  1707. yields {FS, %a}
  1708. pat loc loc cfu $1==INT64 && $2==INT32 /* Convert double to unsigned int */
  1709. with STACK
  1710. gen
  1711. bl {LABEL, ".cfu8"}
  1712. pat loc loc cfi $1==INT64 && $2==INT32 /* Convert double to signed int */
  1713. with STACK
  1714. gen
  1715. bl {LABEL, ".cfi8"}
  1716. pat loc loc cif $1==INT32 && $2==INT64 /* Convert integer to double */
  1717. with STACK
  1718. kills ALL
  1719. gen
  1720. bl {LABEL, ".cif8"}
  1721. pat loc loc cuf $1==INT32 && $2==INT64 /* Convert unsigned int to double */
  1722. with STACK
  1723. gen
  1724. bl {LABEL, ".cuf8"}
  1725. pat fef $1==INT64 /* Split double */
  1726. with FD
  1727. gen
  1728. addi SP, SP, {CONST, 0-8}
  1729. stfd %1, {GPRINDIRECT, SP, 0}
  1730. stwu SP, {GPRINDIRECT, SP, 0-4}
  1731. bl {LABEL, "___fef8"}
  1732. stw R3, {GPRINDIRECT, SP, 0}
  1733. pat fif $1==INT64 /* Multiply and split double (?) */
  1734. with STACK
  1735. gen
  1736. bl {LABEL, ".fif8"}