1 /* tc-sparc.c -- Assemble for the SPARC
2 Copyright (C) 1989, 90-95, 1996 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 /* careful, this file includes data *declarations* */
27 #include "opcode/sparc.h"
29 static void sparc_ip PARAMS ((char *));
31 /* Current architecture. We don't bump up unless necessary. */
32 static enum sparc_opcode_arch_val current_architecture = SPARC_OPCODE_ARCH_V6;
34 /* The maximum architecture level we can bump up to.
35 In a 32 bit environment, don't allow bumping up to v9 by default.
36 The native assembler works this way. The user is required to pass
37 an explicit argument before we'll create v9 object files. However, if
38 we don't see any v9 insns, a v9 object file is not created. */
40 static enum sparc_opcode_arch_val max_architecture = SPARC_OPCODE_ARCH_V9;
42 static enum sparc_opcode_arch_val max_architecture = SPARC_OPCODE_ARCH_V8;
45 static int architecture_requested;
46 static int warn_on_bump;
48 /* If warn_on_bump and the needed architecture is higher than this
49 architecture, issue a warning. */
50 static enum sparc_opcode_arch_val warn_after_architecture;
52 /* Non-zero if we are generating PIC code. */
55 extern int target_big_endian;
57 /* handle of the OPCODE hash table */
58 static struct hash_control *op_hash;
60 static void s_data1 PARAMS ((void));
61 static void s_seg PARAMS ((int));
62 static void s_proc PARAMS ((int));
63 static void s_reserve PARAMS ((int));
64 static void s_common PARAMS ((int));
66 const pseudo_typeS md_pseudo_table[] =
68 {"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
69 {"common", s_common, 0},
70 {"global", s_globl, 0},
72 {"optim", s_ignore, 0},
74 {"reserve", s_reserve, 0},
83 /* these are specific to sparc/svr4 */
84 {"pushsection", obj_elf_section, 0},
85 {"popsection", obj_elf_previous, 0},
92 const int md_reloc_size = 12; /* Size of relocation record */
94 /* This array holds the chars that always start a comment. If the
95 pre-processor is disabled, these aren't very useful */
96 const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
98 /* This array holds the chars that only start a comment at the beginning of
99 a line. If the line seems to have the form '# 123 filename'
100 .line and .file directives will appear in the pre-processed output */
101 /* Note that input_file.c hand checks for '#' at the beginning of the
102 first line of the input file. This is because the compiler outputs
103 #NO_APP at the beginning of its output. */
104 /* Also note that comments started like this one will always
105 work if '/' isn't otherwise defined. */
106 const char line_comment_chars[] = "#";
108 const char line_separator_chars[] = "";
110 /* Chars that can be used to separate mant from exp in floating point nums */
111 const char EXP_CHARS[] = "eE";
113 /* Chars that mean this number is a floating point constant */
116 const char FLT_CHARS[] = "rRsSfFdDxXpP";
118 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
119 changed in read.c. Ideally it shouldn't have to know about it at all,
120 but nothing is ideal around here. */
122 static unsigned char octal[256];
123 #define isoctal(c) octal[(unsigned char) (c)]
124 static unsigned char toHex[256];
129 unsigned long opcode;
130 struct nlist *nlistp;
133 bfd_reloc_code_real_type reloc;
136 struct sparc_it the_insn, set_insn;
139 in_signed_range (val, max)
140 bfd_signed_vma val, max;
152 static void print_insn PARAMS ((struct sparc_it *insn));
154 static int getExpression PARAMS ((char *str));
156 static char *expr_end;
157 static int special_case;
160 * Instructions that require wierd handling because they're longer than
163 #define SPECIAL_CASE_SET 1
164 #define SPECIAL_CASE_FDIV 2
167 * sort of like s_lcomm
171 static int max_alignment = 15;
186 name = input_line_pointer;
187 c = get_symbol_end ();
188 p = input_line_pointer;
192 if (*input_line_pointer != ',')
194 as_bad ("Expected comma after name");
195 ignore_rest_of_line ();
199 ++input_line_pointer;
201 if ((size = get_absolute_expression ()) < 0)
203 as_bad ("BSS length (%d.) <0! Ignored.", size);
204 ignore_rest_of_line ();
209 symbolP = symbol_find_or_make (name);
212 if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
213 && strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
215 as_bad ("bad .reserve segment -- expected BSS segment");
219 if (input_line_pointer[2] == '.')
220 input_line_pointer += 7;
222 input_line_pointer += 6;
225 if (*input_line_pointer == ',')
227 ++input_line_pointer;
230 if (*input_line_pointer == '\n')
232 as_bad ("Missing alignment");
236 align = get_absolute_expression ();
238 if (align > max_alignment)
240 align = max_alignment;
241 as_warn ("Alignment too large: %d. assumed.", align);
247 as_warn ("Alignment negative. 0 assumed.");
250 record_alignment (bss_section, align);
252 /* convert to a power of 2 alignment */
253 for (temp = 0; (align & 1) == 0; align >>= 1, ++temp);;
257 as_bad ("Alignment not a power of 2");
258 ignore_rest_of_line ();
260 } /* not a power of two */
263 } /* if has optional alignment */
267 if (!S_IS_DEFINED (symbolP)
269 && S_GET_OTHER (symbolP) == 0
270 && S_GET_DESC (symbolP) == 0
277 segT current_seg = now_seg;
278 subsegT current_subseg = now_subseg;
280 subseg_set (bss_section, 1); /* switch to bss */
283 frag_align (align, 0); /* do alignment */
285 /* detach from old frag */
286 if (S_GET_SEGMENT(symbolP) == bss_section)
287 symbolP->sy_frag->fr_symbol = NULL;
289 symbolP->sy_frag = frag_now;
290 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
294 S_SET_SEGMENT (symbolP, bss_section);
296 subseg_set (current_seg, current_subseg);
301 as_warn("Ignoring attempt to re-define symbol %s",
302 S_GET_NAME (symbolP));
303 } /* if not redefining */
305 demand_empty_rest_of_line ();
318 name = input_line_pointer;
319 c = get_symbol_end ();
320 /* just after name is now '\0' */
321 p = input_line_pointer;
324 if (*input_line_pointer != ',')
326 as_bad ("Expected comma after symbol-name");
327 ignore_rest_of_line ();
330 input_line_pointer++; /* skip ',' */
331 if ((temp = get_absolute_expression ()) < 0)
333 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
334 ignore_rest_of_line ();
339 symbolP = symbol_find_or_make (name);
341 if (S_IS_DEFINED (symbolP))
343 as_bad ("Ignoring attempt to re-define symbol");
344 ignore_rest_of_line ();
347 if (S_GET_VALUE (symbolP) != 0)
349 if (S_GET_VALUE (symbolP) != size)
351 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
352 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
358 S_SET_VALUE (symbolP, (valueT) size);
359 S_SET_EXTERNAL (symbolP);
362 know (symbolP->sy_frag == &zero_address_frag);
363 if (*input_line_pointer != ',')
365 as_bad ("Expected comma after common length");
366 ignore_rest_of_line ();
369 input_line_pointer++;
371 if (*input_line_pointer != '"')
373 temp = get_absolute_expression ();
375 if (temp > max_alignment)
377 temp = max_alignment;
378 as_warn ("Common alignment too large: %d. assumed", temp);
384 as_warn ("Common alignment negative; 0 assumed");
396 old_subsec = now_subseg;
398 record_alignment (bss_section, align);
399 subseg_set (bss_section, 0);
401 frag_align (align, 0);
402 if (S_GET_SEGMENT (symbolP) == bss_section)
403 symbolP->sy_frag->fr_symbol = 0;
404 symbolP->sy_frag = frag_now;
405 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
408 S_SET_SEGMENT (symbolP, bss_section);
409 S_CLEAR_EXTERNAL (symbolP);
410 subseg_set (old_sec, old_subsec);
416 S_SET_VALUE (symbolP, (valueT) size);
418 S_SET_ALIGN (symbolP, temp);
420 S_SET_EXTERNAL (symbolP);
421 /* should be common, but this is how gas does it for now */
422 S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
427 input_line_pointer++;
428 /* @@ Some use the dot, some don't. Can we get some consistency?? */
429 if (*input_line_pointer == '.')
430 input_line_pointer++;
431 /* @@ Some say data, some say bss. */
432 if (strncmp (input_line_pointer, "bss\"", 4)
433 && strncmp (input_line_pointer, "data\"", 5))
435 while (*--input_line_pointer != '"')
437 input_line_pointer--;
438 goto bad_common_segment;
440 while (*input_line_pointer++ != '"')
442 goto allocate_common;
444 demand_empty_rest_of_line ();
449 p = input_line_pointer;
450 while (*p && *p != '\n')
454 as_bad ("bad .common segment %s", input_line_pointer + 1);
456 input_line_pointer = p;
457 ignore_rest_of_line ();
467 if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
469 input_line_pointer += 6;
473 if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
475 input_line_pointer += 6;
479 if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
481 input_line_pointer += 7;
485 if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
487 input_line_pointer += 5;
488 /* We only support 2 segments -- text and data -- for now, so
489 things in the "bss segment" will have to go into data for now.
490 You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
491 subseg_set (data_section, 255); /* FIXME-SOMEDAY */
494 as_bad ("Unknown segment type");
495 demand_empty_rest_of_line ();
501 subseg_set (data_section, 1);
502 demand_empty_rest_of_line ();
509 while (!is_end_of_line[(unsigned char) *input_line_pointer])
511 ++input_line_pointer;
513 ++input_line_pointer;
516 /* sparc64 priviledged registers */
518 struct priv_reg_entry
524 struct priv_reg_entry priv_reg_table[] =
543 {"", -1}, /* end marker */
548 struct priv_reg_entry *p, *q;
550 return strcmp (q->name, p->name);
553 /* This function is called once, at assembler startup time. It should
554 set up all the tables, etc. that the MD part of the assembler will need. */
559 register const char *retval = NULL;
561 register unsigned int i = 0;
563 op_hash = hash_new ();
565 while (i < sparc_num_opcodes)
567 const char *name = sparc_opcodes[i].name;
568 retval = hash_insert (op_hash, name, &sparc_opcodes[i]);
571 fprintf (stderr, "internal error: can't hash `%s': %s\n",
572 sparc_opcodes[i].name, retval);
577 if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
579 fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
580 sparc_opcodes[i].name, sparc_opcodes[i].args);
585 while (i < sparc_num_opcodes
586 && !strcmp (sparc_opcodes[i].name, name));
590 as_fatal ("Broken assembler. No assembly attempted.");
592 for (i = '0'; i < '8'; ++i)
594 for (i = '0'; i <= '9'; ++i)
596 for (i = 'a'; i <= 'f'; ++i)
597 toHex[i] = i + 10 - 'a';
598 for (i = 'A'; i <= 'F'; ++i)
599 toHex[i] = i + 10 - 'A';
601 qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
602 sizeof (priv_reg_table[0]), cmp_reg_entry);
604 target_big_endian = 1;
606 /* If both an architecture and -bump were requested, allow bumping to go
607 as high as needed. If the requested architecture conflicts with the
608 highest architecture, -bump has no effect. Note that `max_architecture'
609 records the requested architecture. */
610 if (architecture_requested && warn_on_bump
611 && !SPARC_OPCODE_CONFLICT_P (max_architecture, SPARC_OPCODE_ARCH_MAX)
612 && !SPARC_OPCODE_CONFLICT_P (SPARC_OPCODE_ARCH_MAX, max_architecture))
613 max_architecture = SPARC_OPCODE_ARCH_MAX;
616 /* Called after all assembly has been done. */
622 if (current_architecture == SPARC_OPCODE_ARCH_V9A)
623 bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v9a);
625 bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v9);
627 if (current_architecture == SPARC_OPCODE_ARCH_V9)
628 bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v8plus);
629 else if (current_architecture == SPARC_OPCODE_ARCH_V9A)
630 bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v8plusa);
632 bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc);
646 /* See if "set" operand is absolute and small; skip sethi if so. */
647 if (special_case == SPECIAL_CASE_SET
648 && the_insn.exp.X_op == O_constant)
650 if (the_insn.exp.X_add_number >= -(1 << 12)
651 && the_insn.exp.X_add_number < (1 << 12))
653 the_insn.opcode = 0x80102000 /* or %g0,imm,... */
654 | (the_insn.opcode & 0x3E000000) /* dest reg */
655 | (the_insn.exp.X_add_number & 0x1FFF); /* imm */
656 special_case = 0; /* No longer special */
657 the_insn.reloc = BFD_RELOC_NONE; /* No longer relocated */
662 /* put out the opcode */
663 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
665 /* put out the symbol-dependent stuff */
666 if (the_insn.reloc != BFD_RELOC_NONE)
668 fix_new_exp (frag_now, /* which frag */
669 (toP - frag_now->fr_literal), /* where */
676 switch (special_case)
678 case SPECIAL_CASE_SET:
680 assert (the_insn.reloc == BFD_RELOC_HI22);
681 /* See if "set" operand has no low-order bits; skip OR if so. */
682 if (the_insn.exp.X_op == O_constant
683 && ((the_insn.exp.X_add_number & 0x3FF) == 0))
686 rsd = (the_insn.opcode >> 25) & 0x1f;
687 the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
688 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
689 fix_new_exp (frag_now, /* which frag */
690 (toP - frag_now->fr_literal), /* where */
697 case SPECIAL_CASE_FDIV:
698 /* According to information leaked from Sun, the "fdiv" instructions
699 on early SPARC machines would produce incorrect results sometimes.
700 The workaround is to add an fmovs of the destination register to
701 itself just after the instruction. This was true on machines
702 with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
704 assert (the_insn.reloc == BFD_RELOC_NONE);
706 rsd = (the_insn.opcode >> 25) & 0x1f;
707 the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */
708 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
715 as_fatal ("failed sanity check.");
719 /* Implement big shift right. */
725 if (sizeof (bfd_vma) <= 4 && amount >= 32)
726 as_fatal ("Support for 64-bit arithmetic not compiled in.");
727 return val >> amount;
730 /* Parse an argument that can be expressed as a keyword.
732 The result is a boolean indicating success.
733 If successful, INPUT_POINTER is updated. */
736 parse_keyword_arg (lookup_fn, input_pointerP, valueP)
738 char **input_pointerP;
745 for (q = p + (*p == '#'); isalpha (*q) || *q == '_'; ++q)
749 value = (*lookup_fn) (p);
758 /* Parse an argument that is a constant expression.
759 The result is a boolean indicating success. */
762 parse_const_expr_arg (input_pointerP, valueP)
763 char **input_pointerP;
766 char *save = input_line_pointer;
769 input_line_pointer = *input_pointerP;
770 /* The next expression may be something other than a constant
771 (say if we're not processing the right variant of the insn).
772 Don't call expression unless we're sure it will succeed as it will
773 signal an error (which we want to defer until later). */
774 /* FIXME: It might be better to define md_operand and have it recognize
775 things like %asi, etc. but continuing that route through to the end
777 if (*input_line_pointer == '%')
779 input_line_pointer = save;
783 *input_pointerP = input_line_pointer;
784 input_line_pointer = save;
785 if (exp.X_op != O_constant)
787 *valueP = exp.X_add_number;
795 char *error_message = "";
799 const struct sparc_opcode *insn;
801 unsigned long opcode;
802 unsigned int mask = 0;
805 long immediate_max = 0;
808 for (s = str; islower (*s) || (*s >= '0' && *s <= '3'); ++s)
826 as_fatal ("Unknown opcode: `%s'", str);
828 insn = (struct sparc_opcode *) hash_find (op_hash, str);
831 as_bad ("Unknown opcode: `%s'", str);
842 opcode = insn->match;
843 memset (&the_insn, '\0', sizeof (the_insn));
844 the_insn.reloc = BFD_RELOC_NONE;
848 * Build the opcode, checking as we go to make
849 * sure that the operands match
851 for (args = insn->args;; ++args)
859 /* Parse a series of masks. */
866 if (! parse_keyword_arg (sparc_encode_membar, &s,
869 error_message = ": invalid membar mask name";
873 while (*s == ' ') { ++s; continue; }
874 if (*s == '|' || *s == '+')
876 while (*s == ' ') { ++s; continue; }
881 if (! parse_const_expr_arg (&s, &kmask))
883 error_message = ": invalid membar mask expression";
886 if (kmask < 0 || kmask > 127)
888 error_message = ": invalid membar mask number";
893 opcode |= MEMBAR (kmask);
901 /* Parse a prefetch function. */
904 if (! parse_keyword_arg (sparc_encode_prefetch, &s, &fcn))
906 error_message = ": invalid prefetch function name";
912 if (! parse_const_expr_arg (&s, &fcn))
914 error_message = ": invalid prefetch function expression";
917 if (fcn < 0 || fcn > 31)
919 error_message = ": invalid prefetch function number";
929 /* Parse a sparc64 privileged register. */
932 struct priv_reg_entry *p = priv_reg_table;
933 unsigned int len = 9999999; /* init to make gcc happy */
936 while (p->name[0] > s[0])
938 while (p->name[0] == s[0])
940 len = strlen (p->name);
941 if (strncmp (p->name, s, len) == 0)
945 if (p->name[0] != s[0])
947 error_message = ": unrecognizable privileged register";
951 opcode |= (p->regnum << 14);
953 opcode |= (p->regnum << 25);
959 error_message = ": unrecognizable privileged register";
965 if (strncmp (s, "%asr", 4) == 0)
975 num = num * 10 + *s - '0';
979 if (num < 16 || 31 < num)
981 error_message = ": asr number must be between 15 and 31";
985 opcode |= (*args == 'M' ? RS1 (num) : RD (num));
990 error_message = ": expecting %asrN";
992 } /* if %asr followed by a number. */
998 the_insn.reloc = BFD_RELOC_SPARC_11;
999 immediate_max = 0x03FF;
1003 the_insn.reloc = BFD_RELOC_SPARC_10;
1004 immediate_max = 0x01FF;
1008 the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16;
1013 the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
1018 if (*s == 'p' && s[1] == 'n')
1026 if (*s == 'p' && s[1] == 't')
1038 if (strncmp (s, "%icc", 4) == 0)
1050 if (strncmp (s, "%xcc", 4) == 0)
1062 if (strncmp (s, "%fcc0", 5) == 0)
1074 if (strncmp (s, "%fcc1", 5) == 0)
1086 if (strncmp (s, "%fcc2", 5) == 0)
1098 if (strncmp (s, "%fcc3", 5) == 0)
1106 if (strncmp (s, "%pc", 3) == 0)
1114 if (strncmp (s, "%tick", 5) == 0)
1121 case '\0': /* end of args */
1140 case '[': /* these must match exactly */
1148 case '#': /* must be at least one digit */
1151 while (isdigit (*s))
1159 case 'C': /* coprocessor state register */
1160 if (strncmp (s, "%csr", 4) == 0)
1167 case 'b': /* next operand is a coprocessor register */
1170 if (*s++ == '%' && *s++ == 'c' && isdigit (*s))
1175 mask = 10 * (mask - '0') + (*s++ - '0');
1189 opcode |= mask << 14;
1197 opcode |= mask << 25;
1203 case 'r': /* next operand must be a register */
1212 case 'f': /* frame pointer */
1220 case 'g': /* global register */
1221 if (isoctal (c = *s++))
1228 case 'i': /* in register */
1229 if (isoctal (c = *s++))
1231 mask = c - '0' + 24;
1236 case 'l': /* local register */
1237 if (isoctal (c = *s++))
1239 mask = (c - '0' + 16);
1244 case 'o': /* out register */
1245 if (isoctal (c = *s++))
1247 mask = (c - '0' + 8);
1252 case 's': /* stack pointer */
1260 case 'r': /* any register */
1261 if (!isdigit (c = *s++))
1278 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
1294 /* Got the register, now figure out where
1295 it goes in the opcode. */
1300 opcode |= mask << 14;
1308 opcode |= mask << 25;
1312 opcode |= (mask << 25) | (mask << 14);
1318 case 'e': /* next operand is a floating point register */
1333 && ((format = *s) == 'f')
1336 for (mask = 0; isdigit (*s); ++s)
1338 mask = 10 * mask + (*s - '0');
1339 } /* read the number */
1347 } /* register must be even numbered */
1355 } /* register must be multiple of 4 */
1359 if (max_architecture >= SPARC_OPCODE_ARCH_V9)
1360 error_message = ": There are only 64 f registers; [0-63]";
1362 error_message = ": There are only 32 f registers; [0-31]";
1365 else if (mask >= 32)
1367 if (max_architecture >= SPARC_OPCODE_ARCH_V9)
1370 mask -= 31; /* wrap high bit */
1374 error_message = ": There are only 32 f registers; [0-31]";
1382 } /* if not an 'f' register. */
1389 opcode |= RS1 (mask);
1396 opcode |= RS2 (mask);
1402 opcode |= RD (mask);
1411 if (strncmp (s, "%fsr", 4) == 0)
1418 case 'h': /* high 22 bits */
1419 the_insn.reloc = BFD_RELOC_HI22;
1422 case 'l': /* 22 bit PC relative immediate */
1423 the_insn.reloc = BFD_RELOC_SPARC_WDISP22;
1427 case 'L': /* 30 bit immediate */
1428 the_insn.reloc = BFD_RELOC_32_PCREL_S2;
1432 case 'n': /* 22 bit immediate */
1433 the_insn.reloc = BFD_RELOC_SPARC22;
1436 case 'i': /* 13 bit immediate */
1437 the_insn.reloc = BFD_RELOC_SPARC13;
1438 immediate_max = 0x0FFF;
1447 if ((c = s[1]) == 'h' && s[2] == 'i')
1449 the_insn.reloc = BFD_RELOC_HI22;
1452 else if (c == 'l' && s[2] == 'o')
1454 the_insn.reloc = BFD_RELOC_LO10;
1461 the_insn.reloc = BFD_RELOC_SPARC_HH22;
1469 the_insn.reloc = BFD_RELOC_SPARC_HM10;
1476 /* Note that if the getExpression() fails, we will still
1477 have created U entries in the symbol table for the
1478 'symbols' in the input string. Try not to create U
1479 symbols for registers, etc. */
1481 /* This stuff checks to see if the expression ends in
1482 +%reg. If it does, it removes the register from
1483 the expression, and re-sets 's' to point to the
1488 for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++);;
1490 if (s1 != s && isdigit (s1[-1]))
1492 if (s1[-2] == '%' && s1[-3] == '+')
1496 (void) getExpression (s);
1501 else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
1505 (void) getExpression (s);
1512 (void) getExpression (s);
1515 if (the_insn.exp.X_op == O_constant
1516 && the_insn.exp.X_add_symbol == 0
1517 && the_insn.exp.X_op_symbol == 0)
1519 /* Handle %uhi/%ulo by moving the upper word to the lower
1520 one and pretending it's %hi/%lo. We also need to watch
1521 for %hi/%lo: the top word needs to be zeroed otherwise
1522 fixup_segment will complain the value is too big. */
1523 switch (the_insn.reloc)
1525 case BFD_RELOC_SPARC_HH22:
1526 the_insn.reloc = BFD_RELOC_HI22;
1527 the_insn.exp.X_add_number = BSR (the_insn.exp.X_add_number, 32);
1529 case BFD_RELOC_SPARC_HM10:
1530 the_insn.reloc = BFD_RELOC_LO10;
1531 the_insn.exp.X_add_number = BSR (the_insn.exp.X_add_number, 32);
1533 case BFD_RELOC_HI22:
1534 case BFD_RELOC_LO10:
1535 the_insn.exp.X_add_number &= 0xffffffff;
1541 /* For pc-relative call instructions, we reject
1542 constants to get better code. */
1544 && the_insn.reloc == BFD_RELOC_32_PCREL_S2
1545 && in_signed_range (the_insn.exp.X_add_number, 0x3fff)
1548 error_message = ": PC-relative operand can't be a constant";
1551 /* Check for invalid constant values. Don't warn if
1552 constant was inside %hi or %lo, since these
1553 truncate the constant to fit. */
1554 if (immediate_max != 0
1555 && the_insn.reloc != BFD_RELOC_LO10
1556 && the_insn.reloc != BFD_RELOC_HI22
1557 && !in_signed_range (the_insn.exp.X_add_number,
1562 /* Who knows? After relocation, we may be within
1563 range. Let the linker figure it out. */
1565 the_insn.exp.X_op = O_symbol;
1566 the_insn.exp.X_add_symbol = section_symbol (absolute_section);
1569 /* Immediate value is non-pcrel, and out of
1571 as_bad ("constant value %ld out of range (%ld .. %ld)",
1572 the_insn.exp.X_add_number,
1573 ~immediate_max, immediate_max);
1577 /* Reset to prevent extraneous range check. */
1597 if (! parse_keyword_arg (sparc_encode_asi, &s, &asi))
1599 error_message = ": invalid ASI name";
1605 if (! parse_const_expr_arg (&s, &asi))
1607 error_message = ": invalid ASI expression";
1610 if (asi < 0 || asi > 255)
1612 error_message = ": invalid ASI number";
1616 opcode |= ASI (asi);
1618 } /* alternate space */
1621 if (strncmp (s, "%psr", 4) == 0)
1628 case 'q': /* floating point queue */
1629 if (strncmp (s, "%fq", 3) == 0)
1636 case 'Q': /* coprocessor queue */
1637 if (strncmp (s, "%cq", 3) == 0)
1645 if (strcmp (str, "set") == 0)
1647 special_case = SPECIAL_CASE_SET;
1650 else if (strncmp (str, "fdiv", 4) == 0)
1652 special_case = SPECIAL_CASE_FDIV;
1658 if (strncmp (s, "%asi", 4) != 0)
1664 if (strncmp (s, "%fprs", 5) != 0)
1670 if (strncmp (s, "%ccr", 4) != 0)
1676 if (strncmp (s, "%tbr", 4) != 0)
1682 if (strncmp (s, "%wim", 4) != 0)
1689 char *push = input_line_pointer;
1692 input_line_pointer = s;
1694 if (e.X_op == O_constant)
1696 int n = e.X_add_number;
1697 if (n != e.X_add_number || (n & ~0x1ff) != 0)
1698 as_bad ("OPF immediate operand out of range (0-0x1ff)");
1700 opcode |= e.X_add_number << 5;
1703 as_bad ("non-immediate OPF operand, ignored");
1704 s = input_line_pointer;
1705 input_line_pointer = push;
1710 if (strncmp (s, "%y", 2) != 0)
1716 as_fatal ("failed sanity check.");
1717 } /* switch on arg code */
1719 /* Break out of for() loop. */
1721 } /* for each arg that we expect */
1726 /* Args don't match. */
1727 if (((unsigned) (&insn[1] - sparc_opcodes)) < sparc_num_opcodes
1728 && (insn->name == insn[1].name
1729 || !strcmp (insn->name, insn[1].name)))
1737 as_bad ("Illegal operands%s", error_message);
1743 /* We have a match. Now see if the architecture is ok. */
1744 enum sparc_opcode_arch_val needed_architecture =
1745 ((v9_arg_p && insn->architecture < SPARC_OPCODE_ARCH_V9)
1746 ? SPARC_OPCODE_ARCH_V9 : insn->architecture);
1748 if (needed_architecture == current_architecture)
1750 /* Do we have a potential conflict? */
1751 else if (SPARC_OPCODE_CONFLICT_P (max_architecture,
1752 needed_architecture)
1753 || SPARC_OPCODE_CONFLICT_P (needed_architecture,
1755 || needed_architecture > max_architecture)
1757 as_bad ("Architecture mismatch on \"%s\".", str);
1758 as_tsktsk (" (Requires %s; requested architecture is %s.)",
1759 sparc_opcode_archs[needed_architecture].name,
1760 sparc_opcode_archs[max_architecture].name);
1763 /* Do we need to bump? */
1764 else if (needed_architecture > current_architecture)
1767 && needed_architecture > warn_after_architecture)
1769 as_warn ("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1770 sparc_opcode_archs[current_architecture].name,
1771 sparc_opcode_archs[needed_architecture].name,
1774 current_architecture = needed_architecture;
1779 } /* forever looking for a match */
1781 the_insn.opcode = opcode;
1791 save_in = input_line_pointer;
1792 input_line_pointer = str;
1793 seg = expression (&the_insn.exp);
1794 if (seg != absolute_section
1795 && seg != text_section
1796 && seg != data_section
1797 && seg != bss_section
1798 && seg != undefined_section)
1800 the_insn.error = "bad segment";
1801 expr_end = input_line_pointer;
1802 input_line_pointer = save_in;
1805 expr_end = input_line_pointer;
1806 input_line_pointer = save_in;
1808 } /* getExpression() */
1812 This is identical to the md_atof in m68k.c. I think this is right,
1815 Turn a string in input_line_pointer into a floating point constant of type
1816 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1817 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1820 /* Equal to MAX_PRECISION in atof-ieee.c */
1821 #define MAX_LITTLENUMS 6
1824 md_atof (type, litP, sizeP)
1830 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1831 LITTLENUM_TYPE *wordP;
1864 return "Bad call to MD_ATOF()";
1866 t = atof_ieee (input_line_pointer, type, words);
1868 input_line_pointer = t;
1869 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1870 for (wordP = words; prec--;)
1872 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1873 litP += sizeof (LITTLENUM_TYPE);
1879 * Write out big-endian.
1882 md_number_to_chars (buf, val, n)
1887 number_to_chars_bigendian (buf, val, n);
1890 /* Apply a fixS to the frags, now that we know the value it ought to
1894 md_apply_fix (fixP, value)
1898 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1903 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
1905 fixP->fx_addnumber = val; /* Remember value for emit_reloc */
1908 /* FIXME: SPARC ELF relocations don't use an addend in the data
1909 field itself. This whole approach should be somehow combined
1910 with the calls to bfd_perform_relocation. Also, the value passed
1911 in by fixup_segment includes the value of a defined symbol. We
1912 don't want to include the value of an externally visible symbol. */
1913 if (fixP->fx_addsy != NULL)
1915 if ((S_IS_EXTERN (fixP->fx_addsy)
1916 || (sparc_pic_code && ! fixP->fx_pcrel))
1917 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section
1918 && S_GET_SEGMENT (fixP->fx_addsy) != undefined_section
1919 && ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)))
1920 fixP->fx_addnumber -= S_GET_VALUE (fixP->fx_addsy);
1925 /* This is a hack. There should be a better way to
1926 handle this. Probably in terms of howto fields, once
1927 we can look at these fixups in terms of howtos. */
1928 if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
1929 val += fixP->fx_where + fixP->fx_frag->fr_address;
1932 /* FIXME: More ridiculous gas reloc hacking. If we are going to
1933 generate a reloc, then we just want to let the reloc addend set
1934 the value. We do not want to also stuff the addend into the
1935 object file. Including the addend in the object file works when
1936 doing a static link, because the linker will ignore the object
1937 file contents. However, the dynamic linker does not ignore the
1938 object file contents. */
1939 if (fixP->fx_addsy != NULL
1940 && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2)
1943 /* When generating PIC code, we do not want an addend for a reloc
1944 against a local symbol. We adjust fx_addnumber to cancel out the
1945 value already included in val, and to also cancel out the
1946 adjustment which bfd_install_relocation will create. */
1948 && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2
1949 && fixP->fx_addsy != NULL
1950 && ! S_IS_COMMON (fixP->fx_addsy)
1951 && (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0)
1952 fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
1955 switch (fixP->fx_r_type)
1969 case BFD_RELOC_32_PCREL_S2:
1971 if (! sparc_pic_code
1972 || fixP->fx_addsy == NULL
1973 || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
1975 buf[0] |= (val >> 24) & 0x3f;
1976 buf[1] = (val >> 16);
1983 bfd_vma valh = BSR (val, 32);
1984 buf[0] = valh >> 24;
1985 buf[1] = valh >> 16;
1995 case BFD_RELOC_SPARC_11:
1996 if (((val > 0) && (val & ~0x7ff))
1997 || ((val < 0) && (~(val - 1) & ~0x7ff)))
1999 as_bad ("relocation overflow.");
2002 buf[2] |= (val >> 8) & 0x7;
2003 buf[3] = val & 0xff;
2006 case BFD_RELOC_SPARC_10:
2007 if (((val > 0) && (val & ~0x3ff))
2008 || ((val < 0) && (~(val - 1) & ~0x3ff)))
2010 as_bad ("relocation overflow.");
2013 buf[2] |= (val >> 8) & 0x3;
2014 buf[3] = val & 0xff;
2017 case BFD_RELOC_SPARC_WDISP16:
2018 if (((val > 0) && (val & ~0x3fffc))
2019 || ((val < 0) && (~(val - 1) & ~0x3fffc)))
2021 as_bad ("relocation overflow.");
2024 val = (val >>= 2) + 1;
2025 buf[1] |= ((val >> 14) & 0x3) << 4;
2026 buf[2] |= (val >> 8) & 0x3f;
2027 buf[3] = val & 0xff;
2030 case BFD_RELOC_SPARC_WDISP19:
2031 if (((val > 0) && (val & ~0x1ffffc))
2032 || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
2034 as_bad ("relocation overflow.");
2037 val = (val >>= 2) + 1;
2038 buf[1] |= (val >> 16) & 0x7;
2039 buf[2] = (val >> 8) & 0xff;
2040 buf[3] = val & 0xff;
2043 case BFD_RELOC_SPARC_HH22:
2044 val = BSR (val, 32);
2045 /* intentional fallthrough */
2047 case BFD_RELOC_SPARC_LM22:
2048 case BFD_RELOC_HI22:
2049 if (!fixP->fx_addsy)
2051 buf[1] |= (val >> 26) & 0x3f;
2062 case BFD_RELOC_SPARC22:
2063 if (val & ~0x003fffff)
2065 as_bad ("relocation overflow");
2067 buf[1] |= (val >> 16) & 0x3f;
2069 buf[3] = val & 0xff;
2072 case BFD_RELOC_SPARC_HM10:
2073 val = BSR (val, 32);
2074 /* intentional fallthrough */
2076 case BFD_RELOC_LO10:
2077 if (!fixP->fx_addsy)
2079 buf[2] |= (val >> 8) & 0x03;
2086 case BFD_RELOC_SPARC13:
2087 if (! in_signed_range (val, 0x1fff))
2088 as_bad ("relocation overflow");
2090 buf[2] |= (val >> 8) & 0x1f;
2094 case BFD_RELOC_SPARC_WDISP22:
2095 val = (val >> 2) + 1;
2097 case BFD_RELOC_SPARC_BASE22:
2098 buf[1] |= (val >> 16) & 0x3f;
2103 case BFD_RELOC_NONE:
2105 as_bad ("bad or unhandled relocation type: 0x%02x", fixP->fx_r_type);
2109 /* Are we finished with this relocation now? */
2110 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
2116 /* Translate internal representation of relocation info to BFD target
2119 tc_gen_reloc (section, fixp)
2124 bfd_reloc_code_real_type code;
2126 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
2127 assert (reloc != 0);
2129 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2130 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2132 switch (fixp->fx_r_type)
2136 case BFD_RELOC_HI22:
2137 case BFD_RELOC_LO10:
2138 case BFD_RELOC_32_PCREL_S2:
2139 case BFD_RELOC_SPARC13:
2140 case BFD_RELOC_SPARC_BASE13:
2141 case BFD_RELOC_SPARC_WDISP16:
2142 case BFD_RELOC_SPARC_WDISP19:
2143 case BFD_RELOC_SPARC_WDISP22:
2145 case BFD_RELOC_SPARC_10:
2146 case BFD_RELOC_SPARC_11:
2147 case BFD_RELOC_SPARC_HH22:
2148 case BFD_RELOC_SPARC_HM10:
2149 case BFD_RELOC_SPARC_LM22:
2150 case BFD_RELOC_SPARC_PC_HH22:
2151 case BFD_RELOC_SPARC_PC_HM10:
2152 case BFD_RELOC_SPARC_PC_LM22:
2153 code = fixp->fx_r_type;
2159 #if defined (OBJ_ELF) || defined (OBJ_AOUT)
2160 /* If we are generating PIC code, we need to generate a different
2164 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
2166 #define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
2173 case BFD_RELOC_32_PCREL_S2:
2174 if (! S_IS_DEFINED (fixp->fx_addsy)
2175 || S_IS_EXTERNAL (fixp->fx_addsy))
2176 code = BFD_RELOC_SPARC_WPLT30;
2178 case BFD_RELOC_HI22:
2179 if (fixp->fx_addsy != NULL
2180 && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
2181 code = BFD_RELOC_SPARC_PC22;
2183 code = BFD_RELOC_SPARC_GOT22;
2185 case BFD_RELOC_LO10:
2186 if (fixp->fx_addsy != NULL
2187 && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
2188 code = BFD_RELOC_SPARC_PC10;
2190 code = BFD_RELOC_SPARC_GOT10;
2192 case BFD_RELOC_SPARC13:
2193 code = BFD_RELOC_SPARC_GOT13;
2199 #endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */
2201 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2202 if (reloc->howto == 0)
2204 as_bad_where (fixp->fx_file, fixp->fx_line,
2205 "internal error: can't export reloc type %d (`%s')",
2206 fixp->fx_r_type, bfd_get_reloc_code_name (code));
2210 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
2213 if (reloc->howto->pc_relative == 0
2214 || code == BFD_RELOC_SPARC_PC10
2215 || code == BFD_RELOC_SPARC_PC22)
2216 reloc->addend = fixp->fx_addnumber;
2218 reloc->addend = fixp->fx_offset - reloc->address;
2220 #else /* elf or coff */
2222 if (reloc->howto->pc_relative == 0
2223 || code == BFD_RELOC_SPARC_PC10
2224 || code == BFD_RELOC_SPARC_PC22)
2225 reloc->addend = fixp->fx_addnumber;
2226 else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
2227 reloc->addend = (section->vma
2228 + fixp->fx_addnumber
2229 + md_pcrel_from (fixp));
2231 reloc->addend = fixp->fx_offset;
2239 /* for debugging only */
2242 struct sparc_it *insn;
2244 const char *const Reloc[] = {
2273 fprintf (stderr, "ERROR: %s\n");
2274 fprintf (stderr, "opcode=0x%08x\n", insn->opcode);
2275 fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
2276 fprintf (stderr, "exp = {\n");
2277 fprintf (stderr, "\t\tX_add_symbol = %s\n",
2278 ((insn->exp.X_add_symbol != NULL)
2279 ? ((S_GET_NAME (insn->exp.X_add_symbol) != NULL)
2280 ? S_GET_NAME (insn->exp.X_add_symbol)
2283 fprintf (stderr, "\t\tX_sub_symbol = %s\n",
2284 ((insn->exp.X_op_symbol != NULL)
2285 ? (S_GET_NAME (insn->exp.X_op_symbol)
2286 ? S_GET_NAME (insn->exp.X_op_symbol)
2289 fprintf (stderr, "\t\tX_add_number = %d\n",
2290 insn->exp.X_add_number);
2291 fprintf (stderr, "}\n");
2297 * Invocation line includes a switch not recognized by the base assembler.
2298 * See if it's a processor-specific option. These are:
2301 * Warn on architecture bumps. See also -A.
2303 * -Av6, -Av7, -Av8, -Av9, -Av9a, -Asparclite
2304 * -xarch=v8plus, -xarch=v8plusa
2305 * Select the architecture. Instructions or features not
2306 * supported by the selected architecture cause fatal errors.
2308 * The default is to start at v6, and bump the architecture up
2309 * whenever an instruction is seen at a higher level. If 32 bit
2310 * environments, v9 is not bumped up to, the user must pass -Av9.
2312 * -xarch=v8plus{,a} is for compatibility with the Sun assembler.
2314 * If -bump is specified, a warning is printing when bumping to
2317 * If an architecture is specified, all instructions must match
2318 * that architecture. Any higher level instructions are flagged
2319 * as errors. Note that in the 32 bit environment specifying
2320 * -Av9 does not automatically create a v9 object file, a v9
2321 * insn must be seen.
2323 * If both an architecture and -bump are specified, the
2324 * architecture starts at the specified level, but bumps are
2325 * warnings. Note that we can't set `current_architecture' to
2326 * the requested level in this case: in the 32 bit environment,
2327 * we still must avoid creating v9 object files unless v9 insns
2331 * Bumping between incompatible architectures is always an
2332 * error. For example, from sparclite to v9.
2336 CONST char *md_shortopts = "A:K:VQ:sq";
2339 CONST char *md_shortopts = "A:k";
2341 CONST char *md_shortopts = "A:";
2344 struct option md_longopts[] = {
2345 #define OPTION_BUMP (OPTION_MD_BASE)
2346 {"bump", no_argument, NULL, OPTION_BUMP},
2347 #define OPTION_SPARC (OPTION_MD_BASE + 1)
2348 {"sparc", no_argument, NULL, OPTION_SPARC},
2349 #define OPTION_XARCH (OPTION_MD_BASE + 2)
2350 {"xarch", required_argument, NULL, OPTION_XARCH},
2351 {NULL, no_argument, NULL, 0}
2353 size_t md_longopts_size = sizeof(md_longopts);
2356 md_parse_option (c, arg)
2364 warn_after_architecture = SPARC_OPCODE_ARCH_V6;
2368 /* ??? We could add v8plus and v8plusa to sparc_opcode_archs.
2369 But we might want v8plus to mean something different than v9
2370 someday, and we'd recognize more -xarch options than Sun's
2371 assembler does (which may lead to a conflict someday). */
2372 if (strcmp (arg, "v8plus") == 0)
2374 else if (strcmp (arg, "v8plusa") == 0)
2378 as_bad ("invalid architecture -xarch=%s", arg);
2386 enum sparc_opcode_arch_val new_arch = sparc_opcode_lookup_arch (arg);
2388 if (new_arch == SPARC_OPCODE_ARCH_BAD)
2390 as_bad ("invalid architecture -A%s", arg);
2395 max_architecture = new_arch;
2396 architecture_requested = 1;
2402 /* Ignore -sparc, used by SunOS make default .s.o rule. */
2413 print_version_id ();
2417 /* Qy - do emit .comment
2418 Qn - do not emit .comment */
2422 /* use .stab instead of .stab.excl */
2426 /* quick -- native assembler does fewer checks */
2430 if (strcmp (arg, "PIC") != 0)
2431 as_warn ("Unrecognized option following -K");
2445 md_show_usage (stream)
2448 const struct sparc_opcode_arch *arch;
2450 fprintf(stream, "SPARC options:\n");
2451 for (arch = &sparc_opcode_archs[0]; arch->name; arch++)
2453 if (arch != &sparc_opcode_archs[0])
2454 fprintf (stream, " | ");
2455 fprintf (stream, "-A%s", arch->name);
2457 fprintf (stream, "\n-xarch=v8plus | -xarch=v8plusa\n");
2459 specify variant of SPARC architecture\n\
2460 -bump warn when assembler switches architectures\n\
2464 -k generate PIC\n");
2468 -KPIC generate PIC\n\
2469 -V print assembler version number\n\
2476 /* We have no need to default values of symbols. */
2480 md_undefined_symbol (name)
2484 } /* md_undefined_symbol() */
2486 /* Round up a section size to the appropriate boundary. */
2488 md_section_align (segment, size)
2493 /* This is not right for ELF; a.out wants it, and COFF will force
2494 the alignment anyways. */
2495 valueT align = ((valueT) 1
2496 << (valueT) bfd_get_section_alignment (stdoutput, segment));
2498 /* turn alignment value into a mask */
2500 newsize = (size + align) & ~align;
2507 /* Exactly what point is a PC-relative offset relative TO?
2508 On the sparc, they're relative to the address of the offset, plus
2509 its size. This gets us to the following instruction.
2510 (??? Is this right? FIXME-SOON) */
2512 md_pcrel_from (fixP)
2517 ret = fixP->fx_where + fixP->fx_frag->fr_address;
2518 if (! sparc_pic_code
2519 || fixP->fx_addsy == NULL
2520 || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
2521 ret += fixP->fx_size;
2525 /* end of tc-sparc.c */