Add new port: crx-elf
[deliverable/binutils-gdb.git] / gas / config / tc-crx.c
1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright 2004 Free Software Foundation, Inc.
3
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.
7
8 This file is part of GAS, the GNU Assembler.
9
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)
13 any later version.
14
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.
19
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. */
24
25 #include "as.h"
26 #include "safe-ctype.h"
27 #include "dwarf2dbg.h"
28 #include "opcode/crx.h"
29 #include "elf/crx.h"
30
31 /* Include <limits.h> do define ULONG_MAX, LONG_MAX, LONG_MIN. */
32 #include <limits.h>
33
34 /* Word is considered here as a 16-bit unsigned short int. */
35 #define WORD_SIZE 16
36 #define WORD_SHIFT 16
37
38 /* Register is 4-bit size. */
39 #define REG_SIZE 4
40
41 /* Maximum size of a single instruction (in words). */
42 #define INSN_MAX_SIZE 3
43
44 /* Maximum bits which may be set in a `mask16' operand. */
45 #define MAX_REGS_IN_MASK16 8
46
47 /* Escape to 16-bit immediate. */
48 #define ESC_16 0xE
49 /* Escape to 32-bit immediate. */
50 #define ESC_32 0xF
51
52 /* Utility macros for string comparison. */
53 #define streq(a, b) (strcmp (a, b) == 0)
54 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
55
56 /* A mask to set n_bits starting from offset offs. */
57 #define SET_BITS_MASK(offs,n_bits) ((((1 << (n_bits)) - 1) << (offs)))
58 /* A mask to clear n_bits starting from offset offs. */
59 #define CLEAR_BITS_MASK(offs,n_bits) (~(((1 << (n_bits)) - 1) << (offs)))
60
61 /* Get the argument type for each operand of a given instruction. */
62 #define GET_ACTUAL_TYPE \
63 for (i = 0; i < insn->nargs; i++) \
64 atyp_act[i] = getarg_type (instruction->operands[i].op_type)
65
66 /* Get the size (in bits) for each operand of a given instruction. */
67 #define GET_ACTUAL_SIZE \
68 for (i = 0; i < insn->nargs; i++) \
69 bits_act[i] = getbits (instruction->operands[i].op_type)
70
71 /* Non-zero if OP is instruction with no operands. */
72 #define NO_OPERANDS_INST(OP) \
73 (streq (OP, "di") || streq (OP, "nop") \
74 || streq (OP, "retx") || streq (OP, "ei") \
75 || streq (OP, "wait") || streq (OP, "eiwait"))
76
77 /* Print a number NUM, shifted by SHIFT bytes, into a location
78 pointed by index BYTE of array 'output_opcode'. */
79 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
80
81 /* Opcode mnemonics hash table. */
82 static struct hash_control *crx_inst_hash;
83 /* CRX registers hash table. */
84 static struct hash_control *reg_hash;
85 /* CRX coprocessor registers hash table. */
86 static struct hash_control *copreg_hash;
87 /* Current instruction we're assembling. */
88 const inst *instruction;
89
90 /* Initialize global variables. */
91 long output_opcode[2];
92 /* Nonzero means a relocatable symbol. */
93 int relocatable;
94 /* Nonzero means a constant's bit-size was already set. */
95 int size_was_set;
96 /* Nonzero means a negative constant. */
97 int signflag;
98 /* Nonzero means a CST4 instruction. */
99 int cst4flag;
100 /* A copy of the original instruction (used in error messages). */
101 char ins_parse[MAX_INST_LEN];
102 /* Nonzero means instruction is represented in post increment mode. */
103 int post_inc_mode;
104 /* Holds the current processed argument number. */
105 int processing_arg_number;
106
107 /* Generic assembler global variables which must be defined by all targets. */
108
109 /* Characters which always start a comment. */
110 const char comment_chars[] = "#";
111
112 /* Characters which start a comment at the beginning of a line. */
113 const char line_comment_chars[] = "#";
114
115 /* This array holds machine specific line separator characters. */
116 const char line_separator_chars[] = ";";
117
118 /* Chars that can be used to separate mant from exp in floating point nums. */
119 const char EXP_CHARS[] = "eE";
120
121 /* Chars that mean this number is a floating point constant as in 0f12.456 */
122 const char FLT_CHARS[] = "f'";
123
124 /* Target-specific multicharacter options, not const-declared at usage. */
125 const char *md_shortopts = "";
126 struct option md_longopts[] = {
127 {NULL, no_argument, NULL, 0}
128 };
129 size_t md_longopts_size = sizeof (md_longopts);
130
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. */
136
137 const pseudo_typeS md_pseudo_table[] =
138 {
139 /* In CRX machine, align is in bytes (not a ptwo boundary). */
140 {"align", s_align_bytes, 0},
141 {0, 0, 0}
142 };
143
144 const relax_typeS md_relax_table[] =
145 {
146 /* bCC */
147 {0xfa, -0x100, 2, 1}, /* 8 */
148 {0xfffe, -0x10000, 4, 2}, /* 16 */
149 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
150
151 /* bal */
152 {0xfffe, -0x10000, 4, 4}, /* 16 */
153 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
154
155 /* cmpbr */
156 {0xfe, -0x100, 4, 6}, /* 8 */
157 {0xfffffe, -0x1000000, 6, 0} /* 24 */
158 };
159
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 *);
186
187 /* Return the bit size for a given operand. */
188
189 static int
190 getbits (operand_type op)
191 {
192 if (op < MAX_OPRD)
193 return crx_optab[op].bit_size;
194 else
195 return 0;
196 }
197
198 /* Return the argument type of a given operand. */
199
200 static argtype
201 getarg_type (operand_type op)
202 {
203 if (op < MAX_OPRD)
204 return crx_optab[op].arg_type;
205 else
206 return nullargs;
207 }
208
209 /* Get the core processor register 'reg_name'. */
210
211 static reg
212 get_register (char *reg_name)
213 {
214 const reg_entry *reg;
215
216 reg = (const reg_entry *) hash_find (reg_hash, reg_name);
217
218 if (reg != NULL)
219 return reg->value.reg_val;
220 else
221 return nullregister;
222 }
223
224 /* Get the coprocessor register 'copreg_name'. */
225
226 static copreg
227 get_copregister (char *copreg_name)
228 {
229 const reg_entry *copreg;
230
231 copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
232
233 if (copreg != NULL)
234 return copreg->value.copreg_val;
235 else
236 return nullcopregister;
237 }
238
239 /* Mask a constant to the number of bits it is to be mapped to. */
240
241 static void
242 mask_const (unsigned long int *t, int size)
243 {
244 *t &= (((LONGLONG)1 << size) - 1);
245 }
246
247 /* Round up a section size to the appropriate boundary. */
248
249 valueT
250 md_section_align (segT seg, valueT val)
251 {
252 /* Round .text section to a multiple of 2. */
253 if (seg == text_section)
254 return (val + 1) & ~1;
255 return val;
256 }
257
258 /* Parse an operand that is machine-specific (remove '*'). */
259
260 void
261 md_operand (expressionS * exp)
262 {
263 char c = *input_line_pointer;
264
265 switch (c)
266 {
267 case '*':
268 input_line_pointer++;
269 expression (exp);
270 break;
271 default:
272 break;
273 }
274 }
275
276 /* Reset global variables before parsing a new instruction. */
277
278 static void
279 reset_vars (char *op, ins *crx_ins)
280 {
281 unsigned int i;
282
283 processing_arg_number = relocatable = size_was_set
284 = signflag = post_inc_mode = cst4flag = 0;
285 memset (&output_opcode, '\0', sizeof (output_opcode));
286
287 /* Memset the 'signflag' field in every argument. */
288 for (i = 0; i < MAX_OPERANDS; i++)
289 crx_ins->arg[i].signflag = 0;
290
291 /* Save a copy of the original OP (used in error messages). */
292 strcpy (ins_parse, op);
293 }
294
295 /* Generate a relocation entry for a fixup. */
296
297 arelent *
298 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
299 {
300 arelent * reloc;
301
302 reloc = xmalloc (sizeof (arelent));
303 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
304 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
305 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
306 reloc->addend = fixP->fx_offset;
307
308 if (fixP->fx_subsy != NULL)
309 /* We don't resolve difference expressions. */
310 as_bad_where (fixP->fx_file, fixP->fx_line,
311 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
312 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
313 segment_name (fixP->fx_addsy
314 ? S_GET_SEGMENT (fixP->fx_addsy)
315 : absolute_section),
316 S_GET_NAME (fixP->fx_subsy),
317 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
318
319 assert ((int) fixP->fx_r_type > 0);
320 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
321
322 if (reloc->howto == (reloc_howto_type *) NULL)
323 {
324 as_bad_where (fixP->fx_file, fixP->fx_line,
325 _("internal error: reloc %d (`%s') not supported by object file format"),
326 fixP->fx_r_type,
327 bfd_get_reloc_code_name (fixP->fx_r_type));
328 return NULL;
329 }
330 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
331
332 return reloc;
333 }
334
335 /* Prepare machine-dependent frags for relaxation. */
336
337 int
338 md_estimate_size_before_relax (fragS *fragp, asection *seg)
339 {
340 /* If symbol is undefined or located in a different section,
341 select the largest supported relocation. */
342 relax_substateT subtype;
343 relax_substateT rlx_state[] = {0, 2,
344 3, 4,
345 5, 6};
346
347 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
348 {
349 if (fragp->fr_subtype == rlx_state[subtype]
350 && (!S_IS_DEFINED (fragp->fr_symbol)
351 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
352 {
353 fragp->fr_subtype = rlx_state[subtype + 1];
354 break;
355 }
356 }
357
358 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
359 abort ();
360
361 return md_relax_table[fragp->fr_subtype].rlx_length;
362 }
363
364 void
365 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
366 {
367 /* 'opcode' points to the start of the instruction, whether
368 we need to change the instruction's fixed encoding. */
369 char *opcode = fragP->fr_literal + fragP->fr_fix;
370 bfd_reloc_code_real_type reloc;
371
372 subseg_change (sec, 0);
373
374 switch (fragP->fr_subtype)
375 {
376 case 0:
377 reloc = BFD_RELOC_CRX_REL8;
378 break;
379 case 1:
380 *opcode = 0x7e;
381 reloc = BFD_RELOC_CRX_REL16;
382 break;
383 case 2:
384 *opcode = 0x7f;
385 reloc = BFD_RELOC_CRX_REL32;
386 break;
387 case 3:
388 reloc = BFD_RELOC_CRX_REL16;
389 break;
390 case 4:
391 *++opcode = 0x31;
392 reloc = BFD_RELOC_CRX_REL32;
393 break;
394 case 5:
395 reloc = BFD_RELOC_CRX_REL8_CMP;
396 break;
397 case 6:
398 *++opcode = 0x31;
399 reloc = BFD_RELOC_CRX_REL24;
400 break;
401 default:
402 abort ();
403 break;
404 }
405
406 fix_new (fragP, fragP->fr_fix,
407 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
408 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
409 fragP->fr_var = 0;
410 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
411 }
412
413 /* Process machine-dependent command line options. Called once for
414 each option on the command line that the machine-independent part of
415 GAS does not understand. */
416
417 int
418 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
419 {
420 return 0;
421 }
422
423 /* Machine-dependent usage-output. */
424
425 void
426 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
427 {
428 return;
429 }
430
431 /* Turn a string in input_line_pointer into a floating point constant
432 of type TYPE, and store the appropriate bytes in *LITP. The number
433 of LITTLENUMS emitted is stored in *SIZEP. An error message is
434 returned, or NULL on OK. */
435
436 char *
437 md_atof (int type, char *litP, int *sizeP)
438 {
439 int prec;
440 LITTLENUM_TYPE words[4];
441 char *t;
442 int i;
443
444 switch (type)
445 {
446 case 'f':
447 prec = 2;
448 break;
449
450 case 'd':
451 prec = 4;
452 break;
453
454 default:
455 *sizeP = 0;
456 return _("bad call to md_atof");
457 }
458
459 t = atof_ieee (input_line_pointer, type, words);
460 if (t)
461 input_line_pointer = t;
462
463 *sizeP = prec * 2;
464
465 if (! target_big_endian)
466 {
467 for (i = prec - 1; i >= 0; i--)
468 {
469 md_number_to_chars (litP, (valueT) words[i], 2);
470 litP += 2;
471 }
472 }
473 else
474 {
475 for (i = 0; i < prec; i++)
476 {
477 md_number_to_chars (litP, (valueT) words[i], 2);
478 litP += 2;
479 }
480 }
481
482 return NULL;
483 }
484
485 /* Apply a fixS (fixup of an instruction or data that we didn't have
486 enough info to complete immediately) to the data in a frag.
487 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
488 relaxation of debug sections, this function is called only when
489 fixuping relocations of debug sections. */
490
491 void
492 md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
493 {
494 valueT val = * valP;
495 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
496 fixP->fx_offset = 0;
497
498 switch (fixP->fx_r_type)
499 {
500 case BFD_RELOC_CRX_NUM8:
501 bfd_put_8 (stdoutput, (unsigned char) val, buf);
502 break;
503 case BFD_RELOC_CRX_NUM16:
504 bfd_put_16 (stdoutput, val, buf);
505 break;
506 case BFD_RELOC_CRX_NUM32:
507 bfd_put_32 (stdoutput, val, buf);
508 break;
509 default:
510 /* We shouldn't ever get here because linkrelax is nonzero. */
511 abort ();
512 break;
513 }
514
515 fixP->fx_done = 0;
516
517 if (fixP->fx_addsy == NULL
518 && fixP->fx_pcrel == 0)
519 fixP->fx_done = 1;
520
521 if (fixP->fx_pcrel == 1
522 && fixP->fx_addsy != NULL
523 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
524 fixP->fx_done = 1;
525 }
526
527 /* The location from which a PC relative jump should be calculated,
528 given a PC relative reloc. */
529
530 long
531 md_pcrel_from (fixS *fixp)
532 {
533 return fixp->fx_frag->fr_address + fixp->fx_where;
534 }
535
536 /* This function is called once, at assembler startup time. This should
537 set up all the tables, etc that the MD part of the assembler needs. */
538
539 void
540 md_begin (void)
541 {
542 const char *hashret = NULL;
543 int i = 0;
544
545 /* Set up a hash table for the instructions. */
546 crx_inst_hash = hash_new ();
547 if (crx_inst_hash == NULL)
548 as_fatal (_("Virtual memory exhausted"));
549
550 while (crx_instruction[i].mnemonic != NULL)
551 {
552 const char *mnemonic = crx_instruction[i].mnemonic;
553
554 hashret = hash_insert (crx_inst_hash, mnemonic,
555 (PTR) &crx_instruction[i]);
556
557 if (hashret != NULL && *hashret != '\0')
558 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
559 *hashret == 0 ? _("(unknown reason)") : hashret);
560
561 /* Insert unique names into hash table. The CRX instruction set
562 has many identical opcode names that have different opcodes based
563 on the operands. This hash table then provides a quick index to
564 the first opcode with a particular name in the opcode table. */
565 do
566 {
567 ++i;
568 }
569 while (crx_instruction[i].mnemonic != NULL
570 && streq (crx_instruction[i].mnemonic, mnemonic));
571 }
572
573 /* Initialize reg_hash hash table. */
574 reg_hash = hash_new ();
575
576 {
577 const reg_entry *regtab;
578
579 for (regtab = crx_regtab;
580 regtab < (crx_regtab + NUMREGS); regtab++)
581 {
582 hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
583 if (hashret)
584 as_fatal (_("Internal Error: Can't hash %s: %s"),
585 regtab->name,
586 hashret);
587 }
588 }
589
590 /* Initialize copreg_hash hash table. */
591 copreg_hash = hash_new ();
592
593 {
594 const reg_entry *copregtab;
595
596 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
597 copregtab++)
598 {
599 hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
600 if (hashret)
601 as_fatal (_("Internal Error: Can't hash %s: %s"),
602 copregtab->name,
603 hashret);
604 }
605 }
606 /* Set linkrelax here to avoid fixups in most sections. */
607 linkrelax = 1;
608 }
609
610 /* Get the number of bits corresponding to a constant -
611 here we check for possible overflow cases. */
612
613 static void
614 get_number_of_bits (ins * crx_ins, int op_num)
615 {
616 int cnt_bits = 0;
617 unsigned long int temp = crx_ins->arg[op_num].constant;
618 const cst4_entry *cst4_op;
619
620 /* If the constant's size was already set - nothing to do. */
621 if (size_was_set)
622 return;
623
624 /* Already dealt with negative numbers in process_label_constants. */
625 while (temp > 0)
626 {
627 temp >>= 1;
628 cnt_bits++;
629 }
630
631 if (IS_INSN_TYPE (ARITH_INS) && !relocatable && !signflag)
632 {
633 if (cnt_bits == 16)
634 {
635 crx_ins->arg[op_num].size = 17;
636 return;
637 }
638 }
639 /* If a signed +ve is represented in 6 bits then we have to represent
640 it in 22 bits in case of the index mode of addressing. */
641 if (IS_INSN_TYPE (LD_STOR_INS)
642 || IS_INSN_TYPE (LD_STOR_INS_INC)
643 || IS_INSN_TYPE (STOR_IMM_INS)
644 || IS_INSN_TYPE (CSTBIT_INS))
645 {
646 if (!signflag && crx_ins->arg[op_num].type == arg_icr)
647 {
648 if (cnt_bits == 6)
649 {
650 crx_ins->arg[op_num].size = 7;
651 return;
652 }
653 if (cnt_bits == 22)
654 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
655 }
656 }
657 /* If a signed +ve is represnted in 16 bits in case of load/stor disp16
658 then change it to 17 bits.
659 If a signed +ve is represnted in 12 bits in post increment instruction
660 increase it to 13 bits. */
661 if (IS_INSN_TYPE (LD_STOR_INS))
662 {
663 if (!signflag && crx_ins->arg[op_num].type == arg_cr)
664 {
665 if (cnt_bits == 16)
666 {
667 crx_ins->arg[op_num].size = 17;
668 return;
669 }
670 if (cnt_bits == 32)
671 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
672 }
673 }
674
675 if (IS_INSN_TYPE (CSTBIT_INS)
676 || IS_INSN_TYPE (LD_STOR_INS_INC)
677 || IS_INSN_TYPE (STOR_IMM_INS))
678 {
679 if (!signflag && crx_ins->arg[op_num].type == arg_cr)
680 {
681 if (cnt_bits == 12)
682 {
683 crx_ins->arg[op_num].size = 13;
684 if (IS_INSN_TYPE (LD_STOR_INS_INC))
685 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
686 return;
687 }
688 if (IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS))
689 {
690 if (cnt_bits == 28)
691 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
692 }
693
694 }
695 }
696
697 /* Handle negative cst4 mapping for arithmetic/cmp&br operations. */
698 if (signflag && !relocatable
699 && ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
700 || ((IS_INSN_TYPE (CMPBR_INS) && op_num == 0))))
701 {
702 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
703 {
704 if (crx_ins->arg[op_num].constant == (unsigned int)(-cst4_op->value))
705 {
706 crx_ins->arg[op_num].size = 4;
707 crx_ins->arg[op_num].constant = cst4_op->binary;
708 crx_ins->arg[op_num].signflag = 0;
709 return;
710 }
711 }
712 }
713 /* Because of the cst4 mapping -- -1 and -4 already handled above
714 as well as for relocatable cases. */
715 if (signflag && IS_INSN_TYPE (ARITH_BYTE_INS))
716 {
717 if (!relocatable)
718 {
719 if (crx_ins->arg[op_num].constant <= 0xffff)
720 crx_ins->arg[op_num].size = 16;
721 else
722 /* Setting to 18 so that there is no match. */
723 crx_ins->arg[op_num].size = 18;
724 }
725 else
726 crx_ins->arg[op_num].size = 16;
727 return;
728 }
729
730 if (signflag && IS_INSN_TYPE (ARITH_INS))
731 {
732 /* For all immediates which can be expressed in less than 16 bits. */
733 if (crx_ins->arg[op_num].constant <= 0xffff && !relocatable)
734 {
735 crx_ins->arg[op_num].size = 16;
736 return;
737 }
738 /* Either it is relocatable or not representable in 16 bits. */
739 if (crx_ins->arg[op_num].constant < 0xffffffff || relocatable)
740 {
741 crx_ins->arg[op_num].size = 32;
742 return;
743 }
744 crx_ins->arg[op_num].size = 33;
745 return;
746 }
747 if (signflag && !relocatable)
748 return;
749
750 if (!relocatable)
751 crx_ins->arg[op_num].size = cnt_bits;
752
753 /* Checking for Error Conditions. */
754 if (IS_INSN_TYPE (ARITH_INS) && !signflag)
755 {
756 if (cnt_bits > 32)
757 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
758 cnt_bits, ins_parse);
759 }
760 else if (IS_INSN_TYPE (ARITH_BYTE_INS) && !signflag)
761 {
762 if (cnt_bits > 16)
763 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
764 cnt_bits, ins_parse);
765 }
766 }
767
768 /* Handle the constants -immediate/absolute values and
769 Labels (jump targets/Memory locations). */
770
771 static int
772 process_label_constant (char *str, ins * crx_ins, int number)
773 {
774 char *save;
775 unsigned long int temp, cnt;
776 const cst4_entry *cst4_op;
777 int is_cst4=0;
778 int constant_val = 0;
779 int cmp_br_type_flag = 0, i;
780 int br_type_flag = 0;
781 save = input_line_pointer;
782 signflag = 0;
783
784 if (str[0] == '-')
785 {
786 signflag = 1;
787 str++;
788 }
789 else if (str[0] == '+')
790 str++;
791
792 /* Preprocessing for cmpbr instruction and getting the size flag. */
793 if (strstr (str, ":s") != NULL && (IS_INSN_TYPE (CMPBR_INS)
794 || IS_INSN_TYPE (COP_BRANCH_INS)))
795 cmp_br_type_flag = 8;
796
797 if (strstr (str, ":l") != NULL && (IS_INSN_TYPE (CMPBR_INS)
798 || IS_INSN_TYPE (COP_BRANCH_INS)))
799 cmp_br_type_flag = 24;
800
801 /* Branch instruction preprocessing. */
802 if (IS_INSN_TYPE (BRANCH_INS))
803 {
804 if (strstr (str, ":s") != NULL)
805 br_type_flag = 8;
806 else if (strstr (str, ":m") != NULL)
807 br_type_flag = 16;
808 else if (strstr (str, ":l") != NULL)
809 br_type_flag = 32;
810 }
811 /* Making the label cleared for processing removing :lms etc from labels. */
812 if (cmp_br_type_flag != 0 || br_type_flag != 0)
813 {
814 i = 0;
815 while (str[i] != ':')
816 {
817 i++;
818 }
819 str[i] = '\0';
820 }
821 input_line_pointer = str;
822
823 expression (&crx_ins->exp);
824
825 switch (crx_ins->exp.X_op)
826 {
827 case O_constant:
828 crx_ins->arg[number].constant = crx_ins->exp.X_add_number;
829 constant_val = crx_ins->exp.X_add_number;
830 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
831 && number == 2)
832 {
833 /* This variable causes a warning (is to be handles by string
834 type implementation). */
835 LONGLONG temp64 = 0;
836
837 char ptr[20];
838 char temp_str[30];
839 unsigned int jump_value = 0;
840 int BR_MASK = 0, BR_SIZE = 0;
841 temp_str[0] = '\0';
842 if (signflag)
843 {
844 temp_str[0] = '-';
845 temp_str[1] = '\0';
846 }
847 strncat (temp_str, str, strlen (str));
848 temp64 = strtol (temp_str, (char **) &ptr,0);
849 /* This is not accurate :
850 Actually overflow is allowed here (see comment below).
851 Originally the call was to 'strtoll', which isn't
852 identified by MSVC. */
853 if ((temp64 == LONG_MAX) || (temp64 == LONG_MIN))
854 as_bad (_("Overflow in displacement in Instruction `%s'"),
855 ins_parse);
856
857 /* If br *+x
858 It will be returned as '0' padded with 'x' uptill 64 bits
859 If br *-x
860 It will be returned as sign extended form
861
862 Then search for validity of representation
863 Check whether upper 38 bits are all zeroes or all ones
864 If not report error. */
865 if (!(((temp64 & UPPER31_MASK) == UPPER31_MASK)
866 || ((temp64 & UPPER31_MASK) == 0x0)))
867 as_bad (_("Overflow in displacement in Instruction `%s'"),
868 ins_parse);
869
870 if (temp64 % 2 != 0)
871 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
872 ins_parse);
873
874 /* Determine the branch size. */
875 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
876 if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
877 || ((jump_value & 0xFFFFFF00) == 0x0))
878 {
879 BR_MASK = 0xFF;
880 BR_SIZE = 8;
881 }
882 else
883 if (((jump_value & 0xFF000000) == 0xFF000000)
884 || ((jump_value & 0xFF000000) == 0x0))
885 {
886 BR_MASK = 0xFFFFFF;
887 BR_SIZE = 24;
888 }
889 jump_value = jump_value >> 1;
890 crx_ins->arg[number].constant = jump_value & BR_MASK;
891 crx_ins->arg[number].size = BR_SIZE;
892 size_was_set = 1;
893 crx_ins->arg[number].signflag = signflag;
894 input_line_pointer = save;
895 return crx_ins->exp.X_op;
896 }
897
898 if (IS_INSN_TYPE (BRANCH_INS)
899 || IS_INSN_MNEMONIC ("bal")
900 || IS_INSN_TYPE (DCR_BRANCH_INS))
901 {
902 LONGLONG temp64 = 0;
903 char ptr[20];
904 char temp_str[30];
905 unsigned int jump_value = 0;
906 int BR_MASK = 0, BR_SIZE = 0;
907
908 temp_str[0] = '\0';
909 if (signflag)
910 {
911 temp_str[0] = '-';
912 temp_str[1] = '\0';
913 }
914 strncat (temp_str, str, strlen (str));
915 temp64 = strtol (temp_str, (char **) &ptr,0);
916 /* This is not accurate :
917 Actually overflow is allowed here (see comment below).
918 Originally the call was to 'strtoll', which isn't
919 identified by MSVC. */
920 if ((temp64 == LONG_MAX) || (temp64 == LONG_MIN))
921 as_bad (_("Overflow in displacement in Instruction `%s'"),
922 ins_parse);
923
924 /* If br *+x
925 It will be returned as '0' padded with 'x' uptill 64 bits
926 If br *-x
927 It will be returned as sign extended form
928
929 Then search for validity of representation
930 Check whether upper 31 bits are all zeroes or all ones
931 If not report error. */
932 if (!(((temp64 & UPPER31_MASK) == UPPER31_MASK)
933 || ((temp64 & UPPER31_MASK) == 0x0)))
934 as_bad (_("Overflow in displacement in Instruction `%s'"),
935 ins_parse);
936
937 if (temp64 % 2 != 0)
938 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
939 ins_parse);
940
941 /* Determine the branch size. */
942 jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
943 if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
944 && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
945 || ((jump_value & 0xFFFFFF00) == 0x0)))
946 {
947 BR_MASK = 0xFF;
948 BR_SIZE = 8;
949 }
950 else
951 if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
952 || ((jump_value & 0xFFFF0000) == 0x0))
953 {
954 BR_MASK = 0xFFFF;
955 BR_SIZE = 16;
956 }
957 else
958 {
959 BR_MASK = 0xFFFFFFFF;
960 BR_SIZE = 32;
961 }
962 jump_value = jump_value >> 1;
963 crx_ins->arg[number].constant = jump_value & BR_MASK;
964 crx_ins->arg[number].size = BR_SIZE;
965 size_was_set = 1;
966 crx_ins->arg[number].signflag = signflag;
967 input_line_pointer = save;
968 return crx_ins->exp.X_op;
969 }
970 /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
971 if (constant_val < 0 && signflag != 1
972 && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
973 && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
974 && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
975 {
976 crx_ins->arg[number].constant =
977 ~(crx_ins->arg[number].constant) + 1;
978 signflag = 1;
979 }
980 /* For load/store instruction when the value is in the offset part. */
981 if (constant_val < 0 && signflag != 1
982 && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
983 || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
984 {
985 if (crx_ins->arg[number].type == arg_cr
986 || crx_ins->arg[number].type == arg_icr)
987 {
988 crx_ins->arg[number].constant =
989 ~(crx_ins->arg[number].constant) + 1;
990 signflag = 1;
991 }
992 }
993 if (signflag)
994 {
995 /* Signflag in never set in case of load store instructions
996 Mapping in case of only the arithinsn case. */
997 if ((crx_ins->arg[number].constant != 1
998 && crx_ins->arg[number].constant != 4)
999 || (!IS_INSN_TYPE (ARITH_INS)
1000 && !IS_INSN_TYPE (ARITH_BYTE_INS)
1001 && !IS_INSN_TYPE (CMPBR_INS)))
1002 {
1003 /* Counting the number of bits required to represent
1004 the constant. */
1005 cnt = 0;
1006 temp = crx_ins->arg[number].constant - 1;
1007 while (temp > 0)
1008 {
1009 temp >>= 1;
1010 cnt++;
1011 }
1012 crx_ins->arg[number].size = cnt + 1;
1013 crx_ins->arg[number].constant =
1014 ~(crx_ins->arg[number].constant) + 1;
1015 if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
1016 {
1017 char ptr[30];
1018 LONGLONG temp64;
1019
1020 /* Tomer - Originally the call was to 'strtoull', which isn't
1021 identified by MSVC. Instead we check for overflow. */
1022 temp64 = strtoul (str, (char **) &ptr, 0);
1023 if (cnt < 4)
1024 crx_ins->arg[number].size = 5;
1025
1026 if (IS_INSN_TYPE (ARITH_INS))
1027 {
1028 if (crx_ins->arg[number].size > 32
1029 /* Tomer - check for overflow. */
1030 || (temp64 == ULONG_MAX))
1031 {
1032 if (crx_ins->arg[number].size > 32)
1033 as_bad (_("In Instruction `%s': Immediate size is \
1034 %lu bits cannot be accomodated"),
1035 ins_parse, cnt + 1);
1036
1037 /* Tomer - check for overflow. */
1038 if (temp64 == ULONG_MAX)
1039 as_bad (_("Value given more than 32 bits in \
1040 Instruction `%s'"), ins_parse);
1041 }
1042 }
1043 if (IS_INSN_TYPE (ARITH_BYTE_INS))
1044 {
1045 if (crx_ins->arg[number].size > 16
1046 || !((temp64 & 0xFFFF0000) == 0xFFFF0000
1047 || (temp64 & 0xFFFF0000) == 0x0))
1048 {
1049 if (crx_ins->arg[number].size > 16)
1050 as_bad (_("In Instruction `%s': Immediate size is \
1051 %lu bits cannot be accomodated"),
1052 ins_parse, cnt + 1);
1053
1054 if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
1055 || (temp64 & 0xFFFF0000) == 0x0))
1056 as_bad (_("Value given more than 16 bits in \
1057 Instruction `%s'"), ins_parse);
1058 }
1059 }
1060 }
1061 if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr
1062 && !post_inc_mode)
1063 {
1064 /* Cases handled ---
1065 dispub4/dispuw4/dispud4 and for load store dispubwd4
1066 is applicable only. */
1067 if (crx_ins->arg[number].size <= 4)
1068 crx_ins->arg[number].size = 5;
1069 }
1070 /* Argument number is checked to distinguish between
1071 immediate and displacement in cmpbranch and bcopcond. */
1072 if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1073 && number == 2)
1074 {
1075 if (crx_ins->arg[number].size != 32)
1076 crx_ins->arg[number].constant =
1077 crx_ins->arg[number].constant >> 1;
1078 }
1079
1080 mask_const (&crx_ins->arg[number].constant,
1081 (int) crx_ins->arg[number].size);
1082 }
1083 }
1084 else
1085 {
1086 /* Argument number is checked to distinguish between
1087 immediate and displacement in cmpbranch and bcopcond. */
1088 if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1089 && number == 2)
1090 || IS_INSN_TYPE (BRANCH_NEQ_INS))
1091 {
1092 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1093 {
1094 if (crx_ins->arg[number].constant == 0)
1095 as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
1096 }
1097
1098 if (crx_ins->arg[number].constant % 2 != 0)
1099 as_bad (_("Instruction `%s' has odd offset"), ins_parse);
1100
1101 if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1102 {
1103 if (crx_ins->arg[number].constant > 32
1104 || crx_ins->arg[number].constant < 2)
1105 as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1106 ins_parse, crx_ins->arg[number].constant);
1107
1108 crx_ins->arg[number].constant -= 2;
1109 }
1110
1111 crx_ins->arg[number].constant =
1112 crx_ins->arg[number].constant >> 1;
1113 get_number_of_bits (crx_ins, number);
1114 }
1115
1116 /* Compare branch argument number zero to be compared -
1117 mapped to cst4. */
1118 if (IS_INSN_TYPE (CMPBR_INS) && number == 0)
1119 {
1120 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
1121 {
1122 if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value)
1123 {
1124 crx_ins->arg[number].constant = cst4_op->binary;
1125 is_cst4 = 1;
1126 break;
1127 }
1128 }
1129 if (!is_cst4)
1130 as_bad (_("Instruction `%s' has invalid imm value as an \
1131 operand"), ins_parse);
1132 }
1133 }
1134 break;
1135
1136 case O_symbol:
1137 case O_subtract:
1138 crx_ins->arg[number].constant = 0;
1139 relocatable = 1;
1140
1141 switch (crx_ins->arg[number].type)
1142 {
1143 case arg_cr:
1144 /* Have to consider various cases here --load/stor++[bwd] rbase, reg. */
1145 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1146 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
1147 else if (IS_INSN_TYPE (CSTBIT_INS)
1148 || IS_INSN_TYPE (STOR_IMM_INS))
1149 /* 'stor[bwd] imm' and '[stc]bit[bwd]'. */
1150 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
1151 else
1152 /* General load store instruction. */
1153 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
1154 break;
1155 case arg_icr:
1156 /* Index Mode 22 bits relocation. */
1157 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
1158 break;
1159 case arg_c:
1160 /* Absolute types. */
1161 /* Case for jumps...dx types. */
1162 /* For bal. */
1163 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
1164 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1165 else if (IS_INSN_TYPE (BRANCH_INS))
1166 {
1167 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1168
1169 /* Overriding the above by the br_type_flag set above. */
1170 switch (br_type_flag)
1171 {
1172 default:
1173 break;
1174 case 8:
1175 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1176 break;
1177 case 16:
1178 crx_ins->rtype = BFD_RELOC_CRX_REL16;
1179 break;
1180 case 32:
1181 crx_ins->rtype = BFD_RELOC_CRX_REL32;
1182 break;
1183 }
1184 }
1185 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
1186 || IS_INSN_TYPE (CSTBIT_INS))
1187 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
1188 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1189 crx_ins->rtype = BFD_RELOC_CRX_REL4;
1190 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1191 {
1192 if (cmp_br_type_flag == 24)
1193 crx_ins->rtype = BFD_RELOC_CRX_REL24;
1194 else
1195 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1196 }
1197 break;
1198 case arg_ic:
1199 case arg_dc:
1200 if (IS_INSN_TYPE (ARITH_INS))
1201 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
1202 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1203 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
1204 break;
1205 default:
1206 break;
1207 }
1208 crx_ins->arg[number].size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
1209 break;
1210
1211 default:
1212 break;
1213 }
1214
1215 input_line_pointer = save;
1216 crx_ins->arg[number].signflag = signflag;
1217 return crx_ins->exp.X_op;
1218 }
1219
1220 /* Get the values of the scale to be encoded -
1221 used for the scaled index mode of addressing. */
1222
1223 static int
1224 exponent2scale (int val)
1225 {
1226 int exponent;
1227
1228 /* If 'val' is 0, the following 'for' will be an endless loop. */
1229 if (val == 0)
1230 return 0;
1231
1232 for (exponent = 0; (val != 1); val >>= 1, exponent++)
1233 ;
1234
1235 return exponent;
1236 }
1237
1238 /* This is used to set the index mode parameters. Used to set the attributes of
1239 an indexmode type of operand. op_num is the operand number. */
1240
1241 static void
1242 set_indexmode_parameters (char *operand, ins * crx_ins, int op_num)
1243 {
1244 char address_str[30];
1245 char scale_str[MAX_OPERANDS];
1246 int scale_cnt = 0;
1247 char reg_name[MAX_REGNAME_LEN];
1248 char regindex_name[MAX_REGNAME_LEN];
1249 int i = 0;
1250 int reg_counter = 0, addr_cnt = 0, temp_int_val = 0;
1251
1252 switch (crx_ins->arg[op_num].type)
1253 {
1254 case arg_icr:
1255 while (operand[i] != '(')
1256 {
1257 address_str[addr_cnt++] = operand[i];
1258 i++;
1259 }
1260 address_str[addr_cnt] = '\0';
1261 process_label_constant (address_str, crx_ins, op_num);
1262 i++;
1263 reg_counter = 0;
1264 while (operand[i] != ',' && operand[i] != ' ')
1265 {
1266 reg_name[reg_counter++] = operand[i];
1267 i++;
1268 }
1269 reg_name[reg_counter] = '\0';
1270 if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1271 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1272 reg_name, ins_parse);
1273
1274 i++;
1275 while (operand[i] == ' ')
1276 i++;
1277
1278 reg_counter = 0;
1279 while (operand[i] != ')' && operand[i] != ',')
1280 {
1281 regindex_name[reg_counter++] = operand[i];
1282 i++;
1283 }
1284 regindex_name[reg_counter] = '\0';
1285 reg_counter = 0;
1286 if ((crx_ins->arg[op_num].i_r = get_register (regindex_name))
1287 == nullregister)
1288 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1289 regindex_name, ins_parse);
1290
1291 /* Setting the scale parameters. */
1292 while (operand[i] == ' ')
1293 i++;
1294
1295 if (operand[i] == ')')
1296 crx_ins->arg[op_num].scale = 0;
1297 else
1298 {
1299 if (operand[i] == ',')
1300 i++;
1301
1302 while (operand[i] != ' ' && operand[i] != ')')
1303 {
1304 scale_str[scale_cnt++] = operand[i];
1305 i++;
1306 }
1307
1308 scale_str[scale_cnt] = '\0';
1309 /* Preprocess the scale string. */
1310 if (strstr (scale_str, "0x") != NULL
1311 || strstr (scale_str, "0X") != NULL)
1312 {
1313 sscanf (scale_str, "%x", &temp_int_val);
1314 memset (&scale_str, '\0', sizeof (scale_str));
1315 sprintf (scale_str, "%d", temp_int_val);
1316 }
1317 /* Preprocess over. */
1318 temp_int_val = atoi (scale_str);
1319
1320 if (temp_int_val != 1 && temp_int_val != 2
1321 && temp_int_val != 4 && temp_int_val != 8)
1322 as_bad (_("Illegal Scale - `%s'"), scale_str);
1323
1324 crx_ins->arg[op_num].scale = exponent2scale (temp_int_val);
1325 }
1326 break;
1327 default:
1328 break;
1329 }
1330 }
1331
1332 /* Parsing the operands of types
1333 - constants
1334 - rbase -> (register)
1335 - offset(rbase)
1336 - offset(rbase)+ - post increment mode. */
1337
1338 static void
1339 set_cons_rparams (char *operand, ins * crx_ins, int op_num)
1340 {
1341 int i = 0, reg_count = 0;
1342 char reg_name[MAX_REGNAME_LEN];
1343 int change_flag = 0;
1344
1345 if (crx_ins->arg[op_num].type == arg_dc)
1346 change_flag = 1;
1347
1348 switch (crx_ins->arg[op_num].type)
1349 {
1350 case arg_sc: /* Case *+347. */
1351 case arg_dc: /* Case $18. */
1352 i++;
1353 case arg_c:/* Case where its a simple constant. */
1354 process_label_constant (operand + i, crx_ins, op_num);
1355 crx_ins->arg[op_num].type = arg_c;
1356 break;
1357 case arg_dcr: /* Case $9(r13). */
1358 operand++;
1359 case arg_cr: /* Case 9(r13. */
1360 while (operand[i] != '(')
1361 i++;
1362 operand[i] = '\0';
1363 process_label_constant (operand, crx_ins, op_num);
1364 operand[i] = '(';
1365 i++;
1366 reg_count = 0;
1367 while (operand[i] != ')')
1368 {
1369 reg_name[reg_count] = operand[i];
1370 i++;
1371 reg_count++;
1372 }
1373 reg_name[reg_count] = '\0';
1374 if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1375 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1376 reg_name, ins_parse);
1377
1378 crx_ins->arg[op_num].type = arg_cr;
1379 /* Post increment is represented in assembly as offset (register)+. */
1380 if (strstr (operand + i, "+") != NULL)
1381 /* There is a plus after the ')'. */
1382 post_inc_mode = 1;
1383 break;
1384 default:
1385 break;
1386 }
1387 if (change_flag == 1)
1388 crx_ins->arg[op_num].type = arg_ic;
1389 }
1390
1391 /* This is used to get the operand attributes -
1392 operand - current operand to be used
1393 number - operand number
1394 crx_ins - current assembled instruction. */
1395
1396 static void
1397 get_operandtype (char *operand, int number, ins * crx_ins)
1398 {
1399 int ret_val;
1400 char temp_operand[30];
1401
1402 switch (operand[0])
1403 {
1404 /* When it is a register. */
1405 case 'r':
1406 case 'c':
1407 case 'i':
1408 case 'u':
1409 case 's':
1410 case 'p':
1411 case 'l':
1412 case 'h':
1413 /* Check whether this is a general processor register. */
1414 ret_val = get_register (operand);
1415 if (ret_val != nullregister)
1416 {
1417 crx_ins->arg[number].type = arg_r;
1418 crx_ins->arg[number].r = ret_val;
1419 crx_ins->arg[number].size = REG_SIZE;
1420 }
1421 else
1422 {
1423 /* Check whether this is a core [special] coprocessor register. */
1424 ret_val = get_copregister (operand);
1425 if (ret_val != nullcopregister)
1426 {
1427 crx_ins->arg[number].type = arg_copr;
1428 if (ret_val >= cs0)
1429 crx_ins->arg[number].type = arg_copsr;
1430 crx_ins->arg[number].cr = ret_val;
1431 crx_ins->arg[number].size = REG_SIZE;
1432 }
1433 else
1434 {
1435 if (strchr (operand, '(') != NULL)
1436 {
1437 if (strchr (operand, ',') != NULL
1438 && (strchr (operand, ',') > strchr (operand, '(')))
1439 {
1440 crx_ins->arg[number].type = arg_icr;
1441 crx_ins->arg[number].constant = 0;
1442 set_indexmode_parameters (operand, crx_ins, number);
1443 get_number_of_bits (crx_ins, number);
1444 return;
1445 }
1446 else
1447 crx_ins->arg[number].type = arg_cr;
1448 }
1449 else
1450 crx_ins->arg[number].type = arg_c;
1451 crx_ins->arg[number].constant = 0;
1452 set_cons_rparams (operand, crx_ins, number);
1453 get_number_of_bits (crx_ins, number);
1454 }
1455 }
1456 break;
1457 case '$':
1458 if (strchr (operand, '(') != NULL)
1459 crx_ins->arg[number].type = arg_dcr;
1460 else
1461 crx_ins->arg[number].type = arg_dc;
1462 crx_ins->arg[number].constant = 0;
1463 set_cons_rparams (operand, crx_ins, number);
1464 get_number_of_bits (crx_ins, number);
1465 break;
1466
1467 case '(':
1468 /* Augmenting a zero in front of an operand -- won't work for tbit/sbit. */
1469 strcpy (temp_operand, "0");
1470 strcat (temp_operand, operand);
1471 if (strchr (temp_operand, ',') != NULL
1472 && (strchr (temp_operand, ',') > strchr (temp_operand, '(')))
1473 {
1474 crx_ins->arg[number].type = arg_icr;
1475 crx_ins->arg[number].constant = 0;
1476 set_indexmode_parameters (temp_operand, crx_ins, number);
1477 get_number_of_bits (crx_ins, number);
1478 return;
1479 }
1480 else
1481 {
1482 crx_ins->arg[number].type = arg_cr;
1483 crx_ins->arg[number].constant = 0;
1484 set_cons_rparams (operand, crx_ins, number);
1485 get_number_of_bits (crx_ins, number);
1486 if ((! strneq (instruction->mnemonic, "load", 4))
1487 && (! strneq (instruction->mnemonic, "stor", 4)))
1488 {
1489 crx_ins->arg[number].type = arg_rbase;
1490 crx_ins->arg[number].size = REG_SIZE;
1491 }
1492 return;
1493 }
1494 break;
1495 case '*':
1496 crx_ins->arg[number].type = arg_sc;
1497 crx_ins->arg[number].constant = 0;
1498 set_cons_rparams (operand, crx_ins, number);
1499 get_number_of_bits (crx_ins, number);
1500 break;
1501 case '+':
1502 case '-':
1503 case '0':
1504 case '1':
1505 case '2':
1506 case '3':
1507 case '4':
1508 case '5':
1509 case '6':
1510 case '7':
1511 case '8':
1512 case '9':
1513 if (strchr (operand, '(') != NULL)
1514 {
1515 if (strchr (operand, ',') != NULL
1516 && (strchr (operand, ',') > strchr (operand, '(')))
1517 {
1518 crx_ins->arg[number].type = arg_icr;
1519 crx_ins->arg[number].constant = 0;
1520 set_indexmode_parameters (operand, crx_ins, number);
1521 get_number_of_bits (crx_ins, number);
1522 return;
1523 }
1524 else
1525 crx_ins->arg[number].type = arg_cr;
1526 }
1527 else
1528 crx_ins->arg[number].type = arg_c;
1529 crx_ins->arg[number].constant = 0;
1530 set_cons_rparams (operand, crx_ins, number);
1531 get_number_of_bits (crx_ins, number);
1532 break;
1533 default:
1534 if (strchr (operand, '(') != NULL)
1535 {
1536 if (strchr (operand, ',') != NULL
1537 && (strchr (operand, ',') > strchr (operand, '(')))
1538 {
1539 crx_ins->arg[number].type = arg_icr;
1540 crx_ins->arg[number].constant = 0;
1541 set_indexmode_parameters (operand, crx_ins, number);
1542 get_number_of_bits (crx_ins, number);
1543 return;
1544 }
1545 else
1546 crx_ins->arg[number].type = arg_cr;
1547 }
1548 else
1549 crx_ins->arg[number].type = arg_c;
1550 crx_ins->arg[number].constant = 0;
1551 set_cons_rparams (operand, crx_ins, number);
1552 get_number_of_bits (crx_ins, number);
1553 break;
1554 }
1555 }
1556
1557 /* Operands are parsed over here, separated into various operands. Each operand
1558 is then analyzed to fillup the fields in the crx_ins data structure. */
1559
1560 static void
1561 parse_operands (ins * crx_ins, char *operands)
1562 {
1563 char *operandS; /* Operands string. */
1564 char *operandH, *operandT; /* Single operand head/tail pointers. */
1565 int allocated = 0; /* Indicates a new operands string was allocated. */
1566 char *operand[MAX_OPERANDS]; /* Separating the operands. */
1567 int op_num = 0; /* Current operand number we are parsing. */
1568 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
1569 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
1570
1571 /* Preprocess the list of registers, if necessary. */
1572 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
1573 preprocess_reglist (operands, &allocated) : operands;
1574
1575 while (*operandT != '\0')
1576 {
1577 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1578 {
1579 *operandT++ = '\0';
1580 operand[op_num++] = strdup (operandH);
1581 operandH = operandT;
1582 continue;
1583 }
1584
1585 if (*operandT == ' ')
1586 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1587
1588 if (*operandT == '(')
1589 bracket_flag = 1;
1590 else if (*operandT == '[')
1591 sq_bracket_flag = 1;
1592
1593 if (*operandT == ')')
1594 {
1595 if (bracket_flag)
1596 bracket_flag = 0;
1597 else
1598 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1599 }
1600 else if (*operandT == ']')
1601 {
1602 if (sq_bracket_flag)
1603 sq_bracket_flag = 0;
1604 else
1605 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1606 }
1607
1608 if (bracket_flag == 1 && *operandT == ')')
1609 bracket_flag = 0;
1610 else if (sq_bracket_flag == 1 && *operandT == ']')
1611 sq_bracket_flag = 0;
1612
1613 operandT++;
1614 }
1615
1616 /* Adding the last operand. */
1617 operand[op_num++] = strdup (operandH);
1618 crx_ins->nargs = op_num;
1619
1620 /* Verifying correct syntax of operands (all brackets should be closed). */
1621 if (bracket_flag || sq_bracket_flag)
1622 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1623
1624 /* Now to recongnize the operand types. */
1625 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1626 {
1627 get_operandtype (operand[op_num], op_num, crx_ins);
1628 free (operand[op_num]);
1629 }
1630
1631 if (allocated)
1632 free (operandS);
1633 }
1634
1635 /* Get the trap index in dispatch table, given its name.
1636 This routine is used by assembling the 'excp' instruction. */
1637
1638 static int
1639 gettrap (char *s)
1640 {
1641 const trap_entry *trap;
1642
1643 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1644 if (streq (trap->name, s))
1645 return trap->entry;
1646
1647 as_bad (_("Unknown exception: `%s'"), s);
1648 return 0;
1649 }
1650
1651 /* Post-Increment instructions are a sub-group within load/stor instruction
1652 groups. Therefore, when parsing a Post-Increment insn, we have to advance
1653 the instruction pointer to the start of that sub-group. */
1654
1655 static void
1656 handle_pi_insn (char *operands)
1657 {
1658 /* Assuming Post-Increment insn has the following format :
1659 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6'). */
1660 if (strstr (operands, ")+") != NULL)
1661 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1662 instruction++;
1663 }
1664
1665 /* Top level module where instruction parsing starts.
1666 crx_ins - data structure holds some information.
1667 operands - holds the operands part of the whole instruction. */
1668
1669 static void
1670 parse_insn (ins *insn, char *operands)
1671 {
1672 /* Handle 'excp'/'cinv' */
1673 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1674 {
1675 insn->nargs = 1;
1676 insn->arg[0].type = arg_ic;
1677 insn->arg[0].size = 4;
1678 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1679 gettrap (operands) : get_cinv_parameters (operands);
1680 return;
1681 }
1682
1683 /* Handle load/stor post-increment instructions. */
1684 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS))
1685 handle_pi_insn (operands);
1686
1687 if (operands != NULL)
1688 parse_operands (insn, operands);
1689 }
1690
1691 /* Cinv instruction requires special handling. */
1692
1693 static int
1694 get_cinv_parameters (char * operand)
1695 {
1696 char *p = operand;
1697 int d_used = 0, i_used = 0, u_used = 0;
1698
1699 while (*++p != ']')
1700 {
1701 if (*p == ',' || *p == ' ')
1702 continue;
1703
1704 if (*p == 'd')
1705 d_used = 1;
1706 else if (*p == 'i')
1707 i_used = 1;
1708 else if (*p == 'u')
1709 u_used = 1;
1710 else
1711 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1712 }
1713
1714 return ((d_used ? 4 : 0)
1715 + (i_used ? 2 : 0)
1716 + (u_used ? 1 : 0));
1717 }
1718
1719 /* Retrieve the opcode image of a given register.
1720 If the register is illegal for the current instruction,
1721 issue an error. */
1722
1723 static int
1724 getreg_image (reg r)
1725 {
1726 const reg_entry *reg;
1727 char *reg_name;
1728 int special_register_flag = 0;
1729 int movpr_flag = 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1730
1731 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1732 movpr_flag = 1;
1733
1734 if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1))
1735 || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) )
1736 special_register_flag = 1;
1737
1738 /* Check whether the register is in registers table. */
1739 if (r < MAX_REG)
1740 reg = &crx_regtab[r];
1741 /* Check whether the register is in coprocessor registers table. */
1742 else if (r < MAX_COPREG)
1743 reg = &crx_copregtab[r-MAX_REG];
1744 /* Register not found. */
1745 else
1746 {
1747 as_bad (_("Unknown register: `%d'"), r);
1748 return 0;
1749 }
1750
1751 reg_name = reg->name;
1752
1753 /* Issue a error message when register is illegal. */
1754 #define IMAGE_ERR \
1755 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1756 reg_name, ins_parse); \
1757 break;
1758
1759 switch (reg->type)
1760 {
1761 case CRX_U_REGTYPE:
1762 case CRX_CFG_REGTYPE:
1763 case CRX_MTPR_REGTYPE:
1764 if (movpr_flag && special_register_flag)
1765 return reg->image;
1766 else
1767 IMAGE_ERR;
1768
1769 case CRX_R_REGTYPE:
1770 case CRX_C_REGTYPE:
1771 case CRX_CS_REGTYPE:
1772 if (!(movpr_flag && special_register_flag))
1773 return reg->image;
1774 else
1775 IMAGE_ERR;
1776
1777 default:
1778 IMAGE_ERR;
1779 }
1780
1781 return 0;
1782 }
1783
1784 /* Routine used to get the binary-string equivalent of a integer constant
1785 which currently require currbits to represent itself to be extended to
1786 nbits. */
1787
1788 static unsigned long int
1789 getconstant (unsigned long int x, int nbits)
1790 {
1791 int cnt = 0;
1792 unsigned long int temp = x;
1793
1794 while (temp > 0)
1795 {
1796 temp >>= 1;
1797 cnt++;
1798 }
1799
1800 /* Escape sequence to next 16bit immediate. */
1801 if (cnt > nbits)
1802 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1803 x, cnt, ins_parse);
1804 else
1805 {
1806 if (signflag)
1807 x |= SET_BITS_MASK (cnt, nbits - cnt);
1808 else
1809 x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1810 }
1811
1812 /* The following expression avoids overflow if
1813 'nbits' is the number of bits in 'bfd_vma'. */
1814 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1815 }
1816
1817 /* Print a constant value to 'output_opcode':
1818 ARG holds the operand's type and value.
1819 SHIFT represents the location of the operand to be print into.
1820 NBITS determines the size (in bits) of the constant. */
1821
1822 static void
1823 print_constant (int nbits, int shift, argument *arg)
1824 {
1825 unsigned long mask = 0;
1826
1827 long constant = getconstant (arg->constant, nbits);
1828
1829 switch (nbits)
1830 {
1831 case 32:
1832 case 28:
1833 case 24:
1834 case 22:
1835 /* mask the upper part of the constant, that is, the bits
1836 going to the lowest byte of output_opcode[0].
1837 The upper part of output_opcode[1] is always filled,
1838 therefore it is always masked with 0xFFFF. */
1839 mask = (1 << (nbits - 16)) - 1;
1840 /* Divide the constant between two consecutive words :
1841 0 1 2 3
1842 +---------+---------+---------+---------+
1843 | | X X X X | X X X X | |
1844 +---------+---------+---------+---------+
1845 output_opcode[0] output_opcode[1] */
1846
1847 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1848 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1849 break;
1850
1851 case 16:
1852 case 12:
1853 /* Special case - in arg_cr, the SHIFT represents the location
1854 of the REGISTER, not the constant, which is itself not shifted. */
1855 if (arg->type == arg_cr)
1856 {
1857 CRX_PRINT (0, constant, 0);
1858 break;
1859 }
1860
1861 /* When instruction size is 3, a 16-bit constant is always
1862 filling the upper part of output_opcode[1]. */
1863 if (instruction->size > 2)
1864 CRX_PRINT (1, constant, WORD_SHIFT);
1865 else
1866 CRX_PRINT (0, constant, shift);
1867 break;
1868
1869 default:
1870 CRX_PRINT (0, constant, shift);
1871 break;
1872 }
1873 }
1874
1875 /* Print an operand to 'output_opcode', which later on will be
1876 printed to the object file:
1877 ARG holds the operand's type, size and value.
1878 SHIFT represents the printing location of operand.
1879 NBITS determines the size (in bits) of a constant operand. */
1880
1881 static void
1882 print_operand (int nbits, int shift, argument *arg)
1883 {
1884 switch (arg->type)
1885 {
1886 case arg_r:
1887 CRX_PRINT (0, getreg_image (arg->r), shift);
1888 break;
1889
1890 case arg_copr:
1891 if (arg->cr < c0 || arg->cr > c15)
1892 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1893 ins_parse);
1894 CRX_PRINT (0, getreg_image (arg->cr), shift);
1895 break;
1896
1897 case arg_copsr:
1898 if (arg->cr < cs0 || arg->cr > cs15)
1899 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1900 ins_parse);
1901 CRX_PRINT (0, getreg_image (arg->cr), shift);
1902 break;
1903
1904 case arg_ic:
1905 print_constant (nbits, shift, arg);
1906 break;
1907
1908 case arg_icr:
1909 /* 16 12 8 6 0
1910 +--------------------------------+
1911 | reg | r_base | scl| disp |
1912 +--------------------------------+ */
1913 CRX_PRINT (0, getreg_image (arg->r), 12);
1914 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1915 CRX_PRINT (0, arg->scale, 6);
1916 print_constant (nbits, shift, arg);
1917 break;
1918
1919 case arg_rbase:
1920 CRX_PRINT (0, getreg_image (arg->r), shift);
1921 break;
1922
1923 case arg_cr:
1924 /* case base_cst4. */
1925 if ((instruction->flags & CST4MAP) && cst4flag)
1926 output_opcode[0] |= (getconstant (arg->constant, nbits)
1927 << (shift + REG_SIZE));
1928 else
1929 /* rbase_dispu<NN> and other such cases. */
1930 print_constant (nbits, shift, arg);
1931 /* Add the register argument to the output_opcode. */
1932 CRX_PRINT (0, getreg_image (arg->r), shift);
1933 break;
1934
1935 case arg_c:
1936 print_constant (nbits, shift, arg);
1937 break;
1938
1939 default:
1940 break;
1941 }
1942 }
1943
1944 /* Retrieve the number of operands for the current assembled instruction. */
1945
1946 static int
1947 get_number_of_operands (void)
1948 {
1949 int i;
1950
1951 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1952 ;
1953 return i;
1954 }
1955
1956 /* Assemble a single instruction :
1957 Instruction has been parsed and all operand values set appropriately.
1958 Algorithm for assembling -
1959 For instruction to be assembled:
1960 Step 1: Find instruction in the array crx_instruction with same mnemonic.
1961 Step 2: Find instruction with same operand types.
1962 Step 3: If (size_of_operands) match then done, else increment the
1963 array_index and goto Step3.
1964 Step 4: Cannot assemble
1965 Returns 1 upon success, 0 upon failure. */
1966
1967 static int
1968 assemble_insn (char *mnemonic, ins *insn)
1969 {
1970 /* Argument type of each operand in the instruction we are looking for. */
1971 argtype atyp[MAX_OPERANDS];
1972 /* Argument type of each operand in the current instruction. */
1973 argtype atyp_act[MAX_OPERANDS];
1974 /* Size (in bits) of each operand in the instruction we are looking for. */
1975 int bits[MAX_OPERANDS];
1976 /* Size (in bits) of each operand in the current instruction. */
1977 int bits_act[MAX_OPERANDS];
1978 /* Location (in bits) of each operand in the current instruction. */
1979 int shift_act[MAX_OPERANDS];
1980 int match = 0;
1981 int done_flag = 0;
1982 int cst4maptype = 0;
1983 int changed_already = 0;
1984 unsigned int temp_value = 0;
1985 int instrtype, i;
1986 /* A pointer to the argument's constant value. */
1987 unsigned long int *cons;
1988 /* Pointer to loop over all cst4_map entries. */
1989 const cst4_entry *cst4_op;
1990
1991 /* Instruction has no operands -> copy only the constant opcode. */
1992 if (insn->nargs == 0)
1993 {
1994 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1995 return 1;
1996 }
1997
1998 /* Find instruction with same number of operands. */
1999 while (get_number_of_operands () != insn->nargs
2000 && IS_INSN_MNEMONIC (mnemonic))
2001 instruction++;
2002
2003 if (!IS_INSN_MNEMONIC (mnemonic))
2004 return 0;
2005
2006 /* Initialize argument type and size of each given operand. */
2007 for (i = 0; i < insn->nargs; i++)
2008 {
2009 atyp[i] = insn->arg[i].type;
2010 bits[i] = insn->arg[i].size;
2011 }
2012
2013 /* Initialize argument type and size of each operand in current inst. */
2014 GET_ACTUAL_TYPE;
2015 GET_ACTUAL_SIZE;
2016
2017 while (match != 1
2018 /* Check we didn't get to end of table. */
2019 && instruction->mnemonic != NULL
2020 /* Check that the actual mnemonic is still available. */
2021 && IS_INSN_MNEMONIC (mnemonic))
2022 {
2023 /* Check for argement type compatibility. */
2024 for (i = 0; i < insn->nargs; i++)
2025 {
2026 if (atyp_act[i] == atyp[i])
2027 done_flag = 1;
2028 else
2029 {
2030 done_flag = 0;
2031 break;
2032 }
2033 }
2034 if (done_flag)
2035 {
2036 /* Check for post inc mode of the current instruction. */
2037 if (post_inc_mode == 1 || IS_INSN_TYPE (LD_STOR_INS_INC))
2038 done_flag = (post_inc_mode == IS_INSN_TYPE (LD_STOR_INS_INC));
2039 }
2040
2041 if (done_flag == 0)
2042 {
2043 /* Try again with next instruction. */
2044 instruction++;
2045 GET_ACTUAL_TYPE;
2046 GET_ACTUAL_SIZE;
2047 continue;
2048 }
2049 else
2050 {
2051 /* Check for size compatibility. */
2052 for (i = 0; i < insn->nargs; i++)
2053 {
2054 if (bits[i] > bits_act[i])
2055 {
2056 /* Actual size is too small - try again. */
2057 done_flag = 0;
2058 instruction++;
2059 GET_ACTUAL_TYPE;
2060 GET_ACTUAL_SIZE;
2061 break;
2062 }
2063 }
2064
2065 }
2066
2067 if (done_flag == 1)
2068 {
2069 /* Full match is found. */
2070 match = 1;
2071 break;
2072 }
2073 }
2074
2075 if (match == 0)
2076 /* We haven't found a match - instruction can't be assembled. */
2077 return 0;
2078 else
2079 /* Full match - print the final image. */
2080 {
2081 /* Handle positive constants. */
2082 if (!signflag)
2083 {
2084 if (IS_INSN_TYPE (LD_STOR_INS) && !relocatable)
2085 {
2086 /* Get the map type of the instruction. */
2087 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2088 cons = &insn->arg[instrtype].constant;
2089 cst4maptype = instruction->flags & CST4MAP;
2090
2091 switch (cst4maptype)
2092 {
2093 case DISPUB4:
2094 /* 14 and 15 are reserved escape sequences of dispub4. */
2095 if (*cons == 14 || *cons == 15)
2096 {
2097 instruction++;
2098 GET_ACTUAL_SIZE;
2099 }
2100 break;
2101
2102 case DISPUW4:
2103 /* Mapping has to be done. */
2104 if (*cons <= 15 && *cons % 2 != 0)
2105 {
2106 instruction++;
2107 GET_ACTUAL_SIZE;
2108 }
2109 else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2110 {
2111 instruction--;
2112 GET_ACTUAL_SIZE;
2113 }
2114 if (*cons < 27 && *cons % 2 == 0)
2115 *cons /= 2;
2116 break;
2117
2118 case DISPUD4:
2119 /* Mapping has to be done. */
2120 if (*cons <= 15 && *cons % 4 != 0)
2121 {
2122 instruction++;
2123 GET_ACTUAL_SIZE;
2124 }
2125 else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2126 {
2127 instruction--;
2128 GET_ACTUAL_SIZE;
2129 }
2130 if (*cons < 53 && *cons % 4 == 0)
2131 *cons /= 4;
2132 break;
2133 default:
2134 break;
2135 }
2136 }
2137 if ((IS_INSN_TYPE (ARITH_BYTE_INS) || IS_INSN_TYPE (ARITH_INS))
2138 && !relocatable)
2139 {
2140 /* Check whether a cst4 mapping has to be done. */
2141 if ((instruction->operands[0].op_type == cst4
2142 || instruction->operands[0].op_type == i16)
2143 && (instruction->operands[1].op_type == regr))
2144 {
2145 /* 'const' equals reserved escape sequences -->>
2146 represent as i16. */
2147 if (insn->arg[0].constant == ESC_16
2148 || insn->arg[0].constant == ESC_32)
2149 {
2150 instruction++;
2151 GET_ACTUAL_SIZE;
2152 }
2153 else
2154 {
2155 /* Loop over cst4_map entries. */
2156 for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2157 cst4_op++)
2158 {
2159 /* 'const' equals a binary, which is already mapped
2160 by a different value -->> represent as i16. */
2161 if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2162 && cst4_op->binary != cst4_op->value)
2163 {
2164 instruction++;
2165 GET_ACTUAL_SIZE;
2166 }
2167 /* 'const' equals a value bigger than 16 -->> map to
2168 its binary and represent as cst4. */
2169 else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2170 && insn->arg[0].constant >= 16)
2171 {
2172 instruction--;
2173 insn->arg[0].constant = cst4_op->binary;
2174 GET_ACTUAL_SIZE;
2175 }
2176 }
2177 }
2178 }
2179 /* Special check for 'addub 0, r0' instruction -
2180 The opcode '0000 0000 0000 0000' is not allowed. */
2181 if (IS_INSN_MNEMONIC ("addub"))
2182 {
2183 if ((instruction->operands[0].op_type == cst4)
2184 && instruction->operands[1].op_type == regr)
2185 {
2186 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2187 instruction++;
2188 }
2189 }
2190 }
2191 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
2192 || IS_INSN_TYPE (LD_STOR_INS_INC))
2193 {
2194 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2195 if (instruction->operands[instrtype].op_type == rbase)
2196 instruction++;
2197 }
2198 /* Error checking in case of post-increment instruction. */
2199 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2200 {
2201 if (!((strneq (instruction->mnemonic, "stor", 4))
2202 && (insn->arg[0].type != arg_r)))
2203 if (insn->arg[0].r == insn->arg[1].r)
2204 as_bad (_("Invalid instruction : `%s' Source and Destination register \
2205 same in Post INC mode"), ins_parse);
2206 }
2207 if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2208 {
2209 if (instruction->operands[1].op_type == rbase_dispu12)
2210 {
2211 if (insn->arg[1].constant == 0)
2212 {
2213 instruction--;
2214 GET_ACTUAL_SIZE;
2215 }
2216 }
2217 }
2218 if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2219 || IS_INSN_TYPE (STOR_IMM_INS)
2220 || IS_INSN_TYPE (LD_STOR_INS_INC)) & !relocatable)
2221 {
2222 instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2223 changed_already = 0;
2224 /* Convert 32 bits accesses to 16 bits accesses. */
2225 if (instruction->operands[instrtype].op_type == abs32)
2226 {
2227 if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2228 {
2229 instruction--;
2230 insn->arg[instrtype].constant =
2231 insn->arg[instrtype].constant & 0xFFFF;
2232 insn->arg[instrtype].size = 16;
2233 changed_already = 1;
2234 GET_ACTUAL_SIZE;
2235 }
2236 }
2237 /* Convert 16 bits accesses to 32 bits accesses. */
2238 if (instruction->operands[instrtype].op_type == abs16
2239 && changed_already != 1)
2240 {
2241 instruction++;
2242 insn->arg[instrtype].constant =
2243 insn->arg[instrtype].constant & 0xFFFF;
2244 insn->arg[instrtype].size = 32;
2245 GET_ACTUAL_SIZE;
2246 }
2247 changed_already = 0;
2248 }
2249 if (IS_INSN_TYPE (BRANCH_INS) && !relocatable)
2250 {
2251 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2252 if (insn->arg[0].constant == 0x7e || insn->arg[0].constant == 0x7f)
2253 {
2254 instruction++;
2255 GET_ACTUAL_SIZE;
2256 }
2257 }
2258 }
2259
2260 for (i = 0; i < insn->nargs; i++)
2261 {
2262 if (instruction->operands[i].op_type == cst4
2263 || instruction->operands[i].op_type == rbase_cst4)
2264 cst4flag = 1;
2265 }
2266
2267 /* First, copy the instruction's opcode. */
2268 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2269
2270 /* Swap the argument values in case bcop instructions. */
2271 if (IS_INSN_TYPE (COP_BRANCH_INS))
2272 {
2273 temp_value = insn->arg[0].constant;
2274 insn->arg[0].constant = insn->arg[1].constant;
2275 insn->arg[1].constant = temp_value;
2276 }
2277
2278 for (i = 0; i < insn->nargs; i++)
2279 {
2280 shift_act[i] = instruction->operands[i].shift;
2281 signflag = insn->arg[i].signflag;
2282 processing_arg_number = i;
2283 print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2284 }
2285 }
2286
2287 return 1;
2288 }
2289
2290 /* Set the appropriate bit for register 'r' in 'mask'.
2291 This indicates that this register is loaded or stored by
2292 the instruction. */
2293
2294 static void
2295 mask_reg (int r, unsigned short int *mask)
2296 {
2297 if ((reg)r > (reg)sp)
2298 {
2299 as_bad (_("Invalid Register in Register List"));
2300 return;
2301 }
2302
2303 *mask |= (1 << r);
2304 }
2305
2306 /* Preprocess register list - create a 16-bit mask with one bit for each
2307 of the 16 general purpose registers. If a bit is set, it indicates
2308 that this register is loaded or stored by the instruction. */
2309
2310 static char *
2311 preprocess_reglist (char *param, int *allocated)
2312 {
2313 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
2314 char *regP; /* Pointer to 'reg_name' string. */
2315 int reg_counter = 0; /* Count number of parsed registers. */
2316 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
2317 char *new_param; /* New created operands string. */
2318 char *paramP = param; /* Pointer to original opearands string. */
2319 char maskstring[10]; /* Array to print the mask as a string. */
2320 reg r;
2321 copreg cr;
2322
2323 /* If 'param' is already in form of a number, no need to preprocess. */
2324 if (strchr (paramP, '{') == NULL)
2325 return param;
2326
2327 /* Verifying correct syntax of operand. */
2328 if (strchr (paramP, '}') == NULL)
2329 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2330
2331 while (*paramP++ != '{');
2332
2333 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2334 *allocated = 1;
2335 strncpy (new_param, param, paramP - param - 1);
2336
2337 while (*paramP != '}')
2338 {
2339 regP = paramP;
2340 memset (&reg_name, '\0', sizeof (reg_name));
2341
2342 while (ISALNUM (*paramP))
2343 paramP++;
2344
2345 strncpy (reg_name, regP, paramP - regP);
2346
2347 if (IS_INSN_TYPE (COP_REG_INS))
2348 {
2349 if ((cr = get_copregister (reg_name)) == nullcopregister)
2350 as_bad (_("Illegal register `%s' in cop-register list"), reg_name);
2351 mask_reg (getreg_image (cr - c0), &mask);
2352 }
2353 else
2354 {
2355 if ((r = get_register (reg_name)) == nullregister)
2356 as_bad (_("Illegal register `%s' in register list"), reg_name);
2357 mask_reg (getreg_image (r), &mask);
2358 }
2359
2360 if (++reg_counter > MAX_REGS_IN_MASK16)
2361 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2362 MAX_REGS_IN_MASK16);
2363
2364 while (!ISALNUM (*paramP) && *paramP != '}')
2365 paramP++;
2366 }
2367
2368 if (*++paramP != '\0')
2369 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2370 *paramP);
2371
2372 if (mask == 0)
2373 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2374 ins_parse);
2375
2376 sprintf (maskstring, "$0x%x", mask);
2377 strcat (new_param, maskstring);
2378 return new_param;
2379 }
2380
2381 /* Print the instruction.
2382 Handle also cases where the instruction is relaxable/relocatable. */
2383
2384 void
2385 print_insn (ins *insn)
2386 {
2387 unsigned int i, j, insn_size;
2388 char *this_frag;
2389 unsigned short words[4];
2390
2391 /* Arrange the insn encodings in a WORD size array. */
2392 for (i = 0, j = 0; i < 2; i++)
2393 {
2394 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2395 words[j++] = output_opcode[i] & 0xFFFF;
2396 }
2397
2398 /* Handle relaxtion. */
2399 if ((instruction->flags & RELAXABLE) && relocatable)
2400 {
2401 int relax_subtype;
2402
2403 /* Write the maximal instruction size supported. */
2404 insn_size = INSN_MAX_SIZE;
2405
2406 /* bCC */
2407 if (IS_INSN_TYPE (BRANCH_INS))
2408 relax_subtype = 0;
2409 /* bal */
2410 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2411 relax_subtype = 3;
2412 /* cmpbr */
2413 else if (IS_INSN_TYPE (CMPBR_INS))
2414 relax_subtype = 5;
2415 else
2416 abort ();
2417
2418 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2419 4, relax_subtype,
2420 insn->exp.X_add_symbol,
2421 insn->exp.X_add_number,
2422 0);
2423 }
2424 else
2425 {
2426 insn_size = instruction->size;
2427 this_frag = frag_more (insn_size * 2);
2428
2429 /* Handle relocation. */
2430 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2431 {
2432 reloc_howto_type *reloc_howto;
2433 int size;
2434
2435 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2436
2437 if (!reloc_howto)
2438 abort ();
2439
2440 size = bfd_get_reloc_size (reloc_howto);
2441
2442 if (size < 1 || size > 4)
2443 abort ();
2444
2445 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2446 size, &insn->exp, reloc_howto->pc_relative,
2447 insn->rtype);
2448 }
2449 }
2450
2451 /* Write the instruction encoding to frag. */
2452 for (i = 0; i < insn_size; i++)
2453 {
2454 md_number_to_chars (this_frag, (valueT) words[i], 2);
2455 this_frag += 2;
2456 }
2457 }
2458
2459 /* This is the guts of the machine-dependent assembler. OP points to a
2460 machine dependent instruction. This function is supposed to emit
2461 the frags/bytes it assembles to. */
2462
2463 void
2464 md_assemble (char *op)
2465 {
2466 ins crx_ins;
2467 char *param;
2468 char c;
2469
2470 /* Reset global variables for a new instruction. */
2471 reset_vars (op, &crx_ins);
2472
2473 /* Strip the mnemonic. */
2474 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2475 ;
2476 c = *param;
2477 *param++ = '\0';
2478
2479 /* Find the instruction. */
2480 instruction = (const inst *) hash_find (crx_inst_hash, op);
2481 if (instruction == NULL)
2482 {
2483 as_bad (_("Unknown opcode: `%s'"), op);
2484 return;
2485 }
2486
2487 /* Tie dwarf2 debug info to the address at the start of the insn. */
2488 dwarf2_emit_insn (0);
2489
2490 if (NO_OPERANDS_INST (op))
2491 /* Handle instructions with no operands. */
2492 crx_ins.nargs = 0;
2493 else
2494 /* Parse the instruction's operands. */
2495 parse_insn (&crx_ins, param);
2496
2497 /* Assemble the instruction. */
2498 if (assemble_insn (op, &crx_ins) == 0)
2499 {
2500 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2501 return;
2502 }
2503
2504 /* Print the instruction. */
2505 print_insn (&crx_ins);
2506 }
This page took 0.108767 seconds and 5 git commands to generate.