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 "dw2gencfi.h"
28 #include "safe-ctype.h"
29 
30 #include "opcode/arc.h"
31 #include "elf/arc.h"
32 #include "../opcodes/arc-ext.h"
33 
34 /* Defines section.  */
35 
36 #define MAX_INSN_FIXUPS      2
37 #define MAX_CONSTR_STR       20
38 #define FRAG_MAX_GROWTH      8
39 
40 #ifdef DEBUG
41 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
42 #else
43 # define pr_debug(fmt, args...)
44 #endif
45 
46 #define MAJOR_OPCODE(x)  (((x) & 0xF8000000) >> 27)
47 #define SUB_OPCODE(x)	 (((x) & 0x003F0000) >> 16)
48 #define LP_INSN(x)	 ((MAJOR_OPCODE (x) == 0x4) && \
49 			  (SUB_OPCODE (x) == 0x28))
50 
51 /* Equal to MAX_PRECISION in atof-ieee.c.  */
52 #define MAX_LITTLENUMS 6
53 
54 #ifndef TARGET_WITH_CPU
55 #define TARGET_WITH_CPU "arc700"
56 #endif /* TARGET_WITH_CPU */
57 
58 /* Enum used to enumerate the relaxable ins operands.  */
59 enum rlx_operand_type
60 {
61   EMPTY = 0,
62   REGISTER,
63   REGISTER_S,     /* Register for short instruction(s).  */
64   REGISTER_NO_GP, /* Is a register but not gp register specifically.  */
65   REGISTER_DUP,   /* Duplication of previous operand of type register.  */
66   IMMEDIATE,
67   BRACKET
68 };
69 
70 enum arc_rlx_types
71 {
72   ARC_RLX_NONE = 0,
73   ARC_RLX_BL_S,
74   ARC_RLX_BL,
75   ARC_RLX_B_S,
76   ARC_RLX_B,
77   ARC_RLX_ADD_U3,
78   ARC_RLX_ADD_U6,
79   ARC_RLX_ADD_LIMM,
80   ARC_RLX_LD_U7,
81   ARC_RLX_LD_S9,
82   ARC_RLX_LD_LIMM,
83   ARC_RLX_MOV_U8,
84   ARC_RLX_MOV_S12,
85   ARC_RLX_MOV_LIMM,
86   ARC_RLX_SUB_U3,
87   ARC_RLX_SUB_U6,
88   ARC_RLX_SUB_LIMM,
89   ARC_RLX_MPY_U6,
90   ARC_RLX_MPY_LIMM,
91   ARC_RLX_MOV_RU6,
92   ARC_RLX_MOV_RLIMM,
93   ARC_RLX_ADD_RRU6,
94   ARC_RLX_ADD_RRLIMM,
95 };
96 
97 /* Macros section.  */
98 
99 #define regno(x)		((x) & 0x3F)
100 #define is_ir_num(x)		(((x) & ~0x3F) == 0)
101 #define is_code_density_p(sc)   (((sc) == CD1 || (sc) == CD2))
102 #define is_spfp_p(op)           (((sc) == SPX))
103 #define is_dpfp_p(op)           (((sc) == DPX))
104 #define is_fpuda_p(op)          (((sc) == DPA))
105 #define is_br_jmp_insn_p(op)    (((op)->insn_class == BRANCH || (op)->insn_class == JUMP))
106 #define is_kernel_insn_p(op)    (((op)->insn_class == KERNEL))
107 #define is_nps400_p(op)         (((sc) == NPS400))
108 
109 /* Generic assembler global variables which must be defined by all
110    targets.  */
111 
112 /* Characters which always start a comment.  */
113 const char comment_chars[] = "#;";
114 
115 /* Characters which start a comment at the beginning of a line.  */
116 const char line_comment_chars[] = "#";
117 
118 /* Characters which may be used to separate multiple commands on a
119    single line.  */
120 const char line_separator_chars[] = "`";
121 
122 /* Characters which are used to indicate an exponent in a floating
123    point number.  */
124 const char EXP_CHARS[] = "eE";
125 
126 /* Chars that mean this number is a floating point constant
127    As in 0f12.456 or 0d1.2345e12.  */
128 const char FLT_CHARS[] = "rRsSfFdD";
129 
130 /* Byte order.  */
131 extern int target_big_endian;
132 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
133 static int byte_order = DEFAULT_BYTE_ORDER;
134 
135 /* Arc extension section.  */
136 static segT arcext_section;
137 
138 /* By default relaxation is disabled.  */
139 static int relaxation_state = 0;
140 
141 extern int arc_get_mach (char *);
142 
143 /* Forward declarations.  */
144 static void arc_lcomm (int);
145 static void arc_option (int);
146 static void arc_extra_reloc (int);
147 static void arc_extinsn (int);
148 static void arc_extcorereg (int);
149 
150 const pseudo_typeS md_pseudo_table[] =
151 {
152   /* Make sure that .word is 32 bits.  */
153   { "word", cons, 4 },
154 
155   { "align",   s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
156   { "lcomm",   arc_lcomm, 0 },
157   { "lcommon", arc_lcomm, 0 },
158   { "cpu",     arc_option, 0 },
159 
160   { "extinstruction",  arc_extinsn, 0 },
161   { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER },
162   { "extauxregister",  arc_extcorereg, EXT_AUX_REGISTER },
163   { "extcondcode",     arc_extcorereg, EXT_COND_CODE },
164 
165   { "tls_gd_ld",   arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
166   { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
167 
168   { NULL, NULL, 0 }
169 };
170 
171 const char *md_shortopts = "";
172 
173 enum options
174 {
175   OPTION_EB = OPTION_MD_BASE,
176   OPTION_EL,
177 
178   OPTION_ARC600,
179   OPTION_ARC601,
180   OPTION_ARC700,
181   OPTION_ARCEM,
182   OPTION_ARCHS,
183 
184   OPTION_MCPU,
185   OPTION_CD,
186   OPTION_RELAX,
187   OPTION_NPS400,
188 
189   OPTION_SPFP,
190   OPTION_DPFP,
191   OPTION_FPUDA,
192 
193   /* The following options are deprecated and provided here only for
194      compatibility reasons.  */
195   OPTION_USER_MODE,
196   OPTION_LD_EXT_MASK,
197   OPTION_SWAP,
198   OPTION_NORM,
199   OPTION_BARREL_SHIFT,
200   OPTION_MIN_MAX,
201   OPTION_NO_MPY,
202   OPTION_EA,
203   OPTION_MUL64,
204   OPTION_SIMD,
205   OPTION_XMAC_D16,
206   OPTION_XMAC_24,
207   OPTION_DSP_PACKA,
208   OPTION_CRC,
209   OPTION_DVBF,
210   OPTION_TELEPHONY,
211   OPTION_XYMEMORY,
212   OPTION_LOCK,
213   OPTION_SWAPE,
214   OPTION_RTSC
215 };
216 
217 struct option md_longopts[] =
218 {
219   { "EB",		no_argument,	   NULL, OPTION_EB },
220   { "EL",		no_argument,	   NULL, OPTION_EL },
221   { "mcpu",		required_argument, NULL, OPTION_MCPU },
222   { "mA6",		no_argument,	   NULL, OPTION_ARC600 },
223   { "mARC600",		no_argument,	   NULL, OPTION_ARC600 },
224   { "mARC601",		no_argument,	   NULL, OPTION_ARC601 },
225   { "mARC700",		no_argument,	   NULL, OPTION_ARC700 },
226   { "mA7",		no_argument,	   NULL, OPTION_ARC700 },
227   { "mEM",		no_argument,	   NULL, OPTION_ARCEM },
228   { "mHS",		no_argument,	   NULL, OPTION_ARCHS },
229   { "mcode-density",	no_argument,	   NULL, OPTION_CD },
230   { "mrelax",           no_argument,       NULL, OPTION_RELAX },
231   { "mnps400",          no_argument,       NULL, OPTION_NPS400 },
232 
233   /* Floating point options */
234   { "mspfp", no_argument, NULL, OPTION_SPFP},
235   { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
236   { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
237   { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
238   { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
239   { "mdpfp", no_argument, NULL, OPTION_DPFP},
240   { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
241   { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
242   { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
243   { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
244   { "mfpuda", no_argument, NULL, OPTION_FPUDA},
245 
246   /* The following options are deprecated and provided here only for
247      compatibility reasons.  */
248   { "mav2em", no_argument, NULL, OPTION_ARCEM },
249   { "mav2hs", no_argument, NULL, OPTION_ARCHS },
250   { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
251   { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
252   { "mswap", no_argument, NULL, OPTION_SWAP },
253   { "mnorm", no_argument, NULL, OPTION_NORM },
254   { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
255   { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
256   { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
257   { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
258   { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
259   { "mea", no_argument, NULL, OPTION_EA },
260   { "mEA", no_argument, NULL, OPTION_EA },
261   { "mmul64", no_argument, NULL, OPTION_MUL64 },
262   { "msimd", no_argument, NULL, OPTION_SIMD},
263   { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
264   { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
265   { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
266   { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
267   { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
268   { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
269   { "mcrc", no_argument, NULL, OPTION_CRC},
270   { "mdvbf", no_argument, NULL, OPTION_DVBF},
271   { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
272   { "mxy", no_argument, NULL, OPTION_XYMEMORY},
273   { "mlock", no_argument, NULL, OPTION_LOCK},
274   { "mswape", no_argument, NULL, OPTION_SWAPE},
275   { "mrtsc", no_argument, NULL, OPTION_RTSC},
276 
277   { NULL,		no_argument, NULL, 0 }
278 };
279 
280 size_t md_longopts_size = sizeof (md_longopts);
281 
282 /* Local data and data types.  */
283 
284 /* Used since new relocation types are introduced in this
285    file (DUMMY_RELOC_LITUSE_*).  */
286 typedef int extended_bfd_reloc_code_real_type;
287 
288 struct arc_fixup
289 {
290   expressionS exp;
291 
292   extended_bfd_reloc_code_real_type reloc;
293 
294   /* index into arc_operands.  */
295   unsigned int opindex;
296 
297   /* PC-relative, used by internals fixups.  */
298   unsigned char pcrel;
299 
300   /* TRUE if this fixup is for LIMM operand.  */
301   bfd_boolean islong;
302 };
303 
304 struct arc_insn
305 {
306   unsigned int insn;
307   int nfixups;
308   struct arc_fixup fixups[MAX_INSN_FIXUPS];
309   long limm;
310   bfd_boolean short_insn; /* Boolean value: TRUE if current insn is
311 			     short.  */
312   bfd_boolean has_limm;   /* Boolean value: TRUE if limm field is
313 			     valid.  */
314   bfd_boolean relax;	  /* Boolean value: TRUE if needs
315 			     relaxation.  */
316 };
317 
318 /* Structure to hold any last two instructions.  */
319 static struct arc_last_insn
320 {
321   /* Saved instruction opcode.  */
322   const struct arc_opcode *opcode;
323 
324   /* Boolean value: TRUE if current insn is short.  */
325   bfd_boolean has_limm;
326 
327   /* Boolean value: TRUE if current insn has delay slot.  */
328   bfd_boolean has_delay_slot;
329 } arc_last_insns[2];
330 
331 /* Extension instruction suffix classes.  */
332 typedef struct
333 {
334   const char *name;
335   int  len;
336   int  attr_class;
337 } attributes_t;
338 
339 static const attributes_t suffixclass[] =
340 {
341   { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG },
342   { "SUFFIX_COND", 11, ARC_SUFFIX_COND },
343   { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE }
344 };
345 
346 /* Extension instruction syntax classes.  */
347 static const attributes_t syntaxclass[] =
348 {
349   { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP },
350   { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP },
351   { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP },
352   { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP }
353 };
354 
355 /* Extension instruction syntax classes modifiers.  */
356 static const attributes_t syntaxclassmod[] =
357 {
358   { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED },
359   { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM }
360 };
361 
362 /* Extension register type.  */
363 typedef struct
364 {
365   char *name;
366   int  number;
367   int  imode;
368 } extRegister_t;
369 
370 /* A structure to hold the additional conditional codes.  */
371 static struct
372 {
373   struct arc_flag_operand *arc_ext_condcode;
374   int size;
375 } ext_condcode = { NULL, 0 };
376 
377 /* Structure to hold an entry in ARC_OPCODE_HASH.  */
378 struct arc_opcode_hash_entry
379 {
380   /* The number of pointers in the OPCODE list.  */
381   size_t count;
382 
383   /* Points to a list of opcode pointers.  */
384   const struct arc_opcode **opcode;
385 };
386 
387 /* Structure used for iterating through an arc_opcode_hash_entry.  */
388 struct arc_opcode_hash_entry_iterator
389 {
390   /* Index into the OPCODE element of the arc_opcode_hash_entry.  */
391   size_t index;
392 
393   /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
394      returned by this iterator.  */
395   const struct arc_opcode *opcode;
396 };
397 
398 /* Forward declaration.  */
399 static void assemble_insn
400   (const struct arc_opcode *, const expressionS *, int,
401    const struct arc_flags *, int, struct arc_insn *);
402 
403 /* The cpu for which we are generating code.  */
404 static unsigned arc_target;
405 static const char *arc_target_name;
406 static unsigned arc_features;
407 
408 /* The default architecture.  */
409 static int arc_mach_type;
410 
411 /* TRUE if the cpu type has been explicitly specified.  */
412 static bfd_boolean mach_type_specified_p = FALSE;
413 
414 /* The hash table of instruction opcodes.  */
415 static struct hash_control *arc_opcode_hash;
416 
417 /* The hash table of register symbols.  */
418 static struct hash_control *arc_reg_hash;
419 
420 /* The hash table of aux register symbols.  */
421 static struct hash_control *arc_aux_hash;
422 
423 /* A table of CPU names and opcode sets.  */
424 static const struct cpu_type
425 {
426   const char *name;
427   unsigned flags;
428   int mach;
429   unsigned eflags;
430   unsigned features;
431 }
432   cpu_types[] =
433 {
434   { "arc600", ARC_OPCODE_ARC600,  bfd_mach_arc_arc600,
435     E_ARC_MACH_ARC600,  0x00},
436   { "arc700", ARC_OPCODE_ARC700,  bfd_mach_arc_arc700,
437     E_ARC_MACH_ARC700,  0x00},
438   { "nps400", ARC_OPCODE_ARC700 , bfd_mach_arc_arc700,
439     E_ARC_MACH_ARC700,  ARC_NPS400},
440   { "arcem",  ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
441     EF_ARC_CPU_ARCV2EM, 0x00},
442   { "archs",  ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
443     EF_ARC_CPU_ARCV2HS, ARC_CD},
444   { 0, 0, 0, 0, 0 }
445 };
446 
447 /* Used by the arc_reloc_op table.  Order is important.  */
448 #define O_gotoff  O_md1     /* @gotoff relocation.  */
449 #define O_gotpc   O_md2     /* @gotpc relocation.  */
450 #define O_plt     O_md3     /* @plt relocation.  */
451 #define O_sda     O_md4     /* @sda relocation.  */
452 #define O_pcl     O_md5     /* @pcl relocation.  */
453 #define O_tlsgd   O_md6     /* @tlsgd relocation.  */
454 #define O_tlsie   O_md7     /* @tlsie relocation.  */
455 #define O_tpoff9  O_md8     /* @tpoff9 relocation.  */
456 #define O_tpoff   O_md9     /* @tpoff relocation.  */
457 #define O_dtpoff9 O_md10    /* @dtpoff9 relocation.  */
458 #define O_dtpoff  O_md11    /* @dtpoff relocation.  */
459 #define O_last    O_dtpoff
460 
461 /* Used to define a bracket as operand in tokens.  */
462 #define O_bracket O_md32
463 
464 /* Dummy relocation, to be sorted out.  */
465 #define DUMMY_RELOC_ARC_ENTRY     (BFD_RELOC_UNUSED + 1)
466 
467 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
468 
469 /* A table to map the spelling of a relocation operand into an appropriate
470    bfd_reloc_code_real_type type.  The table is assumed to be ordered such
471    that op-O_literal indexes into it.  */
472 #define ARC_RELOC_TABLE(op)				\
473   (&arc_reloc_op[ ((!USER_RELOC_P (op))			\
474 		   ? (abort (), 0)			\
475 		   : (int) (op) - (int) O_gotoff) ])
476 
477 #define DEF(NAME, RELOC, REQ)				\
478   { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
479 
480 static const struct arc_reloc_op_tag
481 {
482   /* String to lookup.  */
483   const char *name;
484   /* Size of the string.  */
485   size_t length;
486   /* Which operator to use.  */
487   operatorT op;
488   extended_bfd_reloc_code_real_type reloc;
489   /* Allows complex relocation expression like identifier@reloc +
490      const.  */
491   unsigned int complex_expr : 1;
492 }
493   arc_reloc_op[] =
494 {
495   DEF (gotoff,  BFD_RELOC_ARC_GOTOFF,		1),
496   DEF (gotpc,   BFD_RELOC_ARC_GOTPC32,		0),
497   DEF (plt,	BFD_RELOC_ARC_PLT32,		0),
498   DEF (sda,	DUMMY_RELOC_ARC_ENTRY,		1),
499   DEF (pcl,	BFD_RELOC_ARC_PC32,		1),
500   DEF (tlsgd,   BFD_RELOC_ARC_TLS_GD_GOT,	0),
501   DEF (tlsie,   BFD_RELOC_ARC_TLS_IE_GOT,	0),
502   DEF (tpoff9,  BFD_RELOC_ARC_TLS_LE_S9,	0),
503   DEF (tpoff,   BFD_RELOC_ARC_TLS_LE_32,	1),
504   DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9,	0),
505   DEF (dtpoff,  BFD_RELOC_ARC_TLS_DTPOFF,	0),
506 };
507 
508 static const int arc_num_reloc_op
509 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
510 
511 /* Structure for relaxable instruction that have to be swapped with a
512    smaller alternative instruction.  */
513 struct arc_relaxable_ins
514 {
515   /* Mnemonic that should be checked.  */
516   const char *mnemonic_r;
517 
518   /* Operands that should be checked.
519      Indexes of operands from operand array.  */
520   enum rlx_operand_type operands[6];
521 
522   /* Flags that should be checked.  */
523   unsigned flag_classes[5];
524 
525   /* Mnemonic (smaller) alternative to be used later for relaxation.  */
526   const char *mnemonic_alt;
527 
528   /* Index of operand that generic relaxation has to check.  */
529   unsigned opcheckidx;
530 
531   /* Base subtype index used.  */
532   enum arc_rlx_types subtype;
533 };
534 
535 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT)			\
536   { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1),	\
537       (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0,				\
538       (SIZE),								\
539       (NEXT) }								\
540 
541 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT)	\
542   { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF,		\
543       (ISSIGNED) ? -(0x7FFFFFFF) : 0,                   \
544       (SIZE),                                           \
545       (NEXT) }                                          \
546 
547 
548 /* ARC relaxation table.  */
549 const relax_typeS md_relax_table[] =
550 {
551   /* Fake entry.  */
552   {0, 0, 0, 0},
553 
554   /* BL_S s13 ->
555      BL s25.  */
556   RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL),
557   RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
558 
559   /* B_S s10 ->
560      B s25.  */
561   RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B),
562   RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
563 
564   /* ADD_S c,b, u3 ->
565      ADD<.f> a,b,u6 ->
566      ADD<.f> a,b,limm.  */
567   RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6),
568   RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM),
569   RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
570 
571   /* LD_S a, [b, u7] ->
572      LD<zz><.x><.aa><.di> a, [b, s9] ->
573      LD<zz><.x><.aa><.di> a, [b, limm] */
574   RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9),
575   RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM),
576   RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE),
577 
578   /* MOV_S b, u8 ->
579      MOV<.f> b, s12 ->
580      MOV<.f> b, limm.  */
581   RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12),
582   RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM),
583   RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
584 
585   /* SUB_S c, b, u3 ->
586      SUB<.f> a, b, u6 ->
587      SUB<.f> a, b, limm.  */
588   RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6),
589   RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM),
590   RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
591 
592   /* MPY<.f> a, b, u6 ->
593      MPY<.f> a, b, limm.  */
594   RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM),
595   RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
596 
597   /* MOV<.f><.cc> b, u6 ->
598      MOV<.f><.cc> b, limm.  */
599   RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM),
600   RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
601 
602   /* ADD<.f><.cc> b, b, u6 ->
603      ADD<.f><.cc> b, b, limm.  */
604   RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM),
605   RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
606 };
607 
608 /* Order of this table's entries matters!  */
609 const struct arc_relaxable_ins arc_relaxable_insns[] =
610 {
611   { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
612   { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
613   { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
614     2, ARC_RLX_ADD_RRU6},
615   { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
616     ARC_RLX_ADD_U3 },
617   { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
618     ARC_RLX_ADD_U6 },
619   { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
620     { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
621   { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
622     { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
623   { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
624   { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
625   { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
626   { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
627     ARC_RLX_SUB_U3 },
628   { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
629     ARC_RLX_SUB_U6 },
630   { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
631     ARC_RLX_MPY_U6 },
632 };
633 
634 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
635 
636 /* Flags to set in the elf header.  */
637 static flagword arc_eflag = 0x00;
638 
639 /* Pre-defined "_GLOBAL_OFFSET_TABLE_".  */
640 symbolS * GOT_symbol = 0;
641 
642 /* Set to TRUE when we assemble instructions.  */
643 static bfd_boolean assembling_insn = FALSE;
644 
645 /* Functions implementation.  */
646 
647 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
648    ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
649    are no matching entries in ARC_OPCODE_HASH.  */
650 
651 static const struct arc_opcode_hash_entry *
arc_find_opcode(const char * name)652 arc_find_opcode (const char *name)
653 {
654   const struct arc_opcode_hash_entry *entry;
655 
656   entry = hash_find (arc_opcode_hash, name);
657   return entry;
658 }
659 
660 /* Initialise the iterator ITER.  */
661 
662 static void
arc_opcode_hash_entry_iterator_init(struct arc_opcode_hash_entry_iterator * iter)663 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter)
664 {
665   iter->index = 0;
666   iter->opcode = NULL;
667 }
668 
669 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
670    calls to this function.  Return NULL when all ARC_OPCODE entries have
671    been returned.  */
672 
673 static const struct arc_opcode *
arc_opcode_hash_entry_iterator_next(const struct arc_opcode_hash_entry * entry,struct arc_opcode_hash_entry_iterator * iter)674 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
675 				     struct arc_opcode_hash_entry_iterator *iter)
676 {
677   if (iter->opcode == NULL && iter->index == 0)
678     {
679       gas_assert (entry->count > 0);
680       iter->opcode = entry->opcode[iter->index];
681     }
682   else if (iter->opcode != NULL)
683     {
684       const char *old_name = iter->opcode->name;
685 
686       iter->opcode++;
687       if (iter->opcode->name == NULL
688 	  || strcmp (old_name, iter->opcode->name) != 0)
689 	{
690 	  iter->index++;
691 	  if (iter->index == entry->count)
692 	    iter->opcode = NULL;
693 	  else
694 	    iter->opcode = entry->opcode[iter->index];
695 	}
696     }
697 
698   return iter->opcode;
699 }
700 
701 /* Insert an opcode into opcode hash structure.  */
702 
703 static void
arc_insert_opcode(const struct arc_opcode * opcode)704 arc_insert_opcode (const struct arc_opcode *opcode)
705 {
706   const char *name, *retval;
707   struct arc_opcode_hash_entry *entry;
708   name = opcode->name;
709 
710   entry = hash_find (arc_opcode_hash, name);
711   if (entry == NULL)
712     {
713       entry = XNEW (struct arc_opcode_hash_entry);
714       entry->count = 0;
715       entry->opcode = NULL;
716 
717       retval = hash_insert (arc_opcode_hash, name, (void *) entry);
718       if (retval)
719 	as_fatal (_("internal error: can't hash opcode '%s': %s"),
720 		  name, retval);
721     }
722 
723   entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode,
724 			      entry->count + 1);
725 
726   if (entry->opcode == NULL)
727     as_fatal (_("Virtual memory exhausted"));
728 
729   entry->opcode[entry->count] = opcode;
730   entry->count++;
731 }
732 
733 
734 /* Like md_number_to_chars but used for limms.  The 4-byte limm value,
735    is encoded as 'middle-endian' for a little-endian target.  FIXME!
736    this function is used for regular 4 byte instructions as well.  */
737 
738 static void
md_number_to_chars_midend(char * buf,valueT val,int n)739 md_number_to_chars_midend (char *buf, valueT val, int n)
740 {
741   if (n == 4)
742     {
743       md_number_to_chars (buf,     (val & 0xffff0000) >> 16, 2);
744       md_number_to_chars (buf + 2, (val & 0xffff), 2);
745     }
746   else
747     {
748       md_number_to_chars (buf, val, n);
749     }
750 }
751 
752 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
753    the relevant static global variables.  */
754 
755 static void
arc_select_cpu(const char * arg)756 arc_select_cpu (const char *arg)
757 {
758   int cpu_flags = 0;
759   int i;
760 
761   for (i = 0; cpu_types[i].name; ++i)
762     {
763       if (!strcasecmp (cpu_types[i].name, arg))
764         {
765           arc_target = cpu_types[i].flags;
766           arc_target_name = cpu_types[i].name;
767           arc_features = cpu_types[i].features;
768           arc_mach_type = cpu_types[i].mach;
769           cpu_flags = cpu_types[i].eflags;
770           break;
771         }
772     }
773 
774   if (!cpu_types[i].name)
775     as_fatal (_("unknown architecture: %s\n"), arg);
776   gas_assert (cpu_flags != 0);
777   arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
778 }
779 
780 /* Here ends all the ARCompact extension instruction assembling
781    stuff.  */
782 
783 static void
arc_extra_reloc(int r_type)784 arc_extra_reloc (int r_type)
785 {
786   char *sym_name, c;
787   symbolS *sym, *lab = NULL;
788 
789   if (*input_line_pointer == '@')
790     input_line_pointer++;
791   c = get_symbol_name (&sym_name);
792   sym = symbol_find_or_make (sym_name);
793   restore_line_pointer (c);
794   if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
795     {
796       ++input_line_pointer;
797       char *lab_name;
798       c = get_symbol_name (&lab_name);
799       lab = symbol_find_or_make (lab_name);
800       restore_line_pointer (c);
801     }
802 
803   /* These relocations exist as a mechanism for the compiler to tell the
804      linker how to patch the code if the tls model is optimised.  However,
805      the relocation itself does not require any space within the assembler
806      fragment, and so we pass a size of 0.
807 
808      The lines that generate these relocations look like this:
809 
810          .tls_gd_ld @.tdata`bl __tls_get_addr@plt
811 
812      The '.tls_gd_ld @.tdata' is processed first and generates the
813      additional relocation, while the 'bl __tls_get_addr@plt' is processed
814      second and generates the additional branch.
815 
816      It is possible that the additional relocation generated by the
817      '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
818      while the 'bl __tls_get_addr@plt' will be generated as the first thing
819      in the next fragment.  This will be fine; both relocations will still
820      appear to be at the same address in the generated object file.
821      However, this only works as the additional relocation is generated
822      with size of 0 bytes.  */
823   fixS *fixP
824     = fix_new (frag_now,	/* Which frag?  */
825 	       frag_now_fix (),	/* Where in that frag?  */
826 	       0,		/* size: 1, 2, or 4 usually.  */
827 	       sym,		/* X_add_symbol.  */
828 	       0,		/* X_add_number.  */
829 	       FALSE,		/* TRUE if PC-relative relocation.  */
830 	       r_type		/* Relocation type.  */);
831   fixP->fx_subsy = lab;
832 }
833 
834 static symbolS *
arc_lcomm_internal(int ignore ATTRIBUTE_UNUSED,symbolS * symbolP,addressT size)835 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
836 		    symbolS *symbolP, addressT size)
837 {
838   addressT align = 0;
839   SKIP_WHITESPACE ();
840 
841   if (*input_line_pointer == ',')
842     {
843       align = parse_align (1);
844 
845       if (align == (addressT) -1)
846 	return NULL;
847     }
848   else
849     {
850       if (size >= 8)
851 	align = 3;
852       else if (size >= 4)
853 	align = 2;
854       else if (size >= 2)
855 	align = 1;
856       else
857 	align = 0;
858     }
859 
860   bss_alloc (symbolP, size, align);
861   S_CLEAR_EXTERNAL (symbolP);
862 
863   return symbolP;
864 }
865 
866 static void
arc_lcomm(int ignore)867 arc_lcomm (int ignore)
868 {
869   symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
870 
871   if (symbolP)
872     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
873 }
874 
875 /* Select the cpu we're assembling for.  */
876 
877 static void
arc_option(int ignore ATTRIBUTE_UNUSED)878 arc_option (int ignore ATTRIBUTE_UNUSED)
879 {
880   int mach = -1;
881   char c;
882   char *cpu;
883 
884   c = get_symbol_name (&cpu);
885   mach = arc_get_mach (cpu);
886 
887   if (mach == -1)
888     goto bad_cpu;
889 
890   if (!mach_type_specified_p)
891     {
892       if ((!strcmp ("ARC600", cpu))
893 	  || (!strcmp ("ARC601", cpu))
894 	  || (!strcmp ("A6", cpu)))
895 	{
896 	  md_parse_option (OPTION_MCPU, "arc600");
897 	}
898       else if ((!strcmp ("ARC700", cpu))
899 	       || (!strcmp ("A7", cpu)))
900 	{
901 	  md_parse_option (OPTION_MCPU, "arc700");
902 	}
903       else if (!strcmp ("EM", cpu))
904 	{
905 	  md_parse_option (OPTION_MCPU, "arcem");
906 	}
907       else if (!strcmp ("HS", cpu))
908 	{
909 	  md_parse_option (OPTION_MCPU, "archs");
910 	}
911       else if (!strcmp ("NPS400", cpu))
912 	{
913 	  md_parse_option (OPTION_MCPU, "nps400");
914 	}
915       else
916 	as_fatal (_("could not find the architecture"));
917 
918       if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
919 	as_fatal (_("could not set architecture and machine"));
920 
921       /* Set elf header flags.  */
922       bfd_set_private_flags (stdoutput, arc_eflag);
923     }
924   else
925     if (arc_mach_type != mach)
926       as_warn (_("Command-line value overrides \".cpu\" directive"));
927 
928   restore_line_pointer (c);
929   demand_empty_rest_of_line ();
930   return;
931 
932  bad_cpu:
933   restore_line_pointer (c);
934   as_bad (_("invalid identifier for \".cpu\""));
935   ignore_rest_of_line ();
936 }
937 
938 /* Smartly print an expression.  */
939 
940 static void
debug_exp(expressionS * t)941 debug_exp (expressionS *t)
942 {
943   const char *name ATTRIBUTE_UNUSED;
944   const char *namemd ATTRIBUTE_UNUSED;
945 
946   pr_debug ("debug_exp: ");
947 
948   switch (t->X_op)
949     {
950     default:			name = "unknown";		break;
951     case O_illegal:		name = "O_illegal";		break;
952     case O_absent:		name = "O_absent";		break;
953     case O_constant:		name = "O_constant";		break;
954     case O_symbol:		name = "O_symbol";		break;
955     case O_symbol_rva:		name = "O_symbol_rva";		break;
956     case O_register:		name = "O_register";		break;
957     case O_big:			name = "O_big";			break;
958     case O_uminus:		name = "O_uminus";		break;
959     case O_bit_not:		name = "O_bit_not";		break;
960     case O_logical_not:		name = "O_logical_not";		break;
961     case O_multiply:		name = "O_multiply";		break;
962     case O_divide:		name = "O_divide";		break;
963     case O_modulus:		name = "O_modulus";		break;
964     case O_left_shift:		name = "O_left_shift";		break;
965     case O_right_shift:		name = "O_right_shift";		break;
966     case O_bit_inclusive_or:	name = "O_bit_inclusive_or";	break;
967     case O_bit_or_not:		name = "O_bit_or_not";		break;
968     case O_bit_exclusive_or:	name = "O_bit_exclusive_or";	break;
969     case O_bit_and:		name = "O_bit_and";		break;
970     case O_add:			name = "O_add";			break;
971     case O_subtract:		name = "O_subtract";		break;
972     case O_eq:			name = "O_eq";			break;
973     case O_ne:			name = "O_ne";			break;
974     case O_lt:			name = "O_lt";			break;
975     case O_le:			name = "O_le";			break;
976     case O_ge:			name = "O_ge";			break;
977     case O_gt:			name = "O_gt";			break;
978     case O_logical_and:		name = "O_logical_and";		break;
979     case O_logical_or:		name = "O_logical_or";		break;
980     case O_index:		name = "O_index";		break;
981     case O_bracket:		name = "O_bracket";		break;
982     }
983 
984   switch (t->X_md)
985     {
986     default:			namemd = "unknown";		break;
987     case O_gotoff:		namemd = "O_gotoff";		break;
988     case O_gotpc:		namemd = "O_gotpc";		break;
989     case O_plt:			namemd = "O_plt";		break;
990     case O_sda:			namemd = "O_sda";		break;
991     case O_pcl:			namemd = "O_pcl";		break;
992     case O_tlsgd:		namemd = "O_tlsgd";		break;
993     case O_tlsie:		namemd = "O_tlsie";		break;
994     case O_tpoff9:		namemd = "O_tpoff9";		break;
995     case O_tpoff:		namemd = "O_tpoff";		break;
996     case O_dtpoff9:		namemd = "O_dtpoff9";		break;
997     case O_dtpoff:		namemd = "O_dtpoff";		break;
998     }
999 
1000   pr_debug ("%s (%s, %s, %d, %s)", name,
1001 	    (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1002 	    (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1003 	    (int) t->X_add_number,
1004 	    (t->X_md) ? namemd : "--");
1005   pr_debug ("\n");
1006   fflush (stderr);
1007 }
1008 
1009 /* Parse the arguments to an opcode.  */
1010 
1011 static int
tokenize_arguments(char * str,expressionS * tok,int ntok)1012 tokenize_arguments (char *str,
1013 		    expressionS *tok,
1014 		    int ntok)
1015 {
1016   char *old_input_line_pointer;
1017   bfd_boolean saw_comma = FALSE;
1018   bfd_boolean saw_arg = FALSE;
1019   int brk_lvl = 0;
1020   int num_args = 0;
1021   int i;
1022   size_t len;
1023   const struct arc_reloc_op_tag *r;
1024   expressionS tmpE;
1025   char *reloc_name, c;
1026 
1027   memset (tok, 0, sizeof (*tok) * ntok);
1028 
1029   /* Save and restore input_line_pointer around this function.  */
1030   old_input_line_pointer = input_line_pointer;
1031   input_line_pointer = str;
1032 
1033   while (*input_line_pointer)
1034     {
1035       SKIP_WHITESPACE ();
1036       switch (*input_line_pointer)
1037 	{
1038 	case '\0':
1039 	  goto fini;
1040 
1041 	case ',':
1042 	  input_line_pointer++;
1043 	  if (saw_comma || !saw_arg)
1044 	    goto err;
1045 	  saw_comma = TRUE;
1046 	  break;
1047 
1048 	case '}':
1049 	case ']':
1050 	  ++input_line_pointer;
1051 	  --brk_lvl;
1052 	  if (!saw_arg || num_args == ntok)
1053 	    goto err;
1054 	  tok->X_op = O_bracket;
1055 	  ++tok;
1056 	  ++num_args;
1057 	  break;
1058 
1059 	case '{':
1060 	case '[':
1061 	  input_line_pointer++;
1062 	  if (brk_lvl || num_args == ntok)
1063 	    goto err;
1064 	  ++brk_lvl;
1065 	  tok->X_op = O_bracket;
1066 	  ++tok;
1067 	  ++num_args;
1068 	  break;
1069 
1070 	case '@':
1071 	  /* We have labels, function names and relocations, all
1072 	     starting with @ symbol.  Sort them out.  */
1073 	  if ((saw_arg && !saw_comma) || num_args == ntok)
1074 	    goto err;
1075 
1076 	  /* Parse @label.  */
1077 	  tok->X_op = O_symbol;
1078 	  tok->X_md = O_absent;
1079 	  expression (tok);
1080 	  if (*input_line_pointer != '@')
1081 	    goto normalsymbol; /* This is not a relocation.  */
1082 
1083 	relocationsym:
1084 
1085 	  /* A relocation opernad has the following form
1086 	     @identifier@relocation_type.  The identifier is already
1087 	     in tok!  */
1088 	  if (tok->X_op != O_symbol)
1089 	    {
1090 	      as_bad (_("No valid label relocation operand"));
1091 	      goto err;
1092 	    }
1093 
1094 	  /* Parse @relocation_type.  */
1095 	  input_line_pointer++;
1096 	  c = get_symbol_name (&reloc_name);
1097 	  len = input_line_pointer - reloc_name;
1098 	  if (len == 0)
1099 	    {
1100 	      as_bad (_("No relocation operand"));
1101 	      goto err;
1102 	    }
1103 
1104 	  /* Go through known relocation and try to find a match.  */
1105 	  r = &arc_reloc_op[0];
1106 	  for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
1107 	    if (len == r->length
1108 		&& memcmp (reloc_name, r->name, len) == 0)
1109 	      break;
1110 	  if (i < 0)
1111 	    {
1112 	      as_bad (_("Unknown relocation operand: @%s"), reloc_name);
1113 	      goto err;
1114 	    }
1115 
1116 	  *input_line_pointer = c;
1117 	  SKIP_WHITESPACE_AFTER_NAME ();
1118 	  /* Extra check for TLS: base.  */
1119 	  if (*input_line_pointer == '@')
1120 	    {
1121 	      symbolS *base;
1122 	      if (tok->X_op_symbol != NULL
1123 		  || tok->X_op != O_symbol)
1124 		{
1125 		  as_bad (_("Unable to parse TLS base: %s"),
1126 			  input_line_pointer);
1127 		  goto err;
1128 		}
1129 	      input_line_pointer++;
1130 	      char *sym_name;
1131 	      c = get_symbol_name (&sym_name);
1132 	      base = symbol_find_or_make (sym_name);
1133 	      tok->X_op = O_subtract;
1134 	      tok->X_op_symbol = base;
1135 	      restore_line_pointer (c);
1136 	      tmpE.X_add_number = 0;
1137 	    }
1138 	  else if ((*input_line_pointer != '+')
1139 		   && (*input_line_pointer != '-'))
1140 	    {
1141 	      tmpE.X_add_number = 0;
1142 	    }
1143 	  else
1144 	    {
1145 	      /* Parse the constant of a complex relocation expression
1146 		 like @identifier@reloc +/- const.  */
1147 	      if (! r->complex_expr)
1148 		{
1149 		  as_bad (_("@%s is not a complex relocation."), r->name);
1150 		  goto err;
1151 		}
1152 	      expression (&tmpE);
1153 	      if (tmpE.X_op != O_constant)
1154 		{
1155 		  as_bad (_("Bad expression: @%s + %s."),
1156 			  r->name, input_line_pointer);
1157 		  goto err;
1158 		}
1159 	    }
1160 
1161 	  tok->X_md = r->op;
1162 	  tok->X_add_number = tmpE.X_add_number;
1163 
1164 	  debug_exp (tok);
1165 
1166 	  saw_comma = FALSE;
1167 	  saw_arg = TRUE;
1168 	  tok++;
1169 	  num_args++;
1170 	  break;
1171 
1172 	case '%':
1173 	  /* Can be a register.  */
1174 	  ++input_line_pointer;
1175 	  /* Fall through.  */
1176 	default:
1177 
1178 	  if ((saw_arg && !saw_comma) || num_args == ntok)
1179 	    goto err;
1180 
1181 	  tok->X_op = O_absent;
1182 	  tok->X_md = O_absent;
1183 	  expression (tok);
1184 
1185 	  /* Legacy: There are cases when we have
1186 	     identifier@relocation_type, if it is the case parse the
1187 	     relocation type as well.  */
1188 	  if (*input_line_pointer == '@')
1189 	    goto relocationsym;
1190 
1191 	normalsymbol:
1192 	  debug_exp (tok);
1193 
1194 	  if (tok->X_op == O_illegal
1195               || tok->X_op == O_absent
1196               || num_args == ntok)
1197 	    goto err;
1198 
1199 	  saw_comma = FALSE;
1200 	  saw_arg = TRUE;
1201 	  tok++;
1202 	  num_args++;
1203 	  break;
1204 	}
1205     }
1206 
1207  fini:
1208   if (saw_comma || brk_lvl)
1209     goto err;
1210   input_line_pointer = old_input_line_pointer;
1211 
1212   return num_args;
1213 
1214  err:
1215   if (brk_lvl)
1216     as_bad (_("Brackets in operand field incorrect"));
1217   else if (saw_comma)
1218     as_bad (_("extra comma"));
1219   else if (!saw_arg)
1220     as_bad (_("missing argument"));
1221   else
1222     as_bad (_("missing comma or colon"));
1223   input_line_pointer = old_input_line_pointer;
1224   return -1;
1225 }
1226 
1227 /* Parse the flags to a structure.  */
1228 
1229 static int
tokenize_flags(const char * str,struct arc_flags flags[],int nflg)1230 tokenize_flags (const char *str,
1231 		struct arc_flags flags[],
1232 		int nflg)
1233 {
1234   char *old_input_line_pointer;
1235   bfd_boolean saw_flg = FALSE;
1236   bfd_boolean saw_dot = FALSE;
1237   int num_flags  = 0;
1238   size_t flgnamelen;
1239 
1240   memset (flags, 0, sizeof (*flags) * nflg);
1241 
1242   /* Save and restore input_line_pointer around this function.  */
1243   old_input_line_pointer = input_line_pointer;
1244   input_line_pointer = (char *) str;
1245 
1246   while (*input_line_pointer)
1247     {
1248       switch (*input_line_pointer)
1249 	{
1250 	case ' ':
1251 	case '\0':
1252 	  goto fini;
1253 
1254 	case '.':
1255 	  input_line_pointer++;
1256 	  if (saw_dot)
1257 	    goto err;
1258 	  saw_dot = TRUE;
1259 	  saw_flg = FALSE;
1260 	  break;
1261 
1262 	default:
1263 	  if (saw_flg && !saw_dot)
1264 	    goto err;
1265 
1266 	  if (num_flags >= nflg)
1267 	    goto err;
1268 
1269 	  flgnamelen = strspn (input_line_pointer,
1270 			       "abcdefghijklmnopqrstuvwxyz0123456789");
1271 	  if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1272 	    goto err;
1273 
1274 	  memcpy (flags->name, input_line_pointer, flgnamelen);
1275 
1276 	  input_line_pointer += flgnamelen;
1277 	  flags++;
1278 	  saw_dot = FALSE;
1279 	  saw_flg = TRUE;
1280 	  num_flags++;
1281 	  break;
1282 	}
1283     }
1284 
1285  fini:
1286   input_line_pointer = old_input_line_pointer;
1287   return num_flags;
1288 
1289  err:
1290   if (saw_dot)
1291     as_bad (_("extra dot"));
1292   else if (!saw_flg)
1293     as_bad (_("unrecognized flag"));
1294   else
1295     as_bad (_("failed to parse flags"));
1296   input_line_pointer = old_input_line_pointer;
1297   return -1;
1298 }
1299 
1300 /* Apply the fixups in order.  */
1301 
1302 static void
apply_fixups(struct arc_insn * insn,fragS * fragP,int fix)1303 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1304 {
1305   int i;
1306 
1307   for (i = 0; i < insn->nfixups; i++)
1308     {
1309       struct arc_fixup *fixup = &insn->fixups[i];
1310       int size, pcrel, offset = 0;
1311 
1312       /* FIXME! the reloc size is wrong in the BFD file.
1313 	 When it is fixed please delete me.  */
1314       size = (insn->short_insn && !fixup->islong) ? 2 : 4;
1315 
1316       if (fixup->islong)
1317 	offset = (insn->short_insn) ? 2 : 4;
1318 
1319       /* Some fixups are only used internally, thus no howto.  */
1320       if ((int) fixup->reloc == 0)
1321 	as_fatal (_("Unhandled reloc type"));
1322 
1323       if ((int) fixup->reloc < 0)
1324 	{
1325 	  /* FIXME! the reloc size is wrong in the BFD file.
1326 	     When it is fixed please enable me.
1327 	     size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1328 	  pcrel = fixup->pcrel;
1329 	}
1330       else
1331 	{
1332 	  reloc_howto_type *reloc_howto =
1333 	    bfd_reloc_type_lookup (stdoutput,
1334 				   (bfd_reloc_code_real_type) fixup->reloc);
1335 	  gas_assert (reloc_howto);
1336 
1337 	  /* FIXME! the reloc size is wrong in the BFD file.
1338 	     When it is fixed please enable me.
1339 	     size = bfd_get_reloc_size (reloc_howto); */
1340 	  pcrel = reloc_howto->pc_relative;
1341 	}
1342 
1343       pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1344 offset %d + %d\n",
1345 		fragP->fr_file, fragP->fr_line,
1346 		(fixup->reloc < 0) ? "Internal" :
1347 		bfd_get_reloc_code_name (fixup->reloc),
1348 		pcrel ? "Y" : "N",
1349 		size, fix, offset);
1350       fix_new_exp (fragP, fix + offset,
1351 		   size, &fixup->exp, pcrel, fixup->reloc);
1352 
1353       /* Check for ZOLs, and update symbol info if any.  */
1354       if (LP_INSN (insn->insn))
1355 	{
1356 	  gas_assert (fixup->exp.X_add_symbol);
1357 	  ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1358 	}
1359     }
1360 }
1361 
1362 /* Actually output an instruction with its fixup.  */
1363 
1364 static void
emit_insn0(struct arc_insn * insn,char * where,bfd_boolean relax)1365 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1366 {
1367   char *f = where;
1368 
1369   pr_debug ("Emit insn : 0x%x\n", insn->insn);
1370   pr_debug ("\tShort   : 0x%d\n", insn->short_insn);
1371   pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1372 
1373   /* Write out the instruction.  */
1374   if (insn->short_insn)
1375     {
1376       if (insn->has_limm)
1377 	{
1378 	  if (!relax)
1379 	    f = frag_more (6);
1380 	  md_number_to_chars (f, insn->insn, 2);
1381 	  md_number_to_chars_midend (f + 2, insn->limm, 4);
1382 	  dwarf2_emit_insn (6);
1383 	}
1384       else
1385 	{
1386 	  if (!relax)
1387 	    f = frag_more (2);
1388 	  md_number_to_chars (f, insn->insn, 2);
1389 	  dwarf2_emit_insn (2);
1390 	}
1391     }
1392   else
1393     {
1394       if (insn->has_limm)
1395 	{
1396 	  if (!relax)
1397 	    f = frag_more (8);
1398 	  md_number_to_chars_midend (f, insn->insn, 4);
1399 	  md_number_to_chars_midend (f + 4, insn->limm, 4);
1400 	  dwarf2_emit_insn (8);
1401 	}
1402       else
1403 	{
1404 	  if (!relax)
1405 	    f = frag_more (4);
1406 	  md_number_to_chars_midend (f, insn->insn, 4);
1407 	  dwarf2_emit_insn (4);
1408 	}
1409     }
1410 
1411   if (!relax)
1412     apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1413 }
1414 
1415 static void
emit_insn1(struct arc_insn * insn)1416 emit_insn1 (struct arc_insn *insn)
1417 {
1418   /* How frag_var's args are currently configured:
1419      - rs_machine_dependent, to dictate it's a relaxation frag.
1420      - FRAG_MAX_GROWTH, maximum size of instruction
1421      - 0, variable size that might grow...unused by generic relaxation.
1422      - frag_now->fr_subtype, fr_subtype starting value, set previously.
1423      - s, opand expression.
1424      - 0, offset but it's unused.
1425      - 0, opcode but it's unused.  */
1426   symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1427   frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1428 
1429   if (frag_room () < FRAG_MAX_GROWTH)
1430     {
1431       /* Handle differently when frag literal memory is exhausted.
1432 	 This is used because when there's not enough memory left in
1433 	 the current frag, a new frag is created and the information
1434 	 we put into frag_now->tc_frag_data is disregarded.  */
1435 
1436       struct arc_relax_type relax_info_copy;
1437       relax_substateT subtype = frag_now->fr_subtype;
1438 
1439       memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1440 	      sizeof (struct arc_relax_type));
1441 
1442       frag_wane (frag_now);
1443       frag_grow (FRAG_MAX_GROWTH);
1444 
1445       memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1446 	      sizeof (struct arc_relax_type));
1447 
1448       frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1449 		subtype, s, 0, 0);
1450     }
1451   else
1452     frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1453 	      frag_now->fr_subtype, s, 0, 0);
1454 }
1455 
1456 static void
emit_insn(struct arc_insn * insn)1457 emit_insn (struct arc_insn *insn)
1458 {
1459   if (insn->relax)
1460     emit_insn1 (insn);
1461   else
1462     emit_insn0 (insn, NULL, FALSE);
1463 }
1464 
1465 /* Check whether a symbol involves a register.  */
1466 
1467 static bfd_boolean
contains_register(symbolS * sym)1468 contains_register (symbolS *sym)
1469 {
1470   if (sym)
1471     {
1472       expressionS *ex = symbol_get_value_expression (sym);
1473 
1474       return ((O_register == ex->X_op)
1475 	      && !contains_register (ex->X_add_symbol)
1476 	      && !contains_register (ex->X_op_symbol));
1477     }
1478 
1479   return FALSE;
1480 }
1481 
1482 /* Returns the register number within a symbol.  */
1483 
1484 static int
get_register(symbolS * sym)1485 get_register (symbolS *sym)
1486 {
1487   if (!contains_register (sym))
1488     return -1;
1489 
1490   expressionS *ex = symbol_get_value_expression (sym);
1491   return regno (ex->X_add_number);
1492 }
1493 
1494 /* Return true if a RELOC is generic.  A generic reloc is PC-rel of a
1495    simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32.  */
1496 
1497 static bfd_boolean
generic_reloc_p(extended_bfd_reloc_code_real_type reloc)1498 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1499 {
1500   if (!reloc)
1501     return FALSE;
1502 
1503   switch (reloc)
1504     {
1505     case BFD_RELOC_ARC_SDA_LDST:
1506     case BFD_RELOC_ARC_SDA_LDST1:
1507     case BFD_RELOC_ARC_SDA_LDST2:
1508     case BFD_RELOC_ARC_SDA16_LD:
1509     case BFD_RELOC_ARC_SDA16_LD1:
1510     case BFD_RELOC_ARC_SDA16_LD2:
1511     case BFD_RELOC_ARC_SDA16_ST2:
1512     case BFD_RELOC_ARC_SDA32_ME:
1513       return FALSE;
1514     default:
1515       return TRUE;
1516     }
1517 }
1518 
1519 /* Allocates a tok entry.  */
1520 
1521 static int
allocate_tok(expressionS * tok,int ntok,int cidx)1522 allocate_tok (expressionS *tok, int ntok, int cidx)
1523 {
1524   if (ntok > MAX_INSN_ARGS - 2)
1525     return 0; /* No space left.  */
1526 
1527   if (cidx > ntok)
1528     return 0; /* Incorect args.  */
1529 
1530   memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1531 
1532   if (cidx == ntok)
1533     return 1; /* Success.  */
1534   return allocate_tok (tok, ntok - 1, cidx);
1535 }
1536 
1537 /* Check if an particular ARC feature is enabled.  */
1538 
1539 static bfd_boolean
check_cpu_feature(insn_subclass_t sc)1540 check_cpu_feature (insn_subclass_t sc)
1541 {
1542   if (is_code_density_p (sc) && !(arc_features & ARC_CD))
1543     return FALSE;
1544 
1545   if (is_spfp_p (sc) && !(arc_features & ARC_SPFP))
1546     return FALSE;
1547 
1548   if (is_dpfp_p (sc) && !(arc_features & ARC_DPFP))
1549     return FALSE;
1550 
1551   if (is_fpuda_p (sc) && !(arc_features & ARC_FPUDA))
1552     return FALSE;
1553 
1554   if (is_nps400_p (sc) && !(arc_features & ARC_NPS400))
1555     return FALSE;
1556 
1557   return TRUE;
1558 }
1559 
1560 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1561    operands in OPCODE.  Stores the matching OPCODES into the FIRST_PFLAG
1562    array and returns TRUE if the flag operands all match, otherwise,
1563    returns FALSE, in which case the FIRST_PFLAG array may have been
1564    modified.  */
1565 
1566 static bfd_boolean
parse_opcode_flags(const struct arc_opcode * opcode,int nflgs,struct arc_flags * first_pflag)1567 parse_opcode_flags (const struct arc_opcode *opcode,
1568                     int nflgs,
1569                     struct arc_flags *first_pflag)
1570 {
1571   int lnflg, i;
1572   const unsigned char *flgidx;
1573 
1574   lnflg = nflgs;
1575   for (i = 0; i < nflgs; i++)
1576     first_pflag[i].flgp = NULL;
1577 
1578   /* Check the flags.  Iterate over the valid flag classes.  */
1579   for (flgidx = opcode->flags; *flgidx; ++flgidx)
1580     {
1581       /* Get a valid flag class.  */
1582       const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1583       const unsigned *flgopridx;
1584       int cl_matches = 0;
1585       struct arc_flags *pflag = NULL;
1586 
1587       /* Check for extension conditional codes.  */
1588       if (ext_condcode.arc_ext_condcode
1589           && cl_flags->flag_class & F_CLASS_EXTEND)
1590         {
1591           struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
1592           while (pf->name)
1593             {
1594               pflag = first_pflag;
1595               for (i = 0; i < nflgs; i++, pflag++)
1596                 {
1597                   if (!strcmp (pf->name, pflag->name))
1598                     {
1599                       if (pflag->flgp != NULL)
1600                         return FALSE;
1601                       /* Found it.  */
1602                       cl_matches++;
1603                       pflag->flgp = pf;
1604                       lnflg--;
1605                       break;
1606                     }
1607                 }
1608               pf++;
1609             }
1610         }
1611 
1612       for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1613         {
1614           const struct arc_flag_operand *flg_operand;
1615 
1616           pflag = first_pflag;
1617           flg_operand = &arc_flag_operands[*flgopridx];
1618           for (i = 0; i < nflgs; i++, pflag++)
1619             {
1620               /* Match against the parsed flags.  */
1621               if (!strcmp (flg_operand->name, pflag->name))
1622                 {
1623                   if (pflag->flgp != NULL)
1624                     return FALSE;
1625                   cl_matches++;
1626                   pflag->flgp = flg_operand;
1627                   lnflg--;
1628                   break; /* goto next flag class and parsed flag.  */
1629                 }
1630             }
1631         }
1632 
1633       if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0)
1634         return FALSE;
1635       if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1)
1636         return FALSE;
1637     }
1638 
1639   /* Did I check all the parsed flags?  */
1640   return lnflg ? FALSE : TRUE;
1641 }
1642 
1643 
1644 /* Search forward through all variants of an opcode looking for a
1645    syntax match.  */
1646 
1647 static const struct arc_opcode *
find_opcode_match(const struct arc_opcode_hash_entry * entry,expressionS * tok,int * pntok,struct arc_flags * first_pflag,int nflgs,int * pcpumatch)1648 find_opcode_match (const struct arc_opcode_hash_entry *entry,
1649 		   expressionS *tok,
1650 		   int *pntok,
1651 		   struct arc_flags *first_pflag,
1652 		   int nflgs,
1653 		   int *pcpumatch)
1654 {
1655   const struct arc_opcode *opcode;
1656   struct arc_opcode_hash_entry_iterator iter;
1657   int ntok = *pntok;
1658   int got_cpu_match = 0;
1659   expressionS bktok[MAX_INSN_ARGS];
1660   int bkntok;
1661   expressionS emptyE;
1662 
1663   arc_opcode_hash_entry_iterator_init (&iter);
1664   memset (&emptyE, 0, sizeof (emptyE));
1665   memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1666   bkntok = ntok;
1667 
1668   for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
1669        opcode != NULL;
1670        opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
1671     {
1672       const unsigned char *opidx;
1673       int tokidx = 0;
1674       const expressionS *t = &emptyE;
1675 
1676       pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1677 		frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1678 
1679       /* Don't match opcodes that don't exist on this
1680 	 architecture.  */
1681       if (!(opcode->cpu & arc_target))
1682 	goto match_failed;
1683 
1684       if (!check_cpu_feature (opcode->subclass))
1685 	goto match_failed;
1686 
1687       got_cpu_match = 1;
1688       pr_debug ("cpu ");
1689 
1690       /* Check the operands.  */
1691       for (opidx = opcode->operands; *opidx; ++opidx)
1692 	{
1693 	  const struct arc_operand *operand = &arc_operands[*opidx];
1694 
1695 	  /* Only take input from real operands.  */
1696 	  if ((operand->flags & ARC_OPERAND_FAKE)
1697 	      && !(operand->flags & ARC_OPERAND_BRAKET))
1698 	    continue;
1699 
1700 	  /* When we expect input, make sure we have it.  */
1701 	  if (tokidx >= ntok)
1702 	    goto match_failed;
1703 
1704 	  /* Match operand type with expression type.  */
1705 	  switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1706 	    {
1707 	    case ARC_OPERAND_IR:
1708 	      /* Check to be a register.  */
1709 	      if ((tok[tokidx].X_op != O_register
1710 		   || !is_ir_num (tok[tokidx].X_add_number))
1711 		  && !(operand->flags & ARC_OPERAND_IGNORE))
1712 		goto match_failed;
1713 
1714 	      /* If expect duplicate, make sure it is duplicate.  */
1715 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
1716 		{
1717 		  /* Check for duplicate.  */
1718 		  if (t->X_op != O_register
1719 		      || !is_ir_num (t->X_add_number)
1720 		      || (regno (t->X_add_number) !=
1721 			  regno (tok[tokidx].X_add_number)))
1722 		    goto match_failed;
1723 		}
1724 
1725 	      /* Special handling?  */
1726 	      if (operand->insert)
1727 		{
1728 		  const char *errmsg = NULL;
1729 		  (*operand->insert)(0,
1730 				     regno (tok[tokidx].X_add_number),
1731 				     &errmsg);
1732 		  if (errmsg)
1733 		    {
1734 		      if (operand->flags & ARC_OPERAND_IGNORE)
1735 			{
1736 			  /* Missing argument, create one.  */
1737 			  if (!allocate_tok (tok, ntok - 1, tokidx))
1738 			    goto match_failed;
1739 
1740 			  tok[tokidx].X_op = O_absent;
1741 			  ++ntok;
1742 			}
1743 		      else
1744 			goto match_failed;
1745 		    }
1746 		}
1747 
1748 	      t = &tok[tokidx];
1749 	      break;
1750 
1751 	    case ARC_OPERAND_BRAKET:
1752 	      /* Check if bracket is also in opcode table as
1753 		 operand.  */
1754 	      if (tok[tokidx].X_op != O_bracket)
1755 		goto match_failed;
1756 	      break;
1757 
1758 	    case ARC_OPERAND_LIMM:
1759 	    case ARC_OPERAND_SIGNED:
1760 	    case ARC_OPERAND_UNSIGNED:
1761 	      switch (tok[tokidx].X_op)
1762 		{
1763 		case O_illegal:
1764 		case O_absent:
1765 		case O_register:
1766 		  goto match_failed;
1767 
1768 		case O_bracket:
1769 		  /* Got an (too) early bracket, check if it is an
1770 		     ignored operand.  N.B. This procedure works only
1771 		     when bracket is the last operand!  */
1772 		  if (!(operand->flags & ARC_OPERAND_IGNORE))
1773 		    goto match_failed;
1774 		  /* Insert the missing operand.  */
1775 		  if (!allocate_tok (tok, ntok - 1, tokidx))
1776 		    goto match_failed;
1777 
1778 		  tok[tokidx].X_op = O_absent;
1779 		  ++ntok;
1780 		  break;
1781 
1782 		case O_symbol:
1783 		  {
1784 		    const char *p;
1785 		    const struct arc_aux_reg *auxr;
1786 
1787 		    if (opcode->insn_class != AUXREG)
1788 		      goto de_fault;
1789 		    p = S_GET_NAME (tok[tokidx].X_add_symbol);
1790 
1791 		    auxr = hash_find (arc_aux_hash, p);
1792 		    if (auxr)
1793 		      {
1794 			/* We modify the token array here, safe in the
1795 			   knowledge, that if this was the wrong
1796 			   choice then the original contents will be
1797 			   restored from BKTOK.  */
1798 			tok[tokidx].X_op = O_constant;
1799 			tok[tokidx].X_add_number = auxr->address;
1800 			ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
1801 		      }
1802 
1803 		    if (tok[tokidx].X_op != O_constant)
1804 		      goto de_fault;
1805 		  }
1806 		  /* Fall-through */
1807 		case O_constant:
1808 		  /* Check the range.  */
1809 		  if (operand->bits != 32
1810 		      && !(operand->flags & ARC_OPERAND_NCHK))
1811 		    {
1812 		      offsetT min, max, val;
1813 		      val = tok[tokidx].X_add_number;
1814 
1815 		      if (operand->flags & ARC_OPERAND_SIGNED)
1816 			{
1817 			  max = (1 << (operand->bits - 1)) - 1;
1818 			  min = -(1 << (operand->bits - 1));
1819 			}
1820 		      else
1821 			{
1822 			  max = (1 << operand->bits) - 1;
1823 			  min = 0;
1824 			}
1825 
1826 		      if (val < min || val > max)
1827 			goto match_failed;
1828 
1829 		      /* Check alignmets.  */
1830 		      if ((operand->flags & ARC_OPERAND_ALIGNED32)
1831 			  && (val & 0x03))
1832 			goto match_failed;
1833 
1834 		      if ((operand->flags & ARC_OPERAND_ALIGNED16)
1835 			  && (val & 0x01))
1836 			goto match_failed;
1837 		    }
1838 		  else if (operand->flags & ARC_OPERAND_NCHK)
1839 		    {
1840 		      if (operand->insert)
1841 			{
1842 			  const char *errmsg = NULL;
1843 			  (*operand->insert)(0,
1844 					     tok[tokidx].X_add_number,
1845 					     &errmsg);
1846 			  if (errmsg)
1847 			    goto match_failed;
1848 			}
1849 		      else if (!(operand->flags & ARC_OPERAND_IGNORE))
1850 			goto match_failed;
1851 		    }
1852 		  break;
1853 
1854 		case O_subtract:
1855 		  /* Check if it is register range.  */
1856 		  if ((tok[tokidx].X_add_number == 0)
1857 		      && contains_register (tok[tokidx].X_add_symbol)
1858 		      && contains_register (tok[tokidx].X_op_symbol))
1859 		    {
1860 		      int regs;
1861 
1862 		      regs = get_register (tok[tokidx].X_add_symbol);
1863 		      regs <<= 16;
1864 		      regs |= get_register (tok[tokidx].X_op_symbol);
1865 		      if (operand->insert)
1866 			{
1867 			  const char *errmsg = NULL;
1868 			  (*operand->insert)(0,
1869 					     regs,
1870 					     &errmsg);
1871 			  if (errmsg)
1872 			    goto match_failed;
1873 			}
1874 		      else
1875 			goto match_failed;
1876 		      break;
1877 		    }
1878 		default:
1879 		de_fault:
1880 		  if (operand->default_reloc == 0)
1881 		    goto match_failed; /* The operand needs relocation.  */
1882 
1883 		  /* Relocs requiring long immediate.  FIXME! make it
1884 		     generic and move it to a function.  */
1885 		  switch (tok[tokidx].X_md)
1886 		    {
1887 		    case O_gotoff:
1888 		    case O_gotpc:
1889 		    case O_pcl:
1890 		    case O_tpoff:
1891 		    case O_dtpoff:
1892 		    case O_tlsgd:
1893 		    case O_tlsie:
1894 		      if (!(operand->flags & ARC_OPERAND_LIMM))
1895 			goto match_failed;
1896 		    case O_absent:
1897 		      if (!generic_reloc_p (operand->default_reloc))
1898 			goto match_failed;
1899 		    default:
1900 		      break;
1901 		    }
1902 		  break;
1903 		}
1904 	      /* If expect duplicate, make sure it is duplicate.  */
1905 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
1906 		{
1907 		  if (t->X_op == O_illegal
1908 		      || t->X_op == O_absent
1909 		      || t->X_op == O_register
1910 		      || (t->X_add_number != tok[tokidx].X_add_number))
1911 		    goto match_failed;
1912 		}
1913 	      t = &tok[tokidx];
1914 	      break;
1915 
1916 	    default:
1917 	      /* Everything else should have been fake.  */
1918 	      abort ();
1919 	    }
1920 
1921 	  ++tokidx;
1922 	}
1923       pr_debug ("opr ");
1924 
1925       /* Setup ready for flag parsing.  */
1926       if (!parse_opcode_flags (opcode, nflgs, first_pflag))
1927 	goto match_failed;
1928 
1929       pr_debug ("flg");
1930       /* Possible match -- did we use all of our input?  */
1931       if (tokidx == ntok)
1932 	{
1933 	  *pntok = ntok;
1934 	  pr_debug ("\n");
1935 	  return opcode;
1936 	}
1937 
1938     match_failed:;
1939       pr_debug ("\n");
1940       /* Restore the original parameters.  */
1941       memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
1942       ntok = bkntok;
1943     }
1944 
1945   if (*pcpumatch)
1946     *pcpumatch = got_cpu_match;
1947 
1948   return NULL;
1949 }
1950 
1951 /* Swap operand tokens.  */
1952 
1953 static void
swap_operand(expressionS * operand_array,unsigned source,unsigned destination)1954 swap_operand (expressionS *operand_array,
1955 	      unsigned source,
1956 	      unsigned destination)
1957 {
1958   expressionS cpy_operand;
1959   expressionS *src_operand;
1960   expressionS *dst_operand;
1961   size_t size;
1962 
1963   if (source == destination)
1964     return;
1965 
1966   src_operand = &operand_array[source];
1967   dst_operand = &operand_array[destination];
1968   size = sizeof (expressionS);
1969 
1970   /* Make copy of operand to swap with and swap.  */
1971   memcpy (&cpy_operand, dst_operand, size);
1972   memcpy (dst_operand, src_operand, size);
1973   memcpy (src_operand, &cpy_operand, size);
1974 }
1975 
1976 /* Check if *op matches *tok type.
1977    Returns FALSE if they don't match, TRUE if they match.  */
1978 
1979 static bfd_boolean
pseudo_operand_match(const expressionS * tok,const struct arc_operand_operation * op)1980 pseudo_operand_match (const expressionS *tok,
1981 		      const struct arc_operand_operation *op)
1982 {
1983   offsetT min, max, val;
1984   bfd_boolean ret;
1985   const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1986 
1987   ret = FALSE;
1988   switch (tok->X_op)
1989     {
1990     case O_constant:
1991       if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1992 	ret = 1;
1993       else if (!(operand_real->flags & ARC_OPERAND_IR))
1994 	{
1995 	  val = tok->X_add_number + op->count;
1996 	  if (operand_real->flags & ARC_OPERAND_SIGNED)
1997 	    {
1998 	      max = (1 << (operand_real->bits - 1)) - 1;
1999 	      min = -(1 << (operand_real->bits - 1));
2000 	    }
2001 	  else
2002 	    {
2003 	      max = (1 << operand_real->bits) - 1;
2004 	      min = 0;
2005 	    }
2006 	  if (min <= val && val <= max)
2007 	    ret = TRUE;
2008 	}
2009       break;
2010 
2011     case O_symbol:
2012       /* Handle all symbols as long immediates or signed 9.  */
2013       if (operand_real->flags & ARC_OPERAND_LIMM ||
2014 	  ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
2015 	ret = TRUE;
2016       break;
2017 
2018     case O_register:
2019       if (operand_real->flags & ARC_OPERAND_IR)
2020 	ret = TRUE;
2021       break;
2022 
2023     case O_bracket:
2024       if (operand_real->flags & ARC_OPERAND_BRAKET)
2025 	ret = TRUE;
2026       break;
2027 
2028     default:
2029       /* Unknown.  */
2030       break;
2031     }
2032   return ret;
2033 }
2034 
2035 /* Find pseudo instruction in array.  */
2036 
2037 static const struct arc_pseudo_insn *
find_pseudo_insn(const char * opname,int ntok,const expressionS * tok)2038 find_pseudo_insn (const char *opname,
2039 		  int ntok,
2040 		  const expressionS *tok)
2041 {
2042   const struct arc_pseudo_insn *pseudo_insn = NULL;
2043   const struct arc_operand_operation *op;
2044   unsigned int i;
2045   int j;
2046 
2047   for (i = 0; i < arc_num_pseudo_insn; ++i)
2048     {
2049       pseudo_insn = &arc_pseudo_insns[i];
2050       if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2051 	{
2052 	  op = pseudo_insn->operand;
2053 	  for (j = 0; j < ntok; ++j)
2054 	    if (!pseudo_operand_match (&tok[j], &op[j]))
2055 	      break;
2056 
2057 	  /* Found the right instruction.  */
2058 	  if (j == ntok)
2059 	    return pseudo_insn;
2060 	}
2061     }
2062   return NULL;
2063 }
2064 
2065 /* Assumes the expressionS *tok is of sufficient size.  */
2066 
2067 static const struct arc_opcode_hash_entry *
find_special_case_pseudo(const char * opname,int * ntok,expressionS * tok,int * nflgs,struct arc_flags * pflags)2068 find_special_case_pseudo (const char *opname,
2069 			  int *ntok,
2070 			  expressionS *tok,
2071 			  int *nflgs,
2072 			  struct arc_flags *pflags)
2073 {
2074   const struct arc_pseudo_insn *pseudo_insn = NULL;
2075   const struct arc_operand_operation *operand_pseudo;
2076   const struct arc_operand *operand_real;
2077   unsigned i;
2078   char construct_operand[MAX_CONSTR_STR];
2079 
2080   /* Find whether opname is in pseudo instruction array.  */
2081   pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2082 
2083   if (pseudo_insn == NULL)
2084     return NULL;
2085 
2086   /* Handle flag, Limited to one flag at the moment.  */
2087   if (pseudo_insn->flag_r != NULL)
2088     *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2089 			      MAX_INSN_FLGS - *nflgs);
2090 
2091   /* Handle operand operations.  */
2092   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2093     {
2094       operand_pseudo = &pseudo_insn->operand[i];
2095       operand_real = &arc_operands[operand_pseudo->operand_idx];
2096 
2097       if (operand_real->flags & ARC_OPERAND_BRAKET &&
2098 	  !operand_pseudo->needs_insert)
2099 	continue;
2100 
2101       /* Has to be inserted (i.e. this token does not exist yet).  */
2102       if (operand_pseudo->needs_insert)
2103 	{
2104 	  if (operand_real->flags & ARC_OPERAND_BRAKET)
2105 	    {
2106 	      tok[i].X_op = O_bracket;
2107 	      ++(*ntok);
2108 	      continue;
2109 	    }
2110 
2111 	  /* Check if operand is a register or constant and handle it
2112 	     by type.  */
2113 	  if (operand_real->flags & ARC_OPERAND_IR)
2114 	    snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2115 		      operand_pseudo->count);
2116 	  else
2117 	    snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2118 		      operand_pseudo->count);
2119 
2120 	  tokenize_arguments (construct_operand, &tok[i], 1);
2121 	  ++(*ntok);
2122 	}
2123 
2124       else if (operand_pseudo->count)
2125 	{
2126 	  /* Operand number has to be adjusted accordingly (by operand
2127 	     type).  */
2128 	  switch (tok[i].X_op)
2129 	    {
2130 	    case O_constant:
2131 	      tok[i].X_add_number += operand_pseudo->count;
2132 	      break;
2133 
2134 	    case O_symbol:
2135 	      break;
2136 
2137 	    default:
2138 	      /* Ignored.  */
2139 	      break;
2140 	    }
2141 	}
2142     }
2143 
2144   /* Swap operands if necessary.  Only supports one swap at the
2145      moment.  */
2146   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2147     {
2148       operand_pseudo = &pseudo_insn->operand[i];
2149 
2150       if (operand_pseudo->swap_operand_idx == i)
2151 	continue;
2152 
2153       swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2154 
2155       /* Prevent a swap back later by breaking out.  */
2156       break;
2157     }
2158 
2159   return arc_find_opcode (pseudo_insn->mnemonic_r);
2160 }
2161 
2162 static const struct arc_opcode_hash_entry *
find_special_case_flag(const char * opname,int * nflgs,struct arc_flags * pflags)2163 find_special_case_flag (const char *opname,
2164 			int *nflgs,
2165 			struct arc_flags *pflags)
2166 {
2167   unsigned int i;
2168   const char *flagnm;
2169   unsigned flag_idx, flag_arr_idx;
2170   size_t flaglen, oplen;
2171   const struct arc_flag_special *arc_flag_special_opcode;
2172   const struct arc_opcode_hash_entry *entry;
2173 
2174   /* Search for special case instruction.  */
2175   for (i = 0; i < arc_num_flag_special; i++)
2176     {
2177       arc_flag_special_opcode = &arc_flag_special_cases[i];
2178       oplen = strlen (arc_flag_special_opcode->name);
2179 
2180       if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2181 	continue;
2182 
2183       /* Found a potential special case instruction, now test for
2184 	 flags.  */
2185       for (flag_arr_idx = 0;; ++flag_arr_idx)
2186 	{
2187 	  flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2188 	  if (flag_idx == 0)
2189 	    break;  /* End of array, nothing found.  */
2190 
2191 	  flagnm = arc_flag_operands[flag_idx].name;
2192 	  flaglen = strlen (flagnm);
2193 	  if (strcmp (opname + oplen, flagnm) == 0)
2194 	    {
2195               entry = arc_find_opcode (arc_flag_special_opcode->name);
2196 
2197 	      if (*nflgs + 1 > MAX_INSN_FLGS)
2198 		break;
2199 	      memcpy (pflags[*nflgs].name, flagnm, flaglen);
2200 	      pflags[*nflgs].name[flaglen] = '\0';
2201 	      (*nflgs)++;
2202 	      return entry;
2203 	    }
2204 	}
2205     }
2206   return NULL;
2207 }
2208 
2209 /* The long instructions are not stored in a hash (there's not many of
2210    them) and so there's no arc_opcode_hash_entry structure to return.  This
2211    helper function for find_special_case_long_opcode takes an arc_opcode
2212    result and places it into a fake arc_opcode_hash_entry that points to
2213    the single arc_opcode OPCODE, which is then returned.  */
2214 
2215 static const struct arc_opcode_hash_entry *
build_fake_opcode_hash_entry(const struct arc_opcode * opcode)2216 build_fake_opcode_hash_entry (const struct arc_opcode *opcode)
2217 {
2218   static struct arc_opcode_hash_entry entry;
2219   static struct arc_opcode tmp[2];
2220   static const struct arc_opcode *ptr[2];
2221 
2222   memcpy (&tmp[0], opcode, sizeof (struct arc_opcode));
2223   memset (&tmp[1], 0, sizeof (struct arc_opcode));
2224   entry.count = 1;
2225   entry.opcode = ptr;
2226   ptr[0] = tmp;
2227   ptr[1] = NULL;
2228   return &entry;
2229 }
2230 
2231 
2232 /* Used by the assembler to match the list of tokens against a long (48 or
2233    64 bits) instruction.  If a matching long instruction is found, then
2234    some of the tokens are consumed in this function and converted into a
2235    single LIMM value, which is then added to the end of the token list,
2236    where it will be consumed by a LIMM operand that exists in the base
2237    opcode of the long instruction.  */
2238 
2239 static const struct arc_opcode_hash_entry *
find_special_case_long_opcode(const char * opname,int * ntok ATTRIBUTE_UNUSED,expressionS * tok ATTRIBUTE_UNUSED,int * nflgs,struct arc_flags * pflags)2240 find_special_case_long_opcode (const char *opname,
2241                                int *ntok ATTRIBUTE_UNUSED,
2242                                expressionS *tok ATTRIBUTE_UNUSED,
2243                                int *nflgs,
2244                                struct arc_flags *pflags)
2245 {
2246   unsigned i;
2247 
2248   if (*ntok == MAX_INSN_ARGS)
2249     return NULL;
2250 
2251   for (i = 0; i < arc_num_long_opcodes; ++i)
2252     {
2253       struct arc_opcode fake_opcode;
2254       const struct arc_opcode *opcode;
2255       struct arc_insn insn;
2256       expressionS *limm_token;
2257 
2258       opcode = &arc_long_opcodes[i].base_opcode;
2259 
2260       if (!(opcode->cpu & arc_target))
2261         continue;
2262 
2263       if (!check_cpu_feature (opcode->subclass))
2264         continue;
2265 
2266       if (strcmp (opname, opcode->name) != 0)
2267         continue;
2268 
2269       /* Check that the flags are a match.  */
2270       if (!parse_opcode_flags (opcode, *nflgs, pflags))
2271         continue;
2272 
2273       /* Parse the LIMM operands into the LIMM template.  */
2274       memset (&fake_opcode, 0, sizeof (fake_opcode));
2275       fake_opcode.name = "fake limm";
2276       fake_opcode.opcode = arc_long_opcodes[i].limm_template;
2277       fake_opcode.mask = arc_long_opcodes[i].limm_mask;
2278       fake_opcode.cpu = opcode->cpu;
2279       fake_opcode.insn_class = opcode->insn_class;
2280       fake_opcode.subclass = opcode->subclass;
2281       memcpy (&fake_opcode.operands[0],
2282               &arc_long_opcodes[i].operands,
2283               MAX_INSN_ARGS);
2284       /* Leave fake_opcode.flags as zero.  */
2285 
2286       pr_debug ("Calling assemble_insn to build fake limm value\n");
2287       assemble_insn (&fake_opcode, tok, *ntok,
2288                      NULL, 0, &insn);
2289       pr_debug ("   got limm value: 0x%x\n", insn.insn);
2290 
2291       /* Now create a new token at the end of the token array (We know this
2292          is safe as the token array is always created with enough space for
2293          MAX_INSN_ARGS, and we check at the start at the start of this
2294          function that we're not there yet).  This new token will
2295          correspond to a LIMM operand that will be contained in the
2296          base_opcode of the arc_long_opcode.  */
2297       limm_token = &tok[(*ntok)];
2298       (*ntok)++;
2299 
2300       /* Modify the LIMM token to hold the constant.  */
2301       limm_token->X_op = O_constant;
2302       limm_token->X_add_number = insn.insn;
2303 
2304       /* Return the base opcode.  */
2305       return build_fake_opcode_hash_entry (opcode);
2306     }
2307 
2308     return NULL;
2309 }
2310 
2311 /* Used to find special case opcode.  */
2312 
2313 static const struct arc_opcode_hash_entry *
find_special_case(const char * opname,int * nflgs,struct arc_flags * pflags,expressionS * tok,int * ntok)2314 find_special_case (const char *opname,
2315 		   int *nflgs,
2316 		   struct arc_flags *pflags,
2317 		   expressionS *tok,
2318 		   int *ntok)
2319 {
2320   const struct arc_opcode_hash_entry *entry;
2321 
2322   entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2323 
2324   if (entry == NULL)
2325     entry = find_special_case_flag (opname, nflgs, pflags);
2326 
2327   if (entry == NULL)
2328     entry = find_special_case_long_opcode (opname, ntok, tok, nflgs, pflags);
2329 
2330   return entry;
2331 }
2332 
2333 /* Given an opcode name, pre-tockenized set of argumenst and the
2334    opcode flags, take it all the way through emission.  */
2335 
2336 static void
assemble_tokens(const char * opname,expressionS * tok,int ntok,struct arc_flags * pflags,int nflgs)2337 assemble_tokens (const char *opname,
2338 		 expressionS *tok,
2339 		 int ntok,
2340 		 struct arc_flags *pflags,
2341 		 int nflgs)
2342 {
2343   bfd_boolean found_something = FALSE;
2344   const struct arc_opcode_hash_entry *entry;
2345   int cpumatch = 1;
2346 
2347   /* Search opcodes.  */
2348   entry = arc_find_opcode (opname);
2349 
2350   /* Couldn't find opcode conventional way, try special cases.  */
2351   if (entry == NULL)
2352     entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2353 
2354   if (entry != NULL)
2355     {
2356       const struct arc_opcode *opcode;
2357 
2358       pr_debug ("%s:%d: assemble_tokens: %s\n",
2359 		frag_now->fr_file, frag_now->fr_line, opname);
2360       found_something = TRUE;
2361       opcode = find_opcode_match (entry, tok, &ntok, pflags,
2362 				  nflgs, &cpumatch);
2363       if (opcode != NULL)
2364 	{
2365 	  struct arc_insn insn;
2366 
2367 	  assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2368 	  emit_insn (&insn);
2369 	  return;
2370 	}
2371     }
2372 
2373   if (found_something)
2374     {
2375       if (cpumatch)
2376 	as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2377       else
2378 	as_bad (_("opcode '%s' not supported for target %s"), opname,
2379 		arc_target_name);
2380     }
2381   else
2382     as_bad (_("unknown opcode '%s'"), opname);
2383 }
2384 
2385 /* The public interface to the instruction assembler.  */
2386 
2387 void
md_assemble(char * str)2388 md_assemble (char *str)
2389 {
2390   char *opname;
2391   expressionS tok[MAX_INSN_ARGS];
2392   int ntok, nflg;
2393   size_t opnamelen;
2394   struct arc_flags flags[MAX_INSN_FLGS];
2395 
2396   /* Split off the opcode.  */
2397   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2398   opname = xmemdup0 (str, opnamelen);
2399 
2400   /* Signalize we are assmbling the instructions.  */
2401   assembling_insn = TRUE;
2402 
2403   /* Tokenize the flags.  */
2404   if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2405     {
2406       as_bad (_("syntax error"));
2407       return;
2408     }
2409 
2410   /* Scan up to the end of the mnemonic which must end in space or end
2411      of string.  */
2412   str += opnamelen;
2413   for (; *str != '\0'; str++)
2414     if (*str == ' ')
2415       break;
2416 
2417   /* Tokenize the rest of the line.  */
2418   if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2419     {
2420       as_bad (_("syntax error"));
2421       return;
2422     }
2423 
2424   /* Finish it off.  */
2425   assemble_tokens (opname, tok, ntok, flags, nflg);
2426   assembling_insn = FALSE;
2427 }
2428 
2429 /* Callback to insert a register into the hash table.  */
2430 
2431 static void
declare_register(const char * name,int number)2432 declare_register (const char *name, int number)
2433 {
2434   const char *err;
2435   symbolS *regS = symbol_create (name, reg_section,
2436 				 number, &zero_address_frag);
2437 
2438   err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2439   if (err)
2440     as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2441 	      name, err);
2442 }
2443 
2444 /* Construct symbols for each of the general registers.  */
2445 
2446 static void
declare_register_set(void)2447 declare_register_set (void)
2448 {
2449   int i;
2450   for (i = 0; i < 64; ++i)
2451     {
2452       char name[7];
2453 
2454       sprintf (name, "r%d", i);
2455       declare_register (name, i);
2456       if ((i & 0x01) == 0)
2457 	{
2458 	  sprintf (name, "r%dr%d", i, i+1);
2459 	  declare_register (name, i);
2460 	}
2461     }
2462 }
2463 
2464 /* Port-specific assembler initialization.  This function is called
2465    once, at assembler startup time.  */
2466 
2467 void
md_begin(void)2468 md_begin (void)
2469 {
2470   const struct arc_opcode *opcode = arc_opcodes;
2471 
2472   if (!mach_type_specified_p)
2473     arc_select_cpu (TARGET_WITH_CPU);
2474 
2475   /* The endianness can be chosen "at the factory".  */
2476   target_big_endian = byte_order == BIG_ENDIAN;
2477 
2478   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
2479     as_warn (_("could not set architecture and machine"));
2480 
2481   /* Set elf header flags.  */
2482   bfd_set_private_flags (stdoutput, arc_eflag);
2483 
2484   /* Set up a hash table for the instructions.  */
2485   arc_opcode_hash = hash_new ();
2486   if (arc_opcode_hash == NULL)
2487     as_fatal (_("Virtual memory exhausted"));
2488 
2489   /* Initialize the hash table with the insns.  */
2490   do
2491     {
2492       const char *name = opcode->name;
2493 
2494       arc_insert_opcode (opcode);
2495 
2496       while (++opcode && opcode->name
2497 	     && (opcode->name == name
2498 		 || !strcmp (opcode->name, name)))
2499 	continue;
2500     }while (opcode->name);
2501 
2502   /* Register declaration.  */
2503   arc_reg_hash = hash_new ();
2504   if (arc_reg_hash == NULL)
2505     as_fatal (_("Virtual memory exhausted"));
2506 
2507   declare_register_set ();
2508   declare_register ("gp", 26);
2509   declare_register ("fp", 27);
2510   declare_register ("sp", 28);
2511   declare_register ("ilink", 29);
2512   declare_register ("ilink1", 29);
2513   declare_register ("ilink2", 30);
2514   declare_register ("blink", 31);
2515 
2516   /* XY memory registers.  */
2517   declare_register ("x0_u0", 32);
2518   declare_register ("x0_u1", 33);
2519   declare_register ("x1_u0", 34);
2520   declare_register ("x1_u1", 35);
2521   declare_register ("x2_u0", 36);
2522   declare_register ("x2_u1", 37);
2523   declare_register ("x3_u0", 38);
2524   declare_register ("x3_u1", 39);
2525   declare_register ("y0_u0", 40);
2526   declare_register ("y0_u1", 41);
2527   declare_register ("y1_u0", 42);
2528   declare_register ("y1_u1", 43);
2529   declare_register ("y2_u0", 44);
2530   declare_register ("y2_u1", 45);
2531   declare_register ("y3_u0", 46);
2532   declare_register ("y3_u1", 47);
2533   declare_register ("x0_nu", 48);
2534   declare_register ("x1_nu", 49);
2535   declare_register ("x2_nu", 50);
2536   declare_register ("x3_nu", 51);
2537   declare_register ("y0_nu", 52);
2538   declare_register ("y1_nu", 53);
2539   declare_register ("y2_nu", 54);
2540   declare_register ("y3_nu", 55);
2541 
2542   declare_register ("mlo", 57);
2543   declare_register ("mmid", 58);
2544   declare_register ("mhi", 59);
2545 
2546   declare_register ("acc1", 56);
2547   declare_register ("acc2", 57);
2548 
2549   declare_register ("lp_count", 60);
2550   declare_register ("pcl", 63);
2551 
2552   /* Initialize the last instructions.  */
2553   memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2554 
2555   /* Aux register declaration.  */
2556   arc_aux_hash = hash_new ();
2557   if (arc_aux_hash == NULL)
2558     as_fatal (_("Virtual memory exhausted"));
2559 
2560   const struct arc_aux_reg *auxr = &arc_aux_regs[0];
2561   unsigned int i;
2562   for (i = 0; i < arc_num_aux_regs; i++, auxr++)
2563     {
2564       const char *retval;
2565 
2566       if (!(auxr->cpu & arc_target))
2567 	continue;
2568 
2569       if ((auxr->subclass != NONE)
2570 	  && !check_cpu_feature (auxr->subclass))
2571 	continue;
2572 
2573       retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
2574       if (retval)
2575 	as_fatal (_("internal error: can't hash aux register '%s': %s"),
2576 		  auxr->name, retval);
2577     }
2578 }
2579 
2580 /* Write a value out to the object file, using the appropriate
2581    endianness.  */
2582 
2583 void
md_number_to_chars(char * buf,valueT val,int n)2584 md_number_to_chars (char *buf,
2585 		    valueT val,
2586 		    int n)
2587 {
2588   if (target_big_endian)
2589     number_to_chars_bigendian (buf, val, n);
2590   else
2591     number_to_chars_littleendian (buf, val, n);
2592 }
2593 
2594 /* Round up a section size to the appropriate boundary.  */
2595 
2596 valueT
md_section_align(segT segment,valueT size)2597 md_section_align (segT segment,
2598 		  valueT size)
2599 {
2600   int align = bfd_get_section_alignment (stdoutput, segment);
2601 
2602   return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2603 }
2604 
2605 /* The location from which a PC relative jump should be calculated,
2606    given a PC relative reloc.  */
2607 
2608 long
md_pcrel_from_section(fixS * fixP,segT sec)2609 md_pcrel_from_section (fixS *fixP,
2610 		       segT sec)
2611 {
2612   offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2613 
2614   pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2615 
2616   if (fixP->fx_addsy != (symbolS *) NULL
2617       && (!S_IS_DEFINED (fixP->fx_addsy)
2618 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2619     {
2620       pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2621 
2622       /* The symbol is undefined (or is defined but not in this section).
2623 	 Let the linker figure it out.  */
2624       return 0;
2625     }
2626 
2627   if ((int) fixP->fx_r_type < 0)
2628     {
2629       /* These are the "internal" relocations.  Align them to
2630 	 32 bit boundary (PCL), for the moment.  */
2631       base &= ~3;
2632     }
2633   else
2634     {
2635       switch (fixP->fx_r_type)
2636 	{
2637 	case BFD_RELOC_ARC_PC32:
2638 	  /* The hardware calculates relative to the start of the
2639 	     insn, but this relocation is relative to location of the
2640 	     LIMM, compensate.  The base always needs to be
2641 	     substracted by 4 as we do not support this type of PCrel
2642 	     relocation for short instructions.  */
2643 	  base -= 4;
2644 	  /* Fall through.  */
2645 	case BFD_RELOC_ARC_PLT32:
2646 	case BFD_RELOC_ARC_S25H_PCREL_PLT:
2647 	case BFD_RELOC_ARC_S21H_PCREL_PLT:
2648 	case BFD_RELOC_ARC_S25W_PCREL_PLT:
2649 	case BFD_RELOC_ARC_S21W_PCREL_PLT:
2650 
2651 	case BFD_RELOC_ARC_S21H_PCREL:
2652 	case BFD_RELOC_ARC_S25H_PCREL:
2653 	case BFD_RELOC_ARC_S13_PCREL:
2654 	case BFD_RELOC_ARC_S21W_PCREL:
2655 	case BFD_RELOC_ARC_S25W_PCREL:
2656 	  base &= ~3;
2657 	  break;
2658 	default:
2659 	  as_bad_where (fixP->fx_file, fixP->fx_line,
2660 			_("unhandled reloc %s in md_pcrel_from_section"),
2661 		  bfd_get_reloc_code_name (fixP->fx_r_type));
2662 	  break;
2663 	}
2664     }
2665 
2666   pr_debug ("pcrel from %"BFD_VMA_FMT"x + %lx = %"BFD_VMA_FMT"x, "
2667 	    "symbol: %s (%"BFD_VMA_FMT"x)\n",
2668 	    fixP->fx_frag->fr_address, fixP->fx_where, base,
2669 	    fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2670 	    fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2671 
2672   return base;
2673 }
2674 
2675 /* Given a BFD relocation find the coresponding operand.  */
2676 
2677 static const struct arc_operand *
find_operand_for_reloc(extended_bfd_reloc_code_real_type reloc)2678 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2679 {
2680   unsigned i;
2681 
2682   for (i = 0; i < arc_num_operands; i++)
2683     if (arc_operands[i].default_reloc == reloc)
2684       return  &arc_operands[i];
2685   return NULL;
2686 }
2687 
2688 /* Insert an operand value into an instruction.  */
2689 
2690 static unsigned
insert_operand(unsigned insn,const struct arc_operand * operand,offsetT val,const char * file,unsigned line)2691 insert_operand (unsigned insn,
2692 		const struct arc_operand *operand,
2693 		offsetT val,
2694 		const char *file,
2695 		unsigned line)
2696 {
2697   offsetT min = 0, max = 0;
2698 
2699   if (operand->bits != 32
2700       && !(operand->flags & ARC_OPERAND_NCHK)
2701       && !(operand->flags & ARC_OPERAND_FAKE))
2702     {
2703       if (operand->flags & ARC_OPERAND_SIGNED)
2704 	{
2705 	  max = (1 << (operand->bits - 1)) - 1;
2706 	  min = -(1 << (operand->bits - 1));
2707 	}
2708       else
2709 	{
2710 	  max = (1 << operand->bits) - 1;
2711 	  min = 0;
2712 	}
2713 
2714       if (val < min || val > max)
2715 	as_bad_value_out_of_range (_("operand"),
2716 				   val, min, max, file, line);
2717     }
2718 
2719   pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2720 	    min, val, max, insn);
2721 
2722   if ((operand->flags & ARC_OPERAND_ALIGNED32)
2723       && (val & 0x03))
2724     as_bad_where (file, line,
2725 		  _("Unaligned operand. Needs to be 32bit aligned"));
2726 
2727   if ((operand->flags & ARC_OPERAND_ALIGNED16)
2728       && (val & 0x01))
2729     as_bad_where (file, line,
2730 		  _("Unaligned operand. Needs to be 16bit aligned"));
2731 
2732   if (operand->insert)
2733     {
2734       const char *errmsg = NULL;
2735 
2736       insn = (*operand->insert) (insn, val, &errmsg);
2737       if (errmsg)
2738 	as_warn_where (file, line, "%s", errmsg);
2739     }
2740   else
2741     {
2742       if (operand->flags & ARC_OPERAND_TRUNCATE)
2743 	{
2744 	  if (operand->flags & ARC_OPERAND_ALIGNED32)
2745 	    val >>= 2;
2746 	  if (operand->flags & ARC_OPERAND_ALIGNED16)
2747 	    val >>= 1;
2748 	}
2749       insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2750     }
2751   return insn;
2752 }
2753 
2754 /* Apply a fixup to the object code.  At this point all symbol values
2755    should be fully resolved, and we attempt to completely resolve the
2756    reloc.  If we can not do that, we determine the correct reloc code
2757    and put it back in the fixup.  To indicate that a fixup has been
2758    eliminated, set fixP->fx_done.  */
2759 
2760 void
md_apply_fix(fixS * fixP,valueT * valP,segT seg)2761 md_apply_fix (fixS *fixP,
2762 	      valueT *valP,
2763 	      segT seg)
2764 {
2765   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2766   valueT value = *valP;
2767   unsigned insn = 0;
2768   symbolS *fx_addsy, *fx_subsy;
2769   offsetT fx_offset;
2770   segT add_symbol_segment = absolute_section;
2771   segT sub_symbol_segment = absolute_section;
2772   const struct arc_operand *operand = NULL;
2773   extended_bfd_reloc_code_real_type reloc;
2774 
2775   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2776 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2777 	    ((int) fixP->fx_r_type < 0) ? "Internal":
2778 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
2779 	    fixP->fx_offset);
2780 
2781   fx_addsy = fixP->fx_addsy;
2782   fx_subsy = fixP->fx_subsy;
2783   fx_offset = 0;
2784 
2785   if (fx_addsy)
2786     {
2787       add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2788     }
2789 
2790   if (fx_subsy
2791       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2792       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2793       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2794     {
2795       resolve_symbol_value (fx_subsy);
2796       sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2797 
2798       if (sub_symbol_segment == absolute_section)
2799 	{
2800 	  /* The symbol is really a constant.  */
2801 	  fx_offset -= S_GET_VALUE (fx_subsy);
2802 	  fx_subsy = NULL;
2803 	}
2804       else
2805 	{
2806 	  as_bad_where (fixP->fx_file, fixP->fx_line,
2807 			_("can't resolve `%s' {%s section} - `%s' {%s section}"),
2808 			fx_addsy ? S_GET_NAME (fx_addsy) : "0",
2809 			segment_name (add_symbol_segment),
2810 			S_GET_NAME (fx_subsy),
2811 			segment_name (sub_symbol_segment));
2812 	  return;
2813 	}
2814     }
2815 
2816   if (fx_addsy
2817       && !S_IS_WEAK (fx_addsy))
2818     {
2819       if (add_symbol_segment == seg
2820 	  && fixP->fx_pcrel)
2821 	{
2822 	  value += S_GET_VALUE (fx_addsy);
2823 	  value -= md_pcrel_from_section (fixP, seg);
2824 	  fx_addsy = NULL;
2825 	  fixP->fx_pcrel = FALSE;
2826 	}
2827       else if (add_symbol_segment == absolute_section)
2828 	{
2829 	  value = fixP->fx_offset;
2830 	  fx_offset += S_GET_VALUE (fixP->fx_addsy);
2831 	  fx_addsy = NULL;
2832 	  fixP->fx_pcrel = FALSE;
2833 	}
2834     }
2835 
2836   if (!fx_addsy)
2837     fixP->fx_done = TRUE;
2838 
2839   if (fixP->fx_pcrel)
2840     {
2841       if (fx_addsy
2842 	  && ((S_IS_DEFINED (fx_addsy)
2843 	       && S_GET_SEGMENT (fx_addsy) != seg)
2844 	      || S_IS_WEAK (fx_addsy)))
2845 	value += md_pcrel_from_section (fixP, seg);
2846 
2847       switch (fixP->fx_r_type)
2848 	{
2849 	case BFD_RELOC_ARC_32_ME:
2850 	  /* This is a pc-relative value in a LIMM.  Adjust it to the
2851 	     address of the instruction not to the address of the
2852 	     LIMM.  Note: it is not anylonger valid this afirmation as
2853 	     the linker consider ARC_PC32 a fixup to entire 64 bit
2854 	     insn.  */
2855 	  fixP->fx_offset += fixP->fx_frag->fr_address;
2856 	  /* Fall through.  */
2857 	case BFD_RELOC_32:
2858 	  fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2859 	  /* Fall through.  */
2860 	case BFD_RELOC_ARC_PC32:
2861 	  /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2862 	  break;
2863 	default:
2864 	  if ((int) fixP->fx_r_type < 0)
2865 	    as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2866 		      fixP->fx_r_type);
2867 	  break;
2868 	}
2869     }
2870 
2871   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2872 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2873 	    ((int) fixP->fx_r_type < 0) ? "Internal":
2874 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
2875 	    fixP->fx_offset);
2876 
2877 
2878   /* Now check for TLS relocations.  */
2879   reloc = fixP->fx_r_type;
2880   switch (reloc)
2881     {
2882     case BFD_RELOC_ARC_TLS_DTPOFF:
2883     case BFD_RELOC_ARC_TLS_LE_32:
2884       if (fixP->fx_done)
2885 	break;
2886       /* Fall through.  */
2887     case BFD_RELOC_ARC_TLS_GD_GOT:
2888     case BFD_RELOC_ARC_TLS_IE_GOT:
2889       S_SET_THREAD_LOCAL (fixP->fx_addsy);
2890       break;
2891 
2892     case BFD_RELOC_ARC_TLS_GD_LD:
2893       gas_assert (!fixP->fx_offset);
2894       if (fixP->fx_subsy)
2895 	fixP->fx_offset
2896 	  = (S_GET_VALUE (fixP->fx_subsy)
2897 	     - fixP->fx_frag->fr_address- fixP->fx_where);
2898       fixP->fx_subsy = NULL;
2899       /* Fall through.  */
2900     case BFD_RELOC_ARC_TLS_GD_CALL:
2901       /* These two relocs are there just to allow ld to change the tls
2902 	 model for this symbol, by patching the code.  The offset -
2903 	 and scale, if any - will be installed by the linker.  */
2904       S_SET_THREAD_LOCAL (fixP->fx_addsy);
2905       break;
2906 
2907     case BFD_RELOC_ARC_TLS_LE_S9:
2908     case BFD_RELOC_ARC_TLS_DTPOFF_S9:
2909       as_bad (_("TLS_*_S9 relocs are not supported yet"));
2910       break;
2911 
2912     default:
2913       break;
2914     }
2915 
2916   if (!fixP->fx_done)
2917     {
2918       return;
2919     }
2920 
2921   /* Addjust the value if we have a constant.  */
2922   value += fx_offset;
2923 
2924   /* For hosts with longs bigger than 32-bits make sure that the top
2925      bits of a 32-bit negative value read in by the parser are set,
2926      so that the correct comparisons are made.  */
2927   if (value & 0x80000000)
2928     value |= (-1UL << 31);
2929 
2930   reloc = fixP->fx_r_type;
2931   switch (reloc)
2932     {
2933     case BFD_RELOC_8:
2934     case BFD_RELOC_16:
2935     case BFD_RELOC_24:
2936     case BFD_RELOC_32:
2937     case BFD_RELOC_64:
2938     case BFD_RELOC_ARC_32_PCREL:
2939       md_number_to_chars (fixpos, value, fixP->fx_size);
2940       return;
2941 
2942     case BFD_RELOC_ARC_GOTPC32:
2943       /* I cannot fix an GOTPC relocation because I need to relax it
2944 	 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc.  */
2945       as_bad (_("Unsupported operation on reloc"));
2946       return;
2947 
2948     case BFD_RELOC_ARC_TLS_DTPOFF:
2949     case BFD_RELOC_ARC_TLS_LE_32:
2950       gas_assert (!fixP->fx_addsy);
2951       gas_assert (!fixP->fx_subsy);
2952 
2953     case BFD_RELOC_ARC_GOTOFF:
2954     case BFD_RELOC_ARC_32_ME:
2955     case BFD_RELOC_ARC_PC32:
2956       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2957       return;
2958 
2959     case BFD_RELOC_ARC_PLT32:
2960       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2961       return;
2962 
2963     case BFD_RELOC_ARC_S25H_PCREL_PLT:
2964       reloc = BFD_RELOC_ARC_S25W_PCREL;
2965       goto solve_plt;
2966 
2967     case BFD_RELOC_ARC_S21H_PCREL_PLT:
2968       reloc = BFD_RELOC_ARC_S21H_PCREL;
2969       goto solve_plt;
2970 
2971     case BFD_RELOC_ARC_S25W_PCREL_PLT:
2972       reloc = BFD_RELOC_ARC_S25W_PCREL;
2973       goto solve_plt;
2974 
2975     case BFD_RELOC_ARC_S21W_PCREL_PLT:
2976       reloc = BFD_RELOC_ARC_S21W_PCREL;
2977 
2978     case BFD_RELOC_ARC_S25W_PCREL:
2979     case BFD_RELOC_ARC_S21W_PCREL:
2980     case BFD_RELOC_ARC_S21H_PCREL:
2981     case BFD_RELOC_ARC_S25H_PCREL:
2982     case BFD_RELOC_ARC_S13_PCREL:
2983     solve_plt:
2984       operand = find_operand_for_reloc (reloc);
2985       gas_assert (operand);
2986       break;
2987 
2988     default:
2989       {
2990 	if ((int) fixP->fx_r_type >= 0)
2991 	  as_fatal (_("unhandled relocation type %s"),
2992 		    bfd_get_reloc_code_name (fixP->fx_r_type));
2993 
2994 	/* The rest of these fixups needs to be completely resolved as
2995 	   constants.  */
2996 	if (fixP->fx_addsy != 0
2997 	    && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
2998 	  as_bad_where (fixP->fx_file, fixP->fx_line,
2999 			_("non-absolute expression in constant field"));
3000 
3001 	gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
3002 	operand = &arc_operands[-(int) fixP->fx_r_type];
3003 	break;
3004       }
3005     }
3006 
3007   if (target_big_endian)
3008     {
3009       switch (fixP->fx_size)
3010 	{
3011 	case 4:
3012 	  insn = bfd_getb32 (fixpos);
3013 	  break;
3014 	case 2:
3015 	  insn = bfd_getb16 (fixpos);
3016 	  break;
3017 	default:
3018 	  as_bad_where (fixP->fx_file, fixP->fx_line,
3019 			_("unknown fixup size"));
3020 	}
3021     }
3022   else
3023     {
3024       insn = 0;
3025       switch (fixP->fx_size)
3026 	{
3027 	case 4:
3028 	  insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
3029 	  break;
3030 	case 2:
3031 	  insn = bfd_getl16 (fixpos);
3032 	  break;
3033 	default:
3034 	  as_bad_where (fixP->fx_file, fixP->fx_line,
3035 			_("unknown fixup size"));
3036 	}
3037     }
3038 
3039   insn = insert_operand (insn, operand, (offsetT) value,
3040 			 fixP->fx_file, fixP->fx_line);
3041 
3042   md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
3043 }
3044 
3045 /* Prepare machine-dependent frags for relaxation.
3046 
3047    Called just before relaxation starts.  Any symbol that is now undefined
3048    will not become defined.
3049 
3050    Return the correct fr_subtype in the frag.
3051 
3052    Return the initial "guess for fr_var" to caller.  The guess for fr_var
3053    is *actually* the growth beyond fr_fix.  Whatever we do to grow fr_fix
3054    or fr_var contributes to our returned value.
3055 
3056    Although it may not be explicit in the frag, pretend
3057    fr_var starts with a value.  */
3058 
3059 int
md_estimate_size_before_relax(fragS * fragP,segT segment)3060 md_estimate_size_before_relax (fragS *fragP,
3061 			       segT segment)
3062 {
3063   int growth;
3064 
3065   /* If the symbol is not located within the same section AND it's not
3066      an absolute section, use the maximum.  OR if the symbol is a
3067      constant AND the insn is by nature not pc-rel, use the maximum.
3068      OR if the symbol is being equated against another symbol, use the
3069      maximum.  OR if the symbol is weak use the maximum.  */
3070   if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
3071        && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3072       || (symbol_constant_p (fragP->fr_symbol)
3073 	  && !fragP->tc_frag_data.pcrel)
3074       || symbol_equated_p (fragP->fr_symbol)
3075       || S_IS_WEAK (fragP->fr_symbol))
3076     {
3077       while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
3078 	++fragP->fr_subtype;
3079     }
3080 
3081   growth = md_relax_table[fragP->fr_subtype].rlx_length;
3082   fragP->fr_var = growth;
3083 
3084   pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3085 	   fragP->fr_file, fragP->fr_line, growth);
3086 
3087   return growth;
3088 }
3089 
3090 /* Translate internal representation of relocation info to BFD target
3091    format.  */
3092 
3093 arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixP)3094 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
3095 	      fixS *fixP)
3096 {
3097   arelent *reloc;
3098   bfd_reloc_code_real_type code;
3099 
3100   reloc = XNEW (arelent);
3101   reloc->sym_ptr_ptr = XNEW (asymbol *);
3102   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3103   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3104 
3105   /* Make sure none of our internal relocations make it this far.
3106      They'd better have been fully resolved by this point.  */
3107   gas_assert ((int) fixP->fx_r_type > 0);
3108 
3109   code = fixP->fx_r_type;
3110 
3111   /* if we have something like add gp, pcl,
3112      _GLOBAL_OFFSET_TABLE_@gotpc.  */
3113   if (code == BFD_RELOC_ARC_GOTPC32
3114       && GOT_symbol
3115       && fixP->fx_addsy == GOT_symbol)
3116     code = BFD_RELOC_ARC_GOTPC;
3117 
3118   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
3119   if (reloc->howto == NULL)
3120     {
3121       as_bad_where (fixP->fx_file, fixP->fx_line,
3122 		    _("cannot represent `%s' relocation in object file"),
3123 		    bfd_get_reloc_code_name (code));
3124       return NULL;
3125     }
3126 
3127   if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
3128     as_fatal (_("internal error? cannot generate `%s' relocation"),
3129 	      bfd_get_reloc_code_name (code));
3130 
3131   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
3132 
3133   if (code == BFD_RELOC_ARC_TLS_DTPOFF
3134       || code ==  BFD_RELOC_ARC_TLS_DTPOFF_S9)
3135     {
3136       asymbol *sym
3137 	= fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
3138       /* We just want to store a 24 bit index, but we have to wait
3139 	 till after write_contents has been called via
3140 	 bfd_map_over_sections before we can get the index from
3141 	 _bfd_elf_symbol_from_bfd_symbol.  Thus, the write_relocs
3142 	 function is elf32-arc.c has to pick up the slack.
3143 	 Unfortunately, this leads to problems with hosts that have
3144 	 pointers wider than long (bfd_vma).  There would be various
3145 	 ways to handle this, all error-prone :-(  */
3146       reloc->addend = (bfd_vma) sym;
3147       if ((asymbol *) reloc->addend != sym)
3148 	{
3149 	  as_bad ("Can't store pointer\n");
3150 	  return NULL;
3151 	}
3152     }
3153   else
3154     reloc->addend = fixP->fx_offset;
3155 
3156   return reloc;
3157 }
3158 
3159 /* Perform post-processing of machine-dependent frags after relaxation.
3160    Called after relaxation is finished.
3161    In:	Address of frag.
3162    fr_type == rs_machine_dependent.
3163    fr_subtype is what the address relaxed to.
3164 
3165    Out: Any fixS:s and constants are set up.  */
3166 
3167 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT segment ATTRIBUTE_UNUSED,fragS * fragP)3168 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
3169 		 segT segment ATTRIBUTE_UNUSED,
3170 		 fragS *fragP)
3171 {
3172   const relax_typeS *table_entry;
3173   char *dest;
3174   const struct arc_opcode *opcode;
3175   struct arc_insn insn;
3176   int size, fix;
3177   struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
3178 
3179   fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix);
3180   dest = fragP->fr_literal + fix;
3181   table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
3182 
3183   pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3184 	    "var: %"BFD_VMA_FMT"d\n",
3185 	    fragP->fr_file, fragP->fr_line,
3186 	    fragP->fr_subtype, fix, fragP->fr_var);
3187 
3188   if (fragP->fr_subtype <= 0
3189       && fragP->fr_subtype >= arc_num_relax_opcodes)
3190     as_fatal (_("no relaxation found for this instruction."));
3191 
3192   opcode = &arc_relax_opcodes[fragP->fr_subtype];
3193 
3194   assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
3195 	relax_arg->nflg, &insn);
3196 
3197   apply_fixups (&insn, fragP, fix);
3198 
3199   size = insn.short_insn ? (insn.has_limm ? 6 : 2) : (insn.has_limm ? 8 : 4);
3200   gas_assert (table_entry->rlx_length == size);
3201   emit_insn0 (&insn, dest, TRUE);
3202 
3203   fragP->fr_fix += table_entry->rlx_length;
3204   fragP->fr_var = 0;
3205 }
3206 
3207 /* We have no need to default values of symbols.  We could catch
3208    register names here, but that is handled by inserting them all in
3209    the symbol table to begin with.  */
3210 
3211 symbolS *
md_undefined_symbol(char * name)3212 md_undefined_symbol (char *name)
3213 {
3214   /* The arc abi demands that a GOT[0] should be referencible as
3215      [pc+_DYNAMIC@gotpc].  Hence we convert a _DYNAMIC@gotpc to a
3216      GOTPC reference to _GLOBAL_OFFSET_TABLE_.  */
3217   if (((*name == '_')
3218        && (*(name+1) == 'G')
3219        && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
3220       || ((*name == '_')
3221 	  && (*(name+1) == 'D')
3222 	  && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
3223     {
3224       if (!GOT_symbol)
3225 	{
3226 	  if (symbol_find (name))
3227 	    as_bad ("GOT already in symbol table");
3228 
3229 	  GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
3230 				   (valueT) 0, &zero_address_frag);
3231 	};
3232       return GOT_symbol;
3233     }
3234   return NULL;
3235 }
3236 
3237 /* Turn a string in input_line_pointer into a floating point constant
3238    of type type, and store the appropriate bytes in *litP.  The number
3239    of LITTLENUMS emitted is stored in *sizeP.  An error message is
3240    returned, or NULL on OK.  */
3241 
3242 const char *
md_atof(int type,char * litP,int * sizeP)3243 md_atof (int type, char *litP, int *sizeP)
3244 {
3245   return ieee_md_atof (type, litP, sizeP, target_big_endian);
3246 }
3247 
3248 /* Called for any expression that can not be recognized.  When the
3249    function is called, `input_line_pointer' will point to the start of
3250    the expression.  */
3251 
3252 void
md_operand(expressionS * expressionP ATTRIBUTE_UNUSED)3253 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
3254 {
3255   char *p = input_line_pointer;
3256   if (*p == '@')
3257     {
3258       input_line_pointer++;
3259       expressionP->X_op = O_symbol;
3260       expression (expressionP);
3261     }
3262 }
3263 
3264 /* This function is called from the function 'expression', it attempts
3265    to parse special names (in our case register names).  It fills in
3266    the expression with the identified register.  It returns TRUE if
3267    it is a register and FALSE otherwise.  */
3268 
3269 bfd_boolean
arc_parse_name(const char * name,struct expressionS * e)3270 arc_parse_name (const char *name,
3271 		struct expressionS *e)
3272 {
3273   struct symbol *sym;
3274 
3275   if (!assembling_insn)
3276     return FALSE;
3277 
3278   /* Handle only registers.  */
3279   if (e->X_op != O_absent)
3280     return FALSE;
3281 
3282   sym = hash_find (arc_reg_hash, name);
3283   if (sym)
3284     {
3285       e->X_op = O_register;
3286       e->X_add_number = S_GET_VALUE (sym);
3287       return TRUE;
3288     }
3289   return FALSE;
3290 }
3291 
3292 /* md_parse_option
3293    Invocation line includes a switch not recognized by the base assembler.
3294    See if it's a processor-specific option.
3295 
3296    New options (supported) are:
3297 
3298    -mcpu=<cpu name>		 Assemble for selected processor
3299    -EB/-mbig-endian		 Big-endian
3300    -EL/-mlittle-endian		 Little-endian
3301    -mrelax                       Enable relaxation
3302 
3303    The following CPU names are recognized:
3304    arc600, arc700, arcem, archs, nps400.  */
3305 
3306 int
md_parse_option(int c,const char * arg ATTRIBUTE_UNUSED)3307 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
3308 {
3309   switch (c)
3310     {
3311     case OPTION_ARC600:
3312     case OPTION_ARC601:
3313       return md_parse_option (OPTION_MCPU, "arc600");
3314 
3315     case OPTION_ARC700:
3316       return md_parse_option (OPTION_MCPU, "arc700");
3317 
3318     case OPTION_ARCEM:
3319       return md_parse_option (OPTION_MCPU, "arcem");
3320 
3321     case OPTION_ARCHS:
3322       return md_parse_option (OPTION_MCPU, "archs");
3323 
3324     case OPTION_MCPU:
3325       {
3326         arc_select_cpu (arg);
3327         mach_type_specified_p = TRUE;
3328 	break;
3329       }
3330 
3331     case OPTION_EB:
3332       arc_target_format = "elf32-bigarc";
3333       byte_order = BIG_ENDIAN;
3334       break;
3335 
3336     case OPTION_EL:
3337       arc_target_format = "elf32-littlearc";
3338       byte_order = LITTLE_ENDIAN;
3339       break;
3340 
3341     case OPTION_CD:
3342       /* This option has an effect only on ARC EM.  */
3343       if (arc_target & ARC_OPCODE_ARCv2EM)
3344 	arc_features |= ARC_CD;
3345       else
3346 	as_warn (_("Code density option invalid for selected CPU"));
3347       break;
3348 
3349     case OPTION_RELAX:
3350       relaxation_state = 1;
3351       break;
3352 
3353     case OPTION_NPS400:
3354       arc_features |= ARC_NPS400;
3355       break;
3356 
3357     case OPTION_SPFP:
3358       arc_features |= ARC_SPFP;
3359       break;
3360 
3361     case OPTION_DPFP:
3362       arc_features |= ARC_DPFP;
3363       break;
3364 
3365     case OPTION_FPUDA:
3366       /* This option has an effect only on ARC EM.  */
3367       if (arc_target & ARC_OPCODE_ARCv2EM)
3368 	arc_features |= ARC_FPUDA;
3369       else
3370 	as_warn (_("FPUDA invalid for selected CPU"));
3371       break;
3372 
3373     /* Dummy options are accepted but have no effect.  */
3374     case OPTION_USER_MODE:
3375     case OPTION_LD_EXT_MASK:
3376     case OPTION_SWAP:
3377     case OPTION_NORM:
3378     case OPTION_BARREL_SHIFT:
3379     case OPTION_MIN_MAX:
3380     case OPTION_NO_MPY:
3381     case OPTION_EA:
3382     case OPTION_MUL64:
3383     case OPTION_SIMD:
3384     case OPTION_XMAC_D16:
3385     case OPTION_XMAC_24:
3386     case OPTION_DSP_PACKA:
3387     case OPTION_CRC:
3388     case OPTION_DVBF:
3389     case OPTION_TELEPHONY:
3390     case OPTION_XYMEMORY:
3391     case OPTION_LOCK:
3392     case OPTION_SWAPE:
3393     case OPTION_RTSC:
3394       break;
3395 
3396     default:
3397       return 0;
3398     }
3399 
3400   return 1;
3401 }
3402 
3403 void
md_show_usage(FILE * stream)3404 md_show_usage (FILE *stream)
3405 {
3406   fprintf (stream, _("ARC-specific assembler options:\n"));
3407 
3408   fprintf (stream, "  -mcpu=<cpu name>\t  assemble for CPU <cpu name> "
3409            "(default: %s)\n", TARGET_WITH_CPU);
3410   fprintf (stream, "  -mcpu=nps400\t\t  same as -mcpu=arc700 -mnps400\n");
3411   fprintf (stream, "  -mA6/-mARC600/-mARC601  same as -mcpu=arc600\n");
3412   fprintf (stream, "  -mA7/-mARC700\t\t  same as -mcpu=arc700\n");
3413   fprintf (stream, "  -mEM\t\t\t  same as -mcpu=arcem\n");
3414   fprintf (stream, "  -mHS\t\t\t  same as -mcpu=archs\n");
3415 
3416   fprintf (stream, "  -mnps400\t\t  enable NPS-400 extended instructions\n");
3417   fprintf (stream, "  -mspfp\t\t  enable single-precision floating point instructions\n");
3418   fprintf (stream, "  -mdpfp\t\t  enable double-precision floating point instructions\n");
3419   fprintf (stream, "  -mfpuda\t\t  enable double-precision assist floating "
3420                    "point\n\t\t\t  instructions for ARC EM\n");
3421 
3422   fprintf (stream,
3423 	   "  -mcode-density\t  enable code density option for ARC EM\n");
3424 
3425   fprintf (stream, _("\
3426   -EB                     assemble code for a big-endian cpu\n"));
3427   fprintf (stream, _("\
3428   -EL                     assemble code for a little-endian cpu\n"));
3429   fprintf (stream, _("\
3430   -mrelax                 enable relaxation\n"));
3431 
3432   fprintf (stream, _("The following ARC-specific assembler options are "
3433                      "deprecated and are accepted\nfor compatibility only:\n"));
3434 
3435   fprintf (stream, _("  -mEA\n"
3436                      "  -mbarrel-shifter\n"
3437                      "  -mbarrel_shifter\n"
3438                      "  -mcrc\n"
3439                      "  -mdsp-packa\n"
3440                      "  -mdsp_packa\n"
3441                      "  -mdvbf\n"
3442                      "  -mld-extension-reg-mask\n"
3443                      "  -mlock\n"
3444                      "  -mmac-24\n"
3445                      "  -mmac-d16\n"
3446                      "  -mmac_24\n"
3447                      "  -mmac_d16\n"
3448                      "  -mmin-max\n"
3449                      "  -mmin_max\n"
3450                      "  -mmul64\n"
3451                      "  -mno-mpy\n"
3452                      "  -mnorm\n"
3453                      "  -mrtsc\n"
3454                      "  -msimd\n"
3455                      "  -mswap\n"
3456                      "  -mswape\n"
3457                      "  -mtelephony\n"
3458 		     "  -muser-mode-only\n"
3459                      "  -mxy\n"));
3460 }
3461 
3462 /* Find the proper relocation for the given opcode.  */
3463 
3464 static extended_bfd_reloc_code_real_type
find_reloc(const char * name,const char * opcodename,const struct arc_flags * pflags,int nflg,extended_bfd_reloc_code_real_type reloc)3465 find_reloc (const char *name,
3466 	    const char *opcodename,
3467 	    const struct arc_flags *pflags,
3468 	    int nflg,
3469 	    extended_bfd_reloc_code_real_type reloc)
3470 {
3471   unsigned int i;
3472   int j;
3473   bfd_boolean found_flag, tmp;
3474   extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3475 
3476   for (i = 0; i < arc_num_equiv_tab; i++)
3477     {
3478       const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3479 
3480       /* Find the entry.  */
3481       if (strcmp (name, r->name))
3482 	continue;
3483       if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3484 	continue;
3485       if (r->flags[0])
3486 	{
3487 	  if (!nflg)
3488 	    continue;
3489 	  found_flag = FALSE;
3490 	  unsigned * psflg = (unsigned *)r->flags;
3491 	  do
3492 	    {
3493 	      tmp = FALSE;
3494 	      for (j = 0; j < nflg; j++)
3495 		if (!strcmp (pflags[j].name,
3496 			     arc_flag_operands[*psflg].name))
3497 		  {
3498 		    tmp = TRUE;
3499 		    break;
3500 		  }
3501 	      if (!tmp)
3502 		{
3503 		  found_flag = FALSE;
3504 		  break;
3505 		}
3506 	      else
3507 		{
3508 		  found_flag = TRUE;
3509 		}
3510 	      ++ psflg;
3511 	    } while (*psflg);
3512 
3513 	  if (!found_flag)
3514 	    continue;
3515 	}
3516 
3517       if (reloc != r->oldreloc)
3518 	continue;
3519       /* Found it.  */
3520       ret = r->newreloc;
3521       break;
3522     }
3523 
3524   if (ret == BFD_RELOC_UNUSED)
3525     as_bad (_("Unable to find %s relocation for instruction %s"),
3526 	    name, opcodename);
3527   return ret;
3528 }
3529 
3530 /* All the symbol types that are allowed to be used for
3531    relaxation.  */
3532 
3533 static bfd_boolean
may_relax_expr(expressionS tok)3534 may_relax_expr (expressionS tok)
3535 {
3536   /* Check if we have unrelaxable relocs.  */
3537   switch (tok.X_md)
3538     {
3539     default:
3540       break;
3541     case O_plt:
3542       return FALSE;
3543     }
3544 
3545   switch (tok.X_op)
3546     {
3547     case O_symbol:
3548     case O_multiply:
3549     case O_divide:
3550     case O_modulus:
3551     case O_add:
3552     case O_subtract:
3553       break;
3554 
3555     default:
3556       return FALSE;
3557     }
3558   return TRUE;
3559 }
3560 
3561 /* Checks if flags are in line with relaxable insn.  */
3562 
3563 static bfd_boolean
relaxable_flag(const struct arc_relaxable_ins * ins,const struct arc_flags * pflags,int nflgs)3564 relaxable_flag (const struct arc_relaxable_ins *ins,
3565 		const struct arc_flags *pflags,
3566 		int nflgs)
3567 {
3568   unsigned flag_class,
3569     flag,
3570     flag_class_idx = 0,
3571     flag_idx = 0;
3572 
3573   const struct arc_flag_operand *flag_opand;
3574   int i, counttrue = 0;
3575 
3576   /* Iterate through flags classes.  */
3577   while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3578     {
3579       /* Iterate through flags in flag class.  */
3580       while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3581 	     != 0)
3582 	{
3583 	  flag_opand = &arc_flag_operands[flag];
3584 	  /* Iterate through flags in ins to compare.  */
3585 	  for (i = 0; i < nflgs; ++i)
3586 	    {
3587 	      if (strcmp (flag_opand->name, pflags[i].name) == 0)
3588 		++counttrue;
3589 	    }
3590 
3591 	  ++flag_idx;
3592 	}
3593 
3594       ++flag_class_idx;
3595       flag_idx = 0;
3596     }
3597 
3598   /* If counttrue == nflgs, then all flags have been found.  */
3599   return (counttrue == nflgs ? TRUE : FALSE);
3600 }
3601 
3602 /* Checks if operands are in line with relaxable insn.  */
3603 
3604 static bfd_boolean
relaxable_operand(const struct arc_relaxable_ins * ins,const expressionS * tok,int ntok)3605 relaxable_operand (const struct arc_relaxable_ins *ins,
3606 		   const expressionS *tok,
3607 		   int ntok)
3608 {
3609   const enum rlx_operand_type *operand = &ins->operands[0];
3610   int i = 0;
3611 
3612   while (*operand != EMPTY)
3613     {
3614       const expressionS *epr = &tok[i];
3615 
3616       if (i != 0 && i >= ntok)
3617 	return FALSE;
3618 
3619       switch (*operand)
3620 	{
3621 	case IMMEDIATE:
3622 	  if (!(epr->X_op == O_multiply
3623 		|| epr->X_op == O_divide
3624 		|| epr->X_op == O_modulus
3625 		|| epr->X_op == O_add
3626 		|| epr->X_op == O_subtract
3627 		|| epr->X_op == O_symbol))
3628 	    return FALSE;
3629 	  break;
3630 
3631 	case REGISTER_DUP:
3632 	  if ((i <= 0)
3633 	      || (epr->X_add_number != tok[i - 1].X_add_number))
3634 	    return FALSE;
3635 	  /* Fall through.  */
3636 	case REGISTER:
3637 	  if (epr->X_op != O_register)
3638 	    return FALSE;
3639 	  break;
3640 
3641 	case REGISTER_S:
3642 	  if (epr->X_op != O_register)
3643 	    return FALSE;
3644 
3645 	  switch (epr->X_add_number)
3646 	    {
3647 	    case 0: case 1: case 2: case 3:
3648 	    case 12: case 13: case 14: case 15:
3649 	      break;
3650 	    default:
3651 	      return FALSE;
3652 	    }
3653 	  break;
3654 
3655 	case REGISTER_NO_GP:
3656 	  if ((epr->X_op != O_register)
3657 	      || (epr->X_add_number == 26)) /* 26 is the gp register.  */
3658 	    return FALSE;
3659 	  break;
3660 
3661 	case BRACKET:
3662 	  if (epr->X_op != O_bracket)
3663 	    return FALSE;
3664 	  break;
3665 
3666 	default:
3667 	  /* Don't understand, bail out.  */
3668 	  return FALSE;
3669 	  break;
3670 	}
3671 
3672       ++i;
3673       operand = &ins->operands[i];
3674     }
3675 
3676   return (i == ntok ? TRUE : FALSE);
3677 }
3678 
3679 /* Return TRUE if this OPDCODE is a candidate for relaxation.  */
3680 
3681 static bfd_boolean
relax_insn_p(const struct arc_opcode * opcode,const expressionS * tok,int ntok,const struct arc_flags * pflags,int nflg)3682 relax_insn_p (const struct arc_opcode *opcode,
3683 	      const expressionS *tok,
3684 	      int ntok,
3685 	      const struct arc_flags *pflags,
3686 	      int nflg)
3687 {
3688   unsigned i;
3689   bfd_boolean rv = FALSE;
3690 
3691   /* Check the relaxation table.  */
3692   for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3693     {
3694       const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3695 
3696       if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3697 	  && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3698 	  && relaxable_operand (arc_rlx_ins, tok, ntok)
3699 	  && relaxable_flag (arc_rlx_ins, pflags, nflg))
3700 	{
3701 	  rv = TRUE;
3702 	  frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3703 	  memcpy (&frag_now->tc_frag_data.tok, tok,
3704 		sizeof (expressionS) * ntok);
3705 	  memcpy (&frag_now->tc_frag_data.pflags, pflags,
3706 		sizeof (struct arc_flags) * nflg);
3707 	  frag_now->tc_frag_data.nflg = nflg;
3708 	  frag_now->tc_frag_data.ntok = ntok;
3709 	  break;
3710 	}
3711     }
3712 
3713   return rv;
3714 }
3715 
3716 /* Turn an opcode description and a set of arguments into
3717    an instruction and a fixup.  */
3718 
3719 static void
assemble_insn(const struct arc_opcode * opcode,const expressionS * tok,int ntok,const struct arc_flags * pflags,int nflg,struct arc_insn * insn)3720 assemble_insn (const struct arc_opcode *opcode,
3721 	       const expressionS *tok,
3722 	       int ntok,
3723 	       const struct arc_flags *pflags,
3724 	       int nflg,
3725 	       struct arc_insn *insn)
3726 {
3727   const expressionS *reloc_exp = NULL;
3728   unsigned image;
3729   const unsigned char *argidx;
3730   int i;
3731   int tokidx = 0;
3732   unsigned char pcrel = 0;
3733   bfd_boolean needGOTSymbol;
3734   bfd_boolean has_delay_slot = FALSE;
3735   extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3736 
3737   memset (insn, 0, sizeof (*insn));
3738   image = opcode->opcode;
3739 
3740   pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3741 	    frag_now->fr_file, frag_now->fr_line, opcode->name,
3742 	    opcode->opcode);
3743 
3744   /* Handle operands.  */
3745   for (argidx = opcode->operands; *argidx; ++argidx)
3746     {
3747       const struct arc_operand *operand = &arc_operands[*argidx];
3748       const expressionS *t = (const expressionS *) 0;
3749 
3750       if ((operand->flags & ARC_OPERAND_FAKE)
3751 	  && !(operand->flags & ARC_OPERAND_BRAKET))
3752 	continue;
3753 
3754       if (operand->flags & ARC_OPERAND_DUPLICATE)
3755 	{
3756 	  /* Duplicate operand, already inserted.  */
3757 	  tokidx ++;
3758 	  continue;
3759 	}
3760 
3761       if (tokidx >= ntok)
3762 	{
3763 	  abort ();
3764 	}
3765       else
3766 	t = &tok[tokidx++];
3767 
3768       /* Regardless if we have a reloc or not mark the instruction
3769 	 limm if it is the case.  */
3770       if (operand->flags & ARC_OPERAND_LIMM)
3771 	insn->has_limm = TRUE;
3772 
3773       switch (t->X_op)
3774 	{
3775 	case O_register:
3776 	  image = insert_operand (image, operand, regno (t->X_add_number),
3777 				  NULL, 0);
3778 	  break;
3779 
3780 	case O_constant:
3781 	  image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3782 	  reloc_exp = t;
3783 	  if (operand->flags & ARC_OPERAND_LIMM)
3784 	    insn->limm = t->X_add_number;
3785 	  break;
3786 
3787 	case O_bracket:
3788 	  /* Ignore brackets.  */
3789 	  break;
3790 
3791 	case O_absent:
3792 	  gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3793 	  break;
3794 
3795 	case O_subtract:
3796 	  /* Maybe register range.  */
3797 	  if ((t->X_add_number == 0)
3798 	      && contains_register (t->X_add_symbol)
3799 	      && contains_register (t->X_op_symbol))
3800 	    {
3801 	      int regs;
3802 
3803 	      regs = get_register (t->X_add_symbol);
3804 	      regs <<= 16;
3805 	      regs |= get_register (t->X_op_symbol);
3806 	      image = insert_operand (image, operand, regs, NULL, 0);
3807 	      break;
3808 	    }
3809 
3810 	default:
3811 	  /* This operand needs a relocation.  */
3812 	  needGOTSymbol = FALSE;
3813 
3814 	  switch (t->X_md)
3815 	    {
3816 	    case O_plt:
3817 	      if (opcode->insn_class == JUMP)
3818 		as_bad_where (frag_now->fr_file, frag_now->fr_line,
3819 			      _("Unable to use @plt relocatio for insn %s"),
3820 			      opcode->name);
3821 	      needGOTSymbol = TRUE;
3822 	      reloc = find_reloc ("plt", opcode->name,
3823 				  pflags, nflg,
3824 				  operand->default_reloc);
3825 	      break;
3826 
3827 	    case O_gotoff:
3828 	    case O_gotpc:
3829 	      needGOTSymbol = TRUE;
3830 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3831 	      break;
3832 	    case O_pcl:
3833 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3834 	      if (ARC_SHORT (opcode->mask) || opcode->insn_class == JUMP)
3835 		as_bad_where (frag_now->fr_file, frag_now->fr_line,
3836 			      _("Unable to use @pcl relocation for insn %s"),
3837 			      opcode->name);
3838 	      break;
3839 	    case O_sda:
3840 	      reloc = find_reloc ("sda", opcode->name,
3841 				  pflags, nflg,
3842 				  operand->default_reloc);
3843 	      break;
3844 	    case O_tlsgd:
3845 	    case O_tlsie:
3846 	      needGOTSymbol = TRUE;
3847 	      /* Fall-through.  */
3848 
3849 	    case O_tpoff:
3850 	    case O_dtpoff:
3851 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3852 	      break;
3853 
3854 	    case O_tpoff9: /*FIXME! Check for the conditionality of
3855 			     the insn.  */
3856 	    case O_dtpoff9: /*FIXME! Check for the conditionality of
3857 			      the insn.  */
3858 	      as_bad (_("TLS_*_S9 relocs are not supported yet"));
3859 	      break;
3860 
3861 	    default:
3862 	      /* Just consider the default relocation.  */
3863 	      reloc = operand->default_reloc;
3864 	      break;
3865 	    }
3866 
3867 	  if (needGOTSymbol && (GOT_symbol == NULL))
3868 	    GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
3869 
3870 	  reloc_exp = t;
3871 
3872 #if 0
3873 	  if (reloc > 0)
3874 	    {
3875 	      /* sanity checks.  */
3876 	      reloc_howto_type *reloc_howto
3877 		= bfd_reloc_type_lookup (stdoutput,
3878 					 (bfd_reloc_code_real_type) reloc);
3879 	      unsigned reloc_bitsize = reloc_howto->bitsize;
3880 	      if (reloc_howto->rightshift)
3881 		reloc_bitsize -= reloc_howto->rightshift;
3882 	      if (reloc_bitsize != operand->bits)
3883 		{
3884 		  as_bad (_("invalid relocation %s for field"),
3885 			  bfd_get_reloc_code_name (reloc));
3886 		  return;
3887 		}
3888 	    }
3889 #endif
3890 	  if (insn->nfixups >= MAX_INSN_FIXUPS)
3891 	    as_fatal (_("too many fixups"));
3892 
3893 	  struct arc_fixup *fixup;
3894 	  fixup = &insn->fixups[insn->nfixups++];
3895 	  fixup->exp = *t;
3896 	  fixup->reloc = reloc;
3897 	  pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
3898 	  fixup->pcrel = pcrel;
3899 	  fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
3900 	    TRUE : FALSE;
3901 	  break;
3902 	}
3903     }
3904 
3905   /* Handle flags.  */
3906   for (i = 0; i < nflg; i++)
3907     {
3908       const struct arc_flag_operand *flg_operand = pflags[i].flgp;
3909 
3910       /* Check if the instruction has a delay slot.  */
3911       if (!strcmp (flg_operand->name, "d"))
3912 	has_delay_slot = TRUE;
3913 
3914       /* There is an exceptional case when we cannot insert a flag
3915 	 just as it is.  The .T flag must be handled in relation with
3916 	 the relative address.  */
3917       if (!strcmp (flg_operand->name, "t")
3918 	  || !strcmp (flg_operand->name, "nt"))
3919 	{
3920 	  unsigned bitYoperand = 0;
3921 	  /* FIXME! move selection bbit/brcc in arc-opc.c.  */
3922 	  if (!strcmp (flg_operand->name, "t"))
3923 	    if (!strcmp (opcode->name, "bbit0")
3924 		|| !strcmp (opcode->name, "bbit1"))
3925 	      bitYoperand = arc_NToperand;
3926 	    else
3927 	      bitYoperand = arc_Toperand;
3928 	  else
3929 	    if (!strcmp (opcode->name, "bbit0")
3930 		|| !strcmp (opcode->name, "bbit1"))
3931 	      bitYoperand = arc_Toperand;
3932 	    else
3933 	      bitYoperand = arc_NToperand;
3934 
3935 	  gas_assert (reloc_exp != NULL);
3936 	  if (reloc_exp->X_op == O_constant)
3937 	    {
3938 	      /* Check if we have a constant and solved it
3939 		 immediately.  */
3940 	      offsetT val = reloc_exp->X_add_number;
3941 	      image |= insert_operand (image, &arc_operands[bitYoperand],
3942 				       val, NULL, 0);
3943 	    }
3944 	  else
3945 	    {
3946 	      struct arc_fixup *fixup;
3947 
3948 	      if (insn->nfixups >= MAX_INSN_FIXUPS)
3949 		as_fatal (_("too many fixups"));
3950 
3951 	      fixup = &insn->fixups[insn->nfixups++];
3952 	      fixup->exp = *reloc_exp;
3953 	      fixup->reloc = -bitYoperand;
3954 	      fixup->pcrel = pcrel;
3955 	      fixup->islong = FALSE;
3956 	    }
3957 	}
3958       else
3959 	image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
3960 	  << flg_operand->shift;
3961     }
3962 
3963   insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
3964 
3965   /* Short instruction?  */
3966   insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
3967 
3968   insn->insn = image;
3969 
3970   /* Update last insn status.  */
3971   arc_last_insns[1]		   = arc_last_insns[0];
3972   arc_last_insns[0].opcode	   = opcode;
3973   arc_last_insns[0].has_limm	   = insn->has_limm;
3974   arc_last_insns[0].has_delay_slot = has_delay_slot;
3975 
3976   /* Check if the current instruction is legally used.  */
3977   if (arc_last_insns[1].has_delay_slot
3978       && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3979     as_bad_where (frag_now->fr_file, frag_now->fr_line,
3980 		  _("A jump/branch instruction in delay slot."));
3981 }
3982 
3983 void
arc_handle_align(fragS * fragP)3984 arc_handle_align (fragS* fragP)
3985 {
3986   if ((fragP)->fr_type == rs_align_code)
3987     {
3988       char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3989       valueT count = ((fragP)->fr_next->fr_address
3990 		      - (fragP)->fr_address - (fragP)->fr_fix);
3991 
3992       (fragP)->fr_var = 2;
3993 
3994       if (count & 1)/* Padding in the gap till the next 2-byte
3995 		       boundary with 0s.  */
3996 	{
3997 	  (fragP)->fr_fix++;
3998 	  *dest++ = 0;
3999 	}
4000       /* Writing nop_s.  */
4001       md_number_to_chars (dest, NOP_OPCODE_S, 2);
4002     }
4003 }
4004 
4005 /* Here we decide which fixups can be adjusted to make them relative
4006    to the beginning of the section instead of the symbol.  Basically
4007    we need to make sure that the dynamic relocations are done
4008    correctly, so in some cases we force the original symbol to be
4009    used.  */
4010 
4011 int
tc_arc_fix_adjustable(fixS * fixP)4012 tc_arc_fix_adjustable (fixS *fixP)
4013 {
4014 
4015   /* Prevent all adjustments to global symbols.  */
4016   if (S_IS_EXTERNAL (fixP->fx_addsy))
4017     return 0;
4018   if (S_IS_WEAK (fixP->fx_addsy))
4019     return 0;
4020 
4021   /* Adjust_reloc_syms doesn't know about the GOT.  */
4022   switch (fixP->fx_r_type)
4023     {
4024     case BFD_RELOC_ARC_GOTPC32:
4025     case BFD_RELOC_ARC_PLT32:
4026     case BFD_RELOC_ARC_S25H_PCREL_PLT:
4027     case BFD_RELOC_ARC_S21H_PCREL_PLT:
4028     case BFD_RELOC_ARC_S25W_PCREL_PLT:
4029     case BFD_RELOC_ARC_S21W_PCREL_PLT:
4030       return 0;
4031 
4032     default:
4033       break;
4034     }
4035 
4036   return 1;
4037 }
4038 
4039 /* Compute the reloc type of an expression EXP.  */
4040 
4041 static void
arc_check_reloc(expressionS * exp,bfd_reloc_code_real_type * r_type_p)4042 arc_check_reloc (expressionS *exp,
4043 		 bfd_reloc_code_real_type *r_type_p)
4044 {
4045   if (*r_type_p == BFD_RELOC_32
4046       && exp->X_op == O_subtract
4047       && exp->X_op_symbol != NULL
4048       && exp->X_op_symbol->bsym->section == now_seg)
4049     *r_type_p = BFD_RELOC_ARC_32_PCREL;
4050 }
4051 
4052 
4053 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG.  */
4054 
4055 void
arc_cons_fix_new(fragS * frag,int off,int size,expressionS * exp,bfd_reloc_code_real_type r_type)4056 arc_cons_fix_new (fragS *frag,
4057 		  int off,
4058 		  int size,
4059 		  expressionS *exp,
4060 		  bfd_reloc_code_real_type r_type)
4061 {
4062   r_type = BFD_RELOC_UNUSED;
4063 
4064   switch (size)
4065     {
4066     case 1:
4067       r_type = BFD_RELOC_8;
4068       break;
4069 
4070     case 2:
4071       r_type = BFD_RELOC_16;
4072       break;
4073 
4074     case 3:
4075       r_type = BFD_RELOC_24;
4076       break;
4077 
4078     case 4:
4079       r_type = BFD_RELOC_32;
4080       arc_check_reloc (exp, &r_type);
4081       break;
4082 
4083     case 8:
4084       r_type = BFD_RELOC_64;
4085       break;
4086 
4087     default:
4088       as_bad (_("unsupported BFD relocation size %u"), size);
4089       r_type = BFD_RELOC_UNUSED;
4090     }
4091 
4092   fix_new_exp (frag, off, size, exp, 0, r_type);
4093 }
4094 
4095 /* The actual routine that checks the ZOL conditions.  */
4096 
4097 static void
check_zol(symbolS * s)4098 check_zol (symbolS *s)
4099 {
4100   switch (arc_mach_type)
4101     {
4102     case bfd_mach_arc_arcv2:
4103       if (arc_target & ARC_OPCODE_ARCv2EM)
4104 	return;
4105 
4106       if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
4107 	  || arc_last_insns[1].has_delay_slot)
4108 	as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4109 		S_GET_NAME (s));
4110 
4111       break;
4112     case bfd_mach_arc_arc600:
4113 
4114       if (is_kernel_insn_p (arc_last_insns[0].opcode))
4115 	as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4116 		S_GET_NAME (s));
4117 
4118       if (arc_last_insns[0].has_limm
4119 	  && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4120 	as_bad (_("A jump instruction with long immediate detected at the \
4121 end of the ZOL label @%s"), S_GET_NAME (s));
4122 
4123       /* Fall through.  */
4124     case bfd_mach_arc_arc700:
4125       if (arc_last_insns[0].has_delay_slot)
4126 	as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4127 		S_GET_NAME (s));
4128 
4129       break;
4130     default:
4131       break;
4132     }
4133 }
4134 
4135 /* If ZOL end check the last two instruction for illegals.  */
4136 void
arc_frob_label(symbolS * sym)4137 arc_frob_label (symbolS * sym)
4138 {
4139   if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
4140     check_zol (sym);
4141 
4142   dwarf2_emit_label (sym);
4143 }
4144 
4145 /* Used because generic relaxation assumes a pc-rel value whilst we
4146    also relax instructions that use an absolute value resolved out of
4147    relative values (if that makes any sense).  An example: 'add r1,
4148    r2, @.L2 - .'  The symbols . and @.L2 are relative to the section
4149    but if they're in the same section we can subtract the section
4150    offset relocation which ends up in a resolved value.  So if @.L2 is
4151    .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4152    .text + 0x40 = 0x10.  */
4153 int
arc_pcrel_adjust(fragS * fragP)4154 arc_pcrel_adjust (fragS *fragP)
4155 {
4156   if (!fragP->tc_frag_data.pcrel)
4157     return fragP->fr_address + fragP->fr_fix;
4158 
4159   return 0;
4160 }
4161 
4162 /* Initialize the DWARF-2 unwind information for this procedure.  */
4163 
4164 void
tc_arc_frame_initial_instructions(void)4165 tc_arc_frame_initial_instructions (void)
4166 {
4167   /* Stack pointer is register 28.  */
4168   cfi_add_CFA_def_cfa (28, 0);
4169 }
4170 
4171 int
tc_arc_regname_to_dw2regnum(char * regname)4172 tc_arc_regname_to_dw2regnum (char *regname)
4173 {
4174   struct symbol *sym;
4175 
4176   sym = hash_find (arc_reg_hash, regname);
4177   if (sym)
4178     return S_GET_VALUE (sym);
4179 
4180   return -1;
4181 }
4182 
4183 /* Adjust the symbol table.  Delete found AUX register symbols.  */
4184 
4185 void
arc_adjust_symtab(void)4186 arc_adjust_symtab (void)
4187 {
4188   symbolS * sym;
4189 
4190   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
4191     {
4192       /* I've created a symbol during parsing process.  Now, remove
4193 	 the symbol as it is found to be an AUX register.  */
4194       if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
4195 	symbol_remove (sym, &symbol_rootP, &symbol_lastP);
4196     }
4197 
4198   /* Now do generic ELF adjustments.  */
4199   elf_adjust_symtab ();
4200 }
4201 
4202 static void
tokenize_extinsn(extInstruction_t * einsn)4203 tokenize_extinsn (extInstruction_t *einsn)
4204 {
4205   char *p, c;
4206   char *insn_name;
4207   unsigned char major_opcode;
4208   unsigned char sub_opcode;
4209   unsigned char syntax_class = 0;
4210   unsigned char syntax_class_modifiers = 0;
4211   unsigned char suffix_class = 0;
4212   unsigned int i;
4213 
4214   SKIP_WHITESPACE ();
4215 
4216   /* 1st: get instruction name.  */
4217   p = input_line_pointer;
4218   c = get_symbol_name (&p);
4219 
4220   insn_name = xstrdup (p);
4221   restore_line_pointer (c);
4222 
4223   /* 2nd: get major opcode.  */
4224   if (*input_line_pointer != ',')
4225     {
4226       as_bad (_("expected comma after instruction name"));
4227       ignore_rest_of_line ();
4228       return;
4229     }
4230   input_line_pointer++;
4231   major_opcode = get_absolute_expression ();
4232 
4233   /* 3rd: get sub-opcode.  */
4234   SKIP_WHITESPACE ();
4235 
4236   if (*input_line_pointer != ',')
4237     {
4238       as_bad (_("expected comma after major opcode"));
4239       ignore_rest_of_line ();
4240       return;
4241     }
4242   input_line_pointer++;
4243   sub_opcode = get_absolute_expression ();
4244 
4245   /* 4th: get suffix class.  */
4246   SKIP_WHITESPACE ();
4247 
4248   if (*input_line_pointer != ',')
4249     {
4250       as_bad ("expected comma after sub opcode");
4251       ignore_rest_of_line ();
4252       return;
4253     }
4254   input_line_pointer++;
4255 
4256   while (1)
4257     {
4258       SKIP_WHITESPACE ();
4259 
4260       for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
4261 	{
4262 	  if (!strncmp (suffixclass[i].name, input_line_pointer,
4263 			suffixclass[i].len))
4264 	    {
4265 	      suffix_class |= suffixclass[i].attr_class;
4266 	      input_line_pointer += suffixclass[i].len;
4267 	      break;
4268 	    }
4269 	}
4270 
4271       if (i == ARRAY_SIZE (suffixclass))
4272 	{
4273 	  as_bad ("invalid suffix class");
4274 	  ignore_rest_of_line ();
4275 	  return;
4276 	}
4277 
4278       SKIP_WHITESPACE ();
4279 
4280       if (*input_line_pointer == '|')
4281 	input_line_pointer++;
4282       else
4283 	break;
4284     }
4285 
4286   /* 5th: get syntax class and syntax class modifiers.  */
4287   if (*input_line_pointer != ',')
4288     {
4289       as_bad ("expected comma after suffix class");
4290       ignore_rest_of_line ();
4291       return;
4292     }
4293   input_line_pointer++;
4294 
4295   while (1)
4296     {
4297       SKIP_WHITESPACE ();
4298 
4299       for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
4300 	{
4301 	  if (!strncmp (syntaxclassmod[i].name,
4302 			input_line_pointer,
4303 			syntaxclassmod[i].len))
4304 	    {
4305 	      syntax_class_modifiers |= syntaxclassmod[i].attr_class;
4306 	      input_line_pointer += syntaxclassmod[i].len;
4307 	      break;
4308 	    }
4309 	}
4310 
4311       if (i == ARRAY_SIZE (syntaxclassmod))
4312 	{
4313 	  for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
4314 	    {
4315 	      if (!strncmp (syntaxclass[i].name,
4316 			    input_line_pointer,
4317 			    syntaxclass[i].len))
4318 		{
4319 		  syntax_class |= syntaxclass[i].attr_class;
4320 		  input_line_pointer += syntaxclass[i].len;
4321 		  break;
4322 		}
4323 	    }
4324 
4325 	  if (i == ARRAY_SIZE (syntaxclass))
4326 	    {
4327 	      as_bad ("missing syntax class");
4328 	      ignore_rest_of_line ();
4329 	      return;
4330 	    }
4331 	}
4332 
4333       SKIP_WHITESPACE ();
4334 
4335       if (*input_line_pointer == '|')
4336 	input_line_pointer++;
4337       else
4338 	break;
4339     }
4340 
4341   demand_empty_rest_of_line ();
4342 
4343   einsn->name   = insn_name;
4344   einsn->major  = major_opcode;
4345   einsn->minor  = sub_opcode;
4346   einsn->syntax = syntax_class;
4347   einsn->modsyn = syntax_class_modifiers;
4348   einsn->suffix = suffix_class;
4349   einsn->flags  = syntax_class
4350     | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
4351 }
4352 
4353 /* Generate an extension section.  */
4354 
4355 static int
arc_set_ext_seg(void)4356 arc_set_ext_seg (void)
4357 {
4358   if (!arcext_section)
4359     {
4360       arcext_section = subseg_new (".arcextmap", 0);
4361       bfd_set_section_flags (stdoutput, arcext_section,
4362 			     SEC_READONLY | SEC_HAS_CONTENTS);
4363     }
4364   else
4365     subseg_set (arcext_section, 0);
4366   return 1;
4367 }
4368 
4369 /* Create an extension instruction description in the arc extension
4370    section of the output file.
4371    The structure for an instruction is like this:
4372    [0]: Length of the record.
4373    [1]: Type of the record.
4374 
4375    [2]: Major opcode.
4376    [3]: Sub-opcode.
4377    [4]: Syntax (flags).
4378    [5]+ Name instruction.
4379 
4380    The sequence is terminated by an empty entry.  */
4381 
4382 static void
create_extinst_section(extInstruction_t * einsn)4383 create_extinst_section (extInstruction_t *einsn)
4384 {
4385 
4386   segT old_sec    = now_seg;
4387   int old_subsec  = now_subseg;
4388   char *p;
4389   int name_len    = strlen (einsn->name);
4390 
4391   arc_set_ext_seg ();
4392 
4393   p = frag_more (1);
4394   *p = 5 + name_len + 1;
4395   p = frag_more (1);
4396   *p = EXT_INSTRUCTION;
4397   p = frag_more (1);
4398   *p = einsn->major;
4399   p = frag_more (1);
4400   *p = einsn->minor;
4401   p = frag_more (1);
4402   *p = einsn->flags;
4403   p = frag_more (name_len + 1);
4404   strcpy (p, einsn->name);
4405 
4406   subseg_set (old_sec, old_subsec);
4407 }
4408 
4409 /* Handler .extinstruction pseudo-op.  */
4410 
4411 static void
arc_extinsn(int ignore ATTRIBUTE_UNUSED)4412 arc_extinsn (int ignore ATTRIBUTE_UNUSED)
4413 {
4414   extInstruction_t einsn;
4415   struct arc_opcode *arc_ext_opcodes;
4416   const char *errmsg = NULL;
4417   unsigned char moplow, mophigh;
4418 
4419   memset (&einsn, 0, sizeof (einsn));
4420   tokenize_extinsn (&einsn);
4421 
4422   /* Check if the name is already used.  */
4423   if (arc_find_opcode (einsn.name))
4424     as_warn (_("Pseudocode already used %s"), einsn.name);
4425 
4426   /* Check the opcode ranges.  */
4427   moplow = 0x05;
4428   mophigh = (arc_target & (ARC_OPCODE_ARCv2EM
4429 			   | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
4430 
4431   if ((einsn.major > mophigh) || (einsn.major < moplow))
4432     as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
4433 
4434   if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
4435       && (einsn.major != 5) && (einsn.major != 9))
4436     as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4437 
4438   switch (einsn.syntax & ARC_SYNTAX_MASK)
4439     {
4440     case ARC_SYNTAX_3OP:
4441       if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
4442 	as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4443       break;
4444     case ARC_SYNTAX_2OP:
4445     case ARC_SYNTAX_1OP:
4446     case ARC_SYNTAX_NOP:
4447       if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
4448 	as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4449       break;
4450     default:
4451       break;
4452     }
4453 
4454   arc_ext_opcodes = arcExtMap_genOpcode (&einsn, arc_target, &errmsg);
4455   if (arc_ext_opcodes == NULL)
4456     {
4457       if (errmsg)
4458 	as_fatal ("%s", errmsg);
4459       else
4460 	as_fatal (_("Couldn't generate extension instruction opcodes"));
4461     }
4462   else if (errmsg)
4463     as_warn ("%s", errmsg);
4464 
4465   /* Insert the extension instruction.  */
4466   arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes);
4467 
4468   create_extinst_section (&einsn);
4469 }
4470 
4471 static void
tokenize_extregister(extRegister_t * ereg,int opertype)4472 tokenize_extregister (extRegister_t *ereg, int opertype)
4473 {
4474   char *name;
4475   char *mode;
4476   char c;
4477   char *p;
4478   int number, imode = 0;
4479   bfd_boolean isCore_p = (opertype == EXT_CORE_REGISTER) ? TRUE : FALSE;
4480   bfd_boolean isReg_p  = (opertype == EXT_CORE_REGISTER
4481 			  || opertype == EXT_AUX_REGISTER) ? TRUE : FALSE;
4482 
4483   /* 1st: get register name.  */
4484   SKIP_WHITESPACE ();
4485   p = input_line_pointer;
4486   c = get_symbol_name (&p);
4487 
4488   name = xstrdup (p);
4489   restore_line_pointer (c);
4490 
4491   /* 2nd: get register number.  */
4492   SKIP_WHITESPACE ();
4493 
4494   if (*input_line_pointer != ',')
4495     {
4496       as_bad (_("expected comma after register name"));
4497       ignore_rest_of_line ();
4498       free (name);
4499       return;
4500     }
4501   input_line_pointer++;
4502   number = get_absolute_expression ();
4503 
4504   if (number < 0)
4505     {
4506       as_bad (_("negative operand number %d"), number);
4507       ignore_rest_of_line ();
4508       free (name);
4509       return;
4510     }
4511 
4512   if (isReg_p)
4513     {
4514       /* 3rd: get register mode.  */
4515       SKIP_WHITESPACE ();
4516 
4517       if (*input_line_pointer != ',')
4518 	{
4519 	  as_bad (_("expected comma after register number"));
4520 	  ignore_rest_of_line ();
4521 	  free (name);
4522 	  return;
4523 	}
4524 
4525       input_line_pointer++;
4526       mode = input_line_pointer;
4527 
4528       if (!strncmp (mode, "r|w", 3))
4529 	{
4530 	  imode = 0;
4531 	  input_line_pointer += 3;
4532 	}
4533       else if (!strncmp (mode, "r", 1))
4534 	{
4535 	  imode = ARC_REGISTER_READONLY;
4536 	  input_line_pointer += 1;
4537 	}
4538       else if (strncmp (mode, "w", 1))
4539 	{
4540 	  as_bad (_("invalid mode"));
4541 	  ignore_rest_of_line ();
4542 	  free (name);
4543 	  return;
4544 	}
4545       else
4546 	{
4547 	  imode = ARC_REGISTER_WRITEONLY;
4548 	  input_line_pointer += 1;
4549 	}
4550     }
4551 
4552   if (isCore_p)
4553     {
4554       /* 4th: get core register shortcut.  */
4555       SKIP_WHITESPACE ();
4556       if (*input_line_pointer != ',')
4557 	{
4558 	  as_bad (_("expected comma after register mode"));
4559 	  ignore_rest_of_line ();
4560 	  free (name);
4561 	  return;
4562 	}
4563 
4564       input_line_pointer++;
4565 
4566       if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
4567 	{
4568 	  imode |= ARC_REGISTER_NOSHORT_CUT;
4569 	  input_line_pointer += 15;
4570 	}
4571       else if (strncmp (input_line_pointer, "can_shortcut", 12))
4572 	{
4573 	  as_bad (_("shortcut designator invalid"));
4574 	  ignore_rest_of_line ();
4575 	  free (name);
4576 	  return;
4577 	}
4578       else
4579 	{
4580 	  input_line_pointer += 12;
4581 	}
4582     }
4583   demand_empty_rest_of_line ();
4584 
4585   ereg->name = name;
4586   ereg->number = number;
4587   ereg->imode  = imode;
4588 }
4589 
4590 /* Create an extension register/condition description in the arc
4591    extension section of the output file.
4592 
4593    The structure for an instruction is like this:
4594    [0]: Length of the record.
4595    [1]: Type of the record.
4596 
4597    For core regs and condition codes:
4598    [2]: Value.
4599    [3]+ Name.
4600 
4601    For auxilirary registers:
4602    [2..5]: Value.
4603    [6]+ Name
4604 
4605    The sequence is terminated by an empty entry.  */
4606 
4607 static void
create_extcore_section(extRegister_t * ereg,int opertype)4608 create_extcore_section (extRegister_t *ereg, int opertype)
4609 {
4610   segT old_sec   = now_seg;
4611   int old_subsec = now_subseg;
4612   char *p;
4613   int name_len   = strlen (ereg->name);
4614 
4615   arc_set_ext_seg ();
4616 
4617   switch (opertype)
4618     {
4619     case EXT_COND_CODE:
4620     case EXT_CORE_REGISTER:
4621       p = frag_more (1);
4622       *p = 3 + name_len + 1;
4623       p = frag_more (1);
4624       *p = opertype;
4625       p = frag_more (1);
4626       *p = ereg->number;
4627       break;
4628     case EXT_AUX_REGISTER:
4629       p = frag_more (1);
4630       *p = 6 + name_len + 1;
4631       p = frag_more (1);
4632       *p = EXT_AUX_REGISTER;
4633       p = frag_more (1);
4634       *p = (ereg->number >> 24) & 0xff;
4635       p = frag_more (1);
4636       *p = (ereg->number >> 16) & 0xff;
4637       p = frag_more (1);
4638       *p = (ereg->number >>  8) & 0xff;
4639       p = frag_more (1);
4640       *p = (ereg->number)       & 0xff;
4641       break;
4642     default:
4643       break;
4644     }
4645 
4646   p = frag_more (name_len + 1);
4647   strcpy (p, ereg->name);
4648 
4649   subseg_set (old_sec, old_subsec);
4650 }
4651 
4652 /* Handler .extCoreRegister pseudo-op.  */
4653 
4654 static void
arc_extcorereg(int opertype)4655 arc_extcorereg (int opertype)
4656 {
4657   extRegister_t ereg;
4658   struct arc_aux_reg *auxr;
4659   const char *retval;
4660   struct arc_flag_operand *ccode;
4661 
4662   memset (&ereg, 0, sizeof (ereg));
4663   tokenize_extregister (&ereg, opertype);
4664 
4665   switch (opertype)
4666     {
4667     case EXT_CORE_REGISTER:
4668       /* Core register.  */
4669       if (ereg.number > 60)
4670 	as_bad (_("core register %s value (%d) too large"), ereg.name,
4671 		ereg.number);
4672       declare_register (ereg.name, ereg.number);
4673       break;
4674     case EXT_AUX_REGISTER:
4675       /* Auxiliary register.  */
4676       auxr = XNEW (struct arc_aux_reg);
4677       auxr->name = ereg.name;
4678       auxr->cpu = arc_target;
4679       auxr->subclass = NONE;
4680       auxr->address = ereg.number;
4681       retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
4682       if (retval)
4683 	as_fatal (_("internal error: can't hash aux register '%s': %s"),
4684 		  auxr->name, retval);
4685       break;
4686     case EXT_COND_CODE:
4687       /* Condition code.  */
4688       if (ereg.number > 31)
4689 	as_bad (_("condition code %s value (%d) too large"), ereg.name,
4690 		ereg.number);
4691       ext_condcode.size ++;
4692       ext_condcode.arc_ext_condcode =
4693 	XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
4694 		    ext_condcode.size + 1);
4695       if (ext_condcode.arc_ext_condcode == NULL)
4696 	as_fatal (_("Virtual memory exhausted"));
4697 
4698       ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
4699       ccode->name   = ereg.name;
4700       ccode->code   = ereg.number;
4701       ccode->bits   = 5;
4702       ccode->shift  = 0;
4703       ccode->favail = 0; /* not used.  */
4704       ccode++;
4705       memset (ccode, 0, sizeof (struct arc_flag_operand));
4706       break;
4707     default:
4708       as_bad (_("Unknown extension"));
4709       break;
4710     }
4711   create_extcore_section (&ereg, opertype);
4712 }
4713 
4714 /* Local variables:
4715    eval: (c-set-style "gnu")
4716    indent-tabs-mode: t
4717    End:  */
4718