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