40ba0ad18fa41a6e699f4f54d09c6fd7e28444b6
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
3
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23 #include "as.h"
24 #include "subsegs.h"
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "safe-ctype.h"
28
29 #include "opcode/arc.h"
30 #include "elf/arc.h"
31
32 /* Defines section. */
33
34 #define MAX_FLAG_NAME_LENGHT 3
35 #define MAX_INSN_FIXUPS 2
36 #define MAX_CONSTR_STR 20
37
38 #ifdef DEBUG
39 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
40 #else
41 # define pr_debug(fmt, args...)
42 #endif
43
44 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
45 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
46 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
47 (SUB_OPCODE (x) == 0x28))
48
49 /* Equal to MAX_PRECISION in atof-ieee.c. */
50 #define MAX_LITTLENUMS 6
51
52 /* Macros section. */
53
54 #define regno(x) ((x) & 0x3F)
55 #define is_ir_num(x) (((x) & ~0x3F) == 0)
56 #define is_code_density_p(op) (((op)->subclass == CD1 || (op)->subclass == CD2))
57 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
58 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
59
60 /* Generic assembler global variables which must be defined by all
61 targets. */
62
63 /* Characters which always start a comment. */
64 const char comment_chars[] = "#;";
65
66 /* Characters which start a comment at the beginning of a line. */
67 const char line_comment_chars[] = "#";
68
69 /* Characters which may be used to separate multiple commands on a
70 single line. */
71 const char line_separator_chars[] = "`";
72
73 /* Characters which are used to indicate an exponent in a floating
74 point number. */
75 const char EXP_CHARS[] = "eE";
76
77 /* Chars that mean this number is a floating point constant
78 As in 0f12.456 or 0d1.2345e12. */
79 const char FLT_CHARS[] = "rRsSfFdD";
80
81 /* Byte order. */
82 extern int target_big_endian;
83 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
84 static int byte_order = DEFAULT_BYTE_ORDER;
85
86 extern int arc_get_mach (char *);
87
88 /* Forward declaration. */
89 static void arc_lcomm (int);
90 static void arc_option (int);
91 static void arc_extra_reloc (int);
92
93 const pseudo_typeS md_pseudo_table[] =
94 {
95 /* Make sure that .word is 32 bits. */
96 { "word", cons, 4 },
97
98 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
99 { "lcomm", arc_lcomm, 0 },
100 { "lcommon", arc_lcomm, 0 },
101 { "cpu", arc_option, 0 },
102
103 { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
104 { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
105
106 { NULL, NULL, 0 }
107 };
108
109 const char *md_shortopts = "";
110
111 enum options
112 {
113 OPTION_EB = OPTION_MD_BASE,
114 OPTION_EL,
115
116 OPTION_ARC600,
117 OPTION_ARC601,
118 OPTION_ARC700,
119 OPTION_ARCEM,
120 OPTION_ARCHS,
121
122 OPTION_MCPU,
123 OPTION_CD,
124
125 /* The following options are deprecated and provided here only for
126 compatibility reasons. */
127 OPTION_USER_MODE,
128 OPTION_LD_EXT_MASK,
129 OPTION_SWAP,
130 OPTION_NORM,
131 OPTION_BARREL_SHIFT,
132 OPTION_MIN_MAX,
133 OPTION_NO_MPY,
134 OPTION_EA,
135 OPTION_MUL64,
136 OPTION_SIMD,
137 OPTION_SPFP,
138 OPTION_DPFP,
139 OPTION_XMAC_D16,
140 OPTION_XMAC_24,
141 OPTION_DSP_PACKA,
142 OPTION_CRC,
143 OPTION_DVBF,
144 OPTION_TELEPHONY,
145 OPTION_XYMEMORY,
146 OPTION_LOCK,
147 OPTION_SWAPE,
148 OPTION_RTSC,
149 OPTION_FPUDA
150 };
151
152 struct option md_longopts[] =
153 {
154 { "EB", no_argument, NULL, OPTION_EB },
155 { "EL", no_argument, NULL, OPTION_EL },
156 { "mcpu", required_argument, NULL, OPTION_MCPU },
157 { "mA6", no_argument, NULL, OPTION_ARC600 },
158 { "mARC600", no_argument, NULL, OPTION_ARC600 },
159 { "mARC601", no_argument, NULL, OPTION_ARC601 },
160 { "mARC700", no_argument, NULL, OPTION_ARC700 },
161 { "mA7", no_argument, NULL, OPTION_ARC700 },
162 { "mEM", no_argument, NULL, OPTION_ARCEM },
163 { "mHS", no_argument, NULL, OPTION_ARCHS },
164 { "mcode-density", no_argument, NULL, OPTION_CD },
165
166 /* The following options are deprecated and provided here only for
167 compatibility reasons. */
168 { "mav2em", no_argument, NULL, OPTION_ARCEM },
169 { "mav2hs", no_argument, NULL, OPTION_ARCHS },
170 { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
171 { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
172 { "mswap", no_argument, NULL, OPTION_SWAP },
173 { "mnorm", no_argument, NULL, OPTION_NORM },
174 { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
175 { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
176 { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
177 { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
178 { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
179 { "mea", no_argument, NULL, OPTION_EA },
180 { "mEA", no_argument, NULL, OPTION_EA },
181 { "mmul64", no_argument, NULL, OPTION_MUL64 },
182 { "msimd", no_argument, NULL, OPTION_SIMD},
183 { "mspfp", no_argument, NULL, OPTION_SPFP},
184 { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
185 { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
186 { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
187 { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
188 { "mdpfp", no_argument, NULL, OPTION_DPFP},
189 { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
190 { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
191 { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
192 { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
193 { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
194 { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
195 { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
196 { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
197 { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
198 { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
199 { "mcrc", no_argument, NULL, OPTION_CRC},
200 { "mdvbf", no_argument, NULL, OPTION_DVBF},
201 { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
202 { "mxy", no_argument, NULL, OPTION_XYMEMORY},
203 { "mlock", no_argument, NULL, OPTION_LOCK},
204 { "mswape", no_argument, NULL, OPTION_SWAPE},
205 { "mrtsc", no_argument, NULL, OPTION_RTSC},
206 { "mfpuda", no_argument, NULL, OPTION_FPUDA},
207
208 { NULL, no_argument, NULL, 0 }
209 };
210
211 size_t md_longopts_size = sizeof (md_longopts);
212
213 /* Local data and data types. */
214
215 /* Used since new relocation types are introduced in this
216 file (DUMMY_RELOC_LITUSE_*). */
217 typedef int extended_bfd_reloc_code_real_type;
218
219 struct arc_fixup
220 {
221 expressionS exp;
222
223 extended_bfd_reloc_code_real_type reloc;
224
225 /* index into arc_operands. */
226 unsigned int opindex;
227
228 /* PC-relative, used by internals fixups. */
229 unsigned char pcrel;
230
231 /* TRUE if this fixup is for LIMM operand. */
232 bfd_boolean islong;
233 };
234
235 struct arc_insn
236 {
237 unsigned int insn;
238 int nfixups;
239 struct arc_fixup fixups[MAX_INSN_FIXUPS];
240 long limm;
241 bfd_boolean short_insn; /* Boolean value: TRUE if current insn is
242 short. */
243 bfd_boolean has_limm; /* Boolean value: TRUE if limm field is
244 valid. */
245 };
246
247 /* Structure to hold any last two instructions. */
248 static struct arc_last_insn
249 {
250 /* Saved instruction opcode. */
251 const struct arc_opcode *opcode;
252
253 /* Boolean value: TRUE if current insn is short. */
254 bfd_boolean has_limm;
255
256 /* Boolean value: TRUE if current insn has delay slot. */
257 bfd_boolean has_delay_slot;
258 } arc_last_insns[2];
259
260 /* The cpu for which we are generating code. */
261 static unsigned arc_target = ARC_OPCODE_BASE;
262 static const char *arc_target_name = "<all>";
263 static unsigned arc_features = 0x00;
264
265 /* The default architecture. */
266 static int arc_mach_type = bfd_mach_arc_arcv2;
267
268 /* Non-zero if the cpu type has been explicitly specified. */
269 static int mach_type_specified_p = 0;
270
271 /* The hash table of instruction opcodes. */
272 static struct hash_control *arc_opcode_hash;
273
274 /* The hash table of register symbols. */
275 static struct hash_control *arc_reg_hash;
276
277 /* A table of CPU names and opcode sets. */
278 static const struct cpu_type
279 {
280 const char *name;
281 unsigned flags;
282 int mach;
283 unsigned eflags;
284 unsigned features;
285 }
286 cpu_types[] =
287 {
288 { "arc600", ARC_OPCODE_ARC600, bfd_mach_arc_arc600,
289 E_ARC_MACH_ARC600, 0x00},
290 { "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700,
291 E_ARC_MACH_ARC700, 0x00},
292 { "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
293 EF_ARC_CPU_ARCV2EM, 0x00},
294 { "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
295 EF_ARC_CPU_ARCV2HS, ARC_CD},
296 { "all", ARC_OPCODE_BASE, bfd_mach_arc_arcv2,
297 0x00, 0x00 },
298 { 0, 0, 0, 0, 0 }
299 };
300
301 struct arc_flags
302 {
303 /* Name of the parsed flag. */
304 char name[MAX_FLAG_NAME_LENGHT+1];
305
306 /* The code of the parsed flag. Valid when is not zero. */
307 unsigned char code;
308 };
309
310 /* Used by the arc_reloc_op table. Order is important. */
311 #define O_gotoff O_md1 /* @gotoff relocation. */
312 #define O_gotpc O_md2 /* @gotpc relocation. */
313 #define O_plt O_md3 /* @plt relocation. */
314 #define O_sda O_md4 /* @sda relocation. */
315 #define O_pcl O_md5 /* @pcl relocation. */
316 #define O_tlsgd O_md6 /* @tlsgd relocation. */
317 #define O_tlsie O_md7 /* @tlsie relocation. */
318 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
319 #define O_tpoff O_md9 /* @tpoff relocation. */
320 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
321 #define O_dtpoff O_md11 /* @dtpoff relocation. */
322 #define O_last O_dtpoff
323
324 /* Used to define a bracket as operand in tokens. */
325 #define O_bracket O_md32
326
327 /* Dummy relocation, to be sorted out. */
328 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
329
330 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
331
332 /* A table to map the spelling of a relocation operand into an appropriate
333 bfd_reloc_code_real_type type. The table is assumed to be ordered such
334 that op-O_literal indexes into it. */
335 #define ARC_RELOC_TABLE(op) \
336 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
337 ? (abort (), 0) \
338 : (int) (op) - (int) O_gotoff) ])
339
340 #define DEF(NAME, RELOC, REQ) \
341 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
342
343 static const struct arc_reloc_op_tag
344 {
345 /* String to lookup. */
346 const char *name;
347 /* Size of the string. */
348 size_t length;
349 /* Which operator to use. */
350 operatorT op;
351 extended_bfd_reloc_code_real_type reloc;
352 /* Allows complex relocation expression like identifier@reloc +
353 const. */
354 unsigned int complex_expr : 1;
355 }
356 arc_reloc_op[] =
357 {
358 DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
359 DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
360 DEF (plt, BFD_RELOC_ARC_PLT32, 0),
361 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
362 DEF (pcl, BFD_RELOC_ARC_PC32, 1),
363 DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
364 DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
365 DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
366 DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 0),
367 DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
368 DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0),
369 };
370
371 static const int arc_num_reloc_op
372 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
373
374 /* Flags to set in the elf header. */
375 static flagword arc_eflag = 0x00;
376
377 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
378 symbolS * GOT_symbol = 0;
379
380 /* Set to TRUE when we assemble instructions. */
381 static bfd_boolean assembling_insn = FALSE;
382
383 /* Functions declaration. */
384
385 static void assemble_tokens (const char *, expressionS *, int,
386 struct arc_flags *, int);
387 static const struct arc_opcode *find_opcode_match (const struct arc_opcode *,
388 expressionS *, int *,
389 struct arc_flags *,
390 int, int *);
391 static void assemble_insn (const struct arc_opcode *, const expressionS *,
392 int, const struct arc_flags *, int,
393 struct arc_insn *);
394 static void emit_insn (struct arc_insn *);
395 static unsigned insert_operand (unsigned, const struct arc_operand *,
396 offsetT, char *, unsigned);
397 static const struct arc_opcode *find_special_case_flag (const char *,
398 int *,
399 struct arc_flags *);
400 static const struct arc_opcode *find_special_case (const char *,
401 int *,
402 struct arc_flags *,
403 expressionS *, int *);
404 static const struct arc_opcode *find_special_case_pseudo (const char *,
405 int *,
406 expressionS *,
407 int *,
408 struct arc_flags *);
409
410 /* Functions implementation. */
411
412 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
413 is encoded as 'middle-endian' for a little-endian target. FIXME!
414 this function is used for regular 4 byte instructions as well. */
415
416 static void
417 md_number_to_chars_midend (char *buf, valueT val, int n)
418 {
419 if (n == 4)
420 {
421 md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2);
422 md_number_to_chars (buf + 2, (val & 0xffff), 2);
423 }
424 else
425 {
426 md_number_to_chars (buf, val, n);
427 }
428 }
429
430 /* Here ends all the ARCompact extension instruction assembling
431 stuff. */
432
433 static void
434 arc_extra_reloc (int r_type)
435 {
436 char *sym_name, c;
437 symbolS *sym, *lab = NULL;
438
439 if (*input_line_pointer == '@')
440 input_line_pointer++;
441 c = get_symbol_name (&sym_name);
442 sym = symbol_find_or_make (sym_name);
443 restore_line_pointer (c);
444 if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
445 {
446 ++input_line_pointer;
447 char *lab_name;
448 c = get_symbol_name (&lab_name);
449 lab = symbol_find_or_make (lab_name);
450 restore_line_pointer (c);
451 }
452 fixS *fixP
453 = fix_new (frag_now, /* Which frag? */
454 frag_now_fix (), /* Where in that frag? */
455 2, /* size: 1, 2, or 4 usually. */
456 sym, /* X_add_symbol. */
457 0, /* X_add_number. */
458 FALSE, /* TRUE if PC-relative relocation. */
459 r_type /* Relocation type. */);
460 fixP->fx_subsy = lab;
461 }
462
463 static symbolS *
464 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
465 symbolS *symbolP, addressT size)
466 {
467 addressT align = 0;
468 SKIP_WHITESPACE ();
469
470 if (*input_line_pointer == ',')
471 {
472 align = parse_align (1);
473
474 if (align == (addressT) -1)
475 return NULL;
476 }
477 else
478 {
479 if (size >= 8)
480 align = 3;
481 else if (size >= 4)
482 align = 2;
483 else if (size >= 2)
484 align = 1;
485 else
486 align = 0;
487 }
488
489 bss_alloc (symbolP, size, align);
490 S_CLEAR_EXTERNAL (symbolP);
491
492 return symbolP;
493 }
494
495 static void
496 arc_lcomm (int ignore)
497 {
498 symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
499
500 if (symbolP)
501 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
502 }
503
504 /* Select the cpu we're assembling for. */
505
506 static void
507 arc_option (int ignore ATTRIBUTE_UNUSED)
508 {
509 int mach = -1;
510 char c;
511 char *cpu;
512
513 c = get_symbol_name (&cpu);
514 mach = arc_get_mach (cpu);
515
516 if (mach == -1)
517 goto bad_cpu;
518
519 if (!mach_type_specified_p)
520 {
521 if ((!strcmp ("ARC600", cpu))
522 || (!strcmp ("ARC601", cpu))
523 || (!strcmp ("A6", cpu)))
524 {
525 md_parse_option (OPTION_MCPU, "arc600");
526 }
527 else if ((!strcmp ("ARC700", cpu))
528 || (!strcmp ("A7", cpu)))
529 {
530 md_parse_option (OPTION_MCPU, "arc700");
531 }
532 else if (!strcmp ("EM", cpu))
533 {
534 md_parse_option (OPTION_MCPU, "arcem");
535 }
536 else if (!strcmp ("HS", cpu))
537 {
538 md_parse_option (OPTION_MCPU, "archs");
539 }
540 else
541 as_fatal ("could not find the architecture");
542
543 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
544 as_fatal ("could not set architecture and machine");
545 }
546 else
547 if (arc_mach_type != mach)
548 as_warn ("Command-line value overrides \".cpu\" directive");
549
550 restore_line_pointer (c);
551 demand_empty_rest_of_line ();
552 return;
553
554 bad_cpu:
555 restore_line_pointer (c);
556 as_bad ("invalid identifier for \".cpu\"");
557 ignore_rest_of_line ();
558 }
559
560 /* Smartly print an expression. */
561
562 static void
563 debug_exp (expressionS *t)
564 {
565 const char *name ATTRIBUTE_UNUSED;
566 const char *namemd ATTRIBUTE_UNUSED;
567
568 pr_debug ("debug_exp: ");
569
570 switch (t->X_op)
571 {
572 default: name = "unknown"; break;
573 case O_illegal: name = "O_illegal"; break;
574 case O_absent: name = "O_absent"; break;
575 case O_constant: name = "O_constant"; break;
576 case O_symbol: name = "O_symbol"; break;
577 case O_symbol_rva: name = "O_symbol_rva"; break;
578 case O_register: name = "O_register"; break;
579 case O_big: name = "O_big"; break;
580 case O_uminus: name = "O_uminus"; break;
581 case O_bit_not: name = "O_bit_not"; break;
582 case O_logical_not: name = "O_logical_not"; break;
583 case O_multiply: name = "O_multiply"; break;
584 case O_divide: name = "O_divide"; break;
585 case O_modulus: name = "O_modulus"; break;
586 case O_left_shift: name = "O_left_shift"; break;
587 case O_right_shift: name = "O_right_shift"; break;
588 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
589 case O_bit_or_not: name = "O_bit_or_not"; break;
590 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
591 case O_bit_and: name = "O_bit_and"; break;
592 case O_add: name = "O_add"; break;
593 case O_subtract: name = "O_subtract"; break;
594 case O_eq: name = "O_eq"; break;
595 case O_ne: name = "O_ne"; break;
596 case O_lt: name = "O_lt"; break;
597 case O_le: name = "O_le"; break;
598 case O_ge: name = "O_ge"; break;
599 case O_gt: name = "O_gt"; break;
600 case O_logical_and: name = "O_logical_and"; break;
601 case O_logical_or: name = "O_logical_or"; break;
602 case O_index: name = "O_index"; break;
603 case O_bracket: name = "O_bracket"; break;
604 }
605
606 switch (t->X_md)
607 {
608 default: namemd = "unknown"; break;
609 case O_gotoff: namemd = "O_gotoff"; break;
610 case O_gotpc: namemd = "O_gotpc"; break;
611 case O_plt: namemd = "O_plt"; break;
612 case O_sda: namemd = "O_sda"; break;
613 case O_pcl: namemd = "O_pcl"; break;
614 case O_tlsgd: namemd = "O_tlsgd"; break;
615 case O_tlsie: namemd = "O_tlsie"; break;
616 case O_tpoff9: namemd = "O_tpoff9"; break;
617 case O_tpoff: namemd = "O_tpoff"; break;
618 case O_dtpoff9: namemd = "O_dtpoff9"; break;
619 case O_dtpoff: namemd = "O_dtpoff"; break;
620 }
621
622 pr_debug ("%s (%s, %s, %d, %s)", name,
623 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
624 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
625 (int) t->X_add_number,
626 (t->X_md) ? namemd : "--");
627 pr_debug ("\n");
628 fflush (stderr);
629 }
630
631 /* Parse the arguments to an opcode. */
632
633 static int
634 tokenize_arguments (char *str,
635 expressionS *tok,
636 int ntok)
637 {
638 char *old_input_line_pointer;
639 bfd_boolean saw_comma = FALSE;
640 bfd_boolean saw_arg = FALSE;
641 int brk_lvl = 0;
642 int num_args = 0;
643 int i;
644 size_t len;
645 const struct arc_reloc_op_tag *r;
646 expressionS tmpE;
647 char *reloc_name, c;
648
649 memset (tok, 0, sizeof (*tok) * ntok);
650
651 /* Save and restore input_line_pointer around this function. */
652 old_input_line_pointer = input_line_pointer;
653 input_line_pointer = str;
654
655 while (*input_line_pointer)
656 {
657 SKIP_WHITESPACE ();
658 switch (*input_line_pointer)
659 {
660 case '\0':
661 goto fini;
662
663 case ',':
664 input_line_pointer++;
665 if (saw_comma || !saw_arg)
666 goto err;
667 saw_comma = TRUE;
668 break;
669
670 case '}':
671 case ']':
672 ++input_line_pointer;
673 --brk_lvl;
674 if (!saw_arg)
675 goto err;
676 tok->X_op = O_bracket;
677 ++tok;
678 ++num_args;
679 break;
680
681 case '{':
682 case '[':
683 input_line_pointer++;
684 if (brk_lvl)
685 goto err;
686 ++brk_lvl;
687 tok->X_op = O_bracket;
688 ++tok;
689 ++num_args;
690 break;
691
692 case '@':
693 /* We have labels, function names and relocations, all
694 starting with @ symbol. Sort them out. */
695 if (saw_arg && !saw_comma)
696 goto err;
697
698 /* Parse @label. */
699 tok->X_op = O_symbol;
700 tok->X_md = O_absent;
701 expression (tok);
702 if (*input_line_pointer != '@')
703 goto normalsymbol; /* This is not a relocation. */
704
705 relocationsym:
706
707 /* A relocation opernad has the following form
708 @identifier@relocation_type. The identifier is already
709 in tok! */
710 if (tok->X_op != O_symbol)
711 {
712 as_bad (_("No valid label relocation operand"));
713 goto err;
714 }
715
716 /* Parse @relocation_type. */
717 input_line_pointer++;
718 c = get_symbol_name (&reloc_name);
719 len = input_line_pointer - reloc_name;
720 if (len == 0)
721 {
722 as_bad (_("No relocation operand"));
723 goto err;
724 }
725
726 /* Go through known relocation and try to find a match. */
727 r = &arc_reloc_op[0];
728 for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
729 if (len == r->length
730 && memcmp (reloc_name, r->name, len) == 0)
731 break;
732 if (i < 0)
733 {
734 as_bad (_("Unknown relocation operand: @%s"), reloc_name);
735 goto err;
736 }
737
738 *input_line_pointer = c;
739 SKIP_WHITESPACE_AFTER_NAME ();
740 /* Extra check for TLS: base. */
741 if (*input_line_pointer == '@')
742 {
743 symbolS *base;
744 if (tok->X_op_symbol != NULL
745 || tok->X_op != O_symbol)
746 {
747 as_bad (_("Unable to parse TLS base: %s"),
748 input_line_pointer);
749 goto err;
750 }
751 input_line_pointer++;
752 char *sym_name;
753 c = get_symbol_name (&sym_name);
754 base = symbol_find_or_make (sym_name);
755 tok->X_op = O_subtract;
756 tok->X_op_symbol = base;
757 restore_line_pointer (c);
758 tmpE.X_add_number = 0;
759 }
760 else if ((*input_line_pointer != '+')
761 && (*input_line_pointer != '-'))
762 {
763 tmpE.X_add_number = 0;
764 }
765 else
766 {
767 /* Parse the constant of a complex relocation expression
768 like @identifier@reloc +/- const. */
769 if (! r->complex_expr)
770 {
771 as_bad (_("@%s is not a complex relocation."), r->name);
772 goto err;
773 }
774 expression (&tmpE);
775 if (tmpE.X_op != O_constant)
776 {
777 as_bad (_("Bad expression: @%s + %s."),
778 r->name, input_line_pointer);
779 goto err;
780 }
781 }
782
783 tok->X_md = r->op;
784 tok->X_add_number = tmpE.X_add_number;
785
786 debug_exp (tok);
787
788 saw_comma = FALSE;
789 saw_arg = TRUE;
790 tok++;
791 num_args++;
792 break;
793
794 case '%':
795 /* Can be a register. */
796 ++input_line_pointer;
797 /* Fall through. */
798 default:
799
800 if (saw_arg && !saw_comma)
801 goto err;
802
803 tok->X_op = O_absent;
804 tok->X_md = O_absent;
805 expression (tok);
806
807 /* Legacy: There are cases when we have
808 identifier@relocation_type, if it is the case parse the
809 relocation type as well. */
810 if (*input_line_pointer == '@')
811 goto relocationsym;
812
813 normalsymbol:
814 debug_exp (tok);
815
816 if (tok->X_op == O_illegal || tok->X_op == O_absent)
817 goto err;
818
819 saw_comma = FALSE;
820 saw_arg = TRUE;
821 tok++;
822 num_args++;
823 break;
824 }
825 }
826
827 fini:
828 if (saw_comma || brk_lvl)
829 goto err;
830 input_line_pointer = old_input_line_pointer;
831
832 return num_args;
833
834 err:
835 if (brk_lvl)
836 as_bad (_("Brackets in operand field incorrect"));
837 else if (saw_comma)
838 as_bad (_("extra comma"));
839 else if (!saw_arg)
840 as_bad (_("missing argument"));
841 else
842 as_bad (_("missing comma or colon"));
843 input_line_pointer = old_input_line_pointer;
844 return -1;
845 }
846
847 /* Parse the flags to a structure. */
848
849 static int
850 tokenize_flags (const char *str,
851 struct arc_flags flags[],
852 int nflg)
853 {
854 char *old_input_line_pointer;
855 bfd_boolean saw_flg = FALSE;
856 bfd_boolean saw_dot = FALSE;
857 int num_flags = 0;
858 size_t flgnamelen;
859
860 memset (flags, 0, sizeof (*flags) * nflg);
861
862 /* Save and restore input_line_pointer around this function. */
863 old_input_line_pointer = input_line_pointer;
864 input_line_pointer = (char *) str;
865
866 while (*input_line_pointer)
867 {
868 switch (*input_line_pointer)
869 {
870 case ' ':
871 case '\0':
872 goto fini;
873
874 case '.':
875 input_line_pointer++;
876 if (saw_dot)
877 goto err;
878 saw_dot = TRUE;
879 saw_flg = FALSE;
880 break;
881
882 default:
883 if (saw_flg && !saw_dot)
884 goto err;
885
886 if (num_flags >= nflg)
887 goto err;
888
889 flgnamelen = strspn (input_line_pointer, "abcdefghilmnopqrstvwxz");
890 if (flgnamelen > MAX_FLAG_NAME_LENGHT)
891 goto err;
892
893 memcpy (flags->name, input_line_pointer, flgnamelen);
894
895 input_line_pointer += flgnamelen;
896 flags++;
897 saw_dot = FALSE;
898 saw_flg = TRUE;
899 num_flags++;
900 break;
901 }
902 }
903
904 fini:
905 input_line_pointer = old_input_line_pointer;
906 return num_flags;
907
908 err:
909 if (saw_dot)
910 as_bad (_("extra dot"));
911 else if (!saw_flg)
912 as_bad (_("unrecognized flag"));
913 else
914 as_bad (_("failed to parse flags"));
915 input_line_pointer = old_input_line_pointer;
916 return -1;
917 }
918
919 /* The public interface to the instruction assembler. */
920
921 void
922 md_assemble (char *str)
923 {
924 char *opname;
925 expressionS tok[MAX_INSN_ARGS];
926 int ntok, nflg;
927 size_t opnamelen;
928 struct arc_flags flags[MAX_INSN_FLGS];
929
930 /* Split off the opcode. */
931 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
932 opname = xmalloc (opnamelen + 1);
933 memcpy (opname, str, opnamelen);
934 opname[opnamelen] = '\0';
935
936 /* Signalize we are assmbling the instructions. */
937 assembling_insn = TRUE;
938
939 /* Tokenize the flags. */
940 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
941 {
942 as_bad (_("syntax error"));
943 return;
944 }
945
946 /* Scan up to the end of the mnemonic which must end in space or end
947 of string. */
948 str += opnamelen;
949 for (; *str != '\0'; str++)
950 if (*str == ' ')
951 break;
952
953 /* Tokenize the rest of the line. */
954 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
955 {
956 as_bad (_("syntax error"));
957 return;
958 }
959
960 /* Finish it off. */
961 assemble_tokens (opname, tok, ntok, flags, nflg);
962 assembling_insn = FALSE;
963 }
964
965 /* Callback to insert a register into the hash table. */
966
967 static void
968 declare_register (char *name, int number)
969 {
970 const char *err;
971 symbolS *regS = symbol_create (name, reg_section,
972 number, &zero_address_frag);
973
974 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
975 if (err)
976 as_fatal ("Inserting \"%s\" into register table failed: %s",
977 name, err);
978 }
979
980 /* Construct symbols for each of the general registers. */
981
982 static void
983 declare_register_set (void)
984 {
985 int i;
986 for (i = 0; i < 64; ++i)
987 {
988 char name[7];
989
990 sprintf (name, "r%d", i);
991 declare_register (name, i);
992 if ((i & 0x01) == 0)
993 {
994 sprintf (name, "r%dr%d", i, i+1);
995 declare_register (name, i);
996 }
997 }
998 }
999
1000 /* Port-specific assembler initialization. This function is called
1001 once, at assembler startup time. */
1002
1003 void
1004 md_begin (void)
1005 {
1006 unsigned int i;
1007
1008 /* The endianness can be chosen "at the factory". */
1009 target_big_endian = byte_order == BIG_ENDIAN;
1010
1011 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
1012 as_warn (_("could not set architecture and machine"));
1013
1014 /* Set elf header flags. */
1015 bfd_set_private_flags (stdoutput, arc_eflag);
1016
1017 /* Set up a hash table for the instructions. */
1018 arc_opcode_hash = hash_new ();
1019 if (arc_opcode_hash == NULL)
1020 as_fatal (_("Virtual memory exhausted"));
1021
1022 /* Initialize the hash table with the insns. */
1023 for (i = 0; i < arc_num_opcodes;)
1024 {
1025 const char *name, *retval;
1026
1027 name = arc_opcodes[i].name;
1028 retval = hash_insert (arc_opcode_hash, name, (void *) &arc_opcodes[i]);
1029 if (retval)
1030 as_fatal (_("internal error: can't hash opcode '%s': %s"),
1031 name, retval);
1032
1033 while (++i < arc_num_opcodes
1034 && (arc_opcodes[i].name == name
1035 || !strcmp (arc_opcodes[i].name, name)))
1036 continue;
1037 }
1038
1039 /* Register declaration. */
1040 arc_reg_hash = hash_new ();
1041 if (arc_reg_hash == NULL)
1042 as_fatal (_("Virtual memory exhausted"));
1043
1044 declare_register_set ();
1045 declare_register ("gp", 26);
1046 declare_register ("fp", 27);
1047 declare_register ("sp", 28);
1048 declare_register ("ilink", 29);
1049 declare_register ("ilink1", 29);
1050 declare_register ("ilink2", 30);
1051 declare_register ("blink", 31);
1052
1053 declare_register ("mlo", 57);
1054 declare_register ("mmid", 58);
1055 declare_register ("mhi", 59);
1056
1057 declare_register ("acc1", 56);
1058 declare_register ("acc2", 57);
1059
1060 declare_register ("lp_count", 60);
1061 declare_register ("pcl", 63);
1062
1063 /* Initialize the last instructions. */
1064 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
1065 }
1066
1067 /* Write a value out to the object file, using the appropriate
1068 endianness. */
1069
1070 void
1071 md_number_to_chars (char *buf,
1072 valueT val,
1073 int n)
1074 {
1075 if (target_big_endian)
1076 number_to_chars_bigendian (buf, val, n);
1077 else
1078 number_to_chars_littleendian (buf, val, n);
1079 }
1080
1081 /* Round up a section size to the appropriate boundary. */
1082
1083 valueT
1084 md_section_align (segT segment,
1085 valueT size)
1086 {
1087 int align = bfd_get_section_alignment (stdoutput, segment);
1088
1089 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
1090 }
1091
1092 /* The location from which a PC relative jump should be calculated,
1093 given a PC relative reloc. */
1094
1095 long
1096 md_pcrel_from_section (fixS *fixP,
1097 segT sec)
1098 {
1099 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
1100
1101 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
1102
1103 if (fixP->fx_addsy != (symbolS *) NULL
1104 && (!S_IS_DEFINED (fixP->fx_addsy)
1105 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1106 {
1107 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
1108
1109 /* The symbol is undefined (or is defined but not in this section).
1110 Let the linker figure it out. */
1111 return 0;
1112 }
1113
1114 if ((int) fixP->fx_r_type < 0)
1115 {
1116 /* These are the "internal" relocations. Align them to
1117 32 bit boundary (PCL), for the moment. */
1118 base &= ~3;
1119 }
1120 else
1121 {
1122 switch (fixP->fx_r_type)
1123 {
1124 case BFD_RELOC_ARC_PC32:
1125 /* The hardware calculates relative to the start of the
1126 insn, but this relocation is relative to location of the
1127 LIMM, compensate. The base always needs to be
1128 substracted by 4 as we do not support this type of PCrel
1129 relocation for short instructions. */
1130 base -= 4;
1131 /* Fall through. */
1132 case BFD_RELOC_ARC_PLT32:
1133 case BFD_RELOC_ARC_S25H_PCREL_PLT:
1134 case BFD_RELOC_ARC_S21H_PCREL_PLT:
1135 case BFD_RELOC_ARC_S25W_PCREL_PLT:
1136 case BFD_RELOC_ARC_S21W_PCREL_PLT:
1137
1138 case BFD_RELOC_ARC_S21H_PCREL:
1139 case BFD_RELOC_ARC_S25H_PCREL:
1140 case BFD_RELOC_ARC_S13_PCREL:
1141 case BFD_RELOC_ARC_S21W_PCREL:
1142 case BFD_RELOC_ARC_S25W_PCREL:
1143 base &= ~3;
1144 break;
1145 default:
1146 as_bad_where (fixP->fx_file, fixP->fx_line,
1147 _("unhandled reloc %s in md_pcrel_from_section"),
1148 bfd_get_reloc_code_name (fixP->fx_r_type));
1149 break;
1150 }
1151 }
1152
1153 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
1154 fixP->fx_frag->fr_address, fixP->fx_where, base,
1155 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
1156 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
1157
1158 return base;
1159 }
1160
1161 /* Given a BFD relocation find the coresponding operand. */
1162
1163 static const struct arc_operand *
1164 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
1165 {
1166 unsigned i;
1167
1168 for (i = 0; i < arc_num_operands; i++)
1169 if (arc_operands[i].default_reloc == reloc)
1170 return &arc_operands[i];
1171 return NULL;
1172 }
1173
1174 /* Apply a fixup to the object code. At this point all symbol values
1175 should be fully resolved, and we attempt to completely resolve the
1176 reloc. If we can not do that, we determine the correct reloc code
1177 and put it back in the fixup. To indicate that a fixup has been
1178 eliminated, set fixP->fx_done. */
1179
1180 void
1181 md_apply_fix (fixS *fixP,
1182 valueT *valP,
1183 segT seg)
1184 {
1185 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1186 valueT value = *valP;
1187 unsigned insn = 0;
1188 symbolS *fx_addsy, *fx_subsy;
1189 offsetT fx_offset;
1190 segT add_symbol_segment = absolute_section;
1191 segT sub_symbol_segment = absolute_section;
1192 const struct arc_operand *operand = NULL;
1193 extended_bfd_reloc_code_real_type reloc;
1194
1195 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
1196 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
1197 ((int) fixP->fx_r_type < 0) ? "Internal":
1198 bfd_get_reloc_code_name (fixP->fx_r_type), value,
1199 fixP->fx_offset);
1200
1201 fx_addsy = fixP->fx_addsy;
1202 fx_subsy = fixP->fx_subsy;
1203 fx_offset = 0;
1204
1205 if (fx_addsy)
1206 {
1207 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
1208 }
1209
1210 if (fx_subsy
1211 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
1212 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
1213 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
1214 {
1215 resolve_symbol_value (fx_subsy);
1216 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
1217
1218 if (sub_symbol_segment == absolute_section)
1219 {
1220 /* The symbol is really a constant. */
1221 fx_offset -= S_GET_VALUE (fx_subsy);
1222 fx_subsy = NULL;
1223 }
1224 else
1225 {
1226 as_bad_where (fixP->fx_file, fixP->fx_line,
1227 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
1228 fx_addsy ? S_GET_NAME (fx_addsy) : "0",
1229 segment_name (add_symbol_segment),
1230 S_GET_NAME (fx_subsy),
1231 segment_name (sub_symbol_segment));
1232 return;
1233 }
1234 }
1235
1236 if (fx_addsy
1237 && !S_IS_WEAK (fx_addsy))
1238 {
1239 if (add_symbol_segment == seg
1240 && fixP->fx_pcrel)
1241 {
1242 value += S_GET_VALUE (fx_addsy);
1243 value -= md_pcrel_from_section (fixP, seg);
1244 fx_addsy = NULL;
1245 fixP->fx_pcrel = FALSE;
1246 }
1247 else if (add_symbol_segment == absolute_section)
1248 {
1249 value = fixP->fx_offset;
1250 fx_offset += S_GET_VALUE (fixP->fx_addsy);
1251 fx_addsy = NULL;
1252 fixP->fx_pcrel = FALSE;
1253 }
1254 }
1255
1256 if (!fx_addsy)
1257 fixP->fx_done = TRUE;
1258
1259 if (fixP->fx_pcrel)
1260 {
1261 if (fx_addsy
1262 && ((S_IS_DEFINED (fx_addsy)
1263 && S_GET_SEGMENT (fx_addsy) != seg)
1264 || S_IS_WEAK (fx_addsy)))
1265 value += md_pcrel_from_section (fixP, seg);
1266
1267 switch (fixP->fx_r_type)
1268 {
1269 case BFD_RELOC_ARC_32_ME:
1270 /* This is a pc-relative value in a LIMM. Adjust it to the
1271 address of the instruction not to the address of the
1272 LIMM. Note: it is not anylonger valid this afirmation as
1273 the linker consider ARC_PC32 a fixup to entire 64 bit
1274 insn. */
1275 fixP->fx_offset += fixP->fx_frag->fr_address;
1276 /* Fall through. */
1277 case BFD_RELOC_32:
1278 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
1279 /* Fall through. */
1280 case BFD_RELOC_ARC_PC32:
1281 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
1282 break;
1283 default:
1284 if ((int) fixP->fx_r_type < 0)
1285 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
1286 fixP->fx_r_type);
1287 break;
1288 }
1289 }
1290
1291 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
1292 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
1293 ((int) fixP->fx_r_type < 0) ? "Internal":
1294 bfd_get_reloc_code_name (fixP->fx_r_type), value,
1295 fixP->fx_offset);
1296
1297
1298 /* Now check for TLS relocations. */
1299 reloc = fixP->fx_r_type;
1300 switch (reloc)
1301 {
1302 case BFD_RELOC_ARC_TLS_DTPOFF:
1303 case BFD_RELOC_ARC_TLS_LE_32:
1304 fixP->fx_offset = 0;
1305 /* Fall through. */
1306 case BFD_RELOC_ARC_TLS_GD_GOT:
1307 case BFD_RELOC_ARC_TLS_IE_GOT:
1308 S_SET_THREAD_LOCAL (fixP->fx_addsy);
1309 break;
1310
1311 case BFD_RELOC_ARC_TLS_GD_LD:
1312 gas_assert (!fixP->fx_offset);
1313 if (fixP->fx_subsy)
1314 fixP->fx_offset
1315 = (S_GET_VALUE (fixP->fx_subsy)
1316 - fixP->fx_frag->fr_address- fixP->fx_where);
1317 fixP->fx_subsy = NULL;
1318 /* Fall through. */
1319 case BFD_RELOC_ARC_TLS_GD_CALL:
1320 /* These two relocs are there just to allow ld to change the tls
1321 model for this symbol, by patching the code. The offset -
1322 and scale, if any - will be installed by the linker. */
1323 S_SET_THREAD_LOCAL (fixP->fx_addsy);
1324 break;
1325
1326 case BFD_RELOC_ARC_TLS_LE_S9:
1327 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
1328 as_bad (_("TLS_*_S9 relocs are not supported yet"));
1329 break;
1330
1331 default:
1332 break;
1333 }
1334
1335 if (!fixP->fx_done)
1336 {
1337 return;
1338 }
1339
1340 /* Addjust the value if we have a constant. */
1341 value += fx_offset;
1342
1343 /* For hosts with longs bigger than 32-bits make sure that the top
1344 bits of a 32-bit negative value read in by the parser are set,
1345 so that the correct comparisons are made. */
1346 if (value & 0x80000000)
1347 value |= (-1L << 31);
1348
1349 reloc = fixP->fx_r_type;
1350 switch (reloc)
1351 {
1352 case BFD_RELOC_8:
1353 case BFD_RELOC_16:
1354 case BFD_RELOC_24:
1355 case BFD_RELOC_32:
1356 case BFD_RELOC_64:
1357 case BFD_RELOC_ARC_32_PCREL:
1358 md_number_to_chars (fixpos, value, fixP->fx_size);
1359 return;
1360
1361 case BFD_RELOC_ARC_GOTPC32:
1362 /* I cannot fix an GOTPC relocation because I need to relax it
1363 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
1364 as_bad (_("Unsupported operation on reloc"));
1365 return;
1366 case BFD_RELOC_ARC_GOTOFF:
1367 case BFD_RELOC_ARC_32_ME:
1368 case BFD_RELOC_ARC_PC32:
1369 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
1370 return;
1371
1372 case BFD_RELOC_ARC_PLT32:
1373 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
1374 return;
1375
1376 case BFD_RELOC_ARC_S25H_PCREL_PLT:
1377 reloc = BFD_RELOC_ARC_S25W_PCREL;
1378 goto solve_plt;
1379
1380 case BFD_RELOC_ARC_S21H_PCREL_PLT:
1381 reloc = BFD_RELOC_ARC_S21H_PCREL;
1382 goto solve_plt;
1383
1384 case BFD_RELOC_ARC_S25W_PCREL_PLT:
1385 reloc = BFD_RELOC_ARC_S25W_PCREL;
1386 goto solve_plt;
1387
1388 case BFD_RELOC_ARC_S21W_PCREL_PLT:
1389 reloc = BFD_RELOC_ARC_S21W_PCREL;
1390
1391 case BFD_RELOC_ARC_S25W_PCREL:
1392 case BFD_RELOC_ARC_S21W_PCREL:
1393 case BFD_RELOC_ARC_S21H_PCREL:
1394 case BFD_RELOC_ARC_S25H_PCREL:
1395 case BFD_RELOC_ARC_S13_PCREL:
1396 solve_plt:
1397 operand = find_operand_for_reloc (reloc);
1398 gas_assert (operand);
1399 break;
1400
1401 default:
1402 {
1403 if ((int) fixP->fx_r_type >= 0)
1404 as_fatal (_("unhandled relocation type %s"),
1405 bfd_get_reloc_code_name (fixP->fx_r_type));
1406
1407 /* The rest of these fixups needs to be completely resolved as
1408 constants. */
1409 if (fixP->fx_addsy != 0
1410 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1411 as_bad_where (fixP->fx_file, fixP->fx_line,
1412 _("non-absolute expression in constant field"));
1413
1414 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
1415 operand = &arc_operands[-(int) fixP->fx_r_type];
1416 break;
1417 }
1418 }
1419
1420 if (target_big_endian)
1421 {
1422 switch (fixP->fx_size)
1423 {
1424 case 4:
1425 insn = bfd_getb32 (fixpos);
1426 break;
1427 case 2:
1428 insn = bfd_getb16 (fixpos);
1429 break;
1430 default:
1431 as_bad_where (fixP->fx_file, fixP->fx_line,
1432 _("unknown fixup size"));
1433 }
1434 }
1435 else
1436 {
1437 insn = 0;
1438 switch (fixP->fx_size)
1439 {
1440 case 4:
1441 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
1442 break;
1443 case 2:
1444 insn = bfd_getl16 (fixpos);
1445 break;
1446 default:
1447 as_bad_where (fixP->fx_file, fixP->fx_line,
1448 _("unknown fixup size"));
1449 }
1450 }
1451
1452 insn = insert_operand (insn, operand, (offsetT) value,
1453 fixP->fx_file, fixP->fx_line);
1454
1455 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
1456 }
1457
1458 /* Prepare machine-dependent frags for relaxation.
1459
1460 Called just before relaxation starts. Any symbol that is now undefined
1461 will not become defined.
1462
1463 Return the correct fr_subtype in the frag.
1464
1465 Return the initial "guess for fr_var" to caller. The guess for fr_var
1466 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
1467 or fr_var contributes to our returned value.
1468
1469 Although it may not be explicit in the frag, pretend
1470 fr_var starts with a value. */
1471
1472 int
1473 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1474 segT segment ATTRIBUTE_UNUSED)
1475 {
1476 int growth = 4;
1477
1478 fragP->fr_var = 4;
1479 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
1480 fragP->fr_file, fragP->fr_line, growth);
1481
1482 as_fatal (_("md_estimate_size_before_relax\n"));
1483 return growth;
1484 }
1485
1486 /* Translate internal representation of relocation info to BFD target
1487 format. */
1488
1489 arelent *
1490 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1491 fixS *fixP)
1492 {
1493 arelent *reloc;
1494 bfd_reloc_code_real_type code;
1495
1496 reloc = (arelent *) xmalloc (sizeof (* reloc));
1497 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1498 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1499 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1500
1501 /* Make sure none of our internal relocations make it this far.
1502 They'd better have been fully resolved by this point. */
1503 gas_assert ((int) fixP->fx_r_type > 0);
1504
1505 code = fixP->fx_r_type;
1506
1507 /* if we have something like add gp, pcl,
1508 _GLOBAL_OFFSET_TABLE_@gotpc. */
1509 if (code == BFD_RELOC_ARC_GOTPC32
1510 && GOT_symbol
1511 && fixP->fx_addsy == GOT_symbol)
1512 code = BFD_RELOC_ARC_GOTPC;
1513
1514 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1515 if (reloc->howto == NULL)
1516 {
1517 as_bad_where (fixP->fx_file, fixP->fx_line,
1518 _("cannot represent `%s' relocation in object file"),
1519 bfd_get_reloc_code_name (code));
1520 return NULL;
1521 }
1522
1523 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
1524 as_fatal (_("internal error? cannot generate `%s' relocation"),
1525 bfd_get_reloc_code_name (code));
1526
1527 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1528
1529 if (code == BFD_RELOC_ARC_TLS_DTPOFF
1530 || code == BFD_RELOC_ARC_TLS_DTPOFF_S9)
1531 {
1532 asymbol *sym
1533 = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
1534 /* We just want to store a 24 bit index, but we have to wait
1535 till after write_contents has been called via
1536 bfd_map_over_sections before we can get the index from
1537 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
1538 function is elf32-arc.c has to pick up the slack.
1539 Unfortunately, this leads to problems with hosts that have
1540 pointers wider than long (bfd_vma). There would be various
1541 ways to handle this, all error-prone :-( */
1542 reloc->addend = (bfd_vma) sym;
1543 if ((asymbol *) reloc->addend != sym)
1544 {
1545 as_bad ("Can't store pointer\n");
1546 return NULL;
1547 }
1548 }
1549 else
1550 reloc->addend = fixP->fx_offset;
1551
1552 return reloc;
1553 }
1554
1555 /* Perform post-processing of machine-dependent frags after relaxation.
1556 Called after relaxation is finished.
1557 In: Address of frag.
1558 fr_type == rs_machine_dependent.
1559 fr_subtype is what the address relaxed to.
1560
1561 Out: Any fixS:s and constants are set up. */
1562
1563 void
1564 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1565 segT segment ATTRIBUTE_UNUSED,
1566 fragS *fragP ATTRIBUTE_UNUSED)
1567 {
1568 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
1569 fragP->fr_file, fragP->fr_line,
1570 fragP->fr_subtype, fragP->fr_fix, fragP->fr_var);
1571 abort ();
1572 }
1573
1574 /* We have no need to default values of symbols. We could catch
1575 register names here, but that is handled by inserting them all in
1576 the symbol table to begin with. */
1577
1578 symbolS *
1579 md_undefined_symbol (char *name)
1580 {
1581 /* The arc abi demands that a GOT[0] should be referencible as
1582 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
1583 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
1584 if (((*name == '_')
1585 && (*(name+1) == 'G')
1586 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
1587 || ((*name == '_')
1588 && (*(name+1) == 'D')
1589 && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
1590 {
1591 if (!GOT_symbol)
1592 {
1593 if (symbol_find (name))
1594 as_bad ("GOT already in symbol table");
1595
1596 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
1597 (valueT) 0, &zero_address_frag);
1598 };
1599 return GOT_symbol;
1600 }
1601 return NULL;
1602 }
1603
1604 /* Turn a string in input_line_pointer into a floating point constant
1605 of type type, and store the appropriate bytes in *litP. The number
1606 of LITTLENUMS emitted is stored in *sizeP. An error message is
1607 returned, or NULL on OK. */
1608
1609 char *
1610 md_atof (int type, char *litP, int *sizeP)
1611 {
1612 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1613 }
1614
1615 /* Called for any expression that can not be recognized. When the
1616 function is called, `input_line_pointer' will point to the start of
1617 the expression. */
1618
1619 void
1620 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1621 {
1622 char *p = input_line_pointer;
1623 if (*p == '@')
1624 {
1625 input_line_pointer++;
1626 expressionP->X_op = O_symbol;
1627 expression (expressionP);
1628 }
1629 }
1630
1631 /* This function is called from the function 'expression', it attempts
1632 to parse special names (in our case register names). It fills in
1633 the expression with the identified register. It returns TRUE if
1634 it is a register and FALSE otherwise. */
1635
1636 bfd_boolean
1637 arc_parse_name (const char *name,
1638 struct expressionS *e)
1639 {
1640 struct symbol *sym;
1641
1642 if (!assembling_insn)
1643 return FALSE;
1644
1645 /* Handle only registers. */
1646 if (e->X_op != O_absent)
1647 return FALSE;
1648
1649 sym = hash_find (arc_reg_hash, name);
1650 if (sym)
1651 {
1652 e->X_op = O_register;
1653 e->X_add_number = S_GET_VALUE (sym);
1654 return TRUE;
1655 }
1656 return FALSE;
1657 }
1658
1659 /* md_parse_option
1660 Invocation line includes a switch not recognized by the base assembler.
1661 See if it's a processor-specific option.
1662
1663 New options (supported) are:
1664
1665 -mcpu=<cpu name> Assemble for selected processor
1666 -EB/-mbig-endian Big-endian
1667 -EL/-mlittle-endian Little-endian
1668
1669 The following CPU names are recognized:
1670 arc700, av2em, av2hs. */
1671
1672 int
1673 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
1674 {
1675 int cpu_flags = EF_ARC_CPU_GENERIC;
1676
1677 switch (c)
1678 {
1679 case OPTION_ARC600:
1680 case OPTION_ARC601:
1681 return md_parse_option (OPTION_MCPU, "arc600");
1682
1683 case OPTION_ARC700:
1684 return md_parse_option (OPTION_MCPU, "arc700");
1685
1686 case OPTION_ARCEM:
1687 return md_parse_option (OPTION_MCPU, "arcem");
1688
1689 case OPTION_ARCHS:
1690 return md_parse_option (OPTION_MCPU, "archs");
1691
1692 case OPTION_MCPU:
1693 {
1694 int i;
1695 char *s = alloca (strlen (arg) + 1);
1696
1697 {
1698 char *t = s;
1699 char *arg1 = arg;
1700
1701 do
1702 *t = TOLOWER (*arg1++);
1703 while (*t++);
1704 }
1705
1706 for (i = 0; cpu_types[i].name; ++i)
1707 {
1708 if (!strcmp (cpu_types[i].name, s))
1709 {
1710 arc_target = cpu_types[i].flags;
1711 arc_target_name = cpu_types[i].name;
1712 arc_features = cpu_types[i].features;
1713 arc_mach_type = cpu_types[i].mach;
1714 cpu_flags = cpu_types[i].eflags;
1715
1716 mach_type_specified_p = 1;
1717 break;
1718 }
1719 }
1720
1721 if (!cpu_types[i].name)
1722 {
1723 as_fatal (_("unknown architecture: %s\n"), arg);
1724 }
1725 break;
1726 }
1727
1728 case OPTION_EB:
1729 arc_target_format = "elf32-bigarc";
1730 byte_order = BIG_ENDIAN;
1731 break;
1732
1733 case OPTION_EL:
1734 arc_target_format = "elf32-littlearc";
1735 byte_order = LITTLE_ENDIAN;
1736 break;
1737
1738 case OPTION_CD:
1739 /* This option has an effect only on ARC EM. */
1740 if (arc_target & ARC_OPCODE_ARCv2EM)
1741 arc_features |= ARC_CD;
1742 break;
1743
1744 case OPTION_USER_MODE:
1745 case OPTION_LD_EXT_MASK:
1746 case OPTION_SWAP:
1747 case OPTION_NORM:
1748 case OPTION_BARREL_SHIFT:
1749 case OPTION_MIN_MAX:
1750 case OPTION_NO_MPY:
1751 case OPTION_EA:
1752 case OPTION_MUL64:
1753 case OPTION_SIMD:
1754 case OPTION_SPFP:
1755 case OPTION_DPFP:
1756 case OPTION_XMAC_D16:
1757 case OPTION_XMAC_24:
1758 case OPTION_DSP_PACKA:
1759 case OPTION_CRC:
1760 case OPTION_DVBF:
1761 case OPTION_TELEPHONY:
1762 case OPTION_XYMEMORY:
1763 case OPTION_LOCK:
1764 case OPTION_SWAPE:
1765 case OPTION_RTSC:
1766 case OPTION_FPUDA:
1767 /* Dummy options are accepted but have no effect. */
1768 break;
1769
1770 default:
1771 return 0;
1772 }
1773
1774 if (cpu_flags != EF_ARC_CPU_GENERIC)
1775 arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
1776
1777 return 1;
1778 }
1779
1780 void
1781 md_show_usage (FILE *stream)
1782 {
1783 fprintf (stream, _("ARC-specific assembler options:\n"));
1784
1785 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
1786 fprintf (stream,
1787 " -mcode-density\t enable code density option for ARC EM\n");
1788
1789 fprintf (stream, _("\
1790 -EB assemble code for a big-endian cpu\n"));
1791 fprintf (stream, _("\
1792 -EL assemble code for a little-endian cpu\n"));
1793 }
1794
1795 static void
1796 preprocess_operands (const struct arc_opcode *opcode,
1797 expressionS *tok,
1798 int ntok)
1799 {
1800 int i;
1801 size_t len;
1802 const char *p;
1803 unsigned j;
1804 const struct arc_aux_reg *auxr;
1805
1806 for (i = 0; i < ntok; i++)
1807 {
1808 switch (tok[i].X_op)
1809 {
1810 case O_illegal:
1811 case O_absent:
1812 break; /* Throw and error. */
1813
1814 case O_symbol:
1815 if (opcode->class != AUXREG)
1816 break;
1817 /* Convert the symbol to a constant if possible. */
1818 p = S_GET_NAME (tok[i].X_add_symbol);
1819 len = strlen (p);
1820
1821 auxr = &arc_aux_regs[0];
1822 for (j = 0; j < arc_num_aux_regs; j++, auxr++)
1823 if (len == auxr->length
1824 && strcasecmp (auxr->name, p) == 0)
1825 {
1826 tok[i].X_op = O_constant;
1827 tok[i].X_add_number = auxr->address;
1828 break;
1829 }
1830 break;
1831 default:
1832 break;
1833 }
1834 }
1835 }
1836
1837 /* Given an opcode name, pre-tockenized set of argumenst and the
1838 opcode flags, take it all the way through emission. */
1839
1840 static void
1841 assemble_tokens (const char *opname,
1842 expressionS *tok,
1843 int ntok,
1844 struct arc_flags *pflags,
1845 int nflgs)
1846 {
1847 bfd_boolean found_something = FALSE;
1848 const struct arc_opcode *opcode;
1849 int cpumatch = 1;
1850
1851 /* Search opcodes. */
1852 opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname);
1853
1854 /* Couldn't find opcode conventional way, try special cases. */
1855 if (!opcode)
1856 opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
1857
1858 if (opcode)
1859 {
1860 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
1861 frag_now->fr_file, frag_now->fr_line, opcode->name,
1862 opcode->opcode);
1863
1864 preprocess_operands (opcode, tok, ntok);
1865
1866 found_something = TRUE;
1867 opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs, &cpumatch);
1868 if (opcode)
1869 {
1870 struct arc_insn insn;
1871 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
1872 emit_insn (&insn);
1873 return;
1874 }
1875 }
1876
1877 if (found_something)
1878 {
1879 if (cpumatch)
1880 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
1881 else
1882 as_bad (_("opcode '%s' not supported for target %s"), opname,
1883 arc_target_name);
1884 }
1885 else
1886 as_bad (_("unknown opcode '%s'"), opname);
1887 }
1888
1889 /* Used to find special case opcode. */
1890
1891 static const struct arc_opcode *
1892 find_special_case (const char *opname,
1893 int *nflgs,
1894 struct arc_flags *pflags,
1895 expressionS *tok,
1896 int *ntok)
1897 {
1898 const struct arc_opcode *opcode;
1899
1900 opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
1901
1902 if (opcode == NULL)
1903 opcode = find_special_case_flag (opname, nflgs, pflags);
1904
1905 return opcode;
1906 }
1907
1908 /* Swap operand tokens. */
1909
1910 static void
1911 swap_operand (expressionS *operand_array,
1912 unsigned source,
1913 unsigned destination)
1914 {
1915 expressionS cpy_operand;
1916 expressionS *src_operand;
1917 expressionS *dst_operand;
1918 size_t size;
1919
1920 if (source == destination)
1921 return;
1922
1923 src_operand = &operand_array[source];
1924 dst_operand = &operand_array[destination];
1925 size = sizeof (expressionS);
1926
1927 /* Make copy of operand to swap with and swap. */
1928 memcpy (&cpy_operand, dst_operand, size);
1929 memcpy (dst_operand, src_operand, size);
1930 memcpy (src_operand, &cpy_operand, size);
1931 }
1932
1933 /* Check if *op matches *tok type.
1934 Returns FALSE if they don't match, TRUE if they match. */
1935
1936 static bfd_boolean
1937 pseudo_operand_match (const expressionS *tok,
1938 const struct arc_operand_operation *op)
1939 {
1940 offsetT min, max, val;
1941 bfd_boolean ret;
1942 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1943
1944 ret = FALSE;
1945 switch (tok->X_op)
1946 {
1947 case O_constant:
1948 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1949 ret = 1;
1950 else if (!(operand_real->flags & ARC_OPERAND_IR))
1951 {
1952 val = tok->X_add_number + op->count;
1953 if (operand_real->flags & ARC_OPERAND_SIGNED)
1954 {
1955 max = (1 << (operand_real->bits - 1)) - 1;
1956 min = -(1 << (operand_real->bits - 1));
1957 }
1958 else
1959 {
1960 max = (1 << operand_real->bits) - 1;
1961 min = 0;
1962 }
1963 if (min <= val && val <= max)
1964 ret = TRUE;
1965 }
1966 break;
1967
1968 case O_symbol:
1969 /* Handle all symbols as long immediates or signed 9. */
1970 if (operand_real->flags & ARC_OPERAND_LIMM ||
1971 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1972 ret = TRUE;
1973 break;
1974
1975 case O_register:
1976 if (operand_real->flags & ARC_OPERAND_IR)
1977 ret = TRUE;
1978 break;
1979
1980 case O_bracket:
1981 if (operand_real->flags & ARC_OPERAND_BRAKET)
1982 ret = TRUE;
1983 break;
1984
1985 default:
1986 /* Unknown. */
1987 break;
1988 }
1989 return ret;
1990 }
1991
1992 /* Find pseudo instruction in array. */
1993
1994 static const struct arc_pseudo_insn *
1995 find_pseudo_insn (const char *opname,
1996 int ntok,
1997 const expressionS *tok)
1998 {
1999 const struct arc_pseudo_insn *pseudo_insn = NULL;
2000 const struct arc_operand_operation *op;
2001 unsigned int i;
2002 int j;
2003
2004 for (i = 0; i < arc_num_pseudo_insn; ++i)
2005 {
2006 pseudo_insn = &arc_pseudo_insns[i];
2007 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2008 {
2009 op = pseudo_insn->operand;
2010 for (j = 0; j < ntok; ++j)
2011 if (!pseudo_operand_match (&tok[j], &op[j]))
2012 break;
2013
2014 /* Found the right instruction. */
2015 if (j == ntok)
2016 return pseudo_insn;
2017 }
2018 }
2019 return NULL;
2020 }
2021
2022 /* Assumes the expressionS *tok is of sufficient size. */
2023
2024 static const struct arc_opcode *
2025 find_special_case_pseudo (const char *opname,
2026 int *ntok,
2027 expressionS *tok,
2028 int *nflgs,
2029 struct arc_flags *pflags)
2030 {
2031 const struct arc_pseudo_insn *pseudo_insn = NULL;
2032 const struct arc_operand_operation *operand_pseudo;
2033 const struct arc_operand *operand_real;
2034 unsigned i;
2035 char construct_operand[MAX_CONSTR_STR];
2036
2037 /* Find whether opname is in pseudo instruction array. */
2038 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2039
2040 if (pseudo_insn == NULL)
2041 return NULL;
2042
2043 /* Handle flag, Limited to one flag at the moment. */
2044 if (pseudo_insn->flag_r != NULL)
2045 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2046 MAX_INSN_FLGS - *nflgs);
2047
2048 /* Handle operand operations. */
2049 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2050 {
2051 operand_pseudo = &pseudo_insn->operand[i];
2052 operand_real = &arc_operands[operand_pseudo->operand_idx];
2053
2054 if (operand_real->flags & ARC_OPERAND_BRAKET &&
2055 !operand_pseudo->needs_insert)
2056 continue;
2057
2058 /* Has to be inserted (i.e. this token does not exist yet). */
2059 if (operand_pseudo->needs_insert)
2060 {
2061 if (operand_real->flags & ARC_OPERAND_BRAKET)
2062 {
2063 tok[i].X_op = O_bracket;
2064 ++(*ntok);
2065 continue;
2066 }
2067
2068 /* Check if operand is a register or constant and handle it
2069 by type. */
2070 if (operand_real->flags & ARC_OPERAND_IR)
2071 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2072 operand_pseudo->count);
2073 else
2074 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2075 operand_pseudo->count);
2076
2077 tokenize_arguments (construct_operand, &tok[i], 1);
2078 ++(*ntok);
2079 }
2080
2081 else if (operand_pseudo->count)
2082 {
2083 /* Operand number has to be adjusted accordingly (by operand
2084 type). */
2085 switch (tok[i].X_op)
2086 {
2087 case O_constant:
2088 tok[i].X_add_number += operand_pseudo->count;
2089 break;
2090
2091 case O_symbol:
2092 break;
2093
2094 default:
2095 /* Ignored. */
2096 break;
2097 }
2098 }
2099 }
2100
2101 /* Swap operands if necessary. Only supports one swap at the
2102 moment. */
2103 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2104 {
2105 operand_pseudo = &pseudo_insn->operand[i];
2106
2107 if (operand_pseudo->swap_operand_idx == i)
2108 continue;
2109
2110 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2111
2112 /* Prevent a swap back later by breaking out. */
2113 break;
2114 }
2115
2116 return (const struct arc_opcode *)
2117 hash_find (arc_opcode_hash, pseudo_insn->mnemonic_r);
2118 }
2119
2120 static const struct arc_opcode *
2121 find_special_case_flag (const char *opname,
2122 int *nflgs,
2123 struct arc_flags *pflags)
2124 {
2125 unsigned int i;
2126 const char *flagnm;
2127 unsigned flag_idx, flag_arr_idx;
2128 size_t flaglen, oplen;
2129 const struct arc_flag_special *arc_flag_special_opcode;
2130 const struct arc_opcode *opcode;
2131
2132 /* Search for special case instruction. */
2133 for (i = 0; i < arc_num_flag_special; i++)
2134 {
2135 arc_flag_special_opcode = &arc_flag_special_cases[i];
2136 oplen = strlen (arc_flag_special_opcode->name);
2137
2138 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2139 continue;
2140
2141 /* Found a potential special case instruction, now test for
2142 flags. */
2143 for (flag_arr_idx = 0;; ++flag_arr_idx)
2144 {
2145 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2146 if (flag_idx == 0)
2147 break; /* End of array, nothing found. */
2148
2149 flagnm = arc_flag_operands[flag_idx].name;
2150 flaglen = strlen (flagnm);
2151 if (strcmp (opname + oplen, flagnm) == 0)
2152 {
2153 opcode = (const struct arc_opcode *)
2154 hash_find (arc_opcode_hash,
2155 arc_flag_special_opcode->name);
2156
2157 if (*nflgs + 1 > MAX_INSN_FLGS)
2158 break;
2159 memcpy (pflags[*nflgs].name, flagnm, flaglen);
2160 pflags[*nflgs].name[flaglen] = '\0';
2161 (*nflgs)++;
2162 return opcode;
2163 }
2164 }
2165 }
2166 return NULL;
2167 }
2168
2169 /* Check whether a symbol involves a register. */
2170
2171 static int
2172 contains_register (symbolS *sym)
2173 {
2174 if (sym)
2175 {
2176 expressionS *ex = symbol_get_value_expression (sym);
2177 return ((O_register == ex->X_op)
2178 && !contains_register (ex->X_add_symbol)
2179 && !contains_register (ex->X_op_symbol));
2180 }
2181 else
2182 return 0;
2183 }
2184
2185 /* Returns the register number within a symbol. */
2186
2187 static int
2188 get_register (symbolS *sym)
2189 {
2190 if (!contains_register (sym))
2191 return -1;
2192
2193 expressionS *ex = symbol_get_value_expression (sym);
2194 return regno (ex->X_add_number);
2195 }
2196
2197 /* Allocates a tok entry. */
2198
2199 static int
2200 allocate_tok (expressionS *tok, int ntok, int cidx)
2201 {
2202 if (ntok > MAX_INSN_ARGS - 2)
2203 return 0; /* No space left. */
2204
2205 if (cidx > ntok)
2206 return 0; /* Incorect args. */
2207
2208 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
2209
2210 if (cidx == ntok)
2211 return 1; /* Success. */
2212 return allocate_tok (tok, ntok - 1, cidx);
2213 }
2214
2215 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
2216 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
2217
2218 static bfd_boolean
2219 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
2220 {
2221 if (!reloc)
2222 return FALSE;
2223
2224 switch (reloc)
2225 {
2226 case BFD_RELOC_ARC_SDA_LDST:
2227 case BFD_RELOC_ARC_SDA_LDST1:
2228 case BFD_RELOC_ARC_SDA_LDST2:
2229 case BFD_RELOC_ARC_SDA16_LD:
2230 case BFD_RELOC_ARC_SDA16_LD1:
2231 case BFD_RELOC_ARC_SDA16_LD2:
2232 case BFD_RELOC_ARC_SDA16_ST2:
2233 case BFD_RELOC_ARC_SDA32_ME:
2234 return FALSE;
2235 default:
2236 break;
2237 }
2238 return TRUE;
2239 }
2240
2241 /* Search forward through all variants of an opcode looking for a
2242 syntax match. */
2243
2244 static const struct arc_opcode *
2245 find_opcode_match (const struct arc_opcode *first_opcode,
2246 expressionS *tok,
2247 int *pntok,
2248 struct arc_flags *first_pflag,
2249 int nflgs,
2250 int *pcpumatch)
2251 {
2252 const struct arc_opcode *opcode = first_opcode;
2253 int ntok = *pntok;
2254 int got_cpu_match = 0;
2255 expressionS bktok[MAX_INSN_ARGS];
2256 int bkntok;
2257 expressionS emptyE;
2258
2259 memset (&emptyE, 0, sizeof (emptyE));
2260 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
2261 bkntok = ntok;
2262
2263 do
2264 {
2265 const unsigned char *opidx;
2266 const unsigned char *flgidx;
2267 int tokidx = 0;
2268 const expressionS *t = &emptyE;
2269
2270 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
2271 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
2272
2273 /* Don't match opcodes that don't exist on this
2274 architecture. */
2275 if (!(opcode->cpu & arc_target))
2276 goto match_failed;
2277
2278 if (is_code_density_p (opcode) && !(arc_features & ARC_CD))
2279 goto match_failed;
2280
2281 got_cpu_match = 1;
2282 pr_debug ("cpu ");
2283
2284 /* Check the operands. */
2285 for (opidx = opcode->operands; *opidx; ++opidx)
2286 {
2287 const struct arc_operand *operand = &arc_operands[*opidx];
2288
2289 /* Only take input from real operands. */
2290 if ((operand->flags & ARC_OPERAND_FAKE)
2291 && !(operand->flags & ARC_OPERAND_BRAKET))
2292 continue;
2293
2294 /* When we expect input, make sure we have it. */
2295 if (tokidx >= ntok)
2296 goto match_failed;
2297
2298 /* Match operand type with expression type. */
2299 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
2300 {
2301 case ARC_OPERAND_IR:
2302 /* Check to be a register. */
2303 if ((tok[tokidx].X_op != O_register
2304 || !is_ir_num (tok[tokidx].X_add_number))
2305 && !(operand->flags & ARC_OPERAND_IGNORE))
2306 goto match_failed;
2307
2308 /* If expect duplicate, make sure it is duplicate. */
2309 if (operand->flags & ARC_OPERAND_DUPLICATE)
2310 {
2311 /* Check for duplicate. */
2312 if (t->X_op != O_register
2313 || !is_ir_num (t->X_add_number)
2314 || (regno (t->X_add_number) !=
2315 regno (tok[tokidx].X_add_number)))
2316 goto match_failed;
2317 }
2318
2319 /* Special handling? */
2320 if (operand->insert)
2321 {
2322 const char *errmsg = NULL;
2323 (*operand->insert)(0,
2324 regno (tok[tokidx].X_add_number),
2325 &errmsg);
2326 if (errmsg)
2327 {
2328 if (operand->flags & ARC_OPERAND_IGNORE)
2329 {
2330 /* Missing argument, create one. */
2331 if (!allocate_tok (tok, ntok - 1, tokidx))
2332 goto match_failed;
2333
2334 tok[tokidx].X_op = O_absent;
2335 ++ntok;
2336 }
2337 else
2338 goto match_failed;
2339 }
2340 }
2341
2342 t = &tok[tokidx];
2343 break;
2344
2345 case ARC_OPERAND_BRAKET:
2346 /* Check if bracket is also in opcode table as
2347 operand. */
2348 if (tok[tokidx].X_op != O_bracket)
2349 goto match_failed;
2350 break;
2351
2352 case ARC_OPERAND_LIMM:
2353 case ARC_OPERAND_SIGNED:
2354 case ARC_OPERAND_UNSIGNED:
2355 switch (tok[tokidx].X_op)
2356 {
2357 case O_illegal:
2358 case O_absent:
2359 case O_register:
2360 goto match_failed;
2361
2362 case O_bracket:
2363 /* Got an (too) early bracket, check if it is an
2364 ignored operand. N.B. This procedure works only
2365 when bracket is the last operand! */
2366 if (!(operand->flags & ARC_OPERAND_IGNORE))
2367 goto match_failed;
2368 /* Insert the missing operand. */
2369 if (!allocate_tok (tok, ntok - 1, tokidx))
2370 goto match_failed;
2371
2372 tok[tokidx].X_op = O_absent;
2373 ++ntok;
2374 break;
2375
2376 case O_constant:
2377 /* Check the range. */
2378 if (operand->bits != 32
2379 && !(operand->flags & ARC_OPERAND_NCHK))
2380 {
2381 offsetT min, max, val;
2382 val = tok[tokidx].X_add_number;
2383
2384 if (operand->flags & ARC_OPERAND_SIGNED)
2385 {
2386 max = (1 << (operand->bits - 1)) - 1;
2387 min = -(1 << (operand->bits - 1));
2388 }
2389 else
2390 {
2391 max = (1 << operand->bits) - 1;
2392 min = 0;
2393 }
2394
2395 if (val < min || val > max)
2396 goto match_failed;
2397
2398 /* Check alignmets. */
2399 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2400 && (val & 0x03))
2401 goto match_failed;
2402
2403 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2404 && (val & 0x01))
2405 goto match_failed;
2406 }
2407 else if (operand->flags & ARC_OPERAND_NCHK)
2408 {
2409 if (operand->insert)
2410 {
2411 const char *errmsg = NULL;
2412 (*operand->insert)(0,
2413 tok[tokidx].X_add_number,
2414 &errmsg);
2415 if (errmsg)
2416 goto match_failed;
2417 }
2418 else
2419 goto match_failed;
2420 }
2421 break;
2422
2423 case O_subtract:
2424 /* Check if it is register range. */
2425 if ((tok[tokidx].X_add_number == 0)
2426 && contains_register (tok[tokidx].X_add_symbol)
2427 && contains_register (tok[tokidx].X_op_symbol))
2428 {
2429 int regs;
2430
2431 regs = get_register (tok[tokidx].X_add_symbol);
2432 regs <<= 16;
2433 regs |= get_register (tok[tokidx].X_op_symbol);
2434 if (operand->insert)
2435 {
2436 const char *errmsg = NULL;
2437 (*operand->insert)(0,
2438 regs,
2439 &errmsg);
2440 if (errmsg)
2441 goto match_failed;
2442 }
2443 else
2444 goto match_failed;
2445 break;
2446 }
2447 default:
2448 if (operand->default_reloc == 0)
2449 goto match_failed; /* The operand needs relocation. */
2450
2451 /* Relocs requiring long immediate. FIXME! make it
2452 generic and move it to a function. */
2453 switch (tok[tokidx].X_md)
2454 {
2455 case O_gotoff:
2456 case O_gotpc:
2457 case O_pcl:
2458 case O_tpoff:
2459 case O_dtpoff:
2460 case O_tlsgd:
2461 case O_tlsie:
2462 if (!(operand->flags & ARC_OPERAND_LIMM))
2463 goto match_failed;
2464 case O_absent:
2465 if (!generic_reloc_p (operand->default_reloc))
2466 goto match_failed;
2467 default:
2468 break;
2469 }
2470 break;
2471 }
2472 /* If expect duplicate, make sure it is duplicate. */
2473 if (operand->flags & ARC_OPERAND_DUPLICATE)
2474 {
2475 if (t->X_op == O_illegal
2476 || t->X_op == O_absent
2477 || t->X_op == O_register
2478 || (t->X_add_number != tok[tokidx].X_add_number))
2479 goto match_failed;
2480 }
2481 t = &tok[tokidx];
2482 break;
2483
2484 default:
2485 /* Everything else should have been fake. */
2486 abort ();
2487 }
2488
2489 ++tokidx;
2490 }
2491 pr_debug ("opr ");
2492
2493 /* Check the flags. Iterate over the valid flag classes. */
2494 int lnflg = nflgs;
2495
2496 for (flgidx = opcode->flags; *flgidx && lnflg; ++flgidx)
2497 {
2498 /* Get a valid flag class. */
2499 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
2500 const unsigned *flgopridx;
2501
2502 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
2503 {
2504 const struct arc_flag_operand *flg_operand;
2505 struct arc_flags *pflag = first_pflag;
2506 int i;
2507
2508 flg_operand = &arc_flag_operands[*flgopridx];
2509 for (i = 0; i < nflgs; i++, pflag++)
2510 {
2511 /* Match against the parsed flags. */
2512 if (!strcmp (flg_operand->name, pflag->name))
2513 {
2514 /*TODO: Check if it is duplicated. */
2515 pflag->code = *flgopridx;
2516 lnflg--;
2517 break; /* goto next flag class and parsed flag. */
2518 }
2519 }
2520 }
2521 }
2522 /* Did I check all the parsed flags? */
2523 if (lnflg)
2524 goto match_failed;
2525
2526 pr_debug ("flg");
2527 /* Possible match -- did we use all of our input? */
2528 if (tokidx == ntok)
2529 {
2530 *pntok = ntok;
2531 pr_debug ("\n");
2532 return opcode;
2533 }
2534
2535 match_failed:;
2536 pr_debug ("\n");
2537 /* Restore the original parameters. */
2538 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
2539 ntok = bkntok;
2540 }
2541 while (++opcode - arc_opcodes < (int) arc_num_opcodes
2542 && !strcmp (opcode->name, first_opcode->name));
2543
2544 if (*pcpumatch)
2545 *pcpumatch = got_cpu_match;
2546
2547 return NULL;
2548 }
2549
2550 /* Find the proper relocation for the given opcode. */
2551
2552 static extended_bfd_reloc_code_real_type
2553 find_reloc (const char *name,
2554 const char *opcodename,
2555 const struct arc_flags *pflags,
2556 int nflg,
2557 extended_bfd_reloc_code_real_type reloc)
2558 {
2559 unsigned int i;
2560 int j;
2561 bfd_boolean found_flag, tmp;
2562 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
2563
2564 for (i = 0; i < arc_num_equiv_tab; i++)
2565 {
2566 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
2567
2568 /* Find the entry. */
2569 if (strcmp (name, r->name))
2570 continue;
2571 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
2572 continue;
2573 if (r->flags[0])
2574 {
2575 if (!nflg)
2576 continue;
2577 found_flag = FALSE;
2578 unsigned * psflg = (unsigned *)r->flags;
2579 do
2580 {
2581 tmp = FALSE;
2582 for (j = 0; j < nflg; j++)
2583 if (!strcmp (pflags[j].name,
2584 arc_flag_operands[*psflg].name))
2585 {
2586 tmp = TRUE;
2587 break;
2588 }
2589 if (!tmp)
2590 {
2591 found_flag = FALSE;
2592 break;
2593 }
2594 else
2595 {
2596 found_flag = TRUE;
2597 }
2598 ++ psflg;
2599 } while (*psflg);
2600
2601 if (!found_flag)
2602 continue;
2603 }
2604
2605 if (reloc != r->oldreloc)
2606 continue;
2607 /* Found it. */
2608 ret = r->newreloc;
2609 break;
2610 }
2611
2612 if (ret == BFD_RELOC_UNUSED)
2613 as_bad (_("Unable to find %s relocation for instruction %s"),
2614 name, opcodename);
2615 return ret;
2616 }
2617
2618 /* Turn an opcode description and a set of arguments into
2619 an instruction and a fixup. */
2620
2621 static void
2622 assemble_insn (const struct arc_opcode *opcode,
2623 const expressionS *tok,
2624 int ntok,
2625 const struct arc_flags *pflags,
2626 int nflg,
2627 struct arc_insn *insn)
2628 {
2629 const expressionS *reloc_exp = NULL;
2630 unsigned image;
2631 const unsigned char *argidx;
2632 int i;
2633 int tokidx = 0;
2634 unsigned char pcrel = 0;
2635 bfd_boolean needGOTSymbol;
2636 bfd_boolean has_delay_slot = FALSE;
2637 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2638
2639 memset (insn, 0, sizeof (*insn));
2640 image = opcode->opcode;
2641
2642 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
2643 frag_now->fr_file, frag_now->fr_line, opcode->name,
2644 opcode->opcode);
2645
2646 /* Handle operands. */
2647 for (argidx = opcode->operands; *argidx; ++argidx)
2648 {
2649 const struct arc_operand *operand = &arc_operands[*argidx];
2650 const expressionS *t = (const expressionS *) 0;
2651
2652 if ((operand->flags & ARC_OPERAND_FAKE)
2653 && !(operand->flags & ARC_OPERAND_BRAKET))
2654 continue;
2655
2656 if (operand->flags & ARC_OPERAND_DUPLICATE)
2657 {
2658 /* Duplicate operand, already inserted. */
2659 tokidx ++;
2660 continue;
2661 }
2662
2663 if (tokidx >= ntok)
2664 {
2665 abort ();
2666 }
2667 else
2668 t = &tok[tokidx++];
2669
2670 /* Regardless if we have a reloc or not mark the instruction
2671 limm if it is the case. */
2672 if (operand->flags & ARC_OPERAND_LIMM)
2673 insn->has_limm = TRUE;
2674
2675 switch (t->X_op)
2676 {
2677 case O_register:
2678 image = insert_operand (image, operand, regno (t->X_add_number),
2679 NULL, 0);
2680 break;
2681
2682 case O_constant:
2683 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2684 reloc_exp = t;
2685 if (operand->flags & ARC_OPERAND_LIMM)
2686 insn->limm = t->X_add_number;
2687 break;
2688
2689 case O_bracket:
2690 /* Ignore brackets. */
2691 break;
2692
2693 case O_absent:
2694 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
2695 break;
2696
2697 case O_subtract:
2698 /* Maybe register range. */
2699 if ((t->X_add_number == 0)
2700 && contains_register (t->X_add_symbol)
2701 && contains_register (t->X_op_symbol))
2702 {
2703 int regs;
2704
2705 regs = get_register (t->X_add_symbol);
2706 regs <<= 16;
2707 regs |= get_register (t->X_op_symbol);
2708 image = insert_operand (image, operand, regs, NULL, 0);
2709 break;
2710 }
2711
2712 default:
2713 /* This operand needs a relocation. */
2714 needGOTSymbol = FALSE;
2715
2716 switch (t->X_md)
2717 {
2718 case O_plt:
2719 needGOTSymbol = TRUE;
2720 reloc = find_reloc ("plt", opcode->name,
2721 pflags, nflg,
2722 operand->default_reloc);
2723 break;
2724
2725 case O_gotoff:
2726 case O_gotpc:
2727 needGOTSymbol = TRUE;
2728 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2729 break;
2730 case O_pcl:
2731 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2732 if (ARC_SHORT (opcode->mask))
2733 as_bad_where (frag_now->fr_file, frag_now->fr_line,
2734 _("Unable to use @pcl relocation for insn %s"),
2735 opcode->name);
2736 break;
2737 case O_sda:
2738 reloc = find_reloc ("sda", opcode->name,
2739 pflags, nflg,
2740 operand->default_reloc);
2741 break;
2742 case O_tlsgd:
2743 case O_tlsie:
2744 needGOTSymbol = TRUE;
2745 /* Fall-through. */
2746
2747 case O_tpoff:
2748 case O_dtpoff:
2749 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2750 break;
2751
2752 case O_tpoff9: /*FIXME! Check for the conditionality of
2753 the insn. */
2754 case O_dtpoff9: /*FIXME! Check for the conditionality of
2755 the insn. */
2756 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2757 break;
2758
2759 default:
2760 /* Just consider the default relocation. */
2761 reloc = operand->default_reloc;
2762 break;
2763 }
2764
2765 if (needGOTSymbol && (GOT_symbol == NULL))
2766 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
2767
2768 reloc_exp = t;
2769
2770 #if 0
2771 if (reloc > 0)
2772 {
2773 /* sanity checks. */
2774 reloc_howto_type *reloc_howto
2775 = bfd_reloc_type_lookup (stdoutput,
2776 (bfd_reloc_code_real_type) reloc);
2777 unsigned reloc_bitsize = reloc_howto->bitsize;
2778 if (reloc_howto->rightshift)
2779 reloc_bitsize -= reloc_howto->rightshift;
2780 if (reloc_bitsize != operand->bits)
2781 {
2782 as_bad (_("invalid relocation %s for field"),
2783 bfd_get_reloc_code_name (reloc));
2784 return;
2785 }
2786 }
2787 #endif
2788 if (insn->nfixups >= MAX_INSN_FIXUPS)
2789 as_fatal (_("too many fixups"));
2790
2791 struct arc_fixup *fixup;
2792 fixup = &insn->fixups[insn->nfixups++];
2793 fixup->exp = *t;
2794 fixup->reloc = reloc;
2795 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
2796 fixup->pcrel = pcrel;
2797 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
2798 TRUE : FALSE;
2799 break;
2800 }
2801 }
2802
2803 /* Handle flags. */
2804 for (i = 0; i < nflg; i++)
2805 {
2806 const struct arc_flag_operand *flg_operand =
2807 &arc_flag_operands[pflags[i].code];
2808
2809 /* Check if the instruction has a delay slot. */
2810 if (!strcmp (flg_operand->name, "d"))
2811 has_delay_slot = TRUE;
2812
2813 /* There is an exceptional case when we cannot insert a flag
2814 just as it is. The .T flag must be handled in relation with
2815 the relative address. */
2816 if (!strcmp (flg_operand->name, "t")
2817 || !strcmp (flg_operand->name, "nt"))
2818 {
2819 unsigned bitYoperand = 0;
2820 /* FIXME! move selection bbit/brcc in arc-opc.c. */
2821 if (!strcmp (flg_operand->name, "t"))
2822 if (!strcmp (opcode->name, "bbit0")
2823 || !strcmp (opcode->name, "bbit1"))
2824 bitYoperand = arc_NToperand;
2825 else
2826 bitYoperand = arc_Toperand;
2827 else
2828 if (!strcmp (opcode->name, "bbit0")
2829 || !strcmp (opcode->name, "bbit1"))
2830 bitYoperand = arc_Toperand;
2831 else
2832 bitYoperand = arc_NToperand;
2833
2834 gas_assert (reloc_exp != NULL);
2835 if (reloc_exp->X_op == O_constant)
2836 {
2837 /* Check if we have a constant and solved it
2838 immediately. */
2839 offsetT val = reloc_exp->X_add_number;
2840 image |= insert_operand (image, &arc_operands[bitYoperand],
2841 val, NULL, 0);
2842 }
2843 else
2844 {
2845 struct arc_fixup *fixup;
2846
2847 if (insn->nfixups >= MAX_INSN_FIXUPS)
2848 as_fatal (_("too many fixups"));
2849
2850 fixup = &insn->fixups[insn->nfixups++];
2851 fixup->exp = *reloc_exp;
2852 fixup->reloc = -bitYoperand;
2853 fixup->pcrel = pcrel;
2854 fixup->islong = FALSE;
2855 }
2856 }
2857 else
2858 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
2859 << flg_operand->shift;
2860 }
2861
2862 /* Short instruction? */
2863 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
2864
2865 insn->insn = image;
2866
2867 /* Update last insn status. */
2868 arc_last_insns[1] = arc_last_insns[0];
2869 arc_last_insns[0].opcode = opcode;
2870 arc_last_insns[0].has_limm = insn->has_limm;
2871 arc_last_insns[0].has_delay_slot = has_delay_slot;
2872
2873 /* Check if the current instruction is legally used. */
2874 if (arc_last_insns[1].has_delay_slot
2875 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
2876 as_bad_where (frag_now->fr_file, frag_now->fr_line,
2877 _("A jump/branch instruction in delay slot."));
2878 }
2879
2880 /* Actually output an instruction with its fixup. */
2881
2882 static void
2883 emit_insn (struct arc_insn *insn)
2884 {
2885 char *f;
2886 int i;
2887
2888 pr_debug ("Emit insn : 0x%x\n", insn->insn);
2889 pr_debug ("\tShort : 0x%d\n", insn->short_insn);
2890 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
2891
2892 /* Write out the instruction. */
2893 if (insn->short_insn)
2894 {
2895 if (insn->has_limm)
2896 {
2897 f = frag_more (6);
2898 md_number_to_chars (f, insn->insn, 2);
2899 md_number_to_chars_midend (f + 2, insn->limm, 4);
2900 dwarf2_emit_insn (6);
2901 }
2902 else
2903 {
2904 f = frag_more (2);
2905 md_number_to_chars (f, insn->insn, 2);
2906 dwarf2_emit_insn (2);
2907 }
2908 }
2909 else
2910 {
2911 if (insn->has_limm)
2912 {
2913 f = frag_more (8);
2914 md_number_to_chars_midend (f, insn->insn, 4);
2915 md_number_to_chars_midend (f + 4, insn->limm, 4);
2916 dwarf2_emit_insn (8);
2917 }
2918 else
2919 {
2920 f = frag_more (4);
2921 md_number_to_chars_midend (f, insn->insn, 4);
2922 dwarf2_emit_insn (4);
2923 }
2924 }
2925
2926 /* Apply the fixups in order. */
2927 for (i = 0; i < insn->nfixups; i++)
2928 {
2929 struct arc_fixup *fixup = &insn->fixups[i];
2930 int size, pcrel, offset = 0;
2931
2932 /*FIXME! the reloc size is wrong in the BFD file. When it will
2933 be fixed please delete me. */
2934 size = (insn->short_insn && !fixup->islong) ? 2 : 4;
2935
2936 if (fixup->islong)
2937 offset = (insn->short_insn) ? 2 : 4;
2938
2939 /* Some fixups are only used internally, thus no howto. */
2940 if ((int) fixup->reloc < 0)
2941 {
2942 /*FIXME! the reloc size is wrong in the BFD file. When it
2943 will be fixed please enable me.
2944 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
2945 pcrel = fixup->pcrel;
2946 }
2947 else
2948 {
2949 reloc_howto_type *reloc_howto =
2950 bfd_reloc_type_lookup (stdoutput,
2951 (bfd_reloc_code_real_type) fixup->reloc);
2952 gas_assert (reloc_howto);
2953 /*FIXME! the reloc size is wrong in the BFD file. When it
2954 will be fixed please enable me.
2955 size = bfd_get_reloc_size (reloc_howto); */
2956 pcrel = reloc_howto->pc_relative;
2957 }
2958
2959 pr_debug ("%s:%d: emit_insn: new %s fixup (PCrel:%s) of size %d @ offset %d\n",
2960 frag_now->fr_file, frag_now->fr_line,
2961 (fixup->reloc < 0) ? "Internal" :
2962 bfd_get_reloc_code_name (fixup->reloc),
2963 pcrel ? "Y" : "N",
2964 size, offset);
2965 fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
2966 size, &fixup->exp, pcrel, fixup->reloc);
2967
2968 /* Check for ZOLs, and update symbol info if any. */
2969 if (LP_INSN (insn->insn))
2970 {
2971 gas_assert (fixup->exp.X_add_symbol);
2972 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
2973 }
2974 }
2975 }
2976
2977 /* Insert an operand value into an instruction. */
2978
2979 static unsigned
2980 insert_operand (unsigned insn,
2981 const struct arc_operand *operand,
2982 offsetT val,
2983 char *file,
2984 unsigned line)
2985 {
2986 offsetT min = 0, max = 0;
2987
2988 if (operand->bits != 32
2989 && !(operand->flags & ARC_OPERAND_NCHK)
2990 && !(operand->flags & ARC_OPERAND_FAKE))
2991 {
2992 if (operand->flags & ARC_OPERAND_SIGNED)
2993 {
2994 max = (1 << (operand->bits - 1)) - 1;
2995 min = -(1 << (operand->bits - 1));
2996 }
2997 else
2998 {
2999 max = (1 << operand->bits) - 1;
3000 min = 0;
3001 }
3002
3003 if (val < min || val > max)
3004 as_bad_value_out_of_range (_("operand"),
3005 val, min, max, file, line);
3006 }
3007
3008 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
3009 min, val, max, insn);
3010
3011 if ((operand->flags & ARC_OPERAND_ALIGNED32)
3012 && (val & 0x03))
3013 as_bad_where (file, line,
3014 _("Unaligned operand. Needs to be 32bit aligned"));
3015
3016 if ((operand->flags & ARC_OPERAND_ALIGNED16)
3017 && (val & 0x01))
3018 as_bad_where (file, line,
3019 _("Unaligned operand. Needs to be 16bit aligned"));
3020
3021 if (operand->insert)
3022 {
3023 const char *errmsg = NULL;
3024
3025 insn = (*operand->insert) (insn, val, &errmsg);
3026 if (errmsg)
3027 as_warn_where (file, line, "%s", errmsg);
3028 }
3029 else
3030 {
3031 if (operand->flags & ARC_OPERAND_TRUNCATE)
3032 {
3033 if (operand->flags & ARC_OPERAND_ALIGNED32)
3034 val >>= 2;
3035 if (operand->flags & ARC_OPERAND_ALIGNED16)
3036 val >>= 1;
3037 }
3038 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
3039 }
3040 return insn;
3041 }
3042
3043 void
3044 arc_handle_align (fragS* fragP)
3045 {
3046 if ((fragP)->fr_type == rs_align_code)
3047 {
3048 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3049 valueT count = ((fragP)->fr_next->fr_address
3050 - (fragP)->fr_address - (fragP)->fr_fix);
3051
3052 (fragP)->fr_var = 2;
3053
3054 if (count & 1)/* Padding in the gap till the next 2-byte
3055 boundary with 0s. */
3056 {
3057 (fragP)->fr_fix++;
3058 *dest++ = 0;
3059 }
3060 /* Writing nop_s. */
3061 md_number_to_chars (dest, NOP_OPCODE_S, 2);
3062 }
3063 }
3064
3065 /* Here we decide which fixups can be adjusted to make them relative
3066 to the beginning of the section instead of the symbol. Basically
3067 we need to make sure that the dynamic relocations are done
3068 correctly, so in some cases we force the original symbol to be
3069 used. */
3070
3071 int
3072 tc_arc_fix_adjustable (fixS *fixP)
3073 {
3074
3075 /* Prevent all adjustments to global symbols. */
3076 if (S_IS_EXTERNAL (fixP->fx_addsy))
3077 return 0;
3078 if (S_IS_WEAK (fixP->fx_addsy))
3079 return 0;
3080
3081 /* Adjust_reloc_syms doesn't know about the GOT. */
3082 switch (fixP->fx_r_type)
3083 {
3084 case BFD_RELOC_ARC_GOTPC32:
3085 case BFD_RELOC_ARC_PLT32:
3086 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3087 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3088 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3089 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3090 return 0;
3091
3092 default:
3093 break;
3094 }
3095
3096 return 0; /* FIXME! return 1, fix it in the linker. */
3097 }
3098
3099 /* Compute the reloc type of an expression EXP. */
3100
3101 static void
3102 arc_check_reloc (expressionS *exp,
3103 bfd_reloc_code_real_type *r_type_p)
3104 {
3105 if (*r_type_p == BFD_RELOC_32
3106 && exp->X_op == O_subtract
3107 && exp->X_op_symbol != NULL
3108 && exp->X_op_symbol->bsym->section == now_seg)
3109 *r_type_p = BFD_RELOC_ARC_32_PCREL;
3110 }
3111
3112
3113 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3114
3115 void
3116 arc_cons_fix_new (fragS *frag,
3117 int off,
3118 int size,
3119 expressionS *exp,
3120 bfd_reloc_code_real_type r_type)
3121 {
3122 r_type = BFD_RELOC_UNUSED;
3123
3124 switch (size)
3125 {
3126 case 1:
3127 r_type = BFD_RELOC_8;
3128 break;
3129
3130 case 2:
3131 r_type = BFD_RELOC_16;
3132 break;
3133
3134 case 3:
3135 r_type = BFD_RELOC_24;
3136 break;
3137
3138 case 4:
3139 r_type = BFD_RELOC_32;
3140 arc_check_reloc (exp, &r_type);
3141 break;
3142
3143 case 8:
3144 r_type = BFD_RELOC_64;
3145 break;
3146
3147 default:
3148 as_bad (_("unsupported BFD relocation size %u"), size);
3149 r_type = BFD_RELOC_UNUSED;
3150 }
3151
3152 fix_new_exp (frag, off, size, exp, 0, r_type);
3153 }
3154
3155 /* The actual routine that checks the ZOL conditions. */
3156
3157 static void
3158 check_zol (symbolS *s)
3159 {
3160 switch (arc_mach_type)
3161 {
3162 case bfd_mach_arc_arcv2:
3163 if (arc_target & ARC_OPCODE_ARCv2EM)
3164 return;
3165
3166 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3167 || arc_last_insns[1].has_delay_slot)
3168 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3169 S_GET_NAME (s));
3170
3171 break;
3172 case bfd_mach_arc_arc600:
3173
3174 if (is_kernel_insn_p (arc_last_insns[0].opcode))
3175 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3176 S_GET_NAME (s));
3177
3178 if (arc_last_insns[0].has_limm
3179 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3180 as_bad (_("A jump instruction with long immediate detected at the \
3181 end of the ZOL label @%s"), S_GET_NAME (s));
3182
3183 /* Fall through. */
3184 case bfd_mach_arc_arc700:
3185 if (arc_last_insns[0].has_delay_slot)
3186 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3187 S_GET_NAME (s));
3188
3189 break;
3190 default:
3191 break;
3192 }
3193 }
3194
3195 /* If ZOL end check the last two instruction for illegals. */
3196 void
3197 arc_frob_label (symbolS * sym)
3198 {
3199 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3200 check_zol (sym);
3201
3202 dwarf2_emit_label (sym);
3203 }
This page took 0.125132 seconds and 3 git commands to generate.