sparc.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. /* sparc.c -- Assemble for the SPARC
  2. Copyright (C) 1989 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 1, 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
  14. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. #include <stdio.h>
  16. #include <ctype.h>
  17. #include "sparc-opcode.h"
  18. #include "as.h"
  19. #include "frags.h"
  20. #include "struc-symbol.h"
  21. #include "flonum.h"
  22. #include "expr.h"
  23. #include "hash.h"
  24. #include "md.h"
  25. #include "sparc.h"
  26. #include "write.h"
  27. #include "read.h"
  28. #include "symbols.h"
  29. void md_begin();
  30. void md_end();
  31. void md_number_to_chars();
  32. void md_assemble();
  33. char *md_atof();
  34. void md_convert_frag();
  35. void md_create_short_jump();
  36. void md_create_long_jump();
  37. int md_estimate_size_before_relax();
  38. void md_number_to_imm();
  39. void md_number_to_disp();
  40. void md_number_to_field();
  41. void md_ri_to_chars();
  42. void emit_relocations();
  43. static void sparc_ip();
  44. relax_typeS md_relax_table[] = { 0 };
  45. /* handle of the OPCODE hash table */
  46. static struct hash_control *op_hash = NULL;
  47. static void s_seg(), s_proc(), s_data1(), s_reserve(), s_common();
  48. extern void s_globl(), s_long(), s_short(), s_space(), cons();
  49. pseudo_typeS
  50. md_pseudo_table[] = {
  51. { "common", s_common, 0 },
  52. { "global", s_globl, 0 },
  53. { "half", cons, 2 },
  54. { "proc", s_proc, 0 },
  55. { "reserve", s_reserve, 0 },
  56. { "seg", s_seg, 0 },
  57. { "skip", s_space, 0 },
  58. { "word", cons, 4 },
  59. { NULL, 0, 0 },
  60. };
  61. int md_short_jump_size = 4;
  62. int md_long_jump_size = 4;
  63. int omagic = (0x103 << 16) | OMAGIC; /* Magic number for header */
  64. /* This array holds the chars that always start a comment. If the
  65. pre-processor is disabled, these aren't very useful */
  66. char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
  67. /* This array holds the chars that only start a comment at the beginning of
  68. a line. If the line seems to have the form '# 123 filename'
  69. .line and .file directives will appear in the pre-processed output */
  70. /* Note that input_file.c hand checks for '#' at the beginning of the
  71. first line of the input file. This is because the compiler outputs
  72. #NO_APP at the beginning of its output. */
  73. /* Also note that '/*' will always start a comment */
  74. char line_comment_chars[] = "#";
  75. /* Chars that can be used to separate mant from exp in floating point nums */
  76. char EXP_CHARS[] = "eE";
  77. /* Chars that mean this number is a floating point constant */
  78. /* As in 0f12.456 */
  79. /* or 0d1.2345e12 */
  80. char FLT_CHARS[] = "rRsSfFdDxXpP";
  81. /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
  82. changed in read.c . Ideally it shouldn't have to know about it at all,
  83. but nothing is ideal around here.
  84. */
  85. int size_reloc_info = sizeof(struct reloc_info_sparc);
  86. static unsigned char octal[256];
  87. #define isoctal(c) octal[c]
  88. static unsigned char toHex[256];
  89. /*
  90. * anull bit - causes the branch delay slot instructions to not be executed
  91. */
  92. #define ANNUL (1 << 29)
  93. struct sparc_it {
  94. char *error;
  95. unsigned long opcode;
  96. struct nlist *nlistp;
  97. expressionS exp;
  98. int pcrel;
  99. enum reloc_type reloc;
  100. } the_insn, set_insn;
  101. #ifdef __STDC__
  102. static void print_insn(struct sparc_it *insn);
  103. static int getExpression(char *str);
  104. #else
  105. static void print_insn();
  106. static int getExpression();
  107. #endif
  108. static char *expr_end;
  109. static int special_case;
  110. #define SPECIAL_CASE_SET 1
  111. /*
  112. * sort of like s_lcomm
  113. *
  114. */
  115. static void
  116. s_reserve()
  117. {
  118. char *name;
  119. char c;
  120. char *p;
  121. int temp;
  122. symbolS *symbolP;
  123. name = input_line_pointer;
  124. c = get_symbol_end();
  125. p = input_line_pointer;
  126. *p = c;
  127. SKIP_WHITESPACE();
  128. if ( * input_line_pointer != ',' ) {
  129. as_warn("Expected comma after name");
  130. ignore_rest_of_line();
  131. return;
  132. }
  133. input_line_pointer ++;
  134. if ((temp = get_absolute_expression()) < 0) {
  135. as_warn("BSS length (%d.) <0! Ignored.", temp);
  136. ignore_rest_of_line();
  137. return;
  138. }
  139. *p = 0;
  140. symbolP = symbol_find_or_make(name);
  141. *p = c;
  142. if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
  143. as_warn("bad .reserve segment: `%s'", input_line_pointer);
  144. return;
  145. }
  146. input_line_pointer += 6;
  147. if (symbolP->sy_other == 0
  148. && symbolP->sy_desc == 0
  149. && ((symbolP->sy_type == N_BSS
  150. && symbolP->sy_value == local_bss_counter)
  151. || ((symbolP->sy_type & N_TYPE) == N_UNDF
  152. && symbolP->sy_value == 0))) {
  153. symbolP->sy_value = local_bss_counter;
  154. symbolP->sy_type = N_BSS;
  155. symbolP->sy_frag = & bss_address_frag;
  156. local_bss_counter += temp;
  157. } else {
  158. as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
  159. symbolP->sy_value, local_bss_counter );
  160. }
  161. demand_empty_rest_of_line();
  162. return;
  163. }
  164. static void
  165. s_common()
  166. {
  167. register char *name;
  168. register char c;
  169. register char *p;
  170. register int temp;
  171. register symbolS * symbolP;
  172. name = input_line_pointer;
  173. c = get_symbol_end();
  174. /* just after name is now '\0' */
  175. p = input_line_pointer;
  176. *p = c;
  177. SKIP_WHITESPACE();
  178. if ( * input_line_pointer != ',' ) {
  179. as_warn("Expected comma after symbol-name");
  180. ignore_rest_of_line();
  181. return;
  182. }
  183. input_line_pointer ++; /* skip ',' */
  184. if ( (temp = get_absolute_expression ()) < 0 ) {
  185. as_warn(".COMMon length (%d.) <0! Ignored.", temp);
  186. ignore_rest_of_line();
  187. return;
  188. }
  189. *p = 0;
  190. symbolP = symbol_find_or_make (name);
  191. *p = c;
  192. if ( (symbolP->sy_type & N_TYPE) != N_UNDF ||
  193. symbolP->sy_other != 0 || symbolP->sy_desc != 0) {
  194. as_warn( "Ignoring attempt to re-define symbol");
  195. ignore_rest_of_line();
  196. return;
  197. }
  198. if (symbolP->sy_value) {
  199. if (symbolP->sy_value != temp) {
  200. as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
  201. symbolP->sy_name, symbolP->sy_value, temp);
  202. }
  203. } else {
  204. symbolP->sy_value = temp;
  205. symbolP->sy_type |= N_EXT;
  206. }
  207. know(symbolP->sy_frag == &zero_address_frag);
  208. if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
  209. p=input_line_pointer;
  210. while(*p && *p!='\n')
  211. p++;
  212. c= *p;
  213. *p='\0';
  214. as_warn("bad .common segment: `%s'", input_line_pointer);
  215. *p=c;
  216. return;
  217. }
  218. input_line_pointer += 6;
  219. demand_empty_rest_of_line();
  220. return;
  221. }
  222. static void
  223. s_seg()
  224. {
  225. if (strncmp(input_line_pointer, "\"text\"", 6) == 0) {
  226. input_line_pointer += 6;
  227. s_text();
  228. return;
  229. }
  230. if (strncmp(input_line_pointer, "\"data\"", 6) == 0) {
  231. input_line_pointer += 6;
  232. s_data();
  233. return;
  234. }
  235. if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) {
  236. input_line_pointer += 7;
  237. s_data1();
  238. return;
  239. }
  240. as_warn("Unknown segment type");
  241. demand_empty_rest_of_line();
  242. return;
  243. }
  244. static void
  245. s_data1()
  246. {
  247. subseg_new(SEG_DATA, 1);
  248. demand_empty_rest_of_line();
  249. return;
  250. }
  251. static void
  252. s_proc()
  253. {
  254. extern char is_end_of_line[];
  255. while (!is_end_of_line[*input_line_pointer]) {
  256. ++input_line_pointer;
  257. }
  258. ++input_line_pointer;
  259. return;
  260. }
  261. static void
  262. s_sparc_align()
  263. {
  264. register unsigned int temp;
  265. register long int temp_fill;
  266. unsigned int i;
  267. temp = get_absolute_expression ();
  268. #define MAX_ALIGNMENT (1 << 15)
  269. if ( temp > MAX_ALIGNMENT ) {
  270. as_warn("Alignment too large: %d. assumed.", temp = MAX_ALIGNMENT);
  271. }
  272. /*
  273. * For the sparc, `.align (1<<n)' actually means `.align n'
  274. * so we have to convert it.
  275. */
  276. if (temp != 0) {
  277. for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
  278. ;
  279. }
  280. if (temp != 1) {
  281. as_warn("Alignment not a power of 2");
  282. }
  283. temp = i;
  284. if (*input_line_pointer == ',') {
  285. input_line_pointer ++;
  286. temp_fill = get_absolute_expression ();
  287. } else {
  288. temp_fill = 0;
  289. }
  290. /* Only make a frag if we HAVE to. . . */
  291. if (temp && ! need_pass_2) {
  292. frag_align (temp, (int)temp_fill);
  293. }
  294. demand_empty_rest_of_line();
  295. return;
  296. }
  297. /* This function is called once, at assembler startup time. It should
  298. set up all the tables, etc. that the MD part of the assembler will need. */
  299. void
  300. md_begin()
  301. {
  302. register char *retval = NULL;
  303. int lose = 0;
  304. register unsigned int i = 0;
  305. op_hash = hash_new();
  306. if (op_hash == NULL)
  307. as_fatal("Virtual memory exhausted");
  308. while (i < NUMOPCODES)
  309. {
  310. const char *name = sparc_opcodes[i].name;
  311. retval = hash_insert(op_hash, name, &sparc_opcodes[i]);
  312. if(retval != NULL && *retval != '\0')
  313. {
  314. fprintf (stderr, "internal error: can't hash `%s': %s\n",
  315. sparc_opcodes[i].name, retval);
  316. lose = 1;
  317. }
  318. do
  319. {
  320. if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
  321. {
  322. fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
  323. sparc_opcodes[i].name, sparc_opcodes[i].args);
  324. lose = 1;
  325. }
  326. ++i;
  327. } while (i < NUMOPCODES
  328. && !strcmp(sparc_opcodes[i].name, name));
  329. }
  330. if (lose)
  331. as_fatal ("Broken assembler. No assembly attempted.");
  332. for (i = '0'; i < '8'; ++i)
  333. octal[i] = 1;
  334. for (i = '0'; i <= '9'; ++i)
  335. toHex[i] = i - '0';
  336. for (i = 'a'; i <= 'f'; ++i)
  337. toHex[i] = i + 10 - 'a';
  338. for (i = 'A'; i <= 'F'; ++i)
  339. toHex[i] = i + 10 - 'A';
  340. }
  341. void
  342. md_end()
  343. {
  344. return;
  345. }
  346. void
  347. md_assemble(str)
  348. char *str;
  349. {
  350. char *toP;
  351. int rsd;
  352. assert(str);
  353. sparc_ip(str);
  354. toP = frag_more(4);
  355. /* put out the opcode */
  356. md_number_to_chars(toP, the_insn.opcode, 4);
  357. /* put out the symbol-dependent stuff */
  358. if (the_insn.reloc != NO_RELOC) {
  359. fix_new(
  360. frag_now, /* which frag */
  361. (toP - frag_now->fr_literal), /* where */
  362. 4, /* size */
  363. the_insn.exp.X_add_symbol,
  364. the_insn.exp.X_subtract_symbol,
  365. the_insn.exp.X_add_number,
  366. the_insn.pcrel,
  367. the_insn.reloc
  368. );
  369. }
  370. switch (special_case) {
  371. case SPECIAL_CASE_SET:
  372. special_case = 0;
  373. assert(the_insn.reloc == RELOC_HI22);
  374. toP = frag_more(4);
  375. rsd = (the_insn.opcode >> 25) & 0x1f;
  376. the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
  377. md_number_to_chars(toP, the_insn.opcode, 4);
  378. fix_new(
  379. frag_now, /* which frag */
  380. (toP - frag_now->fr_literal), /* where */
  381. 4, /* size */
  382. the_insn.exp.X_add_symbol,
  383. the_insn.exp.X_subtract_symbol,
  384. the_insn.exp.X_add_number,
  385. the_insn.pcrel,
  386. RELOC_LO10
  387. );
  388. return;
  389. case 0:
  390. return;
  391. default:
  392. abort();
  393. }
  394. }
  395. static void
  396. sparc_ip(str)
  397. char *str;
  398. {
  399. char *s;
  400. const char *args;
  401. char c;
  402. unsigned long i;
  403. struct sparc_opcode *insn;
  404. char *argsStart;
  405. unsigned long opcode;
  406. unsigned int mask;
  407. int match = FALSE;
  408. int comma = 0;
  409. for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
  410. ;
  411. switch (*s) {
  412. case '\0':
  413. break;
  414. case ',':
  415. comma = 1;
  416. /*FALLTHROUGH*/
  417. case ' ':
  418. *s++ = '\0';
  419. break;
  420. default:
  421. as_warn("Unknown opcode: `%s'", str);
  422. exit(1);
  423. }
  424. if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) {
  425. as_warn("`%s' not in hash table.", str);
  426. return;
  427. }
  428. if (comma) {
  429. *--s = ',';
  430. }
  431. argsStart = s;
  432. for (;;) {
  433. opcode = insn->match;
  434. bzero(&the_insn, sizeof(the_insn));
  435. the_insn.reloc = NO_RELOC;
  436. /*
  437. * Build the opcode, checking as we go to make
  438. * sure that the operands match
  439. */
  440. for (args = insn->args; ; ++args) {
  441. switch (*args) {
  442. case '\0': /* end of args */
  443. if (*s == '\0') {
  444. match = TRUE;
  445. }
  446. break;
  447. case '+':
  448. if (*s == '+') {
  449. ++s;
  450. continue;
  451. }
  452. if (*s == '-') {
  453. continue;
  454. }
  455. break;
  456. case '[': /* these must match exactly */
  457. case ']':
  458. case ',':
  459. case ' ':
  460. if (*s++ == *args)
  461. continue;
  462. break;
  463. case '#': /* must be at least one digit */
  464. if (isdigit(*s++)) {
  465. while (isdigit(*s)) {
  466. ++s;
  467. }
  468. continue;
  469. }
  470. break;
  471. case 'C': /* coprocessor state register */
  472. if (strncmp(s, "%csr", 4) == 0) {
  473. s += 4;
  474. continue;
  475. }
  476. break;
  477. case 'b': /* next operand is a coprocessor register */
  478. case 'c':
  479. case 'D':
  480. if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) {
  481. mask = *s++;
  482. if (isdigit(*s)) {
  483. mask = 10 * (mask - '0') + (*s++ - '0');
  484. if (mask >= 32) {
  485. break;
  486. }
  487. } else {
  488. mask -= '0';
  489. }
  490. switch (*args) {
  491. case 'b':
  492. opcode |= mask << 14;
  493. continue;
  494. case 'c':
  495. opcode |= mask;
  496. continue;
  497. case 'D':
  498. opcode |= mask << 25;
  499. continue;
  500. }
  501. }
  502. break;
  503. case 'r': /* next operand must be a register */
  504. case '1':
  505. case '2':
  506. case 'd':
  507. if (*s++ == '%') {
  508. switch (c = *s++) {
  509. case 'f': /* frame pointer */
  510. if (*s++ == 'p') {
  511. mask = 0x1e;
  512. break;
  513. }
  514. goto error;
  515. case 'g': /* global register */
  516. if (isoctal(c = *s++)) {
  517. mask = c - '0';
  518. break;
  519. }
  520. goto error;
  521. case 'i': /* in register */
  522. if (isoctal(c = *s++)) {
  523. mask = c - '0' + 24;
  524. break;
  525. }
  526. goto error;
  527. case 'l': /* local register */
  528. if (isoctal(c = *s++)) {
  529. mask= (c - '0' + 16) ;
  530. break;
  531. }
  532. goto error;
  533. case 'o': /* out register */
  534. if (isoctal(c = *s++)) {
  535. mask= (c - '0' + 8) ;
  536. break;
  537. }
  538. goto error;
  539. case 's': /* stack pointer */
  540. if (*s++ == 'p') {
  541. mask= 0xe;
  542. break;
  543. }
  544. goto error;
  545. case 'r': /* any register */
  546. if (!isdigit(c = *s++)) {
  547. goto error;
  548. }
  549. /* FALLTHROUGH */
  550. case '0': case '1': case '2': case '3': case '4':
  551. case '5': case '6': case '7': case '8': case '9':
  552. if (isdigit(*s)) {
  553. if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
  554. goto error;
  555. }
  556. } else {
  557. c -= '0';
  558. }
  559. mask= c;
  560. break;
  561. default:
  562. goto error;
  563. }
  564. /*
  565. * Got the register, now figure out where
  566. * it goes in the opcode.
  567. */
  568. switch (*args) {
  569. case '1':
  570. opcode |= mask << 14;
  571. continue;
  572. case '2':
  573. opcode |= mask;
  574. continue;
  575. case 'd':
  576. opcode |= mask << 25;
  577. continue;
  578. case 'r':
  579. opcode |= (mask << 25) | (mask << 14);
  580. continue;
  581. }
  582. }
  583. break;
  584. case 'e': /* next operand is a floating point register */
  585. case 'f':
  586. case 'g':
  587. if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
  588. mask = *s++;
  589. if (isdigit(*s)) {
  590. mask = 10 * (mask - '0') + (*s++ - '0');
  591. if (mask >= 32) {
  592. break;
  593. }
  594. } else {
  595. mask -= '0';
  596. }
  597. switch (*args) {
  598. case 'e':
  599. opcode |= mask << 14;
  600. continue;
  601. case 'f':
  602. opcode |= mask;
  603. continue;
  604. case 'g':
  605. opcode |= mask << 25;
  606. continue;
  607. }
  608. }
  609. break;
  610. case 'F':
  611. if (strncmp(s, "%fsr", 4) == 0) {
  612. s += 4;
  613. continue;
  614. }
  615. break;
  616. case 'h': /* high 22 bits */
  617. the_insn.reloc = RELOC_HI22;
  618. goto immediate;
  619. case 'l': /* 22 bit PC relative immediate */
  620. the_insn.reloc = RELOC_WDISP22;
  621. the_insn.pcrel = 1;
  622. goto immediate;
  623. case 'L': /* 30 bit immediate */
  624. the_insn.reloc = RELOC_WDISP30;
  625. the_insn.pcrel = 1;
  626. goto immediate;
  627. case 'i': /* 13 bit immediate */
  628. the_insn.reloc = RELOC_BASE13;
  629. /*FALLTHROUGH*/
  630. immediate:
  631. if(*s==' ')
  632. s++;
  633. if (*s == '%') {
  634. if ((c = s[1]) == 'h' && s[2] == 'i') {
  635. the_insn.reloc = RELOC_HI22;
  636. s+=3;
  637. } else if (c == 'l' && s[2] == 'o') {
  638. the_insn.reloc = RELOC_LO10;
  639. s+=3;
  640. } else
  641. break;
  642. }
  643. /* Note that if the getExpression() fails, we will still have
  644. created U entries in the symbol table for the 'symbols'
  645. in the input string. Try not to create U symbols for
  646. registers, etc. */
  647. {
  648. /* This stuff checks to see if the expression ends
  649. in +%reg If it does, it removes the register from
  650. the expression, and re-sets 's' to point to the
  651. right place */
  652. char *s1;
  653. for(s1=s;*s1 && *s1!=','&& *s1!=']';s1++)
  654. ;
  655. if(s1!=s && isdigit(s1[-1])) {
  656. if(s1[-2]=='%' && s1[-3]=='+') {
  657. s1-=3;
  658. *s1='\0';
  659. (void)getExpression(s);
  660. *s1='+';
  661. s=s1;
  662. continue;
  663. } else if(index("goli0123456789",s1[-2]) && s1[-3]=='%' && s1[-4]=='+') {
  664. s1-=4;
  665. *s1='\0';
  666. (void)getExpression(s);
  667. *s1='+';
  668. s=s1;
  669. continue;
  670. }
  671. }
  672. }
  673. (void)getExpression(s);
  674. s = expr_end;
  675. continue;
  676. case 'a':
  677. if (*s++ == 'a') {
  678. opcode |= ANNUL;
  679. continue;
  680. }
  681. break;
  682. case 'A': /* alternate space */
  683. abort();
  684. case 'p':
  685. if (strncmp(s, "%psr", 4) == 0) {
  686. s += 4;
  687. continue;
  688. }
  689. break;
  690. case 'q': /* floating point queue */
  691. if (strncmp(s, "%fq", 3) == 0) {
  692. s += 3;
  693. continue;
  694. }
  695. break;
  696. case 'Q': /* coprocessor queue */
  697. if (strncmp(s, "%cq", 3) == 0) {
  698. s += 3;
  699. continue;
  700. }
  701. break;
  702. case 'S':
  703. if (strcmp(str, "set") == 0) {
  704. special_case = SPECIAL_CASE_SET;
  705. continue;
  706. }
  707. break;
  708. case 't':
  709. if (strncmp(s, "%tbr", 4) != 0)
  710. break;
  711. s += 4;
  712. continue;
  713. case 'w':
  714. if (strncmp(s, "%wim", 4) != 0)
  715. break;
  716. s += 4;
  717. continue;
  718. case 'y':
  719. if (strncmp(s, "%y", 2) != 0)
  720. break;
  721. s += 2;
  722. continue;
  723. default:
  724. abort();
  725. }
  726. break;
  727. }
  728. error:
  729. if (match == FALSE)
  730. {
  731. /* Args don't match. */
  732. if (&insn[1] - sparc_opcodes < NUMOPCODES
  733. && !strcmp(insn->name, insn[1].name))
  734. {
  735. ++insn;
  736. s = argsStart;
  737. continue;
  738. }
  739. else
  740. {
  741. as_warn("Illegal operands");
  742. return;
  743. }
  744. }
  745. break;
  746. }
  747. the_insn.opcode = opcode;
  748. return;
  749. }
  750. static int
  751. getExpression(str)
  752. char *str;
  753. {
  754. char *save_in;
  755. segT seg;
  756. save_in = input_line_pointer;
  757. input_line_pointer = str;
  758. switch (seg = expression(&the_insn.exp)) {
  759. case SEG_ABSOLUTE:
  760. case SEG_TEXT:
  761. case SEG_DATA:
  762. case SEG_BSS:
  763. case SEG_UNKNOWN:
  764. case SEG_DIFFERENCE:
  765. case SEG_BIG:
  766. case SEG_NONE:
  767. break;
  768. default:
  769. the_insn.error = "bad segment";
  770. expr_end = input_line_pointer;
  771. input_line_pointer=save_in;
  772. return 1;
  773. }
  774. expr_end = input_line_pointer;
  775. input_line_pointer = save_in;
  776. return 0;
  777. }
  778. #define MAX_LITTLENUMS 6
  779. /*
  780. This is identical to the md_atof in m68k.c. I think this is right,
  781. but I'm not sure.
  782. Turn a string in input_line_pointer into a floating point constant of type
  783. type, and store the appropriate bytes in *litP. The number of LITTLENUMS
  784. emitted is stored in *sizeP . An error message is returned, or NULL on OK.
  785. */
  786. char *
  787. md_atof(type,litP,sizeP)
  788. char type;
  789. char *litP;
  790. int *sizeP;
  791. {
  792. int prec;
  793. LITTLENUM_TYPE words[MAX_LITTLENUMS];
  794. LITTLENUM_TYPE *wordP;
  795. char *t;
  796. char *atof_m68k();
  797. switch(type) {
  798. case 'f':
  799. case 'F':
  800. case 's':
  801. case 'S':
  802. prec = 2;
  803. break;
  804. case 'd':
  805. case 'D':
  806. case 'r':
  807. case 'R':
  808. prec = 4;
  809. break;
  810. case 'x':
  811. case 'X':
  812. prec = 6;
  813. break;
  814. case 'p':
  815. case 'P':
  816. prec = 6;
  817. break;
  818. default:
  819. *sizeP=0;
  820. return "Bad call to MD_ATOF()";
  821. }
  822. t=atof_m68k(input_line_pointer,type,words);
  823. if(t)
  824. input_line_pointer=t;
  825. *sizeP=prec * sizeof(LITTLENUM_TYPE);
  826. for(wordP=words;prec--;) {
  827. md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
  828. litP+=sizeof(LITTLENUM_TYPE);
  829. }
  830. return ""; /* Someone should teach Dean about null pointers */
  831. }
  832. /*
  833. * Write out big-endian.
  834. */
  835. void
  836. md_number_to_chars(buf,val,n)
  837. char *buf;
  838. long val;
  839. int n;
  840. {
  841. switch(n) {
  842. case 4:
  843. *buf++ = val >> 24;
  844. *buf++ = val >> 16;
  845. case 2:
  846. *buf++ = val >> 8;
  847. case 1:
  848. *buf = val;
  849. break;
  850. default:
  851. abort();
  852. }
  853. return;
  854. }
  855. void
  856. md_number_to_imm(buf,val,n, fixP, seg_type)
  857. char *buf;
  858. long val;
  859. int n;
  860. fixS *fixP;
  861. int seg_type;
  862. {
  863. if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC) {
  864. switch (n) {
  865. case 1:
  866. *buf = val;
  867. break;
  868. case 2:
  869. *buf++ = (val>>8);
  870. *buf = val;
  871. break;
  872. case 4:
  873. *buf++ = (val>>24);
  874. *buf++ = (val>>16);
  875. *buf++ = (val>>8);
  876. *buf = val;
  877. break;
  878. default:
  879. abort();
  880. }
  881. return;
  882. }
  883. assert(n == 4);
  884. assert(fixP->fx_r_type < NO_RELOC);
  885. /*
  886. * This is a hack. There should be a better way to
  887. * handle this.
  888. */
  889. if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
  890. val += fixP->fx_where + fixP->fx_frag->fr_address;
  891. }
  892. switch (fixP->fx_r_type) {
  893. case RELOC_32:
  894. buf[0] = val >> 24;
  895. buf[1] = val >> 16;
  896. buf[2] = val >> 8;
  897. buf[3] = val;
  898. break;
  899. #if 0
  900. case RELOC_8: /* These don't seem to ever be needed. */
  901. case RELOC_16:
  902. case RELOC_DISP8:
  903. case RELOC_DISP16:
  904. case RELOC_DISP32:
  905. #endif
  906. case RELOC_WDISP30:
  907. val = (val >>= 2) + 1;
  908. buf[0] |= (val >> 24) & 0x3f;
  909. buf[1]= (val >> 16);
  910. buf[2] = val >> 8;
  911. buf[3] = val;
  912. break;
  913. case RELOC_HI22:
  914. buf[1] |= (val >> 26) & 0x3f;
  915. buf[2] = val >> 18;
  916. buf[3] = val >> 10;
  917. break;
  918. #if 0
  919. case RELOC_22:
  920. case RELOC_13:
  921. #endif
  922. case RELOC_LO10:
  923. buf[2] |= (val >> 8) & 0x03;
  924. buf[3] = val;
  925. break;
  926. #if 0
  927. case RELOC_SFA_BASE:
  928. case RELOC_SFA_OFF13:
  929. case RELOC_BASE10:
  930. #endif
  931. case RELOC_BASE13:
  932. buf[2] |= (val >> 8) & 0x1f;
  933. buf[3] = val;
  934. break;
  935. case RELOC_WDISP22:
  936. val = (val >>= 2) + 1;
  937. /* FALLTHROUGH */
  938. case RELOC_BASE22:
  939. buf[1] |= (val >> 16) & 0x3f;
  940. buf[2] = val >> 8;
  941. buf[3] = val;
  942. break;
  943. #if 0
  944. case RELOC_PC10:
  945. case RELOC_PC22:
  946. case RELOC_JMP_TBL:
  947. case RELOC_SEGOFF16:
  948. case RELOC_GLOB_DAT:
  949. case RELOC_JMP_SLOT:
  950. case RELOC_RELATIVE:
  951. #endif
  952. case NO_RELOC:
  953. default:
  954. as_warn("bad relocation type: 0x%02x", fixP->fx_r_type);
  955. break;
  956. }
  957. return;
  958. }
  959. /* should never be called for sparc */
  960. void
  961. md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
  962. char *ptr;
  963. long from_addr, to_addr;
  964. {
  965. fprintf(stderr, "sparc_create_short_jmp\n");
  966. abort();
  967. }
  968. /* should never be called for sparc */
  969. void
  970. md_number_to_disp(buf,val,n)
  971. char *buf;
  972. long val;
  973. {
  974. fprintf(stderr, "md_number_to_disp\n");
  975. abort();
  976. }
  977. /* should never be called for sparc */
  978. void
  979. md_number_to_field(buf,val,fix)
  980. char *buf;
  981. long val;
  982. void *fix;
  983. {
  984. fprintf(stderr, "sparc_number_to_field\n");
  985. abort();
  986. }
  987. void
  988. md_ri_to_chars(ri_p, ri)
  989. struct reloc_info_sparc *ri_p, ri;
  990. {
  991. /*
  992. * if you want to cross-assemble from
  993. * a little-endian then you might need to
  994. * do some byte-swapping here.
  995. */
  996. return;
  997. }
  998. /* should never be called for sparc */
  999. void
  1000. md_convert_frag(fragP)
  1001. register fragS *fragP;
  1002. {
  1003. fprintf(stderr, "sparc_convert_frag\n");
  1004. abort();
  1005. }
  1006. /* should never be called for sparc */
  1007. void
  1008. md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
  1009. char *ptr;
  1010. long from_addr,
  1011. to_addr;
  1012. fragS *frag;
  1013. symbolS *to_symbol;
  1014. {
  1015. fprintf(stderr, "sparc_create_long_jump\n");
  1016. abort();
  1017. }
  1018. /* should never be called for sparc */
  1019. int
  1020. md_estimate_size_before_relax(fragP, segtype)
  1021. register fragS *fragP;
  1022. {
  1023. fprintf(stderr, "sparc_estimate_size_before_relax\n");
  1024. abort();
  1025. return 0;
  1026. }
  1027. #if 0
  1028. /* for debugging only */
  1029. static void
  1030. print_insn(insn)
  1031. struct sparc_it *insn;
  1032. {
  1033. char *Reloc[] = {
  1034. "RELOC_8",
  1035. "RELOC_16",
  1036. "RELOC_32",
  1037. "RELOC_DISP8",
  1038. "RELOC_DISP16",
  1039. "RELOC_DISP32",
  1040. "RELOC_WDISP30",
  1041. "RELOC_WDISP22",
  1042. "RELOC_HI22",
  1043. "RELOC_22",
  1044. "RELOC_13",
  1045. "RELOC_LO10",
  1046. "RELOC_SFA_BASE",
  1047. "RELOC_SFA_OFF13",
  1048. "RELOC_BASE10",
  1049. "RELOC_BASE13",
  1050. "RELOC_BASE22",
  1051. "RELOC_PC10",
  1052. "RELOC_PC22",
  1053. "RELOC_JMP_TBL",
  1054. "RELOC_SEGOFF16",
  1055. "RELOC_GLOB_DAT",
  1056. "RELOC_JMP_SLOT",
  1057. "RELOC_RELATIVE",
  1058. "NO_RELOC"
  1059. };
  1060. if (insn->error) {
  1061. fprintf(stderr, "ERROR: %s\n");
  1062. }
  1063. fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
  1064. fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
  1065. fprintf(stderr, "exp = {\n");
  1066. fprintf(stderr, "\t\tX_add_symbol = %s\n",
  1067. insn->exp.X_add_symbol ?
  1068. (insn->exp.X_add_symbol->sy_name ?
  1069. insn->exp.X_add_symbol->sy_name : "???") : "0");
  1070. fprintf(stderr, "\t\tX_sub_symbol = %s\n",
  1071. insn->exp.X_subtract_symbol ?
  1072. (insn->exp.X_subtract_symbol->sy_name ?
  1073. insn->exp.X_subtract_symbol->sy_name : "???") : "0");
  1074. fprintf(stderr, "\t\tX_add_number = %d\n",
  1075. insn->exp.X_add_number);
  1076. fprintf(stderr, "}\n");
  1077. return;
  1078. }
  1079. #endif
  1080. /*
  1081. * Sparc relocations are completely different, so it needs
  1082. * this machine dependent routine to emit them.
  1083. */
  1084. void
  1085. emit_relocations(fixP, segment_address_in_file)
  1086. register fixS *fixP;
  1087. relax_addressT segment_address_in_file;
  1088. {
  1089. struct reloc_info_sparc ri;
  1090. register symbolS *symbolP;
  1091. extern char *next_object_file_charP;
  1092. long add_number;
  1093. bzero((char *) &ri, sizeof(ri));
  1094. for (; fixP; fixP = fixP->fx_next) {
  1095. if (fixP->fx_r_type >= NO_RELOC) {
  1096. fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
  1097. abort();
  1098. }
  1099. if ((symbolP = fixP->fx_addsy) != NULL) {
  1100. ri.r_address = fixP->fx_frag->fr_address +
  1101. fixP->fx_where - segment_address_in_file;
  1102. if ((symbolP->sy_type & N_TYPE) == N_UNDF) {
  1103. ri.r_extern = 1;
  1104. ri.r_index = symbolP->sy_number;
  1105. } else {
  1106. ri.r_extern = 0;
  1107. ri.r_index = symbolP->sy_type & N_TYPE;
  1108. }
  1109. if (symbolP && symbolP->sy_frag) {
  1110. ri.r_addend = symbolP->sy_frag->fr_address;
  1111. }
  1112. ri.r_type = fixP->fx_r_type;
  1113. if (fixP->fx_pcrel) {
  1114. /* ri.r_addend -= fixP->fx_where; */
  1115. ri.r_addend -= ri.r_address;
  1116. } else {
  1117. ri.r_addend = fixP->fx_addnumber;
  1118. }
  1119. /* md_ri_to_chars((char *) &ri, ri); */
  1120. append(&next_object_file_charP, (char *)& ri, sizeof(ri));
  1121. }
  1122. }
  1123. return;
  1124. }
  1125. int
  1126. md_parse_option(argP,cntP,vecP)
  1127. char **argP;
  1128. int *cntP;
  1129. char ***vecP;
  1130. {
  1131. return 1;
  1132. }