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_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)
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 are a sub-group within load/stor instruction
1671 groups. Therefore, when parsing a Post-Increment insn, we have to advance
1672 the instruction pointer to the start of that sub-group. */
1675 handle_pi_insn (char *operands)
1677 /* Assuming Post-Increment insn has the following format :
1678 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6'). */
1679 if (strstr (operands, ")+") != NULL)
1680 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1684 /* Top level module where instruction parsing starts.
1685 crx_ins - data structure holds some information.
1686 operands - holds the operands part of the whole instruction. */
1689 parse_insn (ins *insn, char *operands)
1691 /* Handle 'excp'/'cinv' */
1692 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1695 insn->arg[0].type = arg_ic;
1696 insn->arg[0].size = 4;
1697 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1698 gettrap (operands) : get_cinv_parameters (operands);
1702 /* Handle load/stor post-increment instructions. */
1703 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS))
1704 handle_pi_insn (operands);
1706 if (operands != NULL)
1707 parse_operands (insn, operands);
1710 /* Cinv instruction requires special handling. */
1713 get_cinv_parameters (char * operand)
1716 int d_used = 0, i_used = 0, u_used = 0;
1720 if (*p == ',' || *p == ' ')
1730 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1733 return ((d_used ? 4 : 0)
1735 + (u_used ? 1 : 0));
1738 /* Retrieve the opcode image of a given register.
1739 If the register is illegal for the current instruction,
1743 getreg_image (reg r)
1745 const reg_entry *reg;
1747 int special_register_flag = 0;
1748 int movpr_flag = 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1750 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1753 if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1))
1754 || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) )
1755 special_register_flag = 1;
1757 /* Check whether the register is in registers table. */
1759 reg = &crx_regtab[r];
1760 /* Check whether the register is in coprocessor registers table. */
1761 else if (r < MAX_COPREG)
1762 reg = &crx_copregtab[r-MAX_REG];
1763 /* Register not found. */
1766 as_bad (_("Unknown register: `%d'"), r);
1770 reg_name = reg->name;
1772 /* Issue a error message when register is illegal. */
1774 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1775 reg_name, ins_parse); \
1781 case CRX_CFG_REGTYPE:
1782 case CRX_MTPR_REGTYPE:
1783 if (movpr_flag && special_register_flag)
1790 case CRX_CS_REGTYPE:
1791 if (!(movpr_flag && special_register_flag))
1803 /* Routine used to get the binary-string equivalent of a integer constant
1804 which currently require currbits to represent itself to be extended to
1807 static unsigned long int
1808 getconstant (unsigned long int x, int nbits)
1811 unsigned long int temp = x;
1819 /* Escape sequence to next 16bit immediate. */
1821 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1826 x |= SET_BITS_MASK (cnt, nbits - cnt);
1828 x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1831 /* The following expression avoids overflow if
1832 'nbits' is the number of bits in 'bfd_vma'. */
1833 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1836 /* Print a constant value to 'output_opcode':
1837 ARG holds the operand's type and value.
1838 SHIFT represents the location of the operand to be print into.
1839 NBITS determines the size (in bits) of the constant. */
1842 print_constant (int nbits, int shift, argument *arg)
1844 unsigned long mask = 0;
1846 long constant = getconstant (arg->constant, nbits);
1854 /* mask the upper part of the constant, that is, the bits
1855 going to the lowest byte of output_opcode[0].
1856 The upper part of output_opcode[1] is always filled,
1857 therefore it is always masked with 0xFFFF. */
1858 mask = (1 << (nbits - 16)) - 1;
1859 /* Divide the constant between two consecutive words :
1861 +---------+---------+---------+---------+
1862 | | X X X X | X X X X | |
1863 +---------+---------+---------+---------+
1864 output_opcode[0] output_opcode[1] */
1866 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1867 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1872 /* Special case - in arg_cr, the SHIFT represents the location
1873 of the REGISTER, not the constant, which is itself not shifted. */
1874 if (arg->type == arg_cr)
1876 CRX_PRINT (0, constant, 0);
1880 /* When instruction size is 3, a 16-bit constant is always
1881 filling the upper part of output_opcode[1]. */
1882 if (instruction->size > 2)
1883 CRX_PRINT (1, constant, WORD_SHIFT);
1885 CRX_PRINT (0, constant, shift);
1889 CRX_PRINT (0, constant, shift);
1894 /* Print an operand to 'output_opcode', which later on will be
1895 printed to the object file:
1896 ARG holds the operand's type, size and value.
1897 SHIFT represents the printing location of operand.
1898 NBITS determines the size (in bits) of a constant operand. */
1901 print_operand (int nbits, int shift, argument *arg)
1906 CRX_PRINT (0, getreg_image (arg->r), shift);
1910 if (arg->cr < c0 || arg->cr > c15)
1911 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1913 CRX_PRINT (0, getreg_image (arg->cr), shift);
1917 if (arg->cr < cs0 || arg->cr > cs15)
1918 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1920 CRX_PRINT (0, getreg_image (arg->cr), shift);
1924 print_constant (nbits, shift, arg);
1929 +--------------------------------+
1930 | reg | r_base | scl| disp |
1931 +--------------------------------+ */
1932 CRX_PRINT (0, getreg_image (arg->r), 12);
1933 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1934 CRX_PRINT (0, arg->scale, 6);
1935 print_constant (nbits, shift, arg);
1939 CRX_PRINT (0, getreg_image (arg->r), shift);
1943 /* case base_cst4. */
1944 if ((instruction->flags & CST4MAP) && cst4flag)
1945 output_opcode[0] |= (getconstant (arg->constant, nbits)
1946 << (shift + REG_SIZE));
1948 /* rbase_dispu<NN> and other such cases. */
1949 print_constant (nbits, shift, arg);
1950 /* Add the register argument to the output_opcode. */
1951 CRX_PRINT (0, getreg_image (arg->r), shift);
1955 print_constant (nbits, shift, arg);
1963 /* Retrieve the number of operands for the current assembled instruction. */
1966 get_number_of_operands (void)
1970 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1975 /* Assemble a single instruction :
1976 Instruction has been parsed and all operand values set appropriately.
1977 Algorithm for assembling -
1978 For instruction to be assembled:
1979 Step 1: Find instruction in the array crx_instruction with same mnemonic.
1980 Step 2: Find instruction with same operand types.
1981 Step 3: If (size_of_operands) match then done, else increment the
1982 array_index and goto Step3.
1983 Step 4: Cannot assemble
1984 Returns 1 upon success, 0 upon failure. */
1987 assemble_insn (char *mnemonic, ins *insn)
1989 /* Argument type of each operand in the instruction we are looking for. */
1990 argtype atyp[MAX_OPERANDS];
1991 /* Argument type of each operand in the current instruction. */
1992 argtype atyp_act[MAX_OPERANDS];
1993 /* Size (in bits) of each operand in the instruction we are looking for. */
1994 int bits[MAX_OPERANDS];
1995 /* Size (in bits) of each operand in the current instruction. */
1996 int bits_act[MAX_OPERANDS];
1997 /* Location (in bits) of each operand in the current instruction. */
1998 int shift_act[MAX_OPERANDS];
2001 int cst4maptype = 0;
2002 int changed_already = 0;
2003 unsigned int temp_value = 0;
2005 /* A pointer to the argument's constant value. */
2006 unsigned long int *cons;
2007 /* Pointer to loop over all cst4_map entries. */
2008 const cst4_entry *cst4_op;
2010 /* Instruction has no operands -> copy only the constant opcode. */
2011 if (insn->nargs == 0)
2013 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2017 /* Find instruction with same number of operands. */
2018 while (get_number_of_operands () != insn->nargs
2019 && IS_INSN_MNEMONIC (mnemonic))
2022 if (!IS_INSN_MNEMONIC (mnemonic))
2025 /* Initialize argument type and size of each given operand. */
2026 for (i = 0; i < insn->nargs; i++)
2028 atyp[i] = insn->arg[i].type;
2029 bits[i] = insn->arg[i].size;
2032 /* Initialize argument type and size of each operand in current inst. */
2037 /* Check we didn't get to end of table. */
2038 && instruction->mnemonic != NULL
2039 /* Check that the actual mnemonic is still available. */
2040 && IS_INSN_MNEMONIC (mnemonic))
2042 /* Check for argement type compatibility. */
2043 for (i = 0; i < insn->nargs; i++)
2045 if (atyp_act[i] == atyp[i])
2055 /* Check for post inc mode of the current instruction. */
2056 if (post_inc_mode == 1 || IS_INSN_TYPE (LD_STOR_INS_INC))
2057 done_flag = (post_inc_mode == IS_INSN_TYPE (LD_STOR_INS_INC));
2062 /* Try again with next instruction. */
2070 /* Check for size compatibility. */
2071 for (i = 0; i < insn->nargs; i++)
2073 if (bits[i] > bits_act[i])
2075 /* Actual size is too small - try again. */
2088 /* Full match is found. */
2095 /* We haven't found a match - instruction can't be assembled. */
2098 /* Full match - print the final image. */
2100 /* Handle positive constants. */
2103 if (IS_INSN_TYPE (LD_STOR_INS) && !relocatable)
2105 /* Get the map type of the instruction. */
2106 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2107 cons = &insn->arg[instrtype].constant;
2108 cst4maptype = instruction->flags & CST4MAP;
2110 switch (cst4maptype)
2113 /* 14 and 15 are reserved escape sequences of dispub4. */
2114 if (*cons == 14 || *cons == 15)
2122 /* Mapping has to be done. */
2123 if (*cons <= 15 && *cons % 2 != 0)
2128 else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2133 if (*cons < 27 && *cons % 2 == 0)
2138 /* Mapping has to be done. */
2139 if (*cons <= 15 && *cons % 4 != 0)
2144 else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2149 if (*cons < 53 && *cons % 4 == 0)
2156 if ((IS_INSN_TYPE (ARITH_BYTE_INS) || IS_INSN_TYPE (ARITH_INS))
2159 /* Check whether a cst4 mapping has to be done. */
2160 if ((instruction->operands[0].op_type == cst4
2161 || instruction->operands[0].op_type == i16)
2162 && (instruction->operands[1].op_type == regr))
2164 /* 'const' equals reserved escape sequences -->>
2165 represent as i16. */
2166 if (insn->arg[0].constant == ESC_16
2167 || insn->arg[0].constant == ESC_32)
2174 /* Loop over cst4_map entries. */
2175 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2178 /* 'const' equals a binary, which is already mapped
2179 by a different value -->> represent as i16. */
2180 if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2181 && cst4_op->binary != cst4_op->value)
2186 /* 'const' equals a value bigger than 16 -->> map to
2187 its binary and represent as cst4. */
2188 else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2189 && insn->arg[0].constant >= 16)
2192 insn->arg[0].constant = cst4_op->binary;
2198 /* Special check for 'addub 0, r0' instruction -
2199 The opcode '0000 0000 0000 0000' is not allowed. */
2200 if (IS_INSN_MNEMONIC ("addub"))
2202 if ((instruction->operands[0].op_type == cst4)
2203 && instruction->operands[1].op_type == regr)
2205 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2210 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
2211 || IS_INSN_TYPE (LD_STOR_INS_INC))
2213 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2214 if (instruction->operands[instrtype].op_type == rbase)
2217 /* Error checking in case of post-increment instruction. */
2218 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2220 if (!((strneq (instruction->mnemonic, "stor", 4))
2221 && (insn->arg[0].type != arg_r)))
2222 if (insn->arg[0].r == insn->arg[1].r)
2223 as_bad (_("Invalid instruction : `%s' Source and Destination register \
2224 same in Post INC mode"), ins_parse);
2226 if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2228 if (instruction->operands[1].op_type == rbase_dispu12)
2230 if (insn->arg[1].constant == 0)
2237 if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2238 || IS_INSN_TYPE (STOR_IMM_INS)
2239 || IS_INSN_TYPE (LD_STOR_INS_INC)) & !relocatable)
2241 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2242 changed_already = 0;
2243 /* Convert 32 bits accesses to 16 bits accesses. */
2244 if (instruction->operands[instrtype].op_type == abs32)
2246 if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2249 insn->arg[instrtype].constant =
2250 insn->arg[instrtype].constant & 0xFFFF;
2251 insn->arg[instrtype].size = 16;
2252 changed_already = 1;
2256 /* Convert 16 bits accesses to 32 bits accesses. */
2257 if (instruction->operands[instrtype].op_type == abs16
2258 && changed_already != 1)
2261 insn->arg[instrtype].constant =
2262 insn->arg[instrtype].constant & 0xFFFF;
2263 insn->arg[instrtype].size = 32;
2266 changed_already = 0;
2268 if (IS_INSN_TYPE (BRANCH_INS) && !relocatable)
2270 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2271 if (insn->arg[0].constant == 0x7e || insn->arg[0].constant == 0x7f)
2279 for (i = 0; i < insn->nargs; i++)
2281 if (instruction->operands[i].op_type == cst4
2282 || instruction->operands[i].op_type == rbase_cst4)
2286 /* First, copy the instruction's opcode. */
2287 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2289 /* Swap the argument values in case bcop instructions. */
2290 if (IS_INSN_TYPE (COP_BRANCH_INS))
2292 temp_value = insn->arg[0].constant;
2293 insn->arg[0].constant = insn->arg[1].constant;
2294 insn->arg[1].constant = temp_value;
2297 for (i = 0; i < insn->nargs; i++)
2299 shift_act[i] = instruction->operands[i].shift;
2300 signflag = insn->arg[i].signflag;
2301 processing_arg_number = i;
2302 print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2309 /* Set the appropriate bit for register 'r' in 'mask'.
2310 This indicates that this register is loaded or stored by
2314 mask_reg (int r, unsigned short int *mask)
2316 if ((reg)r > (reg)sp)
2318 as_bad (_("Invalid Register in Register List"));
2325 /* Preprocess register list - create a 16-bit mask with one bit for each
2326 of the 16 general purpose registers. If a bit is set, it indicates
2327 that this register is loaded or stored by the instruction. */
2330 preprocess_reglist (char *param, int *allocated)
2332 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
2333 char *regP; /* Pointer to 'reg_name' string. */
2334 int reg_counter = 0; /* Count number of parsed registers. */
2335 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
2336 char *new_param; /* New created operands string. */
2337 char *paramP = param; /* Pointer to original opearands string. */
2338 char maskstring[10]; /* Array to print the mask as a string. */
2342 /* If 'param' is already in form of a number, no need to preprocess. */
2343 if (strchr (paramP, '{') == NULL)
2346 /* Verifying correct syntax of operand. */
2347 if (strchr (paramP, '}') == NULL)
2348 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2350 while (*paramP++ != '{');
2352 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2354 strncpy (new_param, param, paramP - param - 1);
2356 while (*paramP != '}')
2359 memset (®_name, '\0', sizeof (reg_name));
2361 while (ISALNUM (*paramP))
2364 strncpy (reg_name, regP, paramP - regP);
2366 if (IS_INSN_TYPE (COP_REG_INS))
2368 if ((cr = get_copregister (reg_name)) == nullcopregister)
2369 as_bad (_("Illegal register `%s' in cop-register list"), reg_name);
2370 mask_reg (getreg_image (cr - c0), &mask);
2374 if ((r = get_register (reg_name)) == nullregister)
2375 as_bad (_("Illegal register `%s' in register list"), reg_name);
2376 mask_reg (getreg_image (r), &mask);
2379 if (++reg_counter > MAX_REGS_IN_MASK16)
2380 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2381 MAX_REGS_IN_MASK16);
2383 while (!ISALNUM (*paramP) && *paramP != '}')
2387 if (*++paramP != '\0')
2388 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2392 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2395 sprintf (maskstring, "$0x%x", mask);
2396 strcat (new_param, maskstring);
2400 /* Print the instruction.
2401 Handle also cases where the instruction is relaxable/relocatable. */
2404 print_insn (ins *insn)
2406 unsigned int i, j, insn_size;
2408 unsigned short words[4];
2410 /* Arrange the insn encodings in a WORD size array. */
2411 for (i = 0, j = 0; i < 2; i++)
2413 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2414 words[j++] = output_opcode[i] & 0xFFFF;
2417 /* Handle relaxtion. */
2418 if ((instruction->flags & RELAXABLE) && relocatable)
2422 /* Write the maximal instruction size supported. */
2423 insn_size = INSN_MAX_SIZE;
2426 if (IS_INSN_TYPE (BRANCH_INS))
2429 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2432 else if (IS_INSN_TYPE (CMPBR_INS))
2437 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2439 insn->exp.X_add_symbol,
2440 insn->exp.X_add_number,
2445 insn_size = instruction->size;
2446 this_frag = frag_more (insn_size * 2);
2448 /* Handle relocation. */
2449 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2451 reloc_howto_type *reloc_howto;
2454 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2459 size = bfd_get_reloc_size (reloc_howto);
2461 if (size < 1 || size > 4)
2464 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2465 size, &insn->exp, reloc_howto->pc_relative,
2470 /* Write the instruction encoding to frag. */
2471 for (i = 0; i < insn_size; i++)
2473 md_number_to_chars (this_frag, (valueT) words[i], 2);
2478 /* This is the guts of the machine-dependent assembler. OP points to a
2479 machine dependent instruction. This function is supposed to emit
2480 the frags/bytes it assembles to. */
2483 md_assemble (char *op)
2489 /* Reset global variables for a new instruction. */
2490 reset_vars (op, &crx_ins);
2492 /* Strip the mnemonic. */
2493 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2498 /* Find the instruction. */
2499 instruction = (const inst *) hash_find (crx_inst_hash, op);
2500 if (instruction == NULL)
2502 as_bad (_("Unknown opcode: `%s'"), op);
2506 /* Tie dwarf2 debug info to the address at the start of the insn. */
2507 dwarf2_emit_insn (0);
2509 if (NO_OPERANDS_INST (op))
2510 /* Handle instructions with no operands. */
2513 /* Parse the instruction's operands. */
2514 parse_insn (&crx_ins, param);
2516 /* Assemble the instruction. */
2517 if (assemble_insn (op, &crx_ins) == 0)
2519 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2523 /* Print the instruction. */
2524 print_insn (&crx_ins);