Home | History | Annotate | Line # | Download | only in cpu
or1k.opc revision 1.1
      1  1.1  matt /* OpenRISC 1000 opcode support.  -*- C -*-
      2  1.1  matt    Copyright 2000-2014 Free Software Foundation, Inc.
      3  1.1  matt 
      4  1.1  matt    Originally ontributed for OR32 by Red Hat Inc;
      5  1.1  matt 
      6  1.1  matt    This file is part of the GNU Binutils.
      7  1.1  matt 
      8  1.1  matt    This program is free software; you can redistribute it and/or modify
      9  1.1  matt    it under the terms of the GNU General Public License as published by
     10  1.1  matt    the Free Software Foundation; either version 3 of the License, or
     11  1.1  matt    (at your option) any later version.
     12  1.1  matt 
     13  1.1  matt    This program is distributed in the hope that it will be useful,
     14  1.1  matt    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  matt    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  matt    GNU General Public License for more details.
     17  1.1  matt 
     18  1.1  matt    You should have received a copy of the GNU General Public License
     19  1.1  matt    along with this program; if not, see <http://www.gnu.org/licenses/>. */
     20  1.1  matt 
     21  1.1  matt /* This file is an addendum to or1k.cpu.  Heavy use of C code isn't
     22  1.1  matt    appropriate in .cpu files, so it resides here.  This especially applies
     23  1.1  matt    to assembly/disassembly where parsing/printing can be quite involved.
     24  1.1  matt    Such things aren't really part of the specification of the cpu, per se,
     25  1.1  matt    so .cpu files provide the general framework and .opc files handle the
     26  1.1  matt    nitty-gritty details as necessary.
     27  1.1  matt 
     28  1.1  matt    Each section is delimited with start and end markers.
     29  1.1  matt 
     30  1.1  matt    <arch>-opc.h additions use: "-- opc.h"
     31  1.1  matt    <arch>-opc.c additions use: "-- opc.c"
     32  1.1  matt    <arch>-asm.c additions use: "-- asm.c"
     33  1.1  matt    <arch>-dis.c additions use: "-- dis.c"
     34  1.1  matt    <arch>-ibd.h additions use: "-- ibd.h"  */
     35  1.1  matt 
     36  1.1  matt /* -- opc.h */
     37  1.1  matt 
     38  1.1  matt #undef  CGEN_DIS_HASH_SIZE
     39  1.1  matt #define CGEN_DIS_HASH_SIZE 256
     40  1.1  matt #undef  CGEN_DIS_HASH
     41  1.1  matt #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
     42  1.1  matt 
     43  1.1  matt /* -- */
     44  1.1  matt 
     45  1.1  matt /* -- opc.c */
     46  1.1  matt /* -- */
     47  1.1  matt 
     48  1.1  matt /* -- asm.c */
     49  1.1  matt 
     50  1.1  matt static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
     51  1.1  matt 
     52  1.1  matt #define CGEN_VERBOSE_ASSEMBLER_ERRORS
     53  1.1  matt 
     54  1.1  matt static const char *
     55  1.1  matt parse_disp26 (CGEN_CPU_DESC cd,
     56  1.1  matt 	      const char ** strp,
     57  1.1  matt 	      int opindex,
     58  1.1  matt 	      int opinfo,
     59  1.1  matt 	      enum cgen_parse_operand_result * resultp,
     60  1.1  matt 	      bfd_vma * valuep)
     61  1.1  matt {
     62  1.1  matt   const char *errmsg = NULL;
     63  1.1  matt   enum cgen_parse_operand_result result_type;
     64  1.1  matt 
     65  1.1  matt   if (strncasecmp (*strp, "plt(", 4) == 0)
     66  1.1  matt     {
     67  1.1  matt       bfd_vma value;
     68  1.1  matt 
     69  1.1  matt       *strp += 4;
     70  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
     71  1.1  matt 				   & result_type, & value);
     72  1.1  matt       if (**strp != ')')
     73  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
     74  1.1  matt       ++*strp;
     75  1.1  matt       if (errmsg == NULL
     76  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
     77  1.1  matt 	value = (value >> 2) & 0xffff;
     78  1.1  matt       *valuep = value;
     79  1.1  matt       return errmsg;
     80  1.1  matt     }
     81  1.1  matt   return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
     82  1.1  matt }
     83  1.1  matt 
     84  1.1  matt static const char *
     85  1.1  matt parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
     86  1.1  matt {
     87  1.1  matt   const char *errmsg;
     88  1.1  matt   enum cgen_parse_operand_result result_type;
     89  1.1  matt   long ret;
     90  1.1  matt 
     91  1.1  matt   if (**strp == '#')
     92  1.1  matt     ++*strp;
     93  1.1  matt 
     94  1.1  matt   if (strncasecmp (*strp, "hi(", 3) == 0)
     95  1.1  matt     {
     96  1.1  matt       bfd_vma value;
     97  1.1  matt 
     98  1.1  matt       *strp += 3;
     99  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
    100  1.1  matt 				   & result_type, & value);
    101  1.1  matt       if (**strp != ')')
    102  1.1  matt 	errmsg = MISSING_CLOSING_PARENTHESIS;
    103  1.1  matt       ++*strp;
    104  1.1  matt 
    105  1.1  matt       ret = value;
    106  1.1  matt 
    107  1.1  matt       if (errmsg == NULL
    108  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    109  1.1  matt 	{
    110  1.1  matt 	  ret >>= 16;
    111  1.1  matt 	  ret &= 0xffff;
    112  1.1  matt 	  ret = (ret ^ 0x8000) - 0x8000;
    113  1.1  matt 	}
    114  1.1  matt     }
    115  1.1  matt   else if (strncasecmp (*strp, "lo(", 3) == 0)
    116  1.1  matt     {
    117  1.1  matt       bfd_vma value;
    118  1.1  matt 
    119  1.1  matt       *strp += 3;
    120  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
    121  1.1  matt 				   & result_type, & value);
    122  1.1  matt       if (**strp != ')')
    123  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    124  1.1  matt       ++*strp;
    125  1.1  matt 
    126  1.1  matt       ret = value;
    127  1.1  matt 
    128  1.1  matt       if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    129  1.1  matt 	{
    130  1.1  matt 	  ret &= 0xffff;
    131  1.1  matt 	  ret = (ret ^ 0x8000) - 0x8000;
    132  1.1  matt 	}
    133  1.1  matt     }
    134  1.1  matt   else if (strncasecmp (*strp, "got(", 4) == 0)
    135  1.1  matt     {
    136  1.1  matt       bfd_vma value;
    137  1.1  matt 
    138  1.1  matt       *strp += 4;
    139  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16,
    140  1.1  matt 				   & result_type, & value);
    141  1.1  matt       if (**strp != ')')
    142  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    143  1.1  matt       ++*strp;
    144  1.1  matt       if (errmsg == NULL
    145  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    146  1.1  matt 	value &= 0xffff;
    147  1.1  matt       *valuep = value;
    148  1.1  matt       return errmsg;
    149  1.1  matt     }
    150  1.1  matt   else if (strncasecmp (*strp, "gotpchi(", 8) == 0)
    151  1.1  matt     {
    152  1.1  matt       bfd_vma value;
    153  1.1  matt 
    154  1.1  matt       *strp += 8;
    155  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    156  1.1  matt 				   BFD_RELOC_OR1K_GOTPC_HI16,
    157  1.1  matt 				   & result_type, & value);
    158  1.1  matt       if (**strp != ')')
    159  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    160  1.1  matt       ++*strp;
    161  1.1  matt       if (errmsg == NULL
    162  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    163  1.1  matt 	value = (value >> 16) & 0xffff;
    164  1.1  matt       *valuep = value;
    165  1.1  matt       return errmsg;
    166  1.1  matt     }
    167  1.1  matt   else if (strncasecmp (*strp, "gotpclo(", 8) == 0)
    168  1.1  matt     {
    169  1.1  matt       bfd_vma value;
    170  1.1  matt 
    171  1.1  matt       *strp += 8;
    172  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    173  1.1  matt 				   BFD_RELOC_OR1K_GOTPC_LO16,
    174  1.1  matt 				   &result_type, &value);
    175  1.1  matt       if (**strp != ')')
    176  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    177  1.1  matt       ++*strp;
    178  1.1  matt       if (errmsg == NULL
    179  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    180  1.1  matt 	value &= 0xffff;
    181  1.1  matt       *valuep = value;
    182  1.1  matt       return errmsg;
    183  1.1  matt     }
    184  1.1  matt   else if (strncasecmp (*strp, "gotoffhi(", 9) == 0)
    185  1.1  matt     {
    186  1.1  matt       bfd_vma value;
    187  1.1  matt 
    188  1.1  matt       *strp += 9;
    189  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    190  1.1  matt 				   BFD_RELOC_OR1K_GOTOFF_HI16,
    191  1.1  matt 				   & result_type, & value);
    192  1.1  matt 
    193  1.1  matt       if (**strp != ')')
    194  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    195  1.1  matt       ++*strp;
    196  1.1  matt       if (errmsg == NULL
    197  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    198  1.1  matt 	value = (value >> 16) & 0xffff;
    199  1.1  matt       *valuep = value;
    200  1.1  matt       return errmsg;
    201  1.1  matt     }
    202  1.1  matt   else if (strncasecmp (*strp, "gotofflo(", 9) == 0)
    203  1.1  matt     {
    204  1.1  matt       bfd_vma value;
    205  1.1  matt 
    206  1.1  matt       *strp += 9;
    207  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    208  1.1  matt 				   BFD_RELOC_OR1K_GOTOFF_LO16,
    209  1.1  matt 				   &result_type, &value);
    210  1.1  matt       if (**strp != ')')
    211  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    212  1.1  matt       ++*strp;
    213  1.1  matt       if (errmsg == NULL
    214  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    215  1.1  matt 	value &= 0xffff;
    216  1.1  matt       *valuep = value;
    217  1.1  matt       return errmsg;
    218  1.1  matt     }
    219  1.1  matt   else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0)
    220  1.1  matt     {
    221  1.1  matt       bfd_vma value;
    222  1.1  matt 
    223  1.1  matt       *strp += 8;
    224  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    225  1.1  matt 				   BFD_RELOC_OR1K_TLS_GD_HI16,
    226  1.1  matt 				   & result_type, & value);
    227  1.1  matt 
    228  1.1  matt       if (**strp != ')')
    229  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    230  1.1  matt       ++*strp;
    231  1.1  matt       if (errmsg == NULL
    232  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    233  1.1  matt 	value = (value >> 16) & 0xffff;
    234  1.1  matt       *valuep = value;
    235  1.1  matt       return errmsg;
    236  1.1  matt     }
    237  1.1  matt   else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0)
    238  1.1  matt     {
    239  1.1  matt       bfd_vma value;
    240  1.1  matt 
    241  1.1  matt       *strp += 8;
    242  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    243  1.1  matt 				   BFD_RELOC_OR1K_TLS_GD_LO16,
    244  1.1  matt 				   &result_type, &value);
    245  1.1  matt       if (**strp != ')')
    246  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    247  1.1  matt       ++*strp;
    248  1.1  matt       if (errmsg == NULL
    249  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    250  1.1  matt 	value &= 0xffff;
    251  1.1  matt       *valuep = value;
    252  1.1  matt       return errmsg;
    253  1.1  matt     }
    254  1.1  matt   else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0)
    255  1.1  matt     {
    256  1.1  matt       bfd_vma value;
    257  1.1  matt 
    258  1.1  matt       *strp += 9;
    259  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    260  1.1  matt 				   BFD_RELOC_OR1K_TLS_LDM_HI16,
    261  1.1  matt 				   & result_type, & value);
    262  1.1  matt 
    263  1.1  matt       if (**strp != ')')
    264  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    265  1.1  matt       ++*strp;
    266  1.1  matt       if (errmsg == NULL
    267  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    268  1.1  matt 	value = (value >> 16) & 0xffff;
    269  1.1  matt       *valuep = value;
    270  1.1  matt       return errmsg;
    271  1.1  matt     }
    272  1.1  matt   else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0)
    273  1.1  matt     {
    274  1.1  matt       bfd_vma value;
    275  1.1  matt 
    276  1.1  matt       *strp += 9;
    277  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    278  1.1  matt 				   BFD_RELOC_OR1K_TLS_LDM_LO16,
    279  1.1  matt 				   &result_type, &value);
    280  1.1  matt       if (**strp != ')')
    281  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    282  1.1  matt       ++*strp;
    283  1.1  matt       if (errmsg == NULL
    284  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    285  1.1  matt 	value &= 0xffff;
    286  1.1  matt       *valuep = value;
    287  1.1  matt       return errmsg;
    288  1.1  matt     }
    289  1.1  matt   else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0)
    290  1.1  matt     {
    291  1.1  matt       bfd_vma value;
    292  1.1  matt 
    293  1.1  matt       *strp += 9;
    294  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    295  1.1  matt 				   BFD_RELOC_OR1K_TLS_LDO_HI16,
    296  1.1  matt 				   & result_type, & value);
    297  1.1  matt 
    298  1.1  matt       if (**strp != ')')
    299  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    300  1.1  matt       ++*strp;
    301  1.1  matt       if (errmsg == NULL
    302  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    303  1.1  matt 	value = (value >> 16) & 0xffff;
    304  1.1  matt       *valuep = value;
    305  1.1  matt       return errmsg;
    306  1.1  matt     }
    307  1.1  matt   else if (strncasecmp (*strp, "dtpofflo(", 9) == 0)
    308  1.1  matt     {
    309  1.1  matt       bfd_vma value;
    310  1.1  matt 
    311  1.1  matt       *strp += 9;
    312  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    313  1.1  matt 				   BFD_RELOC_OR1K_TLS_LDO_LO16,
    314  1.1  matt 				   &result_type, &value);
    315  1.1  matt       if (**strp != ')')
    316  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    317  1.1  matt       ++*strp;
    318  1.1  matt       if (errmsg == NULL
    319  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    320  1.1  matt 	value &= 0xffff;
    321  1.1  matt       *valuep = value;
    322  1.1  matt       return errmsg;
    323  1.1  matt     }
    324  1.1  matt   else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0)
    325  1.1  matt     {
    326  1.1  matt       bfd_vma value;
    327  1.1  matt 
    328  1.1  matt       *strp += 11;
    329  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    330  1.1  matt 				   BFD_RELOC_OR1K_TLS_IE_HI16,
    331  1.1  matt 				   & result_type, & value);
    332  1.1  matt 
    333  1.1  matt       if (**strp != ')')
    334  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    335  1.1  matt       ++*strp;
    336  1.1  matt       if (errmsg == NULL
    337  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    338  1.1  matt 	value = (value >> 16) & 0xffff;
    339  1.1  matt       *valuep = value;
    340  1.1  matt       return errmsg;
    341  1.1  matt     }
    342  1.1  matt   else if (strncasecmp (*strp, "gottpofflo(", 11) == 0)
    343  1.1  matt     {
    344  1.1  matt       bfd_vma value;
    345  1.1  matt 
    346  1.1  matt       *strp += 11;
    347  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    348  1.1  matt 				   BFD_RELOC_OR1K_TLS_IE_LO16,
    349  1.1  matt 				   &result_type, &value);
    350  1.1  matt       if (**strp != ')')
    351  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    352  1.1  matt       ++*strp;
    353  1.1  matt       if (errmsg == NULL
    354  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    355  1.1  matt 	value &= 0xffff;
    356  1.1  matt       *valuep = value;
    357  1.1  matt       return errmsg;
    358  1.1  matt     }
    359  1.1  matt   else if (strncasecmp (*strp, "tpoffhi(", 8) == 0)
    360  1.1  matt     {
    361  1.1  matt       bfd_vma value;
    362  1.1  matt 
    363  1.1  matt       *strp += 8;
    364  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    365  1.1  matt 				   BFD_RELOC_OR1K_TLS_LE_HI16,
    366  1.1  matt 				   & result_type, & value);
    367  1.1  matt 
    368  1.1  matt       if (**strp != ')')
    369  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    370  1.1  matt       ++*strp;
    371  1.1  matt       if (errmsg == NULL
    372  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    373  1.1  matt 	value = (value >> 16) & 0xffff;
    374  1.1  matt       *valuep = value;
    375  1.1  matt       return errmsg;
    376  1.1  matt     }
    377  1.1  matt   else if (strncasecmp (*strp, "tpofflo(", 8) == 0)
    378  1.1  matt     {
    379  1.1  matt       bfd_vma value;
    380  1.1  matt 
    381  1.1  matt       *strp += 8;
    382  1.1  matt       errmsg = cgen_parse_address (cd, strp, opindex,
    383  1.1  matt 				   BFD_RELOC_OR1K_TLS_LE_LO16,
    384  1.1  matt 				   &result_type, &value);
    385  1.1  matt       if (**strp != ')')
    386  1.1  matt 	return MISSING_CLOSING_PARENTHESIS;
    387  1.1  matt       ++*strp;
    388  1.1  matt       if (errmsg == NULL
    389  1.1  matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    390  1.1  matt 	value &= 0xffff;
    391  1.1  matt       *valuep = value;
    392  1.1  matt       return errmsg;
    393  1.1  matt     }
    394  1.1  matt   else
    395  1.1  matt     {
    396  1.1  matt       long value;
    397  1.1  matt       errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
    398  1.1  matt       ret = value;
    399  1.1  matt     }
    400  1.1  matt 
    401  1.1  matt   if (errmsg == NULL)
    402  1.1  matt     *valuep = ret;
    403  1.1  matt 
    404  1.1  matt   return errmsg;
    405  1.1  matt }
    406  1.1  matt 
    407  1.1  matt static const char *
    408  1.1  matt parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep)
    409  1.1  matt {
    410  1.1  matt   const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep);
    411  1.1  matt 
    412  1.1  matt   if (errmsg == NULL)
    413  1.1  matt     *valuep &= 0xffff;
    414  1.1  matt   return errmsg;
    415  1.1  matt }
    416  1.1  matt 
    417  1.1  matt /* -- */
    418  1.1  matt 
    419  1.1  matt /* -- ibd.h */
    420  1.1  matt 
    421  1.1  matt /* -- */
    422