ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
b90efa5b 2 Copyright (C) 1994-2015 Free Software Foundation, Inc.
252b5132
RH
3 Contributed by Doug Evans (dje@cygnus.com).
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
19203624 18 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
252b5132 21
252b5132 22#include "as.h"
a161fe53 23#include "struc-symbol.h"
3882b010 24#include "safe-ctype.h"
252b5132
RH
25#include "subsegs.h"
26#include "opcode/arc.h"
0d2bcfaf 27#include "../opcodes/arc-ext.h"
252b5132 28#include "elf/arc.h"
bcee8eb8 29#include "dwarf2dbg.h"
252b5132 30
ea1562b3
NC
31const struct suffix_classes
32{
0d2bcfaf
NC
33 char *name;
34 int len;
ea1562b3
NC
35} suffixclass[] =
36{
0d2bcfaf
NC
37 { "SUFFIX_COND|SUFFIX_FLAG",23 },
38 { "SUFFIX_FLAG", 11 },
39 { "SUFFIX_COND", 11 },
40 { "SUFFIX_NONE", 11 }
41};
42
bfb32b52 43#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
0d2bcfaf 44
ea1562b3
NC
45const struct syntax_classes
46{
0d2bcfaf
NC
47 char *name;
48 int len;
96d56e9f 49 int s_class;
ea1562b3
NC
50} syntaxclass[] =
51{
0d2bcfaf
NC
52 { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
53 { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
54 { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
55 { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
56 { "SYNTAX_3OP", 10, SYNTAX_3OP|SYNTAX_VALID },
57 { "SYNTAX_2OP", 10, SYNTAX_2OP|SYNTAX_VALID }
58};
59
bfb32b52 60#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
0d2bcfaf 61
252b5132 62/* This array holds the chars that always start a comment. If the
bcee8eb8 63 pre-processor is disabled, these aren't very useful. */
252b5132
RH
64const char comment_chars[] = "#;";
65
66/* This array holds the chars that only start a comment at the beginning of
67 a line. If the line seems to have the form '# 123 filename'
68 .line and .file directives will appear in the pre-processed output */
69/* Note that input_file.c hand checks for '#' at the beginning of the
70 first line of the input file. This is because the compiler outputs
bfb32b52 71 #NO_APP at the beginning of its output. */
252b5132 72/* Also note that comments started like this one will always
bfb32b52 73 work if '/' isn't otherwise defined. */
252b5132
RH
74const char line_comment_chars[] = "#";
75
76const char line_separator_chars[] = "";
77
bcee8eb8 78/* Chars that can be used to separate mant from exp in floating point nums. */
252b5132
RH
79const char EXP_CHARS[] = "eE";
80
bcee8eb8
AM
81/* Chars that mean this number is a floating point constant
82 As in 0f12.456 or 0d1.2345e12. */
252b5132
RH
83const char FLT_CHARS[] = "rRsSfFdD";
84
85/* Byte order. */
86extern int target_big_endian;
87const char *arc_target_format = DEFAULT_TARGET_FORMAT;
88static int byte_order = DEFAULT_BYTE_ORDER;
89
0d2bcfaf
NC
90static segT arcext_section;
91
92/* One of bfd_mach_arc_n. */
bcee8eb8 93static int arc_mach_type = bfd_mach_arc_6;
252b5132
RH
94
95/* Non-zero if the cpu type has been explicitly specified. */
96static int mach_type_specified_p = 0;
97
98/* Non-zero if opcode tables have been initialized.
bcee8eb8 99 A .option command must appear before any instructions. */
252b5132
RH
100static int cpu_tables_init_p = 0;
101
102static struct hash_control *arc_suffix_hash = NULL;
103\f
104const char *md_shortopts = "";
ea1562b3
NC
105
106enum options
107{
108 OPTION_EB = OPTION_MD_BASE,
109 OPTION_EL,
110 OPTION_ARC5,
111 OPTION_ARC6,
112 OPTION_ARC7,
113 OPTION_ARC8,
114 OPTION_ARC
115};
116
117struct option md_longopts[] =
118{
bcee8eb8 119 { "EB", no_argument, NULL, OPTION_EB },
bcee8eb8 120 { "EL", no_argument, NULL, OPTION_EL },
bcee8eb8
AM
121 { "marc5", no_argument, NULL, OPTION_ARC5 },
122 { "pre-v6", no_argument, NULL, OPTION_ARC5 },
bcee8eb8 123 { "marc6", no_argument, NULL, OPTION_ARC6 },
bcee8eb8 124 { "marc7", no_argument, NULL, OPTION_ARC7 },
bcee8eb8 125 { "marc8", no_argument, NULL, OPTION_ARC8 },
bcee8eb8 126 { "marc", no_argument, NULL, OPTION_ARC },
252b5132
RH
127 { NULL, no_argument, NULL, 0 }
128};
129size_t md_longopts_size = sizeof (md_longopts);
130
0d2bcfaf
NC
131#define IS_SYMBOL_OPERAND(o) \
132 ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
133
19203624 134struct arc_operand_value *get_ext_suffix (char *s);
0d2bcfaf 135
19203624
KH
136/* Invocation line includes a switch not recognized by the base assembler.
137 See if it's a processor-specific option. */
252b5132
RH
138
139int
ea1562b3 140md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
252b5132
RH
141{
142 switch (c)
1e07b820 143 {
0d2bcfaf
NC
144 case OPTION_ARC5:
145 arc_mach_type = bfd_mach_arc_5;
146 break;
bcee8eb8 147 case OPTION_ARC:
0d2bcfaf
NC
148 case OPTION_ARC6:
149 arc_mach_type = bfd_mach_arc_6;
150 break;
151 case OPTION_ARC7:
152 arc_mach_type = bfd_mach_arc_7;
153 break;
154 case OPTION_ARC8:
155 arc_mach_type = bfd_mach_arc_8;
156 break;
252b5132
RH
157 case OPTION_EB:
158 byte_order = BIG_ENDIAN;
159 arc_target_format = "elf32-bigarc";
160 break;
161 case OPTION_EL:
162 byte_order = LITTLE_ENDIAN;
163 arc_target_format = "elf32-littlearc";
164 break;
165 default:
166 return 0;
1e07b820 167 }
252b5132
RH
168 return 1;
169}
170
171void
ea1562b3 172md_show_usage (FILE *stream)
252b5132 173{
0d2bcfaf
NC
174 fprintf (stream, "\
175ARC Options:\n\
176 -marc[5|6|7|8] select processor variant (default arc%d)\n\
177 -EB assemble code for a big endian cpu\n\
178 -EL assemble code for a little endian cpu\n", arc_mach_type + 5);
252b5132
RH
179}
180
181/* This function is called once, at assembler startup time. It should
182 set up all the tables, etc. that the MD part of the assembler will need.
bcee8eb8 183 Opcode selection is deferred until later because we might see a .option
252b5132
RH
184 command. */
185
186void
ea1562b3 187md_begin (void)
252b5132
RH
188{
189 /* The endianness can be chosen "at the factory". */
190 target_big_endian = byte_order == BIG_ENDIAN;
191
192 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
bd3ba5d1 193 as_warn (_("could not set architecture and machine"));
252b5132 194
bcee8eb8
AM
195 /* This call is necessary because we need to initialize `arc_operand_map'
196 which may be needed before we see the first insn. */
0d2bcfaf 197 arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
252b5132
RH
198 target_big_endian));
199}
200
201/* Initialize the various opcode and operand tables.
202 MACH is one of bfd_mach_arc_xxx. */
ea1562b3 203
252b5132 204static void
ea1562b3 205init_opcode_tables (int mach)
252b5132 206{
4a314ec8 207 int i;
252b5132
RH
208 char *last;
209
210 if ((arc_suffix_hash = hash_new ()) == NULL)
bd3ba5d1 211 as_fatal (_("virtual memory exhausted"));
252b5132
RH
212
213 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
bd3ba5d1 214 as_warn (_("could not set architecture and machine"));
252b5132
RH
215
216 /* This initializes a few things in arc-opc.c that we need.
217 This must be called before the various arc_xxx_supported fns. */
218 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
219
220 /* Only put the first entry of each equivalently named suffix in the
221 table. */
222 last = "";
223 for (i = 0; i < arc_suffixes_count; i++)
224 {
252b5132 225 if (strcmp (arc_suffixes[i].name, last) != 0)
ea1562b3 226 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (void *) (arc_suffixes + i));
252b5132
RH
227 last = arc_suffixes[i].name;
228 }
229
230 /* Since registers don't have a prefix, we put them in the symbol table so
231 they can't be used as symbols. This also simplifies argument parsing as
232 we can let gas parse registers for us. The recorded register number is
0d2bcfaf
NC
233 the address of the register's entry in arc_reg_names.
234
235 If the register name is already in the table, then the existing
236 definition is assumed to be from an .ExtCoreRegister pseudo-op. */
237
252b5132
RH
238 for (i = 0; i < arc_reg_names_count; i++)
239 {
19203624 240 if (symbol_find (arc_reg_names[i].name))
252b5132
RH
241 continue;
242 /* Use symbol_create here instead of symbol_new so we don't try to
243 output registers into the object file's symbol table. */
bcee8eb8
AM
244 symbol_table_insert (symbol_create (arc_reg_names[i].name,
245 reg_section,
52de4c06 246 (valueT) &arc_reg_names[i],
bcee8eb8 247 &zero_address_frag));
252b5132
RH
248 }
249
0d2bcfaf 250 /* Tell `.option' it's too late. */
252b5132
RH
251 cpu_tables_init_p = 1;
252}
253\f
254/* Insert an operand value into an instruction.
255 If REG is non-NULL, it is a register number and ignore VAL. */
256
257static arc_insn
ea1562b3
NC
258arc_insert_operand (arc_insn insn,
259 const struct arc_operand *operand,
260 int mods,
261 const struct arc_operand_value *reg,
262 offsetT val,
263 char *file,
264 unsigned int line)
252b5132
RH
265{
266 if (operand->bits != 32)
267 {
268 long min, max;
269 offsetT test;
270
271 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
272 {
273 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
274 max = (1 << operand->bits) - 1;
275 else
276 max = (1 << (operand->bits - 1)) - 1;
277 min = - (1 << (operand->bits - 1));
278 }
279 else
280 {
281 max = (1 << operand->bits) - 1;
282 min = 0;
283 }
284
285 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
286 test = - val;
287 else
288 test = val;
289
290 if (test < (offsetT) min || test > (offsetT) max)
e5976317 291 as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
252b5132
RH
292 }
293
294 if (operand->insert)
295 {
296 const char *errmsg;
297
298 errmsg = NULL;
299 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
300 if (errmsg != (const char *) NULL)
20203fb9 301 as_warn ("%s", errmsg);
252b5132
RH
302 }
303 else
304 insn |= (((long) val & ((1 << operand->bits) - 1))
305 << operand->shift);
306
307 return insn;
308}
309
310/* We need to keep a list of fixups. We can't simply generate them as
311 we go, because that would require us to first create the frag, and
312 that would screw up references to ``.''. */
313
ea1562b3
NC
314struct arc_fixup
315{
bcee8eb8 316 /* index into `arc_operands' */
252b5132
RH
317 int opindex;
318 expressionS exp;
319};
320
321#define MAX_FIXUPS 5
322
323#define MAX_SUFFIXES 5
324
ea1562b3
NC
325/* Compute the reloc type of an expression.
326 The possibly modified expression is stored in EXPNEW.
252b5132 327
ea1562b3
NC
328 This is used to convert the expressions generated by the %-op's into
329 the appropriate operand type. It is called for both data in instructions
330 (operands) and data outside instructions (variables, debugging info, etc.).
331
332 Currently supported %-ops:
333
334 %st(symbol): represented as "symbol >> 2"
335 "st" is short for STatus as in the status register (pc)
336
337 DEFAULT_TYPE is the type to use if no special processing is required.
338
339 DATA_P is non-zero for data or limm values, zero for insn operands.
340 Remember that the opcode "insertion fns" cannot be used on data, they're
341 only for inserting operands into insns. They also can't be used for limm
342 values as the insertion routines don't handle limm values. When called for
343 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
344 called for data or limm values we use real reloc types. */
345
346static int
347get_arc_exp_reloc_type (int data_p,
348 int default_type,
349 expressionS *exp,
350 expressionS *expnew)
252b5132 351{
ea1562b3
NC
352 /* If the expression is "symbol >> 2" we must change it to just "symbol",
353 as fix_new_exp can't handle it. Similarly for (symbol - symbol) >> 2.
354 That's ok though. What's really going on here is that we're using
355 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
252b5132 356
ea1562b3
NC
357 if (exp->X_op == O_right_shift
358 && exp->X_op_symbol != NULL
359 && exp->X_op_symbol->sy_value.X_op == O_constant
360 && exp->X_op_symbol->sy_value.X_add_number == 2
361 && exp->X_add_number == 0)
252b5132 362 {
ea1562b3
NC
363 if (exp->X_add_symbol != NULL
364 && (exp->X_add_symbol->sy_value.X_op == O_constant
365 || exp->X_add_symbol->sy_value.X_op == O_symbol))
366 {
367 *expnew = *exp;
368 expnew->X_op = O_symbol;
369 expnew->X_op_symbol = NULL;
370 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
371 }
372 else if (exp->X_add_symbol != NULL
373 && exp->X_add_symbol->sy_value.X_op == O_subtract)
374 {
375 *expnew = exp->X_add_symbol->sy_value;
376 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
377 }
252b5132
RH
378 }
379
ea1562b3
NC
380 *expnew = *exp;
381 return default_type;
382}
383\f
384static int
385arc_set_ext_seg (void)
386{
387 if (!arcext_section)
388 {
389 arcext_section = subseg_new (".arcextmap", 0);
390 bfd_set_section_flags (stdoutput, arcext_section,
391 SEC_READONLY | SEC_HAS_CONTENTS);
392 }
393 else
394 subseg_set (arcext_section, 0);
395 return 1;
396}
252b5132 397
ea1562b3
NC
398static void
399arc_extoper (int opertype)
400{
401 char *name;
402 char *mode;
403 char c;
404 char *p;
405 int imode = 0;
406 int number;
407 struct arc_ext_operand_value *ext_oper;
408 symbolS *symbolP;
252b5132 409
ea1562b3
NC
410 segT old_sec;
411 int old_subsec;
252b5132 412
ea1562b3
NC
413 name = input_line_pointer;
414 c = get_symbol_end ();
415 name = xstrdup (name);
252b5132 416
ea1562b3
NC
417 p = name;
418 while (*p)
252b5132 419 {
ea1562b3
NC
420 *p = TOLOWER (*p);
421 p++;
422 }
252b5132 423
ea1562b3
NC
424 /* just after name is now '\0' */
425 p = input_line_pointer;
426 *p = c;
427 SKIP_WHITESPACE ();
252b5132 428
ea1562b3
NC
429 if (*input_line_pointer != ',')
430 {
bd3ba5d1 431 as_bad (_("expected comma after operand name"));
ea1562b3
NC
432 ignore_rest_of_line ();
433 free (name);
434 return;
435 }
252b5132 436
ea1562b3
NC
437 input_line_pointer++; /* skip ',' */
438 number = get_absolute_expression ();
252b5132 439
ea1562b3
NC
440 if (number < 0)
441 {
bd3ba5d1 442 as_bad (_("negative operand number %d"), number);
ea1562b3
NC
443 ignore_rest_of_line ();
444 free (name);
445 return;
446 }
447
448 if (opertype)
449 {
450 SKIP_WHITESPACE ();
451
452 if (*input_line_pointer != ',')
252b5132 453 {
bd3ba5d1 454 as_bad (_("expected comma after register-number"));
ea1562b3
NC
455 ignore_rest_of_line ();
456 free (name);
457 return;
458 }
252b5132 459
ea1562b3
NC
460 input_line_pointer++; /* skip ',' */
461 mode = input_line_pointer;
462
463 if (!strncmp (mode, "r|w", 3))
464 {
465 imode = 0;
466 input_line_pointer += 3;
467 }
468 else
469 {
470 if (!strncmp (mode, "r", 1))
252b5132 471 {
ea1562b3
NC
472 imode = ARC_REGISTER_READONLY;
473 input_line_pointer += 1;
474 }
475 else
476 {
477 if (strncmp (mode, "w", 1))
252b5132 478 {
bd3ba5d1 479 as_bad (_("invalid mode"));
ea1562b3
NC
480 ignore_rest_of_line ();
481 free (name);
482 return;
252b5132
RH
483 }
484 else
ea1562b3
NC
485 {
486 imode = ARC_REGISTER_WRITEONLY;
487 input_line_pointer += 1;
488 }
252b5132 489 }
ea1562b3
NC
490 }
491 SKIP_WHITESPACE ();
492 if (1 == opertype)
493 {
494 if (*input_line_pointer != ',')
252b5132 495 {
bd3ba5d1 496 as_bad (_("expected comma after register-mode"));
ea1562b3
NC
497 ignore_rest_of_line ();
498 free (name);
499 return;
252b5132 500 }
252b5132 501
ea1562b3
NC
502 input_line_pointer++; /* skip ',' */
503
504 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
252b5132 505 {
ea1562b3
NC
506 imode |= arc_get_noshortcut_flag ();
507 input_line_pointer += 15;
252b5132 508 }
ea1562b3 509 else
252b5132 510 {
ea1562b3 511 if (strncmp (input_line_pointer, "can_shortcut", 12))
252b5132 512 {
bd3ba5d1 513 as_bad (_("shortcut designator invalid"));
ea1562b3
NC
514 ignore_rest_of_line ();
515 free (name);
516 return;
252b5132
RH
517 }
518 else
519 {
ea1562b3 520 input_line_pointer += 12;
252b5132 521 }
ea1562b3
NC
522 }
523 }
524 }
252b5132 525
ea1562b3
NC
526 if ((opertype == 1) && number > 60)
527 {
bd3ba5d1 528 as_bad (_("core register value (%d) too large"), number);
ea1562b3
NC
529 ignore_rest_of_line ();
530 free (name);
531 return;
532 }
252b5132 533
ea1562b3
NC
534 if ((opertype == 0) && number > 31)
535 {
bd3ba5d1 536 as_bad (_("condition code value (%d) too large"), number);
ea1562b3
NC
537 ignore_rest_of_line ();
538 free (name);
539 return;
540 }
1e07b820 541
21d799b5
NC
542 ext_oper = (struct arc_ext_operand_value *)
543 xmalloc (sizeof (struct arc_ext_operand_value));
ea1562b3
NC
544
545 if (opertype)
546 {
547 /* If the symbol already exists, point it at the new definition. */
548 if ((symbolP = symbol_find (name)))
549 {
550 if (S_GET_SEGMENT (symbolP) == reg_section)
52de4c06 551 S_SET_VALUE (symbolP, (valueT) &ext_oper->operand);
252b5132 552 else
252b5132 553 {
bd3ba5d1 554 as_bad (_("attempt to override symbol: %s"), name);
ea1562b3
NC
555 ignore_rest_of_line ();
556 free (name);
557 free (ext_oper);
558 return;
559 }
560 }
561 else
562 {
563 /* If its not there, add it. */
564 symbol_table_insert (symbol_create (name, reg_section,
52de4c06
NC
565 (valueT) &ext_oper->operand,
566 &zero_address_frag));
ea1562b3
NC
567 }
568 }
252b5132 569
ea1562b3
NC
570 ext_oper->operand.name = name;
571 ext_oper->operand.value = number;
572 ext_oper->operand.type = arc_operand_type (opertype);
573 ext_oper->operand.flags = imode;
252b5132 574
ea1562b3
NC
575 ext_oper->next = arc_ext_operands;
576 arc_ext_operands = ext_oper;
252b5132 577
ea1562b3
NC
578 /* OK, now that we know what this operand is, put a description in
579 the arc extension section of the output file. */
252b5132 580
ea1562b3
NC
581 old_sec = now_seg;
582 old_subsec = now_subseg;
252b5132 583
ea1562b3 584 arc_set_ext_seg ();
252b5132 585
ea1562b3
NC
586 switch (opertype)
587 {
588 case 0:
589 p = frag_more (1);
590 *p = 3 + strlen (name) + 1;
591 p = frag_more (1);
592 *p = EXT_COND_CODE;
593 p = frag_more (1);
594 *p = number;
595 p = frag_more (strlen (name) + 1);
596 strcpy (p, name);
597 break;
598 case 1:
599 p = frag_more (1);
600 *p = 3 + strlen (name) + 1;
601 p = frag_more (1);
602 *p = EXT_CORE_REGISTER;
603 p = frag_more (1);
604 *p = number;
605 p = frag_more (strlen (name) + 1);
606 strcpy (p, name);
607 break;
608 case 2:
609 p = frag_more (1);
610 *p = 6 + strlen (name) + 1;
611 p = frag_more (1);
612 *p = EXT_AUX_REGISTER;
613 p = frag_more (1);
614 *p = number >> 24 & 0xff;
615 p = frag_more (1);
616 *p = number >> 16 & 0xff;
617 p = frag_more (1);
618 *p = number >> 8 & 0xff;
619 p = frag_more (1);
620 *p = number & 0xff;
621 p = frag_more (strlen (name) + 1);
622 strcpy (p, name);
623 break;
624 default:
bd3ba5d1 625 as_bad (_("invalid opertype"));
ea1562b3
NC
626 ignore_rest_of_line ();
627 free (name);
628 return;
629 break;
630 }
252b5132 631
ea1562b3 632 subseg_set (old_sec, old_subsec);
252b5132 633
ea1562b3 634 /* Enter all registers into the symbol table. */
252b5132 635
ea1562b3 636 demand_empty_rest_of_line ();
252b5132 637}
ea1562b3 638
252b5132 639static void
ea1562b3 640arc_extinst (int ignore ATTRIBUTE_UNUSED)
252b5132 641{
ea1562b3 642 char syntax[129];
252b5132 643 char *name;
252b5132 644 char *p;
ea1562b3
NC
645 char c;
646 int suffixcode = -1;
647 int opcode, subopcode;
648 int i;
96d56e9f 649 int s_class = 0;
ea1562b3
NC
650 int name_len;
651 struct arc_opcode *ext_op;
252b5132 652
0d2bcfaf
NC
653 segT old_sec;
654 int old_subsec;
655
252b5132
RH
656 name = input_line_pointer;
657 c = get_symbol_end ();
19203624 658 name = xstrdup (name);
ea1562b3
NC
659 strcpy (syntax, name);
660 name_len = strlen (name);
0d2bcfaf 661
bcee8eb8 662 /* just after name is now '\0' */
252b5132
RH
663 p = input_line_pointer;
664 *p = c;
ea1562b3 665
252b5132 666 SKIP_WHITESPACE ();
0d2bcfaf 667
252b5132
RH
668 if (*input_line_pointer != ',')
669 {
bd3ba5d1 670 as_bad (_("expected comma after operand name"));
252b5132
RH
671 ignore_rest_of_line ();
672 return;
673 }
0d2bcfaf 674
bcee8eb8 675 input_line_pointer++; /* skip ',' */
ea1562b3 676 opcode = get_absolute_expression ();
0d2bcfaf
NC
677
678 SKIP_WHITESPACE ();
679
680 if (*input_line_pointer != ',')
252b5132 681 {
bd3ba5d1 682 as_bad (_("expected comma after opcode"));
252b5132
RH
683 ignore_rest_of_line ();
684 return;
685 }
0d2bcfaf 686
bcee8eb8 687 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
688 subopcode = get_absolute_expression ();
689
19203624 690 if (subopcode < 0)
252b5132 691 {
bd3ba5d1 692 as_bad (_("negative subopcode %d"), subopcode);
19203624 693 ignore_rest_of_line ();
1e07b820 694 return;
252b5132 695 }
0d2bcfaf 696
19203624 697 if (subopcode)
0d2bcfaf 698 {
19203624 699 if (3 != opcode)
1e07b820 700 {
bd3ba5d1 701 as_bad (_("subcode value found when opcode not equal 0x03"));
19203624 702 ignore_rest_of_line ();
1e07b820
KH
703 return;
704 }
705 else
706 {
707 if (subopcode < 0x09 || subopcode == 0x3f)
708 {
bd3ba5d1 709 as_bad (_("invalid subopcode %d"), subopcode);
19203624 710 ignore_rest_of_line ();
1e07b820
KH
711 return;
712 }
713 }
0d2bcfaf
NC
714 }
715
716 SKIP_WHITESPACE ();
717
252b5132
RH
718 if (*input_line_pointer != ',')
719 {
bd3ba5d1 720 as_bad (_("expected comma after subopcode"));
252b5132
RH
721 ignore_rest_of_line ();
722 return;
723 }
0d2bcfaf 724
bcee8eb8 725 input_line_pointer++; /* skip ',' */
0d2bcfaf 726
19203624 727 for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
0d2bcfaf 728 {
19203624 729 if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1e07b820
KH
730 {
731 suffixcode = i;
732 input_line_pointer += suffixclass[i].len;
733 break;
734 }
0d2bcfaf
NC
735 }
736
19203624 737 if (-1 == suffixcode)
0d2bcfaf 738 {
bd3ba5d1 739 as_bad (_("invalid suffix class"));
0d2bcfaf
NC
740 ignore_rest_of_line ();
741 return;
742 }
743
252b5132 744 SKIP_WHITESPACE ();
0d2bcfaf
NC
745
746 if (*input_line_pointer != ',')
252b5132 747 {
bd3ba5d1 748 as_bad (_("expected comma after suffix class"));
0d2bcfaf
NC
749 ignore_rest_of_line ();
750 return;
252b5132 751 }
0d2bcfaf 752
bcee8eb8 753 input_line_pointer++; /* skip ',' */
0d2bcfaf 754
19203624 755 for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 756 {
19203624 757 if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1e07b820 758 {
96d56e9f 759 s_class = syntaxclass[i].s_class;
1e07b820
KH
760 input_line_pointer += syntaxclass[i].len;
761 break;
762 }
252b5132 763 }
252b5132 764
96d56e9f 765 if (0 == (SYNTAX_VALID & s_class))
0d2bcfaf 766 {
bd3ba5d1 767 as_bad (_("invalid syntax class"));
0d2bcfaf
NC
768 ignore_rest_of_line ();
769 return;
770 }
771
96d56e9f 772 if ((0x3 == opcode) & (s_class & SYNTAX_3OP))
0d2bcfaf 773 {
bd3ba5d1 774 as_bad (_("opcode 0x3 and SYNTAX_3OP invalid"));
0d2bcfaf
NC
775 ignore_rest_of_line ();
776 return;
777 }
778
779 switch (suffixcode)
1e07b820
KH
780 {
781 case 0:
19203624 782 strcat (syntax, "%.q%.f ");
1e07b820
KH
783 break;
784 case 1:
19203624 785 strcat (syntax, "%.f ");
1e07b820
KH
786 break;
787 case 2:
19203624 788 strcat (syntax, "%.q ");
1e07b820
KH
789 break;
790 case 3:
19203624 791 strcat (syntax, " ");
1e07b820
KH
792 break;
793 default:
bd3ba5d1 794 as_bad (_("unknown suffix class"));
19203624 795 ignore_rest_of_line ();
1e07b820
KH
796 return;
797 break;
798 };
0d2bcfaf 799
96d56e9f 800 strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((s_class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
19203624
KH
801 if (suffixcode < 2)
802 strcat (syntax, "%F");
803 strcat (syntax, "%S%L");
0d2bcfaf 804
21d799b5 805 ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
19203624 806 ext_op->syntax = xstrdup (syntax);
0d2bcfaf 807
19203624
KH
808 ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
809 ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
96d56e9f 810 ext_op->flags = s_class;
0d2bcfaf
NC
811 ext_op->next_asm = arc_ext_opcodes;
812 ext_op->next_dis = arc_ext_opcodes;
813 arc_ext_opcodes = ext_op;
814
19203624
KH
815 /* OK, now that we know what this inst is, put a description in the
816 arc extension section of the output file. */
0d2bcfaf
NC
817
818 old_sec = now_seg;
819 old_subsec = now_subseg;
820
19203624 821 arc_set_ext_seg ();
0d2bcfaf 822
19203624
KH
823 p = frag_more (1);
824 *p = 5 + name_len + 1;
825 p = frag_more (1);
0d2bcfaf 826 *p = EXT_INSTRUCTION;
19203624 827 p = frag_more (1);
0d2bcfaf 828 *p = opcode;
19203624 829 p = frag_more (1);
0d2bcfaf 830 *p = subopcode;
19203624 831 p = frag_more (1);
96d56e9f 832 *p = (s_class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
19203624
KH
833 p = frag_more (name_len);
834 strncpy (p, syntax, name_len);
835 p = frag_more (1);
0d2bcfaf
NC
836 *p = '\0';
837
838 subseg_set (old_sec, old_subsec);
839
19203624 840 demand_empty_rest_of_line ();
252b5132
RH
841}
842
252b5132 843static void
ea1562b3 844arc_common (int localScope)
252b5132 845{
0d2bcfaf 846 char *name;
252b5132 847 char c;
0d2bcfaf 848 char *p;
19203624 849 int align, size;
0d2bcfaf 850 symbolS *symbolP;
252b5132 851
0d2bcfaf
NC
852 name = input_line_pointer;
853 c = get_symbol_end ();
bcee8eb8 854 /* just after name is now '\0' */
0d2bcfaf
NC
855 p = input_line_pointer;
856 *p = c;
857 SKIP_WHITESPACE ();
858
859 if (*input_line_pointer != ',')
252b5132 860 {
bd3ba5d1 861 as_bad (_("expected comma after symbol name"));
252b5132
RH
862 ignore_rest_of_line ();
863 return;
864 }
865
bcee8eb8 866 input_line_pointer++; /* skip ',' */
0d2bcfaf 867 size = get_absolute_expression ();
252b5132 868
0d2bcfaf
NC
869 if (size < 0)
870 {
bd3ba5d1 871 as_bad (_("negative symbol length"));
0d2bcfaf
NC
872 ignore_rest_of_line ();
873 return;
874 }
252b5132 875
0d2bcfaf
NC
876 *p = 0;
877 symbolP = symbol_find_or_make (name);
878 *p = c;
879
880 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
881 {
bd3ba5d1 882 as_bad (_("ignoring attempt to re-define symbol"));
0d2bcfaf
NC
883 ignore_rest_of_line ();
884 return;
885 }
19203624
KH
886 if (((int) S_GET_VALUE (symbolP) != 0) \
887 && ((int) S_GET_VALUE (symbolP) != size))
0d2bcfaf 888 {
bd3ba5d1 889 as_warn (_("length of symbol \"%s\" already %ld, ignoring %d"),
0d2bcfaf
NC
890 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
891 }
9c2799c2 892 gas_assert (symbolP->sy_frag == &zero_address_frag);
0d2bcfaf 893
0d2bcfaf
NC
894 /* Now parse the alignment field. This field is optional for
895 local and global symbols. Default alignment is zero. */
896 if (*input_line_pointer == ',')
897 {
898 input_line_pointer++;
899 align = get_absolute_expression ();
900 if (align < 0)
901 {
902 align = 0;
bd3ba5d1 903 as_warn (_("assuming symbol alignment of zero"));
0d2bcfaf
NC
904 }
905 }
252b5132 906 else
0d2bcfaf
NC
907 align = 0;
908
909 if (localScope != 0)
252b5132 910 {
0d2bcfaf
NC
911 segT old_sec;
912 int old_subsec;
913 char *pfrag;
914
915 old_sec = now_seg;
916 old_subsec = now_subseg;
917 record_alignment (bss_section, align);
bcee8eb8 918 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
0d2bcfaf
NC
919
920 if (align)
19203624
KH
921 /* Do alignment. */
922 frag_align (align, 0, 0);
0d2bcfaf 923
19203624 924 /* Detach from old frag. */
0d2bcfaf
NC
925 if (S_GET_SEGMENT (symbolP) == bss_section)
926 symbolP->sy_frag->fr_symbol = NULL;
927
928 symbolP->sy_frag = frag_now;
929 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
19203624 930 (offsetT) size, (char *) 0);
0d2bcfaf
NC
931 *pfrag = 0;
932
933 S_SET_SIZE (symbolP, size);
934 S_SET_SEGMENT (symbolP, bss_section);
935 S_CLEAR_EXTERNAL (symbolP);
293855c8 936 symbol_get_obj (symbolP)->local = 1;
0d2bcfaf
NC
937 subseg_set (old_sec, old_subsec);
938 }
939 else
940 {
941 S_SET_VALUE (symbolP, (valueT) size);
942 S_SET_ALIGN (symbolP, align);
943 S_SET_EXTERNAL (symbolP);
944 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 945 }
252b5132 946
0d2bcfaf
NC
947 symbolP->bsym->flags |= BSF_OBJECT;
948
949 demand_empty_rest_of_line ();
252b5132 950}
0d2bcfaf 951\f
0d2bcfaf 952/* Select the cpu we're assembling for. */
252b5132
RH
953
954static void
ea1562b3 955arc_option (int ignore ATTRIBUTE_UNUSED)
252b5132 956{
ea1562b3 957 extern int arc_get_mach (char *);
0d2bcfaf 958 int mach;
252b5132 959 char c;
0d2bcfaf 960 char *cpu;
252b5132 961
0d2bcfaf 962 cpu = input_line_pointer;
252b5132 963 c = get_symbol_end ();
0d2bcfaf 964 mach = arc_get_mach (cpu);
252b5132
RH
965 *input_line_pointer = c;
966
0d2bcfaf
NC
967 /* If an instruction has already been seen, it's too late. */
968 if (cpu_tables_init_p)
252b5132 969 {
bd3ba5d1 970 as_bad (_("\".option\" directive must appear before any instructions"));
252b5132
RH
971 ignore_rest_of_line ();
972 return;
973 }
252b5132 974
0d2bcfaf
NC
975 if (mach == -1)
976 goto bad_cpu;
977
978 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 979 {
bd3ba5d1 980 as_bad (_("\".option\" directive conflicts with initial definition"));
252b5132
RH
981 ignore_rest_of_line ();
982 return;
983 }
0d2bcfaf
NC
984 else
985 {
986 /* The cpu may have been selected on the command line. */
987 if (mach != arc_mach_type)
bd3ba5d1 988 as_warn (_("\".option\" directive overrides command-line (default) value"));
0d2bcfaf
NC
989 arc_mach_type = mach;
990 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
bd3ba5d1 991 as_fatal (_("could not set architecture and machine"));
0d2bcfaf
NC
992 mach_type_specified_p = 1;
993 }
252b5132 994 demand_empty_rest_of_line ();
0d2bcfaf
NC
995 return;
996
997 bad_cpu:
bd3ba5d1 998 as_bad (_("invalid identifier for \".option\""));
0d2bcfaf 999 ignore_rest_of_line ();
252b5132 1000}
252b5132 1001\f
252b5132 1002char *
ea1562b3 1003md_atof (int type, char *litP, int *sizeP)
252b5132 1004{
499ac353 1005 return ieee_md_atof (type, litP, sizeP, TRUE);
252b5132
RH
1006}
1007
1008/* Write a value out to the object file, using the appropriate
1009 endianness. */
1010
1011void
ea1562b3 1012md_number_to_chars (char *buf, valueT val, int n)
252b5132
RH
1013{
1014 if (target_big_endian)
1015 number_to_chars_bigendian (buf, val, n);
1016 else
1017 number_to_chars_littleendian (buf, val, n);
1018}
1019
bfb32b52 1020/* Round up a section size to the appropriate boundary. */
252b5132
RH
1021
1022valueT
ea1562b3 1023md_section_align (segT segment, valueT size)
252b5132
RH
1024{
1025 int align = bfd_get_section_alignment (stdoutput, segment);
1026
1027 return ((size + (1 << align) - 1) & (-1 << align));
1028}
1029
1030/* We don't have any form of relaxing. */
1031
1032int
ea1562b3
NC
1033md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1034 asection *seg ATTRIBUTE_UNUSED)
252b5132 1035{
b2f58c0c 1036 as_fatal (_("relaxation not supported\n"));
0d2bcfaf 1037 return 1;
252b5132
RH
1038}
1039
1040/* Convert a machine dependent frag. We never generate these. */
1041
1042void
ea1562b3
NC
1043md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1044 asection *sec ATTRIBUTE_UNUSED,
1045 fragS *fragp ATTRIBUTE_UNUSED)
252b5132 1046{
b2f58c0c 1047 abort ();
0d2bcfaf
NC
1048}
1049
ea1562b3
NC
1050static void
1051arc_code_symbol (expressionS *expressionP)
0d2bcfaf 1052{
d3ecfc59 1053 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
0d2bcfaf 1054 {
1e07b820 1055 expressionS two;
ea1562b3 1056
1e07b820 1057 expressionP->X_op = O_right_shift;
bcee8eb8 1058 expressionP->X_add_symbol->sy_value.X_op = O_constant;
1e07b820
KH
1059 two.X_op = O_constant;
1060 two.X_add_symbol = two.X_op_symbol = NULL;
1061 two.X_add_number = 2;
1062 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1063 }
bcee8eb8 1064 /* Allow %st(sym1-sym2) */
19203624
KH
1065 else if (expressionP->X_op == O_subtract
1066 && expressionP->X_add_symbol != NULL
1067 && expressionP->X_op_symbol != NULL
1068 && expressionP->X_add_number == 0)
0d2bcfaf 1069 {
1e07b820 1070 expressionS two;
ea1562b3 1071
1e07b820
KH
1072 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1073 expressionP->X_op = O_right_shift;
1074 two.X_op = O_constant;
1075 two.X_add_symbol = two.X_op_symbol = NULL;
1076 two.X_add_number = 2;
1077 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1078 }
1079 else
bd3ba5d1 1080 as_bad (_("expression too complex code symbol"));
252b5132
RH
1081}
1082
1083/* Parse an operand that is machine-specific.
1084
1085 The ARC has a special %-op to adjust addresses so they're usable in
1086 branches. The "st" is short for the STatus register.
1087 ??? Later expand this to take a flags value too.
1088
1089 ??? We can't create new expression types so we map the %-op's onto the
1090 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1091 to achieve the same effect. */
252b5132 1092
bfb32b52 1093void
ea1562b3 1094md_operand (expressionS *expressionP)
252b5132
RH
1095{
1096 char *p = input_line_pointer;
1097
f17c130b
AM
1098 if (*p != '%')
1099 return;
1100
1101 if (strncmp (p, "%st(", 4) == 0)
1102 {
1103 input_line_pointer += 4;
1104 expression (expressionP);
1105 if (*input_line_pointer != ')')
1106 {
bd3ba5d1 1107 as_bad (_("missing ')' in %%-op"));
f17c130b
AM
1108 return;
1109 }
1110 ++input_line_pointer;
1111 arc_code_symbol (expressionP);
1112 }
1113 else
1114 {
1115 /* It could be a register. */
1116 int i, l;
1117 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1118 p++;
1119
1120 while (ext_oper)
1121 {
1122 l = strlen (ext_oper->operand.name);
1123 if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1124 {
1125 input_line_pointer += l + 1;
1126 expressionP->X_op = O_register;
52de4c06 1127 expressionP->X_add_number = (offsetT) &ext_oper->operand;
f17c130b
AM
1128 return;
1129 }
1130 ext_oper = ext_oper->next;
1131 }
1132 for (i = 0; i < arc_reg_names_count; i++)
1133 {
1134 l = strlen (arc_reg_names[i].name);
1135 if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1136 {
1137 input_line_pointer += l + 1;
1138 expressionP->X_op = O_register;
52de4c06 1139 expressionP->X_add_number = (offsetT) &arc_reg_names[i];
f17c130b
AM
1140 break;
1141 }
1142 }
1143 }
252b5132
RH
1144}
1145
1146/* We have no need to default values of symbols.
1147 We could catch register names here, but that is handled by inserting
1148 them all in the symbol table to begin with. */
1149
1150symbolS *
ea1562b3 1151md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
252b5132
RH
1152{
1153 return 0;
1154}
1155\f
1156/* Functions concerning expressions. */
1157
1158/* Parse a .byte, .word, etc. expression.
1159
1160 Values for the status register are specified with %st(label).
1161 `label' will be right shifted by 2. */
1162
62ebcb5c 1163bfd_reloc_code_real_type
ea1562b3
NC
1164arc_parse_cons_expression (expressionS *exp,
1165 unsigned int nbytes ATTRIBUTE_UNUSED)
252b5132 1166{
0d2bcfaf
NC
1167 char *p = input_line_pointer;
1168 int code_symbol_fix = 0;
1169
19203624
KH
1170 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1171 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1172 {
1e07b820 1173 code_symbol_fix = 1;
19203624 1174 strcpy (p, "; ");
0d2bcfaf 1175 }
9497f5ac 1176 expression_and_evaluate (exp);
1e07b820
KH
1177 if (code_symbol_fix)
1178 {
19203624 1179 arc_code_symbol (exp);
1e07b820
KH
1180 input_line_pointer = p;
1181 }
62ebcb5c 1182 return BFD_RELOC_NONE;
252b5132
RH
1183}
1184
1185/* Record a fixup for a cons expression. */
1186
1187void
ea1562b3
NC
1188arc_cons_fix_new (fragS *frag,
1189 int where,
1190 int nbytes,
62ebcb5c
AM
1191 expressionS *exp,
1192 bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
252b5132
RH
1193{
1194 if (nbytes == 4)
1195 {
1196 int reloc_type;
1197 expressionS exptmp;
1198
1199 /* This may be a special ARC reloc (eg: %st()). */
1200 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
21d799b5
NC
1201 fix_new_exp (frag, where, nbytes, &exptmp, 0,
1202 (enum bfd_reloc_code_real) reloc_type);
252b5132
RH
1203 }
1204 else
1205 {
1206 fix_new_exp (frag, where, nbytes, exp, 0,
1207 nbytes == 2 ? BFD_RELOC_16
1208 : nbytes == 8 ? BFD_RELOC_64
1209 : BFD_RELOC_32);
1210 }
1211}
1212\f
1213/* Functions concerning relocs. */
1214
1215/* The location from which a PC relative jump should be calculated,
1216 given a PC relative reloc. */
1217
bfb32b52 1218long
ea1562b3 1219md_pcrel_from (fixS *fixP)
252b5132 1220{
252b5132
RH
1221 /* Return the address of the delay slot. */
1222 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1223}
1224
252b5132
RH
1225/* Apply a fixup to the object code. This is called for all the
1226 fixups we generated by the call to fix_new_exp, above. In the call
1227 above we used a reloc code which was the largest legal reloc code
1228 plus the operand index. Here we undo that to recover the operand
1229 index. At this point all symbol values should be fully resolved,
1230 and we attempt to completely resolve the reloc. If we can not do
1231 that, we determine the correct reloc code and put it back in the fixup. */
1232
94f592af 1233void
55cf6793 1234md_apply_fix (fixS *fixP, valueT * valP, segT seg)
252b5132 1235{
94f592af 1236 valueT value = * valP;
252b5132 1237
252b5132 1238 if (fixP->fx_addsy == (symbolS *) NULL)
94f592af
NC
1239 fixP->fx_done = 1;
1240
252b5132
RH
1241 else if (fixP->fx_pcrel)
1242 {
a161fe53
AM
1243 /* Hack around bfd_install_relocation brain damage. */
1244 if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
252b5132
RH
1245 value += md_pcrel_from (fixP);
1246 }
a161fe53
AM
1247
1248 /* We can't actually support subtracting a symbol. */
1249 if (fixP->fx_subsy != NULL)
1250 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
252b5132
RH
1251
1252 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1253 {
1254 int opindex;
1255 const struct arc_operand *operand;
1256 char *where;
1257 arc_insn insn;
1258
1259 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1260
1261 operand = &arc_operands[opindex];
1262
1263 /* Fetch the instruction, insert the fully resolved operand
1264 value, and stuff the instruction back again. */
1265 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1266 if (target_big_endian)
1267 insn = bfd_getb32 ((unsigned char *) where);
1268 else
1269 insn = bfd_getl32 ((unsigned char *) where);
1270 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1271 fixP->fx_file, fixP->fx_line);
1272 if (target_big_endian)
1273 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1274 else
1275 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1276
1277 if (fixP->fx_done)
ea1562b3
NC
1278 /* Nothing else to do here. */
1279 return;
252b5132
RH
1280
1281 /* Determine a BFD reloc value based on the operand information.
1282 We are only prepared to turn a few of the operands into relocs.
1283 !!! Note that we can't handle limm values here. Since we're using
1284 implicit addends the addend must be inserted into the instruction,
1285 however, the opcode insertion routines currently do nothing with
1286 limm values. */
1287 if (operand->fmt == 'B')
1288 {
9c2799c2 1289 gas_assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
252b5132
RH
1290 && operand->bits == 20
1291 && operand->shift == 7);
1292 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1293 }
0d2bcfaf 1294 else if (operand->fmt == 'J')
252b5132 1295 {
9c2799c2 1296 gas_assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
252b5132
RH
1297 && operand->bits == 24
1298 && operand->shift == 32);
1299 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1300 }
0d2bcfaf 1301 else if (operand->fmt == 'L')
252b5132 1302 {
9c2799c2 1303 gas_assert ((operand->flags & ARC_OPERAND_LIMM) != 0
252b5132
RH
1304 && operand->bits == 32
1305 && operand->shift == 32);
1306 fixP->fx_r_type = BFD_RELOC_32;
1307 }
1308 else
1309 {
1310 as_bad_where (fixP->fx_file, fixP->fx_line,
bd3ba5d1 1311 _("unresolved expression that must be resolved"));
252b5132 1312 fixP->fx_done = 1;
94f592af 1313 return;
252b5132
RH
1314 }
1315 }
1316 else
1317 {
1318 switch (fixP->fx_r_type)
1319 {
1320 case BFD_RELOC_8:
1321 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1322 value, 1);
1323 break;
1324 case BFD_RELOC_16:
1325 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1326 value, 2);
1327 break;
1328 case BFD_RELOC_32:
1329 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1330 value, 4);
1331 break;
252b5132
RH
1332 case BFD_RELOC_ARC_B26:
1333 /* If !fixP->fx_done then `value' is an implicit addend.
1334 We must shift it right by 2 in this case as well because the
1335 linker performs the relocation and then adds this in (as opposed
1336 to adding this in and then shifting right by 2). */
1337 value >>= 2;
1338 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1339 value, 4);
1340 break;
1341 default:
1342 abort ();
1343 }
1344 }
252b5132
RH
1345}
1346
1347/* Translate internal representation of relocation info to BFD target
1348 format. */
1349
1350arelent *
ea1562b3
NC
1351tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1352 fixS *fixP)
252b5132
RH
1353{
1354 arelent *reloc;
1355
21d799b5
NC
1356 reloc = (arelent *) xmalloc (sizeof (arelent));
1357 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
252b5132 1358
65555e64 1359 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
252b5132
RH
1360 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1361 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1362 if (reloc->howto == (reloc_howto_type *) NULL)
1363 {
1364 as_bad_where (fixP->fx_file, fixP->fx_line,
bd3ba5d1 1365 _("internal error: can't export reloc type %d (`%s')"),
19203624
KH
1366 fixP->fx_r_type,
1367 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
1368 return NULL;
1369 }
1370
9c2799c2 1371 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
252b5132 1372
19203624 1373 /* Set addend to account for PC being advanced one insn before the
a161fe53 1374 target address is computed. */
252b5132 1375
19203624 1376 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 1377
0d2bcfaf 1378 return reloc;
252b5132 1379}
ea1562b3
NC
1380
1381const pseudo_typeS md_pseudo_table[] =
1382{
1383 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
1384 { "comm", arc_common, 0 },
1385 { "common", arc_common, 0 },
1386 { "lcomm", arc_common, 1 },
1387 { "lcommon", arc_common, 1 },
1388 { "2byte", cons, 2 },
1389 { "half", cons, 2 },
1390 { "short", cons, 2 },
1391 { "3byte", cons, 3 },
1392 { "4byte", cons, 4 },
1393 { "word", cons, 4 },
1394 { "option", arc_option, 0 },
1395 { "cpu", arc_option, 0 },
1396 { "block", s_space, 0 },
1397 { "extcondcode", arc_extoper, 0 },
1398 { "extcoreregister", arc_extoper, 1 },
1399 { "extauxregister", arc_extoper, 2 },
1400 { "extinstruction", arc_extinst, 0 },
1401 { NULL, 0, 0 },
1402};
1403
1404/* This routine is called for each instruction to be assembled. */
1405
1406void
1407md_assemble (char *str)
1408{
1409 const struct arc_opcode *opcode;
1410 const struct arc_opcode *std_opcode;
1411 struct arc_opcode *ext_opcode;
1412 char *start;
1413 const char *last_errmsg = 0;
1414 arc_insn insn;
1415 static int init_tables_p = 0;
1416
1417 /* Opcode table initialization is deferred until here because we have to
1418 wait for a possible .option command. */
1419 if (!init_tables_p)
1420 {
1421 init_opcode_tables (arc_mach_type);
1422 init_tables_p = 1;
1423 }
1424
1425 /* Skip leading white space. */
1426 while (ISSPACE (*str))
1427 str++;
1428
1429 /* The instructions are stored in lists hashed by the first letter (though
1430 we needn't care how they're hashed). Get the first in the list. */
1431
1432 ext_opcode = arc_ext_opcodes;
1433 std_opcode = arc_opcode_lookup_asm (str);
1434
1435 /* Keep looking until we find a match. */
1436 start = str;
1437 for (opcode = (ext_opcode ? ext_opcode : std_opcode);
1438 opcode != NULL;
1439 opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1440 ? ARC_OPCODE_NEXT_ASM (opcode)
1441 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
1442 {
1443 int past_opcode_p, fc, num_suffixes;
1444 int fix_up_at = 0;
1445 char *syn;
1446 struct arc_fixup fixups[MAX_FIXUPS];
1447 /* Used as a sanity check. If we need a limm reloc, make sure we ask
1448 for an extra 4 bytes from frag_more. */
1449 int limm_reloc_p;
1450 int ext_suffix_p;
1451 const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
1452
1453 /* Is this opcode supported by the selected cpu? */
1454 if (! arc_opcode_supported (opcode))
1455 continue;
1456
1457 /* Scan the syntax string. If it doesn't match, try the next one. */
1458 arc_opcode_init_insert ();
1459 insn = opcode->value;
1460 fc = 0;
1461 past_opcode_p = 0;
1462 num_suffixes = 0;
1463 limm_reloc_p = 0;
1464 ext_suffix_p = 0;
1465
1466 /* We don't check for (*str != '\0') here because we want to parse
1467 any trailing fake arguments in the syntax string. */
1468 for (str = start, syn = opcode->syntax; *syn != '\0';)
1469 {
1470 int mods;
1471 const struct arc_operand *operand;
1472
1473 /* Non operand chars must match exactly. */
1474 if (*syn != '%' || *++syn == '%')
1475 {
1476 if (*str == *syn)
1477 {
1478 if (*syn == ' ')
1479 past_opcode_p = 1;
1480 ++syn;
1481 ++str;
1482 }
1483 else
1484 break;
1485 continue;
1486 }
1487
1488 /* We have an operand. Pick out any modifiers. */
1489 mods = 0;
1490 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
1491 {
1492 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
1493 ++syn;
1494 }
1495 operand = arc_operands + arc_operand_map[(int) *syn];
1496 if (operand->fmt == 0)
bd3ba5d1 1497 as_fatal (_("unknown syntax format character `%c'"), *syn);
ea1562b3
NC
1498
1499 if (operand->flags & ARC_OPERAND_FAKE)
1500 {
1501 const char *errmsg = NULL;
1502 if (operand->insert)
1503 {
1504 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1505 if (errmsg != (const char *) NULL)
1506 {
1507 last_errmsg = errmsg;
1508 if (operand->flags & ARC_OPERAND_ERROR)
1509 {
20203fb9 1510 as_bad ("%s", errmsg);
ea1562b3
NC
1511 return;
1512 }
1513 else if (operand->flags & ARC_OPERAND_WARN)
20203fb9 1514 as_warn ("%s", errmsg);
ea1562b3
NC
1515 break;
1516 }
1517 if (limm_reloc_p
1518 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
1519 && (operand->flags &
1520 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1521 {
1522 fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
1523 }
1524 }
1525 ++syn;
1526 }
1527 /* Are we finished with suffixes? */
1528 else if (!past_opcode_p)
1529 {
1530 int found;
1531 char c;
1532 char *s, *t;
1533 const struct arc_operand_value *suf, *suffix_end;
1534 const struct arc_operand_value *suffix = NULL;
1535
1536 if (!(operand->flags & ARC_OPERAND_SUFFIX))
1537 abort ();
1538
1539 /* If we're at a space in the input string, we want to skip the
1540 remaining suffixes. There may be some fake ones though, so
1541 just go on to try the next one. */
1542 if (*str == ' ')
1543 {
1544 ++syn;
1545 continue;
1546 }
1547
1548 s = str;
1549 if (mods & ARC_MOD_DOT)
1550 {
1551 if (*s != '.')
1552 break;
1553 ++s;
1554 }
1555 else
1556 {
1557 /* This can happen in "b.nd foo" and we're currently looking
1558 for "%q" (ie: a condition code suffix). */
1559 if (*s == '.')
1560 {
1561 ++syn;
1562 continue;
1563 }
1564 }
1565
1566 /* Pick the suffix out and look it up via the hash table. */
1567 for (t = s; *t && ISALNUM (*t); ++t)
1568 continue;
1569 c = *t;
1570 *t = '\0';
1571 if ((suf = get_ext_suffix (s)))
1572 ext_suffix_p = 1;
1573 else
21d799b5
NC
1574 suf = (const struct arc_operand_value *)
1575 hash_find (arc_suffix_hash, s);
ea1562b3
NC
1576 if (!suf)
1577 {
1578 /* This can happen in "blle foo" and we're currently using
1579 the template "b%q%.n %j". The "bl" insn occurs later in
1580 the table so "lle" isn't an illegal suffix. */
1581 *t = c;
1582 break;
1583 }
1584
1585 /* Is it the right type? Note that the same character is used
1586 several times, so we have to examine all of them. This is
1587 relatively efficient as equivalent entries are kept
1588 together. If it's not the right type, don't increment `str'
1589 so we try the next one in the series. */
1590 found = 0;
1591 if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
1592 {
1593 /* Insert the suffix's value into the insn. */
1594 *t = c;
1595 if (operand->insert)
1596 insn = (*operand->insert) (insn, operand,
1597 mods, NULL, suf->value,
1598 NULL);
1599 else
1600 insn |= suf->value << operand->shift;
1601 suffix = suf;
1602 str = t;
1603 found = 1;
1604 }
1605 else
1606 {
1607 *t = c;
1608 suffix_end = arc_suffixes + arc_suffixes_count;
1609 for (suffix = suf;
1610 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
1611 ++suffix)
1612 {
1613 if (arc_operands[suffix->type].fmt == *syn)
1614 {
1615 /* Insert the suffix's value into the insn. */
1616 if (operand->insert)
1617 insn = (*operand->insert) (insn, operand,
1618 mods, NULL, suffix->value,
1619 NULL);
1620 else
1621 insn |= suffix->value << operand->shift;
1622
1623 str = t;
1624 found = 1;
1625 break;
1626 }
1627 }
1628 }
1629 ++syn;
1630 if (!found)
1631 /* Wrong type. Just go on to try next insn entry. */
1632 ;
1633 else
1634 {
1635 if (num_suffixes == MAX_SUFFIXES)
bd3ba5d1 1636 as_bad (_("too many suffixes"));
ea1562b3
NC
1637 else
1638 insn_suffixes[num_suffixes++] = suffix;
1639 }
1640 }
1641 else
1642 /* This is either a register or an expression of some kind. */
1643 {
1644 char *hold;
1645 const struct arc_operand_value *reg = NULL;
1646 long value = 0;
1647 expressionS exp;
1648
1649 if (operand->flags & ARC_OPERAND_SUFFIX)
1650 abort ();
1651
1652 /* Is there anything left to parse?
1653 We don't check for this at the top because we want to parse
1654 any trailing fake arguments in the syntax string. */
1655 if (is_end_of_line[(unsigned char) *str])
1656 break;
1657
1658 /* Parse the operand. */
1659 hold = input_line_pointer;
1660 input_line_pointer = str;
1661 expression (&exp);
1662 str = input_line_pointer;
1663 input_line_pointer = hold;
1664
1665 if (exp.X_op == O_illegal)
bd3ba5d1 1666 as_bad (_("illegal operand"));
ea1562b3 1667 else if (exp.X_op == O_absent)
bd3ba5d1 1668 as_bad (_("missing operand"));
ea1562b3
NC
1669 else if (exp.X_op == O_constant)
1670 value = exp.X_add_number;
1671 else if (exp.X_op == O_register)
1672 reg = (struct arc_operand_value *) exp.X_add_number;
1673#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
1674 else if (IS_REG_DEST_OPERAND (*syn))
bd3ba5d1 1675 as_bad (_("symbol as destination register"));
ea1562b3
NC
1676 else
1677 {
1678 if (!strncmp (str, "@h30", 4))
1679 {
1680 arc_code_symbol (&exp);
1681 str += 4;
1682 }
1683 /* We need to generate a fixup for this expression. */
1684 if (fc >= MAX_FIXUPS)
bd3ba5d1 1685 as_fatal (_("too many fixups"));
ea1562b3
NC
1686 fixups[fc].exp = exp;
1687 /* We don't support shimm relocs. break here to force
1688 the assembler to output a limm. */
1689#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
1690 if (IS_REG_SHIMM_OFFSET (*syn))
1691 break;
1692 /* If this is a register constant (IE: one whose
1693 register value gets stored as 61-63) then this
1694 must be a limm. */
1695 /* ??? This bit could use some cleaning up.
1696 Referencing the format chars like this goes
1697 against style. */
1698 if (IS_SYMBOL_OPERAND (*syn))
1699 {
1700 const char *junk;
1701 limm_reloc_p = 1;
1702 /* Save this, we don't yet know what reloc to use. */
1703 fix_up_at = fc;
1704 /* Tell insert_reg we need a limm. This is
1705 needed because the value at this point is
1706 zero, a shimm. */
1707 /* ??? We need a cleaner interface than this. */
1708 (*arc_operands[arc_operand_map['Q']].insert)
1709 (insn, operand, mods, reg, 0L, &junk);
1710 }
1711 else
1712 fixups[fc].opindex = arc_operand_map[(int) *syn];
1713 ++fc;
1714 value = 0;
1715 }
1716
1717 /* Insert the register or expression into the instruction. */
1718 if (operand->insert)
1719 {
1720 const char *errmsg = NULL;
1721 insn = (*operand->insert) (insn, operand, mods,
1722 reg, (long) value, &errmsg);
1723 if (errmsg != (const char *) NULL)
1724 {
1725 last_errmsg = errmsg;
1726 if (operand->flags & ARC_OPERAND_ERROR)
1727 {
20203fb9 1728 as_bad ("%s", errmsg);
ea1562b3
NC
1729 return;
1730 }
1731 else if (operand->flags & ARC_OPERAND_WARN)
20203fb9 1732 as_warn ("%s", errmsg);
ea1562b3
NC
1733 break;
1734 }
1735 }
1736 else
1737 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
1738
1739 ++syn;
1740 }
1741 }
1742
1743 /* If we're at the end of the syntax string, we're done. */
1744 /* FIXME: try to move this to a separate function. */
1745 if (*syn == '\0')
1746 {
1747 int i;
1748 char *f;
1749 long limm, limm_p;
1750
1751 /* For the moment we assume a valid `str' can only contain blanks
1752 now. IE: We needn't try again with a longer version of the
1753 insn and it is assumed that longer versions of insns appear
1754 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1755
1756 while (ISSPACE (*str))
1757 ++str;
1758
1759 if (!is_end_of_line[(unsigned char) *str])
bd3ba5d1 1760 as_bad (_("junk at end of line: `%s'"), str);
ea1562b3
NC
1761
1762 /* Is there a limm value? */
1763 limm_p = arc_opcode_limm_p (&limm);
1764
1765 /* Perform various error and warning tests. */
1766
1767 {
1768 static int in_delay_slot_p = 0;
1769 static int prev_insn_needs_cc_nop_p = 0;
1770 /* delay slot type seen */
1771 int delay_slot_type = ARC_DELAY_NONE;
1772 /* conditional execution flag seen */
1773 int conditional = 0;
1774 /* 1 if condition codes are being set */
1775 int cc_set_p = 0;
1776 /* 1 if conditional branch, including `b' "branch always" */
1777 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
1778
1779 for (i = 0; i < num_suffixes; ++i)
1780 {
1781 switch (arc_operands[insn_suffixes[i]->type].fmt)
1782 {
1783 case 'n':
1784 delay_slot_type = insn_suffixes[i]->value;
1785 break;
1786 case 'q':
1787 conditional = insn_suffixes[i]->value;
1788 break;
1789 case 'f':
1790 cc_set_p = 1;
1791 break;
1792 }
1793 }
1794
1795 /* Putting an insn with a limm value in a delay slot is supposed to
1796 be legal, but let's warn the user anyway. Ditto for 8 byte
1797 jumps with delay slots. */
1798 if (in_delay_slot_p && limm_p)
bd3ba5d1 1799 as_warn (_("8 byte instruction in delay slot"));
ea1562b3
NC
1800 if (delay_slot_type != ARC_DELAY_NONE
1801 && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
bd3ba5d1 1802 as_warn (_("8 byte jump instruction with delay slot"));
ea1562b3
NC
1803 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
1804
1805 /* Warn when a conditional branch immediately follows a set of
1806 the condition codes. Note that this needn't be done if the
1807 insn that sets the condition codes uses a limm. */
1808 if (cond_branch_p && conditional != 0 /* 0 = "always" */
1809 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
bd3ba5d1 1810 as_warn (_("conditional branch follows set of flags"));
ea1562b3
NC
1811 prev_insn_needs_cc_nop_p =
1812 /* FIXME: ??? not required:
1813 (delay_slot_type != ARC_DELAY_NONE) && */
1814 cc_set_p && !limm_p;
1815 }
1816
1817 /* Write out the instruction.
1818 It is important to fetch enough space in one call to `frag_more'.
1819 We use (f - frag_now->fr_literal) to compute where we are and we
1820 don't want frag_now to change between calls. */
1821 if (limm_p)
1822 {
1823 f = frag_more (8);
1824 md_number_to_chars (f, insn, 4);
1825 md_number_to_chars (f + 4, limm, 4);
1826 dwarf2_emit_insn (8);
1827 }
1828 else if (limm_reloc_p)
1829 /* We need a limm reloc, but the tables think we don't. */
1830 abort ();
1831 else
1832 {
1833 f = frag_more (4);
1834 md_number_to_chars (f, insn, 4);
1835 dwarf2_emit_insn (4);
1836 }
1837
1838 /* Create any fixups. */
1839 for (i = 0; i < fc; ++i)
1840 {
1841 int op_type, reloc_type;
1842 expressionS exptmp;
1843 const struct arc_operand *operand;
1844
1845 /* Create a fixup for this operand.
1846 At this point we do not use a bfd_reloc_code_real_type for
1847 operands residing in the insn, but instead just use the
1848 operand index. This lets us easily handle fixups for any
1849 operand type, although that is admittedly not a very exciting
55cf6793 1850 feature. We pick a BFD reloc type in md_apply_fix.
ea1562b3
NC
1851
1852 Limm values (4 byte immediate "constants") must be treated
1853 normally because they're not part of the actual insn word
1854 and thus the insertion routines don't handle them. */
1855
1856 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
1857 {
1858 /* Modify the fixup addend as required by the cpu. */
1859 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
1860 op_type = fixups[i].opindex;
1861 /* FIXME: can we add this data to the operand table? */
1862 if (op_type == arc_operand_map['L']
1863 || op_type == arc_operand_map['s']
1864 || op_type == arc_operand_map['o']
1865 || op_type == arc_operand_map['O'])
1866 reloc_type = BFD_RELOC_32;
1867 else if (op_type == arc_operand_map['J'])
1868 reloc_type = BFD_RELOC_ARC_B26;
1869 else
1870 abort ();
1871 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
1872 &fixups[i].exp,
1873 &exptmp);
1874 }
1875 else
1876 {
1877 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
1878 &fixups[i].exp, &exptmp);
1879 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
1880 }
1881 operand = &arc_operands[op_type];
1882 fix_new_exp (frag_now,
1883 ((f - frag_now->fr_literal)
1884 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
1885 &exptmp,
1886 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
1887 (bfd_reloc_code_real_type) reloc_type);
1888 }
1889 return;
1890 }
1891 }
1892
1893 if (NULL == last_errmsg)
bd3ba5d1 1894 as_bad (_("bad instruction `%s'"), start);
ea1562b3 1895 else
20203fb9 1896 as_bad ("%s", last_errmsg);
ea1562b3 1897}
This page took 0.914405 seconds and 4 git commands to generate.