Home | History | Annotate | Download | only in cpu
      1 /* Lattice Mico32 opcode support.  -*- C -*-
      2    Copyright 2008, 2009  Free Software Foundation, Inc.
      3    Contributed by Jon Beniston <jon (at) beniston.com>
      4 
      5    This file is part of the GNU Binutils.
      6 
      7    This program 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 of the License, or
     10    (at your option) any later version.
     11 
     12    This program 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, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 /* -- opc.h */
     23 
     24 /* Allows reason codes to be output when assembler errors occur.  */
     25 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
     26 
     27 #define CGEN_DIS_HASH_SIZE 64
     28 #define CGEN_DIS_HASH(buf,value) ((value >> 26) & 0x3f)
     29 
     30 /* -- asm.c */
     31 
     32 /* Handle signed/unsigned literal.  */
     33 
     34 static const char *
     35 parse_imm (CGEN_CPU_DESC cd,
     36 	   const char **strp,
     37 	   int opindex,
     38 	   unsigned long *valuep)
     39 {
     40   const char *errmsg;
     41   signed long value;
     42 
     43   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
     44   if (errmsg == NULL)
     45     {
     46       unsigned long x = value & 0xFFFF0000;
     47       if (x != 0 && x != 0xFFFF0000)
     48         errmsg = _("immediate value out of range");
     49       else
     50         *valuep = (value & 0xFFFF);
     51     }
     52   return errmsg;
     53 }
     54 
     55 /* Handle hi() */
     56 
     57 static const char *
     58 parse_hi16 (CGEN_CPU_DESC cd,
     59 	    const char **strp,
     60 	    int opindex,
     61 	    unsigned long *valuep)
     62 {
     63   if (strncasecmp (*strp, "hi(", 3) == 0)
     64     {
     65       enum cgen_parse_operand_result result_type;
     66       bfd_vma value;
     67       const char *errmsg;
     68 
     69       *strp += 3;
     70       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
     71                                    &result_type, &value);
     72       if (**strp != ')')
     73         return _("missing `)'");
     74 
     75       ++*strp;
     76       if (errmsg == NULL
     77           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
     78         value = (value >> 16) & 0xffff;
     79       *valuep = value;
     80 
     81       return errmsg;
     82     }
     83 
     84   return parse_imm (cd, strp, opindex, valuep);
     85 }
     86 
     87 /* Handle lo() */
     88 
     89 static const char *
     90 parse_lo16 (CGEN_CPU_DESC cd,
     91 	    const char **strp,
     92 	    int opindex,
     93 	    unsigned long *valuep)
     94 {
     95   if (strncasecmp (*strp, "lo(", 3) == 0)
     96     {
     97       const char *errmsg;
     98       enum cgen_parse_operand_result result_type;
     99       bfd_vma value;
    100 
    101       *strp += 3;
    102       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
    103                                    &result_type, &value);
    104       if (**strp != ')')
    105         return _("missing `)'");
    106       ++*strp;
    107       if (errmsg == NULL
    108           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    109         value &= 0xffff;
    110       *valuep = value;
    111       return errmsg;
    112     }
    113 
    114   return parse_imm (cd, strp, opindex, valuep);
    115 }
    116 
    117 /* Handle gp() */
    118 
    119 static const char *
    120 parse_gp16 (CGEN_CPU_DESC cd,
    121 	    const char **strp,
    122 	    int opindex,
    123 	    long *valuep)
    124 {
    125   if (strncasecmp (*strp, "gp(", 3) == 0)
    126     {
    127       const char *errmsg;
    128       enum cgen_parse_operand_result result_type;
    129       bfd_vma value;
    130 
    131       *strp += 3;
    132       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16,
    133                                    & result_type, & value);
    134       if (**strp != ')')
    135         return _("missing `)'");
    136       ++*strp;
    137       if (errmsg == NULL
    138           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    139         value &= 0xffff;
    140       *valuep = value;
    141       return errmsg;
    142     }
    143 
    144   return _("expecting gp relative address: gp(symbol)");
    145 }
    146 
    147 /* Handle got() */
    148 
    149 static const char *
    150 parse_got16 (CGEN_CPU_DESC cd,
    151 	     const char **strp,
    152 	     int opindex,
    153 	     long *valuep)
    154 {
    155   if (strncasecmp (*strp, "got(", 4) == 0)
    156     {
    157       const char *errmsg;
    158       enum cgen_parse_operand_result result_type;
    159       bfd_vma value;
    160 
    161       *strp += 4;
    162       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT,
    163                                    & result_type, & value);
    164       if (**strp != ')')
    165         return _("missing `)'");
    166       ++*strp;
    167       if (errmsg == NULL
    168           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    169         value &= 0xffff;
    170       *valuep = value;
    171       return errmsg;
    172     }
    173 
    174   return _("expecting got relative address: got(symbol)");
    175 }
    176 
    177 /* Handle gotoffhi16() */
    178 
    179 static const char *
    180 parse_gotoff_hi16 (CGEN_CPU_DESC cd,
    181 		   const char **strp,
    182 		   int opindex,
    183 		   long *valuep)
    184 {
    185   if (strncasecmp (*strp, "gotoffhi16(", 11) == 0)
    186     {
    187       const char *errmsg;
    188       enum cgen_parse_operand_result result_type;
    189       bfd_vma value;
    190 
    191       *strp += 11;
    192       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16,
    193                                    & result_type, & value);
    194       if (**strp != ')')
    195         return _("missing `)'");
    196       ++*strp;
    197       if (errmsg == NULL
    198           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    199         value &= 0xffff;
    200       *valuep = value;
    201       return errmsg;
    202     }
    203 
    204   return _("expecting got relative address: gotoffhi16(symbol)");
    205 }
    206 
    207 /* Handle gotofflo16() */
    208 
    209 static const char *
    210 parse_gotoff_lo16 (CGEN_CPU_DESC cd,
    211 		   const char **strp,
    212 		   int opindex,
    213 		   long *valuep)
    214 {
    215   if (strncasecmp (*strp, "gotofflo16(", 11) == 0)
    216     {
    217       const char *errmsg;
    218       enum cgen_parse_operand_result result_type;
    219       bfd_vma value;
    220 
    221       *strp += 11;
    222       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16,
    223                                    &result_type, &value);
    224       if (**strp != ')')
    225         return _("missing `)'");
    226       ++*strp;
    227       if (errmsg == NULL
    228           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    229         value &= 0xffff;
    230       *valuep = value;
    231       return errmsg;
    232     }
    233 
    234   return _("expecting got relative address: gotofflo16(symbol)");
    235 }
    236