* config/atof-ieee.c, config/obj-coff.c, config/obj-elf.c,
[external/binutils.git] / gas / config / tc-openrisc.c
1 /* tc-openrisc.c -- Assembler for the OpenRISC family.
2    Copyright 2001, 2002, 2003 Free Software Foundation.
3    Contributed 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 2, 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 GAS; see the file COPYING.  If not, write to
19    the Free Software Foundation, 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include <stdio.h>
23 #include "as.h"
24 #include "subsegs.h"
25 #include "symcat.h"
26 #include "opcodes/openrisc-desc.h"
27 #include "opcodes/openrisc-opc.h"
28 #include "cgen.h"
29
30 /* Structure to hold all of the different components describing
31    an individual instruction.  */
32 typedef struct openrisc_insn openrisc_insn;
33
34 struct openrisc_insn
35 {
36   const CGEN_INSN *     insn;
37   const CGEN_INSN *     orig_insn;
38   CGEN_FIELDS           fields;
39 #if CGEN_INT_INSN_P
40   CGEN_INSN_INT         buffer [1];
41 #define INSN_VALUE(buf) (*(buf))
42 #else
43   unsigned char         buffer [CGEN_MAX_INSN_SIZE];
44 #define INSN_VALUE(buf) (buf)
45 #endif
46   char *                addr;
47   fragS *               frag;
48   int                   num_fixups;
49   fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
50   int                   indices [MAX_OPERAND_INSTANCES];
51 };
52
53
54 const char comment_chars[]        = "#";
55 const char line_comment_chars[]   = "#";
56 const char line_separator_chars[] = ";";
57 const char EXP_CHARS[]            = "eE";
58 const char FLT_CHARS[]            = "dD";
59
60 \f
61 #define OPENRISC_SHORTOPTS "m:"
62 const char * md_shortopts = OPENRISC_SHORTOPTS;
63
64 struct option md_longopts[] =
65 {
66   {NULL, no_argument, NULL, 0}
67 };
68 size_t md_longopts_size = sizeof (md_longopts);
69
70 unsigned long openrisc_machine = 0; /* default */
71
72 int
73 md_parse_option (c, arg)
74      int    c ATTRIBUTE_UNUSED;
75      char * arg ATTRIBUTE_UNUSED;
76 {
77   return 0;
78 }
79
80 void
81 md_show_usage (stream)
82   FILE * stream ATTRIBUTE_UNUSED;
83 {
84 }
85
86 static void ignore_pseudo PARAMS ((int));
87
88 static void
89 ignore_pseudo (val)
90      int val ATTRIBUTE_UNUSED;
91 {
92   discard_rest_of_line ();
93 }
94
95 const char openrisc_comment_chars [] = ";#";
96
97 /* The target specific pseudo-ops which we support.  */
98 const pseudo_typeS md_pseudo_table[] =
99 {
100   { "word",     cons,           4 },
101   { "proc",     ignore_pseudo,  0 },
102   { "endproc",  ignore_pseudo,  0 },
103   { NULL,       NULL,           0 }
104 };
105
106
107 \f
108 void
109 md_begin ()
110 {
111   /* Initialize the `cgen' interface.  */
112
113   /* Set the machine number and endian.  */
114   gas_cgen_cpu_desc = openrisc_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
115                                               CGEN_CPU_OPEN_ENDIAN,
116                                               CGEN_ENDIAN_BIG,
117                                               CGEN_CPU_OPEN_END);
118   openrisc_cgen_init_asm (gas_cgen_cpu_desc);
119
120   /* This is a callback from cgen to gas to parse operands.  */
121   cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
122 }
123
124 void
125 md_assemble (str)
126      char * str;
127 {
128   static int last_insn_had_delay_slot = 0;
129   openrisc_insn insn;
130   char *    errmsg;
131
132   /* Initialize GAS's cgen interface for a new instruction.  */
133   gas_cgen_init_parse ();
134
135   insn.insn = openrisc_cgen_assemble_insn
136     (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
137
138   if (!insn.insn)
139     {
140       as_bad (errmsg);
141       return;
142     }
143
144   /* Doesn't really matter what we pass for RELAX_P here.  */
145   gas_cgen_finish_insn (insn.insn, insn.buffer,
146                         CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
147
148   last_insn_had_delay_slot
149     = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
150 }
151
152
153 /* The syntax in the manual says constants begin with '#'.
154    We just ignore it.  */
155
156 void
157 md_operand (expressionP)
158      expressionS * expressionP;
159 {
160   if (* input_line_pointer == '#')
161     {
162       input_line_pointer ++;
163       expression (expressionP);
164     }
165 }
166
167 valueT
168 md_section_align (segment, size)
169      segT   segment;
170      valueT size;
171 {
172   int align = bfd_get_section_alignment (stdoutput, segment);
173   return ((size + (1 << align) - 1) & (-1 << align));
174 }
175
176 symbolS *
177 md_undefined_symbol (name)
178      char * name ATTRIBUTE_UNUSED;
179 {
180   return 0;
181 }
182
183 \f
184 /* Interface to relax_segment.  */
185
186 /* FIXME: Look through this.  */
187
188 const relax_typeS md_relax_table[] =
189 {
190 /* The fields are:
191    1) most positive reach of this state,
192    2) most negative reach of this state,
193    3) how many bytes this mode will add to the size of the current frag
194    4) which index into the table to try if we can't fit into this one.  */
195
196   /* The first entry must be unused because an `rlx_more' value of zero ends
197      each list.  */
198   {1, 1, 0, 0},
199
200   /* The displacement used by GAS is from the end of the 2 byte insn,
201      so we subtract 2 from the following.  */
202   /* 16 bit insn, 8 bit disp -> 10 bit range.
203      This doesn't handle a branch in the right slot at the border:
204      the "& -4" isn't taken into account.  It's not important enough to
205      complicate things over it, so we subtract an extra 2 (or + 2 in -ve
206      case).  */
207   {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
208   /* 32 bit insn, 24 bit disp -> 26 bit range.  */
209   {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
210   /* Same thing, but with leading nop for alignment.  */
211   {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
212 };
213
214 long
215 openrisc_relax_frag (segment, fragP, stretch)
216      segT    segment;
217      fragS * fragP;
218      long    stretch;
219 {
220   /* Address of branch insn.  */
221   long address = fragP->fr_address + fragP->fr_fix - 2;
222   long growth = 0;
223
224   /* Keep 32 bit insns aligned on 32 bit boundaries.  */
225   if (fragP->fr_subtype == 2)
226     {
227       if ((address & 3) != 0)
228         {
229           fragP->fr_subtype = 3;
230           growth = 2;
231         }
232     }
233   else if (fragP->fr_subtype == 3)
234     {
235       if ((address & 3) == 0)
236         {
237           fragP->fr_subtype = 2;
238           growth = -2;
239         }
240     }
241   else
242     {
243       growth = relax_frag (segment, fragP, stretch);
244
245       /* Long jump on odd halfword boundary?  */
246       if (fragP->fr_subtype == 2 && (address & 3) != 0)
247         {
248           fragP->fr_subtype = 3;
249           growth += 2;
250         }
251     }
252
253   return growth;
254 }
255
256
257 /* Return an initial guess of the length by which a fragment must grow to
258    hold a branch to reach its destination.
259    Also updates fr_type/fr_subtype as necessary.
260
261    Called just before doing relaxation.
262    Any symbol that is now undefined will not become defined.
263    The guess for fr_var is ACTUALLY the growth beyond fr_fix.
264    Whatever we do to grow fr_fix or fr_var contributes to our returned value.
265    Although it may not be explicit in the frag, pretend fr_var starts with a
266    0 value.  */
267
268 int
269 md_estimate_size_before_relax (fragP, segment)
270      fragS * fragP;
271      segT    segment;
272 {
273   /* The only thing we have to handle here are symbols outside of the
274      current segment.  They may be undefined or in a different segment in
275      which case linker scripts may place them anywhere.
276      However, we can't finish the fragment here and emit the reloc as insn
277      alignment requirements may move the insn about.  */
278
279   if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
280     {
281       /* The symbol is undefined in this segment.
282          Change the relaxation subtype to the max allowable and leave
283          all further handling to md_convert_frag.  */
284       fragP->fr_subtype = 2;
285
286       {
287         const CGEN_INSN * insn;
288         int               i;
289
290         /* Update the recorded insn.
291            Fortunately we don't have to look very far.
292            FIXME: Change this to record in the instruction the next higher
293            relaxable insn to use.  */
294         for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
295           {
296             if ((strcmp (CGEN_INSN_MNEMONIC (insn),
297                          CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
298                  == 0)
299                 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
300               break;
301           }
302         if (i == 4)
303           abort ();
304
305         fragP->fr_cgen.insn = insn;
306         return 2;
307       }
308     }
309
310   return md_relax_table[fragP->fr_subtype].rlx_length;
311 }
312
313 /* *fragP has been relaxed to its final size, and now needs to have
314    the bytes inside it modified to conform to the new size.
315
316    Called after relaxation is finished.
317    fragP->fr_type == rs_machine_dependent.
318    fragP->fr_subtype is the subtype of what the address relaxed to.  */
319
320 void
321 md_convert_frag (abfd, sec, fragP)
322   bfd *   abfd ATTRIBUTE_UNUSED;
323   segT    sec  ATTRIBUTE_UNUSED;
324   fragS * fragP ATTRIBUTE_UNUSED;
325 {
326   /* FIXME */
327 }
328
329 \f
330 /* Functions concerning relocs.  */
331
332 /* The location from which a PC relative jump should be calculated,
333    given a PC relative reloc.  */
334
335 long
336 md_pcrel_from_section (fixP, sec)
337      fixS * fixP;
338      segT   sec;
339 {
340   if (fixP->fx_addsy != (symbolS *) NULL
341       && (! S_IS_DEFINED (fixP->fx_addsy)
342           || S_GET_SEGMENT (fixP->fx_addsy) != sec))
343     {
344       /* The symbol is undefined (or is defined but not in this section).
345          Let the linker figure it out.  */
346       return 0;
347     }
348
349   return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;
350 }
351
352
353 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
354    Returns BFD_RELOC_NONE if no reloc type can be found.
355    *FIXP may be modified if desired.  */
356
357 bfd_reloc_code_real_type
358 md_cgen_lookup_reloc (insn, operand, fixP)
359      const CGEN_INSN *    insn ATTRIBUTE_UNUSED;
360      const CGEN_OPERAND * operand;
361      fixS *               fixP;
362 {
363   bfd_reloc_code_real_type type;
364
365   switch (operand->type)
366     {
367     case OPENRISC_OPERAND_ABS_26:
368       fixP->fx_pcrel = 0;
369       type = BFD_RELOC_OPENRISC_ABS_26;
370       goto emit;
371     case OPENRISC_OPERAND_DISP_26:
372       fixP->fx_pcrel = 1;
373       type = BFD_RELOC_OPENRISC_REL_26;
374       goto emit;
375
376     case OPENRISC_OPERAND_HI16:
377       type = BFD_RELOC_HI16;
378       goto emit;
379
380     case OPENRISC_OPERAND_LO16:
381       type = BFD_RELOC_LO16;
382       goto emit;
383
384     emit:
385       return type;
386
387     default : /* avoid -Wall warning */
388       break;
389     }
390
391   return BFD_RELOC_NONE;
392 }
393 \f
394 /* Write a value out to the object file, using the appropriate endianness.  */
395
396 void
397 md_number_to_chars (buf, val, n)
398      char * buf;
399      valueT val;
400      int    n;
401 {
402   number_to_chars_bigendian (buf, val, n);
403 }
404
405 /* Turn a string in input_line_pointer into a floating point constant of type
406    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
407    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
408 */
409
410 /* Equal to MAX_PRECISION in atof-ieee.c */
411 #define MAX_LITTLENUMS 6
412
413 char *
414 md_atof (type, litP, sizeP)
415      char   type;
416      char * litP;
417      int *  sizeP;
418 {
419   int              i;
420   int              prec;
421   LITTLENUM_TYPE   words [MAX_LITTLENUMS];
422   char *           t;
423
424   switch (type)
425     {
426     case 'f':
427     case 'F':
428     case 's':
429     case 'S':
430       prec = 2;
431       break;
432
433     case 'd':
434     case 'D':
435     case 'r':
436     case 'R':
437       prec = 4;
438       break;
439
440    /* FIXME: Some targets allow other format chars for bigger sizes here.  */
441
442     default:
443       * sizeP = 0;
444       return _("Bad call to md_atof()");
445     }
446
447   t = atof_ieee (input_line_pointer, type, words);
448   if (t)
449     input_line_pointer = t;
450   * sizeP = prec * sizeof (LITTLENUM_TYPE);
451
452   for (i = 0; i < prec; i++)
453     {
454       md_number_to_chars (litP, (valueT) words[i],
455                           sizeof (LITTLENUM_TYPE));
456       litP += sizeof (LITTLENUM_TYPE);
457     }
458
459   return 0;
460 }
461
462 bfd_boolean
463 openrisc_fix_adjustable (fixP)
464    fixS * fixP;
465 {
466   /* We need the symbol name for the VTABLE entries */
467   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
468       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
469     return 0;
470
471   return 1;
472 }
473
474
475