tc-microblaze.c 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573
  1. /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
  2. Copyright (C) 2009-2022 Free Software Foundation, Inc.
  3. This file is part of GAS, the GNU Assembler.
  4. GAS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. GAS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GAS; see the file COPYING. If not, write to the Free
  14. Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
  15. 02110-1301, USA. */
  16. #include "as.h"
  17. #include <stdio.h>
  18. #include "bfd.h"
  19. #include "subsegs.h"
  20. #define DEFINE_TABLE
  21. #include "../opcodes/microblaze-opc.h"
  22. #include "../opcodes/microblaze-opcm.h"
  23. #include "safe-ctype.h"
  24. #include <string.h>
  25. #include <dwarf2dbg.h>
  26. #include "aout/stab_gnu.h"
  27. #ifndef streq
  28. #define streq(a,b) (strcmp (a, b) == 0)
  29. #endif
  30. #define OPTION_EB (OPTION_MD_BASE + 0)
  31. #define OPTION_EL (OPTION_MD_BASE + 1)
  32. void microblaze_generate_symbol (char *sym);
  33. static bool check_spl_reg (unsigned *);
  34. /* Several places in this file insert raw instructions into the
  35. object. They should generate the instruction
  36. and then use these four macros to crack the instruction value into
  37. the appropriate byte values. */
  38. #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
  39. #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
  40. #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
  41. #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
  42. /* This array holds the chars that always start a comment. If the
  43. pre-processor is disabled, these aren't very useful. */
  44. const char comment_chars[] = "#";
  45. const char line_separator_chars[] = ";";
  46. /* This array holds the chars that only start a comment at the beginning of
  47. a line. */
  48. const char line_comment_chars[] = "#";
  49. const int md_reloc_size = 8; /* Size of relocation record. */
  50. /* Chars that can be used to separate mant
  51. from exp in floating point numbers. */
  52. const char EXP_CHARS[] = "eE";
  53. /* Chars that mean this number is a floating point constant
  54. As in 0f12.456
  55. or 0d1.2345e12. */
  56. const char FLT_CHARS[] = "rRsSfFdDxXpP";
  57. /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
  58. #define UNDEFINED_PC_OFFSET 2
  59. #define DEFINED_ABS_SEGMENT 3
  60. #define DEFINED_PC_OFFSET 4
  61. #define DEFINED_RO_SEGMENT 5
  62. #define DEFINED_RW_SEGMENT 6
  63. #define LARGE_DEFINED_PC_OFFSET 7
  64. #define GOT_OFFSET 8
  65. #define PLT_OFFSET 9
  66. #define GOTOFF_OFFSET 10
  67. #define TLSGD_OFFSET 11
  68. #define TLSLD_OFFSET 12
  69. #define TLSDTPMOD_OFFSET 13
  70. #define TLSDTPREL_OFFSET 14
  71. #define TLSGOTTPREL_OFFSET 15
  72. #define TLSTPREL_OFFSET 16
  73. #define TEXT_OFFSET 17
  74. #define TEXT_PC_OFFSET 18
  75. /* Initialize the relax table. */
  76. const relax_typeS md_relax_table[] =
  77. {
  78. { 1, 1, 0, 0 }, /* 0: Unused. */
  79. { 1, 1, 0, 0 }, /* 1: Unused. */
  80. { 1, 1, 0, 0 }, /* 2: Unused. */
  81. { 1, 1, 0, 0 }, /* 3: Unused. */
  82. { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */
  83. { 1, 1, 0, 0 }, /* 5: Unused. */
  84. { 1, 1, 0, 0 }, /* 6: Unused. */
  85. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
  86. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
  87. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
  88. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
  89. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 11: TLSGD_OFFSET. */
  90. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 12: TLSLD_OFFSET. */
  91. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
  92. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
  93. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
  94. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
  95. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
  96. { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
  97. };
  98. static htab_t opcode_hash_control; /* Opcode mnemonics. */
  99. static segT sbss_segment = 0; /* Small bss section. */
  100. static segT sbss2_segment = 0; /* Section not used. */
  101. static segT sdata_segment = 0; /* Small data section. */
  102. static segT sdata2_segment = 0; /* Small read-only section. */
  103. static segT rodata_segment = 0; /* read-only section. */
  104. /* Generate a symbol for stabs information. */
  105. void
  106. microblaze_generate_symbol (char *sym)
  107. {
  108. #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
  109. static int microblaze_label_count;
  110. sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
  111. ++microblaze_label_count;
  112. }
  113. /* Handle the section changing pseudo-ops. */
  114. static void
  115. microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
  116. {
  117. #ifdef OBJ_ELF
  118. obj_elf_text (ignore);
  119. #else
  120. s_text (ignore);
  121. #endif
  122. }
  123. static void
  124. microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
  125. {
  126. #ifdef OBJ_ELF
  127. obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE,
  128. 0, 0, 0, 0);
  129. #else
  130. s_data (ignore);
  131. #endif
  132. }
  133. /* Things in the .sdata segment are always considered to be in the small data section. */
  134. static void
  135. microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
  136. {
  137. #ifdef OBJ_ELF
  138. obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE,
  139. 0, 0, 0, 0);
  140. #else
  141. s_data (ignore);
  142. #endif
  143. }
  144. /* Pseudo op to make file scope bss items. */
  145. static void
  146. microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
  147. {
  148. char *name;
  149. char c;
  150. char *p;
  151. offsetT size;
  152. symbolS *symbolP;
  153. offsetT align;
  154. char *pfrag;
  155. int align2;
  156. segT current_seg = now_seg;
  157. subsegT current_subseg = now_subseg;
  158. c = get_symbol_name (&name);
  159. /* Just after name is now '\0'. */
  160. p = input_line_pointer;
  161. (void) restore_line_pointer (c);
  162. SKIP_WHITESPACE ();
  163. if (*input_line_pointer != ',')
  164. {
  165. as_bad (_("Expected comma after symbol-name: rest of line ignored."));
  166. ignore_rest_of_line ();
  167. return;
  168. }
  169. input_line_pointer++; /* skip ',' */
  170. if ((size = get_absolute_expression ()) < 0)
  171. {
  172. as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
  173. ignore_rest_of_line ();
  174. return;
  175. }
  176. /* The third argument to .lcomm is the alignment. */
  177. if (*input_line_pointer != ',')
  178. align = 8;
  179. else
  180. {
  181. ++input_line_pointer;
  182. align = get_absolute_expression ();
  183. if (align <= 0)
  184. {
  185. as_warn (_("ignoring bad alignment"));
  186. align = 8;
  187. }
  188. }
  189. *p = 0;
  190. symbolP = symbol_find_or_make (name);
  191. *p = c;
  192. if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
  193. {
  194. as_bad (_("Ignoring attempt to re-define symbol `%s'."),
  195. S_GET_NAME (symbolP));
  196. ignore_rest_of_line ();
  197. return;
  198. }
  199. if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
  200. {
  201. as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
  202. S_GET_NAME (symbolP),
  203. (long) S_GET_VALUE (symbolP),
  204. (long) size);
  205. ignore_rest_of_line ();
  206. return;
  207. }
  208. /* Allocate_bss. */
  209. if (align)
  210. {
  211. /* Convert to a power of 2 alignment. */
  212. for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
  213. if (align != 1)
  214. {
  215. as_bad (_("Common alignment not a power of 2"));
  216. ignore_rest_of_line ();
  217. return;
  218. }
  219. }
  220. else
  221. align2 = 0;
  222. record_alignment (current_seg, align2);
  223. subseg_set (current_seg, current_subseg);
  224. if (align2)
  225. frag_align (align2, 0, 0);
  226. if (S_GET_SEGMENT (symbolP) == current_seg)
  227. symbol_get_frag (symbolP)->fr_symbol = 0;
  228. symbol_set_frag (symbolP, frag_now);
  229. pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
  230. (char *) 0);
  231. *pfrag = 0;
  232. S_SET_SIZE (symbolP, size);
  233. S_SET_SEGMENT (symbolP, current_seg);
  234. subseg_set (current_seg, current_subseg);
  235. demand_empty_rest_of_line ();
  236. }
  237. static void
  238. microblaze_s_rdata (int localvar)
  239. {
  240. #ifdef OBJ_ELF
  241. if (localvar == 0)
  242. {
  243. /* rodata. */
  244. obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC,
  245. 0, 0, 0, 0);
  246. if (rodata_segment == 0)
  247. rodata_segment = subseg_new (".rodata", 0);
  248. }
  249. else
  250. {
  251. /* 1 .sdata2. */
  252. obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC,
  253. 0, 0, 0, 0);
  254. }
  255. #else
  256. s_data (ignore);
  257. #endif
  258. }
  259. static void
  260. microblaze_s_bss (int localvar)
  261. {
  262. #ifdef OBJ_ELF
  263. if (localvar == 0) /* bss. */
  264. obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE,
  265. 0, 0, 0, 0);
  266. else if (localvar == 1)
  267. {
  268. /* sbss. */
  269. obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE,
  270. 0, 0, 0, 0);
  271. if (sbss_segment == 0)
  272. sbss_segment = subseg_new (".sbss", 0);
  273. }
  274. #else
  275. s_data (ignore);
  276. #endif
  277. }
  278. /* endp_p is always 1 as this func is called only for .end <funcname>
  279. This func consumes the <funcname> and calls regular processing
  280. s_func(1) with arg 1 (1 for end). */
  281. static void
  282. microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
  283. {
  284. char *name;
  285. restore_line_pointer (get_symbol_name (&name));
  286. s_func (1);
  287. }
  288. /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
  289. static void
  290. microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
  291. {
  292. char *name;
  293. int c;
  294. symbolS *symbolP;
  295. expressionS exp;
  296. c = get_symbol_name (&name);
  297. symbolP = symbol_find_or_make (name);
  298. S_SET_WEAK (symbolP);
  299. (void) restore_line_pointer (c);
  300. SKIP_WHITESPACE ();
  301. if (!is_end_of_line[(unsigned char) *input_line_pointer])
  302. {
  303. if (S_IS_DEFINED (symbolP))
  304. {
  305. as_bad ("Ignoring attempt to redefine symbol `%s'.",
  306. S_GET_NAME (symbolP));
  307. ignore_rest_of_line ();
  308. return;
  309. }
  310. if (*input_line_pointer == ',')
  311. {
  312. ++input_line_pointer;
  313. SKIP_WHITESPACE ();
  314. }
  315. expression (&exp);
  316. if (exp.X_op != O_symbol)
  317. {
  318. as_bad ("bad .weakext directive");
  319. ignore_rest_of_line ();
  320. return;
  321. }
  322. symbol_set_value_expression (symbolP, &exp);
  323. }
  324. demand_empty_rest_of_line ();
  325. }
  326. /* This table describes all the machine specific pseudo-ops the assembler
  327. has to support. The fields are:
  328. Pseudo-op name without dot
  329. Function to call to execute this pseudo-op
  330. Integer arg to pass to the function. */
  331. /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
  332. and then in the read.c table. */
  333. const pseudo_typeS md_pseudo_table[] =
  334. {
  335. {"lcomm", microblaze_s_lcomm, 1},
  336. {"data", microblaze_s_data, 0},
  337. {"data8", cons, 1}, /* Same as byte. */
  338. {"data16", cons, 2}, /* Same as hword. */
  339. {"data32", cons, 4}, /* Same as word. */
  340. {"ent", s_func, 0}, /* Treat ent as function entry point. */
  341. {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
  342. {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
  343. {"weakext", microblaze_s_weakext, 0},
  344. {"rodata", microblaze_s_rdata, 0},
  345. {"sdata2", microblaze_s_rdata, 1},
  346. {"sdata", microblaze_s_sdata, 0},
  347. {"bss", microblaze_s_bss, 0},
  348. {"sbss", microblaze_s_bss, 1},
  349. {"text", microblaze_s_text, 0},
  350. {"word", cons, 4},
  351. {"frame", s_ignore, 0},
  352. {"mask", s_ignore, 0}, /* Emitted by gcc. */
  353. {NULL, NULL, 0}
  354. };
  355. /* This function is called once, at assembler startup time. This should
  356. set up all the tables, etc that the MD part of the assembler needs. */
  357. void
  358. md_begin (void)
  359. {
  360. const struct op_code_struct * opcode;
  361. opcode_hash_control = str_htab_create ();
  362. /* Insert unique names into hash table. */
  363. for (opcode = microblaze_opcodes; opcode->name; opcode ++)
  364. str_hash_insert (opcode_hash_control, opcode->name, opcode, 0);
  365. }
  366. /* Try to parse a reg name. */
  367. static char *
  368. parse_reg (char * s, unsigned * reg)
  369. {
  370. unsigned tmpreg = 0;
  371. /* Strip leading whitespace. */
  372. while (ISSPACE (* s))
  373. ++ s;
  374. if (strncasecmp (s, "rpc", 3) == 0)
  375. {
  376. *reg = REG_PC;
  377. return s + 3;
  378. }
  379. else if (strncasecmp (s, "rmsr", 4) == 0)
  380. {
  381. *reg = REG_MSR;
  382. return s + 4;
  383. }
  384. else if (strncasecmp (s, "rear", 4) == 0)
  385. {
  386. *reg = REG_EAR;
  387. return s + 4;
  388. }
  389. else if (strncasecmp (s, "resr", 4) == 0)
  390. {
  391. *reg = REG_ESR;
  392. return s + 4;
  393. }
  394. else if (strncasecmp (s, "rfsr", 4) == 0)
  395. {
  396. *reg = REG_FSR;
  397. return s + 4;
  398. }
  399. else if (strncasecmp (s, "rbtr", 4) == 0)
  400. {
  401. *reg = REG_BTR;
  402. return s + 4;
  403. }
  404. else if (strncasecmp (s, "redr", 4) == 0)
  405. {
  406. *reg = REG_EDR;
  407. return s + 4;
  408. }
  409. /* MMU registers start. */
  410. else if (strncasecmp (s, "rpid", 4) == 0)
  411. {
  412. *reg = REG_PID;
  413. return s + 4;
  414. }
  415. else if (strncasecmp (s, "rzpr", 4) == 0)
  416. {
  417. *reg = REG_ZPR;
  418. return s + 4;
  419. }
  420. else if (strncasecmp (s, "rtlbx", 5) == 0)
  421. {
  422. *reg = REG_TLBX;
  423. return s + 5;
  424. }
  425. else if (strncasecmp (s, "rtlblo", 6) == 0)
  426. {
  427. *reg = REG_TLBLO;
  428. return s + 6;
  429. }
  430. else if (strncasecmp (s, "rtlbhi", 6) == 0)
  431. {
  432. *reg = REG_TLBHI;
  433. return s + 6;
  434. }
  435. else if (strncasecmp (s, "rtlbsx", 6) == 0)
  436. {
  437. *reg = REG_TLBSX;
  438. return s + 6;
  439. }
  440. /* MMU registers end. */
  441. else if (strncasecmp (s, "rpvr", 4) == 0)
  442. {
  443. if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
  444. {
  445. tmpreg = (s[4]-'0')*10 + s[5] - '0';
  446. s += 6;
  447. }
  448. else if (ISDIGIT (s[4]))
  449. {
  450. tmpreg = s[4] - '0';
  451. s += 5;
  452. }
  453. else
  454. as_bad (_("register expected, but saw '%.6s'"), s);
  455. if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
  456. *reg = REG_PVR + tmpreg;
  457. else
  458. {
  459. as_bad (_("Invalid register number at '%.6s'"), s);
  460. *reg = REG_PVR;
  461. }
  462. return s;
  463. }
  464. else if (strncasecmp (s, "rsp", 3) == 0)
  465. {
  466. *reg = REG_SP;
  467. return s + 3;
  468. }
  469. else if (strncasecmp (s, "rfsl", 4) == 0)
  470. {
  471. if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
  472. {
  473. tmpreg = (s[4] - '0') * 10 + s[5] - '0';
  474. s += 6;
  475. }
  476. else if (ISDIGIT (s[4]))
  477. {
  478. tmpreg = s[4] - '0';
  479. s += 5;
  480. }
  481. else
  482. as_bad (_("register expected, but saw '%.6s'"), s);
  483. if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
  484. *reg = tmpreg;
  485. else
  486. {
  487. as_bad (_("Invalid register number at '%.6s'"), s);
  488. *reg = 0;
  489. }
  490. return s;
  491. }
  492. /* Stack protection registers. */
  493. else if (strncasecmp (s, "rshr", 4) == 0)
  494. {
  495. *reg = REG_SHR;
  496. return s + 4;
  497. }
  498. else if (strncasecmp (s, "rslr", 4) == 0)
  499. {
  500. *reg = REG_SLR;
  501. return s + 4;
  502. }
  503. else
  504. {
  505. if (TOLOWER (s[0]) == 'r')
  506. {
  507. if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
  508. {
  509. tmpreg = (s[1] - '0') * 10 + s[2] - '0';
  510. s += 3;
  511. }
  512. else if (ISDIGIT (s[1]))
  513. {
  514. tmpreg = s[1] - '0';
  515. s += 2;
  516. }
  517. else
  518. as_bad (_("register expected, but saw '%.6s'"), s);
  519. if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
  520. *reg = tmpreg;
  521. else
  522. {
  523. as_bad (_("Invalid register number at '%.6s'"), s);
  524. *reg = 0;
  525. }
  526. return s;
  527. }
  528. }
  529. as_bad (_("register expected, but saw '%.6s'"), s);
  530. *reg = 0;
  531. return s;
  532. }
  533. static char *
  534. parse_exp (char *s, expressionS *e)
  535. {
  536. char *save;
  537. char *new_pointer;
  538. /* Skip whitespace. */
  539. while (ISSPACE (* s))
  540. ++ s;
  541. save = input_line_pointer;
  542. input_line_pointer = s;
  543. expression (e);
  544. if (e->X_op == O_absent)
  545. as_fatal (_("missing operand"));
  546. new_pointer = input_line_pointer;
  547. input_line_pointer = save;
  548. return new_pointer;
  549. }
  550. /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
  551. #define IMM_NONE 0
  552. #define IMM_GOT 1
  553. #define IMM_PLT 2
  554. #define IMM_GOTOFF 3
  555. #define IMM_TLSGD 4
  556. #define IMM_TLSLD 5
  557. #define IMM_TLSDTPMOD 6
  558. #define IMM_TLSDTPREL 7
  559. #define IMM_TLSTPREL 8
  560. #define IMM_TXTREL 9
  561. #define IMM_TXTPCREL 10
  562. #define IMM_MAX 11
  563. struct imm_type {
  564. const char *isuffix; /* Suffix String */
  565. int itype; /* Suffix Type */
  566. int otype; /* Offset Type */
  567. };
  568. /* These are NOT in ascending order of type, GOTOFF is ahead to make
  569. sure @GOTOFF does not get matched with @GOT */
  570. static struct imm_type imm_types[] = {
  571. { "NONE", IMM_NONE , 0 },
  572. { "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET },
  573. { "GOT", IMM_GOT , GOT_OFFSET },
  574. { "PLT", IMM_PLT , PLT_OFFSET },
  575. { "TLSGD", IMM_TLSGD , TLSGD_OFFSET },
  576. { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET },
  577. { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET },
  578. { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET },
  579. { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET },
  580. { "TXTREL", IMM_TXTREL, TEXT_OFFSET },
  581. { "TXTPCREL", IMM_TXTPCREL, TEXT_PC_OFFSET }
  582. };
  583. static int
  584. match_imm (const char *s, int *ilen)
  585. {
  586. int i;
  587. int slen;
  588. /* Check for matching suffix */
  589. for (i = 1; i < IMM_MAX; i++)
  590. {
  591. slen = strlen (imm_types[i].isuffix);
  592. if (strncmp (imm_types[i].isuffix, s, slen) == 0)
  593. {
  594. *ilen = slen;
  595. return imm_types[i].itype;
  596. }
  597. } /* for */
  598. *ilen = 0;
  599. return 0;
  600. }
  601. static int
  602. get_imm_otype (int itype)
  603. {
  604. int i, otype;
  605. otype = 0;
  606. /* Check for matching itype */
  607. for (i = 1; i < IMM_MAX; i++)
  608. {
  609. if (imm_types[i].itype == itype)
  610. {
  611. otype = imm_types[i].otype;
  612. break;
  613. }
  614. }
  615. return otype;
  616. }
  617. static symbolS * GOT_symbol;
  618. #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
  619. static char *
  620. parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
  621. {
  622. char *new_pointer;
  623. char *atp;
  624. int itype, ilen;
  625. ilen = 0;
  626. /* Find the start of "@GOT" or "@PLT" suffix (if any) */
  627. for (atp = s; *atp != '@'; atp++)
  628. if (is_end_of_line[(unsigned char) *atp])
  629. break;
  630. if (*atp == '@')
  631. {
  632. itype = match_imm (atp + 1, &ilen);
  633. if (itype != 0)
  634. {
  635. *atp = 0;
  636. e->X_md = itype;
  637. }
  638. else
  639. {
  640. atp = NULL;
  641. e->X_md = 0;
  642. ilen = 0;
  643. }
  644. *atp = 0;
  645. }
  646. else
  647. {
  648. atp = NULL;
  649. e->X_md = 0;
  650. }
  651. if (atp && !GOT_symbol)
  652. {
  653. GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
  654. }
  655. new_pointer = parse_exp (s, e);
  656. if (!GOT_symbol && startswith (s, GOT_SYMBOL_NAME))
  657. {
  658. GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
  659. }
  660. if (e->X_op == O_absent)
  661. ; /* An error message has already been emitted. */
  662. else if ((e->X_op != O_constant && e->X_op != O_symbol) )
  663. as_fatal (_("operand must be a constant or a label"));
  664. else if (e->X_op == O_constant)
  665. {
  666. /* Special case: sign extend negative 32-bit values to offsetT size. */
  667. if ((e->X_add_number >> 31) == 1)
  668. e->X_add_number |= -((addressT) (1U << 31));
  669. if (e->X_add_number < min || e->X_add_number > max)
  670. {
  671. as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
  672. (long) min, (long) max, (long) e->X_add_number);
  673. }
  674. }
  675. if (atp)
  676. {
  677. *atp = '@'; /* restore back (needed?) */
  678. if (new_pointer >= atp)
  679. new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
  680. }
  681. return new_pointer;
  682. }
  683. static char *
  684. check_got (int * got_type, int * got_len)
  685. {
  686. char *new_pointer;
  687. char *atp;
  688. char *past_got;
  689. int first, second;
  690. char *tmpbuf;
  691. /* Find the start of "@GOT" or "@PLT" suffix (if any). */
  692. for (atp = input_line_pointer; *atp != '@'; atp++)
  693. if (is_end_of_line[(unsigned char) *atp])
  694. return NULL;
  695. if (startswith (atp + 1, "GOTOFF"))
  696. {
  697. *got_len = 6;
  698. *got_type = IMM_GOTOFF;
  699. }
  700. else if (startswith (atp + 1, "GOT"))
  701. {
  702. *got_len = 3;
  703. *got_type = IMM_GOT;
  704. }
  705. else if (startswith (atp + 1, "PLT"))
  706. {
  707. *got_len = 3;
  708. *got_type = IMM_PLT;
  709. }
  710. else
  711. return NULL;
  712. if (!GOT_symbol)
  713. GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
  714. first = atp - input_line_pointer;
  715. past_got = atp + *got_len + 1;
  716. for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
  717. ;
  718. second = new_pointer - past_got;
  719. /* One extra byte for ' ' and one for NUL. */
  720. tmpbuf = XNEWVEC (char, first + second + 2);
  721. memcpy (tmpbuf, input_line_pointer, first);
  722. tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
  723. memcpy (tmpbuf + first + 1, past_got, second);
  724. tmpbuf[first + second + 1] = '\0';
  725. return tmpbuf;
  726. }
  727. extern bfd_reloc_code_real_type
  728. parse_cons_expression_microblaze (expressionS *exp, int size)
  729. {
  730. if (size == 4)
  731. {
  732. /* Handle @GOTOFF et.al. */
  733. char *save, *gotfree_copy;
  734. int got_len, got_type;
  735. save = input_line_pointer;
  736. gotfree_copy = check_got (& got_type, & got_len);
  737. if (gotfree_copy)
  738. input_line_pointer = gotfree_copy;
  739. expression (exp);
  740. if (gotfree_copy)
  741. {
  742. exp->X_md = got_type;
  743. input_line_pointer = save + (input_line_pointer - gotfree_copy)
  744. + got_len;
  745. free (gotfree_copy);
  746. }
  747. }
  748. else
  749. expression (exp);
  750. return BFD_RELOC_NONE;
  751. }
  752. /* This is the guts of the machine-dependent assembler. STR points to a
  753. machine dependent instruction. This function is supposed to emit
  754. the frags/bytes it assembles to. */
  755. static const char * str_microblaze_ro_anchor = "RO";
  756. static const char * str_microblaze_rw_anchor = "RW";
  757. static bool
  758. check_spl_reg (unsigned * reg)
  759. {
  760. if ((*reg == REG_MSR) || (*reg == REG_PC)
  761. || (*reg == REG_EAR) || (*reg == REG_ESR)
  762. || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
  763. || (*reg == REG_PID) || (*reg == REG_ZPR)
  764. || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
  765. || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
  766. || (*reg == REG_SHR) || (*reg == REG_SLR)
  767. || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
  768. return true;
  769. return false;
  770. }
  771. /* Here we decide which fixups can be adjusted to make them relative to
  772. the beginning of the section instead of the symbol. Basically we need
  773. to make sure that the dynamic relocations are done correctly, so in
  774. some cases we force the original symbol to be used. */
  775. int
  776. tc_microblaze_fix_adjustable (struct fix *fixP)
  777. {
  778. if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
  779. return 0;
  780. if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
  781. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
  782. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
  783. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT
  784. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD
  785. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD
  786. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
  787. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL
  788. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL
  789. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
  790. || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL)
  791. return 0;
  792. return 1;
  793. }
  794. void
  795. md_assemble (char * str)
  796. {
  797. char * op_start;
  798. char * op_end;
  799. struct op_code_struct * opcode, *opcode1;
  800. char * output = NULL;
  801. int nlen = 0;
  802. int i;
  803. unsigned long inst, inst1;
  804. unsigned reg1;
  805. unsigned reg2;
  806. unsigned reg3;
  807. unsigned isize;
  808. unsigned int immed = 0, temp;
  809. expressionS exp;
  810. char name[20];
  811. /* Drop leading whitespace. */
  812. while (ISSPACE (* str))
  813. str ++;
  814. /* Find the op code end. */
  815. for (op_start = op_end = str;
  816. *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
  817. op_end++)
  818. {
  819. name[nlen] = op_start[nlen];
  820. nlen++;
  821. if (nlen == sizeof (name) - 1)
  822. break;
  823. }
  824. name [nlen] = 0;
  825. if (nlen == 0)
  826. {
  827. as_bad (_("can't find opcode "));
  828. return;
  829. }
  830. opcode = (struct op_code_struct *) str_hash_find (opcode_hash_control, name);
  831. if (opcode == NULL)
  832. {
  833. as_bad (_("unknown opcode \"%s\""), name);
  834. return;
  835. }
  836. inst = opcode->bit_sequence;
  837. isize = 4;
  838. switch (opcode->inst_type)
  839. {
  840. case INST_TYPE_RD_R1_R2:
  841. if (strcmp (op_end, ""))
  842. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  843. else
  844. {
  845. as_fatal (_("Error in statement syntax"));
  846. reg1 = 0;
  847. }
  848. if (strcmp (op_end, ""))
  849. op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
  850. else
  851. {
  852. as_fatal (_("Error in statement syntax"));
  853. reg2 = 0;
  854. }
  855. if (strcmp (op_end, ""))
  856. op_end = parse_reg (op_end + 1, &reg3); /* Get r2. */
  857. else
  858. {
  859. as_fatal (_("Error in statement syntax"));
  860. reg3 = 0;
  861. }
  862. /* Check for spl registers. */
  863. if (check_spl_reg (& reg1))
  864. as_fatal (_("Cannot use special register with this instruction"));
  865. if (check_spl_reg (& reg2))
  866. as_fatal (_("Cannot use special register with this instruction"));
  867. if (check_spl_reg (& reg3))
  868. as_fatal (_("Cannot use special register with this instruction"));
  869. if (streq (name, "sub"))
  870. {
  871. /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
  872. inst |= (reg1 << RD_LOW) & RD_MASK;
  873. inst |= (reg3 << RA_LOW) & RA_MASK;
  874. inst |= (reg2 << RB_LOW) & RB_MASK;
  875. }
  876. else
  877. {
  878. inst |= (reg1 << RD_LOW) & RD_MASK;
  879. inst |= (reg2 << RA_LOW) & RA_MASK;
  880. inst |= (reg3 << RB_LOW) & RB_MASK;
  881. }
  882. output = frag_more (isize);
  883. break;
  884. case INST_TYPE_RD_R1_IMM:
  885. if (strcmp (op_end, ""))
  886. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  887. else
  888. {
  889. as_fatal (_("Error in statement syntax"));
  890. reg1 = 0;
  891. }
  892. if (strcmp (op_end, ""))
  893. op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
  894. else
  895. {
  896. as_fatal (_("Error in statement syntax"));
  897. reg2 = 0;
  898. }
  899. if (strcmp (op_end, ""))
  900. op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
  901. else
  902. as_fatal (_("Error in statement syntax"));
  903. /* Check for spl registers. */
  904. if (check_spl_reg (& reg1))
  905. as_fatal (_("Cannot use special register with this instruction"));
  906. if (check_spl_reg (& reg2))
  907. as_fatal (_("Cannot use special register with this instruction"));
  908. if (exp.X_op != O_constant || exp.X_md == IMM_TXTPCREL)
  909. {
  910. const char *opc;
  911. relax_substateT subtype;
  912. if (streq (name, "lmi"))
  913. as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
  914. else if (streq (name, "smi"))
  915. as_fatal (_("smi pseudo instruction should not use a label in imm field"));
  916. if (reg2 == REG_ROSDP)
  917. opc = str_microblaze_ro_anchor;
  918. else if (reg2 == REG_RWSDP)
  919. opc = str_microblaze_rw_anchor;
  920. else
  921. opc = NULL;
  922. if (exp.X_md != 0)
  923. subtype = get_imm_otype(exp.X_md);
  924. else
  925. subtype = opcode->inst_offset_type;
  926. output = frag_var (rs_machine_dependent,
  927. isize * 2, /* maxm of 2 words. */
  928. isize, /* minm of 1 word. */
  929. subtype, /* PC-relative or not. */
  930. exp.X_add_symbol,
  931. exp.X_add_number,
  932. (char *) opc);
  933. immed = 0;
  934. }
  935. else
  936. {
  937. output = frag_more (isize);
  938. immed = exp.X_add_number;
  939. }
  940. if (streq (name, "lmi") || streq (name, "smi"))
  941. {
  942. /* Load/store 32-d consecutive registers. Used on exit/entry
  943. to subroutines to save and restore registers to stack.
  944. Generate 32-d insts. */
  945. int count;
  946. count = 32 - reg1;
  947. if (streq (name, "lmi"))
  948. opcode
  949. = (struct op_code_struct *) str_hash_find (opcode_hash_control,
  950. "lwi");
  951. else
  952. opcode
  953. = (struct op_code_struct *) str_hash_find (opcode_hash_control,
  954. "swi");
  955. if (opcode == NULL)
  956. {
  957. as_bad (_("unknown opcode \"%s\""), "lwi");
  958. return;
  959. }
  960. inst = opcode->bit_sequence;
  961. inst |= (reg1 << RD_LOW) & RD_MASK;
  962. inst |= (reg2 << RA_LOW) & RA_MASK;
  963. inst |= (immed << IMM_LOW) & IMM_MASK;
  964. for (i = 0; i < count - 1; i++)
  965. {
  966. output[0] = INST_BYTE0 (inst);
  967. output[1] = INST_BYTE1 (inst);
  968. output[2] = INST_BYTE2 (inst);
  969. output[3] = INST_BYTE3 (inst);
  970. output = frag_more (isize);
  971. immed = immed + 4;
  972. reg1++;
  973. inst = opcode->bit_sequence;
  974. inst |= (reg1 << RD_LOW) & RD_MASK;
  975. inst |= (reg2 << RA_LOW) & RA_MASK;
  976. inst |= (immed << IMM_LOW) & IMM_MASK;
  977. }
  978. }
  979. else
  980. {
  981. temp = immed & 0xFFFF8000;
  982. if ((temp != 0) && (temp != 0xFFFF8000))
  983. {
  984. /* Needs an immediate inst. */
  985. opcode1
  986. = (struct op_code_struct *) str_hash_find (opcode_hash_control,
  987. "imm");
  988. if (opcode1 == NULL)
  989. {
  990. as_bad (_("unknown opcode \"%s\""), "imm");
  991. return;
  992. }
  993. inst1 = opcode1->bit_sequence;
  994. inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
  995. output[0] = INST_BYTE0 (inst1);
  996. output[1] = INST_BYTE1 (inst1);
  997. output[2] = INST_BYTE2 (inst1);
  998. output[3] = INST_BYTE3 (inst1);
  999. output = frag_more (isize);
  1000. }
  1001. inst |= (reg1 << RD_LOW) & RD_MASK;
  1002. inst |= (reg2 << RA_LOW) & RA_MASK;
  1003. inst |= (immed << IMM_LOW) & IMM_MASK;
  1004. }
  1005. break;
  1006. case INST_TYPE_RD_R1_IMM5:
  1007. if (strcmp (op_end, ""))
  1008. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1009. else
  1010. {
  1011. as_fatal (_("Error in statement syntax"));
  1012. reg1 = 0;
  1013. }
  1014. if (strcmp (op_end, ""))
  1015. op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
  1016. else
  1017. {
  1018. as_fatal (_("Error in statement syntax"));
  1019. reg2 = 0;
  1020. }
  1021. if (strcmp (op_end, ""))
  1022. op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
  1023. else
  1024. as_fatal (_("Error in statement syntax"));
  1025. /* Check for spl registers. */
  1026. if (check_spl_reg (&reg1))
  1027. as_fatal (_("Cannot use special register with this instruction"));
  1028. if (check_spl_reg (&reg2))
  1029. as_fatal (_("Cannot use special register with this instruction"));
  1030. if (exp.X_op != O_constant)
  1031. as_warn (_("Symbol used as immediate for shift instruction"));
  1032. else
  1033. {
  1034. output = frag_more (isize);
  1035. immed = exp.X_add_number;
  1036. }
  1037. if (immed != (immed % 32))
  1038. {
  1039. as_warn (_("Shift value > 32. using <value %% 32>"));
  1040. immed = immed % 32;
  1041. }
  1042. inst |= (reg1 << RD_LOW) & RD_MASK;
  1043. inst |= (reg2 << RA_LOW) & RA_MASK;
  1044. inst |= (immed << IMM_LOW) & IMM5_MASK;
  1045. break;
  1046. case INST_TYPE_R1_R2:
  1047. if (strcmp (op_end, ""))
  1048. op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
  1049. else
  1050. {
  1051. as_fatal (_("Error in statement syntax"));
  1052. reg1 = 0;
  1053. }
  1054. if (strcmp (op_end, ""))
  1055. op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
  1056. else
  1057. {
  1058. as_fatal (_("Error in statement syntax"));
  1059. reg2 = 0;
  1060. }
  1061. /* Check for spl registers. */
  1062. if (check_spl_reg (& reg1))
  1063. as_fatal (_("Cannot use special register with this instruction"));
  1064. if (check_spl_reg (& reg2))
  1065. as_fatal (_("Cannot use special register with this instruction"));
  1066. inst |= (reg1 << RA_LOW) & RA_MASK;
  1067. inst |= (reg2 << RB_LOW) & RB_MASK;
  1068. output = frag_more (isize);
  1069. break;
  1070. case INST_TYPE_RD_R1:
  1071. if (strcmp (op_end, ""))
  1072. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1073. else
  1074. {
  1075. as_fatal (_("Error in statement syntax"));
  1076. reg1 = 0;
  1077. }
  1078. if (strcmp (op_end, ""))
  1079. op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
  1080. else
  1081. {
  1082. as_fatal (_("Error in statement syntax"));
  1083. reg2 =0;
  1084. }
  1085. /* Check for spl registers. */
  1086. if (check_spl_reg (&reg1))
  1087. as_fatal (_("Cannot use special register with this instruction"));
  1088. if (check_spl_reg (&reg2))
  1089. as_fatal (_("Cannot use special register with this instruction"));
  1090. inst |= (reg1 << RD_LOW) & RD_MASK;
  1091. inst |= (reg2 << RA_LOW) & RA_MASK;
  1092. output = frag_more (isize);
  1093. break;
  1094. case INST_TYPE_RD_RFSL:
  1095. if (strcmp (op_end, ""))
  1096. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1097. else
  1098. {
  1099. as_fatal (_("Error in statement syntax"));
  1100. reg1 = 0;
  1101. }
  1102. if (strcmp (op_end, ""))
  1103. op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
  1104. else
  1105. {
  1106. as_fatal (_("Error in statement syntax"));
  1107. immed = 0;
  1108. }
  1109. /* Check for spl registers. */
  1110. if (check_spl_reg (&reg1))
  1111. as_fatal (_("Cannot use special register with this instruction"));
  1112. inst |= (reg1 << RD_LOW) & RD_MASK;
  1113. inst |= (immed << IMM_LOW) & RFSL_MASK;
  1114. output = frag_more (isize);
  1115. break;
  1116. case INST_TYPE_RD_IMM15:
  1117. if (strcmp (op_end, ""))
  1118. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1119. else
  1120. {
  1121. as_fatal (_("Error in statement syntax"));
  1122. reg1 = 0;
  1123. }
  1124. if (strcmp (op_end, ""))
  1125. op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
  1126. else
  1127. as_fatal (_("Error in statement syntax"));
  1128. /* Check for spl registers. */
  1129. if (check_spl_reg (&reg1))
  1130. as_fatal (_("Cannot use special register with this instruction"));
  1131. if (exp.X_op != O_constant)
  1132. as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
  1133. else
  1134. {
  1135. output = frag_more (isize);
  1136. immed = exp.X_add_number;
  1137. }
  1138. inst |= (reg1 << RD_LOW) & RD_MASK;
  1139. inst |= (immed << IMM_LOW) & IMM15_MASK;
  1140. break;
  1141. case INST_TYPE_R1_RFSL:
  1142. if (strcmp (op_end, ""))
  1143. op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
  1144. else
  1145. {
  1146. as_fatal (_("Error in statement syntax"));
  1147. reg1 = 0;
  1148. }
  1149. if (strcmp (op_end, ""))
  1150. op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
  1151. else
  1152. {
  1153. as_fatal (_("Error in statement syntax"));
  1154. immed = 0;
  1155. }
  1156. /* Check for spl registers. */
  1157. if (check_spl_reg (&reg1))
  1158. as_fatal (_("Cannot use special register with this instruction"));
  1159. inst |= (reg1 << RA_LOW) & RA_MASK;
  1160. inst |= (immed << IMM_LOW) & RFSL_MASK;
  1161. output = frag_more (isize);
  1162. break;
  1163. case INST_TYPE_RFSL:
  1164. if (strcmp (op_end, ""))
  1165. op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
  1166. else
  1167. {
  1168. as_fatal (_("Error in statement syntax"));
  1169. immed = 0;
  1170. }
  1171. inst |= (immed << IMM_LOW) & RFSL_MASK;
  1172. output = frag_more (isize);
  1173. break;
  1174. case INST_TYPE_R1:
  1175. if (strcmp (op_end, ""))
  1176. op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
  1177. else
  1178. {
  1179. as_fatal (_("Error in statement syntax"));
  1180. reg1 = 0;
  1181. }
  1182. /* Check for spl registers. */
  1183. if (check_spl_reg (&reg1))
  1184. as_fatal (_("Cannot use special register with this instruction"));
  1185. inst |= (reg1 << RA_LOW) & RA_MASK;
  1186. output = frag_more (isize);
  1187. break;
  1188. /* For tuqula insn...:) */
  1189. case INST_TYPE_RD:
  1190. if (strcmp (op_end, ""))
  1191. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1192. else
  1193. {
  1194. as_fatal (_("Error in statement syntax"));
  1195. reg1 = 0;
  1196. }
  1197. /* Check for spl registers. */
  1198. if (check_spl_reg (&reg1))
  1199. as_fatal (_("Cannot use special register with this instruction"));
  1200. inst |= (reg1 << RD_LOW) & RD_MASK;
  1201. output = frag_more (isize);
  1202. break;
  1203. case INST_TYPE_RD_SPECIAL:
  1204. if (strcmp (op_end, ""))
  1205. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1206. else
  1207. {
  1208. as_fatal (_("Error in statement syntax"));
  1209. reg1 = 0;
  1210. }
  1211. if (strcmp (op_end, ""))
  1212. op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
  1213. else
  1214. {
  1215. as_fatal (_("Error in statement syntax"));
  1216. reg2 = 0;
  1217. }
  1218. if (reg2 == REG_MSR)
  1219. immed = opcode->immval_mask | REG_MSR_MASK;
  1220. else if (reg2 == REG_PC)
  1221. immed = opcode->immval_mask | REG_PC_MASK;
  1222. else if (reg2 == REG_EAR)
  1223. immed = opcode->immval_mask | REG_EAR_MASK;
  1224. else if (reg2 == REG_ESR)
  1225. immed = opcode->immval_mask | REG_ESR_MASK;
  1226. else if (reg2 == REG_FSR)
  1227. immed = opcode->immval_mask | REG_FSR_MASK;
  1228. else if (reg2 == REG_BTR)
  1229. immed = opcode->immval_mask | REG_BTR_MASK;
  1230. else if (reg2 == REG_EDR)
  1231. immed = opcode->immval_mask | REG_EDR_MASK;
  1232. else if (reg2 == REG_PID)
  1233. immed = opcode->immval_mask | REG_PID_MASK;
  1234. else if (reg2 == REG_ZPR)
  1235. immed = opcode->immval_mask | REG_ZPR_MASK;
  1236. else if (reg2 == REG_TLBX)
  1237. immed = opcode->immval_mask | REG_TLBX_MASK;
  1238. else if (reg2 == REG_TLBLO)
  1239. immed = opcode->immval_mask | REG_TLBLO_MASK;
  1240. else if (reg2 == REG_TLBHI)
  1241. immed = opcode->immval_mask | REG_TLBHI_MASK;
  1242. else if (reg2 == REG_SHR)
  1243. immed = opcode->immval_mask | REG_SHR_MASK;
  1244. else if (reg2 == REG_SLR)
  1245. immed = opcode->immval_mask | REG_SLR_MASK;
  1246. else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
  1247. immed = opcode->immval_mask | REG_PVR_MASK | reg2;
  1248. else
  1249. as_fatal (_("invalid value for special purpose register"));
  1250. inst |= (reg1 << RD_LOW) & RD_MASK;
  1251. inst |= (immed << IMM_LOW) & IMM_MASK;
  1252. output = frag_more (isize);
  1253. break;
  1254. case INST_TYPE_SPECIAL_R1:
  1255. if (strcmp (op_end, ""))
  1256. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1257. else
  1258. {
  1259. as_fatal (_("Error in statement syntax"));
  1260. reg1 = 0;
  1261. }
  1262. if (strcmp (op_end, ""))
  1263. op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
  1264. else
  1265. {
  1266. as_fatal (_("Error in statement syntax"));
  1267. reg2 = 0;
  1268. }
  1269. if (reg1 == REG_MSR)
  1270. immed = opcode->immval_mask | REG_MSR_MASK;
  1271. else if (reg1 == REG_PC)
  1272. immed = opcode->immval_mask | REG_PC_MASK;
  1273. else if (reg1 == REG_EAR)
  1274. immed = opcode->immval_mask | REG_EAR_MASK;
  1275. else if (reg1 == REG_ESR)
  1276. immed = opcode->immval_mask | REG_ESR_MASK;
  1277. else if (reg1 == REG_FSR)
  1278. immed = opcode->immval_mask | REG_FSR_MASK;
  1279. else if (reg1 == REG_BTR)
  1280. immed = opcode->immval_mask | REG_BTR_MASK;
  1281. else if (reg1 == REG_EDR)
  1282. immed = opcode->immval_mask | REG_EDR_MASK;
  1283. else if (reg1 == REG_PID)
  1284. immed = opcode->immval_mask | REG_PID_MASK;
  1285. else if (reg1 == REG_ZPR)
  1286. immed = opcode->immval_mask | REG_ZPR_MASK;
  1287. else if (reg1 == REG_TLBX)
  1288. immed = opcode->immval_mask | REG_TLBX_MASK;
  1289. else if (reg1 == REG_TLBLO)
  1290. immed = opcode->immval_mask | REG_TLBLO_MASK;
  1291. else if (reg1 == REG_TLBHI)
  1292. immed = opcode->immval_mask | REG_TLBHI_MASK;
  1293. else if (reg1 == REG_TLBSX)
  1294. immed = opcode->immval_mask | REG_TLBSX_MASK;
  1295. else if (reg1 == REG_SHR)
  1296. immed = opcode->immval_mask | REG_SHR_MASK;
  1297. else if (reg1 == REG_SLR)
  1298. immed = opcode->immval_mask | REG_SLR_MASK;
  1299. else
  1300. as_fatal (_("invalid value for special purpose register"));
  1301. inst |= (reg2 << RA_LOW) & RA_MASK;
  1302. inst |= (immed << IMM_LOW) & IMM_MASK;
  1303. output = frag_more (isize);
  1304. break;
  1305. case INST_TYPE_R1_R2_SPECIAL:
  1306. if (strcmp (op_end, ""))
  1307. op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
  1308. else
  1309. {
  1310. as_fatal (_("Error in statement syntax"));
  1311. reg1 = 0;
  1312. }
  1313. if (strcmp (op_end, ""))
  1314. op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
  1315. else
  1316. {
  1317. as_fatal (_("Error in statement syntax"));
  1318. reg2 =0;
  1319. }
  1320. /* Check for spl registers. */
  1321. if (check_spl_reg (&reg1))
  1322. as_fatal (_("Cannot use special register with this instruction"));
  1323. if (check_spl_reg (&reg2))
  1324. as_fatal (_("Cannot use special register with this instruction"));
  1325. /* insn wic ra, rb => wic ra, ra, rb. */
  1326. inst |= (reg1 << RA_LOW) & RA_MASK;
  1327. inst |= (reg2 << RB_LOW) & RB_MASK;
  1328. output = frag_more (isize);
  1329. break;
  1330. case INST_TYPE_RD_R2:
  1331. if (strcmp (op_end, ""))
  1332. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1333. else
  1334. {
  1335. as_fatal (_("Error in statement syntax"));
  1336. reg1 = 0;
  1337. }
  1338. if (strcmp (op_end, ""))
  1339. op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
  1340. else
  1341. {
  1342. as_fatal (_("Error in statement syntax"));
  1343. reg2 = 0;
  1344. }
  1345. /* Check for spl registers. */
  1346. if (check_spl_reg (&reg1))
  1347. as_fatal (_("Cannot use special register with this instruction"));
  1348. if (check_spl_reg (&reg2))
  1349. as_fatal (_("Cannot use special register with this instruction"));
  1350. inst |= (reg1 << RD_LOW) & RD_MASK;
  1351. inst |= (reg2 << RB_LOW) & RB_MASK;
  1352. output = frag_more (isize);
  1353. break;
  1354. case INST_TYPE_R1_IMM:
  1355. if (strcmp (op_end, ""))
  1356. op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
  1357. else
  1358. {
  1359. as_fatal (_("Error in statement syntax"));
  1360. reg1 = 0;
  1361. }
  1362. if (strcmp (op_end, ""))
  1363. op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
  1364. else
  1365. as_fatal (_("Error in statement syntax"));
  1366. /* Check for spl registers. */
  1367. if (check_spl_reg (&reg1))
  1368. as_fatal (_("Cannot use special register with this instruction"));
  1369. if (exp.X_op != O_constant)
  1370. {
  1371. char *opc = NULL;
  1372. relax_substateT subtype;
  1373. if (exp.X_md != 0)
  1374. subtype = get_imm_otype(exp.X_md);
  1375. else
  1376. subtype = opcode->inst_offset_type;
  1377. output = frag_var (rs_machine_dependent,
  1378. isize * 2, /* maxm of 2 words. */
  1379. isize, /* minm of 1 word. */
  1380. subtype, /* PC-relative or not. */
  1381. exp.X_add_symbol,
  1382. exp.X_add_number,
  1383. opc);
  1384. immed = 0;
  1385. }
  1386. else
  1387. {
  1388. output = frag_more (isize);
  1389. immed = exp.X_add_number;
  1390. }
  1391. temp = immed & 0xFFFF8000;
  1392. if ((temp != 0) && (temp != 0xFFFF8000))
  1393. {
  1394. /* Needs an immediate inst. */
  1395. opcode1
  1396. = (struct op_code_struct *) str_hash_find (opcode_hash_control,
  1397. "imm");
  1398. if (opcode1 == NULL)
  1399. {
  1400. as_bad (_("unknown opcode \"%s\""), "imm");
  1401. return;
  1402. }
  1403. inst1 = opcode1->bit_sequence;
  1404. inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
  1405. output[0] = INST_BYTE0 (inst1);
  1406. output[1] = INST_BYTE1 (inst1);
  1407. output[2] = INST_BYTE2 (inst1);
  1408. output[3] = INST_BYTE3 (inst1);
  1409. output = frag_more (isize);
  1410. }
  1411. inst |= (reg1 << RA_LOW) & RA_MASK;
  1412. inst |= (immed << IMM_LOW) & IMM_MASK;
  1413. break;
  1414. case INST_TYPE_RD_IMM:
  1415. if (strcmp (op_end, ""))
  1416. op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
  1417. else
  1418. {
  1419. as_fatal (_("Error in statement syntax"));
  1420. reg1 = 0;
  1421. }
  1422. if (strcmp (op_end, ""))
  1423. op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
  1424. else
  1425. as_fatal (_("Error in statement syntax"));
  1426. /* Check for spl registers. */
  1427. if (check_spl_reg (&reg1))
  1428. as_fatal (_("Cannot use special register with this instruction"));
  1429. if (exp.X_op != O_constant)
  1430. {
  1431. char *opc = NULL;
  1432. relax_substateT subtype;
  1433. if (exp.X_md != 0)
  1434. subtype = get_imm_otype(exp.X_md);
  1435. else
  1436. subtype = opcode->inst_offset_type;
  1437. output = frag_var (rs_machine_dependent,
  1438. isize * 2, /* maxm of 2 words. */
  1439. isize, /* minm of 1 word. */
  1440. subtype, /* PC-relative or not. */
  1441. exp.X_add_symbol,
  1442. exp.X_add_number,
  1443. opc);
  1444. immed = 0;
  1445. }
  1446. else
  1447. {
  1448. output = frag_more (isize);
  1449. immed = exp.X_add_number;
  1450. }
  1451. temp = immed & 0xFFFF8000;
  1452. if ((temp != 0) && (temp != 0xFFFF8000))
  1453. {
  1454. /* Needs an immediate inst. */
  1455. opcode1
  1456. = (struct op_code_struct *) str_hash_find (opcode_hash_control,
  1457. "imm");
  1458. if (opcode1 == NULL)
  1459. {
  1460. as_bad (_("unknown opcode \"%s\""), "imm");
  1461. return;
  1462. }
  1463. inst1 = opcode1->bit_sequence;
  1464. inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
  1465. output[0] = INST_BYTE0 (inst1);
  1466. output[1] = INST_BYTE1 (inst1);
  1467. output[2] = INST_BYTE2 (inst1);
  1468. output[3] = INST_BYTE3 (inst1);
  1469. output = frag_more (isize);
  1470. }
  1471. inst |= (reg1 << RD_LOW) & RD_MASK;
  1472. inst |= (immed << IMM_LOW) & IMM_MASK;
  1473. break;
  1474. case INST_TYPE_R2:
  1475. if (strcmp (op_end, ""))
  1476. op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
  1477. else
  1478. {
  1479. as_fatal (_("Error in statement syntax"));
  1480. reg2 = 0;
  1481. }
  1482. /* Check for spl registers. */
  1483. if (check_spl_reg (&reg2))
  1484. as_fatal (_("Cannot use special register with this instruction"));
  1485. inst |= (reg2 << RB_LOW) & RB_MASK;
  1486. output = frag_more (isize);
  1487. break;
  1488. case INST_TYPE_IMM:
  1489. if (streq (name, "imm"))
  1490. as_fatal (_("An IMM instruction should not be present in the .s file"));
  1491. op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
  1492. if (exp.X_op != O_constant)
  1493. {
  1494. char *opc = NULL;
  1495. relax_substateT subtype;
  1496. if (exp.X_md != 0)
  1497. subtype = get_imm_otype(exp.X_md);
  1498. else
  1499. subtype = opcode->inst_offset_type;
  1500. output = frag_var (rs_machine_dependent,
  1501. isize * 2, /* maxm of 2 words. */
  1502. isize, /* minm of 1 word. */
  1503. subtype, /* PC-relative or not. */
  1504. exp.X_add_symbol,
  1505. exp.X_add_number,
  1506. opc);
  1507. immed = 0;
  1508. }
  1509. else
  1510. {
  1511. output = frag_more (isize);
  1512. immed = exp.X_add_number;
  1513. }
  1514. temp = immed & 0xFFFF8000;
  1515. if ((temp != 0) && (temp != 0xFFFF8000))
  1516. {
  1517. /* Needs an immediate inst. */
  1518. opcode1
  1519. = (struct op_code_struct *) str_hash_find (opcode_hash_control,
  1520. "imm");
  1521. if (opcode1 == NULL)
  1522. {
  1523. as_bad (_("unknown opcode \"%s\""), "imm");
  1524. return;
  1525. }
  1526. inst1 = opcode1->bit_sequence;
  1527. inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
  1528. output[0] = INST_BYTE0 (inst1);
  1529. output[1] = INST_BYTE1 (inst1);
  1530. output[2] = INST_BYTE2 (inst1);
  1531. output[3] = INST_BYTE3 (inst1);
  1532. output = frag_more (isize);
  1533. }
  1534. inst |= (immed << IMM_LOW) & IMM_MASK;
  1535. break;
  1536. case INST_TYPE_NONE:
  1537. output = frag_more (isize);
  1538. break;
  1539. case INST_TYPE_IMM5:
  1540. if (strcmp(op_end, ""))
  1541. op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
  1542. else
  1543. as_fatal(_("Error in statement syntax"));
  1544. if (exp.X_op != O_constant) {
  1545. as_warn(_("Symbol used as immediate for mbar instruction"));
  1546. } else {
  1547. output = frag_more (isize);
  1548. immed = exp.X_add_number;
  1549. }
  1550. if (immed != (immed % 32)) {
  1551. as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
  1552. immed = immed % 32;
  1553. }
  1554. inst |= (immed << IMM_MBAR);
  1555. break;
  1556. default:
  1557. as_fatal (_("unimplemented opcode \"%s\""), name);
  1558. }
  1559. /* Drop whitespace after all the operands have been parsed. */
  1560. while (ISSPACE (* op_end))
  1561. op_end ++;
  1562. /* Give warning message if the insn has more operands than required. */
  1563. if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
  1564. as_warn (_("ignoring operands: %s "), op_end);
  1565. output[0] = INST_BYTE0 (inst);
  1566. output[1] = INST_BYTE1 (inst);
  1567. output[2] = INST_BYTE2 (inst);
  1568. output[3] = INST_BYTE3 (inst);
  1569. #ifdef OBJ_ELF
  1570. dwarf2_emit_insn (4);
  1571. #endif
  1572. }
  1573. symbolS *
  1574. md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
  1575. {
  1576. return NULL;
  1577. }
  1578. /* Turn a string in input_line_pointer into a floating point constant of type
  1579. type, and store the appropriate bytes in *litP. The number of LITTLENUMS
  1580. emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
  1581. const char *
  1582. md_atof (int type, char * litP, int * sizeP)
  1583. {
  1584. int prec;
  1585. LITTLENUM_TYPE words[MAX_LITTLENUMS];
  1586. int i;
  1587. char * t;
  1588. switch (type)
  1589. {
  1590. case 'f':
  1591. case 'F':
  1592. case 's':
  1593. case 'S':
  1594. prec = 2;
  1595. break;
  1596. case 'd':
  1597. case 'D':
  1598. case 'r':
  1599. case 'R':
  1600. prec = 4;
  1601. break;
  1602. case 'x':
  1603. case 'X':
  1604. prec = 6;
  1605. break;
  1606. case 'p':
  1607. case 'P':
  1608. prec = 6;
  1609. break;
  1610. default:
  1611. *sizeP = 0;
  1612. return _("Bad call to MD_NTOF()");
  1613. }
  1614. t = atof_ieee (input_line_pointer, type, words);
  1615. if (t)
  1616. input_line_pointer = t;
  1617. *sizeP = prec * sizeof (LITTLENUM_TYPE);
  1618. if (! target_big_endian)
  1619. {
  1620. for (i = prec - 1; i >= 0; i--)
  1621. {
  1622. md_number_to_chars (litP, (valueT) words[i],
  1623. sizeof (LITTLENUM_TYPE));
  1624. litP += sizeof (LITTLENUM_TYPE);
  1625. }
  1626. }
  1627. else
  1628. for (i = 0; i < prec; i++)
  1629. {
  1630. md_number_to_chars (litP, (valueT) words[i],
  1631. sizeof (LITTLENUM_TYPE));
  1632. litP += sizeof (LITTLENUM_TYPE);
  1633. }
  1634. return NULL;
  1635. }
  1636. const char * md_shortopts = "";
  1637. struct option md_longopts[] =
  1638. {
  1639. {"EB", no_argument, NULL, OPTION_EB},
  1640. {"EL", no_argument, NULL, OPTION_EL},
  1641. { NULL, no_argument, NULL, 0}
  1642. };
  1643. size_t md_longopts_size = sizeof (md_longopts);
  1644. int md_short_jump_size;
  1645. void
  1646. md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
  1647. addressT from_Nddr ATTRIBUTE_UNUSED,
  1648. addressT to_Nddr ATTRIBUTE_UNUSED,
  1649. fragS * frag ATTRIBUTE_UNUSED,
  1650. symbolS * to_symbol ATTRIBUTE_UNUSED)
  1651. {
  1652. as_fatal (_("failed sanity check: short_jump"));
  1653. }
  1654. void
  1655. md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
  1656. addressT from_Nddr ATTRIBUTE_UNUSED,
  1657. addressT to_Nddr ATTRIBUTE_UNUSED,
  1658. fragS * frag ATTRIBUTE_UNUSED,
  1659. symbolS * to_symbol ATTRIBUTE_UNUSED)
  1660. {
  1661. as_fatal (_("failed sanity check: long_jump"));
  1662. }
  1663. /* Called after relaxing, change the frags so they know how big they are. */
  1664. void
  1665. md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
  1666. segT sec ATTRIBUTE_UNUSED,
  1667. fragS * fragP)
  1668. {
  1669. fixS *fixP;
  1670. switch (fragP->fr_subtype)
  1671. {
  1672. case UNDEFINED_PC_OFFSET:
  1673. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1674. fragP->fr_offset, true, BFD_RELOC_64_PCREL);
  1675. fragP->fr_fix += INST_WORD_SIZE * 2;
  1676. fragP->fr_var = 0;
  1677. break;
  1678. case DEFINED_ABS_SEGMENT:
  1679. if (fragP->fr_symbol == GOT_symbol)
  1680. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1681. fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GOTPC);
  1682. else
  1683. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1684. fragP->fr_offset, false, BFD_RELOC_64);
  1685. fragP->fr_fix += INST_WORD_SIZE * 2;
  1686. fragP->fr_var = 0;
  1687. break;
  1688. case DEFINED_RO_SEGMENT:
  1689. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
  1690. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_32_ROSDA);
  1691. fragP->fr_fix += INST_WORD_SIZE;
  1692. fragP->fr_var = 0;
  1693. break;
  1694. case DEFINED_RW_SEGMENT:
  1695. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
  1696. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_32_RWSDA);
  1697. fragP->fr_fix += INST_WORD_SIZE;
  1698. fragP->fr_var = 0;
  1699. break;
  1700. case DEFINED_PC_OFFSET:
  1701. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
  1702. fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
  1703. fragP->fr_fix += INST_WORD_SIZE;
  1704. fragP->fr_var = 0;
  1705. break;
  1706. case LARGE_DEFINED_PC_OFFSET:
  1707. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1708. fragP->fr_offset, true, BFD_RELOC_64_PCREL);
  1709. fragP->fr_fix += INST_WORD_SIZE * 2;
  1710. fragP->fr_var = 0;
  1711. break;
  1712. case GOT_OFFSET:
  1713. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1714. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_GOT);
  1715. fragP->fr_fix += INST_WORD_SIZE * 2;
  1716. fragP->fr_var = 0;
  1717. break;
  1718. case TEXT_OFFSET:
  1719. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1720. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TEXTREL);
  1721. fragP->fr_fix += INST_WORD_SIZE * 2;
  1722. fragP->fr_var = 0;
  1723. break;
  1724. case TEXT_PC_OFFSET:
  1725. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1726. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TEXTPCREL);
  1727. fragP->fr_fix += INST_WORD_SIZE * 2;
  1728. fragP->fr_var = 0;
  1729. break;
  1730. case PLT_OFFSET:
  1731. fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1732. fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_PLT);
  1733. /* fixP->fx_plt = 1; */
  1734. (void) fixP;
  1735. fragP->fr_fix += INST_WORD_SIZE * 2;
  1736. fragP->fr_var = 0;
  1737. break;
  1738. case GOTOFF_OFFSET:
  1739. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1740. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_GOTOFF);
  1741. fragP->fr_fix += INST_WORD_SIZE * 2;
  1742. fragP->fr_var = 0;
  1743. break;
  1744. case TLSGD_OFFSET:
  1745. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1746. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TLSGD);
  1747. fragP->fr_fix += INST_WORD_SIZE * 2;
  1748. fragP->fr_var = 0;
  1749. break;
  1750. case TLSLD_OFFSET:
  1751. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1752. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TLSLD);
  1753. fragP->fr_fix += INST_WORD_SIZE * 2;
  1754. fragP->fr_var = 0;
  1755. break;
  1756. case TLSDTPREL_OFFSET:
  1757. fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
  1758. fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TLSDTPREL);
  1759. fragP->fr_fix += INST_WORD_SIZE * 2;
  1760. fragP->fr_var = 0;
  1761. break;
  1762. default:
  1763. abort ();
  1764. }
  1765. }
  1766. /* Applies the desired value to the specified location.
  1767. Also sets up addends for 'rela' type relocations. */
  1768. void
  1769. md_apply_fix (fixS * fixP,
  1770. valueT * valp,
  1771. segT segment)
  1772. {
  1773. char * buf = fixP->fx_where + &fixP->fx_frag->fr_literal[0];
  1774. const char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
  1775. const char * symname;
  1776. /* Note: use offsetT because it is signed, valueT is unsigned. */
  1777. offsetT val = (offsetT) * valp;
  1778. int i;
  1779. struct op_code_struct * opcode1;
  1780. unsigned long inst1;
  1781. symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
  1782. /* fixP->fx_offset is supposed to be set up correctly for all
  1783. symbol relocations. */
  1784. if (fixP->fx_addsy == NULL)
  1785. {
  1786. if (!fixP->fx_pcrel)
  1787. fixP->fx_offset = val; /* Absolute relocation. */
  1788. else
  1789. fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
  1790. (unsigned int) fixP->fx_offset, (unsigned int) val);
  1791. }
  1792. /* If we aren't adjusting this fixup to be against the section
  1793. symbol, we need to adjust the value. */
  1794. if (fixP->fx_addsy != NULL)
  1795. {
  1796. if (S_IS_WEAK (fixP->fx_addsy)
  1797. || (symbol_used_in_reloc_p (fixP->fx_addsy)
  1798. && (((bfd_section_flags (S_GET_SEGMENT (fixP->fx_addsy))
  1799. & SEC_LINK_ONCE) != 0)
  1800. || startswith (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
  1801. ".gnu.linkonce"))))
  1802. {
  1803. val -= S_GET_VALUE (fixP->fx_addsy);
  1804. if (val != 0 && ! fixP->fx_pcrel)
  1805. {
  1806. /* In this case, the bfd_install_relocation routine will
  1807. incorrectly add the symbol value back in. We just want
  1808. the addend to appear in the object file.
  1809. FIXME: If this makes VALUE zero, we're toast. */
  1810. val -= S_GET_VALUE (fixP->fx_addsy);
  1811. }
  1812. }
  1813. }
  1814. /* If the fix is relative to a symbol which is not defined, or not
  1815. in the same segment as the fix, we cannot resolve it here. */
  1816. /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
  1817. if (fixP->fx_addsy != NULL
  1818. && (!S_IS_DEFINED (fixP->fx_addsy)
  1819. || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
  1820. {
  1821. fixP->fx_done = 0;
  1822. #ifdef OBJ_ELF
  1823. /* For ELF we can just return and let the reloc that will be generated
  1824. take care of everything. For COFF we still have to insert 'val'
  1825. into the insn since the addend field will be ignored. */
  1826. /* return; */
  1827. #endif
  1828. }
  1829. /* All fixups in the text section must be handled in the linker. */
  1830. else if (segment->flags & SEC_CODE)
  1831. fixP->fx_done = 0;
  1832. else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
  1833. fixP->fx_done = 0;
  1834. else
  1835. fixP->fx_done = 1;
  1836. switch (fixP->fx_r_type)
  1837. {
  1838. case BFD_RELOC_MICROBLAZE_32_LO:
  1839. case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
  1840. if (target_big_endian)
  1841. {
  1842. buf[2] |= ((val >> 8) & 0xff);
  1843. buf[3] |= (val & 0xff);
  1844. }
  1845. else
  1846. {
  1847. buf[1] |= ((val >> 8) & 0xff);
  1848. buf[0] |= (val & 0xff);
  1849. }
  1850. break;
  1851. case BFD_RELOC_MICROBLAZE_32_ROSDA:
  1852. case BFD_RELOC_MICROBLAZE_32_RWSDA:
  1853. /* Don't do anything if the symbol is not defined. */
  1854. if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
  1855. {
  1856. if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
  1857. as_bad_where (file, fixP->fx_line,
  1858. _("pcrel for branch to %s too far (0x%x)"),
  1859. symname, (int) val);
  1860. if (target_big_endian)
  1861. {
  1862. buf[2] |= ((val >> 8) & 0xff);
  1863. buf[3] |= (val & 0xff);
  1864. }
  1865. else
  1866. {
  1867. buf[1] |= ((val >> 8) & 0xff);
  1868. buf[0] |= (val & 0xff);
  1869. }
  1870. }
  1871. break;
  1872. case BFD_RELOC_32:
  1873. case BFD_RELOC_RVA:
  1874. case BFD_RELOC_32_PCREL:
  1875. case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
  1876. /* Don't do anything if the symbol is not defined. */
  1877. if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
  1878. {
  1879. if (target_big_endian)
  1880. {
  1881. buf[0] |= ((val >> 24) & 0xff);
  1882. buf[1] |= ((val >> 16) & 0xff);
  1883. buf[2] |= ((val >> 8) & 0xff);
  1884. buf[3] |= (val & 0xff);
  1885. }
  1886. else
  1887. {
  1888. buf[3] |= ((val >> 24) & 0xff);
  1889. buf[2] |= ((val >> 16) & 0xff);
  1890. buf[1] |= ((val >> 8) & 0xff);
  1891. buf[0] |= (val & 0xff);
  1892. }
  1893. }
  1894. break;
  1895. case BFD_RELOC_64_PCREL:
  1896. case BFD_RELOC_64:
  1897. case BFD_RELOC_MICROBLAZE_64_TEXTREL:
  1898. /* Add an imm instruction. First save the current instruction. */
  1899. for (i = 0; i < INST_WORD_SIZE; i++)
  1900. buf[i + INST_WORD_SIZE] = buf[i];
  1901. /* Generate the imm instruction. */
  1902. opcode1
  1903. = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
  1904. if (opcode1 == NULL)
  1905. {
  1906. as_bad (_("unknown opcode \"%s\""), "imm");
  1907. return;
  1908. }
  1909. inst1 = opcode1->bit_sequence;
  1910. if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
  1911. inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
  1912. buf[0] = INST_BYTE0 (inst1);
  1913. buf[1] = INST_BYTE1 (inst1);
  1914. buf[2] = INST_BYTE2 (inst1);
  1915. buf[3] = INST_BYTE3 (inst1);
  1916. /* Add the value only if the symbol is defined. */
  1917. if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
  1918. {
  1919. if (target_big_endian)
  1920. {
  1921. buf[6] |= ((val >> 8) & 0xff);
  1922. buf[7] |= (val & 0xff);
  1923. }
  1924. else
  1925. {
  1926. buf[5] |= ((val >> 8) & 0xff);
  1927. buf[4] |= (val & 0xff);
  1928. }
  1929. }
  1930. break;
  1931. case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
  1932. case BFD_RELOC_MICROBLAZE_64_TLSGD:
  1933. case BFD_RELOC_MICROBLAZE_64_TLSLD:
  1934. S_SET_THREAD_LOCAL (fixP->fx_addsy);
  1935. /* Fall through. */
  1936. case BFD_RELOC_MICROBLAZE_64_GOTPC:
  1937. case BFD_RELOC_MICROBLAZE_64_GOT:
  1938. case BFD_RELOC_MICROBLAZE_64_PLT:
  1939. case BFD_RELOC_MICROBLAZE_64_GOTOFF:
  1940. case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
  1941. /* Add an imm instruction. First save the current instruction. */
  1942. for (i = 0; i < INST_WORD_SIZE; i++)
  1943. buf[i + INST_WORD_SIZE] = buf[i];
  1944. /* Generate the imm instruction. */
  1945. opcode1
  1946. = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
  1947. if (opcode1 == NULL)
  1948. {
  1949. as_bad (_("unknown opcode \"%s\""), "imm");
  1950. return;
  1951. }
  1952. inst1 = opcode1->bit_sequence;
  1953. /* We can fixup call to a defined non-global address
  1954. within the same section only. */
  1955. buf[0] = INST_BYTE0 (inst1);
  1956. buf[1] = INST_BYTE1 (inst1);
  1957. buf[2] = INST_BYTE2 (inst1);
  1958. buf[3] = INST_BYTE3 (inst1);
  1959. return;
  1960. default:
  1961. break;
  1962. }
  1963. if (fixP->fx_addsy == NULL)
  1964. {
  1965. /* This fixup has been resolved. Create a reloc in case the linker
  1966. moves code around due to relaxing. */
  1967. if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
  1968. fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
  1969. else
  1970. fixP->fx_r_type = BFD_RELOC_NONE;
  1971. fixP->fx_addsy = section_symbol (absolute_section);
  1972. }
  1973. return;
  1974. }
  1975. void
  1976. md_operand (expressionS * expressionP)
  1977. {
  1978. /* Ignore leading hash symbol, if present. */
  1979. if (*input_line_pointer == '#')
  1980. {
  1981. input_line_pointer ++;
  1982. expression (expressionP);
  1983. }
  1984. }
  1985. /* Called just before address relaxation, return the length
  1986. by which a fragment must grow to reach it's destination. */
  1987. int
  1988. md_estimate_size_before_relax (fragS * fragP,
  1989. segT segment_type)
  1990. {
  1991. sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
  1992. sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
  1993. sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
  1994. sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
  1995. switch (fragP->fr_subtype)
  1996. {
  1997. case INST_PC_OFFSET:
  1998. /* Used to be a PC-relative branch. */
  1999. if (!fragP->fr_symbol)
  2000. {
  2001. /* We know the abs value: Should never happen. */
  2002. as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
  2003. abort ();
  2004. }
  2005. else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
  2006. !S_IS_WEAK (fragP->fr_symbol))
  2007. {
  2008. fragP->fr_subtype = DEFINED_PC_OFFSET;
  2009. /* Don't know now whether we need an imm instruction. */
  2010. fragP->fr_var = INST_WORD_SIZE;
  2011. }
  2012. else if (S_IS_DEFINED (fragP->fr_symbol)
  2013. && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
  2014. {
  2015. /* Cannot have a PC-relative branch to a diff segment. */
  2016. as_bad (_("PC relative branch to label %s which is not in the instruction space"),
  2017. S_GET_NAME (fragP->fr_symbol));
  2018. fragP->fr_subtype = UNDEFINED_PC_OFFSET;
  2019. fragP->fr_var = INST_WORD_SIZE*2;
  2020. }
  2021. else
  2022. {
  2023. fragP->fr_subtype = UNDEFINED_PC_OFFSET;
  2024. fragP->fr_var = INST_WORD_SIZE*2;
  2025. }
  2026. break;
  2027. case INST_NO_OFFSET:
  2028. case TEXT_OFFSET:
  2029. /* Used to be a reference to somewhere which was unknown. */
  2030. if (fragP->fr_symbol)
  2031. {
  2032. if (fragP->fr_opcode == NULL)
  2033. {
  2034. /* Used as an absolute value. */
  2035. if (fragP->fr_subtype == INST_NO_OFFSET)
  2036. fragP->fr_subtype = DEFINED_ABS_SEGMENT;
  2037. /* Variable part does not change. */
  2038. fragP->fr_var = INST_WORD_SIZE*2;
  2039. }
  2040. else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
  2041. {
  2042. /* It is accessed using the small data read only anchor. */
  2043. if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
  2044. || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
  2045. || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
  2046. || (! S_IS_DEFINED (fragP->fr_symbol)))
  2047. {
  2048. fragP->fr_subtype = DEFINED_RO_SEGMENT;
  2049. fragP->fr_var = INST_WORD_SIZE;
  2050. }
  2051. else
  2052. {
  2053. /* Variable not in small data read only segment accessed
  2054. using small data read only anchor. */
  2055. const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
  2056. as_bad_where (file, fragP->fr_line,
  2057. _("Variable is accessed using small data read "
  2058. "only anchor, but it is not in the small data "
  2059. "read only section"));
  2060. fragP->fr_subtype = DEFINED_RO_SEGMENT;
  2061. fragP->fr_var = INST_WORD_SIZE;
  2062. }
  2063. }
  2064. else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
  2065. {
  2066. if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
  2067. || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
  2068. || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
  2069. || (!S_IS_DEFINED (fragP->fr_symbol)))
  2070. {
  2071. /* It is accessed using the small data read write anchor. */
  2072. fragP->fr_subtype = DEFINED_RW_SEGMENT;
  2073. fragP->fr_var = INST_WORD_SIZE;
  2074. }
  2075. else
  2076. {
  2077. const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
  2078. as_bad_where (file, fragP->fr_line,
  2079. _("Variable is accessed using small data read "
  2080. "write anchor, but it is not in the small data "
  2081. "read write section"));
  2082. fragP->fr_subtype = DEFINED_RW_SEGMENT;
  2083. fragP->fr_var = INST_WORD_SIZE;
  2084. }
  2085. }
  2086. else
  2087. {
  2088. as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
  2089. abort ();
  2090. }
  2091. }
  2092. else
  2093. {
  2094. /* We know the abs value: Should never happen. */
  2095. as_bad (_("Absolute value in relaxation code. Assembler error....."));
  2096. abort ();
  2097. }
  2098. break;
  2099. case UNDEFINED_PC_OFFSET:
  2100. case LARGE_DEFINED_PC_OFFSET:
  2101. case DEFINED_ABS_SEGMENT:
  2102. case GOT_OFFSET:
  2103. case PLT_OFFSET:
  2104. case GOTOFF_OFFSET:
  2105. case TEXT_PC_OFFSET:
  2106. case TLSGD_OFFSET:
  2107. case TLSLD_OFFSET:
  2108. case TLSTPREL_OFFSET:
  2109. case TLSDTPREL_OFFSET:
  2110. fragP->fr_var = INST_WORD_SIZE*2;
  2111. break;
  2112. case DEFINED_RO_SEGMENT:
  2113. case DEFINED_RW_SEGMENT:
  2114. case DEFINED_PC_OFFSET:
  2115. case TLSDTPMOD_OFFSET:
  2116. fragP->fr_var = INST_WORD_SIZE;
  2117. break;
  2118. default:
  2119. abort ();
  2120. }
  2121. return fragP->fr_var;
  2122. }
  2123. /* Put number into target byte order. */
  2124. void
  2125. md_number_to_chars (char * ptr, valueT use, int nbytes)
  2126. {
  2127. if (target_big_endian)
  2128. number_to_chars_bigendian (ptr, use, nbytes);
  2129. else
  2130. number_to_chars_littleendian (ptr, use, nbytes);
  2131. }
  2132. /* Round up a section size to the appropriate boundary. */
  2133. valueT
  2134. md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
  2135. {
  2136. return size; /* Byte alignment is fine. */
  2137. }
  2138. /* The location from which a PC relative jump should be calculated,
  2139. given a PC relative reloc. */
  2140. long
  2141. md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
  2142. {
  2143. #ifdef OBJ_ELF
  2144. /* If the symbol is undefined or defined in another section
  2145. we leave the add number alone for the linker to fix it later.
  2146. Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
  2147. if (fixp->fx_addsy != (symbolS *) NULL
  2148. && (!S_IS_DEFINED (fixp->fx_addsy)
  2149. || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
  2150. return 0;
  2151. else
  2152. {
  2153. /* The case where we are going to resolve things... */
  2154. if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
  2155. return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
  2156. else
  2157. return fixp->fx_where + fixp->fx_frag->fr_address;
  2158. }
  2159. #endif
  2160. }
  2161. #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
  2162. #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
  2163. arelent *
  2164. tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
  2165. {
  2166. arelent * rel;
  2167. bfd_reloc_code_real_type code;
  2168. switch (fixp->fx_r_type)
  2169. {
  2170. case BFD_RELOC_NONE:
  2171. case BFD_RELOC_MICROBLAZE_64_NONE:
  2172. case BFD_RELOC_32:
  2173. case BFD_RELOC_MICROBLAZE_32_LO:
  2174. case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
  2175. case BFD_RELOC_RVA:
  2176. case BFD_RELOC_64:
  2177. case BFD_RELOC_64_PCREL:
  2178. case BFD_RELOC_MICROBLAZE_32_ROSDA:
  2179. case BFD_RELOC_MICROBLAZE_32_RWSDA:
  2180. case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
  2181. case BFD_RELOC_MICROBLAZE_64_GOTPC:
  2182. case BFD_RELOC_MICROBLAZE_64_GOT:
  2183. case BFD_RELOC_MICROBLAZE_64_PLT:
  2184. case BFD_RELOC_MICROBLAZE_64_GOTOFF:
  2185. case BFD_RELOC_MICROBLAZE_32_GOTOFF:
  2186. case BFD_RELOC_MICROBLAZE_64_TLSGD:
  2187. case BFD_RELOC_MICROBLAZE_64_TLSLD:
  2188. case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
  2189. case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
  2190. case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
  2191. case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
  2192. case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
  2193. case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
  2194. case BFD_RELOC_MICROBLAZE_64_TEXTREL:
  2195. code = fixp->fx_r_type;
  2196. break;
  2197. default:
  2198. switch (F (fixp->fx_size, fixp->fx_pcrel))
  2199. {
  2200. MAP (1, 0, BFD_RELOC_8);
  2201. MAP (2, 0, BFD_RELOC_16);
  2202. MAP (4, 0, BFD_RELOC_32);
  2203. MAP (1, 1, BFD_RELOC_8_PCREL);
  2204. MAP (2, 1, BFD_RELOC_16_PCREL);
  2205. MAP (4, 1, BFD_RELOC_32_PCREL);
  2206. default:
  2207. code = fixp->fx_r_type;
  2208. as_bad (_("Can not do %d byte %srelocation"),
  2209. fixp->fx_size,
  2210. fixp->fx_pcrel ? _("pc-relative ") : "");
  2211. }
  2212. break;
  2213. }
  2214. rel = XNEW (arelent);
  2215. rel->sym_ptr_ptr = XNEW (asymbol *);
  2216. if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
  2217. *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
  2218. else
  2219. *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  2220. rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
  2221. /* Always pass the addend along! */
  2222. rel->addend = fixp->fx_offset;
  2223. rel->howto = bfd_reloc_type_lookup (stdoutput, code);
  2224. if (rel->howto == NULL)
  2225. {
  2226. as_bad_where (fixp->fx_file, fixp->fx_line,
  2227. _("Cannot represent relocation type %s"),
  2228. bfd_get_reloc_code_name (code));
  2229. /* Set howto to a garbage value so that we can keep going. */
  2230. rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
  2231. gas_assert (rel->howto != NULL);
  2232. }
  2233. return rel;
  2234. }
  2235. int
  2236. md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
  2237. {
  2238. switch (c)
  2239. {
  2240. case OPTION_EB:
  2241. target_big_endian = 1;
  2242. break;
  2243. case OPTION_EL:
  2244. target_big_endian = 0;
  2245. break;
  2246. default:
  2247. return 0;
  2248. }
  2249. return 1;
  2250. }
  2251. void
  2252. md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
  2253. {
  2254. /* fprintf(stream, _("\
  2255. MicroBlaze options:\n\
  2256. -noSmall Data in the comm and data sections do not go into the small data section\n")); */
  2257. }
  2258. /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
  2259. found a machine specific op in an expression,
  2260. then we create relocs accordingly. */
  2261. void
  2262. cons_fix_new_microblaze (fragS * frag,
  2263. int where,
  2264. int size,
  2265. expressionS *exp,
  2266. bfd_reloc_code_real_type r)
  2267. {
  2268. if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
  2269. (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
  2270. && (!S_IS_LOCAL (exp->X_op_symbol)))
  2271. r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
  2272. else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
  2273. {
  2274. exp->X_op = O_symbol;
  2275. r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
  2276. }
  2277. else
  2278. {
  2279. switch (size)
  2280. {
  2281. case 1:
  2282. r = BFD_RELOC_8;
  2283. break;
  2284. case 2:
  2285. r = BFD_RELOC_16;
  2286. break;
  2287. case 4:
  2288. r = BFD_RELOC_32;
  2289. break;
  2290. case 8:
  2291. r = BFD_RELOC_64;
  2292. break;
  2293. default:
  2294. as_bad (_("unsupported BFD relocation size %u"), size);
  2295. r = BFD_RELOC_32;
  2296. break;
  2297. }
  2298. }
  2299. fix_new_exp (frag, where, size, exp, 0, r);
  2300. }