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 /* Holds the current processed argument number. */
104 /* Generic assembler global variables which must be defined by all targets. */
106 /* Characters which always start a comment. */
107 const char comment_chars[] = "#";
109 /* Characters which start a comment at the beginning of a line. */
110 const char line_comment_chars[] = "#";
112 /* This array holds machine specific line separator characters. */
113 const char line_separator_chars[] = ";";
115 /* Chars that can be used to separate mant from exp in floating point nums. */
116 const char EXP_CHARS[] = "eE";
118 /* Chars that mean this number is a floating point constant as in 0f12.456 */
119 const char FLT_CHARS[] = "f'";
121 /* Target-specific multicharacter options, not const-declared at usage. */
122 const char *md_shortopts = "";
123 struct option md_longopts[] =
125 {NULL, no_argument, NULL, 0}
127 size_t md_longopts_size = sizeof (md_longopts);
129 /* This table describes all the machine specific pseudo-ops
130 the assembler has to support. The fields are:
131 *** Pseudo-op name without dot.
132 *** Function to call to execute this pseudo-op.
133 *** Integer arg to pass to the function. */
135 const pseudo_typeS md_pseudo_table[] =
137 /* In CRX machine, align is in bytes (not a ptwo boundary). */
138 {"align", s_align_bytes, 0},
142 const relax_typeS md_relax_table[] =
145 {0xfa, -0x100, 2, 1}, /* 8 */
146 {0xfffe, -0x10000, 4, 2}, /* 16 */
147 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
150 {0xfffe, -0x10000, 4, 4}, /* 16 */
151 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
154 {0xfe, -0x100, 4, 6}, /* 8 */
155 {0xfffffe, -0x1000000, 6, 0} /* 24 */
158 static void reset_vars (char *, ins *);
159 static reg get_register (char *);
160 static copreg get_copregister (char *);
161 static void set_operand_size (ins *);
162 static argtype getarg_type (operand_type);
163 static int getbits (operand_type);
164 static int get_flags (operand_type);
165 static int get_number_of_operands (void);
166 static void parse_operand (char *, ins *);
167 static int gettrap (char *);
168 static void handle_LoadStor (char *);
169 static int get_cinv_parameters (char *);
170 static unsigned long getconstant (unsigned long, int);
171 static int getreg_image (reg);
172 static void parse_operands (ins *, char *);
173 static void parse_insn (ins *, char *);
174 static void print_operand (int, int, argument *);
175 static void print_constant (int, int, argument *);
176 static int exponent2scale (int);
177 static void mask_const (unsigned long *, int);
178 static void mask_reg (int, unsigned short *);
179 static int process_label_constant (char *, ins *);
180 static void set_operand (char *, ins *);
181 static char * preprocess_reglist (char *, int *);
182 static int assemble_insn (char *, ins *);
183 static void print_insn (ins *);
185 /* Return the bit size for a given operand. */
188 getbits (operand_type op)
191 return crx_optab[op].bit_size;
196 /* Return the argument type of a given operand. */
199 getarg_type (operand_type op)
202 return crx_optab[op].arg_type;
207 /* Return the flags of a given operand. */
210 get_flags (operand_type op)
213 return crx_optab[op].flags;
218 /* Get the core processor register 'reg_name'. */
221 get_register (char *reg_name)
223 const reg_entry *reg;
225 reg = (const reg_entry *) hash_find (reg_hash, reg_name);
228 return reg->value.reg_val;
233 /* Get the coprocessor register 'copreg_name'. */
236 get_copregister (char *copreg_name)
238 const reg_entry *copreg;
240 copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
243 return copreg->value.copreg_val;
245 return nullcopregister;
248 /* Mask a constant to the number of bits it is to be mapped to. */
251 mask_const (unsigned long int *t, int size)
253 *t &= (((LONGLONG)1 << size) - 1);
256 /* Round up a section size to the appropriate boundary. */
259 md_section_align (segT seg, valueT val)
261 /* Round .text section to a multiple of 2. */
262 if (seg == text_section)
263 return (val + 1) & ~1;
267 /* Parse an operand that is machine-specific (remove '*'). */
270 md_operand (expressionS * exp)
272 char c = *input_line_pointer;
277 input_line_pointer++;
285 /* Reset global variables before parsing a new instruction. */
288 reset_vars (char *op, ins *crx_ins)
292 cur_arg_num = relocatable = size_was_set = signflag = cst4flag = 0;
293 memset (& output_opcode, '\0', sizeof (output_opcode));
295 /* Memset the 'signflag' field in every argument. */
296 for (i = 0; i < MAX_OPERANDS; i++)
297 crx_ins->arg[i].signflag = 0;
299 /* Save a copy of the original OP (used in error messages). */
300 strcpy (ins_parse, op);
303 /* This macro decides whether a particular reloc is an entry in a
304 switch table. It is used when relaxing, because the linker needs
305 to know about all such entries so that it can adjust them if
308 #define SWITCH_TABLE(fix) \
309 ( (fix)->fx_addsy != NULL \
310 && (fix)->fx_subsy != NULL \
311 && S_GET_SEGMENT ((fix)->fx_addsy) == \
312 S_GET_SEGMENT ((fix)->fx_subsy) \
313 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
314 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
315 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
316 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
318 /* See whether we need to force a relocation into the output file.
319 This is used to force out switch and PC relative relocations when
323 crx_force_relocation (fixS *fix)
325 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
331 /* Generate a relocation entry for a fixup. */
334 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
338 reloc = xmalloc (sizeof (arelent));
339 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
340 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
341 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
342 reloc->addend = fixP->fx_offset;
344 if (fixP->fx_subsy != NULL)
346 if (SWITCH_TABLE (fixP))
348 /* Keep the current difference in the addend. */
349 reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
350 - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
352 switch (fixP->fx_r_type)
354 case BFD_RELOC_CRX_NUM8:
355 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
357 case BFD_RELOC_CRX_NUM16:
358 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
360 case BFD_RELOC_CRX_NUM32:
361 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
370 /* We only resolve difference expressions in the same section. */
371 as_bad_where (fixP->fx_file, fixP->fx_line,
372 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
373 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
374 segment_name (fixP->fx_addsy
375 ? S_GET_SEGMENT (fixP->fx_addsy)
377 S_GET_NAME (fixP->fx_subsy),
378 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
382 assert ((int) fixP->fx_r_type > 0);
383 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
385 if (reloc->howto == (reloc_howto_type *) NULL)
387 as_bad_where (fixP->fx_file, fixP->fx_line,
388 _("internal error: reloc %d (`%s') not supported by object file format"),
390 bfd_get_reloc_code_name (fixP->fx_r_type));
393 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
398 /* Prepare machine-dependent frags for relaxation. */
401 md_estimate_size_before_relax (fragS *fragp, asection *seg)
403 /* If symbol is undefined or located in a different section,
404 select the largest supported relocation. */
405 relax_substateT subtype;
406 relax_substateT rlx_state[] = {0, 2,
410 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
412 if (fragp->fr_subtype == rlx_state[subtype]
413 && (!S_IS_DEFINED (fragp->fr_symbol)
414 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
416 fragp->fr_subtype = rlx_state[subtype + 1];
421 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
424 return md_relax_table[fragp->fr_subtype].rlx_length;
428 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
430 /* 'opcode' points to the start of the instruction, whether
431 we need to change the instruction's fixed encoding. */
432 char *opcode = fragP->fr_literal + fragP->fr_fix;
433 bfd_reloc_code_real_type reloc;
435 subseg_change (sec, 0);
437 switch (fragP->fr_subtype)
440 reloc = BFD_RELOC_CRX_REL8;
444 reloc = BFD_RELOC_CRX_REL16;
448 reloc = BFD_RELOC_CRX_REL32;
451 reloc = BFD_RELOC_CRX_REL16;
455 reloc = BFD_RELOC_CRX_REL32;
458 reloc = BFD_RELOC_CRX_REL8_CMP;
462 reloc = BFD_RELOC_CRX_REL24;
469 fix_new (fragP, fragP->fr_fix,
470 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
471 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
473 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
476 /* Process machine-dependent command line options. Called once for
477 each option on the command line that the machine-independent part of
478 GAS does not understand. */
481 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
486 /* Machine-dependent usage-output. */
489 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
494 /* Turn a string in input_line_pointer into a floating point constant
495 of type TYPE, and store the appropriate bytes in *LITP. The number
496 of LITTLENUMS emitted is stored in *SIZEP. An error message is
497 returned, or NULL on OK. */
500 md_atof (int type, char *litP, int *sizeP)
503 LITTLENUM_TYPE words[4];
519 return _("bad call to md_atof");
522 t = atof_ieee (input_line_pointer, type, words);
524 input_line_pointer = t;
528 if (! target_big_endian)
530 for (i = prec - 1; i >= 0; i--)
532 md_number_to_chars (litP, (valueT) words[i], 2);
538 for (i = 0; i < prec; i++)
540 md_number_to_chars (litP, (valueT) words[i], 2);
548 /* Apply a fixS (fixup of an instruction or data that we didn't have
549 enough info to complete immediately) to the data in a frag.
550 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
551 relaxation of debug sections, this function is called only when
552 fixuping relocations of debug sections. */
555 md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
558 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
561 switch (fixP->fx_r_type)
563 case BFD_RELOC_CRX_NUM8:
564 bfd_put_8 (stdoutput, (unsigned char) val, buf);
566 case BFD_RELOC_CRX_NUM16:
567 bfd_put_16 (stdoutput, val, buf);
569 case BFD_RELOC_CRX_NUM32:
570 bfd_put_32 (stdoutput, val, buf);
573 /* We shouldn't ever get here because linkrelax is nonzero. */
580 if (fixP->fx_addsy == NULL
581 && fixP->fx_pcrel == 0)
584 if (fixP->fx_pcrel == 1
585 && fixP->fx_addsy != NULL
586 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
590 /* The location from which a PC relative jump should be calculated,
591 given a PC relative reloc. */
594 md_pcrel_from (fixS *fixp)
596 return fixp->fx_frag->fr_address + fixp->fx_where;
599 /* This function is called once, at assembler startup time. This should
600 set up all the tables, etc that the MD part of the assembler needs. */
605 const char *hashret = NULL;
608 /* Set up a hash table for the instructions. */
609 if ((crx_inst_hash = hash_new ()) == NULL)
610 as_fatal (_("Virtual memory exhausted"));
612 while (crx_instruction[i].mnemonic != NULL)
614 const char *mnemonic = crx_instruction[i].mnemonic;
616 hashret = hash_insert (crx_inst_hash, mnemonic,
617 (PTR) &crx_instruction[i]);
619 if (hashret != NULL && *hashret != '\0')
620 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
621 *hashret == 0 ? _("(unknown reason)") : hashret);
623 /* Insert unique names into hash table. The CRX instruction set
624 has many identical opcode names that have different opcodes based
625 on the operands. This hash table then provides a quick index to
626 the first opcode with a particular name in the opcode table. */
631 while (crx_instruction[i].mnemonic != NULL
632 && streq (crx_instruction[i].mnemonic, mnemonic));
635 /* Initialize reg_hash hash table. */
636 if ((reg_hash = hash_new ()) == NULL)
637 as_fatal (_("Virtual memory exhausted"));
640 const reg_entry *regtab;
642 for (regtab = crx_regtab;
643 regtab < (crx_regtab + NUMREGS); regtab++)
645 hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
647 as_fatal (_("Internal Error: Can't hash %s: %s"),
653 /* Initialize copreg_hash hash table. */
654 if ((copreg_hash = hash_new ()) == NULL)
655 as_fatal (_("Virtual memory exhausted"));
658 const reg_entry *copregtab;
660 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
663 hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
665 as_fatal (_("Internal Error: Can't hash %s: %s"),
670 /* Set linkrelax here to avoid fixups in most sections. */
674 /* Set the number of bits corresponding to a constant -
675 here we check for possible overflow cases. */
678 set_operand_size (ins * crx_ins)
681 const cst4_entry *cst4_op;
682 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
683 unsigned long int temp = cur_arg->constant;
685 /* If the constant's size was already set - nothing to do. */
689 /* Already dealt with negative numbers in process_label_constants. */
696 /* Arithmetic instructions :
697 16-bit positive signed immediate -->> represent as 32-bit. */
698 if (IS_INSN_TYPE (ARITH_INS) && !relocatable && !signflag)
706 /* Index addressing mode :
707 6-bit positive signed immediate -->> represent as 22-bit. */
708 if (IS_INSN_TYPE (LD_STOR_INS)
709 || IS_INSN_TYPE (STOR_IMM_INS)
710 || IS_INSN_TYPE (CSTBIT_INS))
712 if (!signflag && cur_arg->type == arg_idxr)
720 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
723 /* load/stor instructions :
724 16-bit positive signed immediate -->> represent as 32-bit. */
725 if (IS_INSN_TYPE (LD_STOR_INS))
727 if (!signflag && cur_arg->type == arg_cr)
735 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
738 /* Post-increment mode :
739 12-bit positive signed immediate -->> represent as 28-bit. */
740 if (IS_INSN_TYPE (CSTBIT_INS)
741 || IS_INSN_TYPE (LD_STOR_INS_INC)
742 || IS_INSN_TYPE (STOR_IMM_INS))
744 if (!signflag && cur_arg->type == arg_cr)
749 if (IS_INSN_TYPE (LD_STOR_INS_INC))
750 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
753 if (IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS))
756 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
762 /* Handle negative cst4 mapping for arithmetic/cmp&br operations. */
763 if (signflag && !relocatable
764 && ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
765 || ((IS_INSN_TYPE (CMPBR_INS) && cur_arg_num == 0))))
767 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
769 if (cur_arg->constant == (unsigned int)(-cst4_op->value))
772 cur_arg->constant = cst4_op->binary;
773 cur_arg->signflag = 0;
778 /* Because of the cst4 mapping -- -1 and -4 already handled above
779 as well as for relocatable cases. */
780 if (signflag && IS_INSN_TYPE (ARITH_BYTE_INS))
784 if (cur_arg->constant <= 0xffff)
787 /* Setting to 18 so that there is no match. */
795 if (signflag && IS_INSN_TYPE (ARITH_INS))
797 /* For all immediates which can be expressed in less than 16 bits. */
798 if (cur_arg->constant <= 0xffff && !relocatable)
803 /* Either it is relocatable or not representable in 16 bits. */
804 if (cur_arg->constant < 0xffffffff || relocatable)
813 if (signflag && !relocatable)
817 cur_arg->size = cnt_bits;
819 /* Checking for Error Conditions. */
820 if (IS_INSN_TYPE (ARITH_INS) && !signflag)
823 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
824 cnt_bits, ins_parse);
826 else if (IS_INSN_TYPE (ARITH_BYTE_INS) && !signflag)
829 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
830 cnt_bits, ins_parse);
834 /* Handle the constants immediate/absolute values and
835 Labels (jump targets/Memory locations). */
838 process_label_constant (char *str, ins * crx_ins)
841 unsigned long int temp, cnt;
842 const cst4_entry *cst4_op;
844 int constant_val = 0;
845 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
847 save = input_line_pointer;
855 else if (str[0] == '+')
858 input_line_pointer = str;
860 expression (&crx_ins->exp);
862 switch (crx_ins->exp.X_op)
866 /* Missing or bad expr becomes absolute 0. */
867 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
869 crx_ins->exp.X_op = O_constant;
870 crx_ins->exp.X_add_number = 0;
871 crx_ins->exp.X_add_symbol = (symbolS *) 0;
872 crx_ins->exp.X_op_symbol = (symbolS *) 0;
876 cur_arg->constant = constant_val = crx_ins->exp.X_add_number;
877 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
883 unsigned int jump_value = 0;
884 int BR_MASK = 0, BR_SIZE = 0;
891 strncat (temp_str, str, strlen (str));
892 temp64 = strtoll (temp_str, (char **) &ptr,0);
895 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
898 /* Determine the branch size. */
899 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
900 if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
901 || ((jump_value & 0xFFFFFF00) == 0x0))
907 if (((jump_value & 0xFF000000) == 0xFF000000)
908 || ((jump_value & 0xFF000000) == 0x0))
913 jump_value = jump_value >> 1;
914 cur_arg->constant = jump_value & BR_MASK;
915 cur_arg->size = BR_SIZE;
917 cur_arg->signflag = signflag;
918 input_line_pointer = save;
919 return crx_ins->exp.X_op;
922 if (IS_INSN_TYPE (BRANCH_INS)
923 || IS_INSN_MNEMONIC ("bal")
924 || IS_INSN_TYPE (DCR_BRANCH_INS))
929 unsigned int jump_value = 0;
930 int BR_MASK = 0, BR_SIZE = 0;
938 strncat (temp_str, str, strlen (str));
939 temp64 = strtoll (temp_str, (char **) &ptr,0);
942 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
945 /* Determine the branch size. */
946 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
947 if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
948 && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
949 || ((jump_value & 0xFFFFFF00) == 0x0)))
954 else if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
955 || ((jump_value & 0xFFFF0000) == 0x0))
962 BR_MASK = 0xFFFFFFFF;
965 jump_value = jump_value >> 1;
966 cur_arg->constant = jump_value & BR_MASK;
967 cur_arg->size = BR_SIZE;
969 cur_arg->signflag = signflag;
970 input_line_pointer = save;
971 return crx_ins->exp.X_op;
973 /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
974 if (constant_val < 0 && signflag != 1
975 && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
976 && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
977 && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
979 cur_arg->constant = ~(cur_arg->constant) + 1;
982 /* For load/store instruction when the value is in the offset part. */
983 if (constant_val < 0 && signflag != 1
984 && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
985 || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
987 if (cur_arg->type == arg_cr || cur_arg->type == arg_idxr)
989 cur_arg->constant = ~(cur_arg->constant) + 1;
995 /* Signflag in never set in case of load store instructions
996 Mapping in case of only the arithinsn case. */
997 if ((cur_arg->constant != 1 && cur_arg->constant != 4)
998 || (!IS_INSN_TYPE (ARITH_INS)
999 && !IS_INSN_TYPE (ARITH_BYTE_INS)
1000 && !IS_INSN_TYPE (CMPBR_INS)))
1002 /* Counting the number of bits required to represent
1005 temp = cur_arg->constant - 1;
1011 cur_arg->size = cnt + 1;
1012 cur_arg->constant = ~(cur_arg->constant) + 1;
1013 if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
1018 temp64 = strtoull (str, (char **) &ptr, 0);
1022 if (IS_INSN_TYPE (ARITH_INS))
1024 if (cur_arg->size > 32
1025 || (temp64 > ULONG_MAX))
1027 if (cur_arg->size > 32)
1028 as_bad (_("In Instruction `%s': Immediate size is \
1029 %lu bits cannot be accomodated"),
1030 ins_parse, cnt + 1);
1032 if (temp64 > ULONG_MAX)
1033 as_bad (_("Value given more than 32 bits in \
1034 Instruction `%s'"), ins_parse);
1037 if (IS_INSN_TYPE (ARITH_BYTE_INS))
1039 if (cur_arg->size > 16
1040 || !((temp64 & 0xFFFF0000) == 0xFFFF0000
1041 || (temp64 & 0xFFFF0000) == 0x0))
1043 if (cur_arg->size > 16)
1044 as_bad (_("In Instruction `%s': Immediate size is \
1045 %lu bits cannot be accomodated"),
1046 ins_parse, cnt + 1);
1048 if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
1049 || (temp64 & 0xFFFF0000) == 0x0))
1050 as_bad (_("Value given more than 16 bits in \
1051 Instruction `%s'"), ins_parse);
1055 if (IS_INSN_TYPE (LD_STOR_INS) && cur_arg->type == arg_cr)
1057 /* Cases handled ---
1058 dispub4/dispuw4/dispud4 and for load store dispubwd4
1059 is applicable only. */
1060 if (cur_arg->size <= 4)
1063 /* Argument number is checked to distinguish between
1064 immediate and displacement in cmpbranch and bcopcond. */
1065 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1066 && cur_arg_num == 2)
1068 if (cur_arg->size != 32)
1069 cur_arg->constant >>= 1;
1072 mask_const (&cur_arg->constant, (int) cur_arg->size);
1077 /* Argument number is checked to distinguish between
1078 immediate and displacement in cmpbranch and bcopcond. */
1079 if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1080 && cur_arg_num == 2)
1081 || IS_INSN_TYPE (BRANCH_NEQ_INS))
1083 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1085 if (cur_arg->constant == 0)
1086 as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
1089 if (cur_arg->constant % 2 != 0)
1090 as_bad (_("Instruction `%s' has odd offset"), ins_parse);
1092 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1094 if (cur_arg->constant > 32 || cur_arg->constant < 2)
1095 as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1096 ins_parse, cur_arg->constant);
1098 cur_arg->constant -= 2;
1101 cur_arg->constant >>= 1;
1102 set_operand_size (crx_ins);
1105 /* Compare branch argument number zero to be compared -
1107 if (IS_INSN_TYPE (CMPBR_INS) && cur_arg_num == 0)
1109 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
1111 if (cur_arg->constant == (unsigned int)cst4_op->value)
1113 cur_arg->constant = cst4_op->binary;
1119 as_bad (_("Instruction `%s' has invalid imm value as an \
1120 operand"), ins_parse);
1127 crx_ins->rtype = BFD_RELOC_NONE;
1130 switch (cur_arg->type)
1133 /* Have to consider various cases here. */
1134 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1135 /* 'load/stor <num>(reg)+'. */
1136 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
1137 else if (IS_INSN_TYPE (CSTBIT_INS)
1138 || IS_INSN_TYPE (STOR_IMM_INS))
1139 /* 'stor imm' and '[stc]bit'. */
1140 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
1142 /* General load/stor instruction. */
1143 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
1146 /* Index Mode 22 bits relocation. */
1147 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
1150 /* Absolute types. */
1151 /* Case for jumps...dx types. */
1153 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
1154 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1155 else if (IS_INSN_TYPE (BRANCH_INS))
1156 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1157 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
1158 || IS_INSN_TYPE (CSTBIT_INS))
1159 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
1160 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1161 crx_ins->rtype = BFD_RELOC_CRX_REL4;
1162 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1163 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1166 if (IS_INSN_TYPE (ARITH_INS))
1167 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
1168 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1169 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
1174 cur_arg->size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
1181 input_line_pointer = save;
1182 cur_arg->signflag = signflag;
1183 return crx_ins->exp.X_op;
1186 /* Get the values of the scale to be encoded -
1187 used for the scaled index mode of addressing. */
1190 exponent2scale (int val)
1194 /* If 'val' is 0, the following 'for' will be an endless loop. */
1198 for (exponent = 0; (val != 1); val >>= 1, exponent++)
1204 /* Parsing different types of operands
1205 -> constants Immediate/Absolute/Relative numbers
1206 -> Labels Relocatable symbols
1207 -> (rbase) Register base
1208 -> disp(rbase) Register relative
1209 -> disp(rbase)+ Post-increment mode
1210 -> disp(rbase,ridx,scl) Register index mode */
1213 set_operand (char *operand, ins * crx_ins)
1215 char *operandS; /* Pointer to start of sub-opearand. */
1216 char *operandE; /* Pointer to end of sub-opearand. */
1219 char *input_save, c;
1220 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
1222 /* Initialize pointers. */
1223 operandS = operandE = operand;
1225 switch (cur_arg->type)
1227 case arg_sc: /* Case *+0x18. */
1228 case arg_ic: /* Case $0x18. */
1230 case arg_c: /* Case 0x18. */
1232 process_label_constant (operandS, crx_ins/*, op_num*/);
1234 if (cur_arg->type != arg_ic)
1235 cur_arg->type = arg_c;
1238 case arg_icr: /* Case $0x18(r1). */
1240 case arg_cr: /* Case 0x18(r1). */
1241 /* Set displacement constant. */
1242 while (*operandE != '(')
1245 process_label_constant (operandS, crx_ins/*, op_num*/);
1246 operandS = operandE;
1247 case arg_rbase: /* Case (r1). */
1249 /* Set register base. */
1250 while (*operandE != ')')
1253 if ((cur_arg->r = get_register (operandS)) == nullregister)
1254 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1255 operandS, ins_parse);
1257 if (cur_arg->type != arg_rbase)
1258 cur_arg->type = arg_cr;
1262 /* Set displacement constant. */
1263 while (*operandE != '(')
1266 process_label_constant (operandS, crx_ins);
1267 operandS = ++operandE;
1269 /* Set register base. */
1270 while ((*operandE != ',') && (! ISSPACE (*operandE)))
1273 if ((cur_arg->r = get_register (operandS)) == nullregister)
1274 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1275 operandS, ins_parse);
1277 /* Skip leading white space. */
1278 while (ISSPACE (*operandE))
1280 operandS = operandE;
1282 /* Set register index. */
1283 while ((*operandE != ')') && (*operandE != ','))
1288 if ((cur_arg->i_r = get_register (operandS)) == nullregister)
1289 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1290 operandS, ins_parse);
1292 /* Skip leading white space. */
1293 while (ISSPACE (*operandE))
1295 operandS = operandE;
1297 /* Set the scale. */
1302 while (*operandE != ')')
1306 /* Preprocess the scale string. */
1307 input_save = input_line_pointer;
1308 input_line_pointer = operandS;
1309 expression (&scale);
1310 input_line_pointer = input_save;
1312 scale_val = scale.X_add_number;
1314 /* Check if the scale value is legal. */
1315 if (scale_val != 1 && scale_val != 2
1316 && scale_val != 4 && scale_val != 8)
1317 as_bad (_("Illegal Scale - `%d'"), scale_val);
1319 cur_arg->scale = exponent2scale (scale_val);
1328 /* Parse a single operand.
1329 operand - Current operand to parse.
1330 crx_ins - Current assembled instruction. */
1333 parse_operand (char *operand, ins * crx_ins)
1336 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
1338 /* Initialize the type to NULL before parsing. */
1339 cur_arg->type = nullargs;
1341 /* Check whether this is a general processor register. */
1342 if ((ret_val = get_register (operand)) != nullregister)
1344 cur_arg->type = arg_r;
1345 cur_arg->r = ret_val;
1349 /* Check whether this is a core [special] coprocessor register. */
1350 if ((ret_val = get_copregister (operand)) != nullcopregister)
1352 cur_arg->type = arg_copr;
1354 cur_arg->type = arg_copsr;
1355 cur_arg->cr = ret_val;
1359 /* Deal with special characters. */
1363 if (strchr (operand, '(') != NULL)
1364 cur_arg->type = arg_icr;
1366 cur_arg->type = arg_ic;
1371 cur_arg->type = arg_sc;
1376 cur_arg->type = arg_rbase;
1384 if (strchr (operand, '(') != NULL)
1386 if (strchr (operand, ',') != NULL
1387 && (strchr (operand, ',') > strchr (operand, '(')))
1388 cur_arg->type = arg_idxr;
1390 cur_arg->type = arg_cr;
1393 cur_arg->type = arg_c;
1396 /* Parse an operand according to its type. */
1398 cur_arg->constant = 0;
1399 set_operand (operand, crx_ins);
1401 /* Determine argument size. */
1403 switch (cur_arg->type)
1405 /* The following are all registers, so set their size to REG_SIZE. */
1410 cur_arg->size = REG_SIZE;
1419 set_operand_size (crx_ins);
1423 as_bad (_("Illegal argument type in instruction `%s'"), ins_parse);
1428 /* Parse the various operands. Each operand is then analyzed to fillup
1429 the fields in the crx_ins data structure. */
1432 parse_operands (ins * crx_ins, char *operands)
1434 char *operandS; /* Operands string. */
1435 char *operandH, *operandT; /* Single operand head/tail pointers. */
1436 int allocated = 0; /* Indicates a new operands string was allocated. */
1437 char *operand[MAX_OPERANDS]; /* Separating the operands. */
1438 int op_num = 0; /* Current operand number we are parsing. */
1439 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
1440 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
1442 /* Preprocess the list of registers, if necessary. */
1443 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
1444 preprocess_reglist (operands, &allocated) : operands;
1446 while (*operandT != '\0')
1448 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1451 operand[op_num++] = strdup (operandH);
1452 operandH = operandT;
1456 if (*operandT == ' ')
1457 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1459 if (*operandT == '(')
1461 else if (*operandT == '[')
1462 sq_bracket_flag = 1;
1464 if (*operandT == ')')
1469 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1471 else if (*operandT == ']')
1473 if (sq_bracket_flag)
1474 sq_bracket_flag = 0;
1476 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1479 if (bracket_flag == 1 && *operandT == ')')
1481 else if (sq_bracket_flag == 1 && *operandT == ']')
1482 sq_bracket_flag = 0;
1487 /* Adding the last operand. */
1488 operand[op_num++] = strdup (operandH);
1489 crx_ins->nargs = op_num;
1491 /* Verifying correct syntax of operands (all brackets should be closed). */
1492 if (bracket_flag || sq_bracket_flag)
1493 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1495 /* Now we parse each operand separately. */
1496 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1498 cur_arg_num = op_num;
1499 parse_operand (operand[op_num], crx_ins);
1500 free (operand[op_num]);
1507 /* Get the trap index in dispatch table, given its name.
1508 This routine is used by assembling the 'excp' instruction. */
1513 const trap_entry *trap;
1515 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1516 if (strcasecmp (trap->name, s) == 0)
1519 as_bad (_("Unknown exception: `%s'"), s);
1523 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1524 sub-group within load/stor instruction groups.
1525 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1526 advance the instruction pointer to the start of that sub-group (that is, up
1527 to the first instruction of that type).
1528 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1531 handle_LoadStor (char *operands)
1533 /* Post-Increment instructions precede Store-Immediate instructions in
1534 CRX instruction table, hence they are handled before.
1535 This synchronization should be kept. */
1537 /* Assuming Post-Increment insn has the following format :
1538 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1539 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1540 if (strstr (operands, ")+") != NULL)
1542 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1547 /* Assuming Store-Immediate insn has the following format :
1548 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1549 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1550 if (strstr (operands, "$") != NULL)
1551 while (! IS_INSN_TYPE (STOR_IMM_INS))
1555 /* Top level module where instruction parsing starts.
1556 crx_ins - data structure holds some information.
1557 operands - holds the operands part of the whole instruction. */
1560 parse_insn (ins *insn, char *operands)
1562 /* Handle 'excp'/'cinv' */
1563 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1566 insn->arg[0].type = arg_ic;
1567 insn->arg[0].size = 4;
1568 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1569 gettrap (operands) : get_cinv_parameters (operands);
1573 /* Handle load/stor unique instructions before parsing. */
1574 if (IS_INSN_TYPE (LD_STOR_INS))
1575 handle_LoadStor (operands);
1577 if (operands != NULL)
1578 parse_operands (insn, operands);
1581 /* Cinv instruction requires special handling. */
1584 get_cinv_parameters (char * operand)
1587 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1591 if (*p == ',' || *p == ' ')
1603 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1606 return ((b_used ? 8 : 0)
1609 + (u_used ? 1 : 0));
1612 /* Retrieve the opcode image of a given register.
1613 If the register is illegal for the current instruction,
1617 getreg_image (reg r)
1619 const reg_entry *reg;
1621 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1623 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1624 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1627 /* Check whether the register is in registers table. */
1629 reg = &crx_regtab[r];
1630 /* Check whether the register is in coprocessor registers table. */
1631 else if (r < MAX_COPREG)
1632 reg = &crx_copregtab[r-MAX_REG];
1633 /* Register not found. */
1636 as_bad (_("Unknown register: `%d'"), r);
1640 reg_name = reg->name;
1642 /* Issue a error message when register is illegal. */
1644 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1645 reg_name, ins_parse); \
1651 if (is_procreg || (instruction->flags & USER_REG))
1656 case CRX_CFG_REGTYPE:
1669 case CRX_CS_REGTYPE:
1680 /* Routine used to get the binary-string equivalent of a integer constant
1681 which currently require currbits to represent itself to be extended to
1684 static unsigned long int
1685 getconstant (unsigned long int x, int nbits)
1688 unsigned long int temp = x;
1696 /* Escape sequence to next 16bit immediate. */
1698 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1703 x |= SET_BITS_MASK (cnt, nbits - cnt);
1705 x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1708 /* The following expression avoids overflow if
1709 'nbits' is the number of bits in 'bfd_vma'. */
1710 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1713 /* Print a constant value to 'output_opcode':
1714 ARG holds the operand's type and value.
1715 SHIFT represents the location of the operand to be print into.
1716 NBITS determines the size (in bits) of the constant. */
1719 print_constant (int nbits, int shift, argument *arg)
1721 unsigned long mask = 0;
1723 long constant = getconstant (arg->constant, nbits);
1731 /* mask the upper part of the constant, that is, the bits
1732 going to the lowest byte of output_opcode[0].
1733 The upper part of output_opcode[1] is always filled,
1734 therefore it is always masked with 0xFFFF. */
1735 mask = (1 << (nbits - 16)) - 1;
1736 /* Divide the constant between two consecutive words :
1738 +---------+---------+---------+---------+
1739 | | X X X X | X X X X | |
1740 +---------+---------+---------+---------+
1741 output_opcode[0] output_opcode[1] */
1743 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1744 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1749 /* Special case - in arg_cr, the SHIFT represents the location
1750 of the REGISTER, not the constant, which is itself not shifted. */
1751 if (arg->type == arg_cr)
1753 CRX_PRINT (0, constant, 0);
1757 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1758 always filling the upper part of output_opcode[1]. If we mistakenly
1759 write it to output_opcode[0], the constant prefix (that is, 'match')
1762 +---------+---------+---------+---------+
1763 | 'match' | | X X X X | |
1764 +---------+---------+---------+---------+
1765 output_opcode[0] output_opcode[1] */
1767 if ((instruction->size > 2) && (shift == WORD_SHIFT))
1768 CRX_PRINT (1, constant, WORD_SHIFT);
1770 CRX_PRINT (0, constant, shift);
1774 CRX_PRINT (0, constant, shift);
1779 /* Print an operand to 'output_opcode', which later on will be
1780 printed to the object file:
1781 ARG holds the operand's type, size and value.
1782 SHIFT represents the printing location of operand.
1783 NBITS determines the size (in bits) of a constant operand. */
1786 print_operand (int nbits, int shift, argument *arg)
1791 CRX_PRINT (0, getreg_image (arg->r), shift);
1795 if (arg->cr < c0 || arg->cr > c15)
1796 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1798 CRX_PRINT (0, getreg_image (arg->cr), shift);
1802 if (arg->cr < cs0 || arg->cr > cs15)
1803 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1805 CRX_PRINT (0, getreg_image (arg->cr), shift);
1810 +--------------------------------+
1811 | r_base | r_idx | scl| disp |
1812 +--------------------------------+ */
1813 CRX_PRINT (0, getreg_image (arg->r), 12);
1814 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1815 CRX_PRINT (0, arg->scale, 6);
1818 print_constant (nbits, shift, arg);
1822 CRX_PRINT (0, getreg_image (arg->r), shift);
1826 /* case base_cst4. */
1827 if ((instruction->flags & DISPU4MAP) && cst4flag)
1828 output_opcode[0] |= (getconstant (arg->constant, nbits)
1829 << (shift + REG_SIZE));
1831 /* rbase_disps<NN> and other such cases. */
1832 print_constant (nbits, shift, arg);
1833 /* Add the register argument to the output_opcode. */
1834 CRX_PRINT (0, getreg_image (arg->r), shift);
1842 /* Retrieve the number of operands for the current assembled instruction. */
1845 get_number_of_operands (void)
1849 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1854 /* Assemble a single instruction :
1855 Instruction has been parsed and all operand values set appropriately.
1856 Algorithm for assembling -
1857 For instruction to be assembled:
1858 Step 1: Find instruction in the array crx_instruction with same mnemonic.
1859 Step 2: Find instruction with same operand types.
1860 Step 3: If (size_of_operands) match then done, else increment the
1861 array_index and goto Step3.
1862 Step 4: Cannot assemble
1863 Returns 1 upon success, 0 upon failure. */
1866 assemble_insn (char *mnemonic, ins *insn)
1868 /* Argument type of each operand in the instruction we are looking for. */
1869 argtype atyp[MAX_OPERANDS];
1870 /* Argument type of each operand in the current instruction. */
1871 argtype atyp_act[MAX_OPERANDS];
1872 /* Size (in bits) of each operand in the instruction we are looking for. */
1873 int bits[MAX_OPERANDS];
1874 /* Size (in bits) of each operand in the current instruction. */
1875 int bits_act[MAX_OPERANDS];
1876 /* Location (in bits) of each operand in the current instruction. */
1877 int shift_act[MAX_OPERANDS];
1878 /* Instruction type to match. */
1879 unsigned int ins_type;
1882 int dispu4map_type = 0;
1883 int changed_already = 0;
1884 unsigned int temp_value = 0;
1886 /* A pointer to the argument's constant value. */
1887 unsigned long int *cons;
1888 /* Pointer to loop over all cst4_map entries. */
1889 const cst4_entry *cst4_op;
1891 /* Instruction has no operands -> copy only the constant opcode. */
1892 if (insn->nargs == 0)
1894 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1898 /* Find instruction with same number of operands. */
1899 while (get_number_of_operands () != insn->nargs
1900 && IS_INSN_MNEMONIC (mnemonic))
1903 if (!IS_INSN_MNEMONIC (mnemonic))
1906 /* Initialize argument type and size of each given operand. */
1907 for (i = 0; i < insn->nargs; i++)
1909 atyp[i] = insn->arg[i].type;
1910 bits[i] = insn->arg[i].size;
1913 /* Initialize argument type and size of each operand in current inst. */
1917 /* In some case, same mnemonic can appear with different instruction types.
1918 For example, 'storb' is supported with 3 different types :
1919 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1920 We assume that when reaching this point, the instruction type was
1921 pre-determined. We need to make sure that the type stays the same
1922 during a search for matching instruction. */
1923 ins_type = CRX_INS_TYPE(instruction->flags);
1926 /* Check we didn't get to end of table. */
1927 && instruction->mnemonic != NULL
1928 /* Check that the actual mnemonic is still available. */
1929 && IS_INSN_MNEMONIC (mnemonic)
1930 /* Check that the instruction type wasn't changed. */
1931 && IS_INSN_TYPE(ins_type))
1933 /* Check for argement type compatibility. */
1934 for (i = 0; i < insn->nargs; i++)
1936 if (atyp_act[i] == atyp[i])
1947 for (i = 0; i < insn->nargs; i++)
1949 if ((get_flags (instruction->operands[i].op_type) & OPERAND_UNSIGNED)
1950 && (insn->arg[i].signflag))
1960 /* Try again with next instruction. */
1968 /* Check for size compatibility. */
1969 for (i = 0; i < insn->nargs; i++)
1971 if (bits[i] > bits_act[i])
1973 /* Actual size is too small - try again. */
1986 /* Full match is found. */
1993 /* We haven't found a match - instruction can't be assembled. */
1996 /* Full match - print the final image. */
1998 /* If the post-increment address mode is used and the load/store
1999 source register is the same as rbase, the result of the
2000 instruction is undefined. */
2001 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2003 /* Enough to verify that one of the arguments is a simple reg. */
2004 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
2005 if (insn->arg[0].r == insn->arg[1].r)
2006 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
2010 /* Optimization: Omit a zero displacement in bit operations,
2011 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
2012 if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2014 if ((instruction->operands[1].op_type == rbase_disps12)
2015 && (insn->arg[1].constant == 0))
2022 /* Some instruction assume the stack pointer as rptr operand.
2023 Issue an error when the register to be loaded is also SP. */
2024 if (instruction->flags & NO_SP)
2026 if (getreg_image (insn->arg[0].r) == getreg_image (sp))
2027 as_bad (_("`%s' has undefined result"), ins_parse);
2030 /* If the rptr register is specified as one of the registers to be loaded,
2031 the final contents of rptr are undefined. Thus, we issue an error. */
2032 if (instruction->flags & NO_RPTR)
2034 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
2035 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
2036 getreg_image (insn->arg[0].r));
2039 /* Handle positive constants. */
2042 if ((instruction->flags & DISPU4MAP) && !relocatable)
2044 /* Get the map type of the instruction. */
2045 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2046 cons = &insn->arg[instrtype].constant;
2047 dispu4map_type = instruction->flags & DISPU4MAP;
2049 switch (dispu4map_type)
2052 /* 14 and 15 are reserved escape sequences of dispub4. */
2053 if (*cons == 14 || *cons == 15)
2061 /* Mapping has to be done. */
2062 if (*cons <= 15 && *cons % 2 != 0)
2067 else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2072 if (*cons < 27 && *cons % 2 == 0)
2077 /* Mapping has to be done. */
2078 if (*cons <= 15 && *cons % 4 != 0)
2083 else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2088 if (*cons < 53 && *cons % 4 == 0)
2092 as_bad (_("Invalid DISPU4 type"));
2097 /* Check whether a cst4 mapping has to be done. */
2098 if ((instruction->flags & CST4MAP) && !relocatable)
2100 /* 'const' equals reserved escape sequences -->>
2101 represent as i16. */
2102 if (insn->arg[0].constant == ESC_16
2103 || insn->arg[0].constant == ESC_32)
2110 /* Loop over cst4_map entries. */
2111 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2114 /* 'const' equals a binary, which is already mapped
2115 by a different value -->> represent as i16. */
2116 if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2117 && cst4_op->binary != cst4_op->value)
2122 /* 'const' equals a value bigger than 16 -->> map to
2123 its binary and represent as cst4. */
2124 else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2125 && insn->arg[0].constant >= 16)
2128 insn->arg[0].constant = cst4_op->binary;
2135 /* Special check for 'addub 0, r0' instruction -
2136 The opcode '0000 0000 0000 0000' is not allowed. */
2137 if (IS_INSN_MNEMONIC ("addub"))
2139 if ((instruction->operands[0].op_type == cst4)
2140 && instruction->operands[1].op_type == regr)
2142 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2146 if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2147 || IS_INSN_TYPE (STOR_IMM_INS)) & !relocatable)
2149 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2150 changed_already = 0;
2151 /* Convert 32 bits accesses to 16 bits accesses. */
2152 if (instruction->operands[instrtype].op_type == abs32)
2154 if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2157 insn->arg[instrtype].constant =
2158 insn->arg[instrtype].constant & 0xFFFF;
2159 insn->arg[instrtype].size = 16;
2160 changed_already = 1;
2164 /* Convert 16 bits accesses to 32 bits accesses. */
2165 if (instruction->operands[instrtype].op_type == abs16
2166 && changed_already != 1)
2169 insn->arg[instrtype].constant =
2170 insn->arg[instrtype].constant & 0xFFFF;
2171 insn->arg[instrtype].size = 32;
2174 changed_already = 0;
2178 for (i = 0; i < insn->nargs; i++)
2180 /* Mark a CST4 argument, if exists. */
2181 if (get_flags (instruction->operands[i].op_type) & OPERAND_CST4)
2184 /* Handle reserved escape sequences. */
2185 if ((get_flags (instruction->operands[i].op_type) & OPERAND_ESC)
2188 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2189 if (insn->arg[i].constant == 0x7e || insn->arg[i].constant == 0x7f)
2191 /* Use a disps17 for these values. */
2198 /* First, copy the instruction's opcode. */
2199 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2201 /* Swap the argument values in case bcop instructions. */
2202 if (IS_INSN_TYPE (COP_BRANCH_INS))
2204 temp_value = insn->arg[0].constant;
2205 insn->arg[0].constant = insn->arg[1].constant;
2206 insn->arg[1].constant = temp_value;
2209 for (i = 0; i < insn->nargs; i++)
2211 shift_act[i] = instruction->operands[i].shift;
2212 signflag = insn->arg[i].signflag;
2214 print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2221 /* Set the appropriate bit for register 'r' in 'mask'.
2222 This indicates that this register is loaded or stored by
2226 mask_reg (int r, unsigned short int *mask)
2228 if ((reg)r > (reg)sp)
2230 as_bad (_("Invalid Register in Register List"));
2237 /* Preprocess register list - create a 16-bit mask with one bit for each
2238 of the 16 general purpose registers. If a bit is set, it indicates
2239 that this register is loaded or stored by the instruction. */
2242 preprocess_reglist (char *param, int *allocated)
2244 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
2245 char *regP; /* Pointer to 'reg_name' string. */
2246 int reg_counter = 0; /* Count number of parsed registers. */
2247 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
2248 char *new_param; /* New created operands string. */
2249 char *paramP = param; /* Pointer to original opearands string. */
2250 char maskstring[10]; /* Array to print the mask as a string. */
2251 int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
2255 /* If 'param' is already in form of a number, no need to preprocess. */
2256 if (strchr (paramP, '{') == NULL)
2259 /* Verifying correct syntax of operand. */
2260 if (strchr (paramP, '}') == NULL)
2261 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2263 while (*paramP++ != '{');
2265 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2267 strncpy (new_param, param, paramP - param - 1);
2269 while (*paramP != '}')
2272 memset (®_name, '\0', sizeof (reg_name));
2274 while (ISALNUM (*paramP))
2277 strncpy (reg_name, regP, paramP - regP);
2279 /* Coprocessor register c<N>. */
2280 if (IS_INSN_TYPE (COP_REG_INS))
2282 if (((cr = get_copregister (reg_name)) == nullcopregister)
2283 || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
2284 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
2285 mask_reg (getreg_image (cr - c0), &mask);
2287 /* Coprocessor Special register cs<N>. */
2288 else if (IS_INSN_TYPE (COPS_REG_INS))
2290 if (((cr = get_copregister (reg_name)) == nullcopregister)
2291 || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
2292 as_fatal (_("Illegal register `%s' in cop-special-register list"),
2294 mask_reg (getreg_image (cr - cs0), &mask);
2296 /* User register u<N>. */
2297 else if (instruction->flags & USER_REG)
2299 if (streq(reg_name, "uhi"))
2304 else if (streq(reg_name, "ulo"))
2309 else if (((r = get_register (reg_name)) == nullregister)
2310 || (crx_regtab[r].type != CRX_U_REGTYPE))
2311 as_fatal (_("Illegal register `%s' in user register list"), reg_name);
2313 mask_reg (getreg_image (r - u0), &mask);
2315 /* General purpose register r<N>. */
2318 if (streq(reg_name, "hi"))
2323 else if (streq(reg_name, "lo"))
2328 else if (((r = get_register (reg_name)) == nullregister)
2329 || (crx_regtab[r].type != CRX_R_REGTYPE))
2330 as_fatal (_("Illegal register `%s' in register list"), reg_name);
2332 mask_reg (getreg_image (r - r0), &mask);
2335 if (++reg_counter > MAX_REGS_IN_MASK16)
2336 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2337 MAX_REGS_IN_MASK16);
2340 while (!ISALNUM (*paramP) && *paramP != '}')
2344 if (*++paramP != '\0')
2345 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2348 switch (hi_found + lo_found)
2351 /* At least one register should be specified. */
2353 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2358 /* HI can't be specified without LO (and vise-versa). */
2359 as_bad (_("HI/LO registers should be specified together"));
2363 /* HI/LO registers mustn't be masked with additional registers. */
2365 as_bad (_("HI/LO registers should be specified without additional registers"));
2371 sprintf (maskstring, "$0x%x", mask);
2372 strcat (new_param, maskstring);
2376 /* Print the instruction.
2377 Handle also cases where the instruction is relaxable/relocatable. */
2380 print_insn (ins *insn)
2382 unsigned int i, j, insn_size;
2384 unsigned short words[4];
2386 /* Arrange the insn encodings in a WORD size array. */
2387 for (i = 0, j = 0; i < 2; i++)
2389 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2390 words[j++] = output_opcode[i] & 0xFFFF;
2393 /* Handle relaxtion. */
2394 if ((instruction->flags & RELAXABLE) && relocatable)
2398 /* Write the maximal instruction size supported. */
2399 insn_size = INSN_MAX_SIZE;
2402 if (IS_INSN_TYPE (BRANCH_INS))
2405 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2408 else if (IS_INSN_TYPE (CMPBR_INS))
2413 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2415 insn->exp.X_add_symbol,
2416 insn->exp.X_add_number,
2421 insn_size = instruction->size;
2422 this_frag = frag_more (insn_size * 2);
2424 /* Handle relocation. */
2425 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2427 reloc_howto_type *reloc_howto;
2430 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2435 size = bfd_get_reloc_size (reloc_howto);
2437 if (size < 1 || size > 4)
2440 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2441 size, &insn->exp, reloc_howto->pc_relative,
2446 /* Write the instruction encoding to frag. */
2447 for (i = 0; i < insn_size; i++)
2449 md_number_to_chars (this_frag, (valueT) words[i], 2);
2454 /* This is the guts of the machine-dependent assembler. OP points to a
2455 machine dependent instruction. This function is supposed to emit
2456 the frags/bytes it assembles to. */
2459 md_assemble (char *op)
2465 /* Reset global variables for a new instruction. */
2466 reset_vars (op, &crx_ins);
2468 /* Strip the mnemonic. */
2469 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2474 /* Find the instruction. */
2475 instruction = (const inst *) hash_find (crx_inst_hash, op);
2476 if (instruction == NULL)
2478 as_bad (_("Unknown opcode: `%s'"), op);
2482 /* Tie dwarf2 debug info to the address at the start of the insn. */
2483 dwarf2_emit_insn (0);
2485 if (NO_OPERANDS_INST (op))
2486 /* Handle instructions with no operands. */
2489 /* Parse the instruction's operands. */
2490 parse_insn (&crx_ins, param);
2492 /* Assemble the instruction. */
2493 if (assemble_insn (op, &crx_ins) == 0)
2495 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2499 /* Print the instruction. */
2500 print_insn (&crx_ins);