linux-s390-low.cc 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883
  1. /* GNU/Linux S/390 specific low level interface, for the remote server
  2. for GDB.
  3. Copyright (C) 2001-2022 Free Software Foundation, Inc.
  4. This file is part of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /* This file is used for both 31-bit and 64-bit S/390 systems. */
  16. #include "server.h"
  17. #include "linux-low.h"
  18. #include "elf/common.h"
  19. #include "ax.h"
  20. #include "tracepoint.h"
  21. #include <asm/ptrace.h>
  22. #include "nat/gdb_ptrace.h"
  23. #include <sys/uio.h>
  24. #include <elf.h>
  25. #include <inttypes.h>
  26. #include "linux-s390-tdesc.h"
  27. #ifndef HWCAP_S390_HIGH_GPRS
  28. #define HWCAP_S390_HIGH_GPRS 512
  29. #endif
  30. #ifndef HWCAP_S390_TE
  31. #define HWCAP_S390_TE 1024
  32. #endif
  33. #ifndef HWCAP_S390_VX
  34. #define HWCAP_S390_VX 2048
  35. #endif
  36. #ifndef HWCAP_S390_GS
  37. #define HWCAP_S390_GS 16384
  38. #endif
  39. #define s390_num_regs 52
  40. /* Linux target op definitions for the S/390 architecture. */
  41. class s390_target : public linux_process_target
  42. {
  43. public:
  44. const regs_info *get_regs_info () override;
  45. const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
  46. bool supports_z_point_type (char z_type) override;
  47. bool supports_tracepoints () override;
  48. bool supports_fast_tracepoints () override;
  49. int install_fast_tracepoint_jump_pad
  50. (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
  51. CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
  52. CORE_ADDR *trampoline, ULONGEST *trampoline_size,
  53. unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
  54. CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
  55. char *err) override;
  56. int get_min_fast_tracepoint_insn_len () override;
  57. void low_collect_ptrace_register (regcache *regcache, int regno,
  58. char *buf) override;
  59. void low_supply_ptrace_register (regcache *regcache, int regno,
  60. const char *buf) override;
  61. struct emit_ops *emit_ops () override;
  62. int get_ipa_tdesc_idx () override;
  63. protected:
  64. void low_arch_setup () override;
  65. bool low_cannot_fetch_register (int regno) override;
  66. bool low_cannot_store_register (int regno) override;
  67. bool low_supports_breakpoints () override;
  68. CORE_ADDR low_get_pc (regcache *regcache) override;
  69. void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
  70. int low_decr_pc_after_break () override;
  71. bool low_breakpoint_at (CORE_ADDR pc) override;
  72. int low_get_thread_area (int lwpid, CORE_ADDR *addrp) override;
  73. };
  74. /* The singleton target ops object. */
  75. static s390_target the_s390_target;
  76. static int s390_regmap[] = {
  77. PT_PSWMASK, PT_PSWADDR,
  78. PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
  79. PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
  80. PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
  81. PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
  82. PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
  83. PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
  84. PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
  85. PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
  86. PT_FPC,
  87. #ifndef __s390x__
  88. PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
  89. PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
  90. PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
  91. PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
  92. #else
  93. PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
  94. PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
  95. PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
  96. PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
  97. #endif
  98. PT_ORIGGPR2,
  99. };
  100. #define s390_num_regs_3264 68
  101. #ifdef __s390x__
  102. static int s390_regmap_3264[] = {
  103. PT_PSWMASK, PT_PSWADDR,
  104. PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1,
  105. PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3,
  106. PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5,
  107. PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7,
  108. PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9,
  109. PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11,
  110. PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13,
  111. PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15,
  112. PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
  113. PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
  114. PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
  115. PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
  116. PT_FPC,
  117. PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
  118. PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
  119. PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
  120. PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
  121. PT_ORIGGPR2,
  122. };
  123. #else
  124. static int s390_regmap_3264[] = {
  125. PT_PSWMASK, PT_PSWADDR,
  126. -1, PT_GPR0, -1, PT_GPR1,
  127. -1, PT_GPR2, -1, PT_GPR3,
  128. -1, PT_GPR4, -1, PT_GPR5,
  129. -1, PT_GPR6, -1, PT_GPR7,
  130. -1, PT_GPR8, -1, PT_GPR9,
  131. -1, PT_GPR10, -1, PT_GPR11,
  132. -1, PT_GPR12, -1, PT_GPR13,
  133. -1, PT_GPR14, -1, PT_GPR15,
  134. PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
  135. PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
  136. PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
  137. PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
  138. PT_FPC,
  139. PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
  140. PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
  141. PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
  142. PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
  143. PT_ORIGGPR2,
  144. };
  145. #endif
  146. bool
  147. s390_target::low_cannot_fetch_register (int regno)
  148. {
  149. return false;
  150. }
  151. bool
  152. s390_target::low_cannot_store_register (int regno)
  153. {
  154. return false;
  155. }
  156. void
  157. s390_target::low_collect_ptrace_register (regcache *regcache, int regno,
  158. char *buf)
  159. {
  160. int size = register_size (regcache->tdesc, regno);
  161. const struct regs_info *regs_info = get_regs_info ();
  162. struct usrregs_info *usr = regs_info->usrregs;
  163. int regaddr = usr->regmap[regno];
  164. if (size < sizeof (long))
  165. {
  166. memset (buf, 0, sizeof (long));
  167. if ((regno ^ 1) < usr->num_regs
  168. && usr->regmap[regno ^ 1] == regaddr)
  169. {
  170. collect_register (regcache, regno & ~1, buf);
  171. collect_register (regcache, (regno & ~1) + 1,
  172. buf + sizeof (long) - size);
  173. }
  174. else if (regaddr == PT_PSWMASK)
  175. {
  176. /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
  177. the basic addressing mode bit from the PSW address. */
  178. gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
  179. collect_register (regcache, regno, buf);
  180. collect_register (regcache, regno ^ 1, addr);
  181. buf[1] &= ~0x8;
  182. buf[size] |= (addr[0] & 0x80);
  183. }
  184. else if (regaddr == PT_PSWADDR)
  185. {
  186. /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
  187. mode bit (which gets copied to the PSW mask instead). */
  188. collect_register (regcache, regno, buf + sizeof (long) - size);
  189. buf[sizeof (long) - size] &= ~0x80;
  190. }
  191. else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
  192. || regaddr == PT_ORIGGPR2)
  193. collect_register (regcache, regno, buf + sizeof (long) - size);
  194. else
  195. collect_register (regcache, regno, buf);
  196. }
  197. else if (regaddr != -1)
  198. collect_register (regcache, regno, buf);
  199. }
  200. void
  201. s390_target::low_supply_ptrace_register (regcache *regcache, int regno,
  202. const char *buf)
  203. {
  204. int size = register_size (regcache->tdesc, regno);
  205. const struct regs_info *regs_info = get_regs_info ();
  206. struct usrregs_info *usr = regs_info->usrregs;
  207. int regaddr = usr->regmap[regno];
  208. if (size < sizeof (long))
  209. {
  210. if ((regno ^ 1) < usr->num_regs
  211. && usr->regmap[regno ^ 1] == regaddr)
  212. {
  213. supply_register (regcache, regno & ~1, buf);
  214. supply_register (regcache, (regno & ~1) + 1,
  215. buf + sizeof (long) - size);
  216. }
  217. else if (regaddr == PT_PSWMASK)
  218. {
  219. /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
  220. the basic addressing mode into the PSW address. */
  221. gdb_byte *mask = (gdb_byte *) alloca (size);
  222. gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
  223. memcpy (mask, buf, size);
  224. mask[1] |= 0x8;
  225. supply_register (regcache, regno, mask);
  226. collect_register (regcache, regno ^ 1, addr);
  227. addr[0] &= ~0x80;
  228. addr[0] |= (buf[size] & 0x80);
  229. supply_register (regcache, regno ^ 1, addr);
  230. }
  231. else if (regaddr == PT_PSWADDR)
  232. {
  233. /* Convert 8-byte PSW address to 4 bytes by truncating, but
  234. keeping the addressing mode bit (which was set from the mask). */
  235. gdb_byte *addr = (gdb_byte *) alloca (size);
  236. char amode;
  237. collect_register (regcache, regno, addr);
  238. amode = addr[0] & 0x80;
  239. memcpy (addr, buf + sizeof (long) - size, size);
  240. addr[0] &= ~0x80;
  241. addr[0] |= amode;
  242. supply_register (regcache, regno, addr);
  243. }
  244. else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
  245. || regaddr == PT_ORIGGPR2)
  246. supply_register (regcache, regno, buf + sizeof (long) - size);
  247. else
  248. supply_register (regcache, regno, buf);
  249. }
  250. else if (regaddr != -1)
  251. supply_register (regcache, regno, buf);
  252. }
  253. /* Provide only a fill function for the general register set. ps_lgetregs
  254. will use this for NPTL support. */
  255. static void
  256. s390_fill_gregset (struct regcache *regcache, void *buf)
  257. {
  258. int i;
  259. const struct regs_info *regs_info = the_linux_target->get_regs_info ();
  260. struct usrregs_info *usr = regs_info->usrregs;
  261. for (i = 0; i < usr->num_regs; i++)
  262. {
  263. if (usr->regmap[i] < PT_PSWMASK
  264. || usr->regmap[i] > PT_ACR15)
  265. continue;
  266. ((s390_target *) the_linux_target)->low_collect_ptrace_register
  267. (regcache, i, (char *) buf + usr->regmap[i]);
  268. }
  269. }
  270. /* Fill and store functions for extended register sets. */
  271. #ifndef __s390x__
  272. static void
  273. s390_fill_gprs_high (struct regcache *regcache, void *buf)
  274. {
  275. int r0h = find_regno (regcache->tdesc, "r0h");
  276. int i;
  277. for (i = 0; i < 16; i++)
  278. collect_register (regcache, r0h + 2 * i, (char *) buf + 4 * i);
  279. }
  280. static void
  281. s390_store_gprs_high (struct regcache *regcache, const void *buf)
  282. {
  283. int r0h = find_regno (regcache->tdesc, "r0h");
  284. int i;
  285. for (i = 0; i < 16; i++)
  286. supply_register (regcache, r0h + 2 * i, (const char *) buf + 4 * i);
  287. }
  288. #endif
  289. static void
  290. s390_store_last_break (struct regcache *regcache, const void *buf)
  291. {
  292. const char *p;
  293. p = (const char *) buf + 8 - register_size (regcache->tdesc, 0);
  294. supply_register_by_name (regcache, "last_break", p);
  295. }
  296. static void
  297. s390_fill_system_call (struct regcache *regcache, void *buf)
  298. {
  299. collect_register_by_name (regcache, "system_call", buf);
  300. }
  301. static void
  302. s390_store_system_call (struct regcache *regcache, const void *buf)
  303. {
  304. supply_register_by_name (regcache, "system_call", buf);
  305. }
  306. static void
  307. s390_store_tdb (struct regcache *regcache, const void *buf)
  308. {
  309. int tdb0 = find_regno (regcache->tdesc, "tdb0");
  310. int tr0 = find_regno (regcache->tdesc, "tr0");
  311. int i;
  312. for (i = 0; i < 4; i++)
  313. supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
  314. for (i = 0; i < 16; i++)
  315. supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
  316. }
  317. static void
  318. s390_fill_vxrs_low (struct regcache *regcache, void *buf)
  319. {
  320. int v0 = find_regno (regcache->tdesc, "v0l");
  321. int i;
  322. for (i = 0; i < 16; i++)
  323. collect_register (regcache, v0 + i, (char *) buf + 8 * i);
  324. }
  325. static void
  326. s390_store_vxrs_low (struct regcache *regcache, const void *buf)
  327. {
  328. int v0 = find_regno (regcache->tdesc, "v0l");
  329. int i;
  330. for (i = 0; i < 16; i++)
  331. supply_register (regcache, v0 + i, (const char *) buf + 8 * i);
  332. }
  333. static void
  334. s390_fill_vxrs_high (struct regcache *regcache, void *buf)
  335. {
  336. int v16 = find_regno (regcache->tdesc, "v16");
  337. int i;
  338. for (i = 0; i < 16; i++)
  339. collect_register (regcache, v16 + i, (char *) buf + 16 * i);
  340. }
  341. static void
  342. s390_store_vxrs_high (struct regcache *regcache, const void *buf)
  343. {
  344. int v16 = find_regno (regcache->tdesc, "v16");
  345. int i;
  346. for (i = 0; i < 16; i++)
  347. supply_register (regcache, v16 + i, (const char *) buf + 16 * i);
  348. }
  349. static void
  350. s390_store_gs (struct regcache *regcache, const void *buf)
  351. {
  352. int gsd = find_regno (regcache->tdesc, "gsd");
  353. int i;
  354. for (i = 0; i < 3; i++)
  355. supply_register (regcache, gsd + i, (const char *) buf + 8 * (i + 1));
  356. }
  357. static void
  358. s390_store_gsbc (struct regcache *regcache, const void *buf)
  359. {
  360. int bc_gsd = find_regno (regcache->tdesc, "bc_gsd");
  361. int i;
  362. for (i = 0; i < 3; i++)
  363. supply_register (regcache, bc_gsd + i, (const char *) buf + 8 * (i + 1));
  364. }
  365. static struct regset_info s390_regsets[] = {
  366. { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
  367. #ifndef __s390x__
  368. { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_HIGH_GPRS, 0,
  369. EXTENDED_REGS, s390_fill_gprs_high, s390_store_gprs_high },
  370. #endif
  371. /* Last break address is read-only; no fill function. */
  372. { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
  373. NULL, s390_store_last_break },
  374. { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
  375. EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
  376. /* TDB is read-only. */
  377. { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
  378. NULL, s390_store_tdb },
  379. { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_LOW, 0,
  380. EXTENDED_REGS, s390_fill_vxrs_low, s390_store_vxrs_low },
  381. { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_HIGH, 0,
  382. EXTENDED_REGS, s390_fill_vxrs_high, s390_store_vxrs_high },
  383. /* Guarded storage registers are read-only. */
  384. { PTRACE_GETREGSET, -1, NT_S390_GS_CB, 0, EXTENDED_REGS,
  385. NULL, s390_store_gs },
  386. { PTRACE_GETREGSET, -1, NT_S390_GS_BC, 0, EXTENDED_REGS,
  387. NULL, s390_store_gsbc },
  388. NULL_REGSET
  389. };
  390. static const gdb_byte s390_breakpoint[] = { 0, 1 };
  391. #define s390_breakpoint_len 2
  392. /* Implementation of target ops method "sw_breakpoint_from_kind". */
  393. const gdb_byte *
  394. s390_target::sw_breakpoint_from_kind (int kind, int *size)
  395. {
  396. *size = s390_breakpoint_len;
  397. return s390_breakpoint;
  398. }
  399. bool
  400. s390_target::low_supports_breakpoints ()
  401. {
  402. return true;
  403. }
  404. CORE_ADDR
  405. s390_target::low_get_pc (regcache *regcache)
  406. {
  407. if (register_size (regcache->tdesc, 0) == 4)
  408. {
  409. unsigned int pswa;
  410. collect_register_by_name (regcache, "pswa", &pswa);
  411. return pswa & 0x7fffffff;
  412. }
  413. else
  414. {
  415. unsigned long pc;
  416. collect_register_by_name (regcache, "pswa", &pc);
  417. return pc;
  418. }
  419. }
  420. void
  421. s390_target::low_set_pc (regcache *regcache, CORE_ADDR newpc)
  422. {
  423. if (register_size (regcache->tdesc, 0) == 4)
  424. {
  425. unsigned int pswa;
  426. collect_register_by_name (regcache, "pswa", &pswa);
  427. pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
  428. supply_register_by_name (regcache, "pswa", &pswa);
  429. }
  430. else
  431. {
  432. unsigned long pc = newpc;
  433. supply_register_by_name (regcache, "pswa", &pc);
  434. }
  435. }
  436. int
  437. s390_target::low_decr_pc_after_break ()
  438. {
  439. return s390_breakpoint_len;
  440. }
  441. /* Determine the word size for the given PID, in bytes. */
  442. #ifdef __s390x__
  443. static int
  444. s390_get_wordsize (int pid)
  445. {
  446. errno = 0;
  447. PTRACE_XFER_TYPE pswm = ptrace (PTRACE_PEEKUSER, pid,
  448. (PTRACE_TYPE_ARG3) 0,
  449. (PTRACE_TYPE_ARG4) 0);
  450. if (errno != 0)
  451. {
  452. warning (_("Couldn't determine word size, assuming 64-bit."));
  453. return 8;
  454. }
  455. /* Derive word size from extended addressing mode (PSW bit 31). */
  456. return pswm & (1L << 32) ? 8 : 4;
  457. }
  458. #else
  459. #define s390_get_wordsize(pid) 4
  460. #endif
  461. static int
  462. s390_check_regset (int pid, int regset, int regsize)
  463. {
  464. void *buf = alloca (regsize);
  465. struct iovec iov;
  466. iov.iov_base = buf;
  467. iov.iov_len = regsize;
  468. if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
  469. || errno == ENODATA)
  470. return 1;
  471. return 0;
  472. }
  473. /* For a 31-bit inferior, whether the kernel supports using the full
  474. 64-bit GPRs. */
  475. static int have_hwcap_s390_high_gprs = 0;
  476. static int have_hwcap_s390_vx = 0;
  477. void
  478. s390_target::low_arch_setup ()
  479. {
  480. const struct target_desc *tdesc;
  481. struct regset_info *regset;
  482. /* Determine word size and HWCAP. */
  483. int pid = pid_of (current_thread);
  484. int wordsize = s390_get_wordsize (pid);
  485. unsigned long hwcap = linux_get_hwcap (wordsize);
  486. /* Check whether the kernel supports extra register sets. */
  487. int have_regset_last_break
  488. = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
  489. int have_regset_system_call
  490. = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
  491. int have_regset_tdb
  492. = (s390_check_regset (pid, NT_S390_TDB, 256)
  493. && (hwcap & HWCAP_S390_TE) != 0);
  494. int have_regset_vxrs
  495. = (s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
  496. && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256)
  497. && (hwcap & HWCAP_S390_VX) != 0);
  498. int have_regset_gs
  499. = (s390_check_regset (pid, NT_S390_GS_CB, 32)
  500. && s390_check_regset (pid, NT_S390_GS_BC, 32)
  501. && (hwcap & HWCAP_S390_GS) != 0);
  502. {
  503. #ifdef __s390x__
  504. if (wordsize == 8)
  505. {
  506. if (have_regset_gs)
  507. tdesc = tdesc_s390x_gs_linux64;
  508. else if (have_regset_vxrs)
  509. tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
  510. tdesc_s390x_vx_linux64);
  511. else if (have_regset_tdb)
  512. tdesc = tdesc_s390x_te_linux64;
  513. else if (have_regset_system_call)
  514. tdesc = tdesc_s390x_linux64v2;
  515. else if (have_regset_last_break)
  516. tdesc = tdesc_s390x_linux64v1;
  517. else
  518. tdesc = tdesc_s390x_linux64;
  519. }
  520. /* For a 31-bit inferior, check whether the kernel supports
  521. using the full 64-bit GPRs. */
  522. else
  523. #endif
  524. if (hwcap & HWCAP_S390_HIGH_GPRS)
  525. {
  526. have_hwcap_s390_high_gprs = 1;
  527. if (have_regset_gs)
  528. tdesc = tdesc_s390_gs_linux64;
  529. else if (have_regset_vxrs)
  530. tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
  531. tdesc_s390_vx_linux64);
  532. else if (have_regset_tdb)
  533. tdesc = tdesc_s390_te_linux64;
  534. else if (have_regset_system_call)
  535. tdesc = tdesc_s390_linux64v2;
  536. else if (have_regset_last_break)
  537. tdesc = tdesc_s390_linux64v1;
  538. else
  539. tdesc = tdesc_s390_linux64;
  540. }
  541. else
  542. {
  543. /* Assume 31-bit inferior process. */
  544. if (have_regset_system_call)
  545. tdesc = tdesc_s390_linux32v2;
  546. else if (have_regset_last_break)
  547. tdesc = tdesc_s390_linux32v1;
  548. else
  549. tdesc = tdesc_s390_linux32;
  550. }
  551. have_hwcap_s390_vx = have_regset_vxrs;
  552. }
  553. /* Update target_regsets according to available register sets. */
  554. for (regset = s390_regsets; regset->size >= 0; regset++)
  555. if (regset->get_request == PTRACE_GETREGSET)
  556. switch (regset->nt_type)
  557. {
  558. #ifndef __s390x__
  559. case NT_S390_HIGH_GPRS:
  560. regset->size = have_hwcap_s390_high_gprs ? 64 : 0;
  561. break;
  562. #endif
  563. case NT_S390_LAST_BREAK:
  564. regset->size = have_regset_last_break ? 8 : 0;
  565. break;
  566. case NT_S390_SYSTEM_CALL:
  567. regset->size = have_regset_system_call ? 4 : 0;
  568. break;
  569. case NT_S390_TDB:
  570. regset->size = have_regset_tdb ? 256 : 0;
  571. break;
  572. case NT_S390_VXRS_LOW:
  573. regset->size = have_regset_vxrs ? 128 : 0;
  574. break;
  575. case NT_S390_VXRS_HIGH:
  576. regset->size = have_regset_vxrs ? 256 : 0;
  577. break;
  578. case NT_S390_GS_CB:
  579. case NT_S390_GS_BC:
  580. regset->size = have_regset_gs ? 32 : 0;
  581. default:
  582. break;
  583. }
  584. current_process ()->tdesc = tdesc;
  585. }
  586. bool
  587. s390_target::low_breakpoint_at (CORE_ADDR pc)
  588. {
  589. unsigned char c[s390_breakpoint_len];
  590. read_inferior_memory (pc, c, s390_breakpoint_len);
  591. return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
  592. }
  593. /* Breakpoint/Watchpoint support. */
  594. /* The "supports_z_point_type" target ops method. */
  595. bool
  596. s390_target::supports_z_point_type (char z_type)
  597. {
  598. switch (z_type)
  599. {
  600. case Z_PACKET_SW_BP:
  601. return true;
  602. default:
  603. return false;
  604. }
  605. }
  606. static struct usrregs_info s390_usrregs_info =
  607. {
  608. s390_num_regs,
  609. s390_regmap,
  610. };
  611. static struct regsets_info s390_regsets_info =
  612. {
  613. s390_regsets, /* regsets */
  614. 0, /* num_regsets */
  615. NULL, /* disabled_regsets */
  616. };
  617. static struct regs_info myregs_info =
  618. {
  619. NULL, /* regset_bitmap */
  620. &s390_usrregs_info,
  621. &s390_regsets_info
  622. };
  623. static struct usrregs_info s390_usrregs_info_3264 =
  624. {
  625. s390_num_regs_3264,
  626. s390_regmap_3264
  627. };
  628. static struct regsets_info s390_regsets_info_3264 =
  629. {
  630. s390_regsets, /* regsets */
  631. 0, /* num_regsets */
  632. NULL, /* disabled_regsets */
  633. };
  634. static struct regs_info regs_info_3264 =
  635. {
  636. NULL, /* regset_bitmap */
  637. &s390_usrregs_info_3264,
  638. &s390_regsets_info_3264
  639. };
  640. const regs_info *
  641. s390_target::get_regs_info ()
  642. {
  643. if (have_hwcap_s390_high_gprs)
  644. {
  645. #ifdef __s390x__
  646. const struct target_desc *tdesc = current_process ()->tdesc;
  647. if (register_size (tdesc, 0) == 4)
  648. return &regs_info_3264;
  649. #else
  650. return &regs_info_3264;
  651. #endif
  652. }
  653. return &myregs_info;
  654. }
  655. /* The "supports_tracepoints" target ops method. */
  656. bool
  657. s390_target::supports_tracepoints ()
  658. {
  659. return true;
  660. }
  661. /* Implementation of linux target ops method "low_get_thread_area". */
  662. int
  663. s390_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
  664. {
  665. CORE_ADDR res = ptrace (PTRACE_PEEKUSER, lwpid, (long) PT_ACR0, (long) 0);
  666. #ifdef __s390x__
  667. struct regcache *regcache = get_thread_regcache (current_thread, 0);
  668. if (register_size (regcache->tdesc, 0) == 4)
  669. res &= 0xffffffffull;
  670. #endif
  671. *addrp = res;
  672. return 0;
  673. }
  674. /* Fast tracepoint support.
  675. The register save area on stack is identical for all targets:
  676. 0x000+i*0x10: VR0-VR31
  677. 0x200+i*8: GR0-GR15
  678. 0x280+i*4: AR0-AR15
  679. 0x2c0: PSWM [64-bit]
  680. 0x2c8: PSWA [64-bit]
  681. 0x2d0: FPC
  682. If we're on 31-bit linux, we just don't store the high parts of the GPRs.
  683. Likewise, if there's no VX support, we just store the FRs into the slots
  684. of low VR halves. The agent code is responsible for rearranging that
  685. into regcache. */
  686. /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
  687. one trick used at the very beginning: since there's no way to allocate
  688. stack space without destroying CC (lay instruction can do it, but it's
  689. only supported on later CPUs), we take 4 different execution paths for
  690. every possible value of CC, allocate stack space, save %r0, stuff the
  691. CC value in %r0 (shifted to match its position in PSWM high word),
  692. then branch to common path. */
  693. static const unsigned char s390_ft_entry_gpr_esa[] = {
  694. 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
  695. 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
  696. 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
  697. /* CC = 0 */
  698. 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
  699. 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
  700. 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
  701. 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
  702. /* .Lcc1: */
  703. 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
  704. 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
  705. 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
  706. 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
  707. /* .Lcc2: */
  708. 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
  709. 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
  710. 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
  711. 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
  712. /* .Lcc3: */
  713. 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
  714. 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
  715. 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
  716. /* .Lccdone: */
  717. 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
  718. 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
  719. 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
  720. 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
  721. 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
  722. 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
  723. 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
  724. 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
  725. 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
  726. 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
  727. 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
  728. 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
  729. 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
  730. 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
  731. /* Compute original value of %r15 and store it. We use ahi instead
  732. of la to preserve the whole value, and not just the low 31 bits.
  733. This is not particularly important here, but essential in the
  734. zarch case where someone might be using the high word of %r15
  735. as an extra register. */
  736. 0x18, 0x1f, /* lr %r1, %r15 */
  737. 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
  738. 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
  739. };
  740. /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
  741. target. Same as above, except this time we can use load/store multiple,
  742. since the 64-bit regs are tightly packed. */
  743. static const unsigned char s390_ft_entry_gpr_zarch[] = {
  744. 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
  745. 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
  746. 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
  747. /* CC = 0 */
  748. 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
  749. 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
  750. 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
  751. 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
  752. /* .Lcc1: */
  753. 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
  754. 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
  755. 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
  756. 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
  757. /* .Lcc2: */
  758. 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
  759. 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
  760. 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
  761. 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
  762. /* .Lcc3: */
  763. 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
  764. 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
  765. 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
  766. /* .Lccdone: */
  767. 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
  768. 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
  769. 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
  770. };
  771. /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
  772. current PSWM (read by epsw) and CC from entry (in %r0). */
  773. static const unsigned char s390_ft_entry_misc[] = {
  774. 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
  775. 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
  776. 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
  777. 0x14, 0x21, /* nr %r2, %r1 */
  778. 0x16, 0x20, /* or %r2, %r0 */
  779. 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
  780. 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
  781. 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
  782. };
  783. /* Code sequence saving FRs, used if VX not supported. */
  784. static const unsigned char s390_ft_entry_fr[] = {
  785. 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
  786. 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
  787. 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
  788. 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
  789. 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
  790. 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
  791. 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
  792. 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
  793. 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
  794. 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
  795. 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
  796. 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
  797. 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
  798. 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
  799. 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
  800. 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
  801. };
  802. /* Code sequence saving VRs, used if VX not supported. */
  803. static const unsigned char s390_ft_entry_vr[] = {
  804. 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
  805. 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
  806. };
  807. /* Code sequence doing the collection call for 31-bit target. %r1 contains
  808. the address of the literal pool. */
  809. static const unsigned char s390_ft_main_31[] = {
  810. /* Load the literals into registers. */
  811. 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
  812. 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
  813. 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
  814. 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
  815. /* Save original PSWA (tracepoint address | 0x80000000). */
  816. 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
  817. /* Construct a collecting_t object at %r15+0x2e0. */
  818. 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
  819. 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
  820. /* Move its address to %r0. */
  821. 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
  822. /* Take the lock. */
  823. /* .Lloop: */
  824. 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
  825. 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
  826. 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
  827. /* Address of the register save block to %r3. */
  828. 0x18, 0x3f, /* lr %r3, %r15 */
  829. /* Make a stack frame, so that we can call the collector. */
  830. 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
  831. /* Call it. */
  832. 0x0d, 0xe4, /* basr %r14, %r4 */
  833. /* And get rid of the stack frame again. */
  834. 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
  835. /* Leave the lock. */
  836. 0x07, 0xf0, /* br %r0 */
  837. 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
  838. 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
  839. };
  840. /* Code sequence doing the collection call for 64-bit target. %r1 contains
  841. the address of the literal pool. */
  842. static const unsigned char s390_ft_main_64[] = {
  843. /* Load the literals into registers. */
  844. 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
  845. 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
  846. 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
  847. 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
  848. /* Save original PSWA (tracepoint address). */
  849. 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
  850. /* Construct a collecting_t object at %r15+0x2e0. */
  851. 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
  852. 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
  853. /* Move its address to %r0. */
  854. 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
  855. /* Take the lock. */
  856. /* .Lloop: */
  857. 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
  858. 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
  859. 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
  860. /* Address of the register save block to %r3. */
  861. 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
  862. /* Make a stack frame, so that we can call the collector. */
  863. 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
  864. /* Call it. */
  865. 0x0d, 0xe4, /* basr %r14, %r4 */
  866. /* And get rid of the stack frame again. */
  867. 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
  868. /* Leave the lock. */
  869. 0x07, 0xf0, /* br %r0 */
  870. 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
  871. 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
  872. };
  873. /* Code sequence restoring FRs, for targets with no VX support. */
  874. static const unsigned char s390_ft_exit_fr[] = {
  875. 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
  876. 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
  877. 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
  878. 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
  879. 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
  880. 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
  881. 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
  882. 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
  883. 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
  884. 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
  885. 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
  886. 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
  887. 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
  888. 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
  889. 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
  890. 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
  891. };
  892. /* Code sequence restoring VRs. */
  893. static const unsigned char s390_ft_exit_vr[] = {
  894. 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
  895. 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
  896. };
  897. /* Code sequence restoring misc registers. As for PSWM, only CC should be
  898. modified by C code, so we use the alr instruction to restore it by
  899. manufacturing an operand that'll result in the original flags. */
  900. static const unsigned char s390_ft_exit_misc[] = {
  901. 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
  902. 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
  903. /* Extract CC to high 2 bits of %r0. */
  904. 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
  905. 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
  906. /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
  907. will have carry iff CC bit 1 is set - resulting in the same flags
  908. as the original. */
  909. 0x1e, 0x00, /* alr %r0, %r0 */
  910. 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
  911. };
  912. /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
  913. static const unsigned char s390_ft_exit_gpr_esa[] = {
  914. 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
  915. 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
  916. 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
  917. 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
  918. 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
  919. 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
  920. 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
  921. 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
  922. 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
  923. 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
  924. 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
  925. 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
  926. 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
  927. 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
  928. 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
  929. 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
  930. };
  931. /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
  932. with high GPRs. */
  933. static const unsigned char s390_ft_exit_gpr_zarch[] = {
  934. 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
  935. };
  936. /* Writes instructions to target, updating the to pointer. */
  937. static void
  938. append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf)
  939. {
  940. target_write_memory (*to, buf, len);
  941. *to += len;
  942. }
  943. /* Relocates an instruction from oldloc to *to, updating to. */
  944. static int
  945. s390_relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc, int is_64)
  946. {
  947. gdb_byte buf[6];
  948. int ilen;
  949. int op2;
  950. /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
  951. int mode = 0;
  952. int is_bras = 0;
  953. read_inferior_memory (oldloc, buf, sizeof buf);
  954. if (buf[0] < 0x40)
  955. ilen = 2;
  956. else if (buf[0] < 0xc0)
  957. ilen = 4;
  958. else
  959. ilen = 6;
  960. switch (buf[0])
  961. {
  962. case 0x05: /* BALR */
  963. case 0x0c: /* BASSM */
  964. case 0x0d: /* BASR */
  965. case 0x45: /* BAL */
  966. case 0x4d: /* BAS */
  967. /* These save a return address and mess around with registers.
  968. We can't relocate them. */
  969. return 1;
  970. case 0x84: /* BRXH */
  971. case 0x85: /* BRXLE */
  972. mode = 1;
  973. break;
  974. case 0xa7:
  975. op2 = buf[1] & 0xf;
  976. /* BRC, BRAS, BRCT, BRCTG */
  977. if (op2 >= 4 && op2 <= 7)
  978. mode = 1;
  979. /* BRAS */
  980. if (op2 == 5)
  981. is_bras = 1;
  982. break;
  983. case 0xc0:
  984. op2 = buf[1] & 0xf;
  985. /* LARL, BRCL, BRASL */
  986. if (op2 == 0 || op2 == 4 || op2 == 5)
  987. mode = 2;
  988. /* BRASL */
  989. if (op2 == 5)
  990. is_bras = 1;
  991. break;
  992. case 0xc4:
  993. case 0xc6:
  994. /* PC-relative addressing instructions. */
  995. mode = 2;
  996. break;
  997. case 0xc5: /* BPRP */
  998. case 0xc7: /* BPP */
  999. /* Branch prediction - just skip it. */
  1000. return 0;
  1001. case 0xcc:
  1002. op2 = buf[1] & 0xf;
  1003. /* BRCTH */
  1004. if (op2 == 6)
  1005. mode = 2;
  1006. break;
  1007. case 0xec:
  1008. op2 = buf[5];
  1009. switch (op2)
  1010. {
  1011. case 0x44: /* BRXHG */
  1012. case 0x45: /* BRXLG */
  1013. case 0x64: /* CGRJ */
  1014. case 0x65: /* CLGRJ */
  1015. case 0x76: /* CRJ */
  1016. case 0x77: /* CLRJ */
  1017. mode = 1;
  1018. break;
  1019. }
  1020. break;
  1021. }
  1022. if (mode != 0)
  1023. {
  1024. /* We'll have to relocate an instruction with a PC-relative field.
  1025. First, compute the target. */
  1026. int64_t loffset = 0;
  1027. CORE_ADDR target;
  1028. if (mode == 1)
  1029. {
  1030. int16_t soffset = 0;
  1031. memcpy (&soffset, buf + 2, 2);
  1032. loffset = soffset;
  1033. }
  1034. else if (mode == 2)
  1035. {
  1036. int32_t soffset = 0;
  1037. memcpy (&soffset, buf + 2, 4);
  1038. loffset = soffset;
  1039. }
  1040. target = oldloc + loffset * 2;
  1041. if (!is_64)
  1042. target &= 0x7fffffff;
  1043. if (is_bras)
  1044. {
  1045. /* BRAS or BRASL was used. We cannot just relocate those, since
  1046. they save the return address in a register. We can, however,
  1047. replace them with a LARL+JG sequence. */
  1048. /* Make the LARL. */
  1049. int32_t soffset;
  1050. buf[0] = 0xc0;
  1051. buf[1] &= 0xf0;
  1052. loffset = oldloc + ilen - *to;
  1053. loffset >>= 1;
  1054. soffset = loffset;
  1055. if (soffset != loffset && is_64)
  1056. return 1;
  1057. memcpy (buf + 2, &soffset, 4);
  1058. append_insns (to, 6, buf);
  1059. /* Note: this is not fully correct. In 31-bit mode, LARL will write
  1060. an address with the top bit 0, while BRAS/BRASL will write it
  1061. with top bit 1. It should not matter much, since linux compilers
  1062. use BR and not BSM to return from functions, but it could confuse
  1063. some poor stack unwinder. */
  1064. /* We'll now be writing a JG. */
  1065. mode = 2;
  1066. buf[0] = 0xc0;
  1067. buf[1] = 0xf4;
  1068. ilen = 6;
  1069. }
  1070. /* Compute the new offset and write it to the buffer. */
  1071. loffset = target - *to;
  1072. loffset >>= 1;
  1073. if (mode == 1)
  1074. {
  1075. int16_t soffset = loffset;
  1076. if (soffset != loffset)
  1077. return 1;
  1078. memcpy (buf + 2, &soffset, 2);
  1079. }
  1080. else if (mode == 2)
  1081. {
  1082. int32_t soffset = loffset;
  1083. if (soffset != loffset && is_64)
  1084. return 1;
  1085. memcpy (buf + 2, &soffset, 4);
  1086. }
  1087. }
  1088. append_insns (to, ilen, buf);
  1089. return 0;
  1090. }
  1091. bool
  1092. s390_target::supports_fast_tracepoints ()
  1093. {
  1094. return true;
  1095. }
  1096. /* Implementation of target ops method
  1097. "install_fast_tracepoint_jump_pad". */
  1098. int
  1099. s390_target::install_fast_tracepoint_jump_pad
  1100. (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
  1101. CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
  1102. CORE_ADDR *trampoline, ULONGEST *trampoline_size,
  1103. unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
  1104. CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
  1105. char *err)
  1106. {
  1107. int i;
  1108. int64_t loffset;
  1109. int32_t offset;
  1110. unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
  1111. CORE_ADDR buildaddr = *jump_entry;
  1112. #ifdef __s390x__
  1113. struct regcache *regcache = get_thread_regcache (current_thread, 0);
  1114. int is_64 = register_size (regcache->tdesc, 0) == 8;
  1115. int is_zarch = is_64 || have_hwcap_s390_high_gprs;
  1116. int has_vx = have_hwcap_s390_vx;
  1117. #else
  1118. int is_64 = 0, is_zarch = 0, has_vx = 0;
  1119. #endif
  1120. CORE_ADDR literals[4] = {
  1121. tpaddr,
  1122. tpoint,
  1123. collector,
  1124. lockaddr,
  1125. };
  1126. /* First, store the GPRs. */
  1127. if (is_zarch)
  1128. append_insns (&buildaddr, sizeof s390_ft_entry_gpr_zarch,
  1129. s390_ft_entry_gpr_zarch);
  1130. else
  1131. append_insns (&buildaddr, sizeof s390_ft_entry_gpr_esa,
  1132. s390_ft_entry_gpr_esa);
  1133. /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
  1134. append_insns (&buildaddr, sizeof s390_ft_entry_misc, s390_ft_entry_misc);
  1135. /* Third, FRs or VRs. */
  1136. if (has_vx)
  1137. append_insns (&buildaddr, sizeof s390_ft_entry_vr, s390_ft_entry_vr);
  1138. else
  1139. append_insns (&buildaddr, sizeof s390_ft_entry_fr, s390_ft_entry_fr);
  1140. /* Now, the main part of code - store PSWA, take lock, call collector,
  1141. leave lock. First, we'll need to fetch 4 literals. */
  1142. if (is_64) {
  1143. unsigned char buf[] = {
  1144. 0x07, 0x07, /* nopr %r7 */
  1145. 0x07, 0x07, /* nopr %r7 */
  1146. 0x07, 0x07, /* nopr %r7 */
  1147. 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
  1148. 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
  1149. 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
  1150. 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
  1151. 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
  1152. /* .Lend: */
  1153. };
  1154. /* Find the proper start place in buf, so that literals will be
  1155. aligned. */
  1156. int bufpos = (buildaddr + 2) & 7;
  1157. /* Stuff the literals into the buffer. */
  1158. for (i = 0; i < 4; i++) {
  1159. uint64_t lit = literals[i];
  1160. memcpy (&buf[sizeof buf - 32 + i * 8], &lit, 8);
  1161. }
  1162. append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
  1163. append_insns (&buildaddr, sizeof s390_ft_main_64, s390_ft_main_64);
  1164. } else {
  1165. unsigned char buf[] = {
  1166. 0x07, 0x07, /* nopr %r7 */
  1167. 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
  1168. 0, 0, 0, 0, /* tpaddr */
  1169. 0, 0, 0, 0, /* tpoint */
  1170. 0, 0, 0, 0, /* collector */
  1171. 0, 0, 0, 0, /* lockaddr */
  1172. /* .Lend: */
  1173. };
  1174. /* Find the proper start place in buf, so that literals will be
  1175. aligned. */
  1176. int bufpos = (buildaddr + 2) & 3;
  1177. /* First literal will be saved as the PSWA, make sure it has the high bit
  1178. set. */
  1179. literals[0] |= 0x80000000;
  1180. /* Stuff the literals into the buffer. */
  1181. for (i = 0; i < 4; i++) {
  1182. uint32_t lit = literals[i];
  1183. memcpy (&buf[sizeof buf - 16 + i * 4], &lit, 4);
  1184. }
  1185. append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
  1186. append_insns (&buildaddr, sizeof s390_ft_main_31, s390_ft_main_31);
  1187. }
  1188. /* Restore FRs or VRs. */
  1189. if (has_vx)
  1190. append_insns (&buildaddr, sizeof s390_ft_exit_vr, s390_ft_exit_vr);
  1191. else
  1192. append_insns (&buildaddr, sizeof s390_ft_exit_fr, s390_ft_exit_fr);
  1193. /* Restore misc registers. */
  1194. append_insns (&buildaddr, sizeof s390_ft_exit_misc, s390_ft_exit_misc);
  1195. /* Restore the GPRs. */
  1196. if (is_zarch)
  1197. append_insns (&buildaddr, sizeof s390_ft_exit_gpr_zarch,
  1198. s390_ft_exit_gpr_zarch);
  1199. else
  1200. append_insns (&buildaddr, sizeof s390_ft_exit_gpr_esa,
  1201. s390_ft_exit_gpr_esa);
  1202. /* Now, adjust the original instruction to execute in the jump
  1203. pad. */
  1204. *adjusted_insn_addr = buildaddr;
  1205. if (s390_relocate_instruction (&buildaddr, tpaddr, is_64))
  1206. {
  1207. sprintf (err, "E.Could not relocate instruction for tracepoint.");
  1208. return 1;
  1209. }
  1210. *adjusted_insn_addr_end = buildaddr;
  1211. /* Finally, write a jump back to the program. */
  1212. loffset = (tpaddr + orig_size) - buildaddr;
  1213. loffset >>= 1;
  1214. offset = loffset;
  1215. if (is_64 && offset != loffset)
  1216. {
  1217. sprintf (err,
  1218. "E.Jump back from jump pad too far from tracepoint "
  1219. "(offset 0x%" PRIx64 " > int33).", loffset);
  1220. return 1;
  1221. }
  1222. memcpy (jbuf + 2, &offset, 4);
  1223. append_insns (&buildaddr, sizeof jbuf, jbuf);
  1224. /* The jump pad is now built. Wire in a jump to our jump pad. This
  1225. is always done last (by our caller actually), so that we can
  1226. install fast tracepoints with threads running. This relies on
  1227. the agent's atomic write support. */
  1228. loffset = *jump_entry - tpaddr;
  1229. loffset >>= 1;
  1230. offset = loffset;
  1231. if (is_64 && offset != loffset)
  1232. {
  1233. sprintf (err,
  1234. "E.Jump back from jump pad too far from tracepoint "
  1235. "(offset 0x%" PRIx64 " > int33).", loffset);
  1236. return 1;
  1237. }
  1238. memcpy (jbuf + 2, &offset, 4);
  1239. memcpy (jjump_pad_insn, jbuf, sizeof jbuf);
  1240. *jjump_pad_insn_size = sizeof jbuf;
  1241. /* Return the end address of our pad. */
  1242. *jump_entry = buildaddr;
  1243. return 0;
  1244. }
  1245. /* Implementation of target ops method
  1246. "get_min_fast_tracepoint_insn_len". */
  1247. int
  1248. s390_target::get_min_fast_tracepoint_insn_len ()
  1249. {
  1250. /* We only support using 6-byte jumps to reach the tracepoint code.
  1251. If the tracepoint buffer were allocated sufficiently close (64kiB)
  1252. to the executable code, and the traced instruction itself was close
  1253. enough to the beginning, we could use 4-byte jumps, but this doesn't
  1254. seem to be worth the effort. */
  1255. return 6;
  1256. }
  1257. /* Implementation of target ops method "get_ipa_tdesc_idx". */
  1258. int
  1259. s390_target::get_ipa_tdesc_idx ()
  1260. {
  1261. struct regcache *regcache = get_thread_regcache (current_thread, 0);
  1262. const struct target_desc *tdesc = regcache->tdesc;
  1263. #ifdef __s390x__
  1264. if (tdesc == tdesc_s390x_linux64)
  1265. return S390_TDESC_64;
  1266. if (tdesc == tdesc_s390x_linux64v1)
  1267. return S390_TDESC_64V1;
  1268. if (tdesc == tdesc_s390x_linux64v2)
  1269. return S390_TDESC_64V2;
  1270. if (tdesc == tdesc_s390x_te_linux64)
  1271. return S390_TDESC_TE;
  1272. if (tdesc == tdesc_s390x_vx_linux64)
  1273. return S390_TDESC_VX;
  1274. if (tdesc == tdesc_s390x_tevx_linux64)
  1275. return S390_TDESC_TEVX;
  1276. if (tdesc == tdesc_s390x_gs_linux64)
  1277. return S390_TDESC_GS;
  1278. #endif
  1279. if (tdesc == tdesc_s390_linux32)
  1280. return S390_TDESC_32;
  1281. if (tdesc == tdesc_s390_linux32v1)
  1282. return S390_TDESC_32V1;
  1283. if (tdesc == tdesc_s390_linux32v2)
  1284. return S390_TDESC_32V2;
  1285. if (tdesc == tdesc_s390_linux64)
  1286. return S390_TDESC_64;
  1287. if (tdesc == tdesc_s390_linux64v1)
  1288. return S390_TDESC_64V1;
  1289. if (tdesc == tdesc_s390_linux64v2)
  1290. return S390_TDESC_64V2;
  1291. if (tdesc == tdesc_s390_te_linux64)
  1292. return S390_TDESC_TE;
  1293. if (tdesc == tdesc_s390_vx_linux64)
  1294. return S390_TDESC_VX;
  1295. if (tdesc == tdesc_s390_tevx_linux64)
  1296. return S390_TDESC_TEVX;
  1297. if (tdesc == tdesc_s390_gs_linux64)
  1298. return S390_TDESC_GS;
  1299. return 0;
  1300. }
  1301. /* Appends given buffer to current_insn_ptr in the target. */
  1302. static void
  1303. add_insns (const unsigned char *start, int len)
  1304. {
  1305. CORE_ADDR buildaddr = current_insn_ptr;
  1306. threads_debug_printf ("Adding %d bytes of insn at %s",
  1307. len, paddress (buildaddr));
  1308. append_insns (&buildaddr, len, start);
  1309. current_insn_ptr = buildaddr;
  1310. }
  1311. /* Register usage in emit:
  1312. - %r0, %r1: temp
  1313. - %r2: top of stack (high word for 31-bit)
  1314. - %r3: low word of top of stack (for 31-bit)
  1315. - %r4, %r5: temp
  1316. - %r6, %r7, %r8: don't use
  1317. - %r9: saved arg1
  1318. - %r10: saved arg2
  1319. - %r11: frame pointer
  1320. - %r12: saved top of stack for void_call_2 (high word for 31-bit)
  1321. - %r13: low word of saved top of stack (for 31-bit)
  1322. - %r14: return address for calls
  1323. - %r15: stack pointer
  1324. */
  1325. /* The "emit_prologue" emit_ops method for s390. */
  1326. static void
  1327. s390_emit_prologue (void)
  1328. {
  1329. static const unsigned char buf[] = {
  1330. 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
  1331. 0x18, 0x92, /* lr %r9, %r2 */
  1332. 0x18, 0xa3, /* lr %r10, %r3 */
  1333. 0x18, 0xbf, /* lr %r11, %r15 */
  1334. };
  1335. add_insns (buf, sizeof buf);
  1336. }
  1337. /* The "emit_epilogue" emit_ops method for s390. */
  1338. static void
  1339. s390_emit_epilogue (void)
  1340. {
  1341. static const unsigned char buf[] = {
  1342. 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
  1343. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1344. 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
  1345. 0x07, 0xfe, /* br %r14 */
  1346. };
  1347. add_insns (buf, sizeof buf);
  1348. }
  1349. /* The "emit_add" emit_ops method for s390. */
  1350. static void
  1351. s390_emit_add (void)
  1352. {
  1353. static const unsigned char buf[] = {
  1354. 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
  1355. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
  1356. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1357. };
  1358. add_insns (buf, sizeof buf);
  1359. }
  1360. /* The "emit_sub" emit_ops method for s390. */
  1361. static void
  1362. s390_emit_sub (void)
  1363. {
  1364. static const unsigned char buf[] = {
  1365. 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
  1366. 0x1f, 0x53, /* slr %r5, %r3 */
  1367. 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
  1368. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1369. 0x18, 0x35, /* lr %r3, %r5 */
  1370. 0x18, 0x24, /* lr %r2, %r4 */
  1371. };
  1372. add_insns (buf, sizeof buf);
  1373. }
  1374. /* The "emit_mul" emit_ops method for s390. */
  1375. static void
  1376. s390_emit_mul (void)
  1377. {
  1378. emit_error = 1;
  1379. }
  1380. /* The "emit_lsh" emit_ops method for s390. */
  1381. static void
  1382. s390_emit_lsh (void)
  1383. {
  1384. static const unsigned char buf[] = {
  1385. 0x18, 0x43, /* lr %r4, %r3 */
  1386. 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
  1387. 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
  1388. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1389. };
  1390. add_insns (buf, sizeof buf);
  1391. }
  1392. /* The "emit_rsh_signed" emit_ops method for s390. */
  1393. static void
  1394. s390_emit_rsh_signed (void)
  1395. {
  1396. static const unsigned char buf[] = {
  1397. 0x18, 0x43, /* lr %r4, %r3 */
  1398. 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
  1399. 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
  1400. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1401. };
  1402. add_insns (buf, sizeof buf);
  1403. }
  1404. /* The "emit_rsh_unsigned" emit_ops method for s390. */
  1405. static void
  1406. s390_emit_rsh_unsigned (void)
  1407. {
  1408. static const unsigned char buf[] = {
  1409. 0x18, 0x43, /* lr %r4, %r3 */
  1410. 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
  1411. 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
  1412. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1413. };
  1414. add_insns (buf, sizeof buf);
  1415. }
  1416. /* The "emit_ext" emit_ops method for s390. */
  1417. static void
  1418. s390_emit_ext (int arg)
  1419. {
  1420. unsigned char buf[] = {
  1421. 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
  1422. 0x8e, 0x20, 0x00, (unsigned char) (64 - arg), /* srda %r2, <64-arg> */
  1423. };
  1424. add_insns (buf, sizeof buf);
  1425. }
  1426. /* The "emit_log_not" emit_ops method for s390. */
  1427. static void
  1428. s390_emit_log_not (void)
  1429. {
  1430. static const unsigned char buf[] = {
  1431. 0x16, 0x23, /* or %r2, %r3 */
  1432. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1433. 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
  1434. 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
  1435. 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
  1436. /* .Lskip: */
  1437. };
  1438. add_insns (buf, sizeof buf);
  1439. }
  1440. /* The "emit_bit_and" emit_ops method for s390. */
  1441. static void
  1442. s390_emit_bit_and (void)
  1443. {
  1444. static const unsigned char buf[] = {
  1445. 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
  1446. 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
  1447. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1448. };
  1449. add_insns (buf, sizeof buf);
  1450. }
  1451. /* The "emit_bit_or" emit_ops method for s390. */
  1452. static void
  1453. s390_emit_bit_or (void)
  1454. {
  1455. static const unsigned char buf[] = {
  1456. 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
  1457. 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
  1458. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1459. };
  1460. add_insns (buf, sizeof buf);
  1461. }
  1462. /* The "emit_bit_xor" emit_ops method for s390. */
  1463. static void
  1464. s390_emit_bit_xor (void)
  1465. {
  1466. static const unsigned char buf[] = {
  1467. 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
  1468. 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
  1469. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1470. };
  1471. add_insns (buf, sizeof buf);
  1472. }
  1473. /* The "emit_bit_not" emit_ops method for s390. */
  1474. static void
  1475. s390_emit_bit_not (void)
  1476. {
  1477. static const unsigned char buf[] = {
  1478. 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
  1479. 0x17, 0x24, /* xr %r2, %r4 */
  1480. 0x17, 0x34, /* xr %r3, %r4 */
  1481. };
  1482. add_insns (buf, sizeof buf);
  1483. }
  1484. /* The "emit_equal" emit_ops method for s390. */
  1485. static void
  1486. s390_emit_equal (void)
  1487. {
  1488. s390_emit_bit_xor ();
  1489. s390_emit_log_not ();
  1490. }
  1491. /* The "emit_less_signed" emit_ops method for s390. */
  1492. static void
  1493. s390_emit_less_signed (void)
  1494. {
  1495. static const unsigned char buf[] = {
  1496. 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
  1497. 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
  1498. 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
  1499. 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
  1500. 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
  1501. /* .Lhigh: */
  1502. 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
  1503. 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
  1504. /* .Lless: */
  1505. 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
  1506. /* .Lend: */
  1507. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1508. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1509. };
  1510. add_insns (buf, sizeof buf);
  1511. }
  1512. /* The "emit_less_unsigned" emit_ops method for s390. */
  1513. static void
  1514. s390_emit_less_unsigned (void)
  1515. {
  1516. static const unsigned char buf[] = {
  1517. 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
  1518. 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
  1519. 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
  1520. 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
  1521. 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
  1522. /* .Lhigh: */
  1523. 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
  1524. 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
  1525. /* .Lless: */
  1526. 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
  1527. /* .Lend: */
  1528. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1529. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1530. };
  1531. add_insns (buf, sizeof buf);
  1532. }
  1533. /* The "emit_ref" emit_ops method for s390. */
  1534. static void
  1535. s390_emit_ref (int size)
  1536. {
  1537. static const unsigned char buf1[] = {
  1538. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1539. 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
  1540. };
  1541. static const unsigned char buf2[] = {
  1542. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1543. 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
  1544. };
  1545. static const unsigned char buf4[] = {
  1546. 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
  1547. 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
  1548. };
  1549. static const unsigned char buf8[] = {
  1550. 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
  1551. };
  1552. switch (size)
  1553. {
  1554. case 1:
  1555. add_insns (buf1, sizeof buf1);
  1556. break;
  1557. case 2:
  1558. add_insns (buf2, sizeof buf2);
  1559. break;
  1560. case 4:
  1561. add_insns (buf4, sizeof buf4);
  1562. break;
  1563. case 8:
  1564. add_insns (buf8, sizeof buf8);
  1565. break;
  1566. default:
  1567. emit_error = 1;
  1568. }
  1569. }
  1570. /* The "emit_if_goto" emit_ops method for s390. */
  1571. static void
  1572. s390_emit_if_goto (int *offset_p, int *size_p)
  1573. {
  1574. static const unsigned char buf[] = {
  1575. 0x16, 0x23, /* or %r2, %r3 */
  1576. 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
  1577. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1578. 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
  1579. };
  1580. add_insns (buf, sizeof buf);
  1581. if (offset_p)
  1582. *offset_p = 12;
  1583. if (size_p)
  1584. *size_p = 4;
  1585. }
  1586. /* The "emit_goto" emit_ops method for s390 and s390x. */
  1587. static void
  1588. s390_emit_goto (int *offset_p, int *size_p)
  1589. {
  1590. static const unsigned char buf[] = {
  1591. 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
  1592. };
  1593. add_insns (buf, sizeof buf);
  1594. if (offset_p)
  1595. *offset_p = 2;
  1596. if (size_p)
  1597. *size_p = 4;
  1598. }
  1599. /* The "write_goto_address" emit_ops method for s390 and s390x. */
  1600. static void
  1601. s390_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
  1602. {
  1603. long diff = ((long) (to - (from - 2))) / 2;
  1604. int sdiff = diff;
  1605. unsigned char buf[sizeof sdiff];
  1606. /* We're only doing 4-byte sizes at the moment. */
  1607. if (size != sizeof sdiff || sdiff != diff)
  1608. {
  1609. emit_error = 1;
  1610. return;
  1611. }
  1612. memcpy (buf, &sdiff, sizeof sdiff);
  1613. target_write_memory (from, buf, sizeof sdiff);
  1614. }
  1615. /* Preparation for emitting a literal pool of given size. Loads the address
  1616. of the pool into %r1, and jumps over it. Called should emit the pool data
  1617. immediately afterwards. Used for both s390 and s390x. */
  1618. static void
  1619. s390_emit_litpool (int size)
  1620. {
  1621. static const unsigned char nop[] = {
  1622. 0x07, 0x07,
  1623. };
  1624. unsigned char buf[] = {
  1625. 0xa7, 0x15, 0x00,
  1626. (unsigned char) ((size + 4) / 2), /* bras %r1, .Lend+size */
  1627. /* .Lend: */
  1628. };
  1629. if (size == 4)
  1630. {
  1631. /* buf needs to start at even halfword for litpool to be aligned */
  1632. if (current_insn_ptr & 2)
  1633. add_insns (nop, sizeof nop);
  1634. }
  1635. else
  1636. {
  1637. while ((current_insn_ptr & 6) != 4)
  1638. add_insns (nop, sizeof nop);
  1639. }
  1640. add_insns (buf, sizeof buf);
  1641. }
  1642. /* The "emit_const" emit_ops method for s390. */
  1643. static void
  1644. s390_emit_const (LONGEST num)
  1645. {
  1646. unsigned long long n = num;
  1647. unsigned char buf_s[] = {
  1648. /* lhi %r3, <num> */
  1649. 0xa7, 0x38,
  1650. (unsigned char) (num >> 8), (unsigned char) num,
  1651. /* xr %r2, %r2 */
  1652. 0x17, 0x22,
  1653. };
  1654. static const unsigned char buf_l[] = {
  1655. 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
  1656. };
  1657. if (num < 0x8000 && num >= 0)
  1658. add_insns (buf_s, sizeof buf_s);
  1659. else
  1660. {
  1661. s390_emit_litpool (8);
  1662. add_insns ((unsigned char *) &n, sizeof n);
  1663. add_insns (buf_l, sizeof buf_l);
  1664. }
  1665. }
  1666. /* The "emit_call" emit_ops method for s390. */
  1667. static void
  1668. s390_emit_call (CORE_ADDR fn)
  1669. {
  1670. unsigned int n = fn;
  1671. static const unsigned char buf[] = {
  1672. 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
  1673. 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
  1674. 0x0d, 0xe1, /* basr %r14, %r1 */
  1675. 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
  1676. };
  1677. s390_emit_litpool (4);
  1678. add_insns ((unsigned char *) &n, sizeof n);
  1679. add_insns (buf, sizeof buf);
  1680. }
  1681. /* The "emit_reg" emit_ops method for s390. */
  1682. static void
  1683. s390_emit_reg (int reg)
  1684. {
  1685. unsigned char bufpre[] = {
  1686. /* lr %r2, %r9 */
  1687. 0x18, 0x29,
  1688. /* lhi %r3, <reg> */
  1689. 0xa7, 0x38, (unsigned char) (reg >> 8), (unsigned char) reg,
  1690. };
  1691. add_insns (bufpre, sizeof bufpre);
  1692. s390_emit_call (get_raw_reg_func_addr ());
  1693. }
  1694. /* The "emit_pop" emit_ops method for s390. */
  1695. static void
  1696. s390_emit_pop (void)
  1697. {
  1698. static const unsigned char buf[] = {
  1699. 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
  1700. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  1701. };
  1702. add_insns (buf, sizeof buf);
  1703. }
  1704. /* The "emit_stack_flush" emit_ops method for s390. */
  1705. static void
  1706. s390_emit_stack_flush (void)
  1707. {
  1708. static const unsigned char buf[] = {
  1709. 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
  1710. 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
  1711. };
  1712. add_insns (buf, sizeof buf);
  1713. }
  1714. /* The "emit_zero_ext" emit_ops method for s390. */
  1715. static void
  1716. s390_emit_zero_ext (int arg)
  1717. {
  1718. unsigned char buf[] = {
  1719. 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
  1720. 0x8c, 0x20, 0x00, (unsigned char) (64 - arg), /* srdl %r2, <64-arg> */
  1721. };
  1722. add_insns (buf, sizeof buf);
  1723. }
  1724. /* The "emit_swap" emit_ops method for s390. */
  1725. static void
  1726. s390_emit_swap (void)
  1727. {
  1728. static const unsigned char buf[] = {
  1729. 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
  1730. 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
  1731. 0x18, 0x24, /* lr %r2, %r4 */
  1732. 0x18, 0x35, /* lr %r3, %r5 */
  1733. };
  1734. add_insns (buf, sizeof buf);
  1735. }
  1736. /* The "emit_stack_adjust" emit_ops method for s390. */
  1737. static void
  1738. s390_emit_stack_adjust (int n)
  1739. {
  1740. unsigned char buf[] = {
  1741. /* ahi %r15, 8*n */
  1742. 0xa7, 0xfa,
  1743. (unsigned char ) (n * 8 >> 8), (unsigned char) (n * 8),
  1744. };
  1745. add_insns (buf, sizeof buf);
  1746. }
  1747. /* Sets %r2 to a 32-bit constant. */
  1748. static void
  1749. s390_emit_set_r2 (int arg1)
  1750. {
  1751. unsigned char buf_s[] = {
  1752. /* lhi %r2, <arg1> */
  1753. 0xa7, 0x28, (unsigned char) (arg1 >> 8), (unsigned char) arg1,
  1754. };
  1755. static const unsigned char buf_l[] = {
  1756. 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
  1757. };
  1758. if (arg1 < 0x8000 && arg1 >= -0x8000)
  1759. add_insns (buf_s, sizeof buf_s);
  1760. else
  1761. {
  1762. s390_emit_litpool (4);
  1763. add_insns ((unsigned char *) &arg1, sizeof arg1);
  1764. add_insns (buf_l, sizeof buf_l);
  1765. }
  1766. }
  1767. /* The "emit_int_call_1" emit_ops method for s390. */
  1768. static void
  1769. s390_emit_int_call_1 (CORE_ADDR fn, int arg1)
  1770. {
  1771. /* FN's prototype is `LONGEST(*fn)(int)'. */
  1772. s390_emit_set_r2 (arg1);
  1773. s390_emit_call (fn);
  1774. }
  1775. /* The "emit_void_call_2" emit_ops method for s390. */
  1776. static void
  1777. s390_emit_void_call_2 (CORE_ADDR fn, int arg1)
  1778. {
  1779. /* FN's prototype is `void(*fn)(int,LONGEST)'. */
  1780. static const unsigned char buf[] = {
  1781. 0x18, 0xc2, /* lr %r12, %r2 */
  1782. 0x18, 0xd3, /* lr %r13, %r3 */
  1783. 0x18, 0x43, /* lr %r4, %r3 */
  1784. 0x18, 0x32, /* lr %r3, %r2 */
  1785. };
  1786. static const unsigned char buf2[] = {
  1787. 0x18, 0x2c, /* lr %r2, %r12 */
  1788. 0x18, 0x3d, /* lr %r3, %r13 */
  1789. };
  1790. add_insns (buf, sizeof buf);
  1791. s390_emit_set_r2 (arg1);
  1792. s390_emit_call (fn);
  1793. add_insns (buf2, sizeof buf2);
  1794. }
  1795. /* The "emit_eq_goto" emit_ops method for s390. */
  1796. static void
  1797. s390_emit_eq_goto (int *offset_p, int *size_p)
  1798. {
  1799. static const unsigned char buf[] = {
  1800. 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
  1801. 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
  1802. 0x16, 0x23, /* or %r2, %r3 */
  1803. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1804. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1805. 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
  1806. };
  1807. add_insns (buf, sizeof buf);
  1808. if (offset_p)
  1809. *offset_p = 20;
  1810. if (size_p)
  1811. *size_p = 4;
  1812. }
  1813. /* The "emit_ne_goto" emit_ops method for s390. */
  1814. static void
  1815. s390_emit_ne_goto (int *offset_p, int *size_p)
  1816. {
  1817. static const unsigned char buf[] = {
  1818. 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
  1819. 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
  1820. 0x16, 0x23, /* or %r2, %r3 */
  1821. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1822. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1823. 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
  1824. };
  1825. add_insns (buf, sizeof buf);
  1826. if (offset_p)
  1827. *offset_p = 20;
  1828. if (size_p)
  1829. *size_p = 4;
  1830. }
  1831. /* The "emit_lt_goto" emit_ops method for s390. */
  1832. static void
  1833. s390_emit_lt_goto (int *offset_p, int *size_p)
  1834. {
  1835. static const unsigned char buf[] = {
  1836. 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
  1837. 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
  1838. 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
  1839. 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
  1840. 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
  1841. /* .Lfalse: */
  1842. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1843. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1844. 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
  1845. /* .Ltrue: */
  1846. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1847. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1848. 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
  1849. /* .Lend: */
  1850. };
  1851. add_insns (buf, sizeof buf);
  1852. if (offset_p)
  1853. *offset_p = 42;
  1854. if (size_p)
  1855. *size_p = 4;
  1856. }
  1857. /* The "emit_le_goto" emit_ops method for s390. */
  1858. static void
  1859. s390_emit_le_goto (int *offset_p, int *size_p)
  1860. {
  1861. static const unsigned char buf[] = {
  1862. 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
  1863. 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
  1864. 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
  1865. 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
  1866. 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
  1867. /* .Lfalse: */
  1868. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1869. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1870. 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
  1871. /* .Ltrue: */
  1872. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1873. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1874. 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
  1875. /* .Lend: */
  1876. };
  1877. add_insns (buf, sizeof buf);
  1878. if (offset_p)
  1879. *offset_p = 42;
  1880. if (size_p)
  1881. *size_p = 4;
  1882. }
  1883. /* The "emit_gt_goto" emit_ops method for s390. */
  1884. static void
  1885. s390_emit_gt_goto (int *offset_p, int *size_p)
  1886. {
  1887. static const unsigned char buf[] = {
  1888. 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
  1889. 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
  1890. 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
  1891. 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
  1892. 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
  1893. /* .Lfalse: */
  1894. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1895. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1896. 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
  1897. /* .Ltrue: */
  1898. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1899. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1900. 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
  1901. /* .Lend: */
  1902. };
  1903. add_insns (buf, sizeof buf);
  1904. if (offset_p)
  1905. *offset_p = 42;
  1906. if (size_p)
  1907. *size_p = 4;
  1908. }
  1909. /* The "emit_ge_goto" emit_ops method for s390. */
  1910. static void
  1911. s390_emit_ge_goto (int *offset_p, int *size_p)
  1912. {
  1913. static const unsigned char buf[] = {
  1914. 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
  1915. 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
  1916. 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
  1917. 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
  1918. 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
  1919. /* .Lfalse: */
  1920. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1921. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1922. 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
  1923. /* .Ltrue: */
  1924. 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
  1925. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  1926. 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
  1927. /* .Lend: */
  1928. };
  1929. add_insns (buf, sizeof buf);
  1930. if (offset_p)
  1931. *offset_p = 42;
  1932. if (size_p)
  1933. *size_p = 4;
  1934. }
  1935. /* The "emit_ops" structure for s390. Named _impl to avoid name
  1936. collision with s390_emit_ops function. */
  1937. static struct emit_ops s390_emit_ops_impl =
  1938. {
  1939. s390_emit_prologue,
  1940. s390_emit_epilogue,
  1941. s390_emit_add,
  1942. s390_emit_sub,
  1943. s390_emit_mul,
  1944. s390_emit_lsh,
  1945. s390_emit_rsh_signed,
  1946. s390_emit_rsh_unsigned,
  1947. s390_emit_ext,
  1948. s390_emit_log_not,
  1949. s390_emit_bit_and,
  1950. s390_emit_bit_or,
  1951. s390_emit_bit_xor,
  1952. s390_emit_bit_not,
  1953. s390_emit_equal,
  1954. s390_emit_less_signed,
  1955. s390_emit_less_unsigned,
  1956. s390_emit_ref,
  1957. s390_emit_if_goto,
  1958. s390_emit_goto,
  1959. s390_write_goto_address,
  1960. s390_emit_const,
  1961. s390_emit_call,
  1962. s390_emit_reg,
  1963. s390_emit_pop,
  1964. s390_emit_stack_flush,
  1965. s390_emit_zero_ext,
  1966. s390_emit_swap,
  1967. s390_emit_stack_adjust,
  1968. s390_emit_int_call_1,
  1969. s390_emit_void_call_2,
  1970. s390_emit_eq_goto,
  1971. s390_emit_ne_goto,
  1972. s390_emit_lt_goto,
  1973. s390_emit_le_goto,
  1974. s390_emit_gt_goto,
  1975. s390_emit_ge_goto
  1976. };
  1977. #ifdef __s390x__
  1978. /* The "emit_prologue" emit_ops method for s390x. */
  1979. static void
  1980. s390x_emit_prologue (void)
  1981. {
  1982. static const unsigned char buf[] = {
  1983. 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
  1984. 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
  1985. 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
  1986. 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
  1987. };
  1988. add_insns (buf, sizeof buf);
  1989. }
  1990. /* The "emit_epilogue" emit_ops method for s390x. */
  1991. static void
  1992. s390x_emit_epilogue (void)
  1993. {
  1994. static const unsigned char buf[] = {
  1995. 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
  1996. 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
  1997. 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
  1998. 0x07, 0xfe, /* br %r14 */
  1999. };
  2000. add_insns (buf, sizeof buf);
  2001. }
  2002. /* The "emit_add" emit_ops method for s390x. */
  2003. static void
  2004. s390x_emit_add (void)
  2005. {
  2006. static const unsigned char buf[] = {
  2007. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
  2008. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2009. };
  2010. add_insns (buf, sizeof buf);
  2011. }
  2012. /* The "emit_sub" emit_ops method for s390x. */
  2013. static void
  2014. s390x_emit_sub (void)
  2015. {
  2016. static const unsigned char buf[] = {
  2017. 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
  2018. 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
  2019. 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
  2020. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2021. };
  2022. add_insns (buf, sizeof buf);
  2023. }
  2024. /* The "emit_mul" emit_ops method for s390x. */
  2025. static void
  2026. s390x_emit_mul (void)
  2027. {
  2028. emit_error = 1;
  2029. }
  2030. /* The "emit_lsh" emit_ops method for s390x. */
  2031. static void
  2032. s390x_emit_lsh (void)
  2033. {
  2034. static const unsigned char buf[] = {
  2035. 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
  2036. 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
  2037. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2038. };
  2039. add_insns (buf, sizeof buf);
  2040. }
  2041. /* The "emit_rsh_signed" emit_ops method for s390x. */
  2042. static void
  2043. s390x_emit_rsh_signed (void)
  2044. {
  2045. static const unsigned char buf[] = {
  2046. 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
  2047. 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
  2048. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2049. };
  2050. add_insns (buf, sizeof buf);
  2051. }
  2052. /* The "emit_rsh_unsigned" emit_ops method for s390x. */
  2053. static void
  2054. s390x_emit_rsh_unsigned (void)
  2055. {
  2056. static const unsigned char buf[] = {
  2057. 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
  2058. 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
  2059. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2060. };
  2061. add_insns (buf, sizeof buf);
  2062. }
  2063. /* The "emit_ext" emit_ops method for s390x. */
  2064. static void
  2065. s390x_emit_ext (int arg)
  2066. {
  2067. unsigned char buf[] = {
  2068. /* sllg %r2, %r2, <64-arg> */
  2069. 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
  2070. /* srag %r2, %r2, <64-arg> */
  2071. 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0a,
  2072. };
  2073. add_insns (buf, sizeof buf);
  2074. }
  2075. /* The "emit_log_not" emit_ops method for s390x. */
  2076. static void
  2077. s390x_emit_log_not (void)
  2078. {
  2079. static const unsigned char buf[] = {
  2080. 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
  2081. 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
  2082. 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
  2083. };
  2084. add_insns (buf, sizeof buf);
  2085. }
  2086. /* The "emit_bit_and" emit_ops method for s390x. */
  2087. static void
  2088. s390x_emit_bit_and (void)
  2089. {
  2090. static const unsigned char buf[] = {
  2091. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
  2092. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2093. };
  2094. add_insns (buf, sizeof buf);
  2095. }
  2096. /* The "emit_bit_or" emit_ops method for s390x. */
  2097. static void
  2098. s390x_emit_bit_or (void)
  2099. {
  2100. static const unsigned char buf[] = {
  2101. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
  2102. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2103. };
  2104. add_insns (buf, sizeof buf);
  2105. }
  2106. /* The "emit_bit_xor" emit_ops method for s390x. */
  2107. static void
  2108. s390x_emit_bit_xor (void)
  2109. {
  2110. static const unsigned char buf[] = {
  2111. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
  2112. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2113. };
  2114. add_insns (buf, sizeof buf);
  2115. }
  2116. /* The "emit_bit_not" emit_ops method for s390x. */
  2117. static void
  2118. s390x_emit_bit_not (void)
  2119. {
  2120. static const unsigned char buf[] = {
  2121. 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
  2122. 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
  2123. };
  2124. add_insns (buf, sizeof buf);
  2125. }
  2126. /* The "emit_equal" emit_ops method for s390x. */
  2127. static void
  2128. s390x_emit_equal (void)
  2129. {
  2130. s390x_emit_bit_xor ();
  2131. s390x_emit_log_not ();
  2132. }
  2133. /* The "emit_less_signed" emit_ops method for s390x. */
  2134. static void
  2135. s390x_emit_less_signed (void)
  2136. {
  2137. static const unsigned char buf[] = {
  2138. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2139. 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
  2140. 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
  2141. 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
  2142. /* .Lend: */
  2143. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2144. };
  2145. add_insns (buf, sizeof buf);
  2146. }
  2147. /* The "emit_less_unsigned" emit_ops method for s390x. */
  2148. static void
  2149. s390x_emit_less_unsigned (void)
  2150. {
  2151. static const unsigned char buf[] = {
  2152. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
  2153. 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
  2154. 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
  2155. 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
  2156. /* .Lend: */
  2157. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2158. };
  2159. add_insns (buf, sizeof buf);
  2160. }
  2161. /* The "emit_ref" emit_ops method for s390x. */
  2162. static void
  2163. s390x_emit_ref (int size)
  2164. {
  2165. static const unsigned char buf1[] = {
  2166. 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
  2167. };
  2168. static const unsigned char buf2[] = {
  2169. 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
  2170. };
  2171. static const unsigned char buf4[] = {
  2172. 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
  2173. };
  2174. static const unsigned char buf8[] = {
  2175. 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
  2176. };
  2177. switch (size)
  2178. {
  2179. case 1:
  2180. add_insns (buf1, sizeof buf1);
  2181. break;
  2182. case 2:
  2183. add_insns (buf2, sizeof buf2);
  2184. break;
  2185. case 4:
  2186. add_insns (buf4, sizeof buf4);
  2187. break;
  2188. case 8:
  2189. add_insns (buf8, sizeof buf8);
  2190. break;
  2191. default:
  2192. emit_error = 1;
  2193. }
  2194. }
  2195. /* The "emit_if_goto" emit_ops method for s390x. */
  2196. static void
  2197. s390x_emit_if_goto (int *offset_p, int *size_p)
  2198. {
  2199. static const unsigned char buf[] = {
  2200. 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
  2201. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
  2202. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2203. 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
  2204. };
  2205. add_insns (buf, sizeof buf);
  2206. if (offset_p)
  2207. *offset_p = 16;
  2208. if (size_p)
  2209. *size_p = 4;
  2210. }
  2211. /* The "emit_const" emit_ops method for s390x. */
  2212. static void
  2213. s390x_emit_const (LONGEST num)
  2214. {
  2215. unsigned long long n = num;
  2216. unsigned char buf_s[] = {
  2217. /* lghi %r2, <num> */
  2218. 0xa7, 0x29, (unsigned char) (num >> 8), (unsigned char) num,
  2219. };
  2220. static const unsigned char buf_l[] = {
  2221. 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
  2222. };
  2223. if (num < 0x8000 && num >= -0x8000)
  2224. add_insns (buf_s, sizeof buf_s);
  2225. else
  2226. {
  2227. s390_emit_litpool (8);
  2228. add_insns ((unsigned char *) &n, sizeof n);
  2229. add_insns (buf_l, sizeof buf_l);
  2230. }
  2231. }
  2232. /* The "emit_call" emit_ops method for s390x. */
  2233. static void
  2234. s390x_emit_call (CORE_ADDR fn)
  2235. {
  2236. unsigned long n = fn;
  2237. static const unsigned char buf[] = {
  2238. 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
  2239. 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
  2240. 0x0d, 0xe1, /* basr %r14, %r1 */
  2241. 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
  2242. };
  2243. s390_emit_litpool (8);
  2244. add_insns ((unsigned char *) &n, sizeof n);
  2245. add_insns (buf, sizeof buf);
  2246. }
  2247. /* The "emit_reg" emit_ops method for s390x. */
  2248. static void
  2249. s390x_emit_reg (int reg)
  2250. {
  2251. unsigned char buf[] = {
  2252. /* lgr %r2, %r9 */
  2253. 0xb9, 0x04, 0x00, 0x29,
  2254. /* lghi %r3, <reg> */
  2255. 0xa7, 0x39, (unsigned char) (reg >> 8), (unsigned char) reg,
  2256. };
  2257. add_insns (buf, sizeof buf);
  2258. s390x_emit_call (get_raw_reg_func_addr ());
  2259. }
  2260. /* The "emit_pop" emit_ops method for s390x. */
  2261. static void
  2262. s390x_emit_pop (void)
  2263. {
  2264. static const unsigned char buf[] = {
  2265. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
  2266. 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
  2267. };
  2268. add_insns (buf, sizeof buf);
  2269. }
  2270. /* The "emit_stack_flush" emit_ops method for s390x. */
  2271. static void
  2272. s390x_emit_stack_flush (void)
  2273. {
  2274. static const unsigned char buf[] = {
  2275. 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
  2276. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
  2277. };
  2278. add_insns (buf, sizeof buf);
  2279. }
  2280. /* The "emit_zero_ext" emit_ops method for s390x. */
  2281. static void
  2282. s390x_emit_zero_ext (int arg)
  2283. {
  2284. unsigned char buf[] = {
  2285. /* sllg %r2, %r2, <64-arg> */
  2286. 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
  2287. /* srlg %r2, %r2, <64-arg> */
  2288. 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0c,
  2289. };
  2290. add_insns (buf, sizeof buf);
  2291. }
  2292. /* The "emit_swap" emit_ops method for s390x. */
  2293. static void
  2294. s390x_emit_swap (void)
  2295. {
  2296. static const unsigned char buf[] = {
  2297. 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
  2298. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
  2299. 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
  2300. };
  2301. add_insns (buf, sizeof buf);
  2302. }
  2303. /* The "emit_stack_adjust" emit_ops method for s390x. */
  2304. static void
  2305. s390x_emit_stack_adjust (int n)
  2306. {
  2307. unsigned char buf[] = {
  2308. /* aghi %r15, 8*n */
  2309. 0xa7, 0xfb,
  2310. (unsigned char) (n * 8 >> 8), (unsigned char) (n * 8),
  2311. };
  2312. add_insns (buf, sizeof buf);
  2313. }
  2314. /* The "emit_int_call_1" emit_ops method for s390x. */
  2315. static void
  2316. s390x_emit_int_call_1 (CORE_ADDR fn, int arg1)
  2317. {
  2318. /* FN's prototype is `LONGEST(*fn)(int)'. */
  2319. s390x_emit_const (arg1);
  2320. s390x_emit_call (fn);
  2321. }
  2322. /* The "emit_void_call_2" emit_ops method for s390x. */
  2323. static void
  2324. s390x_emit_void_call_2 (CORE_ADDR fn, int arg1)
  2325. {
  2326. /* FN's prototype is `void(*fn)(int,LONGEST)'. */
  2327. static const unsigned char buf[] = {
  2328. 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
  2329. 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
  2330. };
  2331. static const unsigned char buf2[] = {
  2332. 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
  2333. };
  2334. add_insns (buf, sizeof buf);
  2335. s390x_emit_const (arg1);
  2336. s390x_emit_call (fn);
  2337. add_insns (buf2, sizeof buf2);
  2338. }
  2339. /* The "emit_eq_goto" emit_ops method for s390x. */
  2340. static void
  2341. s390x_emit_eq_goto (int *offset_p, int *size_p)
  2342. {
  2343. static const unsigned char buf[] = {
  2344. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2345. 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
  2346. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  2347. 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
  2348. };
  2349. add_insns (buf, sizeof buf);
  2350. if (offset_p)
  2351. *offset_p = 18;
  2352. if (size_p)
  2353. *size_p = 4;
  2354. }
  2355. /* The "emit_ne_goto" emit_ops method for s390x. */
  2356. static void
  2357. s390x_emit_ne_goto (int *offset_p, int *size_p)
  2358. {
  2359. static const unsigned char buf[] = {
  2360. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2361. 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
  2362. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  2363. 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
  2364. };
  2365. add_insns (buf, sizeof buf);
  2366. if (offset_p)
  2367. *offset_p = 18;
  2368. if (size_p)
  2369. *size_p = 4;
  2370. }
  2371. /* The "emit_lt_goto" emit_ops method for s390x. */
  2372. static void
  2373. s390x_emit_lt_goto (int *offset_p, int *size_p)
  2374. {
  2375. static const unsigned char buf[] = {
  2376. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2377. 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
  2378. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  2379. 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
  2380. };
  2381. add_insns (buf, sizeof buf);
  2382. if (offset_p)
  2383. *offset_p = 18;
  2384. if (size_p)
  2385. *size_p = 4;
  2386. }
  2387. /* The "emit_le_goto" emit_ops method for s390x. */
  2388. static void
  2389. s390x_emit_le_goto (int *offset_p, int *size_p)
  2390. {
  2391. static const unsigned char buf[] = {
  2392. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2393. 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
  2394. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  2395. 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
  2396. };
  2397. add_insns (buf, sizeof buf);
  2398. if (offset_p)
  2399. *offset_p = 18;
  2400. if (size_p)
  2401. *size_p = 4;
  2402. }
  2403. /* The "emit_gt_goto" emit_ops method for s390x. */
  2404. static void
  2405. s390x_emit_gt_goto (int *offset_p, int *size_p)
  2406. {
  2407. static const unsigned char buf[] = {
  2408. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2409. 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
  2410. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  2411. 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
  2412. };
  2413. add_insns (buf, sizeof buf);
  2414. if (offset_p)
  2415. *offset_p = 18;
  2416. if (size_p)
  2417. *size_p = 4;
  2418. }
  2419. /* The "emit_ge_goto" emit_ops method for s390x. */
  2420. static void
  2421. s390x_emit_ge_goto (int *offset_p, int *size_p)
  2422. {
  2423. static const unsigned char buf[] = {
  2424. 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
  2425. 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
  2426. 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
  2427. 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
  2428. };
  2429. add_insns (buf, sizeof buf);
  2430. if (offset_p)
  2431. *offset_p = 18;
  2432. if (size_p)
  2433. *size_p = 4;
  2434. }
  2435. /* The "emit_ops" structure for s390x. */
  2436. static struct emit_ops s390x_emit_ops =
  2437. {
  2438. s390x_emit_prologue,
  2439. s390x_emit_epilogue,
  2440. s390x_emit_add,
  2441. s390x_emit_sub,
  2442. s390x_emit_mul,
  2443. s390x_emit_lsh,
  2444. s390x_emit_rsh_signed,
  2445. s390x_emit_rsh_unsigned,
  2446. s390x_emit_ext,
  2447. s390x_emit_log_not,
  2448. s390x_emit_bit_and,
  2449. s390x_emit_bit_or,
  2450. s390x_emit_bit_xor,
  2451. s390x_emit_bit_not,
  2452. s390x_emit_equal,
  2453. s390x_emit_less_signed,
  2454. s390x_emit_less_unsigned,
  2455. s390x_emit_ref,
  2456. s390x_emit_if_goto,
  2457. s390_emit_goto,
  2458. s390_write_goto_address,
  2459. s390x_emit_const,
  2460. s390x_emit_call,
  2461. s390x_emit_reg,
  2462. s390x_emit_pop,
  2463. s390x_emit_stack_flush,
  2464. s390x_emit_zero_ext,
  2465. s390x_emit_swap,
  2466. s390x_emit_stack_adjust,
  2467. s390x_emit_int_call_1,
  2468. s390x_emit_void_call_2,
  2469. s390x_emit_eq_goto,
  2470. s390x_emit_ne_goto,
  2471. s390x_emit_lt_goto,
  2472. s390x_emit_le_goto,
  2473. s390x_emit_gt_goto,
  2474. s390x_emit_ge_goto
  2475. };
  2476. #endif
  2477. /* The "emit_ops" target ops method. */
  2478. emit_ops *
  2479. s390_target::emit_ops ()
  2480. {
  2481. #ifdef __s390x__
  2482. struct regcache *regcache = get_thread_regcache (current_thread, 0);
  2483. if (register_size (regcache->tdesc, 0) == 8)
  2484. return &s390x_emit_ops;
  2485. else
  2486. #endif
  2487. return &s390_emit_ops_impl;
  2488. }
  2489. /* The linux target ops object. */
  2490. linux_process_target *the_linux_target = &the_s390_target;
  2491. void
  2492. initialize_low_arch (void)
  2493. {
  2494. /* Initialize the Linux target descriptions. */
  2495. init_registers_s390_linux32 ();
  2496. init_registers_s390_linux32v1 ();
  2497. init_registers_s390_linux32v2 ();
  2498. init_registers_s390_linux64 ();
  2499. init_registers_s390_linux64v1 ();
  2500. init_registers_s390_linux64v2 ();
  2501. init_registers_s390_te_linux64 ();
  2502. init_registers_s390_vx_linux64 ();
  2503. init_registers_s390_tevx_linux64 ();
  2504. init_registers_s390_gs_linux64 ();
  2505. #ifdef __s390x__
  2506. init_registers_s390x_linux64 ();
  2507. init_registers_s390x_linux64v1 ();
  2508. init_registers_s390x_linux64v2 ();
  2509. init_registers_s390x_te_linux64 ();
  2510. init_registers_s390x_vx_linux64 ();
  2511. init_registers_s390x_tevx_linux64 ();
  2512. init_registers_s390x_gs_linux64 ();
  2513. #endif
  2514. initialize_regsets_info (&s390_regsets_info);
  2515. initialize_regsets_info (&s390_regsets_info_3264);
  2516. }