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"
31 /* Include <limits.h> do define ULONG_MAX, LONG_MAX, LONG_MIN. */
34 /* Word is considered here as a 16-bit unsigned short int. */
38 /* Register is 4-bit size. */
41 /* Maximum size of a single instruction (in words). */
42 #define INSN_MAX_SIZE 3
44 /* Maximum bits which may be set in a `mask16' operand. */
45 #define MAX_REGS_IN_MASK16 8
47 /* Escape to 16-bit immediate. */
49 /* Escape to 32-bit immediate. */
52 /* Utility macros for string comparison. */
53 #define streq(a, b) (strcmp (a, b) == 0)
54 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
56 /* A mask to set n_bits starting from offset offs. */
57 #define SET_BITS_MASK(offs,n_bits) ((((1 << (n_bits)) - 1) << (offs)))
58 /* A mask to clear n_bits starting from offset offs. */
59 #define CLEAR_BITS_MASK(offs,n_bits) (~(((1 << (n_bits)) - 1) << (offs)))
61 /* Get the argument type for each operand of a given instruction. */
62 #define GET_ACTUAL_TYPE \
63 for (i = 0; i < insn->nargs; i++) \
64 atyp_act[i] = getarg_type (instruction->operands[i].op_type)
66 /* Get the size (in bits) for each operand of a given instruction. */
67 #define GET_ACTUAL_SIZE \
68 for (i = 0; i < insn->nargs; i++) \
69 bits_act[i] = getbits (instruction->operands[i].op_type)
71 /* Non-zero if OP is instruction with no operands. */
72 #define NO_OPERANDS_INST(OP) \
73 (streq (OP, "di") || streq (OP, "nop") \
74 || streq (OP, "retx") || streq (OP, "ei") \
75 || streq (OP, "wait") || streq (OP, "eiwait"))
77 /* Print a number NUM, shifted by SHIFT bytes, into a location
78 pointed by index BYTE of array 'output_opcode'. */
79 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
81 /* Opcode mnemonics hash table. */
82 static struct hash_control *crx_inst_hash;
83 /* CRX registers hash table. */
84 static struct hash_control *reg_hash;
85 /* CRX coprocessor registers hash table. */
86 static struct hash_control *copreg_hash;
87 /* Current instruction we're assembling. */
88 const inst *instruction;
90 /* Initialize global variables. */
91 long output_opcode[2];
92 /* Nonzero means a relocatable symbol. */
94 /* Nonzero means a constant's bit-size was already set. */
96 /* Nonzero means a negative constant. */
98 /* Nonzero means a CST4 instruction. */
100 /* A copy of the original instruction (used in error messages). */
101 char ins_parse[MAX_INST_LEN];
102 /* Nonzero means instruction is represented in post increment mode. */
104 /* Holds the current processed argument number. */
105 int processing_arg_number;
107 /* Generic assembler global variables which must be defined by all targets. */
109 /* Characters which always start a comment. */
110 const char comment_chars[] = "#";
112 /* Characters which start a comment at the beginning of a line. */
113 const char line_comment_chars[] = "#";
115 /* This array holds machine specific line separator characters. */
116 const char line_separator_chars[] = ";";
118 /* Chars that can be used to separate mant from exp in floating point nums. */
119 const char EXP_CHARS[] = "eE";
121 /* Chars that mean this number is a floating point constant as in 0f12.456 */
122 const char FLT_CHARS[] = "f'";
124 /* Target-specific multicharacter options, not const-declared at usage. */
125 const char *md_shortopts = "";
126 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_pi_insn (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)
883 crx_ins->arg[number].constant = crx_ins->exp.X_add_number;
884 constant_val = crx_ins->exp.X_add_number;
885 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
888 /* This variable causes a warning (is to be handles by string
889 type implementation). */
894 unsigned int jump_value = 0;
895 int BR_MASK = 0, BR_SIZE = 0;
902 strncat (temp_str, str, strlen (str));
903 temp64 = strtol (temp_str, (char **) &ptr,0);
904 /* This is not accurate :
905 Actually overflow is allowed here (see comment below).
906 Originally the call was to 'strtoll', which isn't
907 identified by MSVC. */
908 if ((temp64 == LONG_MAX) || (temp64 == LONG_MIN))
909 as_bad (_("Overflow in displacement in Instruction `%s'"),
913 It will be returned as '0' padded with 'x' uptill 64 bits
915 It will be returned as sign extended form
917 Then search for validity of representation
918 Check whether upper 38 bits are all zeroes or all ones
919 If not report error. */
920 if (!(((temp64 & UPPER31_MASK) == UPPER31_MASK)
921 || ((temp64 & UPPER31_MASK) == 0x0)))
922 as_bad (_("Overflow in displacement in Instruction `%s'"),
926 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
929 /* Determine the branch size. */
930 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
931 if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
932 || ((jump_value & 0xFFFFFF00) == 0x0))
938 if (((jump_value & 0xFF000000) == 0xFF000000)
939 || ((jump_value & 0xFF000000) == 0x0))
944 jump_value = jump_value >> 1;
945 crx_ins->arg[number].constant = jump_value & BR_MASK;
946 crx_ins->arg[number].size = BR_SIZE;
948 crx_ins->arg[number].signflag = signflag;
949 input_line_pointer = save;
950 return crx_ins->exp.X_op;
953 if (IS_INSN_TYPE (BRANCH_INS)
954 || IS_INSN_MNEMONIC ("bal")
955 || IS_INSN_TYPE (DCR_BRANCH_INS))
960 unsigned int jump_value = 0;
961 int BR_MASK = 0, BR_SIZE = 0;
969 strncat (temp_str, str, strlen (str));
970 temp64 = strtol (temp_str, (char **) &ptr,0);
971 /* This is not accurate :
972 Actually overflow is allowed here (see comment below).
973 Originally the call was to 'strtoll', which isn't
974 identified by MSVC. */
975 if ((temp64 == LONG_MAX) || (temp64 == LONG_MIN))
976 as_bad (_("Overflow in displacement in Instruction `%s'"),
980 It will be returned as '0' padded with 'x' uptill 64 bits
982 It will be returned as sign extended form
984 Then search for validity of representation
985 Check whether upper 31 bits are all zeroes or all ones
986 If not report error. */
987 if (!(((temp64 & UPPER31_MASK) == UPPER31_MASK)
988 || ((temp64 & UPPER31_MASK) == 0x0)))
989 as_bad (_("Overflow in displacement in Instruction `%s'"),
993 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
996 /* Determine the branch size. */
997 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
998 if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
999 && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
1000 || ((jump_value & 0xFFFFFF00) == 0x0)))
1006 if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
1007 || ((jump_value & 0xFFFF0000) == 0x0))
1014 BR_MASK = 0xFFFFFFFF;
1017 jump_value = jump_value >> 1;
1018 crx_ins->arg[number].constant = jump_value & BR_MASK;
1019 crx_ins->arg[number].size = BR_SIZE;
1021 crx_ins->arg[number].signflag = signflag;
1022 input_line_pointer = save;
1023 return crx_ins->exp.X_op;
1025 /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
1026 if (constant_val < 0 && signflag != 1
1027 && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
1028 && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
1029 && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
1031 crx_ins->arg[number].constant =
1032 ~(crx_ins->arg[number].constant) + 1;
1035 /* For load/store instruction when the value is in the offset part. */
1036 if (constant_val < 0 && signflag != 1
1037 && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
1038 || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
1040 if (crx_ins->arg[number].type == arg_cr
1041 || crx_ins->arg[number].type == arg_icr)
1043 crx_ins->arg[number].constant =
1044 ~(crx_ins->arg[number].constant) + 1;
1050 /* Signflag in never set in case of load store instructions
1051 Mapping in case of only the arithinsn case. */
1052 if ((crx_ins->arg[number].constant != 1
1053 && crx_ins->arg[number].constant != 4)
1054 || (!IS_INSN_TYPE (ARITH_INS)
1055 && !IS_INSN_TYPE (ARITH_BYTE_INS)
1056 && !IS_INSN_TYPE (CMPBR_INS)))
1058 /* Counting the number of bits required to represent
1061 temp = crx_ins->arg[number].constant - 1;
1067 crx_ins->arg[number].size = cnt + 1;
1068 crx_ins->arg[number].constant =
1069 ~(crx_ins->arg[number].constant) + 1;
1070 if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
1075 /* Tomer - Originally the call was to 'strtoull', which isn't
1076 identified by MSVC. Instead we check for overflow. */
1077 temp64 = strtoul (str, (char **) &ptr, 0);
1079 crx_ins->arg[number].size = 5;
1081 if (IS_INSN_TYPE (ARITH_INS))
1083 if (crx_ins->arg[number].size > 32
1084 /* Tomer - check for overflow. */
1085 || (temp64 == ULONG_MAX))
1087 if (crx_ins->arg[number].size > 32)
1088 as_bad (_("In Instruction `%s': Immediate size is \
1089 %lu bits cannot be accomodated"),
1090 ins_parse, cnt + 1);
1092 /* Tomer - check for overflow. */
1093 if (temp64 == ULONG_MAX)
1094 as_bad (_("Value given more than 32 bits in \
1095 Instruction `%s'"), ins_parse);
1098 if (IS_INSN_TYPE (ARITH_BYTE_INS))
1100 if (crx_ins->arg[number].size > 16
1101 || !((temp64 & 0xFFFF0000) == 0xFFFF0000
1102 || (temp64 & 0xFFFF0000) == 0x0))
1104 if (crx_ins->arg[number].size > 16)
1105 as_bad (_("In Instruction `%s': Immediate size is \
1106 %lu bits cannot be accomodated"),
1107 ins_parse, cnt + 1);
1109 if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
1110 || (temp64 & 0xFFFF0000) == 0x0))
1111 as_bad (_("Value given more than 16 bits in \
1112 Instruction `%s'"), ins_parse);
1116 if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr
1119 /* Cases handled ---
1120 dispub4/dispuw4/dispud4 and for load store dispubwd4
1121 is applicable only. */
1122 if (crx_ins->arg[number].size <= 4)
1123 crx_ins->arg[number].size = 5;
1125 /* Argument number is checked to distinguish between
1126 immediate and displacement in cmpbranch and bcopcond. */
1127 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1130 if (crx_ins->arg[number].size != 32)
1131 crx_ins->arg[number].constant =
1132 crx_ins->arg[number].constant >> 1;
1135 mask_const (&crx_ins->arg[number].constant,
1136 (int) crx_ins->arg[number].size);
1141 /* Argument number is checked to distinguish between
1142 immediate and displacement in cmpbranch and bcopcond. */
1143 if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1145 || IS_INSN_TYPE (BRANCH_NEQ_INS))
1147 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1149 if (crx_ins->arg[number].constant == 0)
1150 as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
1153 if (crx_ins->arg[number].constant % 2 != 0)
1154 as_bad (_("Instruction `%s' has odd offset"), ins_parse);
1156 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1158 if (crx_ins->arg[number].constant > 32
1159 || crx_ins->arg[number].constant < 2)
1160 as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1161 ins_parse, crx_ins->arg[number].constant);
1163 crx_ins->arg[number].constant -= 2;
1166 crx_ins->arg[number].constant =
1167 crx_ins->arg[number].constant >> 1;
1168 get_number_of_bits (crx_ins, number);
1171 /* Compare branch argument number zero to be compared -
1173 if (IS_INSN_TYPE (CMPBR_INS) && number == 0)
1175 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
1177 if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value)
1179 crx_ins->arg[number].constant = cst4_op->binary;
1185 as_bad (_("Instruction `%s' has invalid imm value as an \
1186 operand"), ins_parse);
1193 crx_ins->arg[number].constant = 0;
1196 switch (crx_ins->arg[number].type)
1199 /* Have to consider various cases here --load/stor++[bwd] rbase, reg. */
1200 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1201 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
1202 else if (IS_INSN_TYPE (CSTBIT_INS)
1203 || IS_INSN_TYPE (STOR_IMM_INS))
1204 /* 'stor[bwd] imm' and '[stc]bit[bwd]'. */
1205 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
1207 /* General load store instruction. */
1208 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
1211 /* Index Mode 22 bits relocation. */
1212 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
1215 /* Absolute types. */
1216 /* Case for jumps...dx types. */
1218 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
1219 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1220 else if (IS_INSN_TYPE (BRANCH_INS))
1222 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1224 /* Overriding the above by the br_type_flag set above. */
1225 switch (br_type_flag)
1230 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1233 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1236 crx_ins->rtype = BFD_RELOC_CRX_REL32;
1240 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
1241 || IS_INSN_TYPE (CSTBIT_INS))
1242 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
1243 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1244 crx_ins->rtype = BFD_RELOC_CRX_REL4;
1245 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1247 if (cmp_br_type_flag == 24)
1248 crx_ins->rtype = BFD_RELOC_CRX_REL24;
1250 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1255 if (IS_INSN_TYPE (ARITH_INS))
1256 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
1257 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1258 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
1263 crx_ins->arg[number].size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
1270 input_line_pointer = save;
1271 crx_ins->arg[number].signflag = signflag;
1272 return crx_ins->exp.X_op;
1275 /* Get the values of the scale to be encoded -
1276 used for the scaled index mode of addressing. */
1279 exponent2scale (int val)
1283 /* If 'val' is 0, the following 'for' will be an endless loop. */
1287 for (exponent = 0; (val != 1); val >>= 1, exponent++)
1293 /* This is used to set the index mode parameters. Used to set the attributes of
1294 an indexmode type of operand. op_num is the operand number. */
1297 set_indexmode_parameters (char *operand, ins * crx_ins, int op_num)
1299 char address_str[30];
1300 char scale_str[MAX_OPERANDS];
1302 char reg_name[MAX_REGNAME_LEN];
1303 char regindex_name[MAX_REGNAME_LEN];
1305 int reg_counter = 0, addr_cnt = 0, temp_int_val = 0;
1307 switch (crx_ins->arg[op_num].type)
1310 while (operand[i] != '(')
1312 address_str[addr_cnt++] = operand[i];
1315 address_str[addr_cnt] = '\0';
1316 process_label_constant (address_str, crx_ins, op_num);
1319 while (operand[i] != ',' && operand[i] != ' ')
1321 reg_name[reg_counter++] = operand[i];
1324 reg_name[reg_counter] = '\0';
1325 if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1326 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1327 reg_name, ins_parse);
1330 while (operand[i] == ' ')
1334 while (operand[i] != ')' && operand[i] != ',')
1336 regindex_name[reg_counter++] = operand[i];
1339 regindex_name[reg_counter] = '\0';
1341 if ((crx_ins->arg[op_num].i_r = get_register (regindex_name))
1343 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1344 regindex_name, ins_parse);
1346 /* Setting the scale parameters. */
1347 while (operand[i] == ' ')
1350 if (operand[i] == ')')
1351 crx_ins->arg[op_num].scale = 0;
1354 if (operand[i] == ',')
1357 while (operand[i] != ' ' && operand[i] != ')')
1359 scale_str[scale_cnt++] = operand[i];
1363 scale_str[scale_cnt] = '\0';
1364 /* Preprocess the scale string. */
1365 if (strstr (scale_str, "0x") != NULL
1366 || strstr (scale_str, "0X") != NULL)
1368 sscanf (scale_str, "%x", &temp_int_val);
1369 memset (&scale_str, '\0', sizeof (scale_str));
1370 sprintf (scale_str, "%d", temp_int_val);
1372 /* Preprocess over. */
1373 temp_int_val = atoi (scale_str);
1375 if (temp_int_val != 1 && temp_int_val != 2
1376 && temp_int_val != 4 && temp_int_val != 8)
1377 as_bad (_("Illegal Scale - `%s'"), scale_str);
1379 crx_ins->arg[op_num].scale = exponent2scale (temp_int_val);
1387 /* Parsing the operands of types
1389 - rbase -> (register)
1391 - offset(rbase)+ - post increment mode. */
1394 set_cons_rparams (char *operand, ins * crx_ins, int op_num)
1396 int i = 0, reg_count = 0;
1397 char reg_name[MAX_REGNAME_LEN];
1398 int change_flag = 0;
1400 if (crx_ins->arg[op_num].type == arg_dc)
1403 switch (crx_ins->arg[op_num].type)
1405 case arg_sc: /* Case *+347. */
1406 case arg_dc: /* Case $18. */
1408 case arg_c:/* Case where its a simple constant. */
1409 process_label_constant (operand + i, crx_ins, op_num);
1410 crx_ins->arg[op_num].type = arg_c;
1412 case arg_dcr: /* Case $9(r13). */
1414 case arg_cr: /* Case 9(r13. */
1415 while (operand[i] != '(')
1418 process_label_constant (operand, crx_ins, op_num);
1422 while (operand[i] != ')')
1424 reg_name[reg_count] = operand[i];
1428 reg_name[reg_count] = '\0';
1429 if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1430 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1431 reg_name, ins_parse);
1433 crx_ins->arg[op_num].type = arg_cr;
1434 /* Post increment is represented in assembly as offset (register)+. */
1435 if (strstr (operand + i, "+") != NULL)
1436 /* There is a plus after the ')'. */
1442 if (change_flag == 1)
1443 crx_ins->arg[op_num].type = arg_ic;
1446 /* This is used to get the operand attributes -
1447 operand - current operand to be used
1448 number - operand number
1449 crx_ins - current assembled instruction. */
1452 get_operandtype (char *operand, int number, ins * crx_ins)
1455 char temp_operand[30];
1459 /* When it is a register. */
1468 /* Check whether this is a general processor register. */
1469 ret_val = get_register (operand);
1470 if (ret_val != nullregister)
1472 crx_ins->arg[number].type = arg_r;
1473 crx_ins->arg[number].r = ret_val;
1474 crx_ins->arg[number].size = REG_SIZE;
1478 /* Check whether this is a core [special] coprocessor register. */
1479 ret_val = get_copregister (operand);
1480 if (ret_val != nullcopregister)
1482 crx_ins->arg[number].type = arg_copr;
1484 crx_ins->arg[number].type = arg_copsr;
1485 crx_ins->arg[number].cr = ret_val;
1486 crx_ins->arg[number].size = REG_SIZE;
1490 if (strchr (operand, '(') != NULL)
1492 if (strchr (operand, ',') != NULL
1493 && (strchr (operand, ',') > strchr (operand, '(')))
1495 crx_ins->arg[number].type = arg_icr;
1496 crx_ins->arg[number].constant = 0;
1497 set_indexmode_parameters (operand, crx_ins, number);
1498 get_number_of_bits (crx_ins, number);
1502 crx_ins->arg[number].type = arg_cr;
1505 crx_ins->arg[number].type = arg_c;
1506 crx_ins->arg[number].constant = 0;
1507 set_cons_rparams (operand, crx_ins, number);
1508 get_number_of_bits (crx_ins, number);
1513 if (strchr (operand, '(') != NULL)
1514 crx_ins->arg[number].type = arg_dcr;
1516 crx_ins->arg[number].type = arg_dc;
1517 crx_ins->arg[number].constant = 0;
1518 set_cons_rparams (operand, crx_ins, number);
1519 get_number_of_bits (crx_ins, number);
1523 /* Augmenting a zero in front of an operand -- won't work for tbit/sbit. */
1524 strcpy (temp_operand, "0");
1525 strcat (temp_operand, operand);
1526 if (strchr (temp_operand, ',') != NULL
1527 && (strchr (temp_operand, ',') > strchr (temp_operand, '(')))
1529 crx_ins->arg[number].type = arg_icr;
1530 crx_ins->arg[number].constant = 0;
1531 set_indexmode_parameters (temp_operand, crx_ins, number);
1532 get_number_of_bits (crx_ins, number);
1537 crx_ins->arg[number].type = arg_cr;
1538 crx_ins->arg[number].constant = 0;
1539 set_cons_rparams (operand, crx_ins, number);
1540 get_number_of_bits (crx_ins, number);
1541 if ((! strneq (instruction->mnemonic, "load", 4))
1542 && (! strneq (instruction->mnemonic, "stor", 4)))
1544 crx_ins->arg[number].type = arg_rbase;
1545 crx_ins->arg[number].size = REG_SIZE;
1551 crx_ins->arg[number].type = arg_sc;
1552 crx_ins->arg[number].constant = 0;
1553 set_cons_rparams (operand, crx_ins, number);
1554 get_number_of_bits (crx_ins, number);
1568 if (strchr (operand, '(') != NULL)
1570 if (strchr (operand, ',') != NULL
1571 && (strchr (operand, ',') > strchr (operand, '(')))
1573 crx_ins->arg[number].type = arg_icr;
1574 crx_ins->arg[number].constant = 0;
1575 set_indexmode_parameters (operand, crx_ins, number);
1576 get_number_of_bits (crx_ins, number);
1580 crx_ins->arg[number].type = arg_cr;
1583 crx_ins->arg[number].type = arg_c;
1584 crx_ins->arg[number].constant = 0;
1585 set_cons_rparams (operand, crx_ins, number);
1586 get_number_of_bits (crx_ins, number);
1589 if (strchr (operand, '(') != NULL)
1591 if (strchr (operand, ',') != NULL
1592 && (strchr (operand, ',') > strchr (operand, '(')))
1594 crx_ins->arg[number].type = arg_icr;
1595 crx_ins->arg[number].constant = 0;
1596 set_indexmode_parameters (operand, crx_ins, number);
1597 get_number_of_bits (crx_ins, number);
1601 crx_ins->arg[number].type = arg_cr;
1604 crx_ins->arg[number].type = arg_c;
1605 crx_ins->arg[number].constant = 0;
1606 set_cons_rparams (operand, crx_ins, number);
1607 get_number_of_bits (crx_ins, number);
1612 /* Operands are parsed over here, separated into various operands. Each operand
1613 is then analyzed to fillup the fields in the crx_ins data structure. */
1616 parse_operands (ins * crx_ins, char *operands)
1618 char *operandS; /* Operands string. */
1619 char *operandH, *operandT; /* Single operand head/tail pointers. */
1620 int allocated = 0; /* Indicates a new operands string was allocated. */
1621 char *operand[MAX_OPERANDS]; /* Separating the operands. */
1622 int op_num = 0; /* Current operand number we are parsing. */
1623 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
1624 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
1626 /* Preprocess the list of registers, if necessary. */
1627 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
1628 preprocess_reglist (operands, &allocated) : operands;
1630 while (*operandT != '\0')
1632 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1635 operand[op_num++] = strdup (operandH);
1636 operandH = operandT;
1640 if (*operandT == ' ')
1641 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1643 if (*operandT == '(')
1645 else if (*operandT == '[')
1646 sq_bracket_flag = 1;
1648 if (*operandT == ')')
1653 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1655 else if (*operandT == ']')
1657 if (sq_bracket_flag)
1658 sq_bracket_flag = 0;
1660 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1663 if (bracket_flag == 1 && *operandT == ')')
1665 else if (sq_bracket_flag == 1 && *operandT == ']')
1666 sq_bracket_flag = 0;
1671 /* Adding the last operand. */
1672 operand[op_num++] = strdup (operandH);
1673 crx_ins->nargs = op_num;
1675 /* Verifying correct syntax of operands (all brackets should be closed). */
1676 if (bracket_flag || sq_bracket_flag)
1677 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1679 /* Now to recongnize the operand types. */
1680 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1682 get_operandtype (operand[op_num], op_num, crx_ins);
1683 free (operand[op_num]);
1690 /* Get the trap index in dispatch table, given its name.
1691 This routine is used by assembling the 'excp' instruction. */
1696 const trap_entry *trap;
1698 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1699 if (streq (trap->name, s))
1702 as_bad (_("Unknown exception: `%s'"), s);
1706 /* Post-Increment instructions are a sub-group within load/stor instruction
1707 groups. Therefore, when parsing a Post-Increment insn, we have to advance
1708 the instruction pointer to the start of that sub-group. */
1711 handle_pi_insn (char *operands)
1713 /* Assuming Post-Increment insn has the following format :
1714 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6'). */
1715 if (strstr (operands, ")+") != NULL)
1716 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1720 /* Top level module where instruction parsing starts.
1721 crx_ins - data structure holds some information.
1722 operands - holds the operands part of the whole instruction. */
1725 parse_insn (ins *insn, char *operands)
1727 /* Handle 'excp'/'cinv' */
1728 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1731 insn->arg[0].type = arg_ic;
1732 insn->arg[0].size = 4;
1733 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1734 gettrap (operands) : get_cinv_parameters (operands);
1738 /* Handle load/stor post-increment instructions. */
1739 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS))
1740 handle_pi_insn (operands);
1742 if (operands != NULL)
1743 parse_operands (insn, operands);
1746 /* Cinv instruction requires special handling. */
1749 get_cinv_parameters (char * operand)
1752 int d_used = 0, i_used = 0, u_used = 0;
1756 if (*p == ',' || *p == ' ')
1766 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1769 return ((d_used ? 4 : 0)
1771 + (u_used ? 1 : 0));
1774 /* Retrieve the opcode image of a given register.
1775 If the register is illegal for the current instruction,
1779 getreg_image (reg r)
1781 const reg_entry *reg;
1783 int special_register_flag = 0;
1784 int movpr_flag = 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1786 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1789 if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1))
1790 || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) )
1791 special_register_flag = 1;
1793 /* Check whether the register is in registers table. */
1795 reg = &crx_regtab[r];
1796 /* Check whether the register is in coprocessor registers table. */
1797 else if (r < MAX_COPREG)
1798 reg = &crx_copregtab[r-MAX_REG];
1799 /* Register not found. */
1802 as_bad (_("Unknown register: `%d'"), r);
1806 reg_name = reg->name;
1808 /* Issue a error message when register is illegal. */
1810 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1811 reg_name, ins_parse); \
1817 case CRX_CFG_REGTYPE:
1818 case CRX_MTPR_REGTYPE:
1819 if (movpr_flag && special_register_flag)
1826 case CRX_CS_REGTYPE:
1827 if (!(movpr_flag && special_register_flag))
1839 /* Routine used to get the binary-string equivalent of a integer constant
1840 which currently require currbits to represent itself to be extended to
1843 static unsigned long int
1844 getconstant (unsigned long int x, int nbits)
1847 unsigned long int temp = x;
1855 /* Escape sequence to next 16bit immediate. */
1857 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1862 x |= SET_BITS_MASK (cnt, nbits - cnt);
1864 x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1867 /* The following expression avoids overflow if
1868 'nbits' is the number of bits in 'bfd_vma'. */
1869 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1872 /* Print a constant value to 'output_opcode':
1873 ARG holds the operand's type and value.
1874 SHIFT represents the location of the operand to be print into.
1875 NBITS determines the size (in bits) of the constant. */
1878 print_constant (int nbits, int shift, argument *arg)
1880 unsigned long mask = 0;
1882 long constant = getconstant (arg->constant, nbits);
1890 /* mask the upper part of the constant, that is, the bits
1891 going to the lowest byte of output_opcode[0].
1892 The upper part of output_opcode[1] is always filled,
1893 therefore it is always masked with 0xFFFF. */
1894 mask = (1 << (nbits - 16)) - 1;
1895 /* Divide the constant between two consecutive words :
1897 +---------+---------+---------+---------+
1898 | | X X X X | X X X X | |
1899 +---------+---------+---------+---------+
1900 output_opcode[0] output_opcode[1] */
1902 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1903 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1908 /* Special case - in arg_cr, the SHIFT represents the location
1909 of the REGISTER, not the constant, which is itself not shifted. */
1910 if (arg->type == arg_cr)
1912 CRX_PRINT (0, constant, 0);
1916 /* When instruction size is 3, a 16-bit constant is always
1917 filling the upper part of output_opcode[1]. */
1918 if (instruction->size > 2)
1919 CRX_PRINT (1, constant, WORD_SHIFT);
1921 CRX_PRINT (0, constant, shift);
1925 CRX_PRINT (0, constant, shift);
1930 /* Print an operand to 'output_opcode', which later on will be
1931 printed to the object file:
1932 ARG holds the operand's type, size and value.
1933 SHIFT represents the printing location of operand.
1934 NBITS determines the size (in bits) of a constant operand. */
1937 print_operand (int nbits, int shift, argument *arg)
1942 CRX_PRINT (0, getreg_image (arg->r), shift);
1946 if (arg->cr < c0 || arg->cr > c15)
1947 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1949 CRX_PRINT (0, getreg_image (arg->cr), shift);
1953 if (arg->cr < cs0 || arg->cr > cs15)
1954 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1956 CRX_PRINT (0, getreg_image (arg->cr), shift);
1960 print_constant (nbits, shift, arg);
1965 +--------------------------------+
1966 | reg | r_base | scl| disp |
1967 +--------------------------------+ */
1968 CRX_PRINT (0, getreg_image (arg->r), 12);
1969 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1970 CRX_PRINT (0, arg->scale, 6);
1971 print_constant (nbits, shift, arg);
1975 CRX_PRINT (0, getreg_image (arg->r), shift);
1979 /* case base_cst4. */
1980 if ((instruction->flags & CST4MAP) && cst4flag)
1981 output_opcode[0] |= (getconstant (arg->constant, nbits)
1982 << (shift + REG_SIZE));
1984 /* rbase_dispu<NN> and other such cases. */
1985 print_constant (nbits, shift, arg);
1986 /* Add the register argument to the output_opcode. */
1987 CRX_PRINT (0, getreg_image (arg->r), shift);
1991 print_constant (nbits, shift, arg);
1999 /* Retrieve the number of operands for the current assembled instruction. */
2002 get_number_of_operands (void)
2006 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
2011 /* Assemble a single instruction :
2012 Instruction has been parsed and all operand values set appropriately.
2013 Algorithm for assembling -
2014 For instruction to be assembled:
2015 Step 1: Find instruction in the array crx_instruction with same mnemonic.
2016 Step 2: Find instruction with same operand types.
2017 Step 3: If (size_of_operands) match then done, else increment the
2018 array_index and goto Step3.
2019 Step 4: Cannot assemble
2020 Returns 1 upon success, 0 upon failure. */
2023 assemble_insn (char *mnemonic, ins *insn)
2025 /* Argument type of each operand in the instruction we are looking for. */
2026 argtype atyp[MAX_OPERANDS];
2027 /* Argument type of each operand in the current instruction. */
2028 argtype atyp_act[MAX_OPERANDS];
2029 /* Size (in bits) of each operand in the instruction we are looking for. */
2030 int bits[MAX_OPERANDS];
2031 /* Size (in bits) of each operand in the current instruction. */
2032 int bits_act[MAX_OPERANDS];
2033 /* Location (in bits) of each operand in the current instruction. */
2034 int shift_act[MAX_OPERANDS];
2037 int cst4maptype = 0;
2038 int changed_already = 0;
2039 unsigned int temp_value = 0;
2041 /* A pointer to the argument's constant value. */
2042 unsigned long int *cons;
2043 /* Pointer to loop over all cst4_map entries. */
2044 const cst4_entry *cst4_op;
2046 /* Instruction has no operands -> copy only the constant opcode. */
2047 if (insn->nargs == 0)
2049 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2053 /* Find instruction with same number of operands. */
2054 while (get_number_of_operands () != insn->nargs
2055 && IS_INSN_MNEMONIC (mnemonic))
2058 if (!IS_INSN_MNEMONIC (mnemonic))
2061 /* Initialize argument type and size of each given operand. */
2062 for (i = 0; i < insn->nargs; i++)
2064 atyp[i] = insn->arg[i].type;
2065 bits[i] = insn->arg[i].size;
2068 /* Initialize argument type and size of each operand in current inst. */
2073 /* Check we didn't get to end of table. */
2074 && instruction->mnemonic != NULL
2075 /* Check that the actual mnemonic is still available. */
2076 && IS_INSN_MNEMONIC (mnemonic))
2078 /* Check for argement type compatibility. */
2079 for (i = 0; i < insn->nargs; i++)
2081 if (atyp_act[i] == atyp[i])
2091 /* Check for post inc mode of the current instruction. */
2092 if (post_inc_mode == 1 || IS_INSN_TYPE (LD_STOR_INS_INC))
2093 done_flag = (post_inc_mode == IS_INSN_TYPE (LD_STOR_INS_INC));
2098 /* Try again with next instruction. */
2106 /* Check for size compatibility. */
2107 for (i = 0; i < insn->nargs; i++)
2109 if (bits[i] > bits_act[i])
2111 /* Actual size is too small - try again. */
2124 /* Full match is found. */
2131 /* We haven't found a match - instruction can't be assembled. */
2134 /* Full match - print the final image. */
2136 /* Handle positive constants. */
2139 if (IS_INSN_TYPE (LD_STOR_INS) && !relocatable)
2141 /* Get the map type of the instruction. */
2142 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2143 cons = &insn->arg[instrtype].constant;
2144 cst4maptype = instruction->flags & CST4MAP;
2146 switch (cst4maptype)
2149 /* 14 and 15 are reserved escape sequences of dispub4. */
2150 if (*cons == 14 || *cons == 15)
2158 /* Mapping has to be done. */
2159 if (*cons <= 15 && *cons % 2 != 0)
2164 else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2169 if (*cons < 27 && *cons % 2 == 0)
2174 /* Mapping has to be done. */
2175 if (*cons <= 15 && *cons % 4 != 0)
2180 else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2185 if (*cons < 53 && *cons % 4 == 0)
2192 if ((IS_INSN_TYPE (ARITH_BYTE_INS) || IS_INSN_TYPE (ARITH_INS))
2195 /* Check whether a cst4 mapping has to be done. */
2196 if ((instruction->operands[0].op_type == cst4
2197 || instruction->operands[0].op_type == i16)
2198 && (instruction->operands[1].op_type == regr))
2200 /* 'const' equals reserved escape sequences -->>
2201 represent as i16. */
2202 if (insn->arg[0].constant == ESC_16
2203 || insn->arg[0].constant == ESC_32)
2210 /* Loop over cst4_map entries. */
2211 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2214 /* 'const' equals a binary, which is already mapped
2215 by a different value -->> represent as i16. */
2216 if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2217 && cst4_op->binary != cst4_op->value)
2222 /* 'const' equals a value bigger than 16 -->> map to
2223 its binary and represent as cst4. */
2224 else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2225 && insn->arg[0].constant >= 16)
2228 insn->arg[0].constant = cst4_op->binary;
2234 /* Special check for 'addub 0, r0' instruction -
2235 The opcode '0000 0000 0000 0000' is not allowed. */
2236 if (IS_INSN_MNEMONIC ("addub"))
2238 if ((instruction->operands[0].op_type == cst4)
2239 && instruction->operands[1].op_type == regr)
2241 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2246 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
2247 || IS_INSN_TYPE (LD_STOR_INS_INC))
2249 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2250 if (instruction->operands[instrtype].op_type == rbase)
2253 /* Error checking in case of post-increment instruction. */
2254 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2256 if (!((strneq (instruction->mnemonic, "stor", 4))
2257 && (insn->arg[0].type != arg_r)))
2258 if (insn->arg[0].r == insn->arg[1].r)
2259 as_bad (_("Invalid instruction : `%s' Source and Destination register \
2260 same in Post INC mode"), ins_parse);
2262 if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2264 if (instruction->operands[1].op_type == rbase_dispu12)
2266 if (insn->arg[1].constant == 0)
2273 if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2274 || IS_INSN_TYPE (STOR_IMM_INS)
2275 || IS_INSN_TYPE (LD_STOR_INS_INC)) & !relocatable)
2277 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2278 changed_already = 0;
2279 /* Convert 32 bits accesses to 16 bits accesses. */
2280 if (instruction->operands[instrtype].op_type == abs32)
2282 if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2285 insn->arg[instrtype].constant =
2286 insn->arg[instrtype].constant & 0xFFFF;
2287 insn->arg[instrtype].size = 16;
2288 changed_already = 1;
2292 /* Convert 16 bits accesses to 32 bits accesses. */
2293 if (instruction->operands[instrtype].op_type == abs16
2294 && changed_already != 1)
2297 insn->arg[instrtype].constant =
2298 insn->arg[instrtype].constant & 0xFFFF;
2299 insn->arg[instrtype].size = 32;
2302 changed_already = 0;
2304 if (IS_INSN_TYPE (BRANCH_INS) && !relocatable)
2306 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2307 if (insn->arg[0].constant == 0x7e || insn->arg[0].constant == 0x7f)
2315 for (i = 0; i < insn->nargs; i++)
2317 if (instruction->operands[i].op_type == cst4
2318 || instruction->operands[i].op_type == rbase_cst4)
2322 /* First, copy the instruction's opcode. */
2323 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2325 /* Swap the argument values in case bcop instructions. */
2326 if (IS_INSN_TYPE (COP_BRANCH_INS))
2328 temp_value = insn->arg[0].constant;
2329 insn->arg[0].constant = insn->arg[1].constant;
2330 insn->arg[1].constant = temp_value;
2333 for (i = 0; i < insn->nargs; i++)
2335 shift_act[i] = instruction->operands[i].shift;
2336 signflag = insn->arg[i].signflag;
2337 processing_arg_number = i;
2338 print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2345 /* Set the appropriate bit for register 'r' in 'mask'.
2346 This indicates that this register is loaded or stored by
2350 mask_reg (int r, unsigned short int *mask)
2352 if ((reg)r > (reg)sp)
2354 as_bad (_("Invalid Register in Register List"));
2361 /* Preprocess register list - create a 16-bit mask with one bit for each
2362 of the 16 general purpose registers. If a bit is set, it indicates
2363 that this register is loaded or stored by the instruction. */
2366 preprocess_reglist (char *param, int *allocated)
2368 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
2369 char *regP; /* Pointer to 'reg_name' string. */
2370 int reg_counter = 0; /* Count number of parsed registers. */
2371 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
2372 char *new_param; /* New created operands string. */
2373 char *paramP = param; /* Pointer to original opearands string. */
2374 char maskstring[10]; /* Array to print the mask as a string. */
2378 /* If 'param' is already in form of a number, no need to preprocess. */
2379 if (strchr (paramP, '{') == NULL)
2382 /* Verifying correct syntax of operand. */
2383 if (strchr (paramP, '}') == NULL)
2384 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2386 while (*paramP++ != '{');
2388 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2390 strncpy (new_param, param, paramP - param - 1);
2392 while (*paramP != '}')
2395 memset (®_name, '\0', sizeof (reg_name));
2397 while (ISALNUM (*paramP))
2400 strncpy (reg_name, regP, paramP - regP);
2402 if (IS_INSN_TYPE (COP_REG_INS))
2404 if ((cr = get_copregister (reg_name)) == nullcopregister)
2405 as_bad (_("Illegal register `%s' in cop-register list"), reg_name);
2406 mask_reg (getreg_image (cr - c0), &mask);
2410 if ((r = get_register (reg_name)) == nullregister)
2411 as_bad (_("Illegal register `%s' in register list"), reg_name);
2412 mask_reg (getreg_image (r), &mask);
2415 if (++reg_counter > MAX_REGS_IN_MASK16)
2416 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2417 MAX_REGS_IN_MASK16);
2419 while (!ISALNUM (*paramP) && *paramP != '}')
2423 if (*++paramP != '\0')
2424 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2428 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2431 sprintf (maskstring, "$0x%x", mask);
2432 strcat (new_param, maskstring);
2436 /* Print the instruction.
2437 Handle also cases where the instruction is relaxable/relocatable. */
2440 print_insn (ins *insn)
2442 unsigned int i, j, insn_size;
2444 unsigned short words[4];
2446 /* Arrange the insn encodings in a WORD size array. */
2447 for (i = 0, j = 0; i < 2; i++)
2449 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2450 words[j++] = output_opcode[i] & 0xFFFF;
2453 /* Handle relaxtion. */
2454 if ((instruction->flags & RELAXABLE) && relocatable)
2458 /* Write the maximal instruction size supported. */
2459 insn_size = INSN_MAX_SIZE;
2462 if (IS_INSN_TYPE (BRANCH_INS))
2465 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2468 else if (IS_INSN_TYPE (CMPBR_INS))
2473 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2475 insn->exp.X_add_symbol,
2476 insn->exp.X_add_number,
2481 insn_size = instruction->size;
2482 this_frag = frag_more (insn_size * 2);
2484 /* Handle relocation. */
2485 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2487 reloc_howto_type *reloc_howto;
2490 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2495 size = bfd_get_reloc_size (reloc_howto);
2497 if (size < 1 || size > 4)
2500 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2501 size, &insn->exp, reloc_howto->pc_relative,
2506 /* Write the instruction encoding to frag. */
2507 for (i = 0; i < insn_size; i++)
2509 md_number_to_chars (this_frag, (valueT) words[i], 2);
2514 /* This is the guts of the machine-dependent assembler. OP points to a
2515 machine dependent instruction. This function is supposed to emit
2516 the frags/bytes it assembles to. */
2519 md_assemble (char *op)
2525 /* Reset global variables for a new instruction. */
2526 reset_vars (op, &crx_ins);
2528 /* Strip the mnemonic. */
2529 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2534 /* Find the instruction. */
2535 instruction = (const inst *) hash_find (crx_inst_hash, op);
2536 if (instruction == NULL)
2538 as_bad (_("Unknown opcode: `%s'"), op);
2542 /* Tie dwarf2 debug info to the address at the start of the insn. */
2543 dwarf2_emit_insn (0);
2545 if (NO_OPERANDS_INST (op))
2546 /* Handle instructions with no operands. */
2549 /* Parse the instruction's operands. */
2550 parse_insn (&crx_ins, param);
2552 /* Assemble the instruction. */
2553 if (assemble_insn (op, &crx_ins) == 0)
2555 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2559 /* Print the instruction. */
2560 print_insn (&crx_ins);