1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright 2004 Free Software Foundation, Inc.
4 Contributed by Tomer Levi, NSC, Israel.
5 Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
6 Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the
22 Free Software Foundation, 59 Temple Place - Suite 330, Boston,
23 MA 02111-1307, USA. */
26 #include "safe-ctype.h"
27 #include "dwarf2dbg.h"
28 #include "opcode/crx.h"
33 /* Word is considered here as a 16-bit unsigned short int. */
37 /* Register is 4-bit size. */
40 /* Maximum size of a single instruction (in words). */
41 #define INSN_MAX_SIZE 3
43 /* Maximum bits which may be set in a `mask16' operand. */
44 #define MAX_REGS_IN_MASK16 8
46 /* Escape to 16-bit immediate. */
48 /* Escape to 32-bit immediate. */
51 /* Utility macros for string comparison. */
52 #define streq(a, b) (strcmp (a, b) == 0)
53 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
55 /* A mask to set n_bits starting from offset offs. */
56 #define SET_BITS_MASK(offs,n_bits) ((((1 << (n_bits)) - 1) << (offs)))
57 /* A mask to clear n_bits starting from offset offs. */
58 #define CLEAR_BITS_MASK(offs,n_bits) (~(((1 << (n_bits)) - 1) << (offs)))
60 /* Get the argument type for each operand of a given instruction. */
61 #define GET_ACTUAL_TYPE \
62 for (i = 0; i < insn->nargs; i++) \
63 atyp_act[i] = getarg_type (instruction->operands[i].op_type)
65 /* Get the size (in bits) for each operand of a given instruction. */
66 #define GET_ACTUAL_SIZE \
67 for (i = 0; i < insn->nargs; i++) \
68 bits_act[i] = getbits (instruction->operands[i].op_type)
70 /* Non-zero if OP is instruction with no operands. */
71 #define NO_OPERANDS_INST(OP) \
72 (streq (OP, "di") || streq (OP, "nop") \
73 || streq (OP, "retx") || streq (OP, "ei") \
74 || streq (OP, "wait") || streq (OP, "eiwait"))
76 /* Print a number NUM, shifted by SHIFT bytes, into a location
77 pointed by index BYTE of array 'output_opcode'. */
78 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
80 /* Opcode mnemonics hash table. */
81 static struct hash_control *crx_inst_hash;
82 /* CRX registers hash table. */
83 static struct hash_control *reg_hash;
84 /* CRX coprocessor registers hash table. */
85 static struct hash_control *copreg_hash;
86 /* Current instruction we're assembling. */
87 const inst *instruction;
89 /* Initialize global variables. */
90 long output_opcode[2];
91 /* Nonzero means a relocatable symbol. */
93 /* Nonzero means a constant's bit-size was already set. */
95 /* Nonzero means a negative constant. */
97 /* Nonzero means a CST4 instruction. */
99 /* A copy of the original instruction (used in error messages). */
100 char ins_parse[MAX_INST_LEN];
101 /* Nonzero means instruction is represented in post increment mode. */
103 /* Holds the current processed argument number. */
104 int processing_arg_number;
106 /* Generic assembler global variables which must be defined by all targets. */
108 /* Characters which always start a comment. */
109 const char comment_chars[] = "#";
111 /* Characters which start a comment at the beginning of a line. */
112 const char line_comment_chars[] = "#";
114 /* This array holds machine specific line separator characters. */
115 const char line_separator_chars[] = ";";
117 /* Chars that can be used to separate mant from exp in floating point nums. */
118 const char EXP_CHARS[] = "eE";
120 /* Chars that mean this number is a floating point constant as in 0f12.456 */
121 const char FLT_CHARS[] = "f'";
123 /* Target-specific multicharacter options, not const-declared at usage. */
124 const char *md_shortopts = "";
125 struct option md_longopts[] =
127 {NULL, no_argument, NULL, 0}
129 size_t md_longopts_size = sizeof (md_longopts);
131 /* This table describes all the machine specific pseudo-ops
132 the assembler has to support. The fields are:
133 *** Pseudo-op name without dot.
134 *** Function to call to execute this pseudo-op.
135 *** Integer arg to pass to the function. */
137 const pseudo_typeS md_pseudo_table[] =
139 /* In CRX machine, align is in bytes (not a ptwo boundary). */
140 {"align", s_align_bytes, 0},
144 const relax_typeS md_relax_table[] =
147 {0xfa, -0x100, 2, 1}, /* 8 */
148 {0xfffe, -0x10000, 4, 2}, /* 16 */
149 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
152 {0xfffe, -0x10000, 4, 4}, /* 16 */
153 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
156 {0xfe, -0x100, 4, 6}, /* 8 */
157 {0xfffffe, -0x1000000, 6, 0} /* 24 */
160 static void reset_vars (char *, ins *);
161 static reg get_register (char *);
162 static copreg get_copregister (char *);
163 static void get_number_of_bits (ins *, int);
164 static argtype getarg_type (operand_type);
165 static int getbits (operand_type);
166 static int get_number_of_operands (void);
167 static void get_operandtype (char *, int, ins *);
168 static int gettrap (char *);
169 static void handle_LoadStor (char *);
170 static int get_cinv_parameters (char *);
171 static unsigned long getconstant (unsigned long, int);
172 static int getreg_image (reg);
173 static void parse_operands (ins *, char *);
174 static void parse_insn (ins *, char *);
175 static void print_operand (int, int, argument *);
176 static void print_constant (int, int, argument *);
177 static int exponent2scale (int);
178 static void mask_const (unsigned long *, int);
179 static void mask_reg (int, unsigned short *);
180 static int process_label_constant (char *, ins *, int);
181 static void set_indexmode_parameters (char *, ins *, int);
182 static void set_cons_rparams (char *, ins *, int);
183 static char * preprocess_reglist (char *, int *);
184 static int assemble_insn (char *, ins *);
185 static void print_insn (ins *);
187 /* Return the bit size for a given operand. */
190 getbits (operand_type op)
193 return crx_optab[op].bit_size;
198 /* Return the argument type of a given operand. */
201 getarg_type (operand_type op)
204 return crx_optab[op].arg_type;
209 /* Get the core processor register 'reg_name'. */
212 get_register (char *reg_name)
214 const reg_entry *reg;
216 reg = (const reg_entry *) hash_find (reg_hash, reg_name);
219 return reg->value.reg_val;
224 /* Get the coprocessor register 'copreg_name'. */
227 get_copregister (char *copreg_name)
229 const reg_entry *copreg;
231 copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
234 return copreg->value.copreg_val;
236 return nullcopregister;
239 /* Mask a constant to the number of bits it is to be mapped to. */
242 mask_const (unsigned long int *t, int size)
244 *t &= (((LONGLONG)1 << size) - 1);
247 /* Round up a section size to the appropriate boundary. */
250 md_section_align (segT seg, valueT val)
252 /* Round .text section to a multiple of 2. */
253 if (seg == text_section)
254 return (val + 1) & ~1;
258 /* Parse an operand that is machine-specific (remove '*'). */
261 md_operand (expressionS * exp)
263 char c = *input_line_pointer;
268 input_line_pointer++;
276 /* Reset global variables before parsing a new instruction. */
279 reset_vars (char *op, ins *crx_ins)
283 processing_arg_number = relocatable = size_was_set
284 = signflag = post_inc_mode = cst4flag = 0;
285 memset (& output_opcode, '\0', sizeof (output_opcode));
287 /* Memset the 'signflag' field in every argument. */
288 for (i = 0; i < MAX_OPERANDS; i++)
289 crx_ins->arg[i].signflag = 0;
291 /* Save a copy of the original OP (used in error messages). */
292 strcpy (ins_parse, op);
295 /* This macro decides whether a particular reloc is an entry in a
296 switch table. It is used when relaxing, because the linker needs
297 to know about all such entries so that it can adjust them if
300 #define SWITCH_TABLE(fix) \
301 ( (fix)->fx_addsy != NULL \
302 && (fix)->fx_subsy != NULL \
303 && S_GET_SEGMENT ((fix)->fx_addsy) == \
304 S_GET_SEGMENT ((fix)->fx_subsy) \
305 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
306 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
307 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
308 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
310 /* See whether we need to force a relocation into the output file.
311 This is used to force out switch and PC relative relocations when
315 crx_force_relocation (fixS *fix)
317 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
323 /* Generate a relocation entry for a fixup. */
326 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
330 reloc = xmalloc (sizeof (arelent));
331 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
332 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
333 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
334 reloc->addend = fixP->fx_offset;
336 if (fixP->fx_subsy != NULL)
338 if (SWITCH_TABLE (fixP))
340 /* Keep the current difference in the addend. */
341 reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
342 - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
344 switch (fixP->fx_r_type)
346 case BFD_RELOC_CRX_NUM8:
347 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
349 case BFD_RELOC_CRX_NUM16:
350 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
352 case BFD_RELOC_CRX_NUM32:
353 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
362 /* We only resolve difference expressions in the same section. */
363 as_bad_where (fixP->fx_file, fixP->fx_line,
364 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
365 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
366 segment_name (fixP->fx_addsy
367 ? S_GET_SEGMENT (fixP->fx_addsy)
369 S_GET_NAME (fixP->fx_subsy),
370 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
374 assert ((int) fixP->fx_r_type > 0);
375 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
377 if (reloc->howto == (reloc_howto_type *) NULL)
379 as_bad_where (fixP->fx_file, fixP->fx_line,
380 _("internal error: reloc %d (`%s') not supported by object file format"),
382 bfd_get_reloc_code_name (fixP->fx_r_type));
385 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
390 /* Prepare machine-dependent frags for relaxation. */
393 md_estimate_size_before_relax (fragS *fragp, asection *seg)
395 /* If symbol is undefined or located in a different section,
396 select the largest supported relocation. */
397 relax_substateT subtype;
398 relax_substateT rlx_state[] = {0, 2,
402 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
404 if (fragp->fr_subtype == rlx_state[subtype]
405 && (!S_IS_DEFINED (fragp->fr_symbol)
406 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
408 fragp->fr_subtype = rlx_state[subtype + 1];
413 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
416 return md_relax_table[fragp->fr_subtype].rlx_length;
420 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
422 /* 'opcode' points to the start of the instruction, whether
423 we need to change the instruction's fixed encoding. */
424 char *opcode = fragP->fr_literal + fragP->fr_fix;
425 bfd_reloc_code_real_type reloc;
427 subseg_change (sec, 0);
429 switch (fragP->fr_subtype)
432 reloc = BFD_RELOC_CRX_REL8;
436 reloc = BFD_RELOC_CRX_REL16;
440 reloc = BFD_RELOC_CRX_REL32;
443 reloc = BFD_RELOC_CRX_REL16;
447 reloc = BFD_RELOC_CRX_REL32;
450 reloc = BFD_RELOC_CRX_REL8_CMP;
454 reloc = BFD_RELOC_CRX_REL24;
461 fix_new (fragP, fragP->fr_fix,
462 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
463 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
465 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
468 /* Process machine-dependent command line options. Called once for
469 each option on the command line that the machine-independent part of
470 GAS does not understand. */
473 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
478 /* Machine-dependent usage-output. */
481 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
486 /* Turn a string in input_line_pointer into a floating point constant
487 of type TYPE, and store the appropriate bytes in *LITP. The number
488 of LITTLENUMS emitted is stored in *SIZEP. An error message is
489 returned, or NULL on OK. */
492 md_atof (int type, char *litP, int *sizeP)
495 LITTLENUM_TYPE words[4];
511 return _("bad call to md_atof");
514 t = atof_ieee (input_line_pointer, type, words);
516 input_line_pointer = t;
520 if (! target_big_endian)
522 for (i = prec - 1; i >= 0; i--)
524 md_number_to_chars (litP, (valueT) words[i], 2);
530 for (i = 0; i < prec; i++)
532 md_number_to_chars (litP, (valueT) words[i], 2);
540 /* Apply a fixS (fixup of an instruction or data that we didn't have
541 enough info to complete immediately) to the data in a frag.
542 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
543 relaxation of debug sections, this function is called only when
544 fixuping relocations of debug sections. */
547 md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
550 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
553 switch (fixP->fx_r_type)
555 case BFD_RELOC_CRX_NUM8:
556 bfd_put_8 (stdoutput, (unsigned char) val, buf);
558 case BFD_RELOC_CRX_NUM16:
559 bfd_put_16 (stdoutput, val, buf);
561 case BFD_RELOC_CRX_NUM32:
562 bfd_put_32 (stdoutput, val, buf);
565 /* We shouldn't ever get here because linkrelax is nonzero. */
572 if (fixP->fx_addsy == NULL
573 && fixP->fx_pcrel == 0)
576 if (fixP->fx_pcrel == 1
577 && fixP->fx_addsy != NULL
578 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
582 /* The location from which a PC relative jump should be calculated,
583 given a PC relative reloc. */
586 md_pcrel_from (fixS *fixp)
588 return fixp->fx_frag->fr_address + fixp->fx_where;
591 /* This function is called once, at assembler startup time. This should
592 set up all the tables, etc that the MD part of the assembler needs. */
597 const char *hashret = NULL;
600 /* Set up a hash table for the instructions. */
601 crx_inst_hash = hash_new ();
602 if (crx_inst_hash == NULL)
603 as_fatal (_("Virtual memory exhausted"));
605 while (crx_instruction[i].mnemonic != NULL)
607 const char *mnemonic = crx_instruction[i].mnemonic;
609 hashret = hash_insert (crx_inst_hash, mnemonic,
610 (PTR) &crx_instruction[i]);
612 if (hashret != NULL && *hashret != '\0')
613 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
614 *hashret == 0 ? _("(unknown reason)") : hashret);
616 /* Insert unique names into hash table. The CRX instruction set
617 has many identical opcode names that have different opcodes based
618 on the operands. This hash table then provides a quick index to
619 the first opcode with a particular name in the opcode table. */
624 while (crx_instruction[i].mnemonic != NULL
625 && streq (crx_instruction[i].mnemonic, mnemonic));
628 /* Initialize reg_hash hash table. */
629 reg_hash = hash_new ();
632 const reg_entry *regtab;
634 for (regtab = crx_regtab;
635 regtab < (crx_regtab + NUMREGS); regtab++)
637 hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
639 as_fatal (_("Internal Error: Can't hash %s: %s"),
645 /* Initialize copreg_hash hash table. */
646 copreg_hash = hash_new ();
649 const reg_entry *copregtab;
651 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
654 hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
656 as_fatal (_("Internal Error: Can't hash %s: %s"),
661 /* Set linkrelax here to avoid fixups in most sections. */
665 /* Get the number of bits corresponding to a constant -
666 here we check for possible overflow cases. */
669 get_number_of_bits (ins * crx_ins, int op_num)
672 unsigned long int temp = crx_ins->arg[op_num].constant;
673 const cst4_entry *cst4_op;
675 /* If the constant's size was already set - nothing to do. */
679 /* Already dealt with negative numbers in process_label_constants. */
686 if (IS_INSN_TYPE (ARITH_INS) && !relocatable && !signflag)
690 crx_ins->arg[op_num].size = 17;
694 /* If a signed +ve is represented in 6 bits then we have to represent
695 it in 22 bits in case of the index mode of addressing. */
696 if (IS_INSN_TYPE (LD_STOR_INS)
697 || IS_INSN_TYPE (LD_STOR_INS_INC)
698 || IS_INSN_TYPE (STOR_IMM_INS)
699 || IS_INSN_TYPE (CSTBIT_INS))
701 if (!signflag && crx_ins->arg[op_num].type == arg_icr)
705 crx_ins->arg[op_num].size = 7;
709 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
712 /* If a signed +ve is represnted in 16 bits in case of load/stor disp16
713 then change it to 17 bits.
714 If a signed +ve is represnted in 12 bits in post increment instruction
715 increase it to 13 bits. */
716 if (IS_INSN_TYPE (LD_STOR_INS))
718 if (!signflag && crx_ins->arg[op_num].type == arg_cr)
722 crx_ins->arg[op_num].size = 17;
726 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
730 if (IS_INSN_TYPE (CSTBIT_INS)
731 || IS_INSN_TYPE (LD_STOR_INS_INC)
732 || IS_INSN_TYPE (STOR_IMM_INS))
734 if (!signflag && crx_ins->arg[op_num].type == arg_cr)
738 crx_ins->arg[op_num].size = 13;
739 if (IS_INSN_TYPE (LD_STOR_INS_INC))
740 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
743 if (IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS))
746 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
752 /* Handle negative cst4 mapping for arithmetic/cmp&br operations. */
753 if (signflag && !relocatable
754 && ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
755 || ((IS_INSN_TYPE (CMPBR_INS) && op_num == 0))))
757 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
759 if (crx_ins->arg[op_num].constant == (unsigned int)(-cst4_op->value))
761 crx_ins->arg[op_num].size = 4;
762 crx_ins->arg[op_num].constant = cst4_op->binary;
763 crx_ins->arg[op_num].signflag = 0;
768 /* Because of the cst4 mapping -- -1 and -4 already handled above
769 as well as for relocatable cases. */
770 if (signflag && IS_INSN_TYPE (ARITH_BYTE_INS))
774 if (crx_ins->arg[op_num].constant <= 0xffff)
775 crx_ins->arg[op_num].size = 16;
777 /* Setting to 18 so that there is no match. */
778 crx_ins->arg[op_num].size = 18;
781 crx_ins->arg[op_num].size = 16;
785 if (signflag && IS_INSN_TYPE (ARITH_INS))
787 /* For all immediates which can be expressed in less than 16 bits. */
788 if (crx_ins->arg[op_num].constant <= 0xffff && !relocatable)
790 crx_ins->arg[op_num].size = 16;
793 /* Either it is relocatable or not representable in 16 bits. */
794 if (crx_ins->arg[op_num].constant < 0xffffffff || relocatable)
796 crx_ins->arg[op_num].size = 32;
799 crx_ins->arg[op_num].size = 33;
802 if (signflag && !relocatable)
806 crx_ins->arg[op_num].size = cnt_bits;
808 /* Checking for Error Conditions. */
809 if (IS_INSN_TYPE (ARITH_INS) && !signflag)
812 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
813 cnt_bits, ins_parse);
815 else if (IS_INSN_TYPE (ARITH_BYTE_INS) && !signflag)
818 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
819 cnt_bits, ins_parse);
823 /* Handle the constants -immediate/absolute values and
824 Labels (jump targets/Memory locations). */
827 process_label_constant (char *str, ins * crx_ins, int number)
830 unsigned long int temp, cnt;
831 const cst4_entry *cst4_op;
833 int constant_val = 0;
834 int cmp_br_type_flag = 0, i;
835 int br_type_flag = 0;
836 save = input_line_pointer;
844 else if (str[0] == '+')
847 /* Preprocessing for cmpbr instruction and getting the size flag. */
848 if (strstr (str, ":s") != NULL && (IS_INSN_TYPE (CMPBR_INS)
849 || IS_INSN_TYPE (COP_BRANCH_INS)))
850 cmp_br_type_flag = 8;
852 if (strstr (str, ":l") != NULL && (IS_INSN_TYPE (CMPBR_INS)
853 || IS_INSN_TYPE (COP_BRANCH_INS)))
854 cmp_br_type_flag = 24;
856 /* Branch instruction preprocessing. */
857 if (IS_INSN_TYPE (BRANCH_INS))
859 if (strstr (str, ":s") != NULL)
861 else if (strstr (str, ":m") != NULL)
863 else if (strstr (str, ":l") != NULL)
866 /* Making the label cleared for processing removing :lms etc from labels. */
867 if (cmp_br_type_flag != 0 || br_type_flag != 0)
870 while (str[i] != ':')
876 input_line_pointer = str;
878 expression (&crx_ins->exp);
880 switch (crx_ins->exp.X_op)
884 /* Missing or bad expr becomes absolute 0. */
885 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
887 crx_ins->exp.X_op = O_constant;
888 crx_ins->exp.X_add_number = 0;
889 crx_ins->exp.X_add_symbol = (symbolS *) 0;
890 crx_ins->exp.X_op_symbol = (symbolS *) 0;
894 crx_ins->arg[number].constant = crx_ins->exp.X_add_number;
895 constant_val = crx_ins->exp.X_add_number;
896 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
902 unsigned int jump_value = 0;
903 int BR_MASK = 0, BR_SIZE = 0;
910 strncat (temp_str, str, strlen (str));
911 temp64 = strtoll (temp_str, (char **) &ptr,0);
914 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
917 /* Determine the branch size. */
918 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
919 if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
920 || ((jump_value & 0xFFFFFF00) == 0x0))
926 if (((jump_value & 0xFF000000) == 0xFF000000)
927 || ((jump_value & 0xFF000000) == 0x0))
932 jump_value = jump_value >> 1;
933 crx_ins->arg[number].constant = jump_value & BR_MASK;
934 crx_ins->arg[number].size = BR_SIZE;
936 crx_ins->arg[number].signflag = signflag;
937 input_line_pointer = save;
938 return crx_ins->exp.X_op;
941 if (IS_INSN_TYPE (BRANCH_INS)
942 || IS_INSN_MNEMONIC ("bal")
943 || IS_INSN_TYPE (DCR_BRANCH_INS))
948 unsigned int jump_value = 0;
949 int BR_MASK = 0, BR_SIZE = 0;
957 strncat (temp_str, str, strlen (str));
958 temp64 = strtoll (temp_str, (char **) &ptr,0);
961 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
964 /* Determine the branch size. */
965 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
966 if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
967 && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
968 || ((jump_value & 0xFFFFFF00) == 0x0)))
973 else if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
974 || ((jump_value & 0xFFFF0000) == 0x0))
981 BR_MASK = 0xFFFFFFFF;
984 jump_value = jump_value >> 1;
985 crx_ins->arg[number].constant = jump_value & BR_MASK;
986 crx_ins->arg[number].size = BR_SIZE;
988 crx_ins->arg[number].signflag = signflag;
989 input_line_pointer = save;
990 return crx_ins->exp.X_op;
992 /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
993 if (constant_val < 0 && signflag != 1
994 && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
995 && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
996 && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
998 crx_ins->arg[number].constant =
999 ~(crx_ins->arg[number].constant) + 1;
1002 /* For load/store instruction when the value is in the offset part. */
1003 if (constant_val < 0 && signflag != 1
1004 && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
1005 || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
1007 if (crx_ins->arg[number].type == arg_cr
1008 || crx_ins->arg[number].type == arg_icr)
1010 crx_ins->arg[number].constant =
1011 ~(crx_ins->arg[number].constant) + 1;
1017 /* Signflag in never set in case of load store instructions
1018 Mapping in case of only the arithinsn case. */
1019 if ((crx_ins->arg[number].constant != 1
1020 && crx_ins->arg[number].constant != 4)
1021 || (!IS_INSN_TYPE (ARITH_INS)
1022 && !IS_INSN_TYPE (ARITH_BYTE_INS)
1023 && !IS_INSN_TYPE (CMPBR_INS)))
1025 /* Counting the number of bits required to represent
1028 temp = crx_ins->arg[number].constant - 1;
1034 crx_ins->arg[number].size = cnt + 1;
1035 crx_ins->arg[number].constant =
1036 ~(crx_ins->arg[number].constant) + 1;
1037 if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
1042 temp64 = strtoull (str, (char **) &ptr, 0);
1044 crx_ins->arg[number].size = 5;
1046 if (IS_INSN_TYPE (ARITH_INS))
1048 if (crx_ins->arg[number].size > 32
1049 || (temp64 > ULONG_MAX))
1051 if (crx_ins->arg[number].size > 32)
1052 as_bad (_("In Instruction `%s': Immediate size is \
1053 %lu bits cannot be accomodated"),
1054 ins_parse, cnt + 1);
1056 if (temp64 > ULONG_MAX)
1057 as_bad (_("Value given more than 32 bits in \
1058 Instruction `%s'"), ins_parse);
1061 if (IS_INSN_TYPE (ARITH_BYTE_INS))
1063 if (crx_ins->arg[number].size > 16
1064 || !((temp64 & 0xFFFF0000) == 0xFFFF0000
1065 || (temp64 & 0xFFFF0000) == 0x0))
1067 if (crx_ins->arg[number].size > 16)
1068 as_bad (_("In Instruction `%s': Immediate size is \
1069 %lu bits cannot be accomodated"),
1070 ins_parse, cnt + 1);
1072 if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
1073 || (temp64 & 0xFFFF0000) == 0x0))
1074 as_bad (_("Value given more than 16 bits in \
1075 Instruction `%s'"), ins_parse);
1079 if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr
1082 /* Cases handled ---
1083 dispub4/dispuw4/dispud4 and for load store dispubwd4
1084 is applicable only. */
1085 if (crx_ins->arg[number].size <= 4)
1086 crx_ins->arg[number].size = 5;
1088 /* Argument number is checked to distinguish between
1089 immediate and displacement in cmpbranch and bcopcond. */
1090 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1093 if (crx_ins->arg[number].size != 32)
1094 crx_ins->arg[number].constant =
1095 crx_ins->arg[number].constant >> 1;
1098 mask_const (&crx_ins->arg[number].constant,
1099 (int) crx_ins->arg[number].size);
1104 /* Argument number is checked to distinguish between
1105 immediate and displacement in cmpbranch and bcopcond. */
1106 if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1108 || IS_INSN_TYPE (BRANCH_NEQ_INS))
1110 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1112 if (crx_ins->arg[number].constant == 0)
1113 as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
1116 if (crx_ins->arg[number].constant % 2 != 0)
1117 as_bad (_("Instruction `%s' has odd offset"), ins_parse);
1119 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1121 if (crx_ins->arg[number].constant > 32
1122 || crx_ins->arg[number].constant < 2)
1123 as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1124 ins_parse, crx_ins->arg[number].constant);
1126 crx_ins->arg[number].constant -= 2;
1129 crx_ins->arg[number].constant =
1130 crx_ins->arg[number].constant >> 1;
1131 get_number_of_bits (crx_ins, number);
1134 /* Compare branch argument number zero to be compared -
1136 if (IS_INSN_TYPE (CMPBR_INS) && number == 0)
1138 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
1140 if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value)
1142 crx_ins->arg[number].constant = cst4_op->binary;
1148 as_bad (_("Instruction `%s' has invalid imm value as an \
1149 operand"), ins_parse);
1156 crx_ins->arg[number].constant = 0;
1157 crx_ins->rtype = BFD_RELOC_NONE;
1160 switch (crx_ins->arg[number].type)
1163 /* Have to consider various cases here --load/stor++[bwd] rbase, reg. */
1164 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1165 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
1166 else if (IS_INSN_TYPE (CSTBIT_INS)
1167 || IS_INSN_TYPE (STOR_IMM_INS))
1168 /* 'stor[bwd] imm' and '[stc]bit[bwd]'. */
1169 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
1171 /* General load store instruction. */
1172 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
1175 /* Index Mode 22 bits relocation. */
1176 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
1179 /* Absolute types. */
1180 /* Case for jumps...dx types. */
1182 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
1183 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1184 else if (IS_INSN_TYPE (BRANCH_INS))
1186 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1188 /* Overriding the above by the br_type_flag set above. */
1189 switch (br_type_flag)
1194 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1197 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1200 crx_ins->rtype = BFD_RELOC_CRX_REL32;
1204 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
1205 || IS_INSN_TYPE (CSTBIT_INS))
1206 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
1207 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1208 crx_ins->rtype = BFD_RELOC_CRX_REL4;
1209 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1211 if (cmp_br_type_flag == 24)
1212 crx_ins->rtype = BFD_RELOC_CRX_REL24;
1214 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1219 if (IS_INSN_TYPE (ARITH_INS))
1220 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
1221 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1222 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
1227 crx_ins->arg[number].size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
1234 input_line_pointer = save;
1235 crx_ins->arg[number].signflag = signflag;
1236 return crx_ins->exp.X_op;
1239 /* Get the values of the scale to be encoded -
1240 used for the scaled index mode of addressing. */
1243 exponent2scale (int val)
1247 /* If 'val' is 0, the following 'for' will be an endless loop. */
1251 for (exponent = 0; (val != 1); val >>= 1, exponent++)
1257 /* This is used to set the index mode parameters. Used to set the attributes of
1258 an indexmode type of operand. op_num is the operand number. */
1261 set_indexmode_parameters (char *operand, ins * crx_ins, int op_num)
1263 char address_str[30];
1264 char scale_str[MAX_OPERANDS];
1266 char reg_name[MAX_REGNAME_LEN];
1267 char regindex_name[MAX_REGNAME_LEN];
1269 int reg_counter = 0, addr_cnt = 0, temp_int_val = 0;
1271 switch (crx_ins->arg[op_num].type)
1274 while (operand[i] != '(')
1276 address_str[addr_cnt++] = operand[i];
1279 address_str[addr_cnt] = '\0';
1280 process_label_constant (address_str, crx_ins, op_num);
1283 while (operand[i] != ',' && operand[i] != ' ')
1285 reg_name[reg_counter++] = operand[i];
1288 reg_name[reg_counter] = '\0';
1289 if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1290 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1291 reg_name, ins_parse);
1294 while (operand[i] == ' ')
1298 while (operand[i] != ')' && operand[i] != ',')
1300 regindex_name[reg_counter++] = operand[i];
1303 regindex_name[reg_counter] = '\0';
1305 if ((crx_ins->arg[op_num].i_r = get_register (regindex_name))
1307 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1308 regindex_name, ins_parse);
1310 /* Setting the scale parameters. */
1311 while (operand[i] == ' ')
1314 if (operand[i] == ')')
1315 crx_ins->arg[op_num].scale = 0;
1318 if (operand[i] == ',')
1321 while (operand[i] != ' ' && operand[i] != ')')
1323 scale_str[scale_cnt++] = operand[i];
1327 scale_str[scale_cnt] = '\0';
1328 /* Preprocess the scale string. */
1329 if (strstr (scale_str, "0x") != NULL
1330 || strstr (scale_str, "0X") != NULL)
1332 sscanf (scale_str, "%x", &temp_int_val);
1333 memset (&scale_str, '\0', sizeof (scale_str));
1334 sprintf (scale_str, "%d", temp_int_val);
1336 /* Preprocess over. */
1337 temp_int_val = atoi (scale_str);
1339 if (temp_int_val != 1 && temp_int_val != 2
1340 && temp_int_val != 4 && temp_int_val != 8)
1341 as_bad (_("Illegal Scale - `%s'"), scale_str);
1343 crx_ins->arg[op_num].scale = exponent2scale (temp_int_val);
1351 /* Parsing the operands of types
1353 - rbase -> (register)
1355 - offset(rbase)+ - post increment mode. */
1358 set_cons_rparams (char *operand, ins * crx_ins, int op_num)
1360 int i = 0, reg_count = 0;
1361 char reg_name[MAX_REGNAME_LEN];
1362 int change_flag = 0;
1364 if (crx_ins->arg[op_num].type == arg_dc)
1367 switch (crx_ins->arg[op_num].type)
1369 case arg_sc: /* Case *+347. */
1370 case arg_dc: /* Case $18. */
1372 case arg_c:/* Case where its a simple constant. */
1373 process_label_constant (operand + i, crx_ins, op_num);
1374 crx_ins->arg[op_num].type = arg_c;
1376 case arg_dcr: /* Case $9(r13). */
1378 case arg_cr: /* Case 9(r13. */
1379 while (operand[i] != '(')
1382 process_label_constant (operand, crx_ins, op_num);
1386 while (operand[i] != ')')
1388 reg_name[reg_count] = operand[i];
1392 reg_name[reg_count] = '\0';
1393 if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1394 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1395 reg_name, ins_parse);
1397 crx_ins->arg[op_num].type = arg_cr;
1398 /* Post increment is represented in assembly as offset (register)+. */
1399 if (strstr (operand + i, "+") != NULL)
1400 /* There is a plus after the ')'. */
1406 if (change_flag == 1)
1407 crx_ins->arg[op_num].type = arg_ic;
1410 /* This is used to get the operand attributes -
1411 operand - current operand to be used
1412 number - operand number
1413 crx_ins - current assembled instruction. */
1416 get_operandtype (char *operand, int number, ins * crx_ins)
1419 char temp_operand[30];
1423 /* When it is a register. */
1432 /* Check whether this is a general processor register. */
1433 ret_val = get_register (operand);
1434 if (ret_val != nullregister)
1436 crx_ins->arg[number].type = arg_r;
1437 crx_ins->arg[number].r = ret_val;
1438 crx_ins->arg[number].size = REG_SIZE;
1442 /* Check whether this is a core [special] coprocessor register. */
1443 ret_val = get_copregister (operand);
1444 if (ret_val != nullcopregister)
1446 crx_ins->arg[number].type = arg_copr;
1448 crx_ins->arg[number].type = arg_copsr;
1449 crx_ins->arg[number].cr = ret_val;
1450 crx_ins->arg[number].size = REG_SIZE;
1454 if (strchr (operand, '(') != NULL)
1456 if (strchr (operand, ',') != NULL
1457 && (strchr (operand, ',') > strchr (operand, '(')))
1459 crx_ins->arg[number].type = arg_icr;
1460 crx_ins->arg[number].constant = 0;
1461 set_indexmode_parameters (operand, crx_ins, number);
1462 get_number_of_bits (crx_ins, number);
1466 crx_ins->arg[number].type = arg_cr;
1469 crx_ins->arg[number].type = arg_c;
1470 crx_ins->arg[number].constant = 0;
1471 set_cons_rparams (operand, crx_ins, number);
1472 get_number_of_bits (crx_ins, number);
1477 if (strchr (operand, '(') != NULL)
1478 crx_ins->arg[number].type = arg_dcr;
1480 crx_ins->arg[number].type = arg_dc;
1481 crx_ins->arg[number].constant = 0;
1482 set_cons_rparams (operand, crx_ins, number);
1483 get_number_of_bits (crx_ins, number);
1487 /* Augmenting a zero in front of an operand -- won't work for tbit/sbit. */
1488 strcpy (temp_operand, "0");
1489 strcat (temp_operand, operand);
1490 if (strchr (temp_operand, ',') != NULL
1491 && (strchr (temp_operand, ',') > strchr (temp_operand, '(')))
1493 crx_ins->arg[number].type = arg_icr;
1494 crx_ins->arg[number].constant = 0;
1495 set_indexmode_parameters (temp_operand, crx_ins, number);
1496 get_number_of_bits (crx_ins, number);
1501 crx_ins->arg[number].type = arg_cr;
1502 crx_ins->arg[number].constant = 0;
1503 set_cons_rparams (temp_operand, crx_ins, number);
1504 get_number_of_bits (crx_ins, number);
1505 if ((! strneq (instruction->mnemonic, "load", 4))
1506 && (! strneq (instruction->mnemonic, "stor", 4)))
1508 crx_ins->arg[number].type = arg_rbase;
1509 crx_ins->arg[number].size = REG_SIZE;
1515 crx_ins->arg[number].type = arg_sc;
1516 crx_ins->arg[number].constant = 0;
1517 set_cons_rparams (operand, crx_ins, number);
1518 get_number_of_bits (crx_ins, number);
1532 if (strchr (operand, '(') != NULL)
1534 if (strchr (operand, ',') != NULL
1535 && (strchr (operand, ',') > strchr (operand, '(')))
1537 crx_ins->arg[number].type = arg_icr;
1538 crx_ins->arg[number].constant = 0;
1539 set_indexmode_parameters (operand, crx_ins, number);
1540 get_number_of_bits (crx_ins, number);
1544 crx_ins->arg[number].type = arg_cr;
1547 crx_ins->arg[number].type = arg_c;
1548 crx_ins->arg[number].constant = 0;
1549 set_cons_rparams (operand, crx_ins, number);
1550 get_number_of_bits (crx_ins, number);
1553 if (strchr (operand, '(') != NULL)
1555 if (strchr (operand, ',') != NULL
1556 && (strchr (operand, ',') > strchr (operand, '(')))
1558 crx_ins->arg[number].type = arg_icr;
1559 crx_ins->arg[number].constant = 0;
1560 set_indexmode_parameters (operand, crx_ins, number);
1561 get_number_of_bits (crx_ins, number);
1565 crx_ins->arg[number].type = arg_cr;
1568 crx_ins->arg[number].type = arg_c;
1569 crx_ins->arg[number].constant = 0;
1570 set_cons_rparams (operand, crx_ins, number);
1571 get_number_of_bits (crx_ins, number);
1576 /* Operands are parsed over here, separated into various operands. Each operand
1577 is then analyzed to fillup the fields in the crx_ins data structure. */
1580 parse_operands (ins * crx_ins, char *operands)
1582 char *operandS; /* Operands string. */
1583 char *operandH, *operandT; /* Single operand head/tail pointers. */
1584 int allocated = 0; /* Indicates a new operands string was allocated. */
1585 char *operand[MAX_OPERANDS]; /* Separating the operands. */
1586 int op_num = 0; /* Current operand number we are parsing. */
1587 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
1588 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
1590 /* Preprocess the list of registers, if necessary. */
1591 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
1592 preprocess_reglist (operands, &allocated) : operands;
1594 while (*operandT != '\0')
1596 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1599 operand[op_num++] = strdup (operandH);
1600 operandH = operandT;
1604 if (*operandT == ' ')
1605 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1607 if (*operandT == '(')
1609 else if (*operandT == '[')
1610 sq_bracket_flag = 1;
1612 if (*operandT == ')')
1617 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1619 else if (*operandT == ']')
1621 if (sq_bracket_flag)
1622 sq_bracket_flag = 0;
1624 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1627 if (bracket_flag == 1 && *operandT == ')')
1629 else if (sq_bracket_flag == 1 && *operandT == ']')
1630 sq_bracket_flag = 0;
1635 /* Adding the last operand. */
1636 operand[op_num++] = strdup (operandH);
1637 crx_ins->nargs = op_num;
1639 /* Verifying correct syntax of operands (all brackets should be closed). */
1640 if (bracket_flag || sq_bracket_flag)
1641 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1643 /* Now to recongnize the operand types. */
1644 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1646 get_operandtype (operand[op_num], op_num, crx_ins);
1647 free (operand[op_num]);
1654 /* Get the trap index in dispatch table, given its name.
1655 This routine is used by assembling the 'excp' instruction. */
1660 const trap_entry *trap;
1662 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1663 if (strcasecmp (trap->name, s) == 0)
1666 as_bad (_("Unknown exception: `%s'"), s);
1670 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1671 sub-group within load/stor instruction groups.
1672 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1673 advance the instruction pointer to the start of that sub-group (that is, up
1674 to the first instruction of that type).
1675 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1678 handle_LoadStor (char *operands)
1680 /* Assuming Store-Immediate insn has the following format :
1681 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1682 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1683 if (strstr (operands, "$") != NULL)
1684 while (! IS_INSN_TYPE (STOR_IMM_INS))
1687 /* Assuming Post-Increment insn has the following format :
1688 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1689 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1690 if (strstr (operands, ")+") != NULL)
1691 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1695 /* Top level module where instruction parsing starts.
1696 crx_ins - data structure holds some information.
1697 operands - holds the operands part of the whole instruction. */
1700 parse_insn (ins *insn, char *operands)
1702 /* Handle 'excp'/'cinv' */
1703 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1706 insn->arg[0].type = arg_ic;
1707 insn->arg[0].size = 4;
1708 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1709 gettrap (operands) : get_cinv_parameters (operands);
1713 /* Handle load/stor unique instructions before parsing. */
1714 if (IS_INSN_TYPE (LD_STOR_INS))
1715 handle_LoadStor (operands);
1717 if (operands != NULL)
1718 parse_operands (insn, operands);
1721 /* Cinv instruction requires special handling. */
1724 get_cinv_parameters (char * operand)
1727 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1731 if (*p == ',' || *p == ' ')
1743 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1746 return ((b_used ? 8 : 0)
1749 + (u_used ? 1 : 0));
1752 /* Retrieve the opcode image of a given register.
1753 If the register is illegal for the current instruction,
1757 getreg_image (reg r)
1759 const reg_entry *reg;
1761 int special_register_flag = 0;
1762 int movpr_flag = 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1764 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1767 if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1))
1768 || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) )
1769 special_register_flag = 1;
1771 /* Check whether the register is in registers table. */
1773 reg = &crx_regtab[r];
1774 /* Check whether the register is in coprocessor registers table. */
1775 else if (r < MAX_COPREG)
1776 reg = &crx_copregtab[r-MAX_REG];
1777 /* Register not found. */
1780 as_bad (_("Unknown register: `%d'"), r);
1784 reg_name = reg->name;
1786 /* Issue a error message when register is illegal. */
1788 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1789 reg_name, ins_parse); \
1795 case CRX_CFG_REGTYPE:
1796 case CRX_MTPR_REGTYPE:
1797 if (movpr_flag && special_register_flag)
1804 case CRX_CS_REGTYPE:
1805 if (!(movpr_flag && special_register_flag))
1817 /* Routine used to get the binary-string equivalent of a integer constant
1818 which currently require currbits to represent itself to be extended to
1821 static unsigned long int
1822 getconstant (unsigned long int x, int nbits)
1825 unsigned long int temp = x;
1833 /* Escape sequence to next 16bit immediate. */
1835 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1840 x |= SET_BITS_MASK (cnt, nbits - cnt);
1842 x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1845 /* The following expression avoids overflow if
1846 'nbits' is the number of bits in 'bfd_vma'. */
1847 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1850 /* Print a constant value to 'output_opcode':
1851 ARG holds the operand's type and value.
1852 SHIFT represents the location of the operand to be print into.
1853 NBITS determines the size (in bits) of the constant. */
1856 print_constant (int nbits, int shift, argument *arg)
1858 unsigned long mask = 0;
1860 long constant = getconstant (arg->constant, nbits);
1868 /* mask the upper part of the constant, that is, the bits
1869 going to the lowest byte of output_opcode[0].
1870 The upper part of output_opcode[1] is always filled,
1871 therefore it is always masked with 0xFFFF. */
1872 mask = (1 << (nbits - 16)) - 1;
1873 /* Divide the constant between two consecutive words :
1875 +---------+---------+---------+---------+
1876 | | X X X X | X X X X | |
1877 +---------+---------+---------+---------+
1878 output_opcode[0] output_opcode[1] */
1880 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1881 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1886 /* Special case - in arg_cr, the SHIFT represents the location
1887 of the REGISTER, not the constant, which is itself not shifted. */
1888 if (arg->type == arg_cr)
1890 CRX_PRINT (0, constant, 0);
1894 /* When instruction size is 3, a 16-bit constant is always
1895 filling the upper part of output_opcode[1]. */
1896 if (instruction->size > 2)
1897 CRX_PRINT (1, constant, WORD_SHIFT);
1899 CRX_PRINT (0, constant, shift);
1903 CRX_PRINT (0, constant, shift);
1908 /* Print an operand to 'output_opcode', which later on will be
1909 printed to the object file:
1910 ARG holds the operand's type, size and value.
1911 SHIFT represents the printing location of operand.
1912 NBITS determines the size (in bits) of a constant operand. */
1915 print_operand (int nbits, int shift, argument *arg)
1920 CRX_PRINT (0, getreg_image (arg->r), shift);
1924 if (arg->cr < c0 || arg->cr > c15)
1925 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1927 CRX_PRINT (0, getreg_image (arg->cr), shift);
1931 if (arg->cr < cs0 || arg->cr > cs15)
1932 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1934 CRX_PRINT (0, getreg_image (arg->cr), shift);
1938 print_constant (nbits, shift, arg);
1943 +--------------------------------+
1944 | reg | r_base | scl| disp |
1945 +--------------------------------+ */
1946 CRX_PRINT (0, getreg_image (arg->r), 12);
1947 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1948 CRX_PRINT (0, arg->scale, 6);
1949 print_constant (nbits, shift, arg);
1953 CRX_PRINT (0, getreg_image (arg->r), shift);
1957 /* case base_cst4. */
1958 if ((instruction->flags & CST4MAP) && cst4flag)
1959 output_opcode[0] |= (getconstant (arg->constant, nbits)
1960 << (shift + REG_SIZE));
1962 /* rbase_dispu<NN> and other such cases. */
1963 print_constant (nbits, shift, arg);
1964 /* Add the register argument to the output_opcode. */
1965 CRX_PRINT (0, getreg_image (arg->r), shift);
1969 print_constant (nbits, shift, arg);
1977 /* Retrieve the number of operands for the current assembled instruction. */
1980 get_number_of_operands (void)
1984 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1989 /* Assemble a single instruction :
1990 Instruction has been parsed and all operand values set appropriately.
1991 Algorithm for assembling -
1992 For instruction to be assembled:
1993 Step 1: Find instruction in the array crx_instruction with same mnemonic.
1994 Step 2: Find instruction with same operand types.
1995 Step 3: If (size_of_operands) match then done, else increment the
1996 array_index and goto Step3.
1997 Step 4: Cannot assemble
1998 Returns 1 upon success, 0 upon failure. */
2001 assemble_insn (char *mnemonic, ins *insn)
2003 /* Argument type of each operand in the instruction we are looking for. */
2004 argtype atyp[MAX_OPERANDS];
2005 /* Argument type of each operand in the current instruction. */
2006 argtype atyp_act[MAX_OPERANDS];
2007 /* Size (in bits) of each operand in the instruction we are looking for. */
2008 int bits[MAX_OPERANDS];
2009 /* Size (in bits) of each operand in the current instruction. */
2010 int bits_act[MAX_OPERANDS];
2011 /* Location (in bits) of each operand in the current instruction. */
2012 int shift_act[MAX_OPERANDS];
2015 int cst4maptype = 0;
2016 int changed_already = 0;
2017 unsigned int temp_value = 0;
2019 /* A pointer to the argument's constant value. */
2020 unsigned long int *cons;
2021 /* Pointer to loop over all cst4_map entries. */
2022 const cst4_entry *cst4_op;
2024 /* Instruction has no operands -> copy only the constant opcode. */
2025 if (insn->nargs == 0)
2027 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2031 /* Find instruction with same number of operands. */
2032 while (get_number_of_operands () != insn->nargs
2033 && IS_INSN_MNEMONIC (mnemonic))
2036 if (!IS_INSN_MNEMONIC (mnemonic))
2039 /* Initialize argument type and size of each given operand. */
2040 for (i = 0; i < insn->nargs; i++)
2042 atyp[i] = insn->arg[i].type;
2043 bits[i] = insn->arg[i].size;
2046 /* Initialize argument type and size of each operand in current inst. */
2051 /* Check we didn't get to end of table. */
2052 && instruction->mnemonic != NULL
2053 /* Check that the actual mnemonic is still available. */
2054 && IS_INSN_MNEMONIC (mnemonic))
2056 /* Check for argement type compatibility. */
2057 for (i = 0; i < insn->nargs; i++)
2059 if (atyp_act[i] == atyp[i])
2069 /* Check for post inc mode of the current instruction. */
2070 if (post_inc_mode == 1 || IS_INSN_TYPE (LD_STOR_INS_INC))
2071 done_flag = (post_inc_mode == IS_INSN_TYPE (LD_STOR_INS_INC));
2076 /* Try again with next instruction. */
2084 /* Check for size compatibility. */
2085 for (i = 0; i < insn->nargs; i++)
2087 if (bits[i] > bits_act[i])
2089 /* Actual size is too small - try again. */
2102 /* Full match is found. */
2109 /* We haven't found a match - instruction can't be assembled. */
2112 /* Full match - print the final image. */
2114 /* Error checking for Co-Processor instructions :
2115 The internal coprocessor 0 can only accept the
2116 "mtcr" and "mfcr" instructions. */
2117 if (IS_INSN_TYPE (COP_REG_INS) || IS_INSN_TYPE (COPS_REG_INS)
2118 || IS_INSN_TYPE (COP_BRANCH_INS))
2120 /* The coprocessor id is always the first argument. */
2121 if ((instruction->operands[0].op_type == i4)
2122 && (insn->arg[0].constant == 0)
2123 && (! IS_INSN_MNEMONIC ("mtcr")
2124 && ! IS_INSN_MNEMONIC ("mfcr")))
2126 as_bad (_("Internal Coprocessor 0 doesn't support instruction `%s'"),
2130 /* Handle positive constants. */
2133 if (IS_INSN_TYPE (LD_STOR_INS) && !relocatable)
2135 /* Get the map type of the instruction. */
2136 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2137 cons = &insn->arg[instrtype].constant;
2138 cst4maptype = instruction->flags & CST4MAP;
2140 switch (cst4maptype)
2143 /* 14 and 15 are reserved escape sequences of dispub4. */
2144 if (*cons == 14 || *cons == 15)
2152 /* Mapping has to be done. */
2153 if (*cons <= 15 && *cons % 2 != 0)
2158 else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2163 if (*cons < 27 && *cons % 2 == 0)
2168 /* Mapping has to be done. */
2169 if (*cons <= 15 && *cons % 4 != 0)
2174 else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2179 if (*cons < 53 && *cons % 4 == 0)
2186 if ((IS_INSN_TYPE (ARITH_BYTE_INS) || IS_INSN_TYPE (ARITH_INS))
2189 /* Check whether a cst4 mapping has to be done. */
2190 if ((instruction->operands[0].op_type == cst4
2191 || instruction->operands[0].op_type == i16)
2192 && (instruction->operands[1].op_type == regr))
2194 /* 'const' equals reserved escape sequences -->>
2195 represent as i16. */
2196 if (insn->arg[0].constant == ESC_16
2197 || insn->arg[0].constant == ESC_32)
2204 /* Loop over cst4_map entries. */
2205 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2208 /* 'const' equals a binary, which is already mapped
2209 by a different value -->> represent as i16. */
2210 if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2211 && cst4_op->binary != cst4_op->value)
2216 /* 'const' equals a value bigger than 16 -->> map to
2217 its binary and represent as cst4. */
2218 else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2219 && insn->arg[0].constant >= 16)
2222 insn->arg[0].constant = cst4_op->binary;
2228 /* Special check for 'addub 0, r0' instruction -
2229 The opcode '0000 0000 0000 0000' is not allowed. */
2230 if (IS_INSN_MNEMONIC ("addub"))
2232 if ((instruction->operands[0].op_type == cst4)
2233 && instruction->operands[1].op_type == regr)
2235 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2240 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
2241 || IS_INSN_TYPE (LD_STOR_INS_INC))
2243 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2244 if (instruction->operands[instrtype].op_type == rbase)
2247 /* Error checking in case of post-increment instruction. */
2248 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2250 if (!((strneq (instruction->mnemonic, "stor", 4))
2251 && (insn->arg[0].type != arg_r)))
2252 if (insn->arg[0].r == insn->arg[1].r)
2253 as_bad (_("Invalid instruction : `%s' Source and Destination register \
2254 same in Post INC mode"), ins_parse);
2256 if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2258 if (instruction->operands[1].op_type == rbase_dispu12)
2260 if (insn->arg[1].constant == 0)
2267 if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2268 || IS_INSN_TYPE (STOR_IMM_INS)
2269 || IS_INSN_TYPE (LD_STOR_INS_INC)) & !relocatable)
2271 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2272 changed_already = 0;
2273 /* Convert 32 bits accesses to 16 bits accesses. */
2274 if (instruction->operands[instrtype].op_type == abs32)
2276 if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2279 insn->arg[instrtype].constant =
2280 insn->arg[instrtype].constant & 0xFFFF;
2281 insn->arg[instrtype].size = 16;
2282 changed_already = 1;
2286 /* Convert 16 bits accesses to 32 bits accesses. */
2287 if (instruction->operands[instrtype].op_type == abs16
2288 && changed_already != 1)
2291 insn->arg[instrtype].constant =
2292 insn->arg[instrtype].constant & 0xFFFF;
2293 insn->arg[instrtype].size = 32;
2296 changed_already = 0;
2298 if (IS_INSN_TYPE (BRANCH_INS) && !relocatable)
2300 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2301 if (insn->arg[0].constant == 0x7e || insn->arg[0].constant == 0x7f)
2309 for (i = 0; i < insn->nargs; i++)
2311 if (instruction->operands[i].op_type == cst4
2312 || instruction->operands[i].op_type == rbase_cst4)
2316 /* First, copy the instruction's opcode. */
2317 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2319 /* Swap the argument values in case bcop instructions. */
2320 if (IS_INSN_TYPE (COP_BRANCH_INS))
2322 temp_value = insn->arg[0].constant;
2323 insn->arg[0].constant = insn->arg[1].constant;
2324 insn->arg[1].constant = temp_value;
2327 for (i = 0; i < insn->nargs; i++)
2329 shift_act[i] = instruction->operands[i].shift;
2330 signflag = insn->arg[i].signflag;
2331 processing_arg_number = i;
2332 print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2339 /* Set the appropriate bit for register 'r' in 'mask'.
2340 This indicates that this register is loaded or stored by
2344 mask_reg (int r, unsigned short int *mask)
2346 if ((reg)r > (reg)sp)
2348 as_bad (_("Invalid Register in Register List"));
2355 /* Preprocess register list - create a 16-bit mask with one bit for each
2356 of the 16 general purpose registers. If a bit is set, it indicates
2357 that this register is loaded or stored by the instruction. */
2360 preprocess_reglist (char *param, int *allocated)
2362 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
2363 char *regP; /* Pointer to 'reg_name' string. */
2364 int reg_counter = 0; /* Count number of parsed registers. */
2365 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
2366 char *new_param; /* New created operands string. */
2367 char *paramP = param; /* Pointer to original opearands string. */
2368 char maskstring[10]; /* Array to print the mask as a string. */
2372 /* If 'param' is already in form of a number, no need to preprocess. */
2373 if (strchr (paramP, '{') == NULL)
2376 /* Verifying correct syntax of operand. */
2377 if (strchr (paramP, '}') == NULL)
2378 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2380 while (*paramP++ != '{');
2382 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2384 strncpy (new_param, param, paramP - param - 1);
2386 while (*paramP != '}')
2389 memset (®_name, '\0', sizeof (reg_name));
2391 while (ISALNUM (*paramP))
2394 strncpy (reg_name, regP, paramP - regP);
2396 /* Coprocessor register c<N>. */
2397 if (IS_INSN_TYPE (COP_REG_INS))
2399 if ((cr = get_copregister (reg_name)) == nullcopregister)
2400 as_bad (_("Illegal register `%s' in cop-register list"), reg_name);
2401 mask_reg (getreg_image (cr - c0), &mask);
2403 /* Coprocessor Special register cs<N>. */
2404 else if (IS_INSN_TYPE (COPS_REG_INS))
2406 if ((cr = get_copregister (reg_name)) == nullcopregister)
2407 as_bad (_("Illegal register `%s' in cop-special-register list"),
2409 mask_reg (getreg_image (cr - cs0), &mask);
2411 /* General purpose register r<N>. */
2414 if ((r = get_register (reg_name)) == nullregister)
2415 as_bad (_("Illegal register `%s' in register list"), reg_name);
2416 mask_reg (getreg_image (r), &mask);
2419 if (++reg_counter > MAX_REGS_IN_MASK16)
2420 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2421 MAX_REGS_IN_MASK16);
2423 while (!ISALNUM (*paramP) && *paramP != '}')
2427 if (*++paramP != '\0')
2428 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2432 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2435 sprintf (maskstring, "$0x%x", mask);
2436 strcat (new_param, maskstring);
2440 /* Print the instruction.
2441 Handle also cases where the instruction is relaxable/relocatable. */
2444 print_insn (ins *insn)
2446 unsigned int i, j, insn_size;
2448 unsigned short words[4];
2450 /* Arrange the insn encodings in a WORD size array. */
2451 for (i = 0, j = 0; i < 2; i++)
2453 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2454 words[j++] = output_opcode[i] & 0xFFFF;
2457 /* Handle relaxtion. */
2458 if ((instruction->flags & RELAXABLE) && relocatable)
2462 /* Write the maximal instruction size supported. */
2463 insn_size = INSN_MAX_SIZE;
2466 if (IS_INSN_TYPE (BRANCH_INS))
2469 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2472 else if (IS_INSN_TYPE (CMPBR_INS))
2477 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2479 insn->exp.X_add_symbol,
2480 insn->exp.X_add_number,
2485 insn_size = instruction->size;
2486 this_frag = frag_more (insn_size * 2);
2488 /* Handle relocation. */
2489 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2491 reloc_howto_type *reloc_howto;
2494 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2499 size = bfd_get_reloc_size (reloc_howto);
2501 if (size < 1 || size > 4)
2504 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2505 size, &insn->exp, reloc_howto->pc_relative,
2510 /* Write the instruction encoding to frag. */
2511 for (i = 0; i < insn_size; i++)
2513 md_number_to_chars (this_frag, (valueT) words[i], 2);
2518 /* This is the guts of the machine-dependent assembler. OP points to a
2519 machine dependent instruction. This function is supposed to emit
2520 the frags/bytes it assembles to. */
2523 md_assemble (char *op)
2529 /* Reset global variables for a new instruction. */
2530 reset_vars (op, &crx_ins);
2532 /* Strip the mnemonic. */
2533 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2538 /* Find the instruction. */
2539 instruction = (const inst *) hash_find (crx_inst_hash, op);
2540 if (instruction == NULL)
2542 as_bad (_("Unknown opcode: `%s'"), op);
2546 /* Tie dwarf2 debug info to the address at the start of the insn. */
2547 dwarf2_emit_insn (0);
2549 if (NO_OPERANDS_INST (op))
2550 /* Handle instructions with no operands. */
2553 /* Parse the instruction's operands. */
2554 parse_insn (&crx_ins, param);
2556 /* Assemble the instruction. */
2557 if (assemble_insn (op, &crx_ins) == 0)
2559 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2563 /* Print the instruction. */
2564 print_insn (&crx_ins);