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