daily update
[deliverable/binutils-gdb.git] / opcodes / or1k-asm.c
CommitLineData
87e6d782
NC
1/* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
47b0e7ad
NC
4 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 - the resultant file is machine generated, cgen-asm.in isn't
87e6d782 6
73589c9d 7 Copyright 1996-2014 Free Software Foundation, Inc.
87e6d782 8
9b201bb5 9 This file is part of libopcodes.
87e6d782 10
9b201bb5 11 This library is free software; you can redistribute it and/or modify
47b0e7ad 12 it under the terms of the GNU General Public License as published by
9b201bb5 13 the Free Software Foundation; either version 3, or (at your option)
47b0e7ad 14 any later version.
87e6d782 15
9b201bb5
NC
16 It is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19 License for more details.
87e6d782 20
47b0e7ad
NC
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
87e6d782 24
9b201bb5 25
87e6d782
NC
26/* ??? Eventually more and more of this stuff can go to cpu-independent files.
27 Keep that in mind. */
28
29#include "sysdep.h"
87e6d782
NC
30#include <stdio.h>
31#include "ansidecl.h"
32#include "bfd.h"
33#include "symcat.h"
73589c9d
CS
34#include "or1k-desc.h"
35#include "or1k-opc.h"
87e6d782 36#include "opintl.h"
fc7bc883 37#include "xregex.h"
fc05c67f 38#include "libiberty.h"
37111cc7 39#include "safe-ctype.h"
87e6d782 40
37111cc7 41#undef min
87e6d782 42#define min(a,b) ((a) < (b) ? (a) : (b))
37111cc7 43#undef max
87e6d782
NC
44#define max(a,b) ((a) > (b) ? (a) : (b))
45
46static const char * parse_insn_normal
ffead7ae 47 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
87e6d782 48\f
37111cc7 49/* -- assembler routines inserted here. */
87e6d782
NC
50
51/* -- asm.c */
52
47b0e7ad 53static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
87e6d782 54
47b0e7ad 55#define CGEN_VERBOSE_ASSEMBLER_ERRORS
0e2ee3ca 56
73589c9d
CS
57static const char *
58parse_disp26 (CGEN_CPU_DESC cd,
59 const char ** strp,
60 int opindex,
61 int opinfo,
62 enum cgen_parse_operand_result * resultp,
63 bfd_vma * valuep)
87e6d782 64{
73589c9d
CS
65 const char *errmsg = NULL;
66 enum cgen_parse_operand_result result_type;
87e6d782 67
73589c9d
CS
68 if (strncasecmp (*strp, "plt(", 4) == 0)
69 {
70 bfd_vma value;
71
72 *strp += 4;
73 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
74 & result_type, & value);
75 if (**strp != ')')
76 return MISSING_CLOSING_PARENTHESIS;
77 ++*strp;
78 if (errmsg == NULL
79 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
80 value = (value >> 2) & 0xffff;
81 *valuep = value;
82 return errmsg;
83 }
84 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
85}
87e6d782
NC
86
87static const char *
73589c9d 88parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
87e6d782
NC
89{
90 const char *errmsg;
91 enum cgen_parse_operand_result result_type;
73589c9d 92 long ret;
87e6d782
NC
93
94 if (**strp == '#')
95 ++*strp;
96
97 if (strncasecmp (*strp, "hi(", 3) == 0)
98 {
8f807746 99 bfd_vma value;
87e6d782 100
8f807746 101 *strp += 3;
33b71eeb 102 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
73589c9d
CS
103 & result_type, & value);
104 if (**strp != ')')
105 errmsg = MISSING_CLOSING_PARENTHESIS;
106 ++*strp;
107
108 ret = value;
109
110 if (errmsg == NULL
111 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
112 {
113 ret >>= 16;
114 ret &= 0xffff;
115 ret = (ret ^ 0x8000) - 0x8000;
116 }
117 }
118 else if (strncasecmp (*strp, "lo(", 3) == 0)
119 {
120 bfd_vma value;
121
122 *strp += 3;
123 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
124 & result_type, & value);
87e6d782 125 if (**strp != ')')
47b0e7ad 126 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
127 ++*strp;
128
129 ret = value;
130
131 if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
132 {
133 ret &= 0xffff;
134 ret = (ret ^ 0x8000) - 0x8000;
135 }
136 }
137 else if (strncasecmp (*strp, "got(", 4) == 0)
138 {
139 bfd_vma value;
8f807746 140
73589c9d
CS
141 *strp += 4;
142 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16,
143 & result_type, & value);
144 if (**strp != ')')
145 return MISSING_CLOSING_PARENTHESIS;
87e6d782
NC
146 ++*strp;
147 if (errmsg == NULL
148 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
73589c9d
CS
149 value &= 0xffff;
150 *valuep = value;
151 return errmsg;
87e6d782 152 }
73589c9d 153 else if (strncasecmp (*strp, "gotpchi(", 8) == 0)
87e6d782 154 {
73589c9d 155 bfd_vma value;
33b71eeb 156
73589c9d
CS
157 *strp += 8;
158 errmsg = cgen_parse_address (cd, strp, opindex,
159 BFD_RELOC_OR1K_GOTPC_HI16,
160 & result_type, & value);
161 if (**strp != ')')
162 return MISSING_CLOSING_PARENTHESIS;
163 ++*strp;
164 if (errmsg == NULL
165 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
166 value = (value >> 16) & 0xffff;
167 *valuep = value;
168 return errmsg;
169 }
170 else if (strncasecmp (*strp, "gotpclo(", 8) == 0)
171 {
172 bfd_vma value;
33b71eeb 173
73589c9d
CS
174 *strp += 8;
175 errmsg = cgen_parse_address (cd, strp, opindex,
176 BFD_RELOC_OR1K_GOTPC_LO16,
177 &result_type, &value);
178 if (**strp != ')')
179 return MISSING_CLOSING_PARENTHESIS;
180 ++*strp;
181 if (errmsg == NULL
182 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
183 value &= 0xffff;
184 *valuep = value;
185 return errmsg;
87e6d782 186 }
73589c9d
CS
187 else if (strncasecmp (*strp, "gotoffhi(", 9) == 0)
188 {
189 bfd_vma value;
8f807746 190
73589c9d
CS
191 *strp += 9;
192 errmsg = cgen_parse_address (cd, strp, opindex,
193 BFD_RELOC_OR1K_GOTOFF_HI16,
194 & result_type, & value);
87e6d782 195
73589c9d
CS
196 if (**strp != ')')
197 return MISSING_CLOSING_PARENTHESIS;
198 ++*strp;
199 if (errmsg == NULL
200 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
201 value = (value >> 16) & 0xffff;
202 *valuep = value;
203 return errmsg;
204 }
205 else if (strncasecmp (*strp, "gotofflo(", 9) == 0)
206 {
207 bfd_vma value;
87e6d782 208
73589c9d
CS
209 *strp += 9;
210 errmsg = cgen_parse_address (cd, strp, opindex,
211 BFD_RELOC_OR1K_GOTOFF_LO16,
212 &result_type, &value);
213 if (**strp != ')')
214 return MISSING_CLOSING_PARENTHESIS;
215 ++*strp;
216 if (errmsg == NULL
217 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
218 value &= 0xffff;
219 *valuep = value;
220 return errmsg;
221 }
222 else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0)
223 {
224 bfd_vma value;
87e6d782 225
73589c9d
CS
226 *strp += 8;
227 errmsg = cgen_parse_address (cd, strp, opindex,
228 BFD_RELOC_OR1K_TLS_GD_HI16,
229 & result_type, & value);
87e6d782 230
73589c9d
CS
231 if (**strp != ')')
232 return MISSING_CLOSING_PARENTHESIS;
233 ++*strp;
234 if (errmsg == NULL
235 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
236 value = (value >> 16) & 0xffff;
237 *valuep = value;
238 return errmsg;
239 }
240 else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0)
87e6d782 241 {
8f807746 242 bfd_vma value;
87e6d782 243
73589c9d
CS
244 *strp += 8;
245 errmsg = cgen_parse_address (cd, strp, opindex,
246 BFD_RELOC_OR1K_TLS_GD_LO16,
247 &result_type, &value);
248 if (**strp != ')')
249 return MISSING_CLOSING_PARENTHESIS;
250 ++*strp;
251 if (errmsg == NULL
252 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
253 value &= 0xffff;
254 *valuep = value;
255 return errmsg;
256 }
257 else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0)
258 {
259 bfd_vma value;
260
261 *strp += 9;
262 errmsg = cgen_parse_address (cd, strp, opindex,
263 BFD_RELOC_OR1K_TLS_LDM_HI16,
264 & result_type, & value);
265
87e6d782 266 if (**strp != ')')
47b0e7ad 267 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
268 ++*strp;
269 if (errmsg == NULL
270 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
271 value = (value >> 16) & 0xffff;
272 *valuep = value;
273 return errmsg;
274 }
275 else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0)
276 {
277 bfd_vma value;
87e6d782 278
73589c9d
CS
279 *strp += 9;
280 errmsg = cgen_parse_address (cd, strp, opindex,
281 BFD_RELOC_OR1K_TLS_LDM_LO16,
282 &result_type, &value);
283 if (**strp != ')')
284 return MISSING_CLOSING_PARENTHESIS;
8f807746 285 ++*strp;
73589c9d
CS
286 if (errmsg == NULL
287 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
288 value &= 0xffff;
289 *valuep = value;
290 return errmsg;
87e6d782 291 }
73589c9d 292 else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0)
8f807746 293 {
73589c9d 294 bfd_vma value;
33b71eeb 295
73589c9d
CS
296 *strp += 9;
297 errmsg = cgen_parse_address (cd, strp, opindex,
298 BFD_RELOC_OR1K_TLS_LDO_HI16,
299 & result_type, & value);
33b71eeb 300
73589c9d
CS
301 if (**strp != ')')
302 return MISSING_CLOSING_PARENTHESIS;
303 ++*strp;
304 if (errmsg == NULL
305 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
306 value = (value >> 16) & 0xffff;
307 *valuep = value;
308 return errmsg;
309 }
310 else if (strncasecmp (*strp, "dtpofflo(", 9) == 0)
311 {
312 bfd_vma value;
313
314 *strp += 9;
315 errmsg = cgen_parse_address (cd, strp, opindex,
316 BFD_RELOC_OR1K_TLS_LDO_LO16,
317 &result_type, &value);
318 if (**strp != ')')
319 return MISSING_CLOSING_PARENTHESIS;
320 ++*strp;
321 if (errmsg == NULL
322 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
323 value &= 0xffff;
324 *valuep = value;
325 return errmsg;
8f807746 326 }
73589c9d
CS
327 else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0)
328 {
329 bfd_vma value;
8f807746 330
73589c9d
CS
331 *strp += 11;
332 errmsg = cgen_parse_address (cd, strp, opindex,
333 BFD_RELOC_OR1K_TLS_IE_HI16,
334 & result_type, & value);
335
336 if (**strp != ')')
337 return MISSING_CLOSING_PARENTHESIS;
338 ++*strp;
339 if (errmsg == NULL
340 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
341 value = (value >> 16) & 0xffff;
342 *valuep = value;
343 return errmsg;
344 }
345 else if (strncasecmp (*strp, "gottpofflo(", 11) == 0)
346 {
347 bfd_vma value;
348
349 *strp += 11;
350 errmsg = cgen_parse_address (cd, strp, opindex,
351 BFD_RELOC_OR1K_TLS_IE_LO16,
352 &result_type, &value);
353 if (**strp != ')')
354 return MISSING_CLOSING_PARENTHESIS;
355 ++*strp;
356 if (errmsg == NULL
357 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
358 value &= 0xffff;
359 *valuep = value;
360 return errmsg;
361 }
362 else if (strncasecmp (*strp, "tpoffhi(", 8) == 0)
363 {
364 bfd_vma value;
365
366 *strp += 8;
367 errmsg = cgen_parse_address (cd, strp, opindex,
368 BFD_RELOC_OR1K_TLS_LE_HI16,
369 & result_type, & value);
370
371 if (**strp != ')')
372 return MISSING_CLOSING_PARENTHESIS;
373 ++*strp;
374 if (errmsg == NULL
375 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
376 value = (value >> 16) & 0xffff;
377 *valuep = value;
378 return errmsg;
379 }
380 else if (strncasecmp (*strp, "tpofflo(", 8) == 0)
381 {
382 bfd_vma value;
383
384 *strp += 8;
385 errmsg = cgen_parse_address (cd, strp, opindex,
386 BFD_RELOC_OR1K_TLS_LE_LO16,
387 &result_type, &value);
388 if (**strp != ')')
389 return MISSING_CLOSING_PARENTHESIS;
390 ++*strp;
391 if (errmsg == NULL
392 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
393 value &= 0xffff;
394 *valuep = value;
395 return errmsg;
396 }
397 else
398 {
399 long value;
400 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
401 ret = value;
402 }
403
404 if (errmsg == NULL)
405 *valuep = ret;
406
407 return errmsg;
408}
409
410static const char *
411parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep)
412{
413 const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep);
414 if (errmsg == NULL)
415 *valuep &= 0xffff;
87e6d782
NC
416 return errmsg;
417}
418
419/* -- */
420
73589c9d 421const char * or1k_cgen_parse_operand
47b0e7ad 422 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
0e2ee3ca 423
87e6d782
NC
424/* Main entry point for operand parsing.
425
426 This function is basically just a big switch statement. Earlier versions
427 used tables to look up the function to use, but
428 - if the table contains both assembler and disassembler functions then
429 the disassembler contains much of the assembler and vice-versa,
430 - there's a lot of inlining possibilities as things grow,
431 - using a switch statement avoids the function call overhead.
432
433 This function could be moved into `parse_insn_normal', but keeping it
434 separate makes clear the interface between `parse_insn_normal' and each of
9a2e995d 435 the handlers. */
87e6d782
NC
436
437const char *
73589c9d 438or1k_cgen_parse_operand (CGEN_CPU_DESC cd,
47b0e7ad
NC
439 int opindex,
440 const char ** strp,
441 CGEN_FIELDS * fields)
87e6d782
NC
442{
443 const char * errmsg = NULL;
444 /* Used by scalar operands that still need to be parsed. */
fc05c67f 445 long junk ATTRIBUTE_UNUSED;
87e6d782
NC
446
447 switch (opindex)
448 {
73589c9d 449 case OR1K_OPERAND_DISP26 :
87e6d782 450 {
9494d739 451 bfd_vma value = 0;
73589c9d 452 errmsg = parse_disp26 (cd, strp, OR1K_OPERAND_DISP26, 0, NULL, & value);
87e6d782
NC
453 fields->f_disp26 = value;
454 }
455 break;
73589c9d
CS
456 case OR1K_OPERAND_RA :
457 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r2);
458 break;
459 case OR1K_OPERAND_RADF :
460 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
87e6d782 461 break;
73589c9d
CS
462 case OR1K_OPERAND_RASF :
463 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r2);
87e6d782 464 break;
73589c9d
CS
465 case OR1K_OPERAND_RB :
466 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r3);
87e6d782 467 break;
73589c9d
CS
468 case OR1K_OPERAND_RBDF :
469 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
87e6d782 470 break;
73589c9d
CS
471 case OR1K_OPERAND_RBSF :
472 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r3);
87e6d782 473 break;
73589c9d
CS
474 case OR1K_OPERAND_RD :
475 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r1);
87e6d782 476 break;
73589c9d
CS
477 case OR1K_OPERAND_RDDF :
478 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
87e6d782 479 break;
73589c9d
CS
480 case OR1K_OPERAND_RDSF :
481 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r1);
87e6d782 482 break;
73589c9d
CS
483 case OR1K_OPERAND_SIMM16 :
484 errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16, (long *) (& fields->f_simm16));
87e6d782 485 break;
73589c9d
CS
486 case OR1K_OPERAND_SIMM16_SPLIT :
487 errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16_SPLIT, (long *) (& fields->f_simm16_split));
87e6d782 488 break;
73589c9d
CS
489 case OR1K_OPERAND_UIMM16 :
490 errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16));
491 break;
492 case OR1K_OPERAND_UIMM16_SPLIT :
493 errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16_SPLIT, (unsigned long *) (& fields->f_uimm16_split));
494 break;
495 case OR1K_OPERAND_UIMM6 :
496 errmsg = cgen_parse_unsigned_integer (cd, strp, OR1K_OPERAND_UIMM6, (unsigned long *) (& fields->f_uimm6));
87e6d782
NC
497 break;
498
499 default :
500 /* xgettext:c-format */
501 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
502 abort ();
503 }
504
505 return errmsg;
506}
507
73589c9d 508cgen_parse_fn * const or1k_cgen_parse_handlers[] =
87e6d782
NC
509{
510 parse_insn_normal,
511};
512
513void
73589c9d 514or1k_cgen_init_asm (CGEN_CPU_DESC cd)
87e6d782 515{
73589c9d
CS
516 or1k_cgen_init_opcode_table (cd);
517 or1k_cgen_init_ibld_table (cd);
518 cd->parse_handlers = & or1k_cgen_parse_handlers[0];
519 cd->parse_operand = or1k_cgen_parse_operand;
1620f33d
AM
520#ifdef CGEN_ASM_INIT_HOOK
521CGEN_ASM_INIT_HOOK
522#endif
87e6d782
NC
523}
524
fc7bc883
RH
525\f
526
37111cc7 527/* Regex construction routine.
fc7bc883 528
37111cc7
NC
529 This translates an opcode syntax string into a regex string,
530 by replacing any non-character syntax element (such as an
531 opcode) with the pattern '.*'
fc7bc883 532
37111cc7 533 It then compiles the regex and stores it in the opcode, for
73589c9d 534 later use by or1k_cgen_assemble_insn
fc7bc883 535
37111cc7 536 Returns NULL for success, an error message for failure. */
fc7bc883 537
73589c9d
CS
538char *
539or1k_cgen_build_insn_regex (CGEN_INSN *insn)
540{
fc05c67f 541 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
fc7bc883 542 const char *mnem = CGEN_INSN_MNEMONIC (insn);
fc7bc883
RH
543 char rxbuf[CGEN_MAX_RX_ELEMENTS];
544 char *rx = rxbuf;
545 const CGEN_SYNTAX_CHAR_TYPE *syn;
546 int reg_err;
547
548 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
549
f3a55c17
NC
550 /* Mnemonics come first in the syntax string. */
551 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
552 return _("missing mnemonic in syntax string");
fc7bc883
RH
553 ++syn;
554
f3a55c17
NC
555 /* Generate a case sensitive regular expression that emulates case
556 insensitive matching in the "C" locale. We cannot generate a case
557 insensitive regular expression because in Turkish locales, 'i' and 'I'
558 are not equal modulo case conversion. */
fc7bc883 559
f3a55c17
NC
560 /* Copy the literal mnemonic out of the insn. */
561 for (; *mnem; mnem++)
562 {
563 char c = *mnem;
564
565 if (ISALPHA (c))
566 {
567 *rx++ = '[';
568 *rx++ = TOLOWER (c);
569 *rx++ = TOUPPER (c);
570 *rx++ = ']';
571 }
572 else
573 *rx++ = c;
574 }
575
576 /* Copy any remaining literals from the syntax string into the rx. */
577 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
fc7bc883 578 {
73589c9d 579 if (CGEN_SYNTAX_CHAR_P (* syn))
fc7bc883 580 {
f3a55c17
NC
581 char c = CGEN_SYNTAX_CHAR (* syn);
582
73589c9d 583 switch (c)
f3a55c17
NC
584 {
585 /* Escape any regex metacharacters in the syntax. */
73589c9d
CS
586 case '.': case '[': case '\\':
587 case '*': case '^': case '$':
fc7bc883
RH
588
589#ifdef CGEN_ESCAPE_EXTENDED_REGEX
73589c9d 590 case '?': case '{': case '}':
f3a55c17
NC
591 case '(': case ')': case '*':
592 case '|': case '+': case ']':
fc7bc883 593#endif
f3a55c17
NC
594 *rx++ = '\\';
595 *rx++ = c;
596 break;
597
598 default:
599 if (ISALPHA (c))
600 {
601 *rx++ = '[';
602 *rx++ = TOLOWER (c);
603 *rx++ = TOUPPER (c);
604 *rx++ = ']';
605 }
606 else
607 *rx++ = c;
608 break;
609 }
fc7bc883
RH
610 }
611 else
612 {
f3a55c17
NC
613 /* Replace non-syntax fields with globs. */
614 *rx++ = '.';
615 *rx++ = '*';
fc7bc883
RH
616 }
617 }
618
f3a55c17 619 /* Trailing whitespace ok. */
73589c9d
CS
620 * rx++ = '[';
621 * rx++ = ' ';
622 * rx++ = '\t';
623 * rx++ = ']';
624 * rx++ = '*';
fc7bc883 625
f3a55c17 626 /* But anchor it after that. */
73589c9d 627 * rx++ = '$';
fc7bc883
RH
628 * rx = '\0';
629
630 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
f3a55c17 631 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
fc7bc883 632
73589c9d 633 if (reg_err == 0)
fc7bc883
RH
634 return NULL;
635 else
636 {
637 static char msg[80];
f3a55c17 638
fc7bc883
RH
639 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
640 regfree ((regex_t *) CGEN_INSN_RX (insn));
641 free (CGEN_INSN_RX (insn));
642 (CGEN_INSN_RX (insn)) = NULL;
37111cc7 643 return msg;
fc7bc883
RH
644 }
645}
646
87e6d782
NC
647\f
648/* Default insn parser.
649
650 The syntax string is scanned and operands are parsed and stored in FIELDS.
651 Relocs are queued as we go via other callbacks.
652
653 ??? Note that this is currently an all-or-nothing parser. If we fail to
654 parse the instruction, we return 0 and the caller will start over from
655 the beginning. Backtracking will be necessary in parsing subexpressions,
656 but that can be handled there. Not handling backtracking here may get
657 expensive in the case of the m68k. Deal with later.
658
f3a55c17 659 Returns NULL for success, an error message for failure. */
87e6d782
NC
660
661static const char *
ffead7ae
MM
662parse_insn_normal (CGEN_CPU_DESC cd,
663 const CGEN_INSN *insn,
664 const char **strp,
665 CGEN_FIELDS *fields)
87e6d782
NC
666{
667 /* ??? Runtime added insns not handled yet. */
668 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
669 const char *str = *strp;
670 const char *errmsg;
671 const char *p;
672 const CGEN_SYNTAX_CHAR_TYPE * syn;
673#ifdef CGEN_MNEMONIC_OPERANDS
674 /* FIXME: wip */
675 int past_opcode_p;
676#endif
677
678 /* For now we assume the mnemonic is first (there are no leading operands).
679 We can parse it without needing to set up operand parsing.
680 GAS's input scrubber will ensure mnemonics are lowercase, but we may
681 not be called from GAS. */
682 p = CGEN_INSN_MNEMONIC (insn);
37111cc7 683 while (*p && TOLOWER (*p) == TOLOWER (*str))
87e6d782
NC
684 ++p, ++str;
685
686 if (* p)
687 return _("unrecognized instruction");
688
689#ifndef CGEN_MNEMONIC_OPERANDS
37111cc7 690 if (* str && ! ISSPACE (* str))
87e6d782
NC
691 return _("unrecognized instruction");
692#endif
693
694 CGEN_INIT_PARSE (cd);
695 cgen_init_parse_operand (cd);
696#ifdef CGEN_MNEMONIC_OPERANDS
697 past_opcode_p = 0;
698#endif
699
700 /* We don't check for (*str != '\0') here because we want to parse
701 any trailing fake arguments in the syntax string. */
702 syn = CGEN_SYNTAX_STRING (syntax);
703
704 /* Mnemonics come first for now, ensure valid string. */
705 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
706 abort ();
707
708 ++syn;
709
710 while (* syn != 0)
711 {
712 /* Non operand chars must match exactly. */
713 if (CGEN_SYNTAX_CHAR_P (* syn))
714 {
715 /* FIXME: While we allow for non-GAS callers above, we assume the
716 first char after the mnemonic part is a space. */
717 /* FIXME: We also take inappropriate advantage of the fact that
718 GAS's input scrubber will remove extraneous blanks. */
37111cc7 719 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
87e6d782
NC
720 {
721#ifdef CGEN_MNEMONIC_OPERANDS
722 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
723 past_opcode_p = 1;
724#endif
725 ++ syn;
726 ++ str;
727 }
728 else if (*str)
729 {
730 /* Syntax char didn't match. Can't be this insn. */
731 static char msg [80];
f3a55c17 732
87e6d782
NC
733 /* xgettext:c-format */
734 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
735 CGEN_SYNTAX_CHAR(*syn), *str);
736 return msg;
737 }
738 else
739 {
740 /* Ran out of input. */
741 static char msg [80];
f3a55c17 742
87e6d782
NC
743 /* xgettext:c-format */
744 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
745 CGEN_SYNTAX_CHAR(*syn));
746 return msg;
747 }
748 continue;
749 }
750
c7e2358a
AM
751#ifdef CGEN_MNEMONIC_OPERANDS
752 (void) past_opcode_p;
753#endif
87e6d782 754 /* We have an operand of some sort. */
c7e2358a 755 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
87e6d782
NC
756 if (errmsg)
757 return errmsg;
758
759 /* Done with this operand, continue with next one. */
760 ++ syn;
761 }
762
763 /* If we're at the end of the syntax string, we're done. */
764 if (* syn == 0)
765 {
766 /* FIXME: For the moment we assume a valid `str' can only contain
767 blanks now. IE: We needn't try again with a longer version of
768 the insn and it is assumed that longer versions of insns appear
769 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
37111cc7 770 while (ISSPACE (* str))
87e6d782
NC
771 ++ str;
772
773 if (* str != '\0')
774 return _("junk at end of line"); /* FIXME: would like to include `str' */
775
776 return NULL;
777 }
778
779 /* We couldn't parse it. */
780 return _("unrecognized instruction");
781}
782\f
783/* Main entry point.
784 This routine is called for each instruction to be assembled.
785 STR points to the insn to be assembled.
786 We assume all necessary tables have been initialized.
787 The assembled instruction, less any fixups, is stored in BUF.
788 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
789 still needs to be converted to target byte order, otherwise BUF is an array
790 of bytes in target byte order.
791 The result is a pointer to the insn's entry in the opcode table,
792 or NULL if an error occured (an error message will have already been
793 printed).
794
795 Note that when processing (non-alias) macro-insns,
796 this function recurses.
797
798 ??? It's possible to make this cpu-independent.
799 One would have to deal with a few minor things.
800 At this point in time doing so would be more of a curiosity than useful
801 [for example this file isn't _that_ big], but keeping the possibility in
802 mind helps keep the design clean. */
803
804const CGEN_INSN *
73589c9d 805or1k_cgen_assemble_insn (CGEN_CPU_DESC cd,
ffead7ae
MM
806 const char *str,
807 CGEN_FIELDS *fields,
808 CGEN_INSN_BYTES_PTR buf,
809 char **errmsg)
87e6d782
NC
810{
811 const char *start;
812 CGEN_INSN_LIST *ilist;
813 const char *parse_errmsg = NULL;
814 const char *insert_errmsg = NULL;
fc7bc883 815 int recognized_mnemonic = 0;
87e6d782
NC
816
817 /* Skip leading white space. */
37111cc7 818 while (ISSPACE (* str))
87e6d782
NC
819 ++ str;
820
821 /* The instructions are stored in hashed lists.
822 Get the first in the list. */
823 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
824
825 /* Keep looking until we find a match. */
87e6d782
NC
826 start = str;
827 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
828 {
829 const CGEN_INSN *insn = ilist->insn;
fc7bc883 830 recognized_mnemonic = 1;
87e6d782 831
73589c9d 832#ifdef CGEN_VALIDATE_INSN_SUPPORTED
f3a55c17
NC
833 /* Not usually needed as unsupported opcodes
834 shouldn't be in the hash lists. */
87e6d782 835 /* Is this insn supported by the selected cpu? */
73589c9d 836 if (! or1k_cgen_insn_supported (cd, insn))
87e6d782
NC
837 continue;
838#endif
b11dcf4e 839 /* If the RELAXED attribute is set, this is an insn that shouldn't be
87e6d782
NC
840 chosen immediately. Instead, it is used during assembler/linker
841 relaxation if possible. */
b11dcf4e 842 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
87e6d782
NC
843 continue;
844
845 str = start;
846
f3a55c17 847 /* Skip this insn if str doesn't look right lexically. */
fc7bc883
RH
848 if (CGEN_INSN_RX (insn) != NULL &&
849 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
850 continue;
851
87e6d782
NC
852 /* Allow parse/insert handlers to obtain length of insn. */
853 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
854
855 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
856 if (parse_errmsg != NULL)
857 continue;
858
f3a55c17 859 /* ??? 0 is passed for `pc'. */
87e6d782
NC
860 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
861 (bfd_vma) 0);
862 if (insert_errmsg != NULL)
863 continue;
864
865 /* It is up to the caller to actually output the insn and any
866 queued relocs. */
867 return insn;
868 }
869
870 {
871 static char errbuf[150];
87e6d782 872 const char *tmp_errmsg;
c7e2358a
AM
873#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
874#define be_verbose 1
87e6d782 875#else
c7e2358a 876#define be_verbose 0
87e6d782 877#endif
c7e2358a
AM
878
879 if (be_verbose)
880 {
881 /* If requesting verbose error messages, use insert_errmsg.
882 Failing that, use parse_errmsg. */
883 tmp_errmsg = (insert_errmsg ? insert_errmsg :
884 parse_errmsg ? parse_errmsg :
885 recognized_mnemonic ?
886 _("unrecognized form of instruction") :
887 _("unrecognized instruction"));
888
889 if (strlen (start) > 50)
890 /* xgettext:c-format */
891 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
73589c9d 892 else
c7e2358a
AM
893 /* xgettext:c-format */
894 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
895 }
896 else
897 {
898 if (strlen (start) > 50)
899 /* xgettext:c-format */
900 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
73589c9d 901 else
c7e2358a
AM
902 /* xgettext:c-format */
903 sprintf (errbuf, _("bad instruction `%.50s'"), start);
904 }
73589c9d 905
87e6d782
NC
906 *errmsg = errbuf;
907 return NULL;
908 }
909}
This page took 0.684107 seconds and 4 git commands to generate.