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,
60 int opinfo ATTRIBUTE_UNUSED,
61 enum cgen_parse_operand_result * resultp,
64 const char *str = *strp;
65 const char *errmsg = NULL;
66 bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_REL_26;
68 if (strncasecmp (str, "plta(", 5) == 0)
71 reloc = BFD_RELOC_OR1K_PLTA26;
73 else if (strncasecmp (str, "plt(", 4) == 0)
76 reloc = BFD_RELOC_OR1K_PLT26;
79 errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep);
81 if (reloc != BFD_RELOC_OR1K_REL_26)
84 errmsg = MISSING_CLOSING_PARENTHESIS;
93 parse_disp21 (CGEN_CPU_DESC cd,
96 int opinfo ATTRIBUTE_UNUSED,
97 enum cgen_parse_operand_result * resultp,
100 const char *str = *strp;
101 const char *errmsg = NULL;
102 bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_PCREL_PG21;
104 if (strncasecmp (str, "got(", 4) == 0)
107 reloc = BFD_RELOC_OR1K_GOT_PG21;
109 else if (strncasecmp (str, "tlsgd(", 6) == 0)
112 reloc = BFD_RELOC_OR1K_TLS_GD_PG21;
114 else if (strncasecmp (str, "tlsldm(", 7) == 0)
117 reloc = BFD_RELOC_OR1K_TLS_LDM_PG21;
119 else if (strncasecmp (str, "gottp(", 6) == 0)
122 reloc = BFD_RELOC_OR1K_TLS_IE_PG21;
125 errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep);
127 if (reloc != BFD_RELOC_OR1K_PCREL_PG21)
130 errmsg = MISSING_CLOSING_PARENTHESIS;
161 #define RCLASS_SHIFT 3
164 static const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = {
166 BFD_RELOC_OR1K_SLO16,
168 BFD_RELOC_OR1K_SLO13,
171 { BFD_RELOC_OR1K_GOT16,
173 BFD_RELOC_OR1K_GOT_LO13,
177 { BFD_RELOC_OR1K_GOTPC_LO16,
181 BFD_RELOC_OR1K_GOTPC_HI16,
183 { BFD_RELOC_LO16_GOTOFF,
184 BFD_RELOC_OR1K_GOTOFF_SLO16,
187 BFD_RELOC_HI16_GOTOFF,
188 BFD_RELOC_HI16_S_GOTOFF },
189 { BFD_RELOC_OR1K_TLS_GD_LO16,
191 BFD_RELOC_OR1K_TLS_GD_LO13,
193 BFD_RELOC_OR1K_TLS_GD_HI16,
195 { BFD_RELOC_OR1K_TLS_LDM_LO16,
197 BFD_RELOC_OR1K_TLS_LDM_LO13,
199 BFD_RELOC_OR1K_TLS_LDM_HI16,
201 { BFD_RELOC_OR1K_TLS_LDO_LO16,
205 BFD_RELOC_OR1K_TLS_LDO_HI16,
207 { BFD_RELOC_OR1K_TLS_IE_LO16,
209 BFD_RELOC_OR1K_TLS_IE_LO13,
211 BFD_RELOC_OR1K_TLS_IE_HI16,
212 BFD_RELOC_OR1K_TLS_IE_AHI16 },
213 { BFD_RELOC_OR1K_TLS_LE_LO16,
214 BFD_RELOC_OR1K_TLS_LE_SLO16,
217 BFD_RELOC_OR1K_TLS_LE_HI16,
218 BFD_RELOC_OR1K_TLS_LE_AHI16 },
222 parse_reloc (const char **strp)
224 const char *str = *strp;
225 enum or1k_rclass cls = RCLASS_DIRECT;
228 if (strncasecmp (str, "got(", 4) == 0)
231 return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_LO;
233 if (strncasecmp (str, "gotpo(", 6) == 0)
236 return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_PO;
238 if (strncasecmp (str, "gottppo(", 8) == 0)
241 return (RCLASS_GOTTPOFF << RCLASS_SHIFT) | RTYPE_PO;
244 if (strncasecmp (str, "gotpc", 5) == 0)
249 else if (strncasecmp (str, "gotoff", 6) == 0)
254 else if (strncasecmp (str, "tlsgd", 5) == 0)
259 else if (strncasecmp (str, "tlsldm", 6) == 0)
264 else if (strncasecmp (str, "dtpoff", 6) == 0)
269 else if (strncasecmp (str, "gottpoff", 8) == 0)
272 cls = RCLASS_GOTTPOFF;
274 else if (strncasecmp (str, "tpoff", 5) == 0)
280 if (strncasecmp (str, "hi(", 3) == 0)
285 else if (strncasecmp (str, "lo(", 3) == 0)
290 else if (strncasecmp (str, "ha(", 3) == 0)
295 else if (strncasecmp (str, "po(", 3) == 0 && cls != RCLASS_GOTTPOFF)
304 return (cls << RCLASS_SHIFT) | typ;
308 parse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
309 long *valuep, int splitp)
312 enum cgen_parse_operand_result result_type;
313 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
314 enum or1k_rtype reloc_type;
321 reloc_code = parse_reloc (strp);
322 reloc_type = reloc_code & RTYPE_MASK;
325 enum or1k_rclass reloc_class = reloc_code >> RCLASS_SHIFT;
328 if ((reloc_type == RTYPE_LO || reloc_type == RTYPE_PO)
329 && reloc_class != RCLASS_GOT)
330 /* If split we or up the type to RTYPE_SLO or RTYPE_SPO. */
333 return INVALID_STORE_RELOC;
335 reloc = or1k_imm16_relocs[reloc_class][reloc_type];
338 if (reloc != BFD_RELOC_UNUSED)
342 errmsg = cgen_parse_address (cd, strp, opindex, reloc,
343 &result_type, &value);
345 errmsg = MISSING_CLOSING_PARENTHESIS;
350 if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
362 ret = (ret ^ 0x8000) - 0x8000;
369 errmsg = INVALID_RELOC_TYPE;
375 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
386 parse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
388 return parse_imm16(cd, strp, opindex, (long *) valuep, 0);
392 parse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
395 return parse_imm16(cd, strp, opindex, (long *) valuep, 1);
399 parse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
400 unsigned long *valuep)
402 const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0);
409 parse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
410 unsigned long *valuep)
412 const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1);