* symtab.c (lookup_symbol): Don't try adding .c to the name.
[deliverable/binutils-gdb.git] / gas / config / tc-sparc.c
CommitLineData
fecd2382 1/* tc-sparc.c -- Assemble for the SPARC
a87b3269 2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
355afbcd 3
fecd2382 4 This file is part of GAS, the GNU Assembler.
355afbcd 5
fecd2382
RP
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
6321e9ea 8 the Free Software Foundation; either version 2, or (at your option)
fecd2382 9 any later version.
355afbcd 10
fecd2382
RP
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.
355afbcd 15
fecd2382
RP
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
a87b3269
RP
20#define cypress 1234
21
fecd2382
RP
22#include <stdio.h>
23#include <ctype.h>
24
25#include "as.h"
26
27/* careful, this file includes data *declarations* */
584a0f78 28#include "opcode/sparc.h"
fecd2382 29
7766838e 30static void sparc_ip PARAMS ((char *));
fecd2382 31
839df5c3 32static enum sparc_architecture current_architecture = v6;
428d312b
KR
33static int architecture_requested;
34static int warn_on_bump;
839df5c3 35
ed9638af
KR
36extern int target_big_endian;
37
428d312b 38const relax_typeS md_relax_table[1];
fecd2382
RP
39
40/* handle of the OPCODE hash table */
41static struct hash_control *op_hash = NULL;
42
7766838e
ILT
43static void s_data1 PARAMS ((void));
44static void s_seg PARAMS ((int));
45static void s_proc PARAMS ((int));
46static void s_reserve PARAMS ((int));
47static void s_common PARAMS ((int));
428d312b 48
355afbcd
KR
49const pseudo_typeS md_pseudo_table[] =
50{
51 {"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
52 {"common", s_common, 0},
53 {"global", s_globl, 0},
54 {"half", cons, 2},
55 {"optim", s_ignore, 0},
56 {"proc", s_proc, 0},
57 {"reserve", s_reserve, 0},
58 {"seg", s_seg, 0},
59 {"skip", s_space, 0},
60 {"word", cons, 4},
428d312b
KR
61/* start-sanitize-v9 */
62#ifndef NO_V9
7766838e 63 {"xword", cons, 8},
92421122
KR
64#ifdef OBJ_ELF
65 {"uaxword", cons, 8},
66#endif
428d312b
KR
67#endif
68/* end-sanitize-v9 */
693b21e7 69#ifdef OBJ_ELF
693b21e7
KR
70 /* these are specific to sparc/svr4 */
71 {"pushsection", obj_elf_section, 0},
72 {"popsection", obj_elf_previous, 0},
73 {"uaword", cons, 4},
74 {"uahalf", cons, 2},
75#endif
355afbcd 76 {NULL, 0, 0},
fecd2382
RP
77};
78
839df5c3
RP
79const int md_short_jump_size = 4;
80const int md_long_jump_size = 4;
355afbcd 81const int md_reloc_size = 12; /* Size of relocation record */
fecd2382
RP
82
83/* This array holds the chars that always start a comment. If the
84 pre-processor is disabled, these aren't very useful */
839df5c3 85const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
fecd2382
RP
86
87/* This array holds the chars that only start a comment at the beginning of
88 a line. If the line seems to have the form '# 123 filename'
89 .line and .file directives will appear in the pre-processed output */
90/* Note that input_file.c hand checks for '#' at the beginning of the
91 first line of the input file. This is because the compiler outputs
92 #NO_APP at the beginning of its output. */
839df5c3
RP
93/* Also note that comments started like this one will always
94 work if '/' isn't otherwise defined. */
95const char line_comment_chars[] = "#";
fecd2382 96
355afbcd
KR
97const char line_separator_chars[] = "";
98
fecd2382 99/* Chars that can be used to separate mant from exp in floating point nums */
839df5c3 100const char EXP_CHARS[] = "eE";
fecd2382
RP
101
102/* Chars that mean this number is a floating point constant */
103/* As in 0f12.456 */
104/* or 0d1.2345e12 */
839df5c3 105const char FLT_CHARS[] = "rRsSfFdDxXpP";
fecd2382
RP
106
107/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
9b6a882e
KR
108 changed in read.c. Ideally it shouldn't have to know about it at all,
109 but nothing is ideal around here. */
fecd2382
RP
110
111static unsigned char octal[256];
58d4951d 112#define isoctal(c) octal[(unsigned char) (c)]
355afbcd
KR
113static unsigned char toHex[256];
114
115struct sparc_it
116 {
117 char *error;
118 unsigned long opcode;
119 struct nlist *nlistp;
120 expressionS exp;
121 int pcrel;
428d312b 122 bfd_reloc_code_real_type reloc;
428d312b
KR
123 };
124
125struct sparc_it the_insn, set_insn;
126
fecd2382 127#if 0
428d312b 128static void print_insn PARAMS ((struct sparc_it *insn));
fecd2382 129#endif
428d312b 130static int getExpression PARAMS ((char *str));
a87b3269 131
fecd2382
RP
132static char *expr_end;
133static int special_case;
134
135/*
136 * Instructions that require wierd handling because they're longer than
137 * 4 bytes.
138 */
139#define SPECIAL_CASE_SET 1
140#define SPECIAL_CASE_FDIV 2
141
142/*
143 * sort of like s_lcomm
144 *
145 */
58d4951d 146#ifndef OBJ_ELF
584a0f78 147static int max_alignment = 15;
58d4951d 148#endif
584a0f78 149
355afbcd 150static void
7766838e
ILT
151s_reserve (ignore)
152 int ignore;
355afbcd
KR
153{
154 char *name;
155 char *p;
156 char c;
157 int align;
158 int size;
159 int temp;
160 symbolS *symbolP;
161
162 name = input_line_pointer;
163 c = get_symbol_end ();
164 p = input_line_pointer;
165 *p = c;
166 SKIP_WHITESPACE ();
167
168 if (*input_line_pointer != ',')
169 {
170 as_bad ("Expected comma after name");
171 ignore_rest_of_line ();
172 return;
173 }
174
175 ++input_line_pointer;
176
177 if ((size = get_absolute_expression ()) < 0)
178 {
179 as_bad ("BSS length (%d.) <0! Ignored.", size);
180 ignore_rest_of_line ();
181 return;
182 } /* bad length */
183
184 *p = 0;
185 symbolP = symbol_find_or_make (name);
186 *p = c;
187
125f0b0d
KR
188 if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
189 && strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
355afbcd
KR
190 {
191 as_bad ("bad .reserve segment: `%s'", input_line_pointer);
192 return;
9b6a882e 193 }
355afbcd 194
125f0b0d
KR
195 if (input_line_pointer[2] == '.')
196 input_line_pointer += 7;
197 else
198 input_line_pointer += 6;
355afbcd
KR
199 SKIP_WHITESPACE ();
200
201 if (*input_line_pointer == ',')
202 {
203 ++input_line_pointer;
204
205 SKIP_WHITESPACE ();
206 if (*input_line_pointer == '\n')
207 {
208 as_bad ("Missing alignment");
209 return;
210 }
211
212 align = get_absolute_expression ();
58d4951d 213#ifndef OBJ_ELF
355afbcd
KR
214 if (align > max_alignment)
215 {
216 align = max_alignment;
217 as_warn ("Alignment too large: %d. assumed.", align);
218 }
58d4951d
ILT
219#endif
220 if (align < 0)
355afbcd
KR
221 {
222 align = 0;
223 as_warn ("Alignment negative. 0 assumed.");
fecd2382 224 }
428d312b
KR
225
226 record_alignment (bss_section, align);
355afbcd
KR
227
228 /* convert to a power of 2 alignment */
229 for (temp = 0; (align & 1) == 0; align >>= 1, ++temp);;
230
231 if (align != 1)
232 {
233 as_bad ("Alignment not a power of 2");
234 ignore_rest_of_line ();
235 return;
236 } /* not a power of two */
237
238 align = temp;
355afbcd 239 } /* if has optional alignment */
428d312b
KR
240 else
241 align = 0;
355afbcd 242
125f0b0d
KR
243 if ((S_GET_SEGMENT (symbolP) == bss_section
244 || !S_IS_DEFINED (symbolP))
245#ifdef OBJ_AOUT
246 && S_GET_OTHER (symbolP) == 0
355afbcd 247 && S_GET_DESC (symbolP) == 0
125f0b0d
KR
248#endif
249 )
355afbcd 250 {
428d312b
KR
251 if (! need_pass_2)
252 {
7766838e 253 char *pfrag;
428d312b
KR
254 segT current_seg = now_seg;
255 subsegT current_subseg = now_subseg;
256
257 subseg_set (bss_section, 1); /* switch to bss */
258
259 if (align)
260 frag_align (align, 0); /* do alignment */
261
262 /* detach from old frag */
263 if (S_GET_SEGMENT(symbolP) == bss_section)
264 symbolP->sy_frag->fr_symbol = NULL;
265
266 symbolP->sy_frag = frag_now;
7766838e
ILT
267 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
268 size, (char *)0);
269 *pfrag = 0;
428d312b
KR
270
271 S_SET_SEGMENT (symbolP, bss_section);
272
273 subseg_set (current_seg, current_subseg);
274 }
355afbcd
KR
275 }
276 else
277 {
428d312b 278 as_warn("Ignoring attempt to re-define symbol %s.", name);
355afbcd
KR
279 } /* if not redefining */
280
281 demand_empty_rest_of_line ();
428d312b 282}
355afbcd
KR
283
284static void
7766838e
ILT
285s_common (ignore)
286 int ignore;
355afbcd 287{
ed9638af
KR
288 char *name;
289 char c;
290 char *p;
291 int temp, size;
292 symbolS *symbolP;
355afbcd
KR
293
294 name = input_line_pointer;
295 c = get_symbol_end ();
296 /* just after name is now '\0' */
297 p = input_line_pointer;
298 *p = c;
299 SKIP_WHITESPACE ();
300 if (*input_line_pointer != ',')
301 {
302 as_bad ("Expected comma after symbol-name");
303 ignore_rest_of_line ();
304 return;
305 }
306 input_line_pointer++; /* skip ',' */
307 if ((temp = get_absolute_expression ()) < 0)
308 {
309 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
310 ignore_rest_of_line ();
311 return;
312 }
ed9638af 313 size = temp;
355afbcd
KR
314 *p = 0;
315 symbolP = symbol_find_or_make (name);
316 *p = c;
317 if (S_IS_DEFINED (symbolP))
318 {
319 as_bad ("Ignoring attempt to re-define symbol");
320 ignore_rest_of_line ();
321 return;
322 }
323 if (S_GET_VALUE (symbolP) != 0)
324 {
ed9638af 325 if (S_GET_VALUE (symbolP) != size)
355afbcd 326 {
125f0b0d
KR
327 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
328 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
680227f3 329 }
355afbcd
KR
330 }
331 else
332 {
ed9638af 333#ifndef OBJ_ELF
7766838e 334 S_SET_VALUE (symbolP, (valueT) size);
355afbcd 335 S_SET_EXTERNAL (symbolP);
428d312b 336#endif
355afbcd
KR
337 }
338 know (symbolP->sy_frag == &zero_address_frag);
428d312b
KR
339 if (*input_line_pointer != ',')
340 {
125f0b0d 341 as_bad ("Expected comma after common length");
428d312b
KR
342 ignore_rest_of_line ();
343 return;
344 }
345 input_line_pointer++;
125f0b0d
KR
346 SKIP_WHITESPACE ();
347 if (*input_line_pointer != '"')
ed9638af 348 {
125f0b0d 349 temp = get_absolute_expression ();
58d4951d 350#ifndef OBJ_ELF
125f0b0d
KR
351 if (temp > max_alignment)
352 {
353 temp = max_alignment;
354 as_warn ("Common alignment too large: %d. assumed", temp);
355 }
58d4951d
ILT
356#endif
357 if (temp < 0)
125f0b0d
KR
358 {
359 temp = 0;
360 as_warn ("Common alignment negative; 0 assumed");
361 }
b2565433 362#ifdef OBJ_ELF
125f0b0d
KR
363 if (symbolP->local)
364 {
ff4cac38
KR
365 segT old_sec;
366 int old_subsec;
125f0b0d 367 char *p;
ff4cac38 368 int align;
ed9638af 369
ff4cac38
KR
370 allocate_bss:
371 old_sec = now_seg;
372 old_subsec = now_subseg;
373 align = temp;
125f0b0d
KR
374 record_alignment (bss_section, align);
375 subseg_set (bss_section, 0);
376 if (align)
377 frag_align (align, 0);
378 if (S_GET_SEGMENT (symbolP) == bss_section)
379 symbolP->sy_frag->fr_symbol = 0;
380 symbolP->sy_frag = frag_now;
381 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
382 (char *) 0);
383 *p = 0;
384 S_SET_SEGMENT (symbolP, bss_section);
385 S_CLEAR_EXTERNAL (symbolP);
386 subseg_set (old_sec, old_subsec);
387 }
388 else
b2565433 389#endif
125f0b0d 390 {
ff4cac38 391 allocate_common:
7766838e 392 S_SET_VALUE (symbolP, (valueT) size);
125f0b0d
KR
393 S_SET_EXTERNAL (symbolP);
394 /* should be common, but this is how gas does it for now */
395 S_SET_SEGMENT (symbolP, &bfd_und_section);
396 }
ed9638af
KR
397 }
398 else
399 {
125f0b0d 400 input_line_pointer++;
ff4cac38
KR
401 /* @@ Some use the dot, some don't. Can we get some consistency?? */
402 if (*input_line_pointer == '.')
403 input_line_pointer++;
404 /* @@ Some say data, some say bss. */
125f0b0d 405 if (strncmp (input_line_pointer, "bss\"", 4)
ff4cac38 406 && strncmp (input_line_pointer, "data\"", 5))
125f0b0d 407 {
ff4cac38
KR
408 while (*--input_line_pointer != '"')
409 ;
410 input_line_pointer--;
125f0b0d
KR
411 goto bad_common_segment;
412 }
413 while (*input_line_pointer++ != '"')
414 ;
ff4cac38 415 goto allocate_common;
355afbcd 416 }
355afbcd
KR
417 demand_empty_rest_of_line ();
418 return;
ff4cac38
KR
419
420 {
421 bad_common_segment:
422 p = input_line_pointer;
423 while (*p && *p != '\n')
424 p++;
425 c = *p;
426 *p = '\0';
427 as_bad ("bad .common segment %s", input_line_pointer + 1);
428 *p = c;
429 input_line_pointer = p;
430 ignore_rest_of_line ();
431 return;
432 }
433}
355afbcd
KR
434
435static void
7766838e
ILT
436s_seg (ignore)
437 int ignore;
355afbcd
KR
438{
439
440 if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
441 {
442 input_line_pointer += 6;
7766838e 443 s_text (0);
355afbcd
KR
444 return;
445 }
446 if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
447 {
448 input_line_pointer += 6;
7766838e 449 s_data (0);
355afbcd
KR
450 return;
451 }
452 if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
453 {
454 input_line_pointer += 7;
455 s_data1 ();
456 return;
457 }
458 if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
459 {
460 input_line_pointer += 5;
461 /* We only support 2 segments -- text and data -- for now, so
428d312b
KR
462 things in the "bss segment" will have to go into data for now.
463 You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
464 subseg_set (data_section, 255); /* FIXME-SOMEDAY */
355afbcd
KR
465 return;
466 }
467 as_bad ("Unknown segment type");
468 demand_empty_rest_of_line ();
c999fd9f 469}
355afbcd
KR
470
471static void
472s_data1 ()
473{
428d312b 474 subseg_set (data_section, 1);
355afbcd 475 demand_empty_rest_of_line ();
c999fd9f 476}
fecd2382 477
355afbcd 478static void
7766838e
ILT
479s_proc (ignore)
480 int ignore;
355afbcd 481{
58d4951d 482 while (!is_end_of_line[(unsigned char) *input_line_pointer])
355afbcd
KR
483 {
484 ++input_line_pointer;
485 }
486 ++input_line_pointer;
c999fd9f 487}
fecd2382 488
680227f3
KR
489/* start-sanitize-v9 */
490#ifndef NO_V9
428d312b 491
355afbcd
KR
492struct priv_reg_entry
493 {
494 char *name;
495 int regnum;
496 };
428d312b 497
680227f3
KR
498struct priv_reg_entry priv_reg_table[] =
499{
355afbcd
KR
500 {"tpc", 0},
501 {"tnpc", 1},
502 {"tstate", 2},
503 {"tt", 3},
504 {"tick", 4},
505 {"tba", 5},
506 {"pstate", 6},
507 {"tl", 7},
508 {"pil", 8},
509 {"cwp", 9},
510 {"cansave", 10},
511 {"canrestore", 11},
512 {"cleanwin", 12},
513 {"otherwin", 13},
514 {"wstate", 14},
125f0b0d 515 {"fq", 15},
355afbcd
KR
516 {"ver", 31},
517 {"", -1}, /* end marker */
680227f3
KR
518};
519
ed9638af
KR
520struct membar_masks
521{
522 char *name;
7766838e
ILT
523 unsigned int len;
524 unsigned int mask;
ed9638af
KR
525};
526
527#define MEMBAR_MASKS_SIZE 7
528
529struct membar_masks membar_masks[MEMBAR_MASKS_SIZE] =
530{
531 {"Sync", 4, 0x40},
532 {"MemIssue", 8, 0x20},
533 {"Lookaside", 9, 0x10},
534 {"StoreStore", 10, 0x08},
535 {"LoadStore", 9, 0x04},
536 {"StoreLoad", 9, 0x02},
537 {"LoadLoad", 8, 0x01},
538};
539
355afbcd
KR
540static int
541cmp_reg_entry (p, q)
680227f3
KR
542 struct priv_reg_entry *p, *q;
543{
544 return strcmp (q->name, p->name);
545}
355afbcd 546
680227f3
KR
547#endif
548/* end-sanitize-v9 */
549
fecd2382
RP
550/* This function is called once, at assembler startup time. It should
551 set up all the tables, etc. that the MD part of the assembler will need. */
355afbcd
KR
552void
553md_begin ()
554{
7766838e 555 register const char *retval = NULL;
355afbcd
KR
556 int lose = 0;
557 register unsigned int i = 0;
558
559 op_hash = hash_new ();
355afbcd
KR
560
561 while (i < NUMOPCODES)
562 {
563 const char *name = sparc_opcodes[i].name;
564 retval = hash_insert (op_hash, name, &sparc_opcodes[i]);
7766838e 565 if (retval != NULL)
355afbcd
KR
566 {
567 fprintf (stderr, "internal error: can't hash `%s': %s\n",
568 sparc_opcodes[i].name, retval);
569 lose = 1;
fecd2382 570 }
355afbcd
KR
571 do
572 {
573 if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
574 {
575 fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
576 sparc_opcodes[i].name, sparc_opcodes[i].args);
577 lose = 1;
578 }
579 ++i;
580 }
581 while (i < NUMOPCODES
582 && !strcmp (sparc_opcodes[i].name, name));
583 }
584
585 if (lose)
586 as_fatal ("Broken assembler. No assembly attempted.");
587
588 for (i = '0'; i < '8'; ++i)
589 octal[i] = 1;
590 for (i = '0'; i <= '9'; ++i)
591 toHex[i] = i - '0';
592 for (i = 'a'; i <= 'f'; ++i)
593 toHex[i] = i + 10 - 'a';
594 for (i = 'A'; i <= 'F'; ++i)
595 toHex[i] = i + 10 - 'A';
596
597 /* start-sanitize-v9 */
680227f3 598#ifndef NO_V9
125f0b0d
KR
599#ifdef sparcv9
600 current_architecture = v9;
601#endif
602
355afbcd
KR
603 qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
604 sizeof (priv_reg_table[0]), cmp_reg_entry);
680227f3 605#endif
355afbcd 606 /* end-sanitize-v9 */
ed9638af
KR
607
608 target_big_endian = 1;
9b6a882e 609}
fecd2382 610
355afbcd
KR
611void
612md_assemble (str)
613 char *str;
fecd2382 614{
355afbcd
KR
615 char *toP;
616 int rsd;
617
618 know (str);
619 sparc_ip (str);
620
621 /* See if "set" operand is absolute and small; skip sethi if so. */
428d312b 622 if (special_case == SPECIAL_CASE_SET
5ac34ac3 623 && the_insn.exp.X_op == O_constant)
355afbcd
KR
624 {
625 if (the_insn.exp.X_add_number >= -(1 << 12)
626 && the_insn.exp.X_add_number < (1 << 12))
627 {
628 the_insn.opcode = 0x80102000 /* or %g0,imm,... */
629 | (the_insn.opcode & 0x3E000000) /* dest reg */
630 | (the_insn.exp.X_add_number & 0x1FFF); /* imm */
631 special_case = 0; /* No longer special */
428d312b 632 the_insn.reloc = BFD_RELOC_NONE; /* No longer relocated */
680227f3 633 }
355afbcd
KR
634 }
635
636 toP = frag_more (4);
637 /* put out the opcode */
125f0b0d 638 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
355afbcd
KR
639
640 /* put out the symbol-dependent stuff */
428d312b 641 if (the_insn.reloc != BFD_RELOC_NONE)
355afbcd 642 {
5ac34ac3
ILT
643 fix_new_exp (frag_now, /* which frag */
644 (toP - frag_now->fr_literal), /* where */
645 4, /* size */
646 &the_insn.exp,
647 the_insn.pcrel,
648 the_insn.reloc);
355afbcd 649 }
428d312b 650
355afbcd
KR
651 switch (special_case)
652 {
355afbcd
KR
653 case SPECIAL_CASE_SET:
654 special_case = 0;
428d312b 655 assert (the_insn.reloc == BFD_RELOC_HI22);
355afbcd 656 /* See if "set" operand has no low-order bits; skip OR if so. */
5ac34ac3 657 if (the_insn.exp.X_op == O_constant
355afbcd
KR
658 && ((the_insn.exp.X_add_number & 0x3FF) == 0))
659 return;
660 toP = frag_more (4);
661 rsd = (the_insn.opcode >> 25) & 0x1f;
662 the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
125f0b0d 663 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
5ac34ac3
ILT
664 fix_new_exp (frag_now, /* which frag */
665 (toP - frag_now->fr_literal), /* where */
666 4, /* size */
667 &the_insn.exp,
668 the_insn.pcrel,
669 BFD_RELOC_LO10);
355afbcd
KR
670 return;
671
672 case SPECIAL_CASE_FDIV:
673 /* According to information leaked from Sun, the "fdiv" instructions
8fc0776d
JW
674 on early SPARC machines would produce incorrect results sometimes.
675 The workaround is to add an fmovs of the destination register to
676 itself just after the instruction. This was true on machines
677 with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
355afbcd 678 special_case = 0;
428d312b 679 assert (the_insn.reloc == BFD_RELOC_NONE);
355afbcd
KR
680 toP = frag_more (4);
681 rsd = (the_insn.opcode >> 25) & 0x1f;
682 the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */
125f0b0d 683 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
355afbcd
KR
684 return;
685
686 case 0:
687 return;
688
689 default:
690 as_fatal ("failed sanity check.");
691 }
9b6a882e 692}
355afbcd
KR
693
694static void
695sparc_ip (str)
696 char *str;
fecd2382 697{
355afbcd
KR
698 char *error_message = "";
699 char *s;
700 const char *args;
701 char c;
702 struct sparc_opcode *insn;
703 char *argsStart;
704 unsigned long opcode;
705 unsigned int mask = 0;
706 int match = 0;
707 int comma = 0;
708 long immediate_max = 0;
709
710 for (s = str; islower (*s) || (*s >= '0' && *s <= '3'); ++s)
711 ;
712 switch (*s)
713 {
714
715 case '\0':
716 break;
717
718 case ',':
719 comma = 1;
720
721 /*FALLTHROUGH */
722
723 case ' ':
724 *s++ = '\0';
725 break;
726
727 default:
728 as_bad ("Unknown opcode: `%s'", str);
729 exit (1);
730 }
731 if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL)
732 {
733 as_bad ("Unknown opcode: `%s'", str);
734 return;
735 }
736 if (comma)
737 {
738 *--s = ',';
739 }
740 argsStart = s;
741 for (;;)
742 {
743 opcode = insn->match;
744 memset (&the_insn, '\0', sizeof (the_insn));
428d312b 745 the_insn.reloc = BFD_RELOC_NONE;
355afbcd
KR
746
747 /*
8fc0776d
JW
748 * Build the opcode, checking as we go to make
749 * sure that the operands match
750 */
355afbcd
KR
751 for (args = insn->args;; ++args)
752 {
753 switch (*args)
754 {
755
756 /* start-sanitize-v9 */
680227f3 757#ifndef NO_V9
355afbcd
KR
758 case 'K':
759 {
7766838e 760 int kmask = 0;
ed9638af
KR
761 int i;
762
763 /* Parse a series of masks. */
764 if (*s == '#')
355afbcd 765 {
ed9638af 766 while (*s == '#')
355afbcd 767 {
ed9638af
KR
768 ++s;
769 for (i = 0; i < MEMBAR_MASKS_SIZE; i++)
770 if (!strncmp (s, membar_masks[i].name,
771 membar_masks[i].len))
772 break;
773 if (i < MEMBAR_MASKS_SIZE)
774 {
7766838e 775 kmask |= membar_masks[i].mask;
ed9638af
KR
776 s += membar_masks[i].len;
777 }
778 else
779 {
780 error_message = ": invalid membar mask name";
781 goto error;
782 }
783 if (*s == '|')
784 ++s;
355afbcd 785 }
ed9638af 786 }
c999fd9f 787 else
ed9638af 788 {
c999fd9f
KR
789 expressionS exp;
790 char *hold;
9b2fd75b 791 char *send;
ed9638af 792
c999fd9f
KR
793 hold = input_line_pointer;
794 input_line_pointer = s;
795 expression (&exp);
796 send = input_line_pointer;
797 input_line_pointer = hold;
798
799 kmask = exp.X_add_number;
800 if (exp.X_op != O_constant
801 || kmask < 0
802 || kmask > 127)
ed9638af
KR
803 {
804 error_message = ": invalid membar mask number";
805 goto error;
355afbcd 806 }
c999fd9f 807
9b2fd75b 808 s = send;
355afbcd 809 }
c999fd9f 810
7766838e 811 opcode |= SIMM13 (kmask);
355afbcd
KR
812 continue;
813 }
814
815 case '*':
ed9638af
KR
816 {
817 int prefetch_fcn = 0;
355afbcd 818
ed9638af
KR
819 /* Parse a prefetch function. */
820 if (*s == '#')
821 {
822 s += 1;
823 if (!strncmp (s, "n_reads", 7))
824 prefetch_fcn = 0, s += 7;
825 else if (!strncmp (s, "one_read", 8))
826 prefetch_fcn = 1, s += 8;
827 else if (!strncmp (s, "n_writes", 8))
828 prefetch_fcn = 2, s += 8;
829 else if (!strncmp (s, "one_write", 9))
830 prefetch_fcn = 3, s += 9;
831 else if (!strncmp (s, "page", 4))
832 prefetch_fcn = 4, s += 4;
833 else
834 {
835 error_message = ": invalid prefetch function name";
836 goto error;
837 }
838 }
839 else if (isdigit (*s))
840 {
841 while (isdigit (*s))
842 {
843 prefetch_fcn = prefetch_fcn * 10 + *s - '0';
844 ++s;
845 }
846
847 if (prefetch_fcn < 0 || prefetch_fcn > 31)
848 {
849 error_message = ": invalid prefetch function number";
850 goto error;
851 }
852 }
853 else
854 {
855 error_message = ": unrecognizable prefetch function";
856 goto error;
857 }
858 opcode |= RD (prefetch_fcn);
859 continue;
860 }
355afbcd
KR
861
862 case '!':
863 case '?':
864 /* Parse a privileged register. */
865 if (*s == '%')
866 {
867 struct priv_reg_entry *p = priv_reg_table;
7766838e 868 unsigned int len = 9999999; /* init to make gcc happy */
355afbcd
KR
869
870 s += 1;
871 while (p->name[0] > s[0])
872 p++;
873 while (p->name[0] == s[0])
874 {
875 len = strlen (p->name);
876 if (strncmp (p->name, s, len) == 0)
877 break;
878 p++;
879 }
880 if (p->name[0] != s[0])
881 {
ed9638af 882 error_message = ": unrecognizable privileged register";
355afbcd
KR
883 goto error;
884 }
885 if (*args == '?')
886 opcode |= (p->regnum << 14);
887 else
888 opcode |= (p->regnum << 25);
889 s += len;
890 continue;
891 }
892 else
893 {
ed9638af 894 error_message = ": unrecognizable privileged register";
355afbcd
KR
895 goto error;
896 }
897#endif
898 /* end-sanitize-v9 */
680227f3 899
355afbcd
KR
900 case 'M':
901 case 'm':
902 if (strncmp (s, "%asr", 4) == 0)
903 {
904 s += 4;
680227f3 905
355afbcd
KR
906 if (isdigit (*s))
907 {
908 long num = 0;
909
910 while (isdigit (*s))
911 {
912 num = num * 10 + *s - '0';
913 ++s;
914 }
915
916 if (num < 16 || 31 < num)
917 {
918 error_message = ": asr number must be between 15 and 31";
919 goto error;
920 } /* out of range */
921
922 opcode |= (*args == 'M' ? RS1 (num) : RD (num));
923 continue;
924 }
925 else
926 {
927 error_message = ": expecting %asrN";
928 goto error;
929 } /* if %asr followed by a number. */
930
931 } /* if %asr */
932 break;
933
934 /* start-sanitize-v9 */
935#ifndef NO_V9
936 case 'I':
125f0b0d 937 the_insn.reloc = BFD_RELOC_SPARC_11;
355afbcd
KR
938 immediate_max = 0x03FF;
939 goto immediate;
940
941 case 'j':
125f0b0d 942 the_insn.reloc = BFD_RELOC_SPARC_10;
355afbcd
KR
943 immediate_max = 0x01FF;
944 goto immediate;
945
946 case 'k':
125f0b0d 947 the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16;
355afbcd
KR
948 the_insn.pcrel = 1;
949 goto immediate;
950
951 case 'G':
125f0b0d 952 the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
355afbcd
KR
953 the_insn.pcrel = 1;
954 goto immediate;
955
956 case 'N':
957 if (*s == 'p' && s[1] == 'n')
958 {
959 s += 2;
960 continue;
961 }
962 break;
963
964 case 'T':
965 if (*s == 'p' && s[1] == 't')
966 {
967 s += 2;
968 continue;
969 }
970 break;
971
972 case 'z':
973 if (*s == ' ')
974 {
975 ++s;
976 }
0d44b3d1 977 if (strncmp (s, "%icc", 4) == 0)
355afbcd 978 {
0d44b3d1 979 s += 4;
355afbcd
KR
980 continue;
981 }
982 break;
983
984 case 'Z':
985 if (*s == ' ')
986 {
987 ++s;
988 }
0d44b3d1 989 if (strncmp (s, "%xcc", 4) == 0)
355afbcd 990 {
0d44b3d1 991 s += 4;
355afbcd
KR
992 continue;
993 }
994 break;
995
996 case '6':
997 if (*s == ' ')
998 {
999 ++s;
1000 }
0d44b3d1 1001 if (strncmp (s, "%fcc0", 5) == 0)
355afbcd 1002 {
0d44b3d1 1003 s += 5;
355afbcd
KR
1004 continue;
1005 }
1006 break;
1007
1008 case '7':
1009 if (*s == ' ')
1010 {
1011 ++s;
1012 }
0d44b3d1 1013 if (strncmp (s, "%fcc1", 5) == 0)
355afbcd 1014 {
0d44b3d1 1015 s += 5;
355afbcd
KR
1016 continue;
1017 }
1018 break;
1019
1020 case '8':
1021 if (*s == ' ')
1022 {
1023 ++s;
1024 }
0d44b3d1 1025 if (strncmp (s, "%fcc2", 5) == 0)
355afbcd 1026 {
0d44b3d1 1027 s += 5;
355afbcd
KR
1028 continue;
1029 }
1030 break;
1031
1032 case '9':
1033 if (*s == ' ')
1034 {
1035 ++s;
1036 }
0d44b3d1 1037 if (strncmp (s, "%fcc3", 5) == 0)
355afbcd 1038 {
0d44b3d1 1039 s += 5;
355afbcd
KR
1040 continue;
1041 }
1042 break;
1043
1044 case 'P':
1045 if (strncmp (s, "%pc", 3) == 0)
1046 {
1047 s += 3;
1048 continue;
1049 }
1050 break;
1051
1052 case 'W':
1053 if (strncmp (s, "%tick", 5) == 0)
1054 {
1055 s += 5;
1056 continue;
1057 }
1058 break;
1059#endif /* NO_V9 */
1060 /* end-sanitize-v9 */
1061
1062 case '\0': /* end of args */
1063 if (*s == '\0')
1064 {
1065 match = 1;
1066 }
1067 break;
1068
1069 case '+':
1070 if (*s == '+')
1071 {
1072 ++s;
1073 continue;
1074 }
1075 if (*s == '-')
1076 {
1077 continue;
1078 }
1079 break;
1080
1081 case '[': /* these must match exactly */
1082 case ']':
1083 case ',':
1084 case ' ':
1085 if (*s++ == *args)
1086 continue;
1087 break;
1088
1089 case '#': /* must be at least one digit */
1090 if (isdigit (*s++))
1091 {
1092 while (isdigit (*s))
1093 {
1094 ++s;
1095 }
1096 continue;
1097 }
1098 break;
1099
1100 case 'C': /* coprocessor state register */
1101 if (strncmp (s, "%csr", 4) == 0)
1102 {
1103 s += 4;
1104 continue;
1105 }
1106 break;
1107
1108 case 'b': /* next operand is a coprocessor register */
1109 case 'c':
1110 case 'D':
1111 if (*s++ == '%' && *s++ == 'c' && isdigit (*s))
1112 {
1113 mask = *s++;
1114 if (isdigit (*s))
1115 {
1116 mask = 10 * (mask - '0') + (*s++ - '0');
1117 if (mask >= 32)
1118 {
1119 break;
1120 }
1121 }
1122 else
1123 {
1124 mask -= '0';
1125 }
1126 switch (*args)
1127 {
1128
1129 case 'b':
1130 opcode |= mask << 14;
1131 continue;
1132
1133 case 'c':
1134 opcode |= mask;
1135 continue;
1136
1137 case 'D':
1138 opcode |= mask << 25;
1139 continue;
1140 }
1141 }
1142 break;
1143
1144 case 'r': /* next operand must be a register */
1145 case '1':
1146 case '2':
1147 case 'd':
1148 if (*s++ == '%')
1149 {
1150 switch (c = *s++)
1151 {
1152
1153 case 'f': /* frame pointer */
1154 if (*s++ == 'p')
1155 {
1156 mask = 0x1e;
1157 break;
1158 }
1159 goto error;
1160
1161 case 'g': /* global register */
1162 if (isoctal (c = *s++))
1163 {
1164 mask = c - '0';
1165 break;
1166 }
1167 goto error;
1168
1169 case 'i': /* in register */
1170 if (isoctal (c = *s++))
1171 {
1172 mask = c - '0' + 24;
1173 break;
1174 }
1175 goto error;
1176
1177 case 'l': /* local register */
1178 if (isoctal (c = *s++))
1179 {
1180 mask = (c - '0' + 16);
1181 break;
1182 }
1183 goto error;
1184
1185 case 'o': /* out register */
1186 if (isoctal (c = *s++))
1187 {
1188 mask = (c - '0' + 8);
1189 break;
1190 }
1191 goto error;
1192
1193 case 's': /* stack pointer */
1194 if (*s++ == 'p')
1195 {
1196 mask = 0xe;
1197 break;
1198 }
1199 goto error;
1200
1201 case 'r': /* any register */
1202 if (!isdigit (c = *s++))
1203 {
1204 goto error;
1205 }
1206 /* FALLTHROUGH */
1207 case '0':
1208 case '1':
1209 case '2':
1210 case '3':
1211 case '4':
1212 case '5':
1213 case '6':
1214 case '7':
1215 case '8':
1216 case '9':
1217 if (isdigit (*s))
1218 {
1219 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
680227f3 1220 {
680227f3
KR
1221 goto error;
1222 }
355afbcd
KR
1223 }
1224 else
1225 {
1226 c -= '0';
1227 }
1228 mask = c;
1229 break;
1230
1231 default:
1232 goto error;
1233 }
1234 /*
680227f3
KR
1235 * Got the register, now figure out where
1236 * it goes in the opcode.
1237 */
355afbcd
KR
1238 switch (*args)
1239 {
1240
1241 case '1':
1242 opcode |= mask << 14;
1243 continue;
1244
1245 case '2':
1246 opcode |= mask;
1247 continue;
1248
1249 case 'd':
1250 opcode |= mask << 25;
1251 continue;
1252
1253 case 'r':
1254 opcode |= (mask << 25) | (mask << 14);
1255 continue;
1256 }
1257 }
1258 break;
1259
1260 case 'e': /* next operand is a floating point register */
1261 case 'v':
1262 case 'V':
1263
1264 case 'f':
1265 case 'B':
1266 case 'R':
1267
1268 case 'g':
1269 case 'H':
1270 case 'J':
1271 {
1272 char format;
1273
1274 if (*s++ == '%'
355afbcd 1275 && ((format = *s) == 'f')
355afbcd
KR
1276 && isdigit (*++s))
1277 {
355afbcd
KR
1278 for (mask = 0; isdigit (*s); ++s)
1279 {
1280 mask = 10 * mask + (*s - '0');
1281 } /* read the number */
1282
1283 if ((*args == 'v'
1284 || *args == 'B'
1285 || *args == 'H')
1286 && (mask & 1))
1287 {
1288 break;
1289 } /* register must be even numbered */
1290
1291 if ((*args == 'V'
1292 || *args == 'R'
1293 || *args == 'J')
1294 && (mask & 3))
1295 {
1296 break;
1297 } /* register must be multiple of 4 */
1298
125f0b0d 1299/* start-sanitize-v9 */
a79c6033 1300#ifndef NO_V9
125f0b0d 1301 if (mask >= 64)
355afbcd 1302 {
125f0b0d
KR
1303 error_message = ": There are only 64 f registers; [0-63]";
1304 goto error;
1305 } /* on error */
1306 if (mask >= 32)
1307 {
1308 mask -= 31;
1309 } /* wrap high bit */
1310#else
1311/* end-sanitize-v9 */
1312 if (mask >= 32)
1313 {
1314 error_message = ": There are only 32 f registers; [0-31]";
1315 goto error;
1316 } /* on error */
1317/* start-sanitize-v9 */
1318#endif
1319/* end-sanitize-v9 */
1320 }
1321 else
1322 {
1323 break;
1324 } /* if not an 'f' register. */
355afbcd
KR
1325
1326 switch (*args)
1327 {
1328
1329 case 'v':
1330 case 'V':
1331 case 'e':
1332 opcode |= RS1 (mask);
1333 continue;
1334
1335
1336 case 'f':
1337 case 'B':
1338 case 'R':
1339 opcode |= RS2 (mask);
1340 continue;
1341
1342 case 'g':
1343 case 'H':
1344 case 'J':
1345 opcode |= RD (mask);
1346 continue;
1347 } /* pack it in. */
1348
1349 know (0);
1350 break;
1351 } /* float arg */
1352
1353 case 'F':
1354 if (strncmp (s, "%fsr", 4) == 0)
1355 {
1356 s += 4;
1357 continue;
1358 }
1359 break;
1360
1361 case 'h': /* high 22 bits */
428d312b 1362 the_insn.reloc = BFD_RELOC_HI22;
355afbcd
KR
1363 goto immediate;
1364
1365 case 'l': /* 22 bit PC relative immediate */
428d312b 1366 the_insn.reloc = BFD_RELOC_SPARC_WDISP22;
355afbcd
KR
1367 the_insn.pcrel = 1;
1368 goto immediate;
1369
1370 case 'L': /* 30 bit immediate */
428d312b 1371 the_insn.reloc = BFD_RELOC_32_PCREL_S2;
355afbcd
KR
1372 the_insn.pcrel = 1;
1373 goto immediate;
1374
1375 case 'n': /* 22 bit immediate */
428d312b 1376 the_insn.reloc = BFD_RELOC_SPARC22;
355afbcd
KR
1377 goto immediate;
1378
1379 case 'i': /* 13 bit immediate */
428d312b
KR
1380 /* What's the difference between base13 and 13? */
1381 the_insn.reloc = BFD_RELOC_SPARC_BASE13;
355afbcd
KR
1382 immediate_max = 0x0FFF;
1383
1384 /*FALLTHROUGH */
1385
1386 immediate:
1387 if (*s == ' ')
1388 s++;
1389 if (*s == '%')
1390 {
1391 if ((c = s[1]) == 'h' && s[2] == 'i')
1392 {
428d312b 1393 the_insn.reloc = BFD_RELOC_HI22;
355afbcd
KR
1394 s += 3;
1395 }
1396 else if (c == 'l' && s[2] == 'o')
1397 {
428d312b 1398 the_insn.reloc = BFD_RELOC_LO10;
355afbcd 1399 s += 3;
355afbcd 1400 }
9b6a882e
KR
1401 /* start-sanitize-v9 */
1402#ifndef NO_V9
355afbcd
KR
1403 else if (c == 'u'
1404 && s[2] == 'h'
1405 && s[3] == 'i')
1406 {
125f0b0d 1407 the_insn.reloc = BFD_RELOC_SPARC_HH22;
355afbcd 1408 s += 4;
355afbcd
KR
1409 }
1410 else if (c == 'u'
1411 && s[2] == 'l'
1412 && s[3] == 'o')
1413 {
125f0b0d 1414 the_insn.reloc = BFD_RELOC_SPARC_HM10;
355afbcd 1415 s += 4;
355afbcd 1416 }
9b6a882e
KR
1417#endif /* NO_V9 */
1418 /* end-sanitize-v9 */
355afbcd
KR
1419 else
1420 break;
1421 }
9b6a882e
KR
1422 /* Note that if the getExpression() fails, we will still
1423 have created U entries in the symbol table for the
1424 'symbols' in the input string. Try not to create U
1425 symbols for registers, etc. */
355afbcd 1426 {
9b6a882e
KR
1427 /* This stuff checks to see if the expression ends in
1428 +%reg. If it does, it removes the register from
1429 the expression, and re-sets 's' to point to the
1430 right place. */
355afbcd
KR
1431
1432 char *s1;
1433
1434 for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++);;
1435
1436 if (s1 != s && isdigit (s1[-1]))
1437 {
1438 if (s1[-2] == '%' && s1[-3] == '+')
1439 {
1440 s1 -= 3;
1441 *s1 = '\0';
1442 (void) getExpression (s);
1443 *s1 = '+';
1444 s = s1;
1445 continue;
1446 }
1447 else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
1448 {
1449 s1 -= 4;
1450 *s1 = '\0';
1451 (void) getExpression (s);
1452 *s1 = '+';
1453 s = s1;
1454 continue;
1455 }
1456 }
1457 }
1458 (void) getExpression (s);
1459 s = expr_end;
1460
9b6a882e
KR
1461 if (the_insn.exp.X_op == O_constant
1462 && the_insn.exp.X_add_symbol == 0
1463 && the_insn.exp.X_op_symbol == 0)
1464 {
1465 /* start-sanitize-v9 */
0cef0e20 1466#ifndef NO_V9
9b6a882e
KR
1467 switch (the_insn.reloc)
1468 {
1469 case BFD_RELOC_SPARC_HH22:
1470 the_insn.reloc = BFD_RELOC_HI22;
1471 the_insn.exp.X_add_number >>= 32;
1472 break;
1473 case BFD_RELOC_SPARC_HM10:
1474 the_insn.reloc = BFD_RELOC_LO10;
1475 the_insn.exp.X_add_number >>= 32;
1476 break;
c999fd9f
KR
1477 default:
1478 break;
9b6a882e 1479 }
0cef0e20 1480#endif
9b6a882e
KR
1481 /* end-sanitize-v9 */
1482 /* Check for invalid constant values. Don't warn if
1483 constant was inside %hi or %lo, since these
1484 truncate the constant to fit. */
1485 if (immediate_max != 0
1486 && the_insn.reloc != BFD_RELOC_LO10
1487 && the_insn.reloc != BFD_RELOC_HI22
1488 && (the_insn.exp.X_add_number > immediate_max
1489 || the_insn.exp.X_add_number < ~immediate_max))
1490 as_bad ("constant value must be between %ld and %ld",
1491 ~immediate_max, immediate_max);
1492 }
1493
355afbcd
KR
1494 /* Reset to prevent extraneous range check. */
1495 immediate_max = 0;
1496
1497 continue;
1498
1499 case 'a':
1500 if (*s++ == 'a')
1501 {
1502 opcode |= ANNUL;
1503 continue;
1504 }
1505 break;
1506
1507 case 'A':
1508 {
ed9638af
KR
1509/* start-sanitize-v9 */
1510#ifdef NO_V9
1511/* end-sanitize-v9 */
355afbcd
KR
1512 char *push = input_line_pointer;
1513 expressionS e;
1514
1515 input_line_pointer = s;
1516
5ac34ac3
ILT
1517 expression (&e);
1518 if (e.X_op == O_constant)
355afbcd
KR
1519 {
1520 opcode |= e.X_add_number << 5;
1521 s = input_line_pointer;
1522 input_line_pointer = push;
1523 continue;
1524 } /* if absolute */
1525
1526 break;
ed9638af
KR
1527/* start-sanitize-v9 */
1528#else
1529 int asi = 0;
1530
1531 /* Parse an asi. */
1532 if (*s == '#')
1533 {
1534 s += 1;
1535 if (!strncmp (s, "ASI_AIUP", 8))
1536 asi = 0x10, s += 8;
1537 else if (!strncmp (s, "ASI_AIUS", 8))
1538 asi = 0x11, s += 8;
1539 else if (!strncmp (s, "ASI_PNF", 7))
1540 asi = 0x82, s += 7;
1541 else if (!strncmp (s, "ASI_SNF", 7))
1542 asi = 0x83, s += 7;
1543 else if (!strncmp (s, "ASI_P", 5))
1544 asi = 0x80, s += 5;
1545 else if (!strncmp (s, "ASI_S", 5))
1546 asi = 0x81, s += 5;
1547 else
1548 {
1549 error_message = ": invalid asi name";
1550 goto error;
1551 }
1552 }
1553 else if (isdigit (*s))
1554 {
1555 char *push = input_line_pointer;
1556 input_line_pointer = s;
1557 asi = get_absolute_expression ();
1558 s = input_line_pointer;
1559 input_line_pointer = push;
1560
1561 if (asi < 0 || asi > 255)
1562 {
1563 error_message = ": invalid asi number";
1564 goto error;
1565 }
1566 }
1567 else
1568 {
1569 error_message = ": unrecognizable asi";
1570 goto error;
1571 }
1572 opcode |= ASI (asi);
1573 continue;
1574#endif
1575/* end-sanitize-v9 */
355afbcd
KR
1576 } /* alternate space */
1577
1578 case 'p':
1579 if (strncmp (s, "%psr", 4) == 0)
1580 {
1581 s += 4;
1582 continue;
1583 }
1584 break;
1585
1586 case 'q': /* floating point queue */
1587 if (strncmp (s, "%fq", 3) == 0)
1588 {
1589 s += 3;
1590 continue;
1591 }
1592 break;
1593
1594 case 'Q': /* coprocessor queue */
1595 if (strncmp (s, "%cq", 3) == 0)
1596 {
1597 s += 3;
1598 continue;
1599 }
1600 break;
1601
1602 case 'S':
1603 if (strcmp (str, "set") == 0)
1604 {
1605 special_case = SPECIAL_CASE_SET;
1606 continue;
1607 }
1608 else if (strncmp (str, "fdiv", 4) == 0)
1609 {
1610 special_case = SPECIAL_CASE_FDIV;
1611 continue;
1612 }
1613 break;
1614
1615 /* start-sanitize-v9 */
680227f3 1616#ifndef NO_V9
355afbcd
KR
1617 case 'o':
1618 if (strncmp (s, "%asi", 4) != 0)
1619 break;
1620 s += 4;
1621 continue;
1622
1623 case 's':
1624 if (strncmp (s, "%fprs", 5) != 0)
1625 break;
1626 s += 5;
1627 continue;
1628
1629 case 'E':
1630 if (strncmp (s, "%ccr", 4) != 0)
1631 break;
1632 s += 4;
1633 continue;
680227f3 1634#endif /* NO_V9 */
355afbcd 1635 /* end-sanitize-v9 */
680227f3 1636
355afbcd
KR
1637 case 't':
1638 if (strncmp (s, "%tbr", 4) != 0)
1639 break;
1640 s += 4;
1641 continue;
1642
1643 case 'w':
1644 if (strncmp (s, "%wim", 4) != 0)
1645 break;
1646 s += 4;
1647 continue;
1648
1649 case 'y':
1650 if (strncmp (s, "%y", 2) != 0)
1651 break;
1652 s += 2;
1653 continue;
1654
1655 default:
1656 as_fatal ("failed sanity check.");
1657 } /* switch on arg code */
1658 break;
1659 } /* for each arg that we expect */
1660 error:
1661 if (match == 0)
1662 {
1663 /* Args don't match. */
1664 if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
1665 && !strcmp (insn->name, insn[1].name))
1666 {
1667 ++insn;
1668 s = argsStart;
1669 continue;
1670 }
1671 else
1672 {
1673 as_bad ("Illegal operands%s", error_message);
1674 return;
1675 }
1676 }
1677 else
1678 {
1679 if (insn->architecture > current_architecture)
1680 {
1681 if ((!architecture_requested || warn_on_bump)
1682 &&
1683 /* start-sanitize-v9 */
680227f3 1684#ifndef NO_V9
355afbcd
KR
1685 !ARCHITECTURES_CONFLICT_P (current_architecture,
1686 insn->architecture)
680227f3 1687#else
355afbcd
KR
1688 /* end-sanitize-v9 */
1689 1
1690 /* start-sanitize-v9 */
680227f3 1691#endif
355afbcd
KR
1692 /* end-sanitize-v9 */
1693 )
1694 {
1695 if (warn_on_bump)
1696 {
1697 as_warn ("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1698 architecture_pname[current_architecture],
1699 architecture_pname[insn->architecture],
1700 str);
1701 } /* if warning */
fecd2382 1702
355afbcd
KR
1703 current_architecture = insn->architecture;
1704 }
1705 else
1706 {
1707 as_bad ("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
1708 str,
1709 architecture_pname[insn->architecture],
1710 architecture_pname[current_architecture]);
1711 return;
1712 } /* if bump ok else error */
1713 } /* if architecture higher */
1714 } /* if no match */
1715
1716 break;
1717 } /* forever looking for a match */
1718
1719 the_insn.opcode = opcode;
c999fd9f 1720}
355afbcd
KR
1721
1722static int
1723getExpression (str)
1724 char *str;
fecd2382 1725{
355afbcd
KR
1726 char *save_in;
1727 segT seg;
1728
1729 save_in = input_line_pointer;
1730 input_line_pointer = str;
428d312b 1731 seg = expression (&the_insn.exp);
58d4951d
ILT
1732 if (seg != absolute_section
1733 && seg != text_section
1734 && seg != data_section
1735 && seg != bss_section
1736 && seg != undefined_section)
355afbcd 1737 {
355afbcd
KR
1738 the_insn.error = "bad segment";
1739 expr_end = input_line_pointer;
1740 input_line_pointer = save_in;
1741 return 1;
1742 }
1743 expr_end = input_line_pointer;
1744 input_line_pointer = save_in;
1745 return 0;
1746} /* getExpression() */
fecd2382
RP
1747
1748
1749/*
1750 This is identical to the md_atof in m68k.c. I think this is right,
1751 but I'm not sure.
355afbcd 1752
fecd2382
RP
1753 Turn a string in input_line_pointer into a floating point constant of type
1754 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1755 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1756 */
1757
1758/* Equal to MAX_PRECISION in atof-ieee.c */
1759#define MAX_LITTLENUMS 6
1760
355afbcd
KR
1761char *
1762md_atof (type, litP, sizeP)
1763 char type;
1764 char *litP;
1765 int *sizeP;
fecd2382 1766{
355afbcd
KR
1767 int prec;
1768 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1769 LITTLENUM_TYPE *wordP;
1770 char *t;
1771 char *atof_ieee ();
1772
1773 switch (type)
1774 {
1775
1776 case 'f':
1777 case 'F':
1778 case 's':
1779 case 'S':
1780 prec = 2;
1781 break;
1782
1783 case 'd':
1784 case 'D':
1785 case 'r':
1786 case 'R':
1787 prec = 4;
1788 break;
1789
1790 case 'x':
1791 case 'X':
1792 prec = 6;
1793 break;
1794
1795 case 'p':
1796 case 'P':
1797 prec = 6;
1798 break;
1799
1800 default:
1801 *sizeP = 0;
1802 return "Bad call to MD_ATOF()";
1803 }
1804 t = atof_ieee (input_line_pointer, type, words);
1805 if (t)
1806 input_line_pointer = t;
1807 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1808 for (wordP = words; prec--;)
1809 {
125f0b0d 1810 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
355afbcd
KR
1811 litP += sizeof (LITTLENUM_TYPE);
1812 }
ed9638af
KR
1813 return 0;
1814}
fecd2382
RP
1815
1816/*
1817 * Write out big-endian.
1818 */
355afbcd
KR
1819void
1820md_number_to_chars (buf, val, n)
1821 char *buf;
125f0b0d 1822 valueT val;
355afbcd 1823 int n;
fecd2382 1824{
c999fd9f
KR
1825 number_to_chars_bigendian (buf, val, n);
1826}
fecd2382
RP
1827
1828/* Apply a fixS to the frags, now that we know the value it ought to
1829 hold. */
1830
428d312b 1831int
428d312b 1832md_apply_fix (fixP, value)
355afbcd 1833 fixS *fixP;
125f0b0d 1834 valueT *value;
fecd2382 1835{
355afbcd 1836 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
125f0b0d 1837 offsetT val;
428d312b 1838
428d312b 1839 val = *value;
355afbcd 1840
428d312b 1841 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
355afbcd
KR
1842
1843 fixP->fx_addnumber = val; /* Remember value for emit_reloc */
1844
7766838e
ILT
1845#ifdef OBJ_ELF
1846 /* FIXME: SPARC ELF relocations don't use an addend in the data
1847 field itself. This whole approach should be somehow combined
1848 with the calls to bfd_perform_relocation. */
1849 if (fixP->fx_addsy != NULL)
1850 return 1;
1851#endif
1852
c999fd9f
KR
1853 /* This is a hack. There should be a better way to
1854 handle this. Probably in terms of howto fields, once
1855 we can look at these fixups in terms of howtos. */
428d312b 1856 if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
c999fd9f 1857 val += fixP->fx_where + fixP->fx_frag->fr_address;
355afbcd
KR
1858
1859 switch (fixP->fx_r_type)
1860 {
58d4951d
ILT
1861 case BFD_RELOC_16:
1862 buf[0] = val >> 8;
1863 buf[1] = val;
1864 break;
1865
428d312b 1866 case BFD_RELOC_32:
92421122
KR
1867 buf[0] = val >> 24;
1868 buf[1] = val >> 16;
1869 buf[2] = val >> 8;
1870 buf[3] = val;
355afbcd
KR
1871 break;
1872
428d312b 1873 case BFD_RELOC_32_PCREL_S2:
355afbcd
KR
1874 val = (val >>= 2) + 1;
1875 buf[0] |= (val >> 24) & 0x3f;
1876 buf[1] = (val >> 16);
1877 buf[2] = val >> 8;
1878 buf[3] = val;
1879 break;
1880
1881 /* start-sanitize-v9 */
839df5c3 1882#ifndef NO_V9
693b21e7 1883 case BFD_RELOC_64:
92421122
KR
1884 buf[0] = val >> 56;
1885 buf[1] = val >> 48;
1886 buf[2] = val >> 40;
1887 buf[3] = val >> 32;
1888 buf[4] = val >> 24;
1889 buf[5] = val >> 16;
1890 buf[6] = val >> 8;
1891 buf[7] = val;
693b21e7
KR
1892 break;
1893
125f0b0d 1894 case BFD_RELOC_SPARC_11:
355afbcd
KR
1895 if (((val > 0) && (val & ~0x7ff))
1896 || ((val < 0) && (~(val - 1) & ~0x7ff)))
1897 {
1898 as_bad ("relocation overflow.");
1899 } /* on overflow */
1900
1901 buf[2] |= (val >> 8) & 0x7;
1902 buf[3] = val & 0xff;
1903 break;
1904
125f0b0d 1905 case BFD_RELOC_SPARC_10:
355afbcd
KR
1906 if (((val > 0) && (val & ~0x3ff))
1907 || ((val < 0) && (~(val - 1) & ~0x3ff)))
1908 {
1909 as_bad ("relocation overflow.");
1910 } /* on overflow */
1911
1912 buf[2] |= (val >> 8) & 0x3;
1913 buf[3] = val & 0xff;
1914 break;
1915
125f0b0d 1916 case BFD_RELOC_SPARC_WDISP16:
355afbcd
KR
1917 if (((val > 0) && (val & ~0x3fffc))
1918 || ((val < 0) && (~(val - 1) & ~0x3fffc)))
1919 {
1920 as_bad ("relocation overflow.");
1921 } /* on overflow */
1922
1923 val = (val >>= 2) + 1;
8fc0776d 1924 buf[1] |= ((val >> 14) & 0x3) << 4;
355afbcd
KR
1925 buf[2] |= (val >> 8) & 0x3f;
1926 buf[3] = val & 0xff;
1927 break;
1928
125f0b0d 1929 case BFD_RELOC_SPARC_WDISP19:
355afbcd
KR
1930 if (((val > 0) && (val & ~0x1ffffc))
1931 || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
1932 {
1933 as_bad ("relocation overflow.");
1934 } /* on overflow */
1935
1936 val = (val >>= 2) + 1;
1937 buf[1] |= (val >> 16) & 0x7;
1938 buf[2] = (val >> 8) & 0xff;
1939 buf[3] = val & 0xff;
1940 break;
1941
125f0b0d 1942 case BFD_RELOC_SPARC_HH22:
355afbcd
KR
1943 val >>= 32;
1944 /* intentional fallthrough */
839df5c3 1945#endif /* NO_V9 */
355afbcd
KR
1946 /* end-sanitize-v9 */
1947
125f0b0d
KR
1948 /* start-sanitize-v9 */
1949#ifndef NO_V9
1950 case BFD_RELOC_SPARC_LM22:
1951#endif
1952 /* end-sanitize-v9 */
428d312b 1953 case BFD_RELOC_HI22:
355afbcd
KR
1954 if (!fixP->fx_addsy)
1955 {
1956 buf[1] |= (val >> 26) & 0x3f;
1957 buf[2] = val >> 18;
1958 buf[3] = val >> 10;
1959 }
1960 else
1961 {
1962 buf[2] = 0;
1963 buf[3] = 0;
1964 }
1965 break;
1966
428d312b 1967 case BFD_RELOC_SPARC22:
355afbcd
KR
1968 if (val & ~0x003fffff)
1969 {
1970 as_bad ("relocation overflow");
1971 } /* on overflow */
1972 buf[1] |= (val >> 16) & 0x3f;
1973 buf[2] = val >> 8;
1974 buf[3] = val & 0xff;
1975 break;
1976
428d312b 1977 case BFD_RELOC_SPARC13:
355afbcd
KR
1978 if (val & ~0x00001fff)
1979 {
1980 as_bad ("relocation overflow");
1981 } /* on overflow */
1982 buf[2] |= (val >> 8) & 0x1f;
1983 buf[3] = val & 0xff;
1984 break;
1985
1986 /* start-sanitize-v9 */
9b856b4f 1987#ifndef NO_V9
125f0b0d 1988 case BFD_RELOC_SPARC_HM10:
355afbcd
KR
1989 val >>= 32;
1990 /* intentional fallthrough */
9b856b4f 1991#endif /* NO_V9 */
355afbcd
KR
1992 /* end-sanitize-v9 */
1993
428d312b 1994 case BFD_RELOC_LO10:
355afbcd
KR
1995 if (!fixP->fx_addsy)
1996 {
1997 buf[2] |= (val >> 8) & 0x03;
1998 buf[3] = val;
1999 }
2000 else
2001 buf[3] = 0;
2002 break;
428d312b 2003 case BFD_RELOC_SPARC_BASE13:
125f0b0d
KR
2004 if (((val > 0) && (val & ~(offsetT)0x00001fff))
2005 || ((val < 0) && (~(val - 1) & ~(offsetT)0x00001fff)))
355afbcd
KR
2006 {
2007 as_bad ("relocation overflow");
125f0b0d 2008 }
355afbcd
KR
2009 buf[2] |= (val >> 8) & 0x1f;
2010 buf[3] = val;
2011 break;
2012
428d312b 2013 case BFD_RELOC_SPARC_WDISP22:
355afbcd
KR
2014 val = (val >>= 2) + 1;
2015 /* FALLTHROUGH */
428d312b 2016 case BFD_RELOC_SPARC_BASE22:
355afbcd
KR
2017 buf[1] |= (val >> 16) & 0x3f;
2018 buf[2] = val >> 8;
2019 buf[3] = val;
2020 break;
2021
428d312b 2022 case BFD_RELOC_NONE:
355afbcd 2023 default:
428d312b 2024 as_bad ("bad or unhandled relocation type: 0x%02x", fixP->fx_r_type);
355afbcd
KR
2025 break;
2026 }
428d312b 2027
428d312b 2028 return 1;
428d312b 2029}
fecd2382 2030
428d312b
KR
2031/* Translate internal representation of relocation info to BFD target
2032 format. */
2033arelent *
2034tc_gen_reloc (section, fixp)
2035 asection *section;
2036 fixS *fixp;
2037{
2038 arelent *reloc;
2039 bfd_reloc_code_real_type code;
2040
2041 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
2042 assert (reloc != 0);
2043
2044 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2045 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
428d312b 2046
428d312b
KR
2047 switch (fixp->fx_r_type)
2048 {
58d4951d 2049 case BFD_RELOC_16:
428d312b
KR
2050 case BFD_RELOC_32:
2051 case BFD_RELOC_HI22:
2052 case BFD_RELOC_LO10:
2053 case BFD_RELOC_32_PCREL_S2:
2054 case BFD_RELOC_SPARC_BASE13:
ed9638af 2055 case BFD_RELOC_SPARC_WDISP22:
125f0b0d 2056 /* start-sanitize-v9 */
693b21e7 2057 case BFD_RELOC_64:
125f0b0d
KR
2058 case BFD_RELOC_SPARC_10:
2059 case BFD_RELOC_SPARC_11:
2060 case BFD_RELOC_SPARC_HH22:
2061 case BFD_RELOC_SPARC_HM10:
2062 case BFD_RELOC_SPARC_LM22:
2063 case BFD_RELOC_SPARC_PC_HH22:
2064 case BFD_RELOC_SPARC_PC_HM10:
2065 case BFD_RELOC_SPARC_PC_LM22:
2066 /* end-sanitize-v9 */
428d312b
KR
2067 code = fixp->fx_r_type;
2068 break;
2069 default:
2070 abort ();
2071 }
2072 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2073 assert (reloc->howto != 0);
c999fd9f
KR
2074 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
2075
2076 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
2077 if (reloc->howto->pc_relative == 0)
2078 reloc->addend = fixp->fx_addnumber;
2079 else if (reloc->howto->pcrel_offset)
2080 reloc->addend = fixp->fx_offset - reloc->address;
2081 else
2082 reloc->addend = fixp->fx_offset;
428d312b
KR
2083
2084 return reloc;
2085}
2086
fecd2382
RP
2087
2088#if 0
2089/* for debugging only */
355afbcd
KR
2090static void
2091print_insn (insn)
2092 struct sparc_it *insn;
fecd2382 2093{
c999fd9f 2094 const char *const Reloc[] = {
355afbcd
KR
2095 "RELOC_8",
2096 "RELOC_16",
2097 "RELOC_32",
2098 "RELOC_DISP8",
2099 "RELOC_DISP16",
2100 "RELOC_DISP32",
2101 "RELOC_WDISP30",
2102 "RELOC_WDISP22",
2103 "RELOC_HI22",
2104 "RELOC_22",
2105 "RELOC_13",
2106 "RELOC_LO10",
2107 "RELOC_SFA_BASE",
2108 "RELOC_SFA_OFF13",
2109 "RELOC_BASE10",
2110 "RELOC_BASE13",
2111 "RELOC_BASE22",
2112 "RELOC_PC10",
2113 "RELOC_PC22",
2114 "RELOC_JMP_TBL",
2115 "RELOC_SEGOFF16",
2116 "RELOC_GLOB_DAT",
2117 "RELOC_JMP_SLOT",
2118 "RELOC_RELATIVE",
2119 "NO_RELOC"
2120 };
2121
2122 if (insn->error)
c999fd9f 2123 fprintf (stderr, "ERROR: %s\n");
355afbcd
KR
2124 fprintf (stderr, "opcode=0x%08x\n", insn->opcode);
2125 fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
2126 fprintf (stderr, "exp = {\n");
2127 fprintf (stderr, "\t\tX_add_symbol = %s\n",
2128 ((insn->exp.X_add_symbol != NULL)
2129 ? ((S_GET_NAME (insn->exp.X_add_symbol) != NULL)
2130 ? S_GET_NAME (insn->exp.X_add_symbol)
2131 : "???")
2132 : "0"));
2133 fprintf (stderr, "\t\tX_sub_symbol = %s\n",
5ac34ac3
ILT
2134 ((insn->exp.X_op_symbol != NULL)
2135 ? (S_GET_NAME (insn->exp.X_op_symbol)
2136 ? S_GET_NAME (insn->exp.X_op_symbol)
355afbcd
KR
2137 : "???")
2138 : "0"));
2139 fprintf (stderr, "\t\tX_add_number = %d\n",
2140 insn->exp.X_add_number);
2141 fprintf (stderr, "}\n");
c999fd9f 2142}
fecd2382
RP
2143#endif
2144
839df5c3
RP
2145/*
2146 * md_parse_option
2147 * Invocation line includes a switch not recognized by the base assembler.
2148 * See if it's a processor-specific option. These are:
2149 *
2150 * -bump
2151 * Warn on architecture bumps. See also -A.
2152 *
680227f3 2153 * -Av6, -Av7, -Av8, -Asparclite
839df5c3
RP
2154 * Select the architecture. Instructions or features not
2155 * supported by the selected architecture cause fatal errors.
2156 *
2157 * The default is to start at v6, and bump the architecture up
2158 * whenever an instruction is seen at a higher level.
2159 *
2160 * If -bump is specified, a warning is printing when bumping to
2161 * higher levels.
2162 *
2163 * If an architecture is specified, all instructions must match
2164 * that architecture. Any higher level instructions are flagged
355afbcd 2165 * as errors.
839df5c3
RP
2166 *
2167 * if both an architecture and -bump are specified, the
2168 * architecture starts at the specified level, but bumps are
2169 * warnings.
2170 *
680227f3 2171 * start-sanitize-v9
162e3485
KR
2172 * -Av9
2173 * Another architecture switch.
2174 *
2175 * Note:
680227f3
KR
2176 * Bumping between incompatible architectures is always an
2177 * error. For example, from sparclite to v9.
2178 * end-sanitize-v9
839df5c3 2179 */
162e3485 2180
355afbcd
KR
2181int
2182md_parse_option (argP, cntP, vecP)
2183 char **argP;
2184 int *cntP;
2185 char ***vecP;
fecd2382 2186{
355afbcd
KR
2187 char *p;
2188 const char **arch;
2189
2190 if (!strcmp (*argP, "bump"))
2191 {
2192 warn_on_bump = 1;
2193
2194 }
2195 else if (**argP == 'A')
2196 {
2197 p = (*argP) + 1;
2198
2199 for (arch = architecture_pname; *arch != NULL; ++arch)
2200 {
2201 if (strcmp (p, *arch) == 0)
2202 {
2203 break;
2204 } /* found a match */
2205 } /* walk the pname table */
2206
2207 if (*arch == NULL)
2208 {
2209 as_bad ("unknown architecture: %s", p);
2210 }
2211 else
2212 {
2213 current_architecture = (enum sparc_architecture) (arch - architecture_pname);
2214 architecture_requested = 1;
839df5c3 2215 }
355afbcd 2216 }
ed9638af
KR
2217#ifdef OBJ_ELF
2218 else if (**argP == 'V')
2219 {
ed9638af
KR
2220 print_version_id ();
2221 }
2222 else if (**argP == 'Q')
2223 {
2224 /* Qy - do emit .comment
2225 Qn - do not emit .comment */
2226 }
2227 else if (**argP == 's')
2228 {
2229 /* use .stab instead of .stab.excl */
2230 }
2231#endif
7766838e
ILT
2232 else if (strcmp (*argP, "sparc") == 0)
2233 {
2234 /* Ignore -sparc, used by SunOS make default .s.o rule. */
2235 }
355afbcd
KR
2236 else
2237 {
2238 /* Unknown option */
2239 (*argP)++;
2240 return 0;
2241 }
2242 **argP = '\0'; /* Done parsing this switch */
2243 return 1;
2244} /* md_parse_option() */
fecd2382
RP
2245
2246/* We have no need to default values of symbols. */
2247
2248/* ARGSUSED */
355afbcd
KR
2249symbolS *
2250md_undefined_symbol (name)
2251 char *name;
fecd2382 2252{
355afbcd
KR
2253 return 0;
2254} /* md_undefined_symbol() */
fecd2382
RP
2255
2256/* Parse an operand that is machine-specific.
2257 We just return without modifying the expression if we have nothing
2258 to do. */
2259
2260/* ARGSUSED */
355afbcd
KR
2261void
2262md_operand (expressionP)
2263 expressionS *expressionP;
fecd2382 2264{
428d312b 2265}
fecd2382
RP
2266
2267/* Round up a section size to the appropriate boundary. */
125f0b0d 2268valueT
355afbcd
KR
2269md_section_align (segment, size)
2270 segT segment;
125f0b0d 2271 valueT size;
fecd2382 2272{
693b21e7 2273#ifdef OBJ_AOUT
428d312b 2274 /* Round all sects to multiple of 8 */
7766838e 2275 size = (size + 7) & (valueT) ~7;
693b21e7
KR
2276#endif
2277 return size;
428d312b 2278}
fecd2382
RP
2279
2280/* Exactly what point is a PC-relative offset relative TO?
2281 On the sparc, they're relative to the address of the offset, plus
2282 its size. This gets us to the following instruction.
2283 (??? Is this right? FIXME-SOON) */
355afbcd
KR
2284long
2285md_pcrel_from (fixP)
2286 fixS *fixP;
fecd2382 2287{
355afbcd 2288 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
428d312b 2289}
fecd2382 2290
8b228fe9 2291/* end of tc-sparc.c */
This page took 0.223555 seconds and 4 git commands to generate.