Remove trailing spaces in gprof
[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
b90efa5b 7 Copyright (C) 1996-2015 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,
c151b1c6
AM
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,
c151b1c6 74 & result_type, & value);
73589c9d 75 if (**strp != ')')
c151b1c6 76 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
77 ++*strp;
78 if (errmsg == NULL
c151b1c6
AM
79 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
80 value = (value >> 2) & 0xffff;
73589c9d
CS
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,
c151b1c6 103 & result_type, & value);
73589c9d 104 if (**strp != ')')
c151b1c6 105 errmsg = MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
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,
c151b1c6 124 & result_type, & value);
87e6d782 125 if (**strp != ')')
c151b1c6 126 return MISSING_CLOSING_PARENTHESIS;
73589c9d 127 ++*strp;
c151b1c6 128
73589c9d
CS
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,
c151b1c6 143 & result_type, & value);
73589c9d 144 if (**strp != ')')
c151b1c6 145 return MISSING_CLOSING_PARENTHESIS;
87e6d782
NC
146 ++*strp;
147 if (errmsg == NULL
c151b1c6
AM
148 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
149 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
159 BFD_RELOC_OR1K_GOTPC_HI16,
160 & result_type, & value);
73589c9d 161 if (**strp != ')')
c151b1c6 162 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
163 ++*strp;
164 if (errmsg == NULL
c151b1c6
AM
165 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
166 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
176 BFD_RELOC_OR1K_GOTPC_LO16,
177 &result_type, &value);
73589c9d 178 if (**strp != ')')
c151b1c6 179 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
180 ++*strp;
181 if (errmsg == NULL
c151b1c6
AM
182 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
183 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
193 BFD_RELOC_OR1K_GOTOFF_HI16,
194 & result_type, & value);
87e6d782 195
73589c9d 196 if (**strp != ')')
c151b1c6 197 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
198 ++*strp;
199 if (errmsg == NULL
c151b1c6
AM
200 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
201 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
211 BFD_RELOC_OR1K_GOTOFF_LO16,
212 &result_type, &value);
73589c9d 213 if (**strp != ')')
c151b1c6 214 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
215 ++*strp;
216 if (errmsg == NULL
c151b1c6
AM
217 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
218 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
228 BFD_RELOC_OR1K_TLS_GD_HI16,
229 & result_type, & value);
87e6d782 230
73589c9d 231 if (**strp != ')')
c151b1c6 232 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
233 ++*strp;
234 if (errmsg == NULL
c151b1c6
AM
235 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
236 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
246 BFD_RELOC_OR1K_TLS_GD_LO16,
247 &result_type, &value);
73589c9d 248 if (**strp != ')')
c151b1c6 249 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
250 ++*strp;
251 if (errmsg == NULL
c151b1c6
AM
252 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
253 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
263 BFD_RELOC_OR1K_TLS_LDM_HI16,
264 & result_type, & value);
73589c9d 265
87e6d782 266 if (**strp != ')')
c151b1c6 267 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
268 ++*strp;
269 if (errmsg == NULL
c151b1c6
AM
270 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
271 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
281 BFD_RELOC_OR1K_TLS_LDM_LO16,
282 &result_type, &value);
73589c9d 283 if (**strp != ')')
c151b1c6 284 return MISSING_CLOSING_PARENTHESIS;
8f807746 285 ++*strp;
73589c9d 286 if (errmsg == NULL
c151b1c6
AM
287 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
288 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
298 BFD_RELOC_OR1K_TLS_LDO_HI16,
299 & result_type, & value);
33b71eeb 300
73589c9d 301 if (**strp != ')')
c151b1c6 302 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
303 ++*strp;
304 if (errmsg == NULL
c151b1c6
AM
305 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
306 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
316 BFD_RELOC_OR1K_TLS_LDO_LO16,
317 &result_type, &value);
73589c9d 318 if (**strp != ')')
c151b1c6 319 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
320 ++*strp;
321 if (errmsg == NULL
c151b1c6
AM
322 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
323 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
333 BFD_RELOC_OR1K_TLS_IE_HI16,
334 & result_type, & value);
73589c9d
CS
335
336 if (**strp != ')')
c151b1c6 337 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
338 ++*strp;
339 if (errmsg == NULL
c151b1c6
AM
340 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
341 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
351 BFD_RELOC_OR1K_TLS_IE_LO16,
352 &result_type, &value);
73589c9d 353 if (**strp != ')')
c151b1c6 354 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
355 ++*strp;
356 if (errmsg == NULL
c151b1c6
AM
357 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
358 value &= 0xffff;
73589c9d
CS
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,
c151b1c6
AM
368 BFD_RELOC_OR1K_TLS_LE_HI16,
369 & result_type, & value);
73589c9d
CS
370
371 if (**strp != ')')
c151b1c6 372 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
373 ++*strp;
374 if (errmsg == NULL
c151b1c6
AM
375 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
376 value = (value >> 16) & 0xffff;
73589c9d
CS
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,
c151b1c6
AM
386 BFD_RELOC_OR1K_TLS_LE_LO16,
387 &result_type, &value);
73589c9d 388 if (**strp != ')')
c151b1c6 389 return MISSING_CLOSING_PARENTHESIS;
73589c9d
CS
390 ++*strp;
391 if (errmsg == NULL
c151b1c6
AM
392 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
393 value &= 0xffff;
73589c9d
CS
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);
c151b1c6 414
73589c9d
CS
415 if (errmsg == NULL)
416 *valuep &= 0xffff;
87e6d782
NC
417 return errmsg;
418}
419
420/* -- */
421
73589c9d 422const char * or1k_cgen_parse_operand
47b0e7ad 423 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
0e2ee3ca 424
87e6d782
NC
425/* Main entry point for operand parsing.
426
427 This function is basically just a big switch statement. Earlier versions
428 used tables to look up the function to use, but
429 - if the table contains both assembler and disassembler functions then
430 the disassembler contains much of the assembler and vice-versa,
431 - there's a lot of inlining possibilities as things grow,
432 - using a switch statement avoids the function call overhead.
433
434 This function could be moved into `parse_insn_normal', but keeping it
435 separate makes clear the interface between `parse_insn_normal' and each of
9a2e995d 436 the handlers. */
87e6d782
NC
437
438const char *
73589c9d 439or1k_cgen_parse_operand (CGEN_CPU_DESC cd,
47b0e7ad
NC
440 int opindex,
441 const char ** strp,
442 CGEN_FIELDS * fields)
87e6d782
NC
443{
444 const char * errmsg = NULL;
445 /* Used by scalar operands that still need to be parsed. */
fc05c67f 446 long junk ATTRIBUTE_UNUSED;
87e6d782
NC
447
448 switch (opindex)
449 {
73589c9d 450 case OR1K_OPERAND_DISP26 :
87e6d782 451 {
9494d739 452 bfd_vma value = 0;
73589c9d 453 errmsg = parse_disp26 (cd, strp, OR1K_OPERAND_DISP26, 0, NULL, & value);
87e6d782
NC
454 fields->f_disp26 = value;
455 }
456 break;
73589c9d
CS
457 case OR1K_OPERAND_RA :
458 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r2);
459 break;
460 case OR1K_OPERAND_RADF :
461 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
87e6d782 462 break;
73589c9d
CS
463 case OR1K_OPERAND_RASF :
464 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r2);
87e6d782 465 break;
73589c9d
CS
466 case OR1K_OPERAND_RB :
467 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r3);
87e6d782 468 break;
73589c9d
CS
469 case OR1K_OPERAND_RBDF :
470 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
87e6d782 471 break;
73589c9d
CS
472 case OR1K_OPERAND_RBSF :
473 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r3);
87e6d782 474 break;
73589c9d
CS
475 case OR1K_OPERAND_RD :
476 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r1);
87e6d782 477 break;
73589c9d
CS
478 case OR1K_OPERAND_RDDF :
479 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
87e6d782 480 break;
73589c9d
CS
481 case OR1K_OPERAND_RDSF :
482 errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r1);
87e6d782 483 break;
73589c9d
CS
484 case OR1K_OPERAND_SIMM16 :
485 errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16, (long *) (& fields->f_simm16));
87e6d782 486 break;
73589c9d
CS
487 case OR1K_OPERAND_SIMM16_SPLIT :
488 errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16_SPLIT, (long *) (& fields->f_simm16_split));
87e6d782 489 break;
73589c9d
CS
490 case OR1K_OPERAND_UIMM16 :
491 errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16));
492 break;
493 case OR1K_OPERAND_UIMM16_SPLIT :
494 errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16_SPLIT, (unsigned long *) (& fields->f_uimm16_split));
495 break;
496 case OR1K_OPERAND_UIMM6 :
497 errmsg = cgen_parse_unsigned_integer (cd, strp, OR1K_OPERAND_UIMM6, (unsigned long *) (& fields->f_uimm6));
87e6d782
NC
498 break;
499
500 default :
501 /* xgettext:c-format */
502 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
503 abort ();
504 }
505
506 return errmsg;
507}
508
c151b1c6 509cgen_parse_fn * const or1k_cgen_parse_handlers[] =
87e6d782
NC
510{
511 parse_insn_normal,
512};
513
514void
73589c9d 515or1k_cgen_init_asm (CGEN_CPU_DESC cd)
87e6d782 516{
73589c9d
CS
517 or1k_cgen_init_opcode_table (cd);
518 or1k_cgen_init_ibld_table (cd);
519 cd->parse_handlers = & or1k_cgen_parse_handlers[0];
520 cd->parse_operand = or1k_cgen_parse_operand;
1620f33d
AM
521#ifdef CGEN_ASM_INIT_HOOK
522CGEN_ASM_INIT_HOOK
523#endif
87e6d782
NC
524}
525
fc7bc883
RH
526\f
527
37111cc7 528/* Regex construction routine.
fc7bc883 529
37111cc7
NC
530 This translates an opcode syntax string into a regex string,
531 by replacing any non-character syntax element (such as an
532 opcode) with the pattern '.*'
fc7bc883 533
37111cc7 534 It then compiles the regex and stores it in the opcode, for
73589c9d 535 later use by or1k_cgen_assemble_insn
fc7bc883 536
37111cc7 537 Returns NULL for success, an error message for failure. */
fc7bc883 538
c151b1c6 539char *
73589c9d 540or1k_cgen_build_insn_regex (CGEN_INSN *insn)
c151b1c6 541{
fc05c67f 542 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
fc7bc883 543 const char *mnem = CGEN_INSN_MNEMONIC (insn);
fc7bc883
RH
544 char rxbuf[CGEN_MAX_RX_ELEMENTS];
545 char *rx = rxbuf;
546 const CGEN_SYNTAX_CHAR_TYPE *syn;
547 int reg_err;
548
549 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
550
f3a55c17
NC
551 /* Mnemonics come first in the syntax string. */
552 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
553 return _("missing mnemonic in syntax string");
fc7bc883
RH
554 ++syn;
555
f3a55c17
NC
556 /* Generate a case sensitive regular expression that emulates case
557 insensitive matching in the "C" locale. We cannot generate a case
558 insensitive regular expression because in Turkish locales, 'i' and 'I'
559 are not equal modulo case conversion. */
fc7bc883 560
f3a55c17
NC
561 /* Copy the literal mnemonic out of the insn. */
562 for (; *mnem; mnem++)
563 {
564 char c = *mnem;
565
566 if (ISALPHA (c))
567 {
568 *rx++ = '[';
569 *rx++ = TOLOWER (c);
570 *rx++ = TOUPPER (c);
571 *rx++ = ']';
572 }
573 else
574 *rx++ = c;
575 }
576
577 /* Copy any remaining literals from the syntax string into the rx. */
578 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
fc7bc883 579 {
c151b1c6 580 if (CGEN_SYNTAX_CHAR_P (* syn))
fc7bc883 581 {
f3a55c17
NC
582 char c = CGEN_SYNTAX_CHAR (* syn);
583
c151b1c6 584 switch (c)
f3a55c17
NC
585 {
586 /* Escape any regex metacharacters in the syntax. */
c151b1c6
AM
587 case '.': case '[': case '\\':
588 case '*': case '^': case '$':
fc7bc883
RH
589
590#ifdef CGEN_ESCAPE_EXTENDED_REGEX
c151b1c6 591 case '?': case '{': case '}':
f3a55c17
NC
592 case '(': case ')': case '*':
593 case '|': case '+': case ']':
fc7bc883 594#endif
f3a55c17
NC
595 *rx++ = '\\';
596 *rx++ = c;
597 break;
598
599 default:
600 if (ISALPHA (c))
601 {
602 *rx++ = '[';
603 *rx++ = TOLOWER (c);
604 *rx++ = TOUPPER (c);
605 *rx++ = ']';
606 }
607 else
608 *rx++ = c;
609 break;
610 }
fc7bc883
RH
611 }
612 else
613 {
f3a55c17
NC
614 /* Replace non-syntax fields with globs. */
615 *rx++ = '.';
616 *rx++ = '*';
fc7bc883
RH
617 }
618 }
619
f3a55c17 620 /* Trailing whitespace ok. */
c151b1c6
AM
621 * rx++ = '[';
622 * rx++ = ' ';
623 * rx++ = '\t';
624 * rx++ = ']';
625 * rx++ = '*';
fc7bc883 626
f3a55c17 627 /* But anchor it after that. */
c151b1c6 628 * rx++ = '$';
fc7bc883
RH
629 * rx = '\0';
630
631 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
f3a55c17 632 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
fc7bc883 633
c151b1c6 634 if (reg_err == 0)
fc7bc883
RH
635 return NULL;
636 else
637 {
638 static char msg[80];
f3a55c17 639
fc7bc883
RH
640 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
641 regfree ((regex_t *) CGEN_INSN_RX (insn));
642 free (CGEN_INSN_RX (insn));
643 (CGEN_INSN_RX (insn)) = NULL;
37111cc7 644 return msg;
fc7bc883
RH
645 }
646}
647
87e6d782
NC
648\f
649/* Default insn parser.
650
651 The syntax string is scanned and operands are parsed and stored in FIELDS.
652 Relocs are queued as we go via other callbacks.
653
654 ??? Note that this is currently an all-or-nothing parser. If we fail to
655 parse the instruction, we return 0 and the caller will start over from
656 the beginning. Backtracking will be necessary in parsing subexpressions,
657 but that can be handled there. Not handling backtracking here may get
658 expensive in the case of the m68k. Deal with later.
659
f3a55c17 660 Returns NULL for success, an error message for failure. */
87e6d782
NC
661
662static const char *
ffead7ae
MM
663parse_insn_normal (CGEN_CPU_DESC cd,
664 const CGEN_INSN *insn,
665 const char **strp,
666 CGEN_FIELDS *fields)
87e6d782
NC
667{
668 /* ??? Runtime added insns not handled yet. */
669 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
670 const char *str = *strp;
671 const char *errmsg;
672 const char *p;
673 const CGEN_SYNTAX_CHAR_TYPE * syn;
674#ifdef CGEN_MNEMONIC_OPERANDS
675 /* FIXME: wip */
676 int past_opcode_p;
677#endif
678
679 /* For now we assume the mnemonic is first (there are no leading operands).
680 We can parse it without needing to set up operand parsing.
681 GAS's input scrubber will ensure mnemonics are lowercase, but we may
682 not be called from GAS. */
683 p = CGEN_INSN_MNEMONIC (insn);
37111cc7 684 while (*p && TOLOWER (*p) == TOLOWER (*str))
87e6d782
NC
685 ++p, ++str;
686
687 if (* p)
688 return _("unrecognized instruction");
689
690#ifndef CGEN_MNEMONIC_OPERANDS
37111cc7 691 if (* str && ! ISSPACE (* str))
87e6d782
NC
692 return _("unrecognized instruction");
693#endif
694
695 CGEN_INIT_PARSE (cd);
696 cgen_init_parse_operand (cd);
697#ifdef CGEN_MNEMONIC_OPERANDS
698 past_opcode_p = 0;
699#endif
700
701 /* We don't check for (*str != '\0') here because we want to parse
702 any trailing fake arguments in the syntax string. */
703 syn = CGEN_SYNTAX_STRING (syntax);
704
705 /* Mnemonics come first for now, ensure valid string. */
706 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
707 abort ();
708
709 ++syn;
710
711 while (* syn != 0)
712 {
713 /* Non operand chars must match exactly. */
714 if (CGEN_SYNTAX_CHAR_P (* syn))
715 {
716 /* FIXME: While we allow for non-GAS callers above, we assume the
717 first char after the mnemonic part is a space. */
718 /* FIXME: We also take inappropriate advantage of the fact that
719 GAS's input scrubber will remove extraneous blanks. */
37111cc7 720 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
87e6d782
NC
721 {
722#ifdef CGEN_MNEMONIC_OPERANDS
723 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
724 past_opcode_p = 1;
725#endif
726 ++ syn;
727 ++ str;
728 }
729 else if (*str)
730 {
731 /* Syntax char didn't match. Can't be this insn. */
732 static char msg [80];
f3a55c17 733
87e6d782
NC
734 /* xgettext:c-format */
735 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
736 CGEN_SYNTAX_CHAR(*syn), *str);
737 return msg;
738 }
739 else
740 {
741 /* Ran out of input. */
742 static char msg [80];
f3a55c17 743
87e6d782
NC
744 /* xgettext:c-format */
745 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
746 CGEN_SYNTAX_CHAR(*syn));
747 return msg;
748 }
749 continue;
750 }
751
c7e2358a
AM
752#ifdef CGEN_MNEMONIC_OPERANDS
753 (void) past_opcode_p;
754#endif
87e6d782 755 /* We have an operand of some sort. */
c7e2358a 756 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
87e6d782
NC
757 if (errmsg)
758 return errmsg;
759
760 /* Done with this operand, continue with next one. */
761 ++ syn;
762 }
763
764 /* If we're at the end of the syntax string, we're done. */
765 if (* syn == 0)
766 {
767 /* FIXME: For the moment we assume a valid `str' can only contain
768 blanks now. IE: We needn't try again with a longer version of
769 the insn and it is assumed that longer versions of insns appear
770 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
37111cc7 771 while (ISSPACE (* str))
87e6d782
NC
772 ++ str;
773
774 if (* str != '\0')
775 return _("junk at end of line"); /* FIXME: would like to include `str' */
776
777 return NULL;
778 }
779
780 /* We couldn't parse it. */
781 return _("unrecognized instruction");
782}
783\f
784/* Main entry point.
785 This routine is called for each instruction to be assembled.
786 STR points to the insn to be assembled.
787 We assume all necessary tables have been initialized.
788 The assembled instruction, less any fixups, is stored in BUF.
789 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
790 still needs to be converted to target byte order, otherwise BUF is an array
791 of bytes in target byte order.
792 The result is a pointer to the insn's entry in the opcode table,
793 or NULL if an error occured (an error message will have already been
794 printed).
795
796 Note that when processing (non-alias) macro-insns,
797 this function recurses.
798
799 ??? It's possible to make this cpu-independent.
800 One would have to deal with a few minor things.
801 At this point in time doing so would be more of a curiosity than useful
802 [for example this file isn't _that_ big], but keeping the possibility in
803 mind helps keep the design clean. */
804
805const CGEN_INSN *
73589c9d 806or1k_cgen_assemble_insn (CGEN_CPU_DESC cd,
ffead7ae
MM
807 const char *str,
808 CGEN_FIELDS *fields,
809 CGEN_INSN_BYTES_PTR buf,
810 char **errmsg)
87e6d782
NC
811{
812 const char *start;
813 CGEN_INSN_LIST *ilist;
814 const char *parse_errmsg = NULL;
815 const char *insert_errmsg = NULL;
fc7bc883 816 int recognized_mnemonic = 0;
87e6d782
NC
817
818 /* Skip leading white space. */
37111cc7 819 while (ISSPACE (* str))
87e6d782
NC
820 ++ str;
821
822 /* The instructions are stored in hashed lists.
823 Get the first in the list. */
824 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
825
826 /* Keep looking until we find a match. */
87e6d782
NC
827 start = str;
828 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
829 {
830 const CGEN_INSN *insn = ilist->insn;
fc7bc883 831 recognized_mnemonic = 1;
87e6d782 832
c151b1c6 833#ifdef CGEN_VALIDATE_INSN_SUPPORTED
f3a55c17
NC
834 /* Not usually needed as unsupported opcodes
835 shouldn't be in the hash lists. */
87e6d782 836 /* Is this insn supported by the selected cpu? */
73589c9d 837 if (! or1k_cgen_insn_supported (cd, insn))
87e6d782
NC
838 continue;
839#endif
b11dcf4e 840 /* If the RELAXED attribute is set, this is an insn that shouldn't be
87e6d782
NC
841 chosen immediately. Instead, it is used during assembler/linker
842 relaxation if possible. */
b11dcf4e 843 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
87e6d782
NC
844 continue;
845
846 str = start;
847
f3a55c17 848 /* Skip this insn if str doesn't look right lexically. */
fc7bc883
RH
849 if (CGEN_INSN_RX (insn) != NULL &&
850 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
851 continue;
852
87e6d782
NC
853 /* Allow parse/insert handlers to obtain length of insn. */
854 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
855
856 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
857 if (parse_errmsg != NULL)
858 continue;
859
f3a55c17 860 /* ??? 0 is passed for `pc'. */
87e6d782
NC
861 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
862 (bfd_vma) 0);
863 if (insert_errmsg != NULL)
864 continue;
865
866 /* It is up to the caller to actually output the insn and any
867 queued relocs. */
868 return insn;
869 }
870
871 {
872 static char errbuf[150];
87e6d782 873 const char *tmp_errmsg;
c7e2358a
AM
874#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
875#define be_verbose 1
87e6d782 876#else
c7e2358a 877#define be_verbose 0
87e6d782 878#endif
c7e2358a
AM
879
880 if (be_verbose)
881 {
882 /* If requesting verbose error messages, use insert_errmsg.
883 Failing that, use parse_errmsg. */
884 tmp_errmsg = (insert_errmsg ? insert_errmsg :
885 parse_errmsg ? parse_errmsg :
886 recognized_mnemonic ?
887 _("unrecognized form of instruction") :
888 _("unrecognized instruction"));
889
890 if (strlen (start) > 50)
891 /* xgettext:c-format */
892 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
c151b1c6 893 else
c7e2358a
AM
894 /* xgettext:c-format */
895 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
896 }
897 else
898 {
899 if (strlen (start) > 50)
900 /* xgettext:c-format */
901 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
c151b1c6 902 else
c7e2358a
AM
903 /* xgettext:c-format */
904 sprintf (errbuf, _("bad instruction `%.50s'"), start);
905 }
c151b1c6 906
87e6d782
NC
907 *errmsg = errbuf;
908 return NULL;
909 }
910}
This page took 0.782812 seconds and 4 git commands to generate.