98b75327463b1584da0245b5d9f7bc67800cbb38
[deliverable/binutils-gdb.git] / cpu / or1k.opc
1 /* OpenRISC 1000 opcode support. -*- C -*-
2 Copyright 2000-2014 Free Software Foundation, Inc.
3
4 Originally ontributed for OR32 by Red Hat Inc;
5
6 This file is part of the GNU Binutils.
7
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.
12
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.
17
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/>. */
20
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.
27
28 Each section is delimited with start and end markers.
29
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" */
35
36 /* -- opc.h */
37
38 #undef CGEN_DIS_HASH_SIZE
39 #define CGEN_DIS_HASH_SIZE 256
40 #undef CGEN_DIS_HASH
41 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
42
43 /* -- */
44
45 /* -- opc.c */
46 /* -- */
47
48 /* -- asm.c */
49
50 static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
51
52 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
53
54 static const char *
55 parse_disp26 (CGEN_CPU_DESC cd,
56 const char ** strp,
57 int opindex,
58 int opinfo,
59 enum cgen_parse_operand_result * resultp,
60 bfd_vma * valuep)
61 {
62 const char *errmsg = NULL;
63 enum cgen_parse_operand_result result_type;
64
65 if (strncasecmp (*strp, "plt(", 4) == 0)
66 {
67 bfd_vma value;
68
69 *strp += 4;
70 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
71 & result_type, & value);
72 if (**strp != ')')
73 return MISSING_CLOSING_PARENTHESIS;
74 ++*strp;
75 if (errmsg == NULL
76 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
77 value = (value >> 2) & 0xffff;
78 *valuep = value;
79 return errmsg;
80 }
81 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
82 }
83
84 static const char *
85 parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
86 {
87 const char *errmsg;
88 enum cgen_parse_operand_result result_type;
89 long ret;
90
91 if (**strp == '#')
92 ++*strp;
93
94 if (strncasecmp (*strp, "hi(", 3) == 0)
95 {
96 bfd_vma value;
97
98 *strp += 3;
99 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
100 & result_type, & value);
101 if (**strp != ')')
102 errmsg = MISSING_CLOSING_PARENTHESIS;
103 ++*strp;
104
105 ret = value;
106
107 if (errmsg == NULL
108 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
109 {
110 ret >>= 16;
111 ret &= 0xffff;
112 ret = (ret ^ 0x8000) - 0x8000;
113 }
114 }
115 else if (strncasecmp (*strp, "lo(", 3) == 0)
116 {
117 bfd_vma value;
118
119 *strp += 3;
120 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
121 & result_type, & value);
122 if (**strp != ')')
123 return MISSING_CLOSING_PARENTHESIS;
124 ++*strp;
125
126 ret = value;
127
128 if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
129 {
130 ret &= 0xffff;
131 ret = (ret ^ 0x8000) - 0x8000;
132 }
133 }
134 else if (strncasecmp (*strp, "got(", 4) == 0)
135 {
136 bfd_vma value;
137
138 *strp += 4;
139 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16,
140 & result_type, & value);
141 if (**strp != ')')
142 return MISSING_CLOSING_PARENTHESIS;
143 ++*strp;
144 if (errmsg == NULL
145 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
146 value &= 0xffff;
147 *valuep = value;
148 return errmsg;
149 }
150 else if (strncasecmp (*strp, "gotpchi(", 8) == 0)
151 {
152 bfd_vma value;
153
154 *strp += 8;
155 errmsg = cgen_parse_address (cd, strp, opindex,
156 BFD_RELOC_OR1K_GOTPC_HI16,
157 & result_type, & value);
158 if (**strp != ')')
159 return MISSING_CLOSING_PARENTHESIS;
160 ++*strp;
161 if (errmsg == NULL
162 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
163 value = (value >> 16) & 0xffff;
164 *valuep = value;
165 return errmsg;
166 }
167 else if (strncasecmp (*strp, "gotpclo(", 8) == 0)
168 {
169 bfd_vma value;
170
171 *strp += 8;
172 errmsg = cgen_parse_address (cd, strp, opindex,
173 BFD_RELOC_OR1K_GOTPC_LO16,
174 &result_type, &value);
175 if (**strp != ')')
176 return MISSING_CLOSING_PARENTHESIS;
177 ++*strp;
178 if (errmsg == NULL
179 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
180 value &= 0xffff;
181 *valuep = value;
182 return errmsg;
183 }
184 else if (strncasecmp (*strp, "gotoffhi(", 9) == 0)
185 {
186 bfd_vma value;
187
188 *strp += 9;
189 errmsg = cgen_parse_address (cd, strp, opindex,
190 BFD_RELOC_OR1K_GOTOFF_HI16,
191 & result_type, & value);
192
193 if (**strp != ')')
194 return MISSING_CLOSING_PARENTHESIS;
195 ++*strp;
196 if (errmsg == NULL
197 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
198 value = (value >> 16) & 0xffff;
199 *valuep = value;
200 return errmsg;
201 }
202 else if (strncasecmp (*strp, "gotofflo(", 9) == 0)
203 {
204 bfd_vma value;
205
206 *strp += 9;
207 errmsg = cgen_parse_address (cd, strp, opindex,
208 BFD_RELOC_OR1K_GOTOFF_LO16,
209 &result_type, &value);
210 if (**strp != ')')
211 return MISSING_CLOSING_PARENTHESIS;
212 ++*strp;
213 if (errmsg == NULL
214 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
215 value &= 0xffff;
216 *valuep = value;
217 return errmsg;
218 }
219 else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0)
220 {
221 bfd_vma value;
222
223 *strp += 8;
224 errmsg = cgen_parse_address (cd, strp, opindex,
225 BFD_RELOC_OR1K_TLS_GD_HI16,
226 & result_type, & value);
227
228 if (**strp != ')')
229 return MISSING_CLOSING_PARENTHESIS;
230 ++*strp;
231 if (errmsg == NULL
232 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
233 value = (value >> 16) & 0xffff;
234 *valuep = value;
235 return errmsg;
236 }
237 else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0)
238 {
239 bfd_vma value;
240
241 *strp += 8;
242 errmsg = cgen_parse_address (cd, strp, opindex,
243 BFD_RELOC_OR1K_TLS_GD_LO16,
244 &result_type, &value);
245 if (**strp != ')')
246 return MISSING_CLOSING_PARENTHESIS;
247 ++*strp;
248 if (errmsg == NULL
249 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
250 value &= 0xffff;
251 *valuep = value;
252 return errmsg;
253 }
254 else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0)
255 {
256 bfd_vma value;
257
258 *strp += 9;
259 errmsg = cgen_parse_address (cd, strp, opindex,
260 BFD_RELOC_OR1K_TLS_LDM_HI16,
261 & result_type, & value);
262
263 if (**strp != ')')
264 return MISSING_CLOSING_PARENTHESIS;
265 ++*strp;
266 if (errmsg == NULL
267 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
268 value = (value >> 16) & 0xffff;
269 *valuep = value;
270 return errmsg;
271 }
272 else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0)
273 {
274 bfd_vma value;
275
276 *strp += 9;
277 errmsg = cgen_parse_address (cd, strp, opindex,
278 BFD_RELOC_OR1K_TLS_LDM_LO16,
279 &result_type, &value);
280 if (**strp != ')')
281 return MISSING_CLOSING_PARENTHESIS;
282 ++*strp;
283 if (errmsg == NULL
284 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
285 value &= 0xffff;
286 *valuep = value;
287 return errmsg;
288 }
289 else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0)
290 {
291 bfd_vma value;
292
293 *strp += 9;
294 errmsg = cgen_parse_address (cd, strp, opindex,
295 BFD_RELOC_OR1K_TLS_LDO_HI16,
296 & result_type, & value);
297
298 if (**strp != ')')
299 return MISSING_CLOSING_PARENTHESIS;
300 ++*strp;
301 if (errmsg == NULL
302 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
303 value = (value >> 16) & 0xffff;
304 *valuep = value;
305 return errmsg;
306 }
307 else if (strncasecmp (*strp, "dtpofflo(", 9) == 0)
308 {
309 bfd_vma value;
310
311 *strp += 9;
312 errmsg = cgen_parse_address (cd, strp, opindex,
313 BFD_RELOC_OR1K_TLS_LDO_LO16,
314 &result_type, &value);
315 if (**strp != ')')
316 return MISSING_CLOSING_PARENTHESIS;
317 ++*strp;
318 if (errmsg == NULL
319 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
320 value &= 0xffff;
321 *valuep = value;
322 return errmsg;
323 }
324 else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0)
325 {
326 bfd_vma value;
327
328 *strp += 11;
329 errmsg = cgen_parse_address (cd, strp, opindex,
330 BFD_RELOC_OR1K_TLS_IE_HI16,
331 & result_type, & value);
332
333 if (**strp != ')')
334 return MISSING_CLOSING_PARENTHESIS;
335 ++*strp;
336 if (errmsg == NULL
337 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
338 value = (value >> 16) & 0xffff;
339 *valuep = value;
340 return errmsg;
341 }
342 else if (strncasecmp (*strp, "gottpofflo(", 11) == 0)
343 {
344 bfd_vma value;
345
346 *strp += 11;
347 errmsg = cgen_parse_address (cd, strp, opindex,
348 BFD_RELOC_OR1K_TLS_IE_LO16,
349 &result_type, &value);
350 if (**strp != ')')
351 return MISSING_CLOSING_PARENTHESIS;
352 ++*strp;
353 if (errmsg == NULL
354 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
355 value &= 0xffff;
356 *valuep = value;
357 return errmsg;
358 }
359 else if (strncasecmp (*strp, "tpoffhi(", 8) == 0)
360 {
361 bfd_vma value;
362
363 *strp += 8;
364 errmsg = cgen_parse_address (cd, strp, opindex,
365 BFD_RELOC_OR1K_TLS_LE_HI16,
366 & result_type, & value);
367
368 if (**strp != ')')
369 return MISSING_CLOSING_PARENTHESIS;
370 ++*strp;
371 if (errmsg == NULL
372 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
373 value = (value >> 16) & 0xffff;
374 *valuep = value;
375 return errmsg;
376 }
377 else if (strncasecmp (*strp, "tpofflo(", 8) == 0)
378 {
379 bfd_vma value;
380
381 *strp += 8;
382 errmsg = cgen_parse_address (cd, strp, opindex,
383 BFD_RELOC_OR1K_TLS_LE_LO16,
384 &result_type, &value);
385 if (**strp != ')')
386 return MISSING_CLOSING_PARENTHESIS;
387 ++*strp;
388 if (errmsg == NULL
389 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
390 value &= 0xffff;
391 *valuep = value;
392 return errmsg;
393 }
394 else
395 {
396 long value;
397 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
398 ret = value;
399 }
400
401 if (errmsg == NULL)
402 *valuep = ret;
403
404 return errmsg;
405 }
406
407 static const char *
408 parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep)
409 {
410 const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep);
411
412 if (errmsg == NULL)
413 *valuep &= 0xffff;
414 return errmsg;
415 }
416
417 /* -- */
418
419 /* -- ibd.h */
420
421 /* -- */
This page took 0.038864 seconds and 3 git commands to generate.