1
/* Assembler interface for targets using CGEN. -*- C -*-
2
CGEN: Cpu tools GENerator
4
THIS FILE IS MACHINE GENERATED WITH CGEN.
5
- the resultant file is machine generated, cgen-asm.in isn't
7
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008, 2010
8
Free Software Foundation, Inc.
10
This file is part of libopcodes.
12
This library is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; either version 3, or (at your option)
17
It is distributed in the hope that it will be useful, but WITHOUT
18
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20
License for more details.
22
You should have received a copy of the GNU General Public License
23
along with this program; if not, write to the Free Software Foundation, Inc.,
24
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
27
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
35
#include "ip2k-desc.h"
39
#include "libiberty.h"
40
#include "safe-ctype.h"
43
#define min(a,b) ((a) < (b) ? (a) : (b))
45
#define max(a,b) ((a) > (b) ? (a) : (b))
47
static const char * parse_insn_normal
48
(CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
50
/* -- assembler routines inserted here. */
55
parse_fr (CGEN_CPU_DESC cd,
58
unsigned long *valuep)
63
enum cgen_parse_operand_result result_type;
65
extern CGEN_KEYWORD ip2k_cgen_opval_register_names;
71
/* Check here to see if you're about to try parsing a w as the first arg
72
and return an error if you are. */
73
if ((strncmp (*strp, "w", 1) == 0) || (strncmp (*strp, "W", 1) == 0))
77
if ((strncmp (*strp, ",", 1) == 0) || ISSPACE (**strp))
79
/* We've been passed a w. Return with an error message so that
80
cgen will try the next parsing option. */
81
errmsg = _("W keyword invalid in FR operand slot.");
87
/* Attempt parse as register keyword. */
88
errmsg = cgen_parse_keyword (cd, strp, & ip2k_cgen_opval_register_names,
94
/* Attempt to parse for "(IP)". */
95
afteroffset = strstr (*strp, "(IP)");
97
if (afteroffset == NULL)
98
/* Make sure it's not in lower case. */
99
afteroffset = strstr (*strp, "(ip)");
101
if (afteroffset != NULL)
103
if (afteroffset != *strp)
105
/* Invalid offset present. */
106
errmsg = _("offset(IP) is not a valid form");
118
/* Attempt to parse for DP. ex: mov w, offset(DP)
121
/* Try parsing it as an address and see what comes back. */
122
afteroffset = strstr (*strp, "(DP)");
124
if (afteroffset == NULL)
125
/* Maybe it's in lower case. */
126
afteroffset = strstr (*strp, "(dp)");
128
if (afteroffset != NULL)
130
if (afteroffset == *strp)
132
/* No offset present. Use 0 by default. */
137
errmsg = cgen_parse_address (cd, strp, opindex,
138
BFD_RELOC_IP2K_FR_OFFSET,
139
& result_type, & tempvalue);
143
if (tempvalue <= 127)
145
/* Value is ok. Fix up the first 2 bits and return. */
146
*valuep = 0x0100 | tempvalue;
147
*strp += 4; /* Skip over the (DP) in *strp. */
152
/* Found something there in front of (DP) but it's out
154
errmsg = _("(DP) offset out of range.");
161
/* Attempt to parse for SP. ex: mov w, offset(SP)
162
mov offset(SP), w. */
163
afteroffset = strstr (*strp, "(SP)");
165
if (afteroffset == NULL)
166
/* Maybe it's in lower case. */
167
afteroffset = strstr (*strp, "(sp)");
169
if (afteroffset != NULL)
171
if (afteroffset == *strp)
173
/* No offset present. Use 0 by default. */
178
errmsg = cgen_parse_address (cd, strp, opindex,
179
BFD_RELOC_IP2K_FR_OFFSET,
180
& result_type, & tempvalue);
184
if (tempvalue <= 127)
186
/* Value is ok. Fix up the first 2 bits and return. */
187
*valuep = 0x0180 | tempvalue;
188
*strp += 4; /* Skip over the (SP) in *strp. */
193
/* Found something there in front of (SP) but it's out
195
errmsg = _("(SP) offset out of range.");
201
/* Attempt to parse as an address. */
203
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR9,
204
& result_type, & value);
209
/* If a parenthesis is found, warn about invalid form. */
211
errmsg = _("illegal use of parentheses");
213
/* If a numeric value is specified, ensure that it is between
215
else if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
217
if (value < 0x1 || value > 0xff)
218
errmsg = _("operand out of range (not between 1 and 255)");
225
parse_addr16 (CGEN_CPU_DESC cd,
228
unsigned long *valuep)
231
enum cgen_parse_operand_result result_type;
232
bfd_reloc_code_real_type code = BFD_RELOC_NONE;
235
if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16H)
236
code = BFD_RELOC_IP2K_HI8DATA;
237
else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16L)
238
code = BFD_RELOC_IP2K_LO8DATA;
241
/* Something is very wrong. opindex has to be one of the above. */
242
errmsg = _("parse_addr16: invalid opindex.");
246
errmsg = cgen_parse_address (cd, strp, opindex, code,
247
& result_type, & value);
250
/* We either have a relocation or a number now. */
251
if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
253
/* We got a number back. */
254
if (code == BFD_RELOC_IP2K_HI8DATA)
257
/* code = BFD_RELOC_IP2K_LOW8DATA. */
267
parse_addr16_cjp (CGEN_CPU_DESC cd,
270
unsigned long *valuep)
273
enum cgen_parse_operand_result result_type;
274
bfd_reloc_code_real_type code = BFD_RELOC_NONE;
277
if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP)
278
code = BFD_RELOC_IP2K_ADDR16CJP;
279
else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P)
280
code = BFD_RELOC_IP2K_PAGE3;
282
errmsg = cgen_parse_address (cd, strp, opindex, code,
283
& result_type, & value);
286
if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
288
if ((value & 0x1) == 0) /* If the address is even .... */
290
if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP)
291
*valuep = (value >> 1) & 0x1FFF; /* Should mask be 1FFF? */
292
else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P)
293
*valuep = (value >> 14) & 0x7;
296
errmsg = _("Byte address required. - must be even.");
298
else if (result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED)
300
/* This will happen for things like (s2-s1) where s2 and s1
305
errmsg = _("cgen_parse_address returned a symbol. Literal required.");
311
parse_lit8 (CGEN_CPU_DESC cd,
317
enum cgen_parse_operand_result result_type;
318
bfd_reloc_code_real_type code = BFD_RELOC_NONE;
321
/* Parse %OP relocating operators. */
322
if (strncmp (*strp, "%bank", 5) == 0)
325
code = BFD_RELOC_IP2K_BANK;
327
else if (strncmp (*strp, "%lo8data", 8) == 0)
330
code = BFD_RELOC_IP2K_LO8DATA;
332
else if (strncmp (*strp, "%hi8data", 8) == 0)
335
code = BFD_RELOC_IP2K_HI8DATA;
337
else if (strncmp (*strp, "%ex8data", 8) == 0)
340
code = BFD_RELOC_IP2K_EX8DATA;
342
else if (strncmp (*strp, "%lo8insn", 8) == 0)
345
code = BFD_RELOC_IP2K_LO8INSN;
347
else if (strncmp (*strp, "%hi8insn", 8) == 0)
350
code = BFD_RELOC_IP2K_HI8INSN;
353
/* Parse %op operand. */
354
if (code != BFD_RELOC_NONE)
356
errmsg = cgen_parse_address (cd, strp, opindex, code,
357
& result_type, & value);
358
if ((errmsg == NULL) &&
359
(result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED))
360
errmsg = _("percent-operator operand is not a symbol");
364
/* Parse as a number. */
367
errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
369
/* Truncate to eight bits to accept both signed and unsigned input. */
378
parse_bit3 (CGEN_CPU_DESC cd,
381
unsigned long *valuep)
388
if (strncmp (*strp, "%bit", 4) == 0)
393
else if (strncmp (*strp, "%msbbit", 7) == 0)
398
else if (strncmp (*strp, "%lsbbit", 7) == 0)
404
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
413
errmsg = _("Attempt to find bit index of 0");
420
while ((value & 0x80000000) == 0)
429
while ((value & 0x00000001) == 0)
444
const char * ip2k_cgen_parse_operand
445
(CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
447
/* Main entry point for operand parsing.
449
This function is basically just a big switch statement. Earlier versions
450
used tables to look up the function to use, but
451
- if the table contains both assembler and disassembler functions then
452
the disassembler contains much of the assembler and vice-versa,
453
- there's a lot of inlining possibilities as things grow,
454
- using a switch statement avoids the function call overhead.
456
This function could be moved into `parse_insn_normal', but keeping it
457
separate makes clear the interface between `parse_insn_normal' and each of
461
ip2k_cgen_parse_operand (CGEN_CPU_DESC cd,
464
CGEN_FIELDS * fields)
466
const char * errmsg = NULL;
467
/* Used by scalar operands that still need to be parsed. */
468
long junk ATTRIBUTE_UNUSED;
472
case IP2K_OPERAND_ADDR16CJP :
473
errmsg = parse_addr16_cjp (cd, strp, IP2K_OPERAND_ADDR16CJP, (unsigned long *) (& fields->f_addr16cjp));
475
case IP2K_OPERAND_ADDR16H :
476
errmsg = parse_addr16 (cd, strp, IP2K_OPERAND_ADDR16H, (unsigned long *) (& fields->f_imm8));
478
case IP2K_OPERAND_ADDR16L :
479
errmsg = parse_addr16 (cd, strp, IP2K_OPERAND_ADDR16L, (unsigned long *) (& fields->f_imm8));
481
case IP2K_OPERAND_ADDR16P :
482
errmsg = parse_addr16_cjp (cd, strp, IP2K_OPERAND_ADDR16P, (unsigned long *) (& fields->f_page3));
484
case IP2K_OPERAND_BITNO :
485
errmsg = parse_bit3 (cd, strp, IP2K_OPERAND_BITNO, (unsigned long *) (& fields->f_bitno));
487
case IP2K_OPERAND_CBIT :
488
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_CBIT, (unsigned long *) (& junk));
490
case IP2K_OPERAND_DCBIT :
491
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_DCBIT, (unsigned long *) (& junk));
493
case IP2K_OPERAND_FR :
494
errmsg = parse_fr (cd, strp, IP2K_OPERAND_FR, (unsigned long *) (& fields->f_reg));
496
case IP2K_OPERAND_LIT8 :
497
errmsg = parse_lit8 (cd, strp, IP2K_OPERAND_LIT8, (long *) (& fields->f_imm8));
499
case IP2K_OPERAND_PABITS :
500
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_PABITS, (unsigned long *) (& junk));
502
case IP2K_OPERAND_RETI3 :
503
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_RETI3, (unsigned long *) (& fields->f_reti3));
505
case IP2K_OPERAND_ZBIT :
506
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_ZBIT, (unsigned long *) (& junk));
510
/* xgettext:c-format */
511
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
518
cgen_parse_fn * const ip2k_cgen_parse_handlers[] =
524
ip2k_cgen_init_asm (CGEN_CPU_DESC cd)
526
ip2k_cgen_init_opcode_table (cd);
527
ip2k_cgen_init_ibld_table (cd);
528
cd->parse_handlers = & ip2k_cgen_parse_handlers[0];
529
cd->parse_operand = ip2k_cgen_parse_operand;
530
#ifdef CGEN_ASM_INIT_HOOK
537
/* Regex construction routine.
539
This translates an opcode syntax string into a regex string,
540
by replacing any non-character syntax element (such as an
541
opcode) with the pattern '.*'
543
It then compiles the regex and stores it in the opcode, for
544
later use by ip2k_cgen_assemble_insn
546
Returns NULL for success, an error message for failure. */
549
ip2k_cgen_build_insn_regex (CGEN_INSN *insn)
551
CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
552
const char *mnem = CGEN_INSN_MNEMONIC (insn);
553
char rxbuf[CGEN_MAX_RX_ELEMENTS];
555
const CGEN_SYNTAX_CHAR_TYPE *syn;
558
syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
560
/* Mnemonics come first in the syntax string. */
561
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
562
return _("missing mnemonic in syntax string");
565
/* Generate a case sensitive regular expression that emulates case
566
insensitive matching in the "C" locale. We cannot generate a case
567
insensitive regular expression because in Turkish locales, 'i' and 'I'
568
are not equal modulo case conversion. */
570
/* Copy the literal mnemonic out of the insn. */
571
for (; *mnem; mnem++)
586
/* Copy any remaining literals from the syntax string into the rx. */
587
for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
589
if (CGEN_SYNTAX_CHAR_P (* syn))
591
char c = CGEN_SYNTAX_CHAR (* syn);
595
/* Escape any regex metacharacters in the syntax. */
596
case '.': case '[': case '\\':
597
case '*': case '^': case '$':
599
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
600
case '?': case '{': case '}':
601
case '(': case ')': case '*':
602
case '|': case '+': case ']':
623
/* Replace non-syntax fields with globs. */
629
/* Trailing whitespace ok. */
636
/* But anchor it after that. */
640
CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
641
reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
649
regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
650
regfree ((regex_t *) CGEN_INSN_RX (insn));
651
free (CGEN_INSN_RX (insn));
652
(CGEN_INSN_RX (insn)) = NULL;
658
/* Default insn parser.
660
The syntax string is scanned and operands are parsed and stored in FIELDS.
661
Relocs are queued as we go via other callbacks.
663
??? Note that this is currently an all-or-nothing parser. If we fail to
664
parse the instruction, we return 0 and the caller will start over from
665
the beginning. Backtracking will be necessary in parsing subexpressions,
666
but that can be handled there. Not handling backtracking here may get
667
expensive in the case of the m68k. Deal with later.
669
Returns NULL for success, an error message for failure. */
672
parse_insn_normal (CGEN_CPU_DESC cd,
673
const CGEN_INSN *insn,
677
/* ??? Runtime added insns not handled yet. */
678
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
679
const char *str = *strp;
682
const CGEN_SYNTAX_CHAR_TYPE * syn;
683
#ifdef CGEN_MNEMONIC_OPERANDS
688
/* For now we assume the mnemonic is first (there are no leading operands).
689
We can parse it without needing to set up operand parsing.
690
GAS's input scrubber will ensure mnemonics are lowercase, but we may
691
not be called from GAS. */
692
p = CGEN_INSN_MNEMONIC (insn);
693
while (*p && TOLOWER (*p) == TOLOWER (*str))
697
return _("unrecognized instruction");
699
#ifndef CGEN_MNEMONIC_OPERANDS
700
if (* str && ! ISSPACE (* str))
701
return _("unrecognized instruction");
704
CGEN_INIT_PARSE (cd);
705
cgen_init_parse_operand (cd);
706
#ifdef CGEN_MNEMONIC_OPERANDS
710
/* We don't check for (*str != '\0') here because we want to parse
711
any trailing fake arguments in the syntax string. */
712
syn = CGEN_SYNTAX_STRING (syntax);
714
/* Mnemonics come first for now, ensure valid string. */
715
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
722
/* Non operand chars must match exactly. */
723
if (CGEN_SYNTAX_CHAR_P (* syn))
725
/* FIXME: While we allow for non-GAS callers above, we assume the
726
first char after the mnemonic part is a space. */
727
/* FIXME: We also take inappropriate advantage of the fact that
728
GAS's input scrubber will remove extraneous blanks. */
729
if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
731
#ifdef CGEN_MNEMONIC_OPERANDS
732
if (CGEN_SYNTAX_CHAR(* syn) == ' ')
740
/* Syntax char didn't match. Can't be this insn. */
741
static char msg [80];
743
/* xgettext:c-format */
744
sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
745
CGEN_SYNTAX_CHAR(*syn), *str);
750
/* Ran out of input. */
751
static char msg [80];
753
/* xgettext:c-format */
754
sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
755
CGEN_SYNTAX_CHAR(*syn));
761
#ifdef CGEN_MNEMONIC_OPERANDS
762
(void) past_opcode_p;
764
/* We have an operand of some sort. */
765
errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
769
/* Done with this operand, continue with next one. */
773
/* If we're at the end of the syntax string, we're done. */
776
/* FIXME: For the moment we assume a valid `str' can only contain
777
blanks now. IE: We needn't try again with a longer version of
778
the insn and it is assumed that longer versions of insns appear
779
before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
780
while (ISSPACE (* str))
784
return _("junk at end of line"); /* FIXME: would like to include `str' */
789
/* We couldn't parse it. */
790
return _("unrecognized instruction");
794
This routine is called for each instruction to be assembled.
795
STR points to the insn to be assembled.
796
We assume all necessary tables have been initialized.
797
The assembled instruction, less any fixups, is stored in BUF.
798
Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
799
still needs to be converted to target byte order, otherwise BUF is an array
800
of bytes in target byte order.
801
The result is a pointer to the insn's entry in the opcode table,
802
or NULL if an error occured (an error message will have already been
805
Note that when processing (non-alias) macro-insns,
806
this function recurses.
808
??? It's possible to make this cpu-independent.
809
One would have to deal with a few minor things.
810
At this point in time doing so would be more of a curiosity than useful
811
[for example this file isn't _that_ big], but keeping the possibility in
812
mind helps keep the design clean. */
815
ip2k_cgen_assemble_insn (CGEN_CPU_DESC cd,
818
CGEN_INSN_BYTES_PTR buf,
822
CGEN_INSN_LIST *ilist;
823
const char *parse_errmsg = NULL;
824
const char *insert_errmsg = NULL;
825
int recognized_mnemonic = 0;
827
/* Skip leading white space. */
828
while (ISSPACE (* str))
831
/* The instructions are stored in hashed lists.
832
Get the first in the list. */
833
ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
835
/* Keep looking until we find a match. */
837
for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
839
const CGEN_INSN *insn = ilist->insn;
840
recognized_mnemonic = 1;
842
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
843
/* Not usually needed as unsupported opcodes
844
shouldn't be in the hash lists. */
845
/* Is this insn supported by the selected cpu? */
846
if (! ip2k_cgen_insn_supported (cd, insn))
849
/* If the RELAXED attribute is set, this is an insn that shouldn't be
850
chosen immediately. Instead, it is used during assembler/linker
851
relaxation if possible. */
852
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
857
/* Skip this insn if str doesn't look right lexically. */
858
if (CGEN_INSN_RX (insn) != NULL &&
859
regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
862
/* Allow parse/insert handlers to obtain length of insn. */
863
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
865
parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
866
if (parse_errmsg != NULL)
869
/* ??? 0 is passed for `pc'. */
870
insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
872
if (insert_errmsg != NULL)
875
/* It is up to the caller to actually output the insn and any
881
static char errbuf[150];
882
const char *tmp_errmsg;
883
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
891
/* If requesting verbose error messages, use insert_errmsg.
892
Failing that, use parse_errmsg. */
893
tmp_errmsg = (insert_errmsg ? insert_errmsg :
894
parse_errmsg ? parse_errmsg :
895
recognized_mnemonic ?
896
_("unrecognized form of instruction") :
897
_("unrecognized instruction"));
899
if (strlen (start) > 50)
900
/* xgettext:c-format */
901
sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
903
/* xgettext:c-format */
904
sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
908
if (strlen (start) > 50)
909
/* xgettext:c-format */
910
sprintf (errbuf, _("bad instruction `%.50s...'"), start);
912
/* xgettext:c-format */
913
sprintf (errbuf, _("bad instruction `%.50s'"), start);