Add support for DragonFlyBSD target.
[binutils.git] / gas / config / tc-crx.c
blobb347d8b828a16d582aed192daea37b8af38e7b0a
1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
5 Contributed by Tomer Levi, NSC, Israel.
6 Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
7 Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
9 This file is part of GAS, the GNU Assembler.
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
14 any later version.
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the
23 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
26 #include "as.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "opcode/crx.h"
30 #include "elf/crx.h"
32 /* Word is considered here as a 16-bit unsigned short int. */
33 #define WORD_SHIFT 16
35 /* Register is 4-bit size. */
36 #define REG_SIZE 4
38 /* Maximum size of a single instruction (in words). */
39 #define INSN_MAX_SIZE 3
41 /* Maximum bits which may be set in a `mask16' operand. */
42 #define MAX_REGS_IN_MASK16 8
44 /* Utility macros for string comparison. */
45 #define streq(a, b) (strcmp (a, b) == 0)
46 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
48 /* Assign a number NUM, shifted by SHIFT bytes, into a location
49 pointed by index BYTE of array 'output_opcode'. */
50 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
52 /* Operand errors. */
53 typedef enum
55 OP_LEGAL = 0, /* Legal operand. */
56 OP_OUT_OF_RANGE, /* Operand not within permitted range. */
57 OP_NOT_EVEN, /* Operand is Odd number, should be even. */
58 OP_ILLEGAL_DISPU4, /* Operand is not within DISPU4 range. */
59 OP_ILLEGAL_CST4, /* Operand is not within CST4 range. */
60 OP_NOT_UPPER_64KB /* Operand is not within the upper 64KB
61 (0xFFFF0000-0xFFFFFFFF). */
63 op_err;
65 /* Opcode mnemonics hash table. */
66 static struct hash_control *crx_inst_hash;
67 /* CRX registers hash table. */
68 static struct hash_control *reg_hash;
69 /* CRX coprocessor registers hash table. */
70 static struct hash_control *copreg_hash;
71 /* Current instruction we're assembling. */
72 const inst *instruction;
74 /* Global variables. */
76 /* Array to hold an instruction encoding. */
77 long output_opcode[2];
79 /* Nonzero means a relocatable symbol. */
80 int relocatable;
82 /* A copy of the original instruction (used in error messages). */
83 char ins_parse[MAX_INST_LEN];
85 /* The current processed argument number. */
86 int cur_arg_num;
88 /* Generic assembler global variables which must be defined by all targets. */
90 /* Characters which always start a comment. */
91 const char comment_chars[] = "#";
93 /* Characters which start a comment at the beginning of a line. */
94 const char line_comment_chars[] = "#";
96 /* This array holds machine specific line separator characters. */
97 const char line_separator_chars[] = ";";
99 /* Chars that can be used to separate mant from exp in floating point nums. */
100 const char EXP_CHARS[] = "eE";
102 /* Chars that mean this number is a floating point constant as in 0f12.456 */
103 const char FLT_CHARS[] = "f'";
105 /* Target-specific multicharacter options, not const-declared at usage. */
106 const char *md_shortopts = "";
107 struct option md_longopts[] =
109 {NULL, no_argument, NULL, 0}
111 size_t md_longopts_size = sizeof (md_longopts);
113 /* This table describes all the machine specific pseudo-ops
114 the assembler has to support. The fields are:
115 *** Pseudo-op name without dot.
116 *** Function to call to execute this pseudo-op.
117 *** Integer arg to pass to the function. */
119 const pseudo_typeS md_pseudo_table[] =
121 /* In CRX machine, align is in bytes (not a ptwo boundary). */
122 {"align", s_align_bytes, 0},
123 {0, 0, 0}
126 /* CRX relaxation table. */
127 const relax_typeS md_relax_table[] =
129 /* bCC */
130 {0xfa, -0x100, 2, 1}, /* 8 */
131 {0xfffe, -0x10000, 4, 2}, /* 16 */
132 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
134 /* bal */
135 {0xfffe, -0x10000, 4, 4}, /* 16 */
136 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
138 /* cmpbr/bcop */
139 {0xfe, -0x100, 4, 6}, /* 8 */
140 {0xfffffe, -0x1000000, 6, 0} /* 24 */
143 static void reset_vars (char *);
144 static reg get_register (char *);
145 static copreg get_copregister (char *);
146 static argtype get_optype (operand_type);
147 static int get_opbits (operand_type);
148 static int get_opflags (operand_type);
149 static int get_number_of_operands (void);
150 static void parse_operand (char *, ins *);
151 static int gettrap (const char *);
152 static void handle_LoadStor (const char *);
153 static int get_cinv_parameters (const char *);
154 static long getconstant (long, int);
155 static op_err check_range (long *, int, unsigned int, int);
156 static int getreg_image (reg);
157 static void parse_operands (ins *, char *);
158 static void parse_insn (ins *, char *);
159 static void print_operand (int, int, argument *);
160 static void print_constant (int, int, argument *);
161 static int exponent2scale (int);
162 static void mask_reg (int, unsigned short *);
163 static void process_label_constant (char *, ins *);
164 static void set_operand (char *, ins *);
165 static char * preprocess_reglist (char *, int *);
166 static int assemble_insn (char *, ins *);
167 static void print_insn (ins *);
168 static void warn_if_needed (ins *);
169 static int adjust_if_needed (ins *);
171 /* Return the bit size for a given operand. */
173 static int
174 get_opbits (operand_type op)
176 if (op < MAX_OPRD)
177 return crx_optab[op].bit_size;
178 else
179 return 0;
182 /* Return the argument type of a given operand. */
184 static argtype
185 get_optype (operand_type op)
187 if (op < MAX_OPRD)
188 return crx_optab[op].arg_type;
189 else
190 return nullargs;
193 /* Return the flags of a given operand. */
195 static int
196 get_opflags (operand_type op)
198 if (op < MAX_OPRD)
199 return crx_optab[op].flags;
200 else
201 return 0;
204 /* Get the core processor register 'reg_name'. */
206 static reg
207 get_register (char *reg_name)
209 const reg_entry *rreg;
211 rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
213 if (rreg != NULL)
214 return rreg->value.reg_val;
215 else
216 return nullregister;
219 /* Get the coprocessor register 'copreg_name'. */
221 static copreg
222 get_copregister (char *copreg_name)
224 const reg_entry *coreg;
226 coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
228 if (coreg != NULL)
229 return coreg->value.copreg_val;
230 else
231 return nullcopregister;
234 /* Round up a section size to the appropriate boundary. */
236 valueT
237 md_section_align (segT seg, valueT val)
239 /* Round .text section to a multiple of 2. */
240 if (seg == text_section)
241 return (val + 1) & ~1;
242 return val;
245 /* Parse an operand that is machine-specific (remove '*'). */
247 void
248 md_operand (expressionS * exp)
250 char c = *input_line_pointer;
252 switch (c)
254 case '*':
255 input_line_pointer++;
256 expression (exp);
257 break;
258 default:
259 break;
263 /* Reset global variables before parsing a new instruction. */
265 static void
266 reset_vars (char *op)
268 cur_arg_num = relocatable = 0;
269 memset (& output_opcode, '\0', sizeof (output_opcode));
271 /* Save a copy of the original OP (used in error messages). */
272 strncpy (ins_parse, op, sizeof ins_parse - 1);
273 ins_parse [sizeof ins_parse - 1] = 0;
276 /* This macro decides whether a particular reloc is an entry in a
277 switch table. It is used when relaxing, because the linker needs
278 to know about all such entries so that it can adjust them if
279 necessary. */
281 #define SWITCH_TABLE(fix) \
282 ( (fix)->fx_addsy != NULL \
283 && (fix)->fx_subsy != NULL \
284 && S_GET_SEGMENT ((fix)->fx_addsy) == \
285 S_GET_SEGMENT ((fix)->fx_subsy) \
286 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
287 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
288 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
289 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
291 /* See whether we need to force a relocation into the output file.
292 This is used to force out switch and PC relative relocations when
293 relaxing. */
296 crx_force_relocation (fixS *fix)
298 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
299 return 1;
301 return 0;
304 /* Generate a relocation entry for a fixup. */
306 arelent *
307 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
309 arelent * reloc;
311 reloc = xmalloc (sizeof (arelent));
312 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
313 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
314 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
315 reloc->addend = fixP->fx_offset;
317 if (fixP->fx_subsy != NULL)
319 if (SWITCH_TABLE (fixP))
321 /* Keep the current difference in the addend. */
322 reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
323 - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
325 switch (fixP->fx_r_type)
327 case BFD_RELOC_CRX_NUM8:
328 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
329 break;
330 case BFD_RELOC_CRX_NUM16:
331 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
332 break;
333 case BFD_RELOC_CRX_NUM32:
334 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
335 break;
336 default:
337 abort ();
338 break;
341 else
343 /* We only resolve difference expressions in the same section. */
344 as_bad_where (fixP->fx_file, fixP->fx_line,
345 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
346 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
347 segment_name (fixP->fx_addsy
348 ? S_GET_SEGMENT (fixP->fx_addsy)
349 : absolute_section),
350 S_GET_NAME (fixP->fx_subsy),
351 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
355 gas_assert ((int) fixP->fx_r_type > 0);
356 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
358 if (reloc->howto == (reloc_howto_type *) NULL)
360 as_bad_where (fixP->fx_file, fixP->fx_line,
361 _("internal error: reloc %d (`%s') not supported by object file format"),
362 fixP->fx_r_type,
363 bfd_get_reloc_code_name (fixP->fx_r_type));
364 return NULL;
366 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
368 return reloc;
371 /* Prepare machine-dependent frags for relaxation. */
374 md_estimate_size_before_relax (fragS *fragp, asection *seg)
376 /* If symbol is undefined or located in a different section,
377 select the largest supported relocation. */
378 relax_substateT subtype;
379 relax_substateT rlx_state[] = {0, 2,
380 3, 4,
381 5, 6};
383 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
385 if (fragp->fr_subtype == rlx_state[subtype]
386 && (!S_IS_DEFINED (fragp->fr_symbol)
387 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
389 fragp->fr_subtype = rlx_state[subtype + 1];
390 break;
394 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
395 abort ();
397 return md_relax_table[fragp->fr_subtype].rlx_length;
400 void
401 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
403 /* 'opcode' points to the start of the instruction, whether
404 we need to change the instruction's fixed encoding. */
405 char *opcode = fragP->fr_literal + fragP->fr_fix;
406 bfd_reloc_code_real_type reloc;
408 subseg_change (sec, 0);
410 switch (fragP->fr_subtype)
412 case 0:
413 reloc = BFD_RELOC_CRX_REL8;
414 break;
415 case 1:
416 *opcode = 0x7e;
417 reloc = BFD_RELOC_CRX_REL16;
418 break;
419 case 2:
420 *opcode = 0x7f;
421 reloc = BFD_RELOC_CRX_REL32;
422 break;
423 case 3:
424 reloc = BFD_RELOC_CRX_REL16;
425 break;
426 case 4:
427 *++opcode = 0x31;
428 reloc = BFD_RELOC_CRX_REL32;
429 break;
430 case 5:
431 reloc = BFD_RELOC_CRX_REL8_CMP;
432 break;
433 case 6:
434 *++opcode = 0x31;
435 reloc = BFD_RELOC_CRX_REL24;
436 break;
437 default:
438 abort ();
439 break;
442 fix_new (fragP, fragP->fr_fix,
443 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
444 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
445 fragP->fr_var = 0;
446 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
449 /* Process machine-dependent command line options. Called once for
450 each option on the command line that the machine-independent part of
451 GAS does not understand. */
454 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
456 return 0;
459 /* Machine-dependent usage-output. */
461 void
462 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
464 return;
467 char *
468 md_atof (int type, char *litP, int *sizeP)
470 return ieee_md_atof (type, litP, sizeP, target_big_endian);
473 /* Apply a fixS (fixup of an instruction or data that we didn't have
474 enough info to complete immediately) to the data in a frag.
475 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
476 relaxation of debug sections, this function is called only when
477 fixuping relocations of debug sections. */
479 void
480 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
482 valueT val = * valP;
483 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
484 fixP->fx_offset = 0;
486 switch (fixP->fx_r_type)
488 case BFD_RELOC_CRX_NUM8:
489 bfd_put_8 (stdoutput, (unsigned char) val, buf);
490 break;
491 case BFD_RELOC_CRX_NUM16:
492 bfd_put_16 (stdoutput, val, buf);
493 break;
494 case BFD_RELOC_CRX_NUM32:
495 bfd_put_32 (stdoutput, val, buf);
496 break;
497 default:
498 /* We shouldn't ever get here because linkrelax is nonzero. */
499 abort ();
500 break;
503 fixP->fx_done = 0;
505 if (fixP->fx_addsy == NULL
506 && fixP->fx_pcrel == 0)
507 fixP->fx_done = 1;
509 if (fixP->fx_pcrel == 1
510 && fixP->fx_addsy != NULL
511 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
512 fixP->fx_done = 1;
515 /* The location from which a PC relative jump should be calculated,
516 given a PC relative reloc. */
518 long
519 md_pcrel_from (fixS *fixp)
521 return fixp->fx_frag->fr_address + fixp->fx_where;
524 /* This function is called once, at assembler startup time. This should
525 set up all the tables, etc that the MD part of the assembler needs. */
527 void
528 md_begin (void)
530 const char *hashret = NULL;
531 int i = 0;
533 /* Set up a hash table for the instructions. */
534 if ((crx_inst_hash = hash_new ()) == NULL)
535 as_fatal (_("Virtual memory exhausted"));
537 while (crx_instruction[i].mnemonic != NULL)
539 const char *mnemonic = crx_instruction[i].mnemonic;
541 hashret = hash_insert (crx_inst_hash, mnemonic,
542 (void *) &crx_instruction[i]);
544 if (hashret != NULL && *hashret != '\0')
545 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
546 *hashret == 0 ? _("(unknown reason)") : hashret);
548 /* Insert unique names into hash table. The CRX instruction set
549 has many identical opcode names that have different opcodes based
550 on the operands. This hash table then provides a quick index to
551 the first opcode with a particular name in the opcode table. */
554 ++i;
556 while (crx_instruction[i].mnemonic != NULL
557 && streq (crx_instruction[i].mnemonic, mnemonic));
560 /* Initialize reg_hash hash table. */
561 if ((reg_hash = hash_new ()) == NULL)
562 as_fatal (_("Virtual memory exhausted"));
565 const reg_entry *regtab;
567 for (regtab = crx_regtab;
568 regtab < (crx_regtab + NUMREGS); regtab++)
570 hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
571 if (hashret)
572 as_fatal (_("Internal Error: Can't hash %s: %s"),
573 regtab->name,
574 hashret);
578 /* Initialize copreg_hash hash table. */
579 if ((copreg_hash = hash_new ()) == NULL)
580 as_fatal (_("Virtual memory exhausted"));
583 const reg_entry *copregtab;
585 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
586 copregtab++)
588 hashret = hash_insert (copreg_hash, copregtab->name,
589 (void *) copregtab);
590 if (hashret)
591 as_fatal (_("Internal Error: Can't hash %s: %s"),
592 copregtab->name,
593 hashret);
596 /* Set linkrelax here to avoid fixups in most sections. */
597 linkrelax = 1;
600 /* Process constants (immediate/absolute)
601 and labels (jump targets/Memory locations). */
603 static void
604 process_label_constant (char *str, ins * crx_ins)
606 char *saved_input_line_pointer;
607 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
609 saved_input_line_pointer = input_line_pointer;
610 input_line_pointer = str;
612 expression (&crx_ins->exp);
614 switch (crx_ins->exp.X_op)
616 case O_big:
617 case O_absent:
618 /* Missing or bad expr becomes absolute 0. */
619 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
620 str);
621 crx_ins->exp.X_op = O_constant;
622 crx_ins->exp.X_add_number = 0;
623 crx_ins->exp.X_add_symbol = (symbolS *) 0;
624 crx_ins->exp.X_op_symbol = (symbolS *) 0;
625 /* Fall through. */
627 case O_constant:
628 cur_arg->X_op = O_constant;
629 cur_arg->constant = crx_ins->exp.X_add_number;
630 break;
632 case O_symbol:
633 case O_subtract:
634 case O_add:
635 cur_arg->X_op = O_symbol;
636 crx_ins->rtype = BFD_RELOC_NONE;
637 relocatable = 1;
639 switch (cur_arg->type)
641 case arg_cr:
642 if (IS_INSN_TYPE (LD_STOR_INS_INC))
643 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
644 else if (IS_INSN_TYPE (CSTBIT_INS)
645 || IS_INSN_TYPE (STOR_IMM_INS))
646 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
647 else
648 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
649 break;
651 case arg_idxr:
652 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
653 break;
655 case arg_c:
656 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
657 crx_ins->rtype = BFD_RELOC_CRX_REL16;
658 else if (IS_INSN_TYPE (BRANCH_INS))
659 crx_ins->rtype = BFD_RELOC_CRX_REL8;
660 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
661 || IS_INSN_TYPE (CSTBIT_INS))
662 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
663 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
664 crx_ins->rtype = BFD_RELOC_CRX_REL4;
665 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
666 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
667 break;
669 case arg_ic:
670 if (IS_INSN_TYPE (ARITH_INS))
671 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
672 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
673 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
674 break;
675 default:
676 break;
678 break;
680 default:
681 cur_arg->X_op = crx_ins->exp.X_op;
682 break;
685 input_line_pointer = saved_input_line_pointer;
686 return;
689 /* Get the values of the scale to be encoded -
690 used for the scaled index mode of addressing. */
692 static int
693 exponent2scale (int val)
695 int exponent;
697 /* If 'val' is 0, the following 'for' will be an endless loop. */
698 if (val == 0)
699 return 0;
701 for (exponent = 0; (val != 1); val >>= 1, exponent++)
704 return exponent;
707 /* Parsing different types of operands
708 -> constants Immediate/Absolute/Relative numbers
709 -> Labels Relocatable symbols
710 -> (rbase) Register base
711 -> disp(rbase) Register relative
712 -> disp(rbase)+ Post-increment mode
713 -> disp(rbase,ridx,scl) Register index mode */
715 static void
716 set_operand (char *operand, ins * crx_ins)
718 char *operandS; /* Pointer to start of sub-opearand. */
719 char *operandE; /* Pointer to end of sub-opearand. */
720 expressionS scale;
721 int scale_val;
722 char *input_save, c;
723 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
725 /* Initialize pointers. */
726 operandS = operandE = operand;
728 switch (cur_arg->type)
730 case arg_sc: /* Case *+0x18. */
731 case arg_ic: /* Case $0x18. */
732 operandS++;
733 case arg_c: /* Case 0x18. */
734 /* Set constant. */
735 process_label_constant (operandS, crx_ins);
737 if (cur_arg->type != arg_ic)
738 cur_arg->type = arg_c;
739 break;
741 case arg_icr: /* Case $0x18(r1). */
742 operandS++;
743 case arg_cr: /* Case 0x18(r1). */
744 /* Set displacement constant. */
745 while (*operandE != '(')
746 operandE++;
747 *operandE = '\0';
748 process_label_constant (operandS, crx_ins);
749 operandS = operandE;
750 case arg_rbase: /* Case (r1). */
751 operandS++;
752 /* Set register base. */
753 while (*operandE != ')')
754 operandE++;
755 *operandE = '\0';
756 if ((cur_arg->r = get_register (operandS)) == nullregister)
757 as_bad (_("Illegal register `%s' in Instruction `%s'"),
758 operandS, ins_parse);
760 if (cur_arg->type != arg_rbase)
761 cur_arg->type = arg_cr;
762 break;
764 case arg_idxr:
765 /* Set displacement constant. */
766 while (*operandE != '(')
767 operandE++;
768 *operandE = '\0';
769 process_label_constant (operandS, crx_ins);
770 operandS = ++operandE;
772 /* Set register base. */
773 while ((*operandE != ',') && (! ISSPACE (*operandE)))
774 operandE++;
775 *operandE++ = '\0';
776 if ((cur_arg->r = get_register (operandS)) == nullregister)
777 as_bad (_("Illegal register `%s' in Instruction `%s'"),
778 operandS, ins_parse);
780 /* Skip leading white space. */
781 while (ISSPACE (*operandE))
782 operandE++;
783 operandS = operandE;
785 /* Set register index. */
786 while ((*operandE != ')') && (*operandE != ','))
787 operandE++;
788 c = *operandE;
789 *operandE++ = '\0';
791 if ((cur_arg->i_r = get_register (operandS)) == nullregister)
792 as_bad (_("Illegal register `%s' in Instruction `%s'"),
793 operandS, ins_parse);
795 /* Skip leading white space. */
796 while (ISSPACE (*operandE))
797 operandE++;
798 operandS = operandE;
800 /* Set the scale. */
801 if (c == ')')
802 cur_arg->scale = 0;
803 else
805 while (*operandE != ')')
806 operandE++;
807 *operandE = '\0';
809 /* Preprocess the scale string. */
810 input_save = input_line_pointer;
811 input_line_pointer = operandS;
812 expression (&scale);
813 input_line_pointer = input_save;
815 scale_val = scale.X_add_number;
817 /* Check if the scale value is legal. */
818 if (scale_val != 1 && scale_val != 2
819 && scale_val != 4 && scale_val != 8)
820 as_bad (_("Illegal Scale - `%d'"), scale_val);
822 cur_arg->scale = exponent2scale (scale_val);
824 break;
826 default:
827 break;
831 /* Parse a single operand.
832 operand - Current operand to parse.
833 crx_ins - Current assembled instruction. */
835 static void
836 parse_operand (char *operand, ins * crx_ins)
838 int ret_val;
839 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
841 /* Initialize the type to NULL before parsing. */
842 cur_arg->type = nullargs;
844 /* Check whether this is a general processor register. */
845 if ((ret_val = get_register (operand)) != nullregister)
847 cur_arg->type = arg_r;
848 cur_arg->r = ret_val;
849 cur_arg->X_op = O_register;
850 return;
853 /* Check whether this is a core [special] coprocessor register. */
854 if ((ret_val = get_copregister (operand)) != nullcopregister)
856 cur_arg->type = arg_copr;
857 if (ret_val >= cs0)
858 cur_arg->type = arg_copsr;
859 cur_arg->cr = ret_val;
860 cur_arg->X_op = O_register;
861 return;
864 /* Deal with special characters. */
865 switch (operand[0])
867 case '$':
868 if (strchr (operand, '(') != NULL)
869 cur_arg->type = arg_icr;
870 else
871 cur_arg->type = arg_ic;
872 goto set_params;
873 break;
875 case '*':
876 cur_arg->type = arg_sc;
877 goto set_params;
878 break;
880 case '(':
881 cur_arg->type = arg_rbase;
882 goto set_params;
883 break;
885 default:
886 break;
889 if (strchr (operand, '(') != NULL)
891 if (strchr (operand, ',') != NULL
892 && (strchr (operand, ',') > strchr (operand, '(')))
893 cur_arg->type = arg_idxr;
894 else
895 cur_arg->type = arg_cr;
897 else
898 cur_arg->type = arg_c;
899 goto set_params;
901 /* Parse an operand according to its type. */
902 set_params:
903 cur_arg->constant = 0;
904 set_operand (operand, crx_ins);
907 /* Parse the various operands. Each operand is then analyzed to fillup
908 the fields in the crx_ins data structure. */
910 static void
911 parse_operands (ins * crx_ins, char *operands)
913 char *operandS; /* Operands string. */
914 char *operandH, *operandT; /* Single operand head/tail pointers. */
915 int allocated = 0; /* Indicates a new operands string was allocated. */
916 char *operand[MAX_OPERANDS]; /* Separating the operands. */
917 int op_num = 0; /* Current operand number we are parsing. */
918 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
919 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
921 /* Preprocess the list of registers, if necessary. */
922 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
923 preprocess_reglist (operands, &allocated) : operands;
925 while (*operandT != '\0')
927 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
929 *operandT++ = '\0';
930 operand[op_num++] = strdup (operandH);
931 operandH = operandT;
932 continue;
935 if (*operandT == ' ')
936 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
938 if (*operandT == '(')
939 bracket_flag = 1;
940 else if (*operandT == '[')
941 sq_bracket_flag = 1;
943 if (*operandT == ')')
945 if (bracket_flag)
946 bracket_flag = 0;
947 else
948 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
950 else if (*operandT == ']')
952 if (sq_bracket_flag)
953 sq_bracket_flag = 0;
954 else
955 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
958 if (bracket_flag == 1 && *operandT == ')')
959 bracket_flag = 0;
960 else if (sq_bracket_flag == 1 && *operandT == ']')
961 sq_bracket_flag = 0;
963 operandT++;
966 /* Adding the last operand. */
967 operand[op_num++] = strdup (operandH);
968 crx_ins->nargs = op_num;
970 /* Verifying correct syntax of operands (all brackets should be closed). */
971 if (bracket_flag || sq_bracket_flag)
972 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
974 /* Now we parse each operand separately. */
975 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
977 cur_arg_num = op_num;
978 parse_operand (operand[op_num], crx_ins);
979 free (operand[op_num]);
982 if (allocated)
983 free (operandS);
986 /* Get the trap index in dispatch table, given its name.
987 This routine is used by assembling the 'excp' instruction. */
989 static int
990 gettrap (const char *s)
992 const trap_entry *trap;
994 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
995 if (strcasecmp (trap->name, s) == 0)
996 return trap->entry;
998 as_bad (_("Unknown exception: `%s'"), s);
999 return 0;
1002 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1003 sub-group within load/stor instruction groups.
1004 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1005 advance the instruction pointer to the start of that sub-group (that is, up
1006 to the first instruction of that type).
1007 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1009 static void
1010 handle_LoadStor (const char *operands)
1012 /* Post-Increment instructions precede Store-Immediate instructions in
1013 CRX instruction table, hence they are handled before.
1014 This synchronization should be kept. */
1016 /* Assuming Post-Increment insn has the following format :
1017 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1018 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1019 if (strstr (operands, ")+") != NULL)
1021 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1022 instruction++;
1023 return;
1026 /* Assuming Store-Immediate insn has the following format :
1027 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1028 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1029 if (strstr (operands, "$") != NULL)
1030 while (! IS_INSN_TYPE (STOR_IMM_INS))
1031 instruction++;
1034 /* Top level module where instruction parsing starts.
1035 crx_ins - data structure holds some information.
1036 operands - holds the operands part of the whole instruction. */
1038 static void
1039 parse_insn (ins *insn, char *operands)
1041 int i;
1043 /* Handle instructions with no operands. */
1044 for (i = 0; no_op_insn[i] != NULL; i++)
1046 if (streq (no_op_insn[i], instruction->mnemonic))
1048 insn->nargs = 0;
1049 return;
1053 /* Handle 'excp'/'cinv' instructions. */
1054 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1056 insn->nargs = 1;
1057 insn->arg[0].type = arg_ic;
1058 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1059 gettrap (operands) : get_cinv_parameters (operands);
1060 insn->arg[0].X_op = O_constant;
1061 return;
1064 /* Handle load/stor unique instructions before parsing. */
1065 if (IS_INSN_TYPE (LD_STOR_INS))
1066 handle_LoadStor (operands);
1068 if (operands != NULL)
1069 parse_operands (insn, operands);
1072 /* Cinv instruction requires special handling. */
1074 static int
1075 get_cinv_parameters (const char *operand)
1077 const char *p = operand;
1078 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1080 while (*++p != ']')
1082 if (*p == ',' || *p == ' ')
1083 continue;
1085 if (*p == 'd')
1086 d_used = 1;
1087 else if (*p == 'i')
1088 i_used = 1;
1089 else if (*p == 'u')
1090 u_used = 1;
1091 else if (*p == 'b')
1092 b_used = 1;
1093 else
1094 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1097 return ((b_used ? 8 : 0)
1098 + (d_used ? 4 : 0)
1099 + (i_used ? 2 : 0)
1100 + (u_used ? 1 : 0));
1103 /* Retrieve the opcode image of a given register.
1104 If the register is illegal for the current instruction,
1105 issue an error. */
1107 static int
1108 getreg_image (reg r)
1110 const reg_entry *rreg;
1111 char *reg_name;
1112 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1114 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1115 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1116 is_procreg = 1;
1118 /* Check whether the register is in registers table. */
1119 if (r < MAX_REG)
1120 rreg = &crx_regtab[r];
1121 /* Check whether the register is in coprocessor registers table. */
1122 else if (r < (int) MAX_COPREG)
1123 rreg = &crx_copregtab[r-MAX_REG];
1124 /* Register not found. */
1125 else
1127 as_bad (_("Unknown register: `%d'"), r);
1128 return 0;
1131 reg_name = rreg->name;
1133 /* Issue a error message when register is illegal. */
1134 #define IMAGE_ERR \
1135 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1136 reg_name, ins_parse); \
1137 break;
1139 switch (rreg->type)
1141 case CRX_U_REGTYPE:
1142 if (is_procreg || (instruction->flags & USER_REG))
1143 return rreg->image;
1144 else
1145 IMAGE_ERR;
1147 case CRX_CFG_REGTYPE:
1148 if (is_procreg)
1149 return rreg->image;
1150 else
1151 IMAGE_ERR;
1153 case CRX_R_REGTYPE:
1154 if (! is_procreg)
1155 return rreg->image;
1156 else
1157 IMAGE_ERR;
1159 case CRX_C_REGTYPE:
1160 case CRX_CS_REGTYPE:
1161 return rreg->image;
1162 break;
1164 default:
1165 IMAGE_ERR;
1168 return 0;
1171 /* Routine used to represent integer X using NBITS bits. */
1173 static long
1174 getconstant (long x, int nbits)
1176 /* The following expression avoids overflow if
1177 'nbits' is the number of bits in 'bfd_vma'. */
1178 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1181 /* Print a constant value to 'output_opcode':
1182 ARG holds the operand's type and value.
1183 SHIFT represents the location of the operand to be print into.
1184 NBITS determines the size (in bits) of the constant. */
1186 static void
1187 print_constant (int nbits, int shift, argument *arg)
1189 unsigned long mask = 0;
1191 long constant = getconstant (arg->constant, nbits);
1193 switch (nbits)
1195 case 32:
1196 case 28:
1197 case 24:
1198 case 22:
1199 /* mask the upper part of the constant, that is, the bits
1200 going to the lowest byte of output_opcode[0].
1201 The upper part of output_opcode[1] is always filled,
1202 therefore it is always masked with 0xFFFF. */
1203 mask = (1 << (nbits - 16)) - 1;
1204 /* Divide the constant between two consecutive words :
1205 0 1 2 3
1206 +---------+---------+---------+---------+
1207 | | X X X X | X X X X | |
1208 +---------+---------+---------+---------+
1209 output_opcode[0] output_opcode[1] */
1211 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1212 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1213 break;
1215 case 16:
1216 case 12:
1217 /* Special case - in arg_cr, the SHIFT represents the location
1218 of the REGISTER, not the constant, which is itself not shifted. */
1219 if (arg->type == arg_cr)
1221 CRX_PRINT (0, constant, 0);
1222 break;
1225 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1226 always filling the upper part of output_opcode[1]. If we mistakenly
1227 write it to output_opcode[0], the constant prefix (that is, 'match')
1228 will be overridden.
1229 0 1 2 3
1230 +---------+---------+---------+---------+
1231 | 'match' | | X X X X | |
1232 +---------+---------+---------+---------+
1233 output_opcode[0] output_opcode[1] */
1235 if ((instruction->size > 2) && (shift == WORD_SHIFT))
1236 CRX_PRINT (1, constant, WORD_SHIFT);
1237 else
1238 CRX_PRINT (0, constant, shift);
1239 break;
1241 default:
1242 CRX_PRINT (0, constant, shift);
1243 break;
1247 /* Print an operand to 'output_opcode', which later on will be
1248 printed to the object file:
1249 ARG holds the operand's type, size and value.
1250 SHIFT represents the printing location of operand.
1251 NBITS determines the size (in bits) of a constant operand. */
1253 static void
1254 print_operand (int nbits, int shift, argument *arg)
1256 switch (arg->type)
1258 case arg_r:
1259 CRX_PRINT (0, getreg_image (arg->r), shift);
1260 break;
1262 case arg_copr:
1263 if (arg->cr < c0 || arg->cr > c15)
1264 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1265 ins_parse);
1266 CRX_PRINT (0, getreg_image (arg->cr), shift);
1267 break;
1269 case arg_copsr:
1270 if (arg->cr < cs0 || arg->cr > cs15)
1271 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1272 ins_parse);
1273 CRX_PRINT (0, getreg_image (arg->cr), shift);
1274 break;
1276 case arg_idxr:
1277 /* 16 12 8 6 0
1278 +--------------------------------+
1279 | r_base | r_idx | scl| disp |
1280 +--------------------------------+ */
1281 CRX_PRINT (0, getreg_image (arg->r), 12);
1282 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1283 CRX_PRINT (0, arg->scale, 6);
1284 case arg_ic:
1285 case arg_c:
1286 print_constant (nbits, shift, arg);
1287 break;
1289 case arg_rbase:
1290 CRX_PRINT (0, getreg_image (arg->r), shift);
1291 break;
1293 case arg_cr:
1294 /* case base_cst4. */
1295 if (instruction->flags & DISPU4MAP)
1296 print_constant (nbits, shift + REG_SIZE, arg);
1297 else
1298 /* rbase_disps<NN> and other such cases. */
1299 print_constant (nbits, shift, arg);
1300 /* Add the register argument to the output_opcode. */
1301 CRX_PRINT (0, getreg_image (arg->r), shift);
1302 break;
1304 default:
1305 break;
1309 /* Retrieve the number of operands for the current assembled instruction. */
1311 static int
1312 get_number_of_operands (void)
1314 int i;
1316 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1318 return i;
1321 /* Verify that the number NUM can be represented in BITS bits (that is,
1322 within its permitted range), based on the instruction's FLAGS.
1323 If UPDATE is nonzero, update the value of NUM if necessary.
1324 Return OP_LEGAL upon success, actual error type upon failure. */
1326 static op_err
1327 check_range (long *num, int bits, int unsigned flags, int update)
1329 long min, max;
1330 int retval = OP_LEGAL;
1331 int bin;
1332 long upper_64kb = 0xFFFF0000;
1333 long value = *num;
1335 /* For hosts witah longs bigger than 32-bits make sure that the top
1336 bits of a 32-bit negative value read in by the parser are set,
1337 so that the correct comparisons are made. */
1338 if (value & 0x80000000)
1339 value |= (-1L << 31);
1341 /* Verify operand value is even. */
1342 if (flags & OP_EVEN)
1344 if (value % 2)
1345 return OP_NOT_EVEN;
1348 if (flags & OP_UPPER_64KB)
1350 /* Check if value is to be mapped to upper 64 KB memory area. */
1351 if ((value & upper_64kb) == upper_64kb)
1353 value -= upper_64kb;
1354 if (update)
1355 *num = value;
1357 else
1358 return OP_NOT_UPPER_64KB;
1361 if (flags & OP_SHIFT)
1363 value >>= 1;
1364 if (update)
1365 *num = value;
1367 else if (flags & OP_SHIFT_DEC)
1369 value = (value >> 1) - 1;
1370 if (update)
1371 *num = value;
1374 if (flags & OP_ESC)
1376 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1377 if (value == 0x7e || value == 0x7f)
1378 return OP_OUT_OF_RANGE;
1381 if (flags & OP_DISPU4)
1383 int is_dispu4 = 0;
1385 int mul = (instruction->flags & DISPUB4) ? 1
1386 : (instruction->flags & DISPUW4) ? 2
1387 : (instruction->flags & DISPUD4) ? 4 : 0;
1389 for (bin = 0; bin < cst4_maps; bin++)
1391 if (value == (mul * bin))
1393 is_dispu4 = 1;
1394 if (update)
1395 *num = bin;
1396 break;
1399 if (!is_dispu4)
1400 retval = OP_ILLEGAL_DISPU4;
1402 else if (flags & OP_CST4)
1404 int is_cst4 = 0;
1406 for (bin = 0; bin < cst4_maps; bin++)
1408 if (value == cst4_map[bin])
1410 is_cst4 = 1;
1411 if (update)
1412 *num = bin;
1413 break;
1416 if (!is_cst4)
1417 retval = OP_ILLEGAL_CST4;
1419 else if (flags & OP_SIGNED)
1421 max = (1 << (bits - 1)) - 1;
1422 min = - (1 << (bits - 1));
1423 if ((value > max) || (value < min))
1424 retval = OP_OUT_OF_RANGE;
1426 else if (flags & OP_UNSIGNED)
1428 max = ((((1 << (bits - 1)) - 1) << 1) | 1);
1429 min = 0;
1430 if (((unsigned long) value > (unsigned long) max)
1431 || ((unsigned long) value < (unsigned long) min))
1432 retval = OP_OUT_OF_RANGE;
1434 return retval;
1437 /* Assemble a single instruction:
1438 INSN is already parsed (that is, all operand values and types are set).
1439 For instruction to be assembled, we need to find an appropriate template in
1440 the instruction table, meeting the following conditions:
1441 1: Has the same number of operands.
1442 2: Has the same operand types.
1443 3: Each operand size is sufficient to represent the instruction's values.
1444 Returns 1 upon success, 0 upon failure. */
1446 static int
1447 assemble_insn (char *mnemonic, ins *insn)
1449 /* Type of each operand in the current template. */
1450 argtype cur_type[MAX_OPERANDS];
1451 /* Size (in bits) of each operand in the current template. */
1452 unsigned int cur_size[MAX_OPERANDS];
1453 /* Flags of each operand in the current template. */
1454 unsigned int cur_flags[MAX_OPERANDS];
1455 /* Instruction type to match. */
1456 unsigned int ins_type;
1457 /* Boolean flag to mark whether a match was found. */
1458 int match = 0;
1459 int i;
1460 /* Nonzero if an instruction with same number of operands was found. */
1461 int found_same_number_of_operands = 0;
1462 /* Nonzero if an instruction with same argument types was found. */
1463 int found_same_argument_types = 0;
1464 /* Nonzero if a constant was found within the required range. */
1465 int found_const_within_range = 0;
1466 /* Argument number of an operand with invalid type. */
1467 int invalid_optype = -1;
1468 /* Argument number of an operand with invalid constant value. */
1469 int invalid_const = -1;
1470 /* Operand error (used for issuing various constant error messages). */
1471 op_err op_error, const_err = OP_LEGAL;
1473 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1474 #define GET_CURRENT_DATA(FUNC, ARRAY) \
1475 for (i = 0; i < insn->nargs; i++) \
1476 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1478 #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1479 #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1480 #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1482 /* Instruction has no operands -> only copy the constant opcode. */
1483 if (insn->nargs == 0)
1485 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1486 return 1;
1489 /* In some case, same mnemonic can appear with different instruction types.
1490 For example, 'storb' is supported with 3 different types :
1491 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1492 We assume that when reaching this point, the instruction type was
1493 pre-determined. We need to make sure that the type stays the same
1494 during a search for matching instruction. */
1495 ins_type = CRX_INS_TYPE(instruction->flags);
1497 while (/* Check that match is still not found. */
1498 match != 1
1499 /* Check we didn't get to end of table. */
1500 && instruction->mnemonic != NULL
1501 /* Check that the actual mnemonic is still available. */
1502 && IS_INSN_MNEMONIC (mnemonic)
1503 /* Check that the instruction type wasn't changed. */
1504 && IS_INSN_TYPE(ins_type))
1506 /* Check whether number of arguments is legal. */
1507 if (get_number_of_operands () != insn->nargs)
1508 goto next_insn;
1509 found_same_number_of_operands = 1;
1511 /* Initialize arrays with data of each operand in current template. */
1512 GET_CURRENT_TYPE;
1513 GET_CURRENT_SIZE;
1514 GET_CURRENT_FLAGS;
1516 /* Check for type compatibility. */
1517 for (i = 0; i < insn->nargs; i++)
1519 if (cur_type[i] != insn->arg[i].type)
1521 if (invalid_optype == -1)
1522 invalid_optype = i + 1;
1523 goto next_insn;
1526 found_same_argument_types = 1;
1528 for (i = 0; i < insn->nargs; i++)
1530 /* Reverse the operand indices for certain opcodes:
1531 Index 0 -->> 1
1532 Index 1 -->> 0
1533 Other index -->> stays the same. */
1534 int j = instruction->flags & REVERSE_MATCH ?
1535 i == 0 ? 1 :
1536 i == 1 ? 0 : i :
1539 /* Only check range - don't update the constant's value, since the
1540 current instruction may not be the last we try to match.
1541 The constant's value will be updated later, right before printing
1542 it to the object file. */
1543 if ((insn->arg[j].X_op == O_constant)
1544 && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1545 cur_flags[j], 0)))
1547 if (invalid_const == -1)
1549 invalid_const = j + 1;
1550 const_err = op_error;
1552 goto next_insn;
1554 /* For symbols, we make sure the relocation size (which was already
1555 determined) is sufficient. */
1556 else if ((insn->arg[j].X_op == O_symbol)
1557 && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1558 > cur_size[j]))
1559 goto next_insn;
1561 found_const_within_range = 1;
1563 /* If we got till here -> Full match is found. */
1564 match = 1;
1565 break;
1567 /* Try again with next instruction. */
1568 next_insn:
1569 instruction++;
1572 if (!match)
1574 /* We haven't found a match - instruction can't be assembled. */
1575 if (!found_same_number_of_operands)
1576 as_bad (_("Incorrect number of operands"));
1577 else if (!found_same_argument_types)
1578 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1579 else if (!found_const_within_range)
1581 switch (const_err)
1583 case OP_OUT_OF_RANGE:
1584 as_bad (_("Operand out of range (arg %d)"), invalid_const);
1585 break;
1586 case OP_NOT_EVEN:
1587 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1588 break;
1589 case OP_ILLEGAL_DISPU4:
1590 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1591 break;
1592 case OP_ILLEGAL_CST4:
1593 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1594 break;
1595 case OP_NOT_UPPER_64KB:
1596 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1597 invalid_const);
1598 break;
1599 default:
1600 as_bad (_("Illegal operand (arg %d)"), invalid_const);
1601 break;
1605 return 0;
1607 else
1608 /* Full match - print the encoding to output file. */
1610 /* Make further checkings (such that couldn't be made earlier).
1611 Warn the user if necessary. */
1612 warn_if_needed (insn);
1614 /* Check whether we need to adjust the instruction pointer. */
1615 if (adjust_if_needed (insn))
1616 /* If instruction pointer was adjusted, we need to update
1617 the size of the current template operands. */
1618 GET_CURRENT_SIZE;
1620 for (i = 0; i < insn->nargs; i++)
1622 int j = instruction->flags & REVERSE_MATCH ?
1623 i == 0 ? 1 :
1624 i == 1 ? 0 : i :
1627 /* This time, update constant value before printing it. */
1628 if ((insn->arg[j].X_op == O_constant)
1629 && (check_range (&insn->arg[j].constant, cur_size[j],
1630 cur_flags[j], 1) != OP_LEGAL))
1631 as_fatal (_("Illegal operand (arg %d)"), j+1);
1634 /* First, copy the instruction's opcode. */
1635 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1637 for (i = 0; i < insn->nargs; i++)
1639 cur_arg_num = i;
1640 print_operand (cur_size[i], instruction->operands[i].shift,
1641 &insn->arg[i]);
1645 return 1;
1648 /* Bunch of error checkings.
1649 The checks are made after a matching instruction was found. */
1651 void
1652 warn_if_needed (ins *insn)
1654 /* If the post-increment address mode is used and the load/store
1655 source register is the same as rbase, the result of the
1656 instruction is undefined. */
1657 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1659 /* Enough to verify that one of the arguments is a simple reg. */
1660 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1661 if (insn->arg[0].r == insn->arg[1].r)
1662 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1663 insn->arg[0].r);
1666 /* Some instruction assume the stack pointer as rptr operand.
1667 Issue an error when the register to be loaded is also SP. */
1668 if (instruction->flags & NO_SP)
1670 if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1671 as_bad (_("`%s' has undefined result"), ins_parse);
1674 /* If the rptr register is specified as one of the registers to be loaded,
1675 the final contents of rptr are undefined. Thus, we issue an error. */
1676 if (instruction->flags & NO_RPTR)
1678 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1679 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1680 getreg_image (insn->arg[0].r));
1684 /* In some cases, we need to adjust the instruction pointer although a
1685 match was already found. Here, we gather all these cases.
1686 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1689 adjust_if_needed (ins *insn)
1691 int ret_value = 0;
1693 /* Special check for 'addub $0, r0' instruction -
1694 The opcode '0000 0000 0000 0000' is not allowed. */
1695 if (IS_INSN_MNEMONIC ("addub"))
1697 if ((instruction->operands[0].op_type == cst4)
1698 && instruction->operands[1].op_type == regr)
1700 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1702 instruction++;
1703 ret_value = 1;
1708 /* Optimization: Omit a zero displacement in bit operations,
1709 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1710 if (IS_INSN_TYPE (CSTBIT_INS))
1712 if ((instruction->operands[1].op_type == rbase_disps12)
1713 && (insn->arg[1].X_op == O_constant)
1714 && (insn->arg[1].constant == 0))
1716 instruction--;
1717 ret_value = 1;
1721 return ret_value;
1724 /* Set the appropriate bit for register 'r' in 'mask'.
1725 This indicates that this register is loaded or stored by
1726 the instruction. */
1728 static void
1729 mask_reg (int r, unsigned short int *mask)
1731 if ((reg)r > (reg)sp)
1733 as_bad (_("Invalid Register in Register List"));
1734 return;
1737 *mask |= (1 << r);
1740 /* Preprocess register list - create a 16-bit mask with one bit for each
1741 of the 16 general purpose registers. If a bit is set, it indicates
1742 that this register is loaded or stored by the instruction. */
1744 static char *
1745 preprocess_reglist (char *param, int *allocated)
1747 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
1748 char *regP; /* Pointer to 'reg_name' string. */
1749 int reg_counter = 0; /* Count number of parsed registers. */
1750 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
1751 char *new_param; /* New created operands string. */
1752 char *paramP = param; /* Pointer to original opearands string. */
1753 char maskstring[10]; /* Array to print the mask as a string. */
1754 int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
1755 reg r;
1756 copreg cr;
1758 /* If 'param' is already in form of a number, no need to preprocess. */
1759 if (strchr (paramP, '{') == NULL)
1760 return param;
1762 /* Verifying correct syntax of operand. */
1763 if (strchr (paramP, '}') == NULL)
1764 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1766 while (*paramP++ != '{');
1768 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1769 *allocated = 1;
1770 strncpy (new_param, param, paramP - param - 1);
1772 while (*paramP != '}')
1774 regP = paramP;
1775 memset (&reg_name, '\0', sizeof (reg_name));
1777 while (ISALNUM (*paramP))
1778 paramP++;
1780 strncpy (reg_name, regP, paramP - regP);
1782 /* Coprocessor register c<N>. */
1783 if (IS_INSN_TYPE (COP_REG_INS))
1785 if (((cr = get_copregister (reg_name)) == nullcopregister)
1786 || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1787 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1788 mask_reg (getreg_image (cr - c0), &mask);
1790 /* Coprocessor Special register cs<N>. */
1791 else if (IS_INSN_TYPE (COPS_REG_INS))
1793 if (((cr = get_copregister (reg_name)) == nullcopregister)
1794 || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1795 as_fatal (_("Illegal register `%s' in cop-special-register list"),
1796 reg_name);
1797 mask_reg (getreg_image (cr - cs0), &mask);
1799 /* User register u<N>. */
1800 else if (instruction->flags & USER_REG)
1802 if (streq(reg_name, "uhi"))
1804 hi_found = 1;
1805 goto next_inst;
1807 else if (streq(reg_name, "ulo"))
1809 lo_found = 1;
1810 goto next_inst;
1812 else if (((r = get_register (reg_name)) == nullregister)
1813 || (crx_regtab[r].type != CRX_U_REGTYPE))
1814 as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1816 mask_reg (getreg_image (r - u0), &mask);
1818 /* General purpose register r<N>. */
1819 else
1821 if (streq(reg_name, "hi"))
1823 hi_found = 1;
1824 goto next_inst;
1826 else if (streq(reg_name, "lo"))
1828 lo_found = 1;
1829 goto next_inst;
1831 else if (((r = get_register (reg_name)) == nullregister)
1832 || (crx_regtab[r].type != CRX_R_REGTYPE))
1833 as_fatal (_("Illegal register `%s' in register list"), reg_name);
1835 mask_reg (getreg_image (r - r0), &mask);
1838 if (++reg_counter > MAX_REGS_IN_MASK16)
1839 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1840 MAX_REGS_IN_MASK16);
1842 next_inst:
1843 while (!ISALNUM (*paramP) && *paramP != '}')
1844 paramP++;
1847 if (*++paramP != '\0')
1848 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1849 *paramP);
1851 switch (hi_found + lo_found)
1853 case 0:
1854 /* At least one register should be specified. */
1855 if (mask == 0)
1856 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1857 ins_parse);
1858 break;
1860 case 1:
1861 /* HI can't be specified without LO (and vise-versa). */
1862 as_bad (_("HI/LO registers should be specified together"));
1863 break;
1865 case 2:
1866 /* HI/LO registers mustn't be masked with additional registers. */
1867 if (mask != 0)
1868 as_bad (_("HI/LO registers should be specified without additional registers"));
1870 default:
1871 break;
1874 sprintf (maskstring, "$0x%x", mask);
1875 strcat (new_param, maskstring);
1876 return new_param;
1879 /* Print the instruction.
1880 Handle also cases where the instruction is relaxable/relocatable. */
1882 void
1883 print_insn (ins *insn)
1885 unsigned int i, j, insn_size;
1886 char *this_frag;
1887 unsigned short words[4];
1888 int addr_mod;
1890 /* Arrange the insn encodings in a WORD size array. */
1891 for (i = 0, j = 0; i < 2; i++)
1893 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1894 words[j++] = output_opcode[i] & 0xFFFF;
1897 /* Handle relaxtion. */
1898 if ((instruction->flags & RELAXABLE) && relocatable)
1900 int relax_subtype;
1902 /* Write the maximal instruction size supported. */
1903 insn_size = INSN_MAX_SIZE;
1905 /* bCC */
1906 if (IS_INSN_TYPE (BRANCH_INS))
1907 relax_subtype = 0;
1908 /* bal */
1909 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1910 relax_subtype = 3;
1911 /* cmpbr/bcop */
1912 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1913 relax_subtype = 5;
1914 else
1915 abort ();
1917 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1918 4, relax_subtype,
1919 insn->exp.X_add_symbol,
1920 insn->exp.X_add_number,
1923 else
1925 insn_size = instruction->size;
1926 this_frag = frag_more (insn_size * 2);
1928 /* Handle relocation. */
1929 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1931 reloc_howto_type *reloc_howto;
1932 int size;
1934 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1936 if (!reloc_howto)
1937 abort ();
1939 size = bfd_get_reloc_size (reloc_howto);
1941 if (size < 1 || size > 4)
1942 abort ();
1944 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1945 size, &insn->exp, reloc_howto->pc_relative,
1946 insn->rtype);
1950 /* Verify a 2-byte code alignment. */
1951 addr_mod = frag_now_fix () & 1;
1952 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1953 as_bad (_("instruction address is not a multiple of 2"));
1954 frag_now->insn_addr = addr_mod;
1955 frag_now->has_code = 1;
1957 /* Write the instruction encoding to frag. */
1958 for (i = 0; i < insn_size; i++)
1960 md_number_to_chars (this_frag, (valueT) words[i], 2);
1961 this_frag += 2;
1965 /* This is the guts of the machine-dependent assembler. OP points to a
1966 machine dependent instruction. This function is supposed to emit
1967 the frags/bytes it assembles to. */
1969 void
1970 md_assemble (char *op)
1972 ins crx_ins;
1973 char *param;
1974 char c;
1976 /* Reset global variables for a new instruction. */
1977 reset_vars (op);
1979 /* Strip the mnemonic. */
1980 for (param = op; *param != 0 && !ISSPACE (*param); param++)
1982 c = *param;
1983 *param++ = '\0';
1985 /* Find the instruction. */
1986 instruction = (const inst *) hash_find (crx_inst_hash, op);
1987 if (instruction == NULL)
1989 as_bad (_("Unknown opcode: `%s'"), op);
1990 param[-1] = c;
1991 return;
1994 /* Tie dwarf2 debug info to the address at the start of the insn. */
1995 dwarf2_emit_insn (0);
1997 /* Parse the instruction's operands. */
1998 parse_insn (&crx_ins, param);
2000 /* Assemble the instruction - return upon failure. */
2001 if (assemble_insn (op, &crx_ins) == 0)
2003 param[-1] = c;
2004 return;
2007 /* Print the instruction. */
2008 param[-1] = c;
2009 print_insn (&crx_ins);