This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / gas / config / tc-openrisc.c
1 /* tc-openrisc.c -- Assembler for the OpenRISC family.
2    Copyright (C) 2001, 2002 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
87 ignore_pseudo (val)
88      int val ATTRIBUTE_UNUSED;
89 {
90   discard_rest_of_line ();
91 }
92
93 const char openrisc_comment_chars [] = ";#";
94
95 /* The target specific pseudo-ops which we support.  */
96 const pseudo_typeS md_pseudo_table[] =
97 {
98   { "word",     cons,           4 },
99   { "proc",     ignore_pseudo,  0 },
100   { "endproc",  ignore_pseudo,  0 },
101   { NULL,       NULL,           0 }
102 };
103
104
105 \f
106 void
107 md_begin ()
108 {
109   /* Initialize the `cgen' interface.  */
110
111   /* Set the machine number and endian.  */
112   gas_cgen_cpu_desc = openrisc_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
113                                               CGEN_CPU_OPEN_ENDIAN,
114                                               CGEN_ENDIAN_BIG,
115                                               CGEN_CPU_OPEN_END);
116   openrisc_cgen_init_asm (gas_cgen_cpu_desc);
117
118   /* This is a callback from cgen to gas to parse operands.  */
119   cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
120 }
121
122 void
123 md_assemble (str)
124      char * str;
125 {
126   static int last_insn_had_delay_slot = 0;
127   openrisc_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 = openrisc_cgen_assemble_insn
134     (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
135
136   if (!insn.insn)
137     {
138       as_bad (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 #if 0 /* Currently disabled  */
147   /* Warn about invalid insns in delay slots.  */
148   if (last_insn_had_delay_slot
149       && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_NOT_IN_DELAY_SLOT))
150     as_warn (_("Instruction %s not allowed in a delay slot."),
151              CGEN_INSN_NAME (insn.insn));
152 #endif
153
154   last_insn_had_delay_slot
155     = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
156 }
157
158
159 /* The syntax in the manual says constants begin with '#'.
160    We just ignore it.  */
161
162 void
163 md_operand (expressionP)
164      expressionS * expressionP;
165 {
166   if (* input_line_pointer == '#')
167     {
168       input_line_pointer ++;
169       expression (expressionP);
170     }
171 }
172
173 valueT
174 md_section_align (segment, size)
175      segT   segment;
176      valueT size;
177 {
178   int align = bfd_get_section_alignment (stdoutput, segment);
179   return ((size + (1 << align) - 1) & (-1 << align));
180 }
181
182 symbolS *
183 md_undefined_symbol (name)
184      char * name ATTRIBUTE_UNUSED;
185 {
186   return 0;
187 }
188
189 \f
190 /* Interface to relax_segment.  */
191
192 /* FIXME: Look through this.  */
193
194 const relax_typeS md_relax_table[] =
195 {
196 /* The fields are:
197    1) most positive reach of this state,
198    2) most negative reach of this state,
199    3) how many bytes this mode will add to the size of the current frag
200    4) which index into the table to try if we can't fit into this one.  */
201
202   /* The first entry must be unused because an `rlx_more' value of zero ends
203      each list.  */
204   {1, 1, 0, 0},
205
206   /* The displacement used by GAS is from the end of the 2 byte insn,
207      so we subtract 2 from the following.  */
208   /* 16 bit insn, 8 bit disp -> 10 bit range.
209      This doesn't handle a branch in the right slot at the border:
210      the "& -4" isn't taken into account.  It's not important enough to
211      complicate things over it, so we subtract an extra 2 (or + 2 in -ve
212      case).  */
213   {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
214   /* 32 bit insn, 24 bit disp -> 26 bit range.  */
215   {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
216   /* Same thing, but with leading nop for alignment.  */
217   {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
218 };
219
220 long
221 openrisc_relax_frag (segment, fragP, stretch)
222      segT    segment;
223      fragS * fragP;
224      long    stretch;
225 {
226   /* Address of branch insn.  */
227   long address = fragP->fr_address + fragP->fr_fix - 2;
228   long growth = 0;
229
230   /* Keep 32 bit insns aligned on 32 bit boundaries.  */
231   if (fragP->fr_subtype == 2)
232     {
233       if ((address & 3) != 0)
234         {
235           fragP->fr_subtype = 3;
236           growth = 2;
237         }
238     }
239   else if (fragP->fr_subtype == 3)
240     {
241       if ((address & 3) == 0)
242         {
243           fragP->fr_subtype = 2;
244           growth = -2;
245         }
246     }
247   else
248     {
249       growth = relax_frag (segment, fragP, stretch);
250
251       /* Long jump on odd halfword boundary?  */
252       if (fragP->fr_subtype == 2 && (address & 3) != 0)
253         {
254           fragP->fr_subtype = 3;
255           growth += 2;
256         }
257     }
258
259   return growth;
260 }
261
262
263 /* Return an initial guess of the length by which a fragment must grow to
264    hold a branch to reach its destination.
265    Also updates fr_type/fr_subtype as necessary.
266
267    Called just before doing relaxation.
268    Any symbol that is now undefined will not become defined.
269    The guess for fr_var is ACTUALLY the growth beyond fr_fix.
270    Whatever we do to grow fr_fix or fr_var contributes to our returned value.
271    Although it may not be explicit in the frag, pretend fr_var starts with a
272    0 value.  */
273
274 int
275 md_estimate_size_before_relax (fragP, segment)
276      fragS * fragP;
277      segT    segment;
278 {
279   /* The only thing we have to handle here are symbols outside of the
280      current segment.  They may be undefined or in a different segment in
281      which case linker scripts may place them anywhere.
282      However, we can't finish the fragment here and emit the reloc as insn
283      alignment requirements may move the insn about.  */
284
285   if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
286     {
287       /* The symbol is undefined in this segment.
288          Change the relaxation subtype to the max allowable and leave
289          all further handling to md_convert_frag.  */
290       fragP->fr_subtype = 2;
291
292       {
293         const CGEN_INSN * insn;
294         int               i;
295
296         /* Update the recorded insn.
297            Fortunately we don't have to look very far.
298            FIXME: Change this to record in the instruction the next higher
299            relaxable insn to use.  */
300         for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
301           {
302             if ((strcmp (CGEN_INSN_MNEMONIC (insn),
303                          CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
304                  == 0)
305                 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX))
306               break;
307           }
308         if (i == 4)
309           abort ();
310
311         fragP->fr_cgen.insn = insn;
312         return 2;
313       }
314     }
315
316   return md_relax_table[fragP->fr_subtype].rlx_length;
317 }
318
319 /* *fragP has been relaxed to its final size, and now needs to have
320    the bytes inside it modified to conform to the new size.
321
322    Called after relaxation is finished.
323    fragP->fr_type == rs_machine_dependent.
324    fragP->fr_subtype is the subtype of what the address relaxed to.  */
325
326 void
327 md_convert_frag (abfd, sec, fragP)
328   bfd *   abfd ATTRIBUTE_UNUSED;
329   segT    sec  ATTRIBUTE_UNUSED;
330   fragS * fragP ATTRIBUTE_UNUSED;
331 {
332   /* FIXME */
333 }
334
335 \f
336 /* Functions concerning relocs.  */
337
338 /* The location from which a PC relative jump should be calculated,
339    given a PC relative reloc.  */
340
341 long
342 md_pcrel_from_section (fixP, sec)
343      fixS * fixP;
344      segT   sec;
345 {
346   if (fixP->fx_addsy != (symbolS *) NULL
347       && (! S_IS_DEFINED (fixP->fx_addsy)
348           || S_GET_SEGMENT (fixP->fx_addsy) != sec))
349     {
350       /* The symbol is undefined (or is defined but not in this section).
351          Let the linker figure it out.  */
352       return 0;
353     }
354
355   return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;
356 }
357
358
359 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
360    Returns BFD_RELOC_NONE if no reloc type can be found.
361    *FIXP may be modified if desired.  */
362
363 bfd_reloc_code_real_type
364 md_cgen_lookup_reloc (insn, operand, fixP)
365      const CGEN_INSN *    insn ATTRIBUTE_UNUSED;
366      const CGEN_OPERAND * operand;
367      fixS *               fixP;
368 {
369   bfd_reloc_code_real_type type;
370
371   switch (operand->type)
372     {
373     case OPENRISC_OPERAND_ABS_26:
374       fixP->fx_pcrel = 0;
375       type = BFD_RELOC_OPENRISC_ABS_26;
376       goto emit;
377     case OPENRISC_OPERAND_DISP_26:
378       fixP->fx_pcrel = 1;
379       type = BFD_RELOC_OPENRISC_REL_26;
380       goto emit;
381
382     case OPENRISC_OPERAND_HI16:
383       type = BFD_RELOC_HI16;
384       goto emit;
385
386     case OPENRISC_OPERAND_LO16:
387       type = BFD_RELOC_LO16;
388       goto emit;
389
390     emit:
391       return type;
392
393     default : /* avoid -Wall warning */
394       break;
395     }
396
397   return BFD_RELOC_NONE;
398 }
399
400 /* See whether we need to force a relocation into the output file.
401    This is used to force out switch and PC relative relocations when
402    relaxing.  */
403
404 int
405 openrisc_force_relocation (fix)
406      fixS * fix ATTRIBUTE_UNUSED;
407 {
408   if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
409       || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
410     return 1;
411
412   return 0;
413 }
414
415
416 \f
417 /* Write a value out to the object file, using the appropriate endianness.  */
418
419 void
420 md_number_to_chars (buf, val, n)
421      char * buf;
422      valueT val;
423      int    n;
424 {
425   number_to_chars_bigendian (buf, val, n);
426 }
427
428 /* Turn a string in input_line_pointer into a floating point constant of type
429    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
430    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
431 */
432
433 /* Equal to MAX_PRECISION in atof-ieee.c */
434 #define MAX_LITTLENUMS 6
435
436 char *
437 md_atof (type, litP, sizeP)
438      char   type;
439      char * litP;
440      int *  sizeP;
441 {
442   int              i;
443   int              prec;
444   LITTLENUM_TYPE   words [MAX_LITTLENUMS];
445   char *           t;
446   char *           atof_ieee ();
447
448   switch (type)
449     {
450     case 'f':
451     case 'F':
452     case 's':
453     case 'S':
454       prec = 2;
455       break;
456
457     case 'd':
458     case 'D':
459     case 'r':
460     case 'R':
461       prec = 4;
462       break;
463
464    /* FIXME: Some targets allow other format chars for bigger sizes here.  */
465
466     default:
467       * sizeP = 0;
468       return _("Bad call to md_atof()");
469     }
470
471   t = atof_ieee (input_line_pointer, type, words);
472   if (t)
473     input_line_pointer = t;
474   * sizeP = prec * sizeof (LITTLENUM_TYPE);
475
476   for (i = 0; i < prec; i++)
477     {
478       md_number_to_chars (litP, (valueT) words[i],
479                           sizeof (LITTLENUM_TYPE));
480       litP += sizeof (LITTLENUM_TYPE);
481     }
482
483   return 0;
484 }
485
486 boolean
487 openrisc_fix_adjustable (fixP)
488    fixS * fixP;
489 {
490   if (fixP->fx_addsy == NULL)
491     return 1;
492
493   /* We need the symbol name for the VTABLE entries */
494   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
495       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
496     return 0;
497
498   return 1;
499 }
500
501
502