Home | History | Annotate | Download | only in config
      1 /* tc-or1k.c -- Assembler for the OpenRISC family.
      2    Copyright 2001-2014 Free Software Foundation.
      3    Contributed for OR32 by Johan Rydberg, jrydberg (at) 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, 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 /* Equal to MAX_PRECISION in atof-ieee.c.  */
    279 #define MAX_LITTLENUMS 6
    280 
    281 char *
    282 md_atof (int type, char * litP, int *  sizeP)
    283 {
    284   return ieee_md_atof (type, litP, sizeP, TRUE);
    285 }
    286 
    287 bfd_boolean
    288 or1k_fix_adjustable (fixS * fixP)
    289 {
    290   /* We need the symbol name for the VTABLE entries.  */
    291   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
    292       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    293     return FALSE;
    294 
    295   return TRUE;
    296 }
    297 
    298 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
    299 
    300 arelent *
    301 tc_gen_reloc (asection *sec, fixS *fx)
    302 {
    303   bfd_reloc_code_real_type code = fx->fx_r_type;
    304 
    305   if (fx->fx_addsy != NULL
    306       && strcmp (S_GET_NAME (fx->fx_addsy), GOT_NAME) == 0
    307       && (code == BFD_RELOC_OR1K_GOTPC_HI16
    308           || code == BFD_RELOC_OR1K_GOTPC_LO16))
    309     {
    310       arelent * reloc;
    311 
    312       reloc = xmalloc (sizeof (* reloc));
    313       reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
    314       *reloc->sym_ptr_ptr = symbol_get_bfdsym (fx->fx_addsy);
    315       reloc->address = fx->fx_frag->fr_address + fx->fx_where;
    316       reloc->howto = bfd_reloc_type_lookup (stdoutput, fx->fx_r_type);
    317       reloc->addend = fx->fx_offset;
    318       return reloc;
    319     }
    320 
    321   return gas_cgen_tc_gen_reloc (sec, fx);
    322 }
    323 
    324 void
    325 or1k_apply_fix (struct fix *f, valueT *t, segT s)
    326 {
    327   gas_cgen_md_apply_fix (f, t, s);
    328 
    329   switch (f->fx_r_type)
    330     {
    331     case BFD_RELOC_OR1K_TLS_GD_HI16:
    332     case BFD_RELOC_OR1K_TLS_GD_LO16:
    333     case BFD_RELOC_OR1K_TLS_LDM_HI16:
    334     case BFD_RELOC_OR1K_TLS_LDM_LO16:
    335     case BFD_RELOC_OR1K_TLS_LDO_HI16:
    336     case BFD_RELOC_OR1K_TLS_LDO_LO16:
    337     case BFD_RELOC_OR1K_TLS_IE_HI16:
    338     case BFD_RELOC_OR1K_TLS_IE_LO16:
    339     case BFD_RELOC_OR1K_TLS_LE_HI16:
    340     case BFD_RELOC_OR1K_TLS_LE_LO16:
    341       S_SET_THREAD_LOCAL (f->fx_addsy);
    342       break;
    343     default:
    344       break;
    345     }
    346 }
    347 
    348 void
    349 or1k_elf_final_processing (void)
    350 {
    351   if (nodelay)
    352     elf_elfheader (stdoutput)->e_flags |= EF_OR1K_NODELAY;
    353 }
    354 
    355 /* Standard calling conventions leave the CFA at SP on entry.  */
    356 
    357 void
    358 or1k_cfi_frame_initial_instructions (void)
    359 {
    360     cfi_add_CFA_def_cfa_register (1);
    361 }
    362 
    363