1 /* OpenRISC 1000 opcode support. -*- C -*-
2 Copyright 2000-2014 Free Software Foundation, Inc.
4 Originally ontributed for OR32 by Red Hat Inc;
6 This file is part of the GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>. */
21 /* This file is an addendum to or1k.cpu. Heavy use of C code isn't
22 appropriate in .cpu files, so it resides here. This especially applies
23 to assembly/disassembly where parsing/printing can be quite involved.
24 Such things aren't really part of the specification of the cpu, per se,
25 so .cpu files provide the general framework and .opc files handle the
26 nitty-gritty details as necessary.
28 Each section is delimited with start and end markers.
30 <arch>-opc.h additions use: "-- opc.h"
31 <arch>-opc.c additions use: "-- opc.c"
32 <arch>-asm.c additions use: "-- asm.c"
33 <arch>-dis.c additions use: "-- dis.c"
34 <arch>-ibd.h additions use: "-- ibd.h" */
38 #undef CGEN_DIS_HASH_SIZE
39 #define CGEN_DIS_HASH_SIZE 256
41 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
50 static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
51 static const char * INVALID_STORE_RELOC = N_("relocation invalid for store");
52 static const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid");
54 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
57 parse_disp26 (CGEN_CPU_DESC cd,
61 enum cgen_parse_operand_result * resultp,
64 const char *errmsg = NULL;
65 enum cgen_parse_operand_result result_type;
67 if (strncasecmp (*strp, "plt(", 4) == 0)
72 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
73 & result_type, & value);
75 return MISSING_CLOSING_PARENTHESIS;
78 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
79 value = (value >> 2) & 0xffff;
83 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
94 RTYPE_GOTPC = (2 << 2),
95 RTYPE_GOTOFF = (3 << 2),
96 RTYPE_TLSGD = (4 << 2),
97 RTYPE_TLSLDM = (5 << 2),
98 RTYPE_DTPOFF = (6 << 2),
99 RTYPE_GOTTPOFF = (7 << 2),
100 RTYPE_TPOFF = (8 << 2),
103 static const bfd_reloc_code_real_type or1k_imm16_relocs[][4] = {
107 BFD_RELOC_OR1K_SLO16 },
108 { BFD_RELOC_OR1K_GOT16,
112 { BFD_RELOC_OR1K_GOTPC_LO16,
113 BFD_RELOC_OR1K_GOTPC_HI16,
116 { BFD_RELOC_LO16_GOTOFF,
117 BFD_RELOC_HI16_GOTOFF,
118 BFD_RELOC_HI16_S_GOTOFF,
119 BFD_RELOC_OR1K_GOTOFF_SLO16 },
120 { BFD_RELOC_OR1K_TLS_GD_LO16,
121 BFD_RELOC_OR1K_TLS_GD_HI16,
124 { BFD_RELOC_OR1K_TLS_LDM_LO16,
125 BFD_RELOC_OR1K_TLS_LDM_HI16,
128 { BFD_RELOC_OR1K_TLS_LDO_LO16,
129 BFD_RELOC_OR1K_TLS_LDO_HI16,
132 { BFD_RELOC_OR1K_TLS_IE_LO16,
133 BFD_RELOC_OR1K_TLS_IE_HI16,
134 BFD_RELOC_OR1K_TLS_IE_AHI16,
136 { BFD_RELOC_OR1K_TLS_LE_LO16,
137 BFD_RELOC_OR1K_TLS_LE_HI16,
138 BFD_RELOC_OR1K_TLS_LE_AHI16,
139 BFD_RELOC_OR1K_TLS_LE_SLO16 }
143 parse_reloc (const char **strp)
145 const char *str = *strp;
148 if (strncasecmp (str, "got(", 4) == 0)
151 return RTYPE_GOT | RTYPE_LO;
154 if (strncasecmp (str, "gotpc", 5) == 0)
159 else if (strncasecmp (str, "gotoff", 6) == 0)
164 else if (strncasecmp (str, "tlsgd", 5) == 0)
169 else if (strncasecmp (str, "tlsldm", 6) == 0)
174 else if (strncasecmp (str, "dtpoff", 6) == 0)
179 else if (strncasecmp (str, "gottpoff", 8) == 0)
182 ret = RTYPE_GOTTPOFF;
184 else if (strncasecmp (str, "tpoff", 5) == 0)
190 if (strncasecmp (str, "hi(", 3) == 0)
195 else if (strncasecmp (str, "lo(", 3) == 0)
200 else if (strncasecmp (str, "ha(", 3) == 0)
213 parse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
214 long *valuep, int splitp)
217 enum cgen_parse_operand_result result_type;
218 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
225 reloc_type = parse_reloc (strp);
230 if ((reloc_type & 3) == RTYPE_LO && reloc_type != RTYPE_GOT)
231 reloc_type |= RTYPE_SLO;
233 return INVALID_STORE_RELOC;
235 reloc = or1k_imm16_relocs[reloc_type >> 2][reloc_type & 3];
238 if (reloc != BFD_RELOC_UNUSED)
242 errmsg = cgen_parse_address (cd, strp, opindex, reloc,
243 &result_type, &value);
245 errmsg = MISSING_CLOSING_PARENTHESIS;
250 if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
251 switch (reloc_type & 3)
262 ret = (ret ^ 0x8000) - 0x8000;
265 errmsg = INVALID_RELOC_TYPE;
271 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
282 parse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
284 return parse_imm16(cd, strp, opindex, (long *) valuep, 0);
288 parse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
291 return parse_imm16(cd, strp, opindex, (long *) valuep, 1);
295 parse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
296 unsigned long *valuep)
298 const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0);
305 parse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
306 unsigned long *valuep)
308 const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1);