Cache result of scan for __start_* and __stop_* sections
[external/binutils.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 /* -- */