x86: correct "-Q" option handling
[external/binutils.git] / gas / config / tc-or1k.c
1 /* tc-or1k.c -- Assembler for the OpenRISC family.
2    Copyright (C) 2001-2019 Free Software Foundation, Inc.
3    Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org
4
5    This file is part of GAS, the GNU Assembler.
6
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, see <http://www.gnu.org/licenses/> */
19 #include "as.h"
20 #include "safe-ctype.h"
21 #include "subsegs.h"
22 #include "symcat.h"
23 #include "opcodes/or1k-desc.h"
24 #include "opcodes/or1k-opc.h"
25 #include "cgen.h"
26 #include "elf/or1k.h"
27 #include "dw2gencfi.h"
28
29 /* Structure to hold all of the different components describing
30    an individual instruction.  */
31
32 typedef struct
33 {
34   const CGEN_INSN *     insn;
35   const CGEN_INSN *     orig_insn;
36   CGEN_FIELDS           fields;
37 #if CGEN_INT_INSN_P
38   CGEN_INSN_INT         buffer [1];
39 #define INSN_VALUE(buf) (*(buf))
40 #else
41   unsigned char         buffer [CGEN_MAX_INSN_SIZE];
42 #define INSN_VALUE(buf) (buf)
43 #endif
44   char *                addr;
45   fragS *               frag;
46   int                   num_fixups;
47   fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
48   int                   indices [MAX_OPERAND_INSTANCES];
49 }
50 or1k_insn;
51
52 const char comment_chars[]        = "#";
53 const char line_comment_chars[]   = "#";
54 const char line_separator_chars[] = ";";
55 const char EXP_CHARS[]            = "eE";
56 const char FLT_CHARS[]            = "dD";
57
58 #define OR1K_SHORTOPTS "m:"
59 const char * md_shortopts = OR1K_SHORTOPTS;
60
61 struct option md_longopts[] =
62 {
63   {NULL, no_argument, NULL, 0}
64 };
65 size_t md_longopts_size = sizeof (md_longopts);
66
67 unsigned long or1k_machine = 0; /* default */
68
69 int
70 md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
71 {
72   return 0;
73 }
74
75 void
76 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
77 {
78 }
79
80 static void
81 ignore_pseudo (int val ATTRIBUTE_UNUSED)
82 {
83   discard_rest_of_line ();
84 }
85
86 static bfd_boolean nodelay = FALSE;
87 static void
88 s_nodelay (int val ATTRIBUTE_UNUSED)
89 {
90   nodelay = TRUE;
91 }
92
93 const char or1k_comment_chars [] = ";#";
94
95 /* The target specific pseudo-ops which we support.  */
96 const pseudo_typeS md_pseudo_table[] =
97 {
98   { "align",    s_align_bytes,  0 },
99   { "word",     cons,           4 },
100   { "proc",     ignore_pseudo,  0 },
101   { "endproc",  ignore_pseudo,  0 },
102   { "nodelay",  s_nodelay,      0 },
103   { NULL,       NULL,           0 }
104 };
105
106
107 void
108 md_begin (void)
109 {
110   /* Initialize the `cgen' interface.  */
111
112   /* Set the machine number and endian.  */
113   gas_cgen_cpu_desc = or1k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
114                                               CGEN_CPU_OPEN_ENDIAN,
115                                               CGEN_ENDIAN_BIG,
116                                               CGEN_CPU_OPEN_END);
117   or1k_cgen_init_asm (gas_cgen_cpu_desc);
118
119   /* This is a callback from cgen to gas to parse operands.  */
120   cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
121 }
122
123 void
124 md_assemble (char * str)
125 {
126   static int last_insn_had_delay_slot = 0;
127   or1k_insn insn;
128   char *    errmsg;
129
130   /* Initialize GAS's cgen interface for a new instruction.  */
131   gas_cgen_init_parse ();
132
133   insn.insn = or1k_cgen_assemble_insn
134     (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
135
136   if (!insn.insn)
137     {
138       as_bad ("%s", errmsg);
139       return;
140     }
141
142   /* Doesn't really matter what we pass for RELAX_P here.  */
143   gas_cgen_finish_insn (insn.insn, insn.buffer,
144                         CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
145
146   last_insn_had_delay_slot
147     = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
148   (void) last_insn_had_delay_slot;
149 }
150
151
152 /* The syntax in the manual says constants begin with '#'.
153    We just ignore it.  */
154
155 void
156 md_operand (expressionS * expressionP)
157 {
158   if (* input_line_pointer == '#')
159     {
160       input_line_pointer ++;
161       expression (expressionP);
162     }
163 }
164
165 valueT
166 md_section_align (segT segment, valueT size)
167 {
168   int align = bfd_get_section_alignment (stdoutput, segment);
169   return ((size + (1 << align) - 1) & -(1 << align));
170 }
171
172 symbolS *
173 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
174 {
175   return 0;
176 }
177
178
179 /* Interface to relax_segment.  */
180
181 const relax_typeS md_relax_table[] =
182 {
183 /* The fields are:
184    1) most positive reach of this state,
185    2) most negative reach of this state,
186    3) how many bytes this mode will add to the size of the current frag
187    4) which index into the table to try if we can't fit into this one.  */
188
189   /* The first entry must be unused because an `rlx_more' value of zero ends
190      each list.  */
191   {1, 1, 0, 0},
192
193   /* The displacement used by GAS is from the end of the 4 byte insn,
194      so we subtract 4 from the following.  */
195   {(((1 << 25) - 1) << 2) - 4, -(1 << 25) - 4, 0, 0},
196 };
197
198 int
199 md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
200 {
201   return md_relax_table[fragP->fr_subtype].rlx_length;
202 }
203
204 /* *fragP has been relaxed to its final size, and now needs to have
205    the bytes inside it modified to conform to the new size.
206
207    Called after relaxation is finished.
208    fragP->fr_type == rs_machine_dependent.
209    fragP->fr_subtype is the subtype of what the address relaxed to.  */
210
211 void
212 md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
213                  segT    sec  ATTRIBUTE_UNUSED,
214                  fragS * fragP ATTRIBUTE_UNUSED)
215 {
216   /* FIXME */
217 }
218
219
220 /* Functions concerning relocs.  */
221
222 /* The location from which a PC relative jump should be calculated,
223    given a PC relative reloc.  */
224
225 long
226 md_pcrel_from_section (fixS * fixP, segT sec)
227 {
228   if (fixP->fx_addsy != (symbolS *) NULL
229       && (! S_IS_DEFINED (fixP->fx_addsy)
230           || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
231           || S_IS_EXTERNAL (fixP->fx_addsy)
232           || S_IS_WEAK (fixP->fx_addsy)))
233     {
234         /* The symbol is undefined (or is defined but not in this section).
235          Let the linker figure it out.  */
236       return 0;
237     }
238
239   return fixP->fx_frag->fr_address + fixP->fx_where;
240 }
241
242
243 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
244    Returns BFD_RELOC_NONE if no reloc type can be found.
245    *FIXP may be modified if desired.  */
246
247 bfd_reloc_code_real_type
248 md_cgen_lookup_reloc (const CGEN_INSN *    insn ATTRIBUTE_UNUSED,
249                       const CGEN_OPERAND * operand,
250                       fixS *               fixP)
251 {
252   if (fixP->fx_cgen.opinfo)
253     return fixP->fx_cgen.opinfo;
254
255   switch (operand->type)
256     {
257     case OR1K_OPERAND_DISP26:
258       fixP->fx_pcrel = 1;
259       return BFD_RELOC_OR1K_REL_26;
260
261     default: /* avoid -Wall warning */
262       return BFD_RELOC_NONE;
263     }
264 }
265
266 /* Write a value out to the object file, using the appropriate endianness.  */
267
268 void
269 md_number_to_chars (char * buf, valueT val, int n)
270 {
271   number_to_chars_bigendian (buf, val, n);
272 }
273
274 /* Turn a string in input_line_pointer into a floating point constant of type
275    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
276    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.  */
277
278 const char *
279 md_atof (int type, char * litP, int *  sizeP)
280 {
281   return ieee_md_atof (type, litP, sizeP, TRUE);
282 }
283
284 bfd_boolean
285 or1k_fix_adjustable (fixS * fixP)
286 {
287   /* We need the symbol name for the VTABLE entries.  */
288   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
289       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
290     return FALSE;
291
292   return TRUE;
293 }
294
295 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
296
297 arelent *
298 tc_gen_reloc (asection * section, fixS * fixp)
299 {
300   arelent *reloc;
301   bfd_reloc_code_real_type code;
302
303   reloc = XNEW (arelent);
304
305   reloc->sym_ptr_ptr = XNEW (asymbol *);
306   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
307   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
308
309   if (fixp->fx_pcrel)
310     {
311       if (section->use_rela_p)
312         fixp->fx_offset -= md_pcrel_from_section (fixp, section);
313       else
314         fixp->fx_offset = reloc->address;
315     }
316   reloc->addend = fixp->fx_offset;
317
318   code = fixp->fx_r_type;
319   switch (code)
320     {
321     case BFD_RELOC_16:
322       if (fixp->fx_pcrel)
323         code = BFD_RELOC_16_PCREL;
324       break;
325
326     case BFD_RELOC_32:
327       if (fixp->fx_pcrel)
328         code = BFD_RELOC_32_PCREL;
329       break;
330
331     case BFD_RELOC_64:
332       if (fixp->fx_pcrel)
333         code = BFD_RELOC_64_PCREL;
334       break;
335
336     default:
337       break;
338     }
339
340   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
341   if (reloc->howto == NULL)
342     {
343       as_bad_where (fixp->fx_file, fixp->fx_line,
344                     _
345                     ("cannot represent %s relocation in this object file format"),
346                     bfd_get_reloc_code_name (code));
347       return NULL;
348     }
349
350   return reloc;
351 }
352
353 void
354 or1k_apply_fix (struct fix *f, valueT *t, segT s)
355 {
356   gas_cgen_md_apply_fix (f, t, s);
357
358   switch (f->fx_r_type)
359     {
360     case BFD_RELOC_OR1K_TLS_GD_HI16:
361     case BFD_RELOC_OR1K_TLS_GD_LO16:
362     case BFD_RELOC_OR1K_TLS_GD_PG21:
363     case BFD_RELOC_OR1K_TLS_GD_LO13:
364     case BFD_RELOC_OR1K_TLS_LDM_HI16:
365     case BFD_RELOC_OR1K_TLS_LDM_LO16:
366     case BFD_RELOC_OR1K_TLS_LDM_PG21:
367     case BFD_RELOC_OR1K_TLS_LDM_LO13:
368     case BFD_RELOC_OR1K_TLS_LDO_HI16:
369     case BFD_RELOC_OR1K_TLS_LDO_LO16:
370     case BFD_RELOC_OR1K_TLS_IE_HI16:
371     case BFD_RELOC_OR1K_TLS_IE_LO16:
372     case BFD_RELOC_OR1K_TLS_IE_PG21:
373     case BFD_RELOC_OR1K_TLS_IE_LO13:
374     case BFD_RELOC_OR1K_TLS_LE_HI16:
375     case BFD_RELOC_OR1K_TLS_LE_LO16:
376       S_SET_THREAD_LOCAL (f->fx_addsy);
377       break;
378     default:
379       break;
380     }
381 }
382
383 void
384 or1k_elf_final_processing (void)
385 {
386   if (nodelay)
387     elf_elfheader (stdoutput)->e_flags |= EF_OR1K_NODELAY;
388 }
389
390 /* Standard calling conventions leave the CFA at SP on entry.  */
391
392 void
393 or1k_cfi_frame_initial_instructions (void)
394 {
395     cfi_add_CFA_def_cfa_register (1);
396 }
397