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