iq2000.c 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507
  1. /* Subroutines used for code generation on Vitesse IQ2000 processors
  2. Copyright (C) 2003-2015 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. GCC is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "config.h"
  16. #include "system.h"
  17. #include "coretypes.h"
  18. #include "tm.h"
  19. #include "hash-set.h"
  20. #include "machmode.h"
  21. #include "vec.h"
  22. #include "double-int.h"
  23. #include "input.h"
  24. #include "alias.h"
  25. #include "symtab.h"
  26. #include "wide-int.h"
  27. #include "inchash.h"
  28. #include "tree.h"
  29. #include "fold-const.h"
  30. #include "stor-layout.h"
  31. #include "calls.h"
  32. #include "varasm.h"
  33. #include "rtl.h"
  34. #include "regs.h"
  35. #include "hard-reg-set.h"
  36. #include "insn-config.h"
  37. #include "conditions.h"
  38. #include "output.h"
  39. #include "insn-attr.h"
  40. #include "flags.h"
  41. #include "function.h"
  42. #include "hashtab.h"
  43. #include "statistics.h"
  44. #include "real.h"
  45. #include "fixed-value.h"
  46. #include "expmed.h"
  47. #include "dojump.h"
  48. #include "explow.h"
  49. #include "emit-rtl.h"
  50. #include "stmt.h"
  51. #include "expr.h"
  52. #include "insn-codes.h"
  53. #include "optabs.h"
  54. #include "libfuncs.h"
  55. #include "recog.h"
  56. #include "diagnostic-core.h"
  57. #include "reload.h"
  58. #include "ggc.h"
  59. #include "tm_p.h"
  60. #include "debug.h"
  61. #include "target.h"
  62. #include "target-def.h"
  63. #include "langhooks.h"
  64. #include "dominance.h"
  65. #include "cfg.h"
  66. #include "cfgrtl.h"
  67. #include "cfganal.h"
  68. #include "lcm.h"
  69. #include "cfgbuild.h"
  70. #include "cfgcleanup.h"
  71. #include "predict.h"
  72. #include "basic-block.h"
  73. #include "df.h"
  74. #include "builtins.h"
  75. /* Enumeration for all of the relational tests, so that we can build
  76. arrays indexed by the test type, and not worry about the order
  77. of EQ, NE, etc. */
  78. enum internal_test
  79. {
  80. ITEST_EQ,
  81. ITEST_NE,
  82. ITEST_GT,
  83. ITEST_GE,
  84. ITEST_LT,
  85. ITEST_LE,
  86. ITEST_GTU,
  87. ITEST_GEU,
  88. ITEST_LTU,
  89. ITEST_LEU,
  90. ITEST_MAX
  91. };
  92. struct constant;
  93. /* Structure to be filled in by compute_frame_size with register
  94. save masks, and offsets for the current function. */
  95. struct iq2000_frame_info
  96. {
  97. long total_size; /* # bytes that the entire frame takes up. */
  98. long var_size; /* # bytes that variables take up. */
  99. long args_size; /* # bytes that outgoing arguments take up. */
  100. long extra_size; /* # bytes of extra gunk. */
  101. int gp_reg_size; /* # bytes needed to store gp regs. */
  102. int fp_reg_size; /* # bytes needed to store fp regs. */
  103. long mask; /* Mask of saved gp registers. */
  104. long gp_save_offset; /* Offset from vfp to store gp registers. */
  105. long fp_save_offset; /* Offset from vfp to store fp registers. */
  106. long gp_sp_offset; /* Offset from new sp to store gp registers. */
  107. long fp_sp_offset; /* Offset from new sp to store fp registers. */
  108. int initialized; /* != 0 if frame size already calculated. */
  109. int num_gp; /* Number of gp registers saved. */
  110. } iq2000_frame_info;
  111. struct GTY(()) machine_function
  112. {
  113. /* Current frame information, calculated by compute_frame_size. */
  114. long total_size; /* # bytes that the entire frame takes up. */
  115. long var_size; /* # bytes that variables take up. */
  116. long args_size; /* # bytes that outgoing arguments take up. */
  117. long extra_size; /* # bytes of extra gunk. */
  118. int gp_reg_size; /* # bytes needed to store gp regs. */
  119. int fp_reg_size; /* # bytes needed to store fp regs. */
  120. long mask; /* Mask of saved gp registers. */
  121. long gp_save_offset; /* Offset from vfp to store gp registers. */
  122. long fp_save_offset; /* Offset from vfp to store fp registers. */
  123. long gp_sp_offset; /* Offset from new sp to store gp registers. */
  124. long fp_sp_offset; /* Offset from new sp to store fp registers. */
  125. int initialized; /* != 0 if frame size already calculated. */
  126. int num_gp; /* Number of gp registers saved. */
  127. };
  128. /* Global variables for machine-dependent things. */
  129. /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
  130. static char iq2000_print_operand_punct[256];
  131. /* Which instruction set architecture to use. */
  132. int iq2000_isa;
  133. /* Local variables. */
  134. /* The next branch instruction is a branch likely, not branch normal. */
  135. static int iq2000_branch_likely;
  136. /* Count of delay slots and how many are filled. */
  137. static int dslots_load_total;
  138. static int dslots_load_filled;
  139. static int dslots_jump_total;
  140. /* # of nops needed by previous insn. */
  141. static int dslots_number_nops;
  142. /* Number of 1/2/3 word references to data items (i.e., not jal's). */
  143. static int num_refs[3];
  144. /* Registers to check for load delay. */
  145. static rtx iq2000_load_reg;
  146. static rtx iq2000_load_reg2;
  147. static rtx iq2000_load_reg3;
  148. static rtx iq2000_load_reg4;
  149. /* Mode used for saving/restoring general purpose registers. */
  150. static machine_mode gpr_mode;
  151. /* Initialize the GCC target structure. */
  152. static struct machine_function* iq2000_init_machine_status (void);
  153. static void iq2000_option_override (void);
  154. static section *iq2000_select_rtx_section (machine_mode, rtx,
  155. unsigned HOST_WIDE_INT);
  156. static void iq2000_init_builtins (void);
  157. static rtx iq2000_expand_builtin (tree, rtx, rtx, machine_mode, int);
  158. static bool iq2000_return_in_memory (const_tree, const_tree);
  159. static void iq2000_setup_incoming_varargs (cumulative_args_t,
  160. machine_mode, tree, int *,
  161. int);
  162. static bool iq2000_rtx_costs (rtx, int, int, int, int *, bool);
  163. static int iq2000_address_cost (rtx, machine_mode, addr_space_t,
  164. bool);
  165. static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
  166. static rtx iq2000_legitimize_address (rtx, rtx, machine_mode);
  167. static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode,
  168. const_tree, bool);
  169. static int iq2000_arg_partial_bytes (cumulative_args_t, machine_mode,
  170. tree, bool);
  171. static rtx iq2000_function_arg (cumulative_args_t,
  172. machine_mode, const_tree, bool);
  173. static void iq2000_function_arg_advance (cumulative_args_t,
  174. machine_mode, const_tree, bool);
  175. static unsigned int iq2000_function_arg_boundary (machine_mode,
  176. const_tree);
  177. static void iq2000_va_start (tree, rtx);
  178. static bool iq2000_legitimate_address_p (machine_mode, rtx, bool);
  179. static bool iq2000_can_eliminate (const int, const int);
  180. static void iq2000_asm_trampoline_template (FILE *);
  181. static void iq2000_trampoline_init (rtx, tree, rtx);
  182. static rtx iq2000_function_value (const_tree, const_tree, bool);
  183. static rtx iq2000_libcall_value (machine_mode, const_rtx);
  184. static void iq2000_print_operand (FILE *, rtx, int);
  185. static void iq2000_print_operand_address (FILE *, rtx);
  186. static bool iq2000_print_operand_punct_valid_p (unsigned char code);
  187. #undef TARGET_INIT_BUILTINS
  188. #define TARGET_INIT_BUILTINS iq2000_init_builtins
  189. #undef TARGET_EXPAND_BUILTIN
  190. #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
  191. #undef TARGET_ASM_SELECT_RTX_SECTION
  192. #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
  193. #undef TARGET_OPTION_OVERRIDE
  194. #define TARGET_OPTION_OVERRIDE iq2000_option_override
  195. #undef TARGET_RTX_COSTS
  196. #define TARGET_RTX_COSTS iq2000_rtx_costs
  197. #undef TARGET_ADDRESS_COST
  198. #define TARGET_ADDRESS_COST iq2000_address_cost
  199. #undef TARGET_ASM_SELECT_SECTION
  200. #define TARGET_ASM_SELECT_SECTION iq2000_select_section
  201. #undef TARGET_LEGITIMIZE_ADDRESS
  202. #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
  203. /* The assembler supports switchable .bss sections, but
  204. iq2000_select_section doesn't yet make use of them. */
  205. #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
  206. #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
  207. #undef TARGET_PRINT_OPERAND
  208. #define TARGET_PRINT_OPERAND iq2000_print_operand
  209. #undef TARGET_PRINT_OPERAND_ADDRESS
  210. #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
  211. #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
  212. #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
  213. #undef TARGET_PROMOTE_FUNCTION_MODE
  214. #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
  215. #undef TARGET_PROMOTE_PROTOTYPES
  216. #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
  217. #undef TARGET_FUNCTION_VALUE
  218. #define TARGET_FUNCTION_VALUE iq2000_function_value
  219. #undef TARGET_LIBCALL_VALUE
  220. #define TARGET_LIBCALL_VALUE iq2000_libcall_value
  221. #undef TARGET_RETURN_IN_MEMORY
  222. #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
  223. #undef TARGET_PASS_BY_REFERENCE
  224. #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
  225. #undef TARGET_CALLEE_COPIES
  226. #define TARGET_CALLEE_COPIES hook_callee_copies_named
  227. #undef TARGET_ARG_PARTIAL_BYTES
  228. #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
  229. #undef TARGET_FUNCTION_ARG
  230. #define TARGET_FUNCTION_ARG iq2000_function_arg
  231. #undef TARGET_FUNCTION_ARG_ADVANCE
  232. #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
  233. #undef TARGET_FUNCTION_ARG_BOUNDARY
  234. #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
  235. #undef TARGET_SETUP_INCOMING_VARARGS
  236. #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
  237. #undef TARGET_STRICT_ARGUMENT_NAMING
  238. #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
  239. #undef TARGET_EXPAND_BUILTIN_VA_START
  240. #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
  241. #undef TARGET_LEGITIMATE_ADDRESS_P
  242. #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
  243. #undef TARGET_CAN_ELIMINATE
  244. #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
  245. #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
  246. #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
  247. #undef TARGET_TRAMPOLINE_INIT
  248. #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
  249. struct gcc_target targetm = TARGET_INITIALIZER;
  250. /* Return nonzero if we split the address into high and low parts. */
  251. int
  252. iq2000_check_split (rtx address, machine_mode mode)
  253. {
  254. /* This is the same check used in simple_memory_operand.
  255. We use it here because LO_SUM is not offsettable. */
  256. if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
  257. return 0;
  258. if ((GET_CODE (address) == SYMBOL_REF)
  259. || (GET_CODE (address) == CONST
  260. && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
  261. || GET_CODE (address) == LABEL_REF)
  262. return 1;
  263. return 0;
  264. }
  265. /* Return nonzero if REG is valid for MODE. */
  266. int
  267. iq2000_reg_mode_ok_for_base_p (rtx reg,
  268. machine_mode mode ATTRIBUTE_UNUSED,
  269. int strict)
  270. {
  271. return (strict
  272. ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
  273. : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
  274. }
  275. /* Return a nonzero value if XINSN is a legitimate address for a
  276. memory operand of the indicated MODE. STRICT is nonzero if this
  277. function is called during reload. */
  278. bool
  279. iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict)
  280. {
  281. if (TARGET_DEBUG_A_MODE)
  282. {
  283. GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
  284. strict ? "" : "not ");
  285. GO_DEBUG_RTX (xinsn);
  286. }
  287. /* Check for constant before stripping off SUBREG, so that we don't
  288. accept (subreg (const_int)) which will fail to reload. */
  289. if (CONSTANT_ADDRESS_P (xinsn)
  290. && ! (iq2000_check_split (xinsn, mode))
  291. && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
  292. return 1;
  293. while (GET_CODE (xinsn) == SUBREG)
  294. xinsn = SUBREG_REG (xinsn);
  295. if (GET_CODE (xinsn) == REG
  296. && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
  297. return 1;
  298. if (GET_CODE (xinsn) == LO_SUM)
  299. {
  300. rtx xlow0 = XEXP (xinsn, 0);
  301. rtx xlow1 = XEXP (xinsn, 1);
  302. while (GET_CODE (xlow0) == SUBREG)
  303. xlow0 = SUBREG_REG (xlow0);
  304. if (GET_CODE (xlow0) == REG
  305. && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
  306. && iq2000_check_split (xlow1, mode))
  307. return 1;
  308. }
  309. if (GET_CODE (xinsn) == PLUS)
  310. {
  311. rtx xplus0 = XEXP (xinsn, 0);
  312. rtx xplus1 = XEXP (xinsn, 1);
  313. enum rtx_code code0;
  314. enum rtx_code code1;
  315. while (GET_CODE (xplus0) == SUBREG)
  316. xplus0 = SUBREG_REG (xplus0);
  317. code0 = GET_CODE (xplus0);
  318. while (GET_CODE (xplus1) == SUBREG)
  319. xplus1 = SUBREG_REG (xplus1);
  320. code1 = GET_CODE (xplus1);
  321. if (code0 == REG
  322. && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
  323. {
  324. if (code1 == CONST_INT && SMALL_INT (xplus1)
  325. && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
  326. return 1;
  327. }
  328. }
  329. if (TARGET_DEBUG_A_MODE)
  330. GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
  331. /* The address was not legitimate. */
  332. return 0;
  333. }
  334. /* Returns an operand string for the given instruction's delay slot,
  335. after updating filled delay slot statistics.
  336. We assume that operands[0] is the target register that is set.
  337. In order to check the next insn, most of this functionality is moved
  338. to FINAL_PRESCAN_INSN, and we just set the global variables that
  339. it needs. */
  340. const char *
  341. iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
  342. rtx_insn *cur_insn)
  343. {
  344. rtx set_reg;
  345. machine_mode mode;
  346. rtx_insn *next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL;
  347. int num_nops;
  348. if (type == DELAY_LOAD || type == DELAY_FCMP)
  349. num_nops = 1;
  350. else
  351. num_nops = 0;
  352. /* Make sure that we don't put nop's after labels. */
  353. next_insn = NEXT_INSN (cur_insn);
  354. while (next_insn != 0
  355. && (NOTE_P (next_insn) || LABEL_P (next_insn)))
  356. next_insn = NEXT_INSN (next_insn);
  357. dslots_load_total += num_nops;
  358. if (TARGET_DEBUG_C_MODE
  359. || type == DELAY_NONE
  360. || operands == 0
  361. || cur_insn == 0
  362. || next_insn == 0
  363. || LABEL_P (next_insn)
  364. || (set_reg = operands[0]) == 0)
  365. {
  366. dslots_number_nops = 0;
  367. iq2000_load_reg = 0;
  368. iq2000_load_reg2 = 0;
  369. iq2000_load_reg3 = 0;
  370. iq2000_load_reg4 = 0;
  371. return ret;
  372. }
  373. set_reg = operands[0];
  374. if (set_reg == 0)
  375. return ret;
  376. while (GET_CODE (set_reg) == SUBREG)
  377. set_reg = SUBREG_REG (set_reg);
  378. mode = GET_MODE (set_reg);
  379. dslots_number_nops = num_nops;
  380. iq2000_load_reg = set_reg;
  381. if (GET_MODE_SIZE (mode)
  382. > (unsigned) (UNITS_PER_WORD))
  383. iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
  384. else
  385. iq2000_load_reg2 = 0;
  386. return ret;
  387. }
  388. /* Determine whether a memory reference takes one (based off of the GP
  389. pointer), two (normal), or three (label + reg) instructions, and bump the
  390. appropriate counter for -mstats. */
  391. static void
  392. iq2000_count_memory_refs (rtx op, int num)
  393. {
  394. int additional = 0;
  395. int n_words = 0;
  396. rtx addr, plus0, plus1;
  397. enum rtx_code code0, code1;
  398. int looping;
  399. if (TARGET_DEBUG_B_MODE)
  400. {
  401. fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
  402. debug_rtx (op);
  403. }
  404. /* Skip MEM if passed, otherwise handle movsi of address. */
  405. addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
  406. /* Loop, going through the address RTL. */
  407. do
  408. {
  409. looping = FALSE;
  410. switch (GET_CODE (addr))
  411. {
  412. case REG:
  413. case CONST_INT:
  414. case LO_SUM:
  415. break;
  416. case PLUS:
  417. plus0 = XEXP (addr, 0);
  418. plus1 = XEXP (addr, 1);
  419. code0 = GET_CODE (plus0);
  420. code1 = GET_CODE (plus1);
  421. if (code0 == REG)
  422. {
  423. additional++;
  424. addr = plus1;
  425. looping = 1;
  426. continue;
  427. }
  428. if (code0 == CONST_INT)
  429. {
  430. addr = plus1;
  431. looping = 1;
  432. continue;
  433. }
  434. if (code1 == REG)
  435. {
  436. additional++;
  437. addr = plus0;
  438. looping = 1;
  439. continue;
  440. }
  441. if (code1 == CONST_INT)
  442. {
  443. addr = plus0;
  444. looping = 1;
  445. continue;
  446. }
  447. if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
  448. {
  449. addr = plus0;
  450. looping = 1;
  451. continue;
  452. }
  453. if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
  454. {
  455. addr = plus1;
  456. looping = 1;
  457. continue;
  458. }
  459. break;
  460. case LABEL_REF:
  461. n_words = 2; /* Always 2 words. */
  462. break;
  463. case CONST:
  464. addr = XEXP (addr, 0);
  465. looping = 1;
  466. continue;
  467. case SYMBOL_REF:
  468. n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
  469. break;
  470. default:
  471. break;
  472. }
  473. }
  474. while (looping);
  475. if (n_words == 0)
  476. return;
  477. n_words += additional;
  478. if (n_words > 3)
  479. n_words = 3;
  480. num_refs[n_words-1] += num;
  481. }
  482. /* Abort after printing out a specific insn. */
  483. static void
  484. abort_with_insn (rtx insn, const char * reason)
  485. {
  486. error (reason);
  487. debug_rtx (insn);
  488. fancy_abort (__FILE__, __LINE__, __FUNCTION__);
  489. }
  490. /* Return the appropriate instructions to move one operand to another. */
  491. const char *
  492. iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp)
  493. {
  494. const char *ret = 0;
  495. rtx op0 = operands[0];
  496. rtx op1 = operands[1];
  497. enum rtx_code code0 = GET_CODE (op0);
  498. enum rtx_code code1 = GET_CODE (op1);
  499. machine_mode mode = GET_MODE (op0);
  500. int subreg_offset0 = 0;
  501. int subreg_offset1 = 0;
  502. enum delay_type delay = DELAY_NONE;
  503. while (code0 == SUBREG)
  504. {
  505. subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
  506. GET_MODE (SUBREG_REG (op0)),
  507. SUBREG_BYTE (op0),
  508. GET_MODE (op0));
  509. op0 = SUBREG_REG (op0);
  510. code0 = GET_CODE (op0);
  511. }
  512. while (code1 == SUBREG)
  513. {
  514. subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
  515. GET_MODE (SUBREG_REG (op1)),
  516. SUBREG_BYTE (op1),
  517. GET_MODE (op1));
  518. op1 = SUBREG_REG (op1);
  519. code1 = GET_CODE (op1);
  520. }
  521. /* For our purposes, a condition code mode is the same as SImode. */
  522. if (mode == CCmode)
  523. mode = SImode;
  524. if (code0 == REG)
  525. {
  526. int regno0 = REGNO (op0) + subreg_offset0;
  527. if (code1 == REG)
  528. {
  529. int regno1 = REGNO (op1) + subreg_offset1;
  530. /* Do not do anything for assigning a register to itself */
  531. if (regno0 == regno1)
  532. ret = "";
  533. else if (GP_REG_P (regno0))
  534. {
  535. if (GP_REG_P (regno1))
  536. ret = "or\t%0,%%0,%1";
  537. }
  538. }
  539. else if (code1 == MEM)
  540. {
  541. delay = DELAY_LOAD;
  542. if (TARGET_STATS)
  543. iq2000_count_memory_refs (op1, 1);
  544. if (GP_REG_P (regno0))
  545. {
  546. /* For loads, use the mode of the memory item, instead of the
  547. target, so zero/sign extend can use this code as well. */
  548. switch (GET_MODE (op1))
  549. {
  550. default:
  551. break;
  552. case SFmode:
  553. ret = "lw\t%0,%1";
  554. break;
  555. case SImode:
  556. case CCmode:
  557. ret = "lw\t%0,%1";
  558. break;
  559. case HImode:
  560. ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
  561. break;
  562. case QImode:
  563. ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
  564. break;
  565. }
  566. }
  567. }
  568. else if (code1 == CONST_INT
  569. || (code1 == CONST_DOUBLE
  570. && GET_MODE (op1) == VOIDmode))
  571. {
  572. if (code1 == CONST_DOUBLE)
  573. {
  574. /* This can happen when storing constants into long long
  575. bitfields. Just store the least significant word of
  576. the value. */
  577. operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
  578. }
  579. if (INTVAL (op1) == 0)
  580. {
  581. if (GP_REG_P (regno0))
  582. ret = "or\t%0,%%0,%z1";
  583. }
  584. else if (GP_REG_P (regno0))
  585. {
  586. if (SMALL_INT_UNSIGNED (op1))
  587. ret = "ori\t%0,%%0,%x1\t\t\t# %1";
  588. else if (SMALL_INT (op1))
  589. ret = "addiu\t%0,%%0,%1\t\t\t# %1";
  590. else
  591. ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
  592. }
  593. }
  594. else if (code1 == CONST_DOUBLE && mode == SFmode)
  595. {
  596. if (op1 == CONST0_RTX (SFmode))
  597. {
  598. if (GP_REG_P (regno0))
  599. ret = "or\t%0,%%0,%.";
  600. }
  601. else
  602. {
  603. delay = DELAY_LOAD;
  604. ret = "li.s\t%0,%1";
  605. }
  606. }
  607. else if (code1 == LABEL_REF)
  608. {
  609. if (TARGET_STATS)
  610. iq2000_count_memory_refs (op1, 1);
  611. ret = "la\t%0,%a1";
  612. }
  613. else if (code1 == SYMBOL_REF || code1 == CONST)
  614. {
  615. if (TARGET_STATS)
  616. iq2000_count_memory_refs (op1, 1);
  617. ret = "la\t%0,%a1";
  618. }
  619. else if (code1 == PLUS)
  620. {
  621. rtx add_op0 = XEXP (op1, 0);
  622. rtx add_op1 = XEXP (op1, 1);
  623. if (GET_CODE (XEXP (op1, 1)) == REG
  624. && GET_CODE (XEXP (op1, 0)) == CONST_INT)
  625. add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
  626. operands[2] = add_op0;
  627. operands[3] = add_op1;
  628. ret = "add%:\t%0,%2,%3";
  629. }
  630. else if (code1 == HIGH)
  631. {
  632. operands[1] = XEXP (op1, 0);
  633. ret = "lui\t%0,%%hi(%1)";
  634. }
  635. }
  636. else if (code0 == MEM)
  637. {
  638. if (TARGET_STATS)
  639. iq2000_count_memory_refs (op0, 1);
  640. if (code1 == REG)
  641. {
  642. int regno1 = REGNO (op1) + subreg_offset1;
  643. if (GP_REG_P (regno1))
  644. {
  645. switch (mode)
  646. {
  647. case SFmode: ret = "sw\t%1,%0"; break;
  648. case SImode: ret = "sw\t%1,%0"; break;
  649. case HImode: ret = "sh\t%1,%0"; break;
  650. case QImode: ret = "sb\t%1,%0"; break;
  651. default: break;
  652. }
  653. }
  654. }
  655. else if (code1 == CONST_INT && INTVAL (op1) == 0)
  656. {
  657. switch (mode)
  658. {
  659. case SFmode: ret = "sw\t%z1,%0"; break;
  660. case SImode: ret = "sw\t%z1,%0"; break;
  661. case HImode: ret = "sh\t%z1,%0"; break;
  662. case QImode: ret = "sb\t%z1,%0"; break;
  663. default: break;
  664. }
  665. }
  666. else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
  667. {
  668. switch (mode)
  669. {
  670. case SFmode: ret = "sw\t%.,%0"; break;
  671. case SImode: ret = "sw\t%.,%0"; break;
  672. case HImode: ret = "sh\t%.,%0"; break;
  673. case QImode: ret = "sb\t%.,%0"; break;
  674. default: break;
  675. }
  676. }
  677. }
  678. if (ret == 0)
  679. {
  680. abort_with_insn (insn, "Bad move");
  681. return 0;
  682. }
  683. if (delay != DELAY_NONE)
  684. return iq2000_fill_delay_slot (ret, delay, operands, insn);
  685. return ret;
  686. }
  687. /* Provide the costs of an addressing mode that contains ADDR. */
  688. static int
  689. iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as,
  690. bool speed)
  691. {
  692. switch (GET_CODE (addr))
  693. {
  694. case LO_SUM:
  695. return 1;
  696. case LABEL_REF:
  697. return 2;
  698. case CONST:
  699. {
  700. rtx offset = const0_rtx;
  701. addr = eliminate_constant_term (XEXP (addr, 0), & offset);
  702. if (GET_CODE (addr) == LABEL_REF)
  703. return 2;
  704. if (GET_CODE (addr) != SYMBOL_REF)
  705. return 4;
  706. if (! SMALL_INT (offset))
  707. return 2;
  708. }
  709. /* Fall through. */
  710. case SYMBOL_REF:
  711. return SYMBOL_REF_FLAG (addr) ? 1 : 2;
  712. case PLUS:
  713. {
  714. rtx plus0 = XEXP (addr, 0);
  715. rtx plus1 = XEXP (addr, 1);
  716. if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
  717. plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
  718. if (GET_CODE (plus0) != REG)
  719. break;
  720. switch (GET_CODE (plus1))
  721. {
  722. case CONST_INT:
  723. return SMALL_INT (plus1) ? 1 : 2;
  724. case CONST:
  725. case SYMBOL_REF:
  726. case LABEL_REF:
  727. case HIGH:
  728. case LO_SUM:
  729. return iq2000_address_cost (plus1, mode, as, speed) + 1;
  730. default:
  731. break;
  732. }
  733. }
  734. default:
  735. break;
  736. }
  737. return 4;
  738. }
  739. /* Make normal rtx_code into something we can index from an array. */
  740. static enum internal_test
  741. map_test_to_internal_test (enum rtx_code test_code)
  742. {
  743. enum internal_test test = ITEST_MAX;
  744. switch (test_code)
  745. {
  746. case EQ: test = ITEST_EQ; break;
  747. case NE: test = ITEST_NE; break;
  748. case GT: test = ITEST_GT; break;
  749. case GE: test = ITEST_GE; break;
  750. case LT: test = ITEST_LT; break;
  751. case LE: test = ITEST_LE; break;
  752. case GTU: test = ITEST_GTU; break;
  753. case GEU: test = ITEST_GEU; break;
  754. case LTU: test = ITEST_LTU; break;
  755. case LEU: test = ITEST_LEU; break;
  756. default: break;
  757. }
  758. return test;
  759. }
  760. /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
  761. and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
  762. The return value RESULT is:
  763. (reg:SI xx) The pseudo register the comparison is in
  764. 0 No register, generate a simple branch. */
  765. rtx
  766. gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
  767. int *p_invert)
  768. {
  769. struct cmp_info
  770. {
  771. enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
  772. int const_low; /* Low bound of constant we can accept. */
  773. int const_high; /* High bound of constant we can accept. */
  774. int const_add; /* Constant to add (convert LE -> LT). */
  775. int reverse_regs; /* Reverse registers in test. */
  776. int invert_const; /* != 0 if invert value if cmp1 is constant. */
  777. int invert_reg; /* != 0 if invert value if cmp1 is register. */
  778. int unsignedp; /* != 0 for unsigned comparisons. */
  779. };
  780. static struct cmp_info info[ (int)ITEST_MAX ] =
  781. {
  782. { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
  783. { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
  784. { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
  785. { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
  786. { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
  787. { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
  788. { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
  789. { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
  790. { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
  791. { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
  792. };
  793. enum internal_test test;
  794. machine_mode mode;
  795. struct cmp_info *p_info;
  796. int branch_p;
  797. int eqne_p;
  798. int invert;
  799. rtx reg;
  800. rtx reg2;
  801. test = map_test_to_internal_test (test_code);
  802. gcc_assert (test != ITEST_MAX);
  803. p_info = &info[(int) test];
  804. eqne_p = (p_info->test_code == XOR);
  805. mode = GET_MODE (cmp0);
  806. if (mode == VOIDmode)
  807. mode = GET_MODE (cmp1);
  808. /* Eliminate simple branches. */
  809. branch_p = (result == 0);
  810. if (branch_p)
  811. {
  812. if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
  813. {
  814. /* Comparisons against zero are simple branches. */
  815. if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
  816. return 0;
  817. /* Test for beq/bne. */
  818. if (eqne_p)
  819. return 0;
  820. }
  821. /* Allocate a pseudo to calculate the value in. */
  822. result = gen_reg_rtx (mode);
  823. }
  824. /* Make sure we can handle any constants given to us. */
  825. if (GET_CODE (cmp0) == CONST_INT)
  826. cmp0 = force_reg (mode, cmp0);
  827. if (GET_CODE (cmp1) == CONST_INT)
  828. {
  829. HOST_WIDE_INT value = INTVAL (cmp1);
  830. if (value < p_info->const_low
  831. || value > p_info->const_high)
  832. cmp1 = force_reg (mode, cmp1);
  833. }
  834. /* See if we need to invert the result. */
  835. invert = (GET_CODE (cmp1) == CONST_INT
  836. ? p_info->invert_const : p_info->invert_reg);
  837. if (p_invert != (int *)0)
  838. {
  839. *p_invert = invert;
  840. invert = 0;
  841. }
  842. /* Comparison to constants, may involve adding 1 to change a LT into LE.
  843. Comparison between two registers, may involve switching operands. */
  844. if (GET_CODE (cmp1) == CONST_INT)
  845. {
  846. if (p_info->const_add != 0)
  847. {
  848. HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
  849. /* If modification of cmp1 caused overflow,
  850. we would get the wrong answer if we follow the usual path;
  851. thus, x > 0xffffffffU would turn into x > 0U. */
  852. if ((p_info->unsignedp
  853. ? (unsigned HOST_WIDE_INT) new_const >
  854. (unsigned HOST_WIDE_INT) INTVAL (cmp1)
  855. : new_const > INTVAL (cmp1))
  856. != (p_info->const_add > 0))
  857. {
  858. /* This test is always true, but if INVERT is true then
  859. the result of the test needs to be inverted so 0 should
  860. be returned instead. */
  861. emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
  862. return result;
  863. }
  864. else
  865. cmp1 = GEN_INT (new_const);
  866. }
  867. }
  868. else if (p_info->reverse_regs)
  869. {
  870. rtx temp = cmp0;
  871. cmp0 = cmp1;
  872. cmp1 = temp;
  873. }
  874. if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
  875. reg = cmp0;
  876. else
  877. {
  878. reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
  879. convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
  880. }
  881. if (test == ITEST_NE)
  882. {
  883. convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
  884. if (p_invert != NULL)
  885. *p_invert = 0;
  886. invert = 0;
  887. }
  888. else if (test == ITEST_EQ)
  889. {
  890. reg2 = invert ? gen_reg_rtx (mode) : result;
  891. convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
  892. reg = reg2;
  893. }
  894. if (invert)
  895. {
  896. rtx one;
  897. one = const1_rtx;
  898. convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
  899. }
  900. return result;
  901. }
  902. /* Emit the common code for doing conditional branches.
  903. operand[0] is the label to jump to.
  904. The comparison operands are saved away by cmp{si,di,sf,df}. */
  905. void
  906. gen_conditional_branch (rtx operands[], machine_mode mode)
  907. {
  908. enum rtx_code test_code = GET_CODE (operands[0]);
  909. rtx cmp0 = operands[1];
  910. rtx cmp1 = operands[2];
  911. rtx reg;
  912. int invert;
  913. rtx label1, label2;
  914. invert = 0;
  915. reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
  916. if (reg)
  917. {
  918. cmp0 = reg;
  919. cmp1 = const0_rtx;
  920. test_code = NE;
  921. }
  922. else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
  923. /* We don't want to build a comparison against a nonzero
  924. constant. */
  925. cmp1 = force_reg (mode, cmp1);
  926. /* Generate the branch. */
  927. label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
  928. label2 = pc_rtx;
  929. if (invert)
  930. {
  931. label2 = label1;
  932. label1 = pc_rtx;
  933. }
  934. emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
  935. gen_rtx_IF_THEN_ELSE (VOIDmode,
  936. gen_rtx_fmt_ee (test_code,
  937. VOIDmode,
  938. cmp0, cmp1),
  939. label1, label2)));
  940. }
  941. /* Initialize CUM for a function FNTYPE. */
  942. void
  943. init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
  944. rtx libname ATTRIBUTE_UNUSED)
  945. {
  946. static CUMULATIVE_ARGS zero_cum;
  947. tree param;
  948. tree next_param;
  949. if (TARGET_DEBUG_D_MODE)
  950. {
  951. fprintf (stderr,
  952. "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
  953. if (!fntype)
  954. fputc ('\n', stderr);
  955. else
  956. {
  957. tree ret_type = TREE_TYPE (fntype);
  958. fprintf (stderr, ", fntype code = %s, ret code = %s\n",
  959. get_tree_code_name (TREE_CODE (fntype)),
  960. get_tree_code_name (TREE_CODE (ret_type)));
  961. }
  962. }
  963. *cum = zero_cum;
  964. /* Determine if this function has variable arguments. This is
  965. indicated by the last argument being 'void_type_mode' if there
  966. are no variable arguments. The standard IQ2000 calling sequence
  967. passes all arguments in the general purpose registers in this case. */
  968. for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
  969. param != 0; param = next_param)
  970. {
  971. next_param = TREE_CHAIN (param);
  972. if (next_param == 0 && TREE_VALUE (param) != void_type_node)
  973. cum->gp_reg_found = 1;
  974. }
  975. }
  976. /* Advance the argument of type TYPE and mode MODE to the next argument
  977. position in CUM. */
  978. static void
  979. iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
  980. const_tree type, bool named)
  981. {
  982. CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  983. if (TARGET_DEBUG_D_MODE)
  984. {
  985. fprintf (stderr,
  986. "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
  987. cum->gp_reg_found, cum->arg_number, cum->arg_words,
  988. GET_MODE_NAME (mode));
  989. fprintf (stderr, "%p", (const void *) type);
  990. fprintf (stderr, ", %d )\n\n", named);
  991. }
  992. cum->arg_number++;
  993. switch (mode)
  994. {
  995. case VOIDmode:
  996. break;
  997. default:
  998. gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
  999. || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
  1000. cum->gp_reg_found = 1;
  1001. cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
  1002. / UNITS_PER_WORD);
  1003. break;
  1004. case BLKmode:
  1005. cum->gp_reg_found = 1;
  1006. cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
  1007. / UNITS_PER_WORD);
  1008. break;
  1009. case SFmode:
  1010. cum->arg_words ++;
  1011. if (! cum->gp_reg_found && cum->arg_number <= 2)
  1012. cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
  1013. break;
  1014. case DFmode:
  1015. cum->arg_words += 2;
  1016. if (! cum->gp_reg_found && cum->arg_number <= 2)
  1017. cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
  1018. break;
  1019. case DImode:
  1020. cum->gp_reg_found = 1;
  1021. cum->arg_words += 2;
  1022. break;
  1023. case TImode:
  1024. cum->gp_reg_found = 1;
  1025. cum->arg_words += 4;
  1026. break;
  1027. case QImode:
  1028. case HImode:
  1029. case SImode:
  1030. cum->gp_reg_found = 1;
  1031. cum->arg_words ++;
  1032. break;
  1033. }
  1034. }
  1035. /* Return an RTL expression containing the register for the given mode MODE
  1036. and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
  1037. static rtx
  1038. iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
  1039. const_tree type, bool named)
  1040. {
  1041. CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  1042. rtx ret;
  1043. int regbase = -1;
  1044. int bias = 0;
  1045. unsigned int *arg_words = &cum->arg_words;
  1046. int struct_p = (type != 0
  1047. && (TREE_CODE (type) == RECORD_TYPE
  1048. || TREE_CODE (type) == UNION_TYPE
  1049. || TREE_CODE (type) == QUAL_UNION_TYPE));
  1050. if (TARGET_DEBUG_D_MODE)
  1051. {
  1052. fprintf (stderr,
  1053. "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
  1054. cum->gp_reg_found, cum->arg_number, cum->arg_words,
  1055. GET_MODE_NAME (mode));
  1056. fprintf (stderr, "%p", (const void *) type);
  1057. fprintf (stderr, ", %d ) = ", named);
  1058. }
  1059. cum->last_arg_fp = 0;
  1060. switch (mode)
  1061. {
  1062. case SFmode:
  1063. regbase = GP_ARG_FIRST;
  1064. break;
  1065. case DFmode:
  1066. cum->arg_words += cum->arg_words & 1;
  1067. regbase = GP_ARG_FIRST;
  1068. break;
  1069. default:
  1070. gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
  1071. || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
  1072. /* Drops through. */
  1073. case BLKmode:
  1074. if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
  1075. cum->arg_words += (cum->arg_words & 1);
  1076. regbase = GP_ARG_FIRST;
  1077. break;
  1078. case VOIDmode:
  1079. case QImode:
  1080. case HImode:
  1081. case SImode:
  1082. regbase = GP_ARG_FIRST;
  1083. break;
  1084. case DImode:
  1085. cum->arg_words += (cum->arg_words & 1);
  1086. regbase = GP_ARG_FIRST;
  1087. break;
  1088. case TImode:
  1089. cum->arg_words += (cum->arg_words & 3);
  1090. regbase = GP_ARG_FIRST;
  1091. break;
  1092. }
  1093. if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
  1094. {
  1095. if (TARGET_DEBUG_D_MODE)
  1096. fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
  1097. ret = 0;
  1098. }
  1099. else
  1100. {
  1101. gcc_assert (regbase != -1);
  1102. if (! type || TREE_CODE (type) != RECORD_TYPE
  1103. || ! named || ! TYPE_SIZE_UNIT (type)
  1104. || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
  1105. ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
  1106. else
  1107. {
  1108. tree field;
  1109. for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
  1110. if (TREE_CODE (field) == FIELD_DECL
  1111. && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
  1112. && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
  1113. && tree_fits_shwi_p (bit_position (field))
  1114. && int_bit_position (field) % BITS_PER_WORD == 0)
  1115. break;
  1116. /* If the whole struct fits a DFmode register,
  1117. we don't need the PARALLEL. */
  1118. if (! field || mode == DFmode)
  1119. ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
  1120. else
  1121. {
  1122. unsigned int chunks;
  1123. HOST_WIDE_INT bitpos;
  1124. unsigned int regno;
  1125. unsigned int i;
  1126. /* ??? If this is a packed structure, then the last hunk won't
  1127. be 64 bits. */
  1128. chunks
  1129. = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
  1130. if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
  1131. chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
  1132. /* Assign_parms checks the mode of ENTRY_PARM, so we must
  1133. use the actual mode here. */
  1134. ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
  1135. bitpos = 0;
  1136. regno = regbase + *arg_words + bias;
  1137. field = TYPE_FIELDS (type);
  1138. for (i = 0; i < chunks; i++)
  1139. {
  1140. rtx reg;
  1141. for (; field; field = DECL_CHAIN (field))
  1142. if (TREE_CODE (field) == FIELD_DECL
  1143. && int_bit_position (field) >= bitpos)
  1144. break;
  1145. if (field
  1146. && int_bit_position (field) == bitpos
  1147. && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
  1148. && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
  1149. reg = gen_rtx_REG (DFmode, regno++);
  1150. else
  1151. reg = gen_rtx_REG (word_mode, regno);
  1152. XVECEXP (ret, 0, i)
  1153. = gen_rtx_EXPR_LIST (VOIDmode, reg,
  1154. GEN_INT (bitpos / BITS_PER_UNIT));
  1155. bitpos += 64;
  1156. regno++;
  1157. }
  1158. }
  1159. }
  1160. if (TARGET_DEBUG_D_MODE)
  1161. fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
  1162. struct_p ? ", [struct]" : "");
  1163. }
  1164. /* We will be called with a mode of VOIDmode after the last argument
  1165. has been seen. Whatever we return will be passed to the call
  1166. insn. If we need any shifts for small structures, return them in
  1167. a PARALLEL. */
  1168. if (mode == VOIDmode)
  1169. {
  1170. if (cum->num_adjusts > 0)
  1171. ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
  1172. gen_rtvec_v (cum->num_adjusts, cum->adjust));
  1173. }
  1174. return ret;
  1175. }
  1176. static unsigned int
  1177. iq2000_function_arg_boundary (machine_mode mode, const_tree type)
  1178. {
  1179. return (type != NULL_TREE
  1180. ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
  1181. ? PARM_BOUNDARY
  1182. : TYPE_ALIGN (type))
  1183. : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
  1184. ? PARM_BOUNDARY
  1185. : GET_MODE_ALIGNMENT (mode)));
  1186. }
  1187. static int
  1188. iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
  1189. tree type ATTRIBUTE_UNUSED,
  1190. bool named ATTRIBUTE_UNUSED)
  1191. {
  1192. CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  1193. if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
  1194. {
  1195. if (TARGET_DEBUG_D_MODE)
  1196. fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
  1197. return UNITS_PER_WORD;
  1198. }
  1199. return 0;
  1200. }
  1201. /* Implement va_start. */
  1202. static void
  1203. iq2000_va_start (tree valist, rtx nextarg)
  1204. {
  1205. int int_arg_words;
  1206. /* Find out how many non-float named formals. */
  1207. int gpr_save_area_size;
  1208. /* Note UNITS_PER_WORD is 4 bytes. */
  1209. int_arg_words = crtl->args.info.arg_words;
  1210. if (int_arg_words < 8 )
  1211. /* Adjust for the prologue's economy measure. */
  1212. gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
  1213. else
  1214. gpr_save_area_size = 0;
  1215. /* Everything is in the GPR save area, or in the overflow
  1216. area which is contiguous with it. */
  1217. nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
  1218. std_expand_builtin_va_start (valist, nextarg);
  1219. }
  1220. /* Allocate a chunk of memory for per-function machine-dependent data. */
  1221. static struct machine_function *
  1222. iq2000_init_machine_status (void)
  1223. {
  1224. return ggc_cleared_alloc<machine_function> ();
  1225. }
  1226. /* Detect any conflicts in the switches. */
  1227. static void
  1228. iq2000_option_override (void)
  1229. {
  1230. target_flags &= ~MASK_GPOPT;
  1231. iq2000_isa = IQ2000_ISA_DEFAULT;
  1232. /* Identify the processor type. */
  1233. iq2000_print_operand_punct['?'] = 1;
  1234. iq2000_print_operand_punct['#'] = 1;
  1235. iq2000_print_operand_punct['&'] = 1;
  1236. iq2000_print_operand_punct['!'] = 1;
  1237. iq2000_print_operand_punct['*'] = 1;
  1238. iq2000_print_operand_punct['@'] = 1;
  1239. iq2000_print_operand_punct['.'] = 1;
  1240. iq2000_print_operand_punct['('] = 1;
  1241. iq2000_print_operand_punct[')'] = 1;
  1242. iq2000_print_operand_punct['['] = 1;
  1243. iq2000_print_operand_punct[']'] = 1;
  1244. iq2000_print_operand_punct['<'] = 1;
  1245. iq2000_print_operand_punct['>'] = 1;
  1246. iq2000_print_operand_punct['{'] = 1;
  1247. iq2000_print_operand_punct['}'] = 1;
  1248. iq2000_print_operand_punct['^'] = 1;
  1249. iq2000_print_operand_punct['$'] = 1;
  1250. iq2000_print_operand_punct['+'] = 1;
  1251. iq2000_print_operand_punct['~'] = 1;
  1252. /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
  1253. initialized yet, so we can't use that here. */
  1254. gpr_mode = SImode;
  1255. /* Function to allocate machine-dependent function status. */
  1256. init_machine_status = iq2000_init_machine_status;
  1257. }
  1258. /* The arg pointer (which is eliminated) points to the virtual frame pointer,
  1259. while the frame pointer (which may be eliminated) points to the stack
  1260. pointer after the initial adjustments. */
  1261. HOST_WIDE_INT
  1262. iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
  1263. {
  1264. rtx offset2 = const0_rtx;
  1265. rtx reg = eliminate_constant_term (addr, & offset2);
  1266. if (offset == 0)
  1267. offset = INTVAL (offset2);
  1268. if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
  1269. || reg == hard_frame_pointer_rtx)
  1270. {
  1271. HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
  1272. ? compute_frame_size (get_frame_size ())
  1273. : cfun->machine->total_size;
  1274. offset = offset - frame_size;
  1275. }
  1276. return offset;
  1277. }
  1278. /* If defined, a C statement to be executed just prior to the output of
  1279. assembler code for INSN, to modify the extracted operands so they will be
  1280. output differently.
  1281. Here the argument OPVEC is the vector containing the operands extracted
  1282. from INSN, and NOPERANDS is the number of elements of the vector which
  1283. contain meaningful data for this insn. The contents of this vector are
  1284. what will be used to convert the insn template into assembler code, so you
  1285. can change the assembler output by changing the contents of the vector.
  1286. We use it to check if the current insn needs a nop in front of it because
  1287. of load delays, and also to update the delay slot statistics. */
  1288. void
  1289. final_prescan_insn (rtx_insn *insn, rtx opvec[] ATTRIBUTE_UNUSED,
  1290. int noperands ATTRIBUTE_UNUSED)
  1291. {
  1292. if (dslots_number_nops > 0)
  1293. {
  1294. rtx pattern = PATTERN (insn);
  1295. int length = get_attr_length (insn);
  1296. /* Do we need to emit a NOP? */
  1297. if (length == 0
  1298. || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
  1299. || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
  1300. || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
  1301. || (iq2000_load_reg4 != 0
  1302. && reg_mentioned_p (iq2000_load_reg4, pattern)))
  1303. fputs ("\tnop\n", asm_out_file);
  1304. else
  1305. dslots_load_filled ++;
  1306. while (--dslots_number_nops > 0)
  1307. fputs ("\tnop\n", asm_out_file);
  1308. iq2000_load_reg = 0;
  1309. iq2000_load_reg2 = 0;
  1310. iq2000_load_reg3 = 0;
  1311. iq2000_load_reg4 = 0;
  1312. }
  1313. if ( (JUMP_P (insn)
  1314. || CALL_P (insn)
  1315. || (GET_CODE (PATTERN (insn)) == RETURN))
  1316. && NEXT_INSN (PREV_INSN (insn)) == insn)
  1317. {
  1318. rtx_insn *nop_insn = emit_insn_after (gen_nop (), insn);
  1319. INSN_ADDRESSES_NEW (nop_insn, -1);
  1320. }
  1321. if (TARGET_STATS
  1322. && (JUMP_P (insn) || CALL_P (insn)))
  1323. dslots_jump_total ++;
  1324. }
  1325. /* Return the bytes needed to compute the frame pointer from the current
  1326. stack pointer where SIZE is the # of var. bytes allocated.
  1327. IQ2000 stack frames look like:
  1328. Before call After call
  1329. +-----------------------+ +-----------------------+
  1330. high | | | |
  1331. mem. | | | |
  1332. | caller's temps. | | caller's temps. |
  1333. | | | |
  1334. +-----------------------+ +-----------------------+
  1335. | | | |
  1336. | arguments on stack. | | arguments on stack. |
  1337. | | | |
  1338. +-----------------------+ +-----------------------+
  1339. | 4 words to save | | 4 words to save |
  1340. | arguments passed | | arguments passed |
  1341. | in registers, even | | in registers, even |
  1342. SP->| if not passed. | VFP->| if not passed. |
  1343. +-----------------------+ +-----------------------+
  1344. | |
  1345. | fp register save |
  1346. | |
  1347. +-----------------------+
  1348. | |
  1349. | gp register save |
  1350. | |
  1351. +-----------------------+
  1352. | |
  1353. | local variables |
  1354. | |
  1355. +-----------------------+
  1356. | |
  1357. | alloca allocations |
  1358. | |
  1359. +-----------------------+
  1360. | |
  1361. | GP save for V.4 abi |
  1362. | |
  1363. +-----------------------+
  1364. | |
  1365. | arguments on stack |
  1366. | |
  1367. +-----------------------+
  1368. | 4 words to save |
  1369. | arguments passed |
  1370. | in registers, even |
  1371. low SP->| if not passed. |
  1372. memory +-----------------------+ */
  1373. HOST_WIDE_INT
  1374. compute_frame_size (HOST_WIDE_INT size)
  1375. {
  1376. int regno;
  1377. HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
  1378. HOST_WIDE_INT var_size; /* # bytes that variables take up. */
  1379. HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
  1380. HOST_WIDE_INT extra_size; /* # extra bytes. */
  1381. HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
  1382. HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
  1383. HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
  1384. long mask; /* mask of saved gp registers. */
  1385. gp_reg_size = 0;
  1386. fp_reg_size = 0;
  1387. mask = 0;
  1388. extra_size = IQ2000_STACK_ALIGN ((0));
  1389. var_size = IQ2000_STACK_ALIGN (size);
  1390. args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
  1391. /* If a function dynamically allocates the stack and
  1392. has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
  1393. if (args_size == 0 && cfun->calls_alloca)
  1394. args_size = 4 * UNITS_PER_WORD;
  1395. total_size = var_size + args_size + extra_size;
  1396. /* Calculate space needed for gp registers. */
  1397. for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
  1398. {
  1399. if (MUST_SAVE_REGISTER (regno))
  1400. {
  1401. gp_reg_size += GET_MODE_SIZE (gpr_mode);
  1402. mask |= 1L << (regno - GP_REG_FIRST);
  1403. }
  1404. }
  1405. /* We need to restore these for the handler. */
  1406. if (crtl->calls_eh_return)
  1407. {
  1408. unsigned int i;
  1409. for (i = 0; ; ++i)
  1410. {
  1411. regno = EH_RETURN_DATA_REGNO (i);
  1412. if (regno == (int) INVALID_REGNUM)
  1413. break;
  1414. gp_reg_size += GET_MODE_SIZE (gpr_mode);
  1415. mask |= 1L << (regno - GP_REG_FIRST);
  1416. }
  1417. }
  1418. gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
  1419. total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
  1420. /* The gp reg is caller saved, so there is no need for leaf routines
  1421. (total_size == extra_size) to save the gp reg. */
  1422. if (total_size == extra_size
  1423. && ! profile_flag)
  1424. total_size = extra_size = 0;
  1425. total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
  1426. /* Save other computed information. */
  1427. cfun->machine->total_size = total_size;
  1428. cfun->machine->var_size = var_size;
  1429. cfun->machine->args_size = args_size;
  1430. cfun->machine->extra_size = extra_size;
  1431. cfun->machine->gp_reg_size = gp_reg_size;
  1432. cfun->machine->fp_reg_size = fp_reg_size;
  1433. cfun->machine->mask = mask;
  1434. cfun->machine->initialized = reload_completed;
  1435. cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
  1436. if (mask)
  1437. {
  1438. unsigned long offset;
  1439. offset = (args_size + extra_size + var_size
  1440. + gp_reg_size - GET_MODE_SIZE (gpr_mode));
  1441. cfun->machine->gp_sp_offset = offset;
  1442. cfun->machine->gp_save_offset = offset - total_size;
  1443. }
  1444. else
  1445. {
  1446. cfun->machine->gp_sp_offset = 0;
  1447. cfun->machine->gp_save_offset = 0;
  1448. }
  1449. cfun->machine->fp_sp_offset = 0;
  1450. cfun->machine->fp_save_offset = 0;
  1451. /* Ok, we're done. */
  1452. return total_size;
  1453. }
  1454. /* We can always eliminate to the frame pointer. We can eliminate to the
  1455. stack pointer unless a frame pointer is needed. */
  1456. bool
  1457. iq2000_can_eliminate (const int from, const int to)
  1458. {
  1459. return (from == RETURN_ADDRESS_POINTER_REGNUM
  1460. && (! leaf_function_p ()
  1461. || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
  1462. || (from != RETURN_ADDRESS_POINTER_REGNUM
  1463. && (to == HARD_FRAME_POINTER_REGNUM
  1464. || (to == STACK_POINTER_REGNUM
  1465. && ! frame_pointer_needed)));
  1466. }
  1467. /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
  1468. pointer, argument pointer, or return address pointer. TO is either
  1469. the stack pointer or hard frame pointer. */
  1470. int
  1471. iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
  1472. {
  1473. int offset;
  1474. compute_frame_size (get_frame_size ());
  1475. if ((from) == FRAME_POINTER_REGNUM)
  1476. (offset) = 0;
  1477. else if ((from) == ARG_POINTER_REGNUM)
  1478. (offset) = (cfun->machine->total_size);
  1479. else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
  1480. {
  1481. if (leaf_function_p ())
  1482. (offset) = 0;
  1483. else (offset) = cfun->machine->gp_sp_offset
  1484. + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
  1485. * (BYTES_BIG_ENDIAN != 0));
  1486. }
  1487. else
  1488. gcc_unreachable ();
  1489. return offset;
  1490. }
  1491. /* Common code to emit the insns (or to write the instructions to a file)
  1492. to save/restore registers.
  1493. Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
  1494. is not modified within save_restore_insns. */
  1495. #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
  1496. /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
  1497. and return an rtl expression for the register. Write the assembly
  1498. instructions directly to FILE if it is not null, otherwise emit them as
  1499. rtl.
  1500. This function is a subroutine of save_restore_insns. It is used when
  1501. OFFSET is too large to add in a single instruction. */
  1502. static rtx
  1503. iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
  1504. {
  1505. rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
  1506. rtx offset_rtx = GEN_INT (offset);
  1507. emit_move_insn (reg, offset_rtx);
  1508. emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
  1509. return reg;
  1510. }
  1511. /* Make INSN frame related and note that it performs the frame-related
  1512. operation DWARF_PATTERN. */
  1513. static void
  1514. iq2000_annotate_frame_insn (rtx_insn *insn, rtx dwarf_pattern)
  1515. {
  1516. RTX_FRAME_RELATED_P (insn) = 1;
  1517. REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
  1518. dwarf_pattern,
  1519. REG_NOTES (insn));
  1520. }
  1521. /* Emit a move instruction that stores REG in MEM. Make the instruction
  1522. frame related and note that it stores REG at (SP + OFFSET). */
  1523. static void
  1524. iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
  1525. {
  1526. rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
  1527. rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
  1528. iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
  1529. gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
  1530. }
  1531. /* Emit instructions to save/restore registers, as determined by STORE_P. */
  1532. static void
  1533. save_restore_insns (int store_p)
  1534. {
  1535. long mask = cfun->machine->mask;
  1536. int regno;
  1537. rtx base_reg_rtx;
  1538. HOST_WIDE_INT base_offset;
  1539. HOST_WIDE_INT gp_offset;
  1540. HOST_WIDE_INT end_offset;
  1541. gcc_assert (!frame_pointer_needed
  1542. || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
  1543. if (mask == 0)
  1544. {
  1545. base_reg_rtx = 0, base_offset = 0;
  1546. return;
  1547. }
  1548. /* Save registers starting from high to low. The debuggers prefer at least
  1549. the return register be stored at func+4, and also it allows us not to
  1550. need a nop in the epilog if at least one register is reloaded in
  1551. addition to return address. */
  1552. /* Save GP registers if needed. */
  1553. /* Pick which pointer to use as a base register. For small frames, just
  1554. use the stack pointer. Otherwise, use a temporary register. Save 2
  1555. cycles if the save area is near the end of a large frame, by reusing
  1556. the constant created in the prologue/epilogue to adjust the stack
  1557. frame. */
  1558. gp_offset = cfun->machine->gp_sp_offset;
  1559. end_offset
  1560. = gp_offset - (cfun->machine->gp_reg_size
  1561. - GET_MODE_SIZE (gpr_mode));
  1562. if (gp_offset < 0 || end_offset < 0)
  1563. internal_error
  1564. ("gp_offset (%ld) or end_offset (%ld) is less than zero",
  1565. (long) gp_offset, (long) end_offset);
  1566. else if (gp_offset < 32768)
  1567. base_reg_rtx = stack_pointer_rtx, base_offset = 0;
  1568. else
  1569. {
  1570. int regno;
  1571. int reg_save_count = 0;
  1572. for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
  1573. if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
  1574. base_offset = gp_offset - ((reg_save_count - 1) * 4);
  1575. base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
  1576. }
  1577. for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
  1578. {
  1579. if (BITSET_P (mask, regno - GP_REG_FIRST))
  1580. {
  1581. rtx reg_rtx;
  1582. rtx mem_rtx
  1583. = gen_rtx_MEM (gpr_mode,
  1584. gen_rtx_PLUS (Pmode, base_reg_rtx,
  1585. GEN_INT (gp_offset - base_offset)));
  1586. reg_rtx = gen_rtx_REG (gpr_mode, regno);
  1587. if (store_p)
  1588. iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
  1589. else
  1590. {
  1591. emit_move_insn (reg_rtx, mem_rtx);
  1592. }
  1593. gp_offset -= GET_MODE_SIZE (gpr_mode);
  1594. }
  1595. }
  1596. }
  1597. /* Expand the prologue into a bunch of separate insns. */
  1598. void
  1599. iq2000_expand_prologue (void)
  1600. {
  1601. int regno;
  1602. HOST_WIDE_INT tsize;
  1603. int last_arg_is_vararg_marker = 0;
  1604. tree fndecl = current_function_decl;
  1605. tree fntype = TREE_TYPE (fndecl);
  1606. tree fnargs = DECL_ARGUMENTS (fndecl);
  1607. rtx next_arg_reg;
  1608. int i;
  1609. tree next_arg;
  1610. tree cur_arg;
  1611. CUMULATIVE_ARGS args_so_far_v;
  1612. cumulative_args_t args_so_far;
  1613. int store_args_on_stack = (iq2000_can_use_return_insn ());
  1614. /* If struct value address is treated as the first argument. */
  1615. if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
  1616. && !cfun->returns_pcc_struct
  1617. && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
  1618. {
  1619. tree type = build_pointer_type (fntype);
  1620. tree function_result_decl = build_decl (BUILTINS_LOCATION,
  1621. PARM_DECL, NULL_TREE, type);
  1622. DECL_ARG_TYPE (function_result_decl) = type;
  1623. DECL_CHAIN (function_result_decl) = fnargs;
  1624. fnargs = function_result_decl;
  1625. }
  1626. /* For arguments passed in registers, find the register number
  1627. of the first argument in the variable part of the argument list,
  1628. otherwise GP_ARG_LAST+1. Note also if the last argument is
  1629. the varargs special argument, and treat it as part of the
  1630. variable arguments.
  1631. This is only needed if store_args_on_stack is true. */
  1632. INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
  1633. args_so_far = pack_cumulative_args (&args_so_far_v);
  1634. regno = GP_ARG_FIRST;
  1635. for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
  1636. {
  1637. tree passed_type = DECL_ARG_TYPE (cur_arg);
  1638. machine_mode passed_mode = TYPE_MODE (passed_type);
  1639. rtx entry_parm;
  1640. if (TREE_ADDRESSABLE (passed_type))
  1641. {
  1642. passed_type = build_pointer_type (passed_type);
  1643. passed_mode = Pmode;
  1644. }
  1645. entry_parm = iq2000_function_arg (args_so_far, passed_mode,
  1646. passed_type, true);
  1647. iq2000_function_arg_advance (args_so_far, passed_mode,
  1648. passed_type, true);
  1649. next_arg = DECL_CHAIN (cur_arg);
  1650. if (entry_parm && store_args_on_stack)
  1651. {
  1652. if (next_arg == 0
  1653. && DECL_NAME (cur_arg)
  1654. && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
  1655. "__builtin_va_alist"))
  1656. || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
  1657. "va_alist"))))
  1658. {
  1659. last_arg_is_vararg_marker = 1;
  1660. break;
  1661. }
  1662. else
  1663. {
  1664. int words;
  1665. gcc_assert (GET_CODE (entry_parm) == REG);
  1666. /* Passed in a register, so will get homed automatically. */
  1667. if (GET_MODE (entry_parm) == BLKmode)
  1668. words = (int_size_in_bytes (passed_type) + 3) / 4;
  1669. else
  1670. words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
  1671. regno = REGNO (entry_parm) + words - 1;
  1672. }
  1673. }
  1674. else
  1675. {
  1676. regno = GP_ARG_LAST+1;
  1677. break;
  1678. }
  1679. }
  1680. /* In order to pass small structures by value in registers we need to
  1681. shift the value into the high part of the register.
  1682. iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
  1683. adjustments to be made as the next_arg_reg variable, so we split up
  1684. the insns, and emit them separately. */
  1685. next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
  1686. void_type_node, true);
  1687. if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
  1688. {
  1689. rtvec adjust = XVEC (next_arg_reg, 0);
  1690. int num = GET_NUM_ELEM (adjust);
  1691. for (i = 0; i < num; i++)
  1692. {
  1693. rtx pattern;
  1694. pattern = RTVEC_ELT (adjust, i);
  1695. if (GET_CODE (pattern) != SET
  1696. || GET_CODE (SET_SRC (pattern)) != ASHIFT)
  1697. abort_with_insn (pattern, "Insn is not a shift");
  1698. PUT_CODE (SET_SRC (pattern), ASHIFTRT);
  1699. emit_insn (pattern);
  1700. }
  1701. }
  1702. tsize = compute_frame_size (get_frame_size ());
  1703. /* If this function is a varargs function, store any registers that
  1704. would normally hold arguments ($4 - $7) on the stack. */
  1705. if (store_args_on_stack
  1706. && (stdarg_p (fntype)
  1707. || last_arg_is_vararg_marker))
  1708. {
  1709. int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
  1710. rtx ptr = stack_pointer_rtx;
  1711. for (; regno <= GP_ARG_LAST; regno++)
  1712. {
  1713. if (offset != 0)
  1714. ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
  1715. emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
  1716. gen_rtx_REG (gpr_mode, regno));
  1717. offset += GET_MODE_SIZE (gpr_mode);
  1718. }
  1719. }
  1720. if (tsize > 0)
  1721. {
  1722. rtx tsize_rtx = GEN_INT (tsize);
  1723. rtx adjustment_rtx, dwarf_pattern;
  1724. rtx_insn *insn;
  1725. if (tsize > 32767)
  1726. {
  1727. adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
  1728. emit_move_insn (adjustment_rtx, tsize_rtx);
  1729. }
  1730. else
  1731. adjustment_rtx = tsize_rtx;
  1732. insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
  1733. adjustment_rtx));
  1734. dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
  1735. plus_constant (Pmode, stack_pointer_rtx,
  1736. -tsize));
  1737. iq2000_annotate_frame_insn (insn, dwarf_pattern);
  1738. save_restore_insns (1);
  1739. if (frame_pointer_needed)
  1740. {
  1741. rtx_insn *insn = 0;
  1742. insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
  1743. stack_pointer_rtx));
  1744. if (insn)
  1745. RTX_FRAME_RELATED_P (insn) = 1;
  1746. }
  1747. }
  1748. emit_insn (gen_blockage ());
  1749. }
  1750. /* Expand the epilogue into a bunch of separate insns. */
  1751. void
  1752. iq2000_expand_epilogue (void)
  1753. {
  1754. HOST_WIDE_INT tsize = cfun->machine->total_size;
  1755. rtx tsize_rtx = GEN_INT (tsize);
  1756. rtx tmp_rtx = (rtx)0;
  1757. if (iq2000_can_use_return_insn ())
  1758. {
  1759. emit_jump_insn (gen_return ());
  1760. return;
  1761. }
  1762. if (tsize > 32767)
  1763. {
  1764. tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
  1765. emit_move_insn (tmp_rtx, tsize_rtx);
  1766. tsize_rtx = tmp_rtx;
  1767. }
  1768. if (tsize > 0)
  1769. {
  1770. if (frame_pointer_needed)
  1771. {
  1772. emit_insn (gen_blockage ());
  1773. emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
  1774. }
  1775. save_restore_insns (0);
  1776. if (crtl->calls_eh_return)
  1777. {
  1778. rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
  1779. emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
  1780. tsize_rtx = eh_ofs;
  1781. }
  1782. emit_insn (gen_blockage ());
  1783. if (tsize != 0 || crtl->calls_eh_return)
  1784. {
  1785. emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  1786. tsize_rtx));
  1787. }
  1788. }
  1789. if (crtl->calls_eh_return)
  1790. {
  1791. /* Perform the additional bump for __throw. */
  1792. emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
  1793. stack_pointer_rtx);
  1794. emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
  1795. emit_jump_insn (gen_eh_return_internal ());
  1796. }
  1797. else
  1798. emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
  1799. GP_REG_FIRST + 31)));
  1800. }
  1801. void
  1802. iq2000_expand_eh_return (rtx address)
  1803. {
  1804. HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
  1805. rtx scratch;
  1806. scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
  1807. emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
  1808. }
  1809. /* Return nonzero if this function is known to have a null epilogue.
  1810. This allows the optimizer to omit jumps to jumps if no stack
  1811. was created. */
  1812. int
  1813. iq2000_can_use_return_insn (void)
  1814. {
  1815. if (! reload_completed)
  1816. return 0;
  1817. if (df_regs_ever_live_p (31) || profile_flag)
  1818. return 0;
  1819. if (cfun->machine->initialized)
  1820. return cfun->machine->total_size == 0;
  1821. return compute_frame_size (get_frame_size ()) == 0;
  1822. }
  1823. /* Choose the section to use for the constant rtx expression X that has
  1824. mode MODE. */
  1825. static section *
  1826. iq2000_select_rtx_section (machine_mode mode, rtx x ATTRIBUTE_UNUSED,
  1827. unsigned HOST_WIDE_INT align)
  1828. {
  1829. /* For embedded applications, always put constants in read-only data,
  1830. in order to reduce RAM usage. */
  1831. return mergeable_constant_section (mode, align, 0);
  1832. }
  1833. /* Choose the section to use for DECL. RELOC is true if its value contains
  1834. any relocatable expression.
  1835. Some of the logic used here needs to be replicated in
  1836. ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
  1837. are done correctly. */
  1838. static section *
  1839. iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
  1840. unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
  1841. {
  1842. if (TARGET_EMBEDDED_DATA)
  1843. {
  1844. /* For embedded applications, always put an object in read-only data
  1845. if possible, in order to reduce RAM usage. */
  1846. if ((TREE_CODE (decl) == VAR_DECL
  1847. && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
  1848. && DECL_INITIAL (decl)
  1849. && (DECL_INITIAL (decl) == error_mark_node
  1850. || TREE_CONSTANT (DECL_INITIAL (decl))))
  1851. /* Deal with calls from output_constant_def_contents. */
  1852. || TREE_CODE (decl) != VAR_DECL)
  1853. return readonly_data_section;
  1854. else
  1855. return data_section;
  1856. }
  1857. else
  1858. {
  1859. /* For hosted applications, always put an object in small data if
  1860. possible, as this gives the best performance. */
  1861. if ((TREE_CODE (decl) == VAR_DECL
  1862. && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
  1863. && DECL_INITIAL (decl)
  1864. && (DECL_INITIAL (decl) == error_mark_node
  1865. || TREE_CONSTANT (DECL_INITIAL (decl))))
  1866. /* Deal with calls from output_constant_def_contents. */
  1867. || TREE_CODE (decl) != VAR_DECL)
  1868. return readonly_data_section;
  1869. else
  1870. return data_section;
  1871. }
  1872. }
  1873. /* Return register to use for a function return value with VALTYPE for function
  1874. FUNC. */
  1875. static rtx
  1876. iq2000_function_value (const_tree valtype,
  1877. const_tree fn_decl_or_type,
  1878. bool outgoing ATTRIBUTE_UNUSED)
  1879. {
  1880. int reg = GP_RETURN;
  1881. machine_mode mode = TYPE_MODE (valtype);
  1882. int unsignedp = TYPE_UNSIGNED (valtype);
  1883. const_tree func = fn_decl_or_type;
  1884. if (fn_decl_or_type
  1885. && !DECL_P (fn_decl_or_type))
  1886. fn_decl_or_type = NULL;
  1887. /* Since we promote return types, we must promote the mode here too. */
  1888. mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
  1889. return gen_rtx_REG (mode, reg);
  1890. }
  1891. /* Worker function for TARGET_LIBCALL_VALUE. */
  1892. static rtx
  1893. iq2000_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
  1894. {
  1895. return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
  1896. || GET_MODE_SIZE (mode) >= 4)
  1897. ? mode : SImode),
  1898. GP_RETURN);
  1899. }
  1900. /* Worker function for FUNCTION_VALUE_REGNO_P.
  1901. On the IQ2000, R2 and R3 are the only register thus used. */
  1902. bool
  1903. iq2000_function_value_regno_p (const unsigned int regno)
  1904. {
  1905. return (regno == GP_RETURN);
  1906. }
  1907. /* Return true when an argument must be passed by reference. */
  1908. static bool
  1909. iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
  1910. const_tree type, bool named ATTRIBUTE_UNUSED)
  1911. {
  1912. CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  1913. int size;
  1914. /* We must pass by reference if we would be both passing in registers
  1915. and the stack. This is because any subsequent partial arg would be
  1916. handled incorrectly in this case. */
  1917. if (cum && targetm.calls.must_pass_in_stack (mode, type))
  1918. {
  1919. /* Don't pass the actual CUM to FUNCTION_ARG, because we would
  1920. get double copies of any offsets generated for small structs
  1921. passed in registers. */
  1922. CUMULATIVE_ARGS temp;
  1923. temp = *cum;
  1924. if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
  1925. != 0)
  1926. return 1;
  1927. }
  1928. if (type == NULL_TREE || mode == DImode || mode == DFmode)
  1929. return 0;
  1930. size = int_size_in_bytes (type);
  1931. return size == -1 || size > UNITS_PER_WORD;
  1932. }
  1933. /* Return the length of INSN. LENGTH is the initial length computed by
  1934. attributes in the machine-description file. */
  1935. int
  1936. iq2000_adjust_insn_length (rtx_insn *insn, int length)
  1937. {
  1938. /* A unconditional jump has an unfilled delay slot if it is not part
  1939. of a sequence. A conditional jump normally has a delay slot. */
  1940. if (simplejump_p (insn)
  1941. || ( (JUMP_P (insn)
  1942. || CALL_P (insn))))
  1943. length += 4;
  1944. return length;
  1945. }
  1946. /* Output assembly instructions to perform a conditional branch.
  1947. INSN is the branch instruction. OPERANDS[0] is the condition.
  1948. OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
  1949. of the first operand to the condition. If TWO_OPERANDS_P is
  1950. nonzero the comparison takes two operands; OPERANDS[3] will be the
  1951. second operand.
  1952. If INVERTED_P is nonzero we are to branch if the condition does
  1953. not hold. If FLOAT_P is nonzero this is a floating-point comparison.
  1954. LENGTH is the length (in bytes) of the sequence we are to generate.
  1955. That tells us whether to generate a simple conditional branch, or a
  1956. reversed conditional branch around a `jr' instruction. */
  1957. char *
  1958. iq2000_output_conditional_branch (rtx_insn *insn, rtx * operands,
  1959. int two_operands_p, int float_p,
  1960. int inverted_p, int length)
  1961. {
  1962. static char buffer[200];
  1963. /* The kind of comparison we are doing. */
  1964. enum rtx_code code = GET_CODE (operands[0]);
  1965. /* Nonzero if the opcode for the comparison needs a `z' indicating
  1966. that it is a comparison against zero. */
  1967. int need_z_p;
  1968. /* A string to use in the assembly output to represent the first
  1969. operand. */
  1970. const char *op1 = "%z2";
  1971. /* A string to use in the assembly output to represent the second
  1972. operand. Use the hard-wired zero register if there's no second
  1973. operand. */
  1974. const char *op2 = (two_operands_p ? ",%z3" : ",%.");
  1975. /* The operand-printing string for the comparison. */
  1976. const char *comp = (float_p ? "%F0" : "%C0");
  1977. /* The operand-printing string for the inverted comparison. */
  1978. const char *inverted_comp = (float_p ? "%W0" : "%N0");
  1979. /* Likely variants of each branch instruction annul the instruction
  1980. in the delay slot if the branch is not taken. */
  1981. iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
  1982. if (!two_operands_p)
  1983. {
  1984. /* To compute whether than A > B, for example, we normally
  1985. subtract B from A and then look at the sign bit. But, if we
  1986. are doing an unsigned comparison, and B is zero, we don't
  1987. have to do the subtraction. Instead, we can just check to
  1988. see if A is nonzero. Thus, we change the CODE here to
  1989. reflect the simpler comparison operation. */
  1990. switch (code)
  1991. {
  1992. case GTU:
  1993. code = NE;
  1994. break;
  1995. case LEU:
  1996. code = EQ;
  1997. break;
  1998. case GEU:
  1999. /* A condition which will always be true. */
  2000. code = EQ;
  2001. op1 = "%.";
  2002. break;
  2003. case LTU:
  2004. /* A condition which will always be false. */
  2005. code = NE;
  2006. op1 = "%.";
  2007. break;
  2008. default:
  2009. /* Not a special case. */
  2010. break;
  2011. }
  2012. }
  2013. /* Relative comparisons are always done against zero. But
  2014. equality comparisons are done between two operands, and therefore
  2015. do not require a `z' in the assembly language output. */
  2016. need_z_p = (!float_p && code != EQ && code != NE);
  2017. /* For comparisons against zero, the zero is not provided
  2018. explicitly. */
  2019. if (need_z_p)
  2020. op2 = "";
  2021. /* Begin by terminating the buffer. That way we can always use
  2022. strcat to add to it. */
  2023. buffer[0] = '\0';
  2024. switch (length)
  2025. {
  2026. case 4:
  2027. case 8:
  2028. /* Just a simple conditional branch. */
  2029. if (float_p)
  2030. sprintf (buffer, "b%s%%?\t%%Z2%%1",
  2031. inverted_p ? inverted_comp : comp);
  2032. else
  2033. sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
  2034. inverted_p ? inverted_comp : comp,
  2035. need_z_p ? "z" : "",
  2036. op1,
  2037. op2);
  2038. return buffer;
  2039. case 12:
  2040. case 16:
  2041. {
  2042. /* Generate a reversed conditional branch around ` j'
  2043. instruction:
  2044. .set noreorder
  2045. .set nomacro
  2046. bc l
  2047. nop
  2048. j target
  2049. .set macro
  2050. .set reorder
  2051. l:
  2052. Because we have to jump four bytes *past* the following
  2053. instruction if this branch was annulled, we can't just use
  2054. a label, as in the picture above; there's no way to put the
  2055. label after the next instruction, as the assembler does not
  2056. accept `.L+4' as the target of a branch. (We can't just
  2057. wait until the next instruction is output; it might be a
  2058. macro and take up more than four bytes. Once again, we see
  2059. why we want to eliminate macros.)
  2060. If the branch is annulled, we jump four more bytes that we
  2061. would otherwise; that way we skip the annulled instruction
  2062. in the delay slot. */
  2063. const char *target
  2064. = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
  2065. char *c;
  2066. c = strchr (buffer, '\0');
  2067. /* Generate the reversed comparison. This takes four
  2068. bytes. */
  2069. if (float_p)
  2070. sprintf (c, "b%s\t%%Z2%s",
  2071. inverted_p ? comp : inverted_comp,
  2072. target);
  2073. else
  2074. sprintf (c, "b%s%s\t%s%s,%s",
  2075. inverted_p ? comp : inverted_comp,
  2076. need_z_p ? "z" : "",
  2077. op1,
  2078. op2,
  2079. target);
  2080. strcat (c, "\n\tnop\n\tj\t%1");
  2081. if (length == 16)
  2082. /* The delay slot was unfilled. Since we're inside
  2083. .noreorder, the assembler will not fill in the NOP for
  2084. us, so we must do it ourselves. */
  2085. strcat (buffer, "\n\tnop");
  2086. return buffer;
  2087. }
  2088. default:
  2089. gcc_unreachable ();
  2090. }
  2091. /* NOTREACHED */
  2092. return 0;
  2093. }
  2094. #define def_builtin(NAME, TYPE, CODE) \
  2095. add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
  2096. NULL, NULL_TREE)
  2097. static void
  2098. iq2000_init_builtins (void)
  2099. {
  2100. tree void_ftype, void_ftype_int, void_ftype_int_int;
  2101. tree void_ftype_int_int_int;
  2102. tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
  2103. tree int_ftype_int_int_int_int;
  2104. /* func () */
  2105. void_ftype
  2106. = build_function_type_list (void_type_node, NULL_TREE);
  2107. /* func (int) */
  2108. void_ftype_int
  2109. = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
  2110. /* void func (int, int) */
  2111. void_ftype_int_int
  2112. = build_function_type_list (void_type_node,
  2113. integer_type_node,
  2114. integer_type_node,
  2115. NULL_TREE);
  2116. /* int func (int) */
  2117. int_ftype_int
  2118. = build_function_type_list (integer_type_node,
  2119. integer_type_node, NULL_TREE);
  2120. /* int func (int, int) */
  2121. int_ftype_int_int
  2122. = build_function_type_list (integer_type_node,
  2123. integer_type_node,
  2124. integer_type_node,
  2125. NULL_TREE);
  2126. /* void func (int, int, int) */
  2127. void_ftype_int_int_int
  2128. = build_function_type_list (void_type_node,
  2129. integer_type_node,
  2130. integer_type_node,
  2131. integer_type_node,
  2132. NULL_TREE);
  2133. /* int func (int, int, int) */
  2134. int_ftype_int_int_int
  2135. = build_function_type_list (integer_type_node,
  2136. integer_type_node,
  2137. integer_type_node,
  2138. integer_type_node,
  2139. NULL_TREE);
  2140. /* int func (int, int, int, int) */
  2141. int_ftype_int_int_int_int
  2142. = build_function_type_list (integer_type_node,
  2143. integer_type_node,
  2144. integer_type_node,
  2145. integer_type_node,
  2146. integer_type_node,
  2147. NULL_TREE);
  2148. def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
  2149. def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
  2150. def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
  2151. def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
  2152. def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
  2153. def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
  2154. def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
  2155. def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
  2156. def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
  2157. def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
  2158. def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
  2159. def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
  2160. def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
  2161. def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
  2162. def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
  2163. def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
  2164. def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
  2165. def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
  2166. def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
  2167. def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
  2168. def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
  2169. def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
  2170. def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
  2171. def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
  2172. def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
  2173. def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
  2174. def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
  2175. def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
  2176. def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
  2177. def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
  2178. def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
  2179. def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
  2180. def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
  2181. def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
  2182. def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
  2183. def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
  2184. def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
  2185. def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
  2186. def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
  2187. def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
  2188. def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
  2189. def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
  2190. def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
  2191. def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
  2192. def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
  2193. def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
  2194. }
  2195. /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
  2196. has an rtx CODE. */
  2197. static rtx
  2198. expand_one_builtin (enum insn_code icode, rtx target, tree exp,
  2199. enum rtx_code *code, int argcount)
  2200. {
  2201. rtx pat;
  2202. tree arg [5];
  2203. rtx op [5];
  2204. machine_mode mode [5];
  2205. int i;
  2206. mode[0] = insn_data[icode].operand[0].mode;
  2207. for (i = 0; i < argcount; i++)
  2208. {
  2209. arg[i] = CALL_EXPR_ARG (exp, i);
  2210. op[i] = expand_normal (arg[i]);
  2211. mode[i] = insn_data[icode].operand[i].mode;
  2212. if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
  2213. error ("argument %qd is not a constant", i + 1);
  2214. if (code[i] == REG
  2215. && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
  2216. op[i] = copy_to_mode_reg (mode[i], op[i]);
  2217. }
  2218. if (insn_data[icode].operand[0].constraint[0] == '=')
  2219. {
  2220. if (target == 0
  2221. || GET_MODE (target) != mode[0]
  2222. || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
  2223. target = gen_reg_rtx (mode[0]);
  2224. }
  2225. else
  2226. target = 0;
  2227. switch (argcount)
  2228. {
  2229. case 0:
  2230. pat = GEN_FCN (icode) (target);
  2231. case 1:
  2232. if (target)
  2233. pat = GEN_FCN (icode) (target, op[0]);
  2234. else
  2235. pat = GEN_FCN (icode) (op[0]);
  2236. break;
  2237. case 2:
  2238. if (target)
  2239. pat = GEN_FCN (icode) (target, op[0], op[1]);
  2240. else
  2241. pat = GEN_FCN (icode) (op[0], op[1]);
  2242. break;
  2243. case 3:
  2244. if (target)
  2245. pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
  2246. else
  2247. pat = GEN_FCN (icode) (op[0], op[1], op[2]);
  2248. break;
  2249. case 4:
  2250. if (target)
  2251. pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
  2252. else
  2253. pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
  2254. break;
  2255. default:
  2256. gcc_unreachable ();
  2257. }
  2258. if (! pat)
  2259. return 0;
  2260. emit_insn (pat);
  2261. return target;
  2262. }
  2263. /* Expand an expression EXP that calls a built-in function,
  2264. with result going to TARGET if that's convenient
  2265. (and in mode MODE if that's convenient).
  2266. SUBTARGET may be used as the target for computing one of EXP's operands.
  2267. IGNORE is nonzero if the value is to be ignored. */
  2268. static rtx
  2269. iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
  2270. machine_mode mode ATTRIBUTE_UNUSED,
  2271. int ignore ATTRIBUTE_UNUSED)
  2272. {
  2273. tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
  2274. int fcode = DECL_FUNCTION_CODE (fndecl);
  2275. enum rtx_code code [5];
  2276. code[0] = REG;
  2277. code[1] = REG;
  2278. code[2] = REG;
  2279. code[3] = REG;
  2280. code[4] = REG;
  2281. switch (fcode)
  2282. {
  2283. default:
  2284. break;
  2285. case IQ2000_BUILTIN_ADO16:
  2286. return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
  2287. case IQ2000_BUILTIN_RAM:
  2288. code[1] = CONST_INT;
  2289. code[2] = CONST_INT;
  2290. code[3] = CONST_INT;
  2291. return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
  2292. case IQ2000_BUILTIN_CHKHDR:
  2293. return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
  2294. case IQ2000_BUILTIN_PKRL:
  2295. return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
  2296. case IQ2000_BUILTIN_CFC0:
  2297. code[0] = CONST_INT;
  2298. return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
  2299. case IQ2000_BUILTIN_CFC1:
  2300. code[0] = CONST_INT;
  2301. return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
  2302. case IQ2000_BUILTIN_CFC2:
  2303. code[0] = CONST_INT;
  2304. return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
  2305. case IQ2000_BUILTIN_CFC3:
  2306. code[0] = CONST_INT;
  2307. return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
  2308. case IQ2000_BUILTIN_CTC0:
  2309. code[1] = CONST_INT;
  2310. return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
  2311. case IQ2000_BUILTIN_CTC1:
  2312. code[1] = CONST_INT;
  2313. return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
  2314. case IQ2000_BUILTIN_CTC2:
  2315. code[1] = CONST_INT;
  2316. return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
  2317. case IQ2000_BUILTIN_CTC3:
  2318. code[1] = CONST_INT;
  2319. return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
  2320. case IQ2000_BUILTIN_MFC0:
  2321. code[0] = CONST_INT;
  2322. return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
  2323. case IQ2000_BUILTIN_MFC1:
  2324. code[0] = CONST_INT;
  2325. return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
  2326. case IQ2000_BUILTIN_MFC2:
  2327. code[0] = CONST_INT;
  2328. return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
  2329. case IQ2000_BUILTIN_MFC3:
  2330. code[0] = CONST_INT;
  2331. return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
  2332. case IQ2000_BUILTIN_MTC0:
  2333. code[1] = CONST_INT;
  2334. return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
  2335. case IQ2000_BUILTIN_MTC1:
  2336. code[1] = CONST_INT;
  2337. return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
  2338. case IQ2000_BUILTIN_MTC2:
  2339. code[1] = CONST_INT;
  2340. return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
  2341. case IQ2000_BUILTIN_MTC3:
  2342. code[1] = CONST_INT;
  2343. return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
  2344. case IQ2000_BUILTIN_LUR:
  2345. return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
  2346. case IQ2000_BUILTIN_RB:
  2347. return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
  2348. case IQ2000_BUILTIN_RX:
  2349. return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
  2350. case IQ2000_BUILTIN_SRRD:
  2351. return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
  2352. case IQ2000_BUILTIN_SRWR:
  2353. return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
  2354. case IQ2000_BUILTIN_WB:
  2355. return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
  2356. case IQ2000_BUILTIN_WX:
  2357. return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
  2358. case IQ2000_BUILTIN_LUC32L:
  2359. return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
  2360. case IQ2000_BUILTIN_LUC64:
  2361. return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
  2362. case IQ2000_BUILTIN_LUC64L:
  2363. return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
  2364. case IQ2000_BUILTIN_LUK:
  2365. return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
  2366. case IQ2000_BUILTIN_LULCK:
  2367. return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
  2368. case IQ2000_BUILTIN_LUM32:
  2369. return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
  2370. case IQ2000_BUILTIN_LUM32L:
  2371. return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
  2372. case IQ2000_BUILTIN_LUM64:
  2373. return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
  2374. case IQ2000_BUILTIN_LUM64L:
  2375. return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
  2376. case IQ2000_BUILTIN_LURL:
  2377. return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
  2378. case IQ2000_BUILTIN_MRGB:
  2379. code[2] = CONST_INT;
  2380. return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
  2381. case IQ2000_BUILTIN_SRRDL:
  2382. return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
  2383. case IQ2000_BUILTIN_SRULCK:
  2384. return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
  2385. case IQ2000_BUILTIN_SRWRU:
  2386. return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
  2387. case IQ2000_BUILTIN_TRAPQFL:
  2388. return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
  2389. case IQ2000_BUILTIN_TRAPQNE:
  2390. return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
  2391. case IQ2000_BUILTIN_TRAPREL:
  2392. return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
  2393. case IQ2000_BUILTIN_WBU:
  2394. return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
  2395. case IQ2000_BUILTIN_SYSCALL:
  2396. return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
  2397. }
  2398. return NULL_RTX;
  2399. }
  2400. /* Worker function for TARGET_RETURN_IN_MEMORY. */
  2401. static bool
  2402. iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
  2403. {
  2404. return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
  2405. || (int_size_in_bytes (type) == -1));
  2406. }
  2407. /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
  2408. static void
  2409. iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
  2410. machine_mode mode ATTRIBUTE_UNUSED,
  2411. tree type ATTRIBUTE_UNUSED, int * pretend_size,
  2412. int no_rtl)
  2413. {
  2414. CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  2415. unsigned int iq2000_off = ! cum->last_arg_fp;
  2416. unsigned int iq2000_fp_off = cum->last_arg_fp;
  2417. if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
  2418. {
  2419. int iq2000_save_gp_regs
  2420. = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
  2421. int iq2000_save_fp_regs
  2422. = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
  2423. if (iq2000_save_gp_regs < 0)
  2424. iq2000_save_gp_regs = 0;
  2425. if (iq2000_save_fp_regs < 0)
  2426. iq2000_save_fp_regs = 0;
  2427. *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
  2428. + (iq2000_save_fp_regs * UNITS_PER_FPREG));
  2429. if (! (no_rtl))
  2430. {
  2431. if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
  2432. {
  2433. rtx ptr, mem;
  2434. ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
  2435. - (iq2000_save_gp_regs
  2436. * UNITS_PER_WORD));
  2437. mem = gen_rtx_MEM (BLKmode, ptr);
  2438. move_block_from_reg
  2439. (cum->arg_words + GP_ARG_FIRST + iq2000_off,
  2440. mem,
  2441. iq2000_save_gp_regs);
  2442. }
  2443. }
  2444. }
  2445. }
  2446. /* A C compound statement to output to stdio stream STREAM the
  2447. assembler syntax for an instruction operand that is a memory
  2448. reference whose address is ADDR. ADDR is an RTL expression. */
  2449. static void
  2450. iq2000_print_operand_address (FILE * file, rtx addr)
  2451. {
  2452. if (!addr)
  2453. error ("PRINT_OPERAND_ADDRESS, null pointer");
  2454. else
  2455. switch (GET_CODE (addr))
  2456. {
  2457. case REG:
  2458. if (REGNO (addr) == ARG_POINTER_REGNUM)
  2459. abort_with_insn (addr, "Arg pointer not eliminated.");
  2460. fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
  2461. break;
  2462. case LO_SUM:
  2463. {
  2464. rtx arg0 = XEXP (addr, 0);
  2465. rtx arg1 = XEXP (addr, 1);
  2466. if (GET_CODE (arg0) != REG)
  2467. abort_with_insn (addr,
  2468. "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
  2469. fprintf (file, "%%lo(");
  2470. iq2000_print_operand_address (file, arg1);
  2471. fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
  2472. }
  2473. break;
  2474. case PLUS:
  2475. {
  2476. rtx reg = 0;
  2477. rtx offset = 0;
  2478. rtx arg0 = XEXP (addr, 0);
  2479. rtx arg1 = XEXP (addr, 1);
  2480. if (GET_CODE (arg0) == REG)
  2481. {
  2482. reg = arg0;
  2483. offset = arg1;
  2484. if (GET_CODE (offset) == REG)
  2485. abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
  2486. }
  2487. else if (GET_CODE (arg1) == REG)
  2488. reg = arg1, offset = arg0;
  2489. else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
  2490. {
  2491. output_addr_const (file, addr);
  2492. break;
  2493. }
  2494. else
  2495. abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
  2496. if (! CONSTANT_P (offset))
  2497. abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
  2498. if (REGNO (reg) == ARG_POINTER_REGNUM)
  2499. abort_with_insn (addr, "Arg pointer not eliminated.");
  2500. output_addr_const (file, offset);
  2501. fprintf (file, "(%s)", reg_names [REGNO (reg)]);
  2502. }
  2503. break;
  2504. case LABEL_REF:
  2505. case SYMBOL_REF:
  2506. case CONST_INT:
  2507. case CONST:
  2508. output_addr_const (file, addr);
  2509. if (GET_CODE (addr) == CONST_INT)
  2510. fprintf (file, "(%s)", reg_names [0]);
  2511. break;
  2512. default:
  2513. abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
  2514. break;
  2515. }
  2516. }
  2517. /* A C compound statement to output to stdio stream FILE the
  2518. assembler syntax for an instruction operand OP.
  2519. LETTER is a value that can be used to specify one of several ways
  2520. of printing the operand. It is used when identical operands
  2521. must be printed differently depending on the context. LETTER
  2522. comes from the `%' specification that was used to request
  2523. printing of the operand. If the specification was just `%DIGIT'
  2524. then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
  2525. is the ASCII code for LTR.
  2526. If OP is a register, this macro should print the register's name.
  2527. The names can be found in an array `reg_names' whose type is
  2528. `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
  2529. When the machine description has a specification `%PUNCT' (a `%'
  2530. followed by a punctuation character), this macro is called with
  2531. a null pointer for X and the punctuation character for LETTER.
  2532. The IQ2000 specific codes are:
  2533. 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
  2534. 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
  2535. 'd' output integer constant in decimal,
  2536. 'z' if the operand is 0, use $0 instead of normal operand.
  2537. 'D' print second part of double-word register or memory operand.
  2538. 'L' print low-order register of double-word register operand.
  2539. 'M' print high-order register of double-word register operand.
  2540. 'C' print part of opcode for a branch condition.
  2541. 'F' print part of opcode for a floating-point branch condition.
  2542. 'N' print part of opcode for a branch condition, inverted.
  2543. 'W' print part of opcode for a floating-point branch condition, inverted.
  2544. 'A' Print part of opcode for a bit test condition.
  2545. 'P' Print label for a bit test.
  2546. 'p' Print log for a bit test.
  2547. 'B' print 'z' for EQ, 'n' for NE
  2548. 'b' print 'n' for EQ, 'z' for NE
  2549. 'T' print 'f' for EQ, 't' for NE
  2550. 't' print 't' for EQ, 'f' for NE
  2551. 'Z' print register and a comma, but print nothing for $fcc0
  2552. '?' Print 'l' if we are to use a branch likely instead of normal branch.
  2553. '@' Print the name of the assembler temporary register (at or $1).
  2554. '.' Print the name of the register with a hard-wired zero (zero or $0).
  2555. '$' Print the name of the stack pointer register (sp or $29).
  2556. '+' Print the name of the gp register (gp or $28). */
  2557. static void
  2558. iq2000_print_operand (FILE *file, rtx op, int letter)
  2559. {
  2560. enum rtx_code code;
  2561. if (iq2000_print_operand_punct_valid_p (letter))
  2562. {
  2563. switch (letter)
  2564. {
  2565. case '?':
  2566. if (iq2000_branch_likely)
  2567. putc ('l', file);
  2568. break;
  2569. case '@':
  2570. fputs (reg_names [GP_REG_FIRST + 1], file);
  2571. break;
  2572. case '.':
  2573. fputs (reg_names [GP_REG_FIRST + 0], file);
  2574. break;
  2575. case '$':
  2576. fputs (reg_names[STACK_POINTER_REGNUM], file);
  2577. break;
  2578. case '+':
  2579. fputs (reg_names[GP_REG_FIRST + 28], file);
  2580. break;
  2581. default:
  2582. error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
  2583. break;
  2584. }
  2585. return;
  2586. }
  2587. if (! op)
  2588. {
  2589. error ("PRINT_OPERAND null pointer");
  2590. return;
  2591. }
  2592. code = GET_CODE (op);
  2593. if (code == SIGN_EXTEND)
  2594. op = XEXP (op, 0), code = GET_CODE (op);
  2595. if (letter == 'C')
  2596. switch (code)
  2597. {
  2598. case EQ: fputs ("eq", file); break;
  2599. case NE: fputs ("ne", file); break;
  2600. case GT: fputs ("gt", file); break;
  2601. case GE: fputs ("ge", file); break;
  2602. case LT: fputs ("lt", file); break;
  2603. case LE: fputs ("le", file); break;
  2604. case GTU: fputs ("ne", file); break;
  2605. case GEU: fputs ("geu", file); break;
  2606. case LTU: fputs ("ltu", file); break;
  2607. case LEU: fputs ("eq", file); break;
  2608. default:
  2609. abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
  2610. }
  2611. else if (letter == 'N')
  2612. switch (code)
  2613. {
  2614. case EQ: fputs ("ne", file); break;
  2615. case NE: fputs ("eq", file); break;
  2616. case GT: fputs ("le", file); break;
  2617. case GE: fputs ("lt", file); break;
  2618. case LT: fputs ("ge", file); break;
  2619. case LE: fputs ("gt", file); break;
  2620. case GTU: fputs ("leu", file); break;
  2621. case GEU: fputs ("ltu", file); break;
  2622. case LTU: fputs ("geu", file); break;
  2623. case LEU: fputs ("gtu", file); break;
  2624. default:
  2625. abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
  2626. }
  2627. else if (letter == 'F')
  2628. switch (code)
  2629. {
  2630. case EQ: fputs ("c1f", file); break;
  2631. case NE: fputs ("c1t", file); break;
  2632. default:
  2633. abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
  2634. }
  2635. else if (letter == 'W')
  2636. switch (code)
  2637. {
  2638. case EQ: fputs ("c1t", file); break;
  2639. case NE: fputs ("c1f", file); break;
  2640. default:
  2641. abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
  2642. }
  2643. else if (letter == 'A')
  2644. fputs (code == LABEL_REF ? "i" : "in", file);
  2645. else if (letter == 'P')
  2646. {
  2647. if (code == LABEL_REF)
  2648. output_addr_const (file, op);
  2649. else if (code != PC)
  2650. output_operand_lossage ("invalid %%P operand");
  2651. }
  2652. else if (letter == 'p')
  2653. {
  2654. int value;
  2655. if (code != CONST_INT
  2656. || (value = exact_log2 (INTVAL (op))) < 0)
  2657. output_operand_lossage ("invalid %%p value");
  2658. else
  2659. fprintf (file, "%d", value);
  2660. }
  2661. else if (letter == 'Z')
  2662. {
  2663. gcc_unreachable ();
  2664. }
  2665. else if (code == REG || code == SUBREG)
  2666. {
  2667. int regnum;
  2668. if (code == REG)
  2669. regnum = REGNO (op);
  2670. else
  2671. regnum = true_regnum (op);
  2672. if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
  2673. || (letter == 'L' && WORDS_BIG_ENDIAN)
  2674. || letter == 'D')
  2675. regnum++;
  2676. fprintf (file, "%s", reg_names[regnum]);
  2677. }
  2678. else if (code == MEM)
  2679. {
  2680. if (letter == 'D')
  2681. output_address (plus_constant (Pmode, XEXP (op, 0), 4));
  2682. else
  2683. output_address (XEXP (op, 0));
  2684. }
  2685. else if (code == CONST_DOUBLE
  2686. && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
  2687. {
  2688. char s[60];
  2689. real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
  2690. fputs (s, file);
  2691. }
  2692. else if (letter == 'x' && GET_CODE (op) == CONST_INT)
  2693. fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
  2694. else if (letter == 'X' && GET_CODE(op) == CONST_INT)
  2695. fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
  2696. else if (letter == 'd' && GET_CODE(op) == CONST_INT)
  2697. fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
  2698. else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
  2699. fputs (reg_names[GP_REG_FIRST], file);
  2700. else if (letter == 'd' || letter == 'x' || letter == 'X')
  2701. output_operand_lossage ("invalid use of %%d, %%x, or %%X");
  2702. else if (letter == 'B')
  2703. fputs (code == EQ ? "z" : "n", file);
  2704. else if (letter == 'b')
  2705. fputs (code == EQ ? "n" : "z", file);
  2706. else if (letter == 'T')
  2707. fputs (code == EQ ? "f" : "t", file);
  2708. else if (letter == 't')
  2709. fputs (code == EQ ? "t" : "f", file);
  2710. else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
  2711. {
  2712. iq2000_print_operand (file, XEXP (op, 0), letter);
  2713. }
  2714. else
  2715. output_addr_const (file, op);
  2716. }
  2717. static bool
  2718. iq2000_print_operand_punct_valid_p (unsigned char code)
  2719. {
  2720. return iq2000_print_operand_punct[code];
  2721. }
  2722. /* For the IQ2000, transform:
  2723. memory(X + <large int>)
  2724. into:
  2725. Y = <large int> & ~0x7fff;
  2726. Z = X + Y
  2727. memory (Z + (<large int> & 0x7fff));
  2728. */
  2729. rtx
  2730. iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
  2731. machine_mode mode)
  2732. {
  2733. if (TARGET_DEBUG_B_MODE)
  2734. {
  2735. GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
  2736. GO_DEBUG_RTX (xinsn);
  2737. }
  2738. if (iq2000_check_split (xinsn, mode))
  2739. {
  2740. return gen_rtx_LO_SUM (Pmode,
  2741. copy_to_mode_reg (Pmode,
  2742. gen_rtx_HIGH (Pmode, xinsn)),
  2743. xinsn);
  2744. }
  2745. if (GET_CODE (xinsn) == PLUS)
  2746. {
  2747. rtx xplus0 = XEXP (xinsn, 0);
  2748. rtx xplus1 = XEXP (xinsn, 1);
  2749. enum rtx_code code0 = GET_CODE (xplus0);
  2750. enum rtx_code code1 = GET_CODE (xplus1);
  2751. if (code0 != REG && code1 == REG)
  2752. {
  2753. xplus0 = XEXP (xinsn, 1);
  2754. xplus1 = XEXP (xinsn, 0);
  2755. code0 = GET_CODE (xplus0);
  2756. code1 = GET_CODE (xplus1);
  2757. }
  2758. if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
  2759. && code1 == CONST_INT && !SMALL_INT (xplus1))
  2760. {
  2761. rtx int_reg = gen_reg_rtx (Pmode);
  2762. rtx ptr_reg = gen_reg_rtx (Pmode);
  2763. emit_move_insn (int_reg,
  2764. GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
  2765. emit_insn (gen_rtx_SET (VOIDmode,
  2766. ptr_reg,
  2767. gen_rtx_PLUS (Pmode, xplus0, int_reg)));
  2768. return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff);
  2769. }
  2770. }
  2771. if (TARGET_DEBUG_B_MODE)
  2772. GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
  2773. return xinsn;
  2774. }
  2775. static bool
  2776. iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
  2777. int opno ATTRIBUTE_UNUSED, int * total,
  2778. bool speed ATTRIBUTE_UNUSED)
  2779. {
  2780. machine_mode mode = GET_MODE (x);
  2781. switch (code)
  2782. {
  2783. case MEM:
  2784. {
  2785. int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
  2786. if (simple_memory_operand (x, mode))
  2787. return COSTS_N_INSNS (num_words);
  2788. * total = COSTS_N_INSNS (2 * num_words);
  2789. break;
  2790. }
  2791. case FFS:
  2792. * total = COSTS_N_INSNS (6);
  2793. break;
  2794. case AND:
  2795. case IOR:
  2796. case XOR:
  2797. case NOT:
  2798. * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
  2799. break;
  2800. case ASHIFT:
  2801. case ASHIFTRT:
  2802. case LSHIFTRT:
  2803. if (mode == DImode)
  2804. * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
  2805. else
  2806. * total = COSTS_N_INSNS (1);
  2807. break;
  2808. case ABS:
  2809. if (mode == SFmode || mode == DFmode)
  2810. * total = COSTS_N_INSNS (1);
  2811. else
  2812. * total = COSTS_N_INSNS (4);
  2813. break;
  2814. case PLUS:
  2815. case MINUS:
  2816. if (mode == SFmode || mode == DFmode)
  2817. * total = COSTS_N_INSNS (6);
  2818. else if (mode == DImode)
  2819. * total = COSTS_N_INSNS (4);
  2820. else
  2821. * total = COSTS_N_INSNS (1);
  2822. break;
  2823. case NEG:
  2824. * total = (mode == DImode) ? 4 : 1;
  2825. break;
  2826. case MULT:
  2827. if (mode == SFmode)
  2828. * total = COSTS_N_INSNS (7);
  2829. else if (mode == DFmode)
  2830. * total = COSTS_N_INSNS (8);
  2831. else
  2832. * total = COSTS_N_INSNS (10);
  2833. break;
  2834. case DIV:
  2835. case MOD:
  2836. if (mode == SFmode)
  2837. * total = COSTS_N_INSNS (23);
  2838. else if (mode == DFmode)
  2839. * total = COSTS_N_INSNS (36);
  2840. else
  2841. * total = COSTS_N_INSNS (69);
  2842. break;
  2843. case UDIV:
  2844. case UMOD:
  2845. * total = COSTS_N_INSNS (69);
  2846. break;
  2847. case SIGN_EXTEND:
  2848. * total = COSTS_N_INSNS (2);
  2849. break;
  2850. case ZERO_EXTEND:
  2851. * total = COSTS_N_INSNS (1);
  2852. break;
  2853. case CONST_INT:
  2854. * total = 0;
  2855. break;
  2856. case LABEL_REF:
  2857. * total = COSTS_N_INSNS (2);
  2858. break;
  2859. case CONST:
  2860. {
  2861. rtx offset = const0_rtx;
  2862. rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
  2863. if (GET_CODE (symref) == LABEL_REF)
  2864. * total = COSTS_N_INSNS (2);
  2865. else if (GET_CODE (symref) != SYMBOL_REF)
  2866. * total = COSTS_N_INSNS (4);
  2867. /* Let's be paranoid.... */
  2868. else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
  2869. * total = COSTS_N_INSNS (2);
  2870. else
  2871. * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
  2872. break;
  2873. }
  2874. case SYMBOL_REF:
  2875. * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
  2876. break;
  2877. case CONST_DOUBLE:
  2878. {
  2879. rtx high, low;
  2880. split_double (x, & high, & low);
  2881. * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
  2882. || low == CONST0_RTX (GET_MODE (low)))
  2883. ? 2 : 4);
  2884. break;
  2885. }
  2886. default:
  2887. return false;
  2888. }
  2889. return true;
  2890. }
  2891. /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
  2892. static void
  2893. iq2000_asm_trampoline_template (FILE *f)
  2894. {
  2895. fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
  2896. fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
  2897. fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
  2898. if (Pmode == DImode)
  2899. {
  2900. fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
  2901. fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
  2902. }
  2903. else
  2904. {
  2905. fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
  2906. fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
  2907. }
  2908. fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
  2909. fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
  2910. fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
  2911. fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
  2912. fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
  2913. }
  2914. /* Worker for TARGET_TRAMPOLINE_INIT. */
  2915. static void
  2916. iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
  2917. {
  2918. rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
  2919. rtx mem;
  2920. emit_block_move (m_tramp, assemble_trampoline_template (),
  2921. GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
  2922. mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
  2923. emit_move_insn (mem, fnaddr);
  2924. mem = adjust_address (m_tramp, Pmode,
  2925. TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
  2926. emit_move_insn (mem, chain_value);
  2927. }
  2928. #include "gt-iq2000.h"