gold: fix ABI pagesize for aarch64
[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
d02603dc 413 c = get_symbol_name (&name);
ea1562b3 414 name = xstrdup (name);
252b5132 415
ea1562b3
NC
416 p = name;
417 while (*p)
252b5132 418 {
ea1562b3
NC
419 *p = TOLOWER (*p);
420 p++;
421 }
252b5132 422
ea1562b3
NC
423 /* just after name is now '\0' */
424 p = input_line_pointer;
d02603dc 425 (void) restore_line_pointer (c);
ea1562b3 426 SKIP_WHITESPACE ();
252b5132 427
ea1562b3
NC
428 if (*input_line_pointer != ',')
429 {
bd3ba5d1 430 as_bad (_("expected comma after operand name"));
ea1562b3
NC
431 ignore_rest_of_line ();
432 free (name);
433 return;
434 }
252b5132 435
ea1562b3
NC
436 input_line_pointer++; /* skip ',' */
437 number = get_absolute_expression ();
252b5132 438
ea1562b3
NC
439 if (number < 0)
440 {
bd3ba5d1 441 as_bad (_("negative operand number %d"), number);
ea1562b3
NC
442 ignore_rest_of_line ();
443 free (name);
444 return;
445 }
446
447 if (opertype)
448 {
449 SKIP_WHITESPACE ();
450
451 if (*input_line_pointer != ',')
252b5132 452 {
bd3ba5d1 453 as_bad (_("expected comma after register-number"));
ea1562b3
NC
454 ignore_rest_of_line ();
455 free (name);
456 return;
457 }
252b5132 458
ea1562b3
NC
459 input_line_pointer++; /* skip ',' */
460 mode = input_line_pointer;
461
462 if (!strncmp (mode, "r|w", 3))
463 {
464 imode = 0;
465 input_line_pointer += 3;
466 }
467 else
468 {
469 if (!strncmp (mode, "r", 1))
252b5132 470 {
ea1562b3
NC
471 imode = ARC_REGISTER_READONLY;
472 input_line_pointer += 1;
473 }
474 else
475 {
476 if (strncmp (mode, "w", 1))
252b5132 477 {
bd3ba5d1 478 as_bad (_("invalid mode"));
ea1562b3
NC
479 ignore_rest_of_line ();
480 free (name);
481 return;
252b5132
RH
482 }
483 else
ea1562b3
NC
484 {
485 imode = ARC_REGISTER_WRITEONLY;
486 input_line_pointer += 1;
487 }
252b5132 488 }
ea1562b3
NC
489 }
490 SKIP_WHITESPACE ();
491 if (1 == opertype)
492 {
493 if (*input_line_pointer != ',')
252b5132 494 {
bd3ba5d1 495 as_bad (_("expected comma after register-mode"));
ea1562b3
NC
496 ignore_rest_of_line ();
497 free (name);
498 return;
252b5132 499 }
252b5132 500
ea1562b3
NC
501 input_line_pointer++; /* skip ',' */
502
503 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
252b5132 504 {
ea1562b3
NC
505 imode |= arc_get_noshortcut_flag ();
506 input_line_pointer += 15;
252b5132 507 }
ea1562b3 508 else
252b5132 509 {
ea1562b3 510 if (strncmp (input_line_pointer, "can_shortcut", 12))
252b5132 511 {
bd3ba5d1 512 as_bad (_("shortcut designator invalid"));
ea1562b3
NC
513 ignore_rest_of_line ();
514 free (name);
515 return;
252b5132
RH
516 }
517 else
518 {
ea1562b3 519 input_line_pointer += 12;
252b5132 520 }
ea1562b3
NC
521 }
522 }
523 }
252b5132 524
ea1562b3
NC
525 if ((opertype == 1) && number > 60)
526 {
bd3ba5d1 527 as_bad (_("core register value (%d) too large"), number);
ea1562b3
NC
528 ignore_rest_of_line ();
529 free (name);
530 return;
531 }
252b5132 532
ea1562b3
NC
533 if ((opertype == 0) && number > 31)
534 {
bd3ba5d1 535 as_bad (_("condition code value (%d) too large"), number);
ea1562b3
NC
536 ignore_rest_of_line ();
537 free (name);
538 return;
539 }
1e07b820 540
21d799b5
NC
541 ext_oper = (struct arc_ext_operand_value *)
542 xmalloc (sizeof (struct arc_ext_operand_value));
ea1562b3
NC
543
544 if (opertype)
545 {
546 /* If the symbol already exists, point it at the new definition. */
547 if ((symbolP = symbol_find (name)))
548 {
549 if (S_GET_SEGMENT (symbolP) == reg_section)
52de4c06 550 S_SET_VALUE (symbolP, (valueT) &ext_oper->operand);
252b5132 551 else
252b5132 552 {
bd3ba5d1 553 as_bad (_("attempt to override symbol: %s"), name);
ea1562b3
NC
554 ignore_rest_of_line ();
555 free (name);
556 free (ext_oper);
557 return;
558 }
559 }
560 else
561 {
562 /* If its not there, add it. */
563 symbol_table_insert (symbol_create (name, reg_section,
52de4c06
NC
564 (valueT) &ext_oper->operand,
565 &zero_address_frag));
ea1562b3
NC
566 }
567 }
252b5132 568
ea1562b3
NC
569 ext_oper->operand.name = name;
570 ext_oper->operand.value = number;
571 ext_oper->operand.type = arc_operand_type (opertype);
572 ext_oper->operand.flags = imode;
252b5132 573
ea1562b3
NC
574 ext_oper->next = arc_ext_operands;
575 arc_ext_operands = ext_oper;
252b5132 576
ea1562b3
NC
577 /* OK, now that we know what this operand is, put a description in
578 the arc extension section of the output file. */
252b5132 579
ea1562b3
NC
580 old_sec = now_seg;
581 old_subsec = now_subseg;
252b5132 582
ea1562b3 583 arc_set_ext_seg ();
252b5132 584
ea1562b3
NC
585 switch (opertype)
586 {
587 case 0:
588 p = frag_more (1);
589 *p = 3 + strlen (name) + 1;
590 p = frag_more (1);
591 *p = EXT_COND_CODE;
592 p = frag_more (1);
593 *p = number;
594 p = frag_more (strlen (name) + 1);
595 strcpy (p, name);
596 break;
597 case 1:
598 p = frag_more (1);
599 *p = 3 + strlen (name) + 1;
600 p = frag_more (1);
601 *p = EXT_CORE_REGISTER;
602 p = frag_more (1);
603 *p = number;
604 p = frag_more (strlen (name) + 1);
605 strcpy (p, name);
606 break;
607 case 2:
608 p = frag_more (1);
609 *p = 6 + strlen (name) + 1;
610 p = frag_more (1);
611 *p = EXT_AUX_REGISTER;
612 p = frag_more (1);
613 *p = number >> 24 & 0xff;
614 p = frag_more (1);
615 *p = number >> 16 & 0xff;
616 p = frag_more (1);
617 *p = number >> 8 & 0xff;
618 p = frag_more (1);
619 *p = number & 0xff;
620 p = frag_more (strlen (name) + 1);
621 strcpy (p, name);
622 break;
623 default:
bd3ba5d1 624 as_bad (_("invalid opertype"));
ea1562b3
NC
625 ignore_rest_of_line ();
626 free (name);
627 return;
628 break;
629 }
252b5132 630
ea1562b3 631 subseg_set (old_sec, old_subsec);
252b5132 632
ea1562b3 633 /* Enter all registers into the symbol table. */
252b5132 634
ea1562b3 635 demand_empty_rest_of_line ();
252b5132 636}
ea1562b3 637
252b5132 638static void
ea1562b3 639arc_extinst (int ignore ATTRIBUTE_UNUSED)
252b5132 640{
ea1562b3 641 char syntax[129];
252b5132 642 char *name;
252b5132 643 char *p;
ea1562b3
NC
644 char c;
645 int suffixcode = -1;
646 int opcode, subopcode;
647 int i;
96d56e9f 648 int s_class = 0;
ea1562b3
NC
649 int name_len;
650 struct arc_opcode *ext_op;
252b5132 651
0d2bcfaf
NC
652 segT old_sec;
653 int old_subsec;
654
d02603dc 655 c = get_symbol_name (&name);
19203624 656 name = xstrdup (name);
ea1562b3
NC
657 strcpy (syntax, name);
658 name_len = strlen (name);
0d2bcfaf 659
bcee8eb8 660 /* just after name is now '\0' */
252b5132 661 p = input_line_pointer;
d02603dc 662 (void) restore_line_pointer (c);
ea1562b3 663
252b5132 664 SKIP_WHITESPACE ();
0d2bcfaf 665
252b5132
RH
666 if (*input_line_pointer != ',')
667 {
bd3ba5d1 668 as_bad (_("expected comma after operand name"));
252b5132
RH
669 ignore_rest_of_line ();
670 return;
671 }
0d2bcfaf 672
bcee8eb8 673 input_line_pointer++; /* skip ',' */
ea1562b3 674 opcode = get_absolute_expression ();
0d2bcfaf
NC
675
676 SKIP_WHITESPACE ();
677
678 if (*input_line_pointer != ',')
252b5132 679 {
bd3ba5d1 680 as_bad (_("expected comma after opcode"));
252b5132
RH
681 ignore_rest_of_line ();
682 return;
683 }
0d2bcfaf 684
bcee8eb8 685 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
686 subopcode = get_absolute_expression ();
687
19203624 688 if (subopcode < 0)
252b5132 689 {
bd3ba5d1 690 as_bad (_("negative subopcode %d"), subopcode);
19203624 691 ignore_rest_of_line ();
1e07b820 692 return;
252b5132 693 }
0d2bcfaf 694
19203624 695 if (subopcode)
0d2bcfaf 696 {
19203624 697 if (3 != opcode)
1e07b820 698 {
bd3ba5d1 699 as_bad (_("subcode value found when opcode not equal 0x03"));
19203624 700 ignore_rest_of_line ();
1e07b820
KH
701 return;
702 }
703 else
704 {
705 if (subopcode < 0x09 || subopcode == 0x3f)
706 {
bd3ba5d1 707 as_bad (_("invalid subopcode %d"), subopcode);
19203624 708 ignore_rest_of_line ();
1e07b820
KH
709 return;
710 }
711 }
0d2bcfaf
NC
712 }
713
714 SKIP_WHITESPACE ();
715
252b5132
RH
716 if (*input_line_pointer != ',')
717 {
bd3ba5d1 718 as_bad (_("expected comma after subopcode"));
252b5132
RH
719 ignore_rest_of_line ();
720 return;
721 }
0d2bcfaf 722
bcee8eb8 723 input_line_pointer++; /* skip ',' */
0d2bcfaf 724
19203624 725 for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
0d2bcfaf 726 {
19203624 727 if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1e07b820
KH
728 {
729 suffixcode = i;
730 input_line_pointer += suffixclass[i].len;
731 break;
732 }
0d2bcfaf
NC
733 }
734
19203624 735 if (-1 == suffixcode)
0d2bcfaf 736 {
bd3ba5d1 737 as_bad (_("invalid suffix class"));
0d2bcfaf
NC
738 ignore_rest_of_line ();
739 return;
740 }
741
252b5132 742 SKIP_WHITESPACE ();
0d2bcfaf
NC
743
744 if (*input_line_pointer != ',')
252b5132 745 {
bd3ba5d1 746 as_bad (_("expected comma after suffix class"));
0d2bcfaf
NC
747 ignore_rest_of_line ();
748 return;
252b5132 749 }
0d2bcfaf 750
bcee8eb8 751 input_line_pointer++; /* skip ',' */
0d2bcfaf 752
19203624 753 for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 754 {
19203624 755 if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1e07b820 756 {
96d56e9f 757 s_class = syntaxclass[i].s_class;
1e07b820
KH
758 input_line_pointer += syntaxclass[i].len;
759 break;
760 }
252b5132 761 }
252b5132 762
96d56e9f 763 if (0 == (SYNTAX_VALID & s_class))
0d2bcfaf 764 {
bd3ba5d1 765 as_bad (_("invalid syntax class"));
0d2bcfaf
NC
766 ignore_rest_of_line ();
767 return;
768 }
769
96d56e9f 770 if ((0x3 == opcode) & (s_class & SYNTAX_3OP))
0d2bcfaf 771 {
bd3ba5d1 772 as_bad (_("opcode 0x3 and SYNTAX_3OP invalid"));
0d2bcfaf
NC
773 ignore_rest_of_line ();
774 return;
775 }
776
777 switch (suffixcode)
1e07b820
KH
778 {
779 case 0:
19203624 780 strcat (syntax, "%.q%.f ");
1e07b820
KH
781 break;
782 case 1:
19203624 783 strcat (syntax, "%.f ");
1e07b820
KH
784 break;
785 case 2:
19203624 786 strcat (syntax, "%.q ");
1e07b820
KH
787 break;
788 case 3:
19203624 789 strcat (syntax, " ");
1e07b820
KH
790 break;
791 default:
bd3ba5d1 792 as_bad (_("unknown suffix class"));
19203624 793 ignore_rest_of_line ();
1e07b820
KH
794 return;
795 break;
796 };
0d2bcfaf 797
96d56e9f 798 strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((s_class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
19203624
KH
799 if (suffixcode < 2)
800 strcat (syntax, "%F");
801 strcat (syntax, "%S%L");
0d2bcfaf 802
21d799b5 803 ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
19203624 804 ext_op->syntax = xstrdup (syntax);
0d2bcfaf 805
19203624
KH
806 ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
807 ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
96d56e9f 808 ext_op->flags = s_class;
0d2bcfaf
NC
809 ext_op->next_asm = arc_ext_opcodes;
810 ext_op->next_dis = arc_ext_opcodes;
811 arc_ext_opcodes = ext_op;
812
19203624
KH
813 /* OK, now that we know what this inst is, put a description in the
814 arc extension section of the output file. */
0d2bcfaf
NC
815
816 old_sec = now_seg;
817 old_subsec = now_subseg;
818
19203624 819 arc_set_ext_seg ();
0d2bcfaf 820
19203624
KH
821 p = frag_more (1);
822 *p = 5 + name_len + 1;
823 p = frag_more (1);
0d2bcfaf 824 *p = EXT_INSTRUCTION;
19203624 825 p = frag_more (1);
0d2bcfaf 826 *p = opcode;
19203624 827 p = frag_more (1);
0d2bcfaf 828 *p = subopcode;
19203624 829 p = frag_more (1);
96d56e9f 830 *p = (s_class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
19203624
KH
831 p = frag_more (name_len);
832 strncpy (p, syntax, name_len);
833 p = frag_more (1);
0d2bcfaf
NC
834 *p = '\0';
835
836 subseg_set (old_sec, old_subsec);
837
19203624 838 demand_empty_rest_of_line ();
252b5132
RH
839}
840
252b5132 841static void
ea1562b3 842arc_common (int localScope)
252b5132 843{
0d2bcfaf 844 char *name;
252b5132 845 char c;
0d2bcfaf 846 char *p;
19203624 847 int align, size;
0d2bcfaf 848 symbolS *symbolP;
252b5132 849
d02603dc 850 c = get_symbol_name (&name);
bcee8eb8 851 /* just after name is now '\0' */
0d2bcfaf 852 p = input_line_pointer;
d02603dc 853 (void) restore_line_pointer (c);
0d2bcfaf
NC
854 SKIP_WHITESPACE ();
855
856 if (*input_line_pointer != ',')
252b5132 857 {
bd3ba5d1 858 as_bad (_("expected comma after symbol name"));
252b5132
RH
859 ignore_rest_of_line ();
860 return;
861 }
862
bcee8eb8 863 input_line_pointer++; /* skip ',' */
0d2bcfaf 864 size = get_absolute_expression ();
252b5132 865
0d2bcfaf
NC
866 if (size < 0)
867 {
bd3ba5d1 868 as_bad (_("negative symbol length"));
0d2bcfaf
NC
869 ignore_rest_of_line ();
870 return;
871 }
252b5132 872
0d2bcfaf
NC
873 *p = 0;
874 symbolP = symbol_find_or_make (name);
875 *p = c;
876
877 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
878 {
bd3ba5d1 879 as_bad (_("ignoring attempt to re-define symbol"));
0d2bcfaf
NC
880 ignore_rest_of_line ();
881 return;
882 }
19203624
KH
883 if (((int) S_GET_VALUE (symbolP) != 0) \
884 && ((int) S_GET_VALUE (symbolP) != size))
0d2bcfaf 885 {
bd3ba5d1 886 as_warn (_("length of symbol \"%s\" already %ld, ignoring %d"),
0d2bcfaf
NC
887 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
888 }
9c2799c2 889 gas_assert (symbolP->sy_frag == &zero_address_frag);
0d2bcfaf 890
0d2bcfaf
NC
891 /* Now parse the alignment field. This field is optional for
892 local and global symbols. Default alignment is zero. */
893 if (*input_line_pointer == ',')
894 {
895 input_line_pointer++;
896 align = get_absolute_expression ();
897 if (align < 0)
898 {
899 align = 0;
bd3ba5d1 900 as_warn (_("assuming symbol alignment of zero"));
0d2bcfaf
NC
901 }
902 }
252b5132 903 else
0d2bcfaf
NC
904 align = 0;
905
906 if (localScope != 0)
252b5132 907 {
0d2bcfaf
NC
908 segT old_sec;
909 int old_subsec;
910 char *pfrag;
911
912 old_sec = now_seg;
913 old_subsec = now_subseg;
914 record_alignment (bss_section, align);
bcee8eb8 915 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
0d2bcfaf
NC
916
917 if (align)
19203624
KH
918 /* Do alignment. */
919 frag_align (align, 0, 0);
0d2bcfaf 920
19203624 921 /* Detach from old frag. */
0d2bcfaf
NC
922 if (S_GET_SEGMENT (symbolP) == bss_section)
923 symbolP->sy_frag->fr_symbol = NULL;
924
925 symbolP->sy_frag = frag_now;
926 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
19203624 927 (offsetT) size, (char *) 0);
0d2bcfaf
NC
928 *pfrag = 0;
929
930 S_SET_SIZE (symbolP, size);
931 S_SET_SEGMENT (symbolP, bss_section);
932 S_CLEAR_EXTERNAL (symbolP);
293855c8 933 symbol_get_obj (symbolP)->local = 1;
0d2bcfaf
NC
934 subseg_set (old_sec, old_subsec);
935 }
936 else
937 {
938 S_SET_VALUE (symbolP, (valueT) size);
939 S_SET_ALIGN (symbolP, align);
940 S_SET_EXTERNAL (symbolP);
941 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 942 }
252b5132 943
0d2bcfaf
NC
944 symbolP->bsym->flags |= BSF_OBJECT;
945
946 demand_empty_rest_of_line ();
252b5132 947}
0d2bcfaf 948\f
0d2bcfaf 949/* Select the cpu we're assembling for. */
252b5132
RH
950
951static void
ea1562b3 952arc_option (int ignore ATTRIBUTE_UNUSED)
252b5132 953{
ea1562b3 954 extern int arc_get_mach (char *);
0d2bcfaf 955 int mach;
252b5132 956 char c;
0d2bcfaf 957 char *cpu;
252b5132 958
d02603dc 959 c = get_symbol_name (&cpu);
0d2bcfaf 960 mach = arc_get_mach (cpu);
d02603dc 961 (void) restore_line_pointer (c);
252b5132 962
0d2bcfaf
NC
963 /* If an instruction has already been seen, it's too late. */
964 if (cpu_tables_init_p)
252b5132 965 {
bd3ba5d1 966 as_bad (_("\".option\" directive must appear before any instructions"));
252b5132
RH
967 ignore_rest_of_line ();
968 return;
969 }
252b5132 970
0d2bcfaf
NC
971 if (mach == -1)
972 goto bad_cpu;
973
974 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 975 {
bd3ba5d1 976 as_bad (_("\".option\" directive conflicts with initial definition"));
252b5132
RH
977 ignore_rest_of_line ();
978 return;
979 }
0d2bcfaf
NC
980 else
981 {
982 /* The cpu may have been selected on the command line. */
983 if (mach != arc_mach_type)
bd3ba5d1 984 as_warn (_("\".option\" directive overrides command-line (default) value"));
0d2bcfaf
NC
985 arc_mach_type = mach;
986 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
bd3ba5d1 987 as_fatal (_("could not set architecture and machine"));
0d2bcfaf
NC
988 mach_type_specified_p = 1;
989 }
252b5132 990 demand_empty_rest_of_line ();
0d2bcfaf
NC
991 return;
992
993 bad_cpu:
bd3ba5d1 994 as_bad (_("invalid identifier for \".option\""));
0d2bcfaf 995 ignore_rest_of_line ();
252b5132 996}
252b5132 997\f
252b5132 998char *
ea1562b3 999md_atof (int type, char *litP, int *sizeP)
252b5132 1000{
499ac353 1001 return ieee_md_atof (type, litP, sizeP, TRUE);
252b5132
RH
1002}
1003
1004/* Write a value out to the object file, using the appropriate
1005 endianness. */
1006
1007void
ea1562b3 1008md_number_to_chars (char *buf, valueT val, int n)
252b5132
RH
1009{
1010 if (target_big_endian)
1011 number_to_chars_bigendian (buf, val, n);
1012 else
1013 number_to_chars_littleendian (buf, val, n);
1014}
1015
bfb32b52 1016/* Round up a section size to the appropriate boundary. */
252b5132
RH
1017
1018valueT
ea1562b3 1019md_section_align (segT segment, valueT size)
252b5132
RH
1020{
1021 int align = bfd_get_section_alignment (stdoutput, segment);
1022
1023 return ((size + (1 << align) - 1) & (-1 << align));
1024}
1025
1026/* We don't have any form of relaxing. */
1027
1028int
ea1562b3
NC
1029md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1030 asection *seg ATTRIBUTE_UNUSED)
252b5132 1031{
b2f58c0c 1032 as_fatal (_("relaxation not supported\n"));
0d2bcfaf 1033 return 1;
252b5132
RH
1034}
1035
1036/* Convert a machine dependent frag. We never generate these. */
1037
1038void
ea1562b3
NC
1039md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1040 asection *sec ATTRIBUTE_UNUSED,
1041 fragS *fragp ATTRIBUTE_UNUSED)
252b5132 1042{
b2f58c0c 1043 abort ();
0d2bcfaf
NC
1044}
1045
ea1562b3
NC
1046static void
1047arc_code_symbol (expressionS *expressionP)
0d2bcfaf 1048{
d3ecfc59 1049 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
0d2bcfaf 1050 {
1e07b820 1051 expressionS two;
ea1562b3 1052
1e07b820 1053 expressionP->X_op = O_right_shift;
bcee8eb8 1054 expressionP->X_add_symbol->sy_value.X_op = O_constant;
1e07b820
KH
1055 two.X_op = O_constant;
1056 two.X_add_symbol = two.X_op_symbol = NULL;
1057 two.X_add_number = 2;
1058 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1059 }
bcee8eb8 1060 /* Allow %st(sym1-sym2) */
19203624
KH
1061 else if (expressionP->X_op == O_subtract
1062 && expressionP->X_add_symbol != NULL
1063 && expressionP->X_op_symbol != NULL
1064 && expressionP->X_add_number == 0)
0d2bcfaf 1065 {
1e07b820 1066 expressionS two;
ea1562b3 1067
1e07b820
KH
1068 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1069 expressionP->X_op = O_right_shift;
1070 two.X_op = O_constant;
1071 two.X_add_symbol = two.X_op_symbol = NULL;
1072 two.X_add_number = 2;
1073 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1074 }
1075 else
bd3ba5d1 1076 as_bad (_("expression too complex code symbol"));
252b5132
RH
1077}
1078
1079/* Parse an operand that is machine-specific.
1080
1081 The ARC has a special %-op to adjust addresses so they're usable in
1082 branches. The "st" is short for the STatus register.
1083 ??? Later expand this to take a flags value too.
1084
1085 ??? We can't create new expression types so we map the %-op's onto the
1086 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1087 to achieve the same effect. */
252b5132 1088
bfb32b52 1089void
ea1562b3 1090md_operand (expressionS *expressionP)
252b5132
RH
1091{
1092 char *p = input_line_pointer;
1093
f17c130b
AM
1094 if (*p != '%')
1095 return;
1096
1097 if (strncmp (p, "%st(", 4) == 0)
1098 {
1099 input_line_pointer += 4;
1100 expression (expressionP);
1101 if (*input_line_pointer != ')')
1102 {
bd3ba5d1 1103 as_bad (_("missing ')' in %%-op"));
f17c130b
AM
1104 return;
1105 }
1106 ++input_line_pointer;
1107 arc_code_symbol (expressionP);
1108 }
1109 else
1110 {
1111 /* It could be a register. */
1112 int i, l;
1113 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1114 p++;
1115
1116 while (ext_oper)
1117 {
1118 l = strlen (ext_oper->operand.name);
1119 if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1120 {
1121 input_line_pointer += l + 1;
1122 expressionP->X_op = O_register;
52de4c06 1123 expressionP->X_add_number = (offsetT) &ext_oper->operand;
f17c130b
AM
1124 return;
1125 }
1126 ext_oper = ext_oper->next;
1127 }
1128 for (i = 0; i < arc_reg_names_count; i++)
1129 {
1130 l = strlen (arc_reg_names[i].name);
1131 if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1132 {
1133 input_line_pointer += l + 1;
1134 expressionP->X_op = O_register;
52de4c06 1135 expressionP->X_add_number = (offsetT) &arc_reg_names[i];
f17c130b
AM
1136 break;
1137 }
1138 }
1139 }
252b5132
RH
1140}
1141
1142/* We have no need to default values of symbols.
1143 We could catch register names here, but that is handled by inserting
1144 them all in the symbol table to begin with. */
1145
1146symbolS *
ea1562b3 1147md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
252b5132
RH
1148{
1149 return 0;
1150}
1151\f
1152/* Functions concerning expressions. */
1153
1154/* Parse a .byte, .word, etc. expression.
1155
1156 Values for the status register are specified with %st(label).
1157 `label' will be right shifted by 2. */
1158
62ebcb5c 1159bfd_reloc_code_real_type
ea1562b3
NC
1160arc_parse_cons_expression (expressionS *exp,
1161 unsigned int nbytes ATTRIBUTE_UNUSED)
252b5132 1162{
0d2bcfaf
NC
1163 char *p = input_line_pointer;
1164 int code_symbol_fix = 0;
1165
19203624
KH
1166 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1167 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1168 {
1e07b820 1169 code_symbol_fix = 1;
19203624 1170 strcpy (p, "; ");
0d2bcfaf 1171 }
9497f5ac 1172 expression_and_evaluate (exp);
1e07b820
KH
1173 if (code_symbol_fix)
1174 {
19203624 1175 arc_code_symbol (exp);
1e07b820
KH
1176 input_line_pointer = p;
1177 }
62ebcb5c 1178 return BFD_RELOC_NONE;
252b5132
RH
1179}
1180
1181/* Record a fixup for a cons expression. */
1182
1183void
ea1562b3
NC
1184arc_cons_fix_new (fragS *frag,
1185 int where,
1186 int nbytes,
62ebcb5c
AM
1187 expressionS *exp,
1188 bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
252b5132
RH
1189{
1190 if (nbytes == 4)
1191 {
1192 int reloc_type;
1193 expressionS exptmp;
1194
1195 /* This may be a special ARC reloc (eg: %st()). */
1196 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
21d799b5
NC
1197 fix_new_exp (frag, where, nbytes, &exptmp, 0,
1198 (enum bfd_reloc_code_real) reloc_type);
252b5132
RH
1199 }
1200 else
1201 {
1202 fix_new_exp (frag, where, nbytes, exp, 0,
1203 nbytes == 2 ? BFD_RELOC_16
1204 : nbytes == 8 ? BFD_RELOC_64
1205 : BFD_RELOC_32);
1206 }
1207}
1208\f
1209/* Functions concerning relocs. */
1210
1211/* The location from which a PC relative jump should be calculated,
1212 given a PC relative reloc. */
1213
bfb32b52 1214long
ea1562b3 1215md_pcrel_from (fixS *fixP)
252b5132 1216{
252b5132
RH
1217 /* Return the address of the delay slot. */
1218 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1219}
1220
252b5132
RH
1221/* Apply a fixup to the object code. This is called for all the
1222 fixups we generated by the call to fix_new_exp, above. In the call
1223 above we used a reloc code which was the largest legal reloc code
1224 plus the operand index. Here we undo that to recover the operand
1225 index. At this point all symbol values should be fully resolved,
1226 and we attempt to completely resolve the reloc. If we can not do
1227 that, we determine the correct reloc code and put it back in the fixup. */
1228
94f592af 1229void
55cf6793 1230md_apply_fix (fixS *fixP, valueT * valP, segT seg)
252b5132 1231{
94f592af 1232 valueT value = * valP;
252b5132 1233
252b5132 1234 if (fixP->fx_addsy == (symbolS *) NULL)
94f592af
NC
1235 fixP->fx_done = 1;
1236
252b5132
RH
1237 else if (fixP->fx_pcrel)
1238 {
a161fe53
AM
1239 /* Hack around bfd_install_relocation brain damage. */
1240 if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
252b5132
RH
1241 value += md_pcrel_from (fixP);
1242 }
a161fe53
AM
1243
1244 /* We can't actually support subtracting a symbol. */
1245 if (fixP->fx_subsy != NULL)
1246 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
252b5132
RH
1247
1248 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1249 {
1250 int opindex;
1251 const struct arc_operand *operand;
1252 char *where;
1253 arc_insn insn;
1254
1255 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1256
1257 operand = &arc_operands[opindex];
1258
1259 /* Fetch the instruction, insert the fully resolved operand
1260 value, and stuff the instruction back again. */
1261 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1262 if (target_big_endian)
1263 insn = bfd_getb32 ((unsigned char *) where);
1264 else
1265 insn = bfd_getl32 ((unsigned char *) where);
1266 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1267 fixP->fx_file, fixP->fx_line);
1268 if (target_big_endian)
1269 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1270 else
1271 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1272
1273 if (fixP->fx_done)
ea1562b3
NC
1274 /* Nothing else to do here. */
1275 return;
252b5132
RH
1276
1277 /* Determine a BFD reloc value based on the operand information.
1278 We are only prepared to turn a few of the operands into relocs.
1279 !!! Note that we can't handle limm values here. Since we're using
1280 implicit addends the addend must be inserted into the instruction,
1281 however, the opcode insertion routines currently do nothing with
1282 limm values. */
1283 if (operand->fmt == 'B')
1284 {
9c2799c2 1285 gas_assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
252b5132
RH
1286 && operand->bits == 20
1287 && operand->shift == 7);
1288 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1289 }
0d2bcfaf 1290 else if (operand->fmt == 'J')
252b5132 1291 {
9c2799c2 1292 gas_assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
252b5132
RH
1293 && operand->bits == 24
1294 && operand->shift == 32);
1295 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1296 }
0d2bcfaf 1297 else if (operand->fmt == 'L')
252b5132 1298 {
9c2799c2 1299 gas_assert ((operand->flags & ARC_OPERAND_LIMM) != 0
252b5132
RH
1300 && operand->bits == 32
1301 && operand->shift == 32);
1302 fixP->fx_r_type = BFD_RELOC_32;
1303 }
1304 else
1305 {
1306 as_bad_where (fixP->fx_file, fixP->fx_line,
bd3ba5d1 1307 _("unresolved expression that must be resolved"));
252b5132 1308 fixP->fx_done = 1;
94f592af 1309 return;
252b5132
RH
1310 }
1311 }
1312 else
1313 {
1314 switch (fixP->fx_r_type)
1315 {
1316 case BFD_RELOC_8:
1317 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1318 value, 1);
1319 break;
1320 case BFD_RELOC_16:
1321 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1322 value, 2);
1323 break;
1324 case BFD_RELOC_32:
1325 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1326 value, 4);
1327 break;
252b5132
RH
1328 case BFD_RELOC_ARC_B26:
1329 /* If !fixP->fx_done then `value' is an implicit addend.
1330 We must shift it right by 2 in this case as well because the
1331 linker performs the relocation and then adds this in (as opposed
1332 to adding this in and then shifting right by 2). */
1333 value >>= 2;
1334 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1335 value, 4);
1336 break;
1337 default:
1338 abort ();
1339 }
1340 }
252b5132
RH
1341}
1342
1343/* Translate internal representation of relocation info to BFD target
1344 format. */
1345
1346arelent *
ea1562b3
NC
1347tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1348 fixS *fixP)
252b5132
RH
1349{
1350 arelent *reloc;
1351
21d799b5
NC
1352 reloc = (arelent *) xmalloc (sizeof (arelent));
1353 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
252b5132 1354
65555e64 1355 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
252b5132
RH
1356 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1357 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1358 if (reloc->howto == (reloc_howto_type *) NULL)
1359 {
1360 as_bad_where (fixP->fx_file, fixP->fx_line,
bd3ba5d1 1361 _("internal error: can't export reloc type %d (`%s')"),
19203624
KH
1362 fixP->fx_r_type,
1363 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
1364 return NULL;
1365 }
1366
9c2799c2 1367 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
252b5132 1368
19203624 1369 /* Set addend to account for PC being advanced one insn before the
a161fe53 1370 target address is computed. */
252b5132 1371
19203624 1372 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 1373
0d2bcfaf 1374 return reloc;
252b5132 1375}
ea1562b3
NC
1376
1377const pseudo_typeS md_pseudo_table[] =
1378{
1379 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
1380 { "comm", arc_common, 0 },
1381 { "common", arc_common, 0 },
1382 { "lcomm", arc_common, 1 },
1383 { "lcommon", arc_common, 1 },
1384 { "2byte", cons, 2 },
1385 { "half", cons, 2 },
1386 { "short", cons, 2 },
1387 { "3byte", cons, 3 },
1388 { "4byte", cons, 4 },
1389 { "word", cons, 4 },
1390 { "option", arc_option, 0 },
1391 { "cpu", arc_option, 0 },
1392 { "block", s_space, 0 },
1393 { "extcondcode", arc_extoper, 0 },
1394 { "extcoreregister", arc_extoper, 1 },
1395 { "extauxregister", arc_extoper, 2 },
1396 { "extinstruction", arc_extinst, 0 },
1397 { NULL, 0, 0 },
1398};
1399
1400/* This routine is called for each instruction to be assembled. */
1401
1402void
1403md_assemble (char *str)
1404{
1405 const struct arc_opcode *opcode;
1406 const struct arc_opcode *std_opcode;
1407 struct arc_opcode *ext_opcode;
1408 char *start;
1409 const char *last_errmsg = 0;
1410 arc_insn insn;
1411 static int init_tables_p = 0;
1412
1413 /* Opcode table initialization is deferred until here because we have to
1414 wait for a possible .option command. */
1415 if (!init_tables_p)
1416 {
1417 init_opcode_tables (arc_mach_type);
1418 init_tables_p = 1;
1419 }
1420
1421 /* Skip leading white space. */
1422 while (ISSPACE (*str))
1423 str++;
1424
1425 /* The instructions are stored in lists hashed by the first letter (though
1426 we needn't care how they're hashed). Get the first in the list. */
1427
1428 ext_opcode = arc_ext_opcodes;
1429 std_opcode = arc_opcode_lookup_asm (str);
1430
1431 /* Keep looking until we find a match. */
1432 start = str;
1433 for (opcode = (ext_opcode ? ext_opcode : std_opcode);
1434 opcode != NULL;
1435 opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1436 ? ARC_OPCODE_NEXT_ASM (opcode)
1437 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
1438 {
1439 int past_opcode_p, fc, num_suffixes;
1440 int fix_up_at = 0;
1441 char *syn;
1442 struct arc_fixup fixups[MAX_FIXUPS];
1443 /* Used as a sanity check. If we need a limm reloc, make sure we ask
1444 for an extra 4 bytes from frag_more. */
1445 int limm_reloc_p;
1446 int ext_suffix_p;
1447 const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
1448
1449 /* Is this opcode supported by the selected cpu? */
1450 if (! arc_opcode_supported (opcode))
1451 continue;
1452
1453 /* Scan the syntax string. If it doesn't match, try the next one. */
1454 arc_opcode_init_insert ();
1455 insn = opcode->value;
1456 fc = 0;
1457 past_opcode_p = 0;
1458 num_suffixes = 0;
1459 limm_reloc_p = 0;
1460 ext_suffix_p = 0;
1461
1462 /* We don't check for (*str != '\0') here because we want to parse
1463 any trailing fake arguments in the syntax string. */
1464 for (str = start, syn = opcode->syntax; *syn != '\0';)
1465 {
1466 int mods;
1467 const struct arc_operand *operand;
1468
1469 /* Non operand chars must match exactly. */
1470 if (*syn != '%' || *++syn == '%')
1471 {
1472 if (*str == *syn)
1473 {
1474 if (*syn == ' ')
1475 past_opcode_p = 1;
1476 ++syn;
1477 ++str;
1478 }
1479 else
1480 break;
1481 continue;
1482 }
1483
1484 /* We have an operand. Pick out any modifiers. */
1485 mods = 0;
1486 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
1487 {
1488 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
1489 ++syn;
1490 }
1491 operand = arc_operands + arc_operand_map[(int) *syn];
1492 if (operand->fmt == 0)
bd3ba5d1 1493 as_fatal (_("unknown syntax format character `%c'"), *syn);
ea1562b3
NC
1494
1495 if (operand->flags & ARC_OPERAND_FAKE)
1496 {
1497 const char *errmsg = NULL;
1498 if (operand->insert)
1499 {
1500 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1501 if (errmsg != (const char *) NULL)
1502 {
1503 last_errmsg = errmsg;
1504 if (operand->flags & ARC_OPERAND_ERROR)
1505 {
20203fb9 1506 as_bad ("%s", errmsg);
ea1562b3
NC
1507 return;
1508 }
1509 else if (operand->flags & ARC_OPERAND_WARN)
20203fb9 1510 as_warn ("%s", errmsg);
ea1562b3
NC
1511 break;
1512 }
1513 if (limm_reloc_p
1514 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
1515 && (operand->flags &
1516 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1517 {
1518 fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
1519 }
1520 }
1521 ++syn;
1522 }
1523 /* Are we finished with suffixes? */
1524 else if (!past_opcode_p)
1525 {
1526 int found;
1527 char c;
1528 char *s, *t;
1529 const struct arc_operand_value *suf, *suffix_end;
1530 const struct arc_operand_value *suffix = NULL;
1531
1532 if (!(operand->flags & ARC_OPERAND_SUFFIX))
1533 abort ();
1534
1535 /* If we're at a space in the input string, we want to skip the
1536 remaining suffixes. There may be some fake ones though, so
1537 just go on to try the next one. */
1538 if (*str == ' ')
1539 {
1540 ++syn;
1541 continue;
1542 }
1543
1544 s = str;
1545 if (mods & ARC_MOD_DOT)
1546 {
1547 if (*s != '.')
1548 break;
1549 ++s;
1550 }
1551 else
1552 {
1553 /* This can happen in "b.nd foo" and we're currently looking
1554 for "%q" (ie: a condition code suffix). */
1555 if (*s == '.')
1556 {
1557 ++syn;
1558 continue;
1559 }
1560 }
1561
1562 /* Pick the suffix out and look it up via the hash table. */
1563 for (t = s; *t && ISALNUM (*t); ++t)
1564 continue;
1565 c = *t;
1566 *t = '\0';
1567 if ((suf = get_ext_suffix (s)))
1568 ext_suffix_p = 1;
1569 else
21d799b5
NC
1570 suf = (const struct arc_operand_value *)
1571 hash_find (arc_suffix_hash, s);
ea1562b3
NC
1572 if (!suf)
1573 {
1574 /* This can happen in "blle foo" and we're currently using
1575 the template "b%q%.n %j". The "bl" insn occurs later in
1576 the table so "lle" isn't an illegal suffix. */
1577 *t = c;
1578 break;
1579 }
1580
1581 /* Is it the right type? Note that the same character is used
1582 several times, so we have to examine all of them. This is
1583 relatively efficient as equivalent entries are kept
1584 together. If it's not the right type, don't increment `str'
1585 so we try the next one in the series. */
1586 found = 0;
1587 if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
1588 {
1589 /* Insert the suffix's value into the insn. */
1590 *t = c;
1591 if (operand->insert)
1592 insn = (*operand->insert) (insn, operand,
1593 mods, NULL, suf->value,
1594 NULL);
1595 else
1596 insn |= suf->value << operand->shift;
1597 suffix = suf;
1598 str = t;
1599 found = 1;
1600 }
1601 else
1602 {
1603 *t = c;
1604 suffix_end = arc_suffixes + arc_suffixes_count;
1605 for (suffix = suf;
1606 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
1607 ++suffix)
1608 {
1609 if (arc_operands[suffix->type].fmt == *syn)
1610 {
1611 /* Insert the suffix's value into the insn. */
1612 if (operand->insert)
1613 insn = (*operand->insert) (insn, operand,
1614 mods, NULL, suffix->value,
1615 NULL);
1616 else
1617 insn |= suffix->value << operand->shift;
1618
1619 str = t;
1620 found = 1;
1621 break;
1622 }
1623 }
1624 }
1625 ++syn;
1626 if (!found)
1627 /* Wrong type. Just go on to try next insn entry. */
1628 ;
1629 else
1630 {
1631 if (num_suffixes == MAX_SUFFIXES)
bd3ba5d1 1632 as_bad (_("too many suffixes"));
ea1562b3
NC
1633 else
1634 insn_suffixes[num_suffixes++] = suffix;
1635 }
1636 }
1637 else
1638 /* This is either a register or an expression of some kind. */
1639 {
1640 char *hold;
1641 const struct arc_operand_value *reg = NULL;
1642 long value = 0;
1643 expressionS exp;
1644
1645 if (operand->flags & ARC_OPERAND_SUFFIX)
1646 abort ();
1647
1648 /* Is there anything left to parse?
1649 We don't check for this at the top because we want to parse
1650 any trailing fake arguments in the syntax string. */
1651 if (is_end_of_line[(unsigned char) *str])
1652 break;
1653
1654 /* Parse the operand. */
1655 hold = input_line_pointer;
1656 input_line_pointer = str;
1657 expression (&exp);
1658 str = input_line_pointer;
1659 input_line_pointer = hold;
1660
1661 if (exp.X_op == O_illegal)
bd3ba5d1 1662 as_bad (_("illegal operand"));
ea1562b3 1663 else if (exp.X_op == O_absent)
bd3ba5d1 1664 as_bad (_("missing operand"));
ea1562b3
NC
1665 else if (exp.X_op == O_constant)
1666 value = exp.X_add_number;
1667 else if (exp.X_op == O_register)
1668 reg = (struct arc_operand_value *) exp.X_add_number;
1669#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
1670 else if (IS_REG_DEST_OPERAND (*syn))
bd3ba5d1 1671 as_bad (_("symbol as destination register"));
ea1562b3
NC
1672 else
1673 {
1674 if (!strncmp (str, "@h30", 4))
1675 {
1676 arc_code_symbol (&exp);
1677 str += 4;
1678 }
1679 /* We need to generate a fixup for this expression. */
1680 if (fc >= MAX_FIXUPS)
bd3ba5d1 1681 as_fatal (_("too many fixups"));
ea1562b3
NC
1682 fixups[fc].exp = exp;
1683 /* We don't support shimm relocs. break here to force
1684 the assembler to output a limm. */
1685#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
1686 if (IS_REG_SHIMM_OFFSET (*syn))
1687 break;
1688 /* If this is a register constant (IE: one whose
1689 register value gets stored as 61-63) then this
1690 must be a limm. */
1691 /* ??? This bit could use some cleaning up.
1692 Referencing the format chars like this goes
1693 against style. */
1694 if (IS_SYMBOL_OPERAND (*syn))
1695 {
1696 const char *junk;
1697 limm_reloc_p = 1;
1698 /* Save this, we don't yet know what reloc to use. */
1699 fix_up_at = fc;
1700 /* Tell insert_reg we need a limm. This is
1701 needed because the value at this point is
1702 zero, a shimm. */
1703 /* ??? We need a cleaner interface than this. */
1704 (*arc_operands[arc_operand_map['Q']].insert)
1705 (insn, operand, mods, reg, 0L, &junk);
1706 }
1707 else
1708 fixups[fc].opindex = arc_operand_map[(int) *syn];
1709 ++fc;
1710 value = 0;
1711 }
1712
1713 /* Insert the register or expression into the instruction. */
1714 if (operand->insert)
1715 {
1716 const char *errmsg = NULL;
1717 insn = (*operand->insert) (insn, operand, mods,
1718 reg, (long) value, &errmsg);
1719 if (errmsg != (const char *) NULL)
1720 {
1721 last_errmsg = errmsg;
1722 if (operand->flags & ARC_OPERAND_ERROR)
1723 {
20203fb9 1724 as_bad ("%s", errmsg);
ea1562b3
NC
1725 return;
1726 }
1727 else if (operand->flags & ARC_OPERAND_WARN)
20203fb9 1728 as_warn ("%s", errmsg);
ea1562b3
NC
1729 break;
1730 }
1731 }
1732 else
1733 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
1734
1735 ++syn;
1736 }
1737 }
1738
1739 /* If we're at the end of the syntax string, we're done. */
1740 /* FIXME: try to move this to a separate function. */
1741 if (*syn == '\0')
1742 {
1743 int i;
1744 char *f;
1745 long limm, limm_p;
1746
1747 /* For the moment we assume a valid `str' can only contain blanks
1748 now. IE: We needn't try again with a longer version of the
1749 insn and it is assumed that longer versions of insns appear
1750 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1751
1752 while (ISSPACE (*str))
1753 ++str;
1754
1755 if (!is_end_of_line[(unsigned char) *str])
bd3ba5d1 1756 as_bad (_("junk at end of line: `%s'"), str);
ea1562b3
NC
1757
1758 /* Is there a limm value? */
1759 limm_p = arc_opcode_limm_p (&limm);
1760
1761 /* Perform various error and warning tests. */
1762
1763 {
1764 static int in_delay_slot_p = 0;
1765 static int prev_insn_needs_cc_nop_p = 0;
1766 /* delay slot type seen */
1767 int delay_slot_type = ARC_DELAY_NONE;
1768 /* conditional execution flag seen */
1769 int conditional = 0;
1770 /* 1 if condition codes are being set */
1771 int cc_set_p = 0;
1772 /* 1 if conditional branch, including `b' "branch always" */
1773 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
1774
1775 for (i = 0; i < num_suffixes; ++i)
1776 {
1777 switch (arc_operands[insn_suffixes[i]->type].fmt)
1778 {
1779 case 'n':
1780 delay_slot_type = insn_suffixes[i]->value;
1781 break;
1782 case 'q':
1783 conditional = insn_suffixes[i]->value;
1784 break;
1785 case 'f':
1786 cc_set_p = 1;
1787 break;
1788 }
1789 }
1790
1791 /* Putting an insn with a limm value in a delay slot is supposed to
1792 be legal, but let's warn the user anyway. Ditto for 8 byte
1793 jumps with delay slots. */
1794 if (in_delay_slot_p && limm_p)
bd3ba5d1 1795 as_warn (_("8 byte instruction in delay slot"));
ea1562b3
NC
1796 if (delay_slot_type != ARC_DELAY_NONE
1797 && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
bd3ba5d1 1798 as_warn (_("8 byte jump instruction with delay slot"));
ea1562b3
NC
1799 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
1800
1801 /* Warn when a conditional branch immediately follows a set of
1802 the condition codes. Note that this needn't be done if the
1803 insn that sets the condition codes uses a limm. */
1804 if (cond_branch_p && conditional != 0 /* 0 = "always" */
1805 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
bd3ba5d1 1806 as_warn (_("conditional branch follows set of flags"));
ea1562b3
NC
1807 prev_insn_needs_cc_nop_p =
1808 /* FIXME: ??? not required:
1809 (delay_slot_type != ARC_DELAY_NONE) && */
1810 cc_set_p && !limm_p;
1811 }
1812
1813 /* Write out the instruction.
1814 It is important to fetch enough space in one call to `frag_more'.
1815 We use (f - frag_now->fr_literal) to compute where we are and we
1816 don't want frag_now to change between calls. */
1817 if (limm_p)
1818 {
1819 f = frag_more (8);
1820 md_number_to_chars (f, insn, 4);
1821 md_number_to_chars (f + 4, limm, 4);
1822 dwarf2_emit_insn (8);
1823 }
1824 else if (limm_reloc_p)
1825 /* We need a limm reloc, but the tables think we don't. */
1826 abort ();
1827 else
1828 {
1829 f = frag_more (4);
1830 md_number_to_chars (f, insn, 4);
1831 dwarf2_emit_insn (4);
1832 }
1833
1834 /* Create any fixups. */
1835 for (i = 0; i < fc; ++i)
1836 {
1837 int op_type, reloc_type;
1838 expressionS exptmp;
1839 const struct arc_operand *operand;
1840
1841 /* Create a fixup for this operand.
1842 At this point we do not use a bfd_reloc_code_real_type for
1843 operands residing in the insn, but instead just use the
1844 operand index. This lets us easily handle fixups for any
1845 operand type, although that is admittedly not a very exciting
55cf6793 1846 feature. We pick a BFD reloc type in md_apply_fix.
ea1562b3
NC
1847
1848 Limm values (4 byte immediate "constants") must be treated
1849 normally because they're not part of the actual insn word
1850 and thus the insertion routines don't handle them. */
1851
1852 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
1853 {
1854 /* Modify the fixup addend as required by the cpu. */
1855 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
1856 op_type = fixups[i].opindex;
1857 /* FIXME: can we add this data to the operand table? */
1858 if (op_type == arc_operand_map['L']
1859 || op_type == arc_operand_map['s']
1860 || op_type == arc_operand_map['o']
1861 || op_type == arc_operand_map['O'])
1862 reloc_type = BFD_RELOC_32;
1863 else if (op_type == arc_operand_map['J'])
1864 reloc_type = BFD_RELOC_ARC_B26;
1865 else
1866 abort ();
1867 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
1868 &fixups[i].exp,
1869 &exptmp);
1870 }
1871 else
1872 {
1873 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
1874 &fixups[i].exp, &exptmp);
1875 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
1876 }
1877 operand = &arc_operands[op_type];
1878 fix_new_exp (frag_now,
1879 ((f - frag_now->fr_literal)
1880 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
1881 &exptmp,
1882 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
1883 (bfd_reloc_code_real_type) reloc_type);
1884 }
1885 return;
1886 }
1887 }
1888
1889 if (NULL == last_errmsg)
bd3ba5d1 1890 as_bad (_("bad instruction `%s'"), start);
ea1562b3 1891 else
20203fb9 1892 as_bad ("%s", last_errmsg);
ea1562b3 1893}
This page took 0.792712 seconds and 4 git commands to generate.