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