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 /* Word is considered here as a 16-bit unsigned short int. */
32 #define WORD_SHIFT 16
33
34 /* Register is 4-bit size. */
35 #define REG_SIZE 4
36
37 /* Maximum size of a single instruction (in words). */
38 #define INSN_MAX_SIZE 3
39
40 /* Maximum bits which may be set in a `mask16' operand. */
41 #define MAX_REGS_IN_MASK16 8
42
43 /* Utility macros for string comparison. */
44 #define streq(a, b) (strcmp (a, b) == 0)
45 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
46
47 /* Assign a number NUM, shifted by SHIFT bytes, into a location
48 pointed by index BYTE of array 'output_opcode'. */
49 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
50
51 /* Operand errors. */
52 typedef enum
53 {
54 OP_LEGAL = 0, /* Legal operand. */
55 OP_OUT_OF_RANGE, /* Operand not within permitted range. */
56 OP_NOT_EVEN, /* Operand is Odd number, should be even. */
57 OP_ILLEGAL_DISPU4, /* Operand is not within DISPU4 range. */
58 OP_ILLEGAL_CST4, /* Operand is not within CST4 range. */
59 OP_NOT_UPPER_64KB /* Operand is not within the upper 64KB
60 (0xFFFF0000-0xFFFFFFFF). */
61 }
62 op_err;
63
64 /* Opcode mnemonics hash table. */
65 static struct hash_control *crx_inst_hash;
66 /* CRX registers hash table. */
67 static struct hash_control *reg_hash;
68 /* CRX coprocessor registers hash table. */
69 static struct hash_control *copreg_hash;
70 /* Current instruction we're assembling. */
71 const inst *instruction;
72
73 /* Global variables. */
74
75 /* Array to hold an instruction encoding. */
76 long output_opcode[2];
77
78 /* Nonzero means a relocatable symbol. */
79 int relocatable;
80
81 /* A copy of the original instruction (used in error messages). */
82 char ins_parse[MAX_INST_LEN];
83
84 /* The current processed argument number. */
85 int cur_arg_num;
86
87 /* Generic assembler global variables which must be defined by all targets. */
88
89 /* Characters which always start a comment. */
90 const char comment_chars[] = "#";
91
92 /* Characters which start a comment at the beginning of a line. */
93 const char line_comment_chars[] = "#";
94
95 /* This array holds machine specific line separator characters. */
96 const char line_separator_chars[] = ";";
97
98 /* Chars that can be used to separate mant from exp in floating point nums. */
99 const char EXP_CHARS[] = "eE";
100
101 /* Chars that mean this number is a floating point constant as in 0f12.456 */
102 const char FLT_CHARS[] = "f'";
103
104 /* Target-specific multicharacter options, not const-declared at usage. */
105 const char *md_shortopts = "";
106 struct option md_longopts[] =
107 {
108 {NULL, no_argument, NULL, 0}
109 };
110 size_t md_longopts_size = sizeof (md_longopts);
111
112 /* This table describes all the machine specific pseudo-ops
113 the assembler has to support. The fields are:
114 *** Pseudo-op name without dot.
115 *** Function to call to execute this pseudo-op.
116 *** Integer arg to pass to the function. */
117
118 const pseudo_typeS md_pseudo_table[] =
119 {
120 /* In CRX machine, align is in bytes (not a ptwo boundary). */
121 {"align", s_align_bytes, 0},
122 {0, 0, 0}
123 };
124
125 /* CRX relaxation table. */
126 const relax_typeS md_relax_table[] =
127 {
128 /* bCC */
129 {0xfa, -0x100, 2, 1}, /* 8 */
130 {0xfffe, -0x10000, 4, 2}, /* 16 */
131 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
132
133 /* bal */
134 {0xfffe, -0x10000, 4, 4}, /* 16 */
135 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
136
137 /* cmpbr/bcop */
138 {0xfe, -0x100, 4, 6}, /* 8 */
139 {0xfffffe, -0x1000000, 6, 0} /* 24 */
140 };
141
142 static void reset_vars (char *);
143 static reg get_register (char *);
144 static copreg get_copregister (char *);
145 static argtype get_optype (operand_type);
146 static int get_opbits (operand_type);
147 static int get_opflags (operand_type);
148 static int get_number_of_operands (void);
149 static void parse_operand (char *, ins *);
150 static int gettrap (char *);
151 static void handle_LoadStor (char *);
152 static int get_cinv_parameters (char *);
153 static long getconstant (long, int);
154 static op_err check_range (long *, int, unsigned int, int);
155 static int getreg_image (reg);
156 static void parse_operands (ins *, char *);
157 static void parse_insn (ins *, char *);
158 static void print_operand (int, int, argument *);
159 static void print_constant (int, int, argument *);
160 static int exponent2scale (int);
161 static void mask_reg (int, unsigned short *);
162 static void process_label_constant (char *, ins *);
163 static void set_operand (char *, ins *);
164 static char * preprocess_reglist (char *, int *);
165 static int assemble_insn (char *, ins *);
166 static void print_insn (ins *);
167 static void warn_if_needed (ins *);
168 static int adjust_if_needed (ins *);
169
170 /* Return the bit size for a given operand. */
171
172 static int
get_opbits(operand_type op)173 get_opbits (operand_type op)
174 {
175 if (op < MAX_OPRD)
176 return crx_optab[op].bit_size;
177 else
178 return 0;
179 }
180
181 /* Return the argument type of a given operand. */
182
183 static argtype
get_optype(operand_type op)184 get_optype (operand_type op)
185 {
186 if (op < MAX_OPRD)
187 return crx_optab[op].arg_type;
188 else
189 return nullargs;
190 }
191
192 /* Return the flags of a given operand. */
193
194 static int
get_opflags(operand_type op)195 get_opflags (operand_type op)
196 {
197 if (op < MAX_OPRD)
198 return crx_optab[op].flags;
199 else
200 return 0;
201 }
202
203 /* Get the core processor register 'reg_name'. */
204
205 static reg
get_register(char * reg_name)206 get_register (char *reg_name)
207 {
208 const reg_entry *reg;
209
210 reg = (const reg_entry *) hash_find (reg_hash, reg_name);
211
212 if (reg != NULL)
213 return reg->value.reg_val;
214 else
215 return nullregister;
216 }
217
218 /* Get the coprocessor register 'copreg_name'. */
219
220 static copreg
get_copregister(char * copreg_name)221 get_copregister (char *copreg_name)
222 {
223 const reg_entry *copreg;
224
225 copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
226
227 if (copreg != NULL)
228 return copreg->value.copreg_val;
229 else
230 return nullcopregister;
231 }
232
233 /* Round up a section size to the appropriate boundary. */
234
235 valueT
md_section_align(segT seg,valueT val)236 md_section_align (segT seg, valueT val)
237 {
238 /* Round .text section to a multiple of 2. */
239 if (seg == text_section)
240 return (val + 1) & ~1;
241 return val;
242 }
243
244 /* Parse an operand that is machine-specific (remove '*'). */
245
246 void
md_operand(expressionS * exp)247 md_operand (expressionS * exp)
248 {
249 char c = *input_line_pointer;
250
251 switch (c)
252 {
253 case '*':
254 input_line_pointer++;
255 expression (exp);
256 break;
257 default:
258 break;
259 }
260 }
261
262 /* Reset global variables before parsing a new instruction. */
263
264 static void
reset_vars(char * op)265 reset_vars (char *op)
266 {
267 cur_arg_num = relocatable = 0;
268 memset (& output_opcode, '\0', sizeof (output_opcode));
269
270 /* Save a copy of the original OP (used in error messages). */
271 strcpy (ins_parse, op);
272 }
273
274 /* This macro decides whether a particular reloc is an entry in a
275 switch table. It is used when relaxing, because the linker needs
276 to know about all such entries so that it can adjust them if
277 necessary. */
278
279 #define SWITCH_TABLE(fix) \
280 ( (fix)->fx_addsy != NULL \
281 && (fix)->fx_subsy != NULL \
282 && S_GET_SEGMENT ((fix)->fx_addsy) == \
283 S_GET_SEGMENT ((fix)->fx_subsy) \
284 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
285 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
286 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
287 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
288
289 /* See whether we need to force a relocation into the output file.
290 This is used to force out switch and PC relative relocations when
291 relaxing. */
292
293 int
crx_force_relocation(fixS * fix)294 crx_force_relocation (fixS *fix)
295 {
296 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
297 return 1;
298
299 return 0;
300 }
301
302 /* Generate a relocation entry for a fixup. */
303
304 arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixP)305 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
306 {
307 arelent * reloc;
308
309 reloc = xmalloc (sizeof (arelent));
310 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
311 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
312 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
313 reloc->addend = fixP->fx_offset;
314
315 if (fixP->fx_subsy != NULL)
316 {
317 if (SWITCH_TABLE (fixP))
318 {
319 /* Keep the current difference in the addend. */
320 reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
321 - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
322
323 switch (fixP->fx_r_type)
324 {
325 case BFD_RELOC_CRX_NUM8:
326 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
327 break;
328 case BFD_RELOC_CRX_NUM16:
329 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
330 break;
331 case BFD_RELOC_CRX_NUM32:
332 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
333 break;
334 default:
335 abort ();
336 break;
337 }
338 }
339 else
340 {
341 /* We only resolve difference expressions in the same section. */
342 as_bad_where (fixP->fx_file, fixP->fx_line,
343 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
344 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
345 segment_name (fixP->fx_addsy
346 ? S_GET_SEGMENT (fixP->fx_addsy)
347 : absolute_section),
348 S_GET_NAME (fixP->fx_subsy),
349 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
350 }
351 }
352
353 assert ((int) fixP->fx_r_type > 0);
354 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
355
356 if (reloc->howto == (reloc_howto_type *) NULL)
357 {
358 as_bad_where (fixP->fx_file, fixP->fx_line,
359 _("internal error: reloc %d (`%s') not supported by object file format"),
360 fixP->fx_r_type,
361 bfd_get_reloc_code_name (fixP->fx_r_type));
362 return NULL;
363 }
364 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
365
366 return reloc;
367 }
368
369 /* Prepare machine-dependent frags for relaxation. */
370
371 int
md_estimate_size_before_relax(fragS * fragp,asection * seg)372 md_estimate_size_before_relax (fragS *fragp, asection *seg)
373 {
374 /* If symbol is undefined or located in a different section,
375 select the largest supported relocation. */
376 relax_substateT subtype;
377 relax_substateT rlx_state[] = {0, 2,
378 3, 4,
379 5, 6};
380
381 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
382 {
383 if (fragp->fr_subtype == rlx_state[subtype]
384 && (!S_IS_DEFINED (fragp->fr_symbol)
385 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
386 {
387 fragp->fr_subtype = rlx_state[subtype + 1];
388 break;
389 }
390 }
391
392 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
393 abort ();
394
395 return md_relax_table[fragp->fr_subtype].rlx_length;
396 }
397
398 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,fragS * fragP)399 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
400 {
401 /* 'opcode' points to the start of the instruction, whether
402 we need to change the instruction's fixed encoding. */
403 char *opcode = fragP->fr_literal + fragP->fr_fix;
404 bfd_reloc_code_real_type reloc;
405
406 subseg_change (sec, 0);
407
408 switch (fragP->fr_subtype)
409 {
410 case 0:
411 reloc = BFD_RELOC_CRX_REL8;
412 break;
413 case 1:
414 *opcode = 0x7e;
415 reloc = BFD_RELOC_CRX_REL16;
416 break;
417 case 2:
418 *opcode = 0x7f;
419 reloc = BFD_RELOC_CRX_REL32;
420 break;
421 case 3:
422 reloc = BFD_RELOC_CRX_REL16;
423 break;
424 case 4:
425 *++opcode = 0x31;
426 reloc = BFD_RELOC_CRX_REL32;
427 break;
428 case 5:
429 reloc = BFD_RELOC_CRX_REL8_CMP;
430 break;
431 case 6:
432 *++opcode = 0x31;
433 reloc = BFD_RELOC_CRX_REL24;
434 break;
435 default:
436 abort ();
437 break;
438 }
439
440 fix_new (fragP, fragP->fr_fix,
441 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
442 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
443 fragP->fr_var = 0;
444 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
445 }
446
447 /* Process machine-dependent command line options. Called once for
448 each option on the command line that the machine-independent part of
449 GAS does not understand. */
450
451 int
md_parse_option(int c ATTRIBUTE_UNUSED,char * arg ATTRIBUTE_UNUSED)452 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
453 {
454 return 0;
455 }
456
457 /* Machine-dependent usage-output. */
458
459 void
md_show_usage(FILE * stream ATTRIBUTE_UNUSED)460 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
461 {
462 return;
463 }
464
465 /* Turn a string in input_line_pointer into a floating point constant
466 of type TYPE, and store the appropriate bytes in *LITP. The number
467 of LITTLENUMS emitted is stored in *SIZEP. An error message is
468 returned, or NULL on OK. */
469
470 char *
md_atof(int type,char * litP,int * sizeP)471 md_atof (int type, char *litP, int *sizeP)
472 {
473 int prec;
474 LITTLENUM_TYPE words[4];
475 char *t;
476 int i;
477
478 switch (type)
479 {
480 case 'f':
481 prec = 2;
482 break;
483
484 case 'd':
485 prec = 4;
486 break;
487
488 default:
489 *sizeP = 0;
490 return _("bad call to md_atof");
491 }
492
493 t = atof_ieee (input_line_pointer, type, words);
494 if (t)
495 input_line_pointer = t;
496
497 *sizeP = prec * 2;
498
499 if (! target_big_endian)
500 {
501 for (i = prec - 1; i >= 0; i--)
502 {
503 md_number_to_chars (litP, (valueT) words[i], 2);
504 litP += 2;
505 }
506 }
507 else
508 {
509 for (i = 0; i < prec; i++)
510 {
511 md_number_to_chars (litP, (valueT) words[i], 2);
512 litP += 2;
513 }
514 }
515
516 return NULL;
517 }
518
519 /* Apply a fixS (fixup of an instruction or data that we didn't have
520 enough info to complete immediately) to the data in a frag.
521 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
522 relaxation of debug sections, this function is called only when
523 fixuping relocations of debug sections. */
524
525 void
md_apply_fix3(fixS * fixP,valueT * valP,segT seg)526 md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
527 {
528 valueT val = * valP;
529 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
530 fixP->fx_offset = 0;
531
532 switch (fixP->fx_r_type)
533 {
534 case BFD_RELOC_CRX_NUM8:
535 bfd_put_8 (stdoutput, (unsigned char) val, buf);
536 break;
537 case BFD_RELOC_CRX_NUM16:
538 bfd_put_16 (stdoutput, val, buf);
539 break;
540 case BFD_RELOC_CRX_NUM32:
541 bfd_put_32 (stdoutput, val, buf);
542 break;
543 default:
544 /* We shouldn't ever get here because linkrelax is nonzero. */
545 abort ();
546 break;
547 }
548
549 fixP->fx_done = 0;
550
551 if (fixP->fx_addsy == NULL
552 && fixP->fx_pcrel == 0)
553 fixP->fx_done = 1;
554
555 if (fixP->fx_pcrel == 1
556 && fixP->fx_addsy != NULL
557 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
558 fixP->fx_done = 1;
559 }
560
561 /* The location from which a PC relative jump should be calculated,
562 given a PC relative reloc. */
563
564 long
md_pcrel_from(fixS * fixp)565 md_pcrel_from (fixS *fixp)
566 {
567 return fixp->fx_frag->fr_address + fixp->fx_where;
568 }
569
570 /* This function is called once, at assembler startup time. This should
571 set up all the tables, etc that the MD part of the assembler needs. */
572
573 void
md_begin(void)574 md_begin (void)
575 {
576 const char *hashret = NULL;
577 int i = 0;
578
579 /* Set up a hash table for the instructions. */
580 if ((crx_inst_hash = hash_new ()) == NULL)
581 as_fatal (_("Virtual memory exhausted"));
582
583 while (crx_instruction[i].mnemonic != NULL)
584 {
585 const char *mnemonic = crx_instruction[i].mnemonic;
586
587 hashret = hash_insert (crx_inst_hash, mnemonic,
588 (PTR) &crx_instruction[i]);
589
590 if (hashret != NULL && *hashret != '\0')
591 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
592 *hashret == 0 ? _("(unknown reason)") : hashret);
593
594 /* Insert unique names into hash table. The CRX instruction set
595 has many identical opcode names that have different opcodes based
596 on the operands. This hash table then provides a quick index to
597 the first opcode with a particular name in the opcode table. */
598 do
599 {
600 ++i;
601 }
602 while (crx_instruction[i].mnemonic != NULL
603 && streq (crx_instruction[i].mnemonic, mnemonic));
604 }
605
606 /* Initialize reg_hash hash table. */
607 if ((reg_hash = hash_new ()) == NULL)
608 as_fatal (_("Virtual memory exhausted"));
609
610 {
611 const reg_entry *regtab;
612
613 for (regtab = crx_regtab;
614 regtab < (crx_regtab + NUMREGS); regtab++)
615 {
616 hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
617 if (hashret)
618 as_fatal (_("Internal Error: Can't hash %s: %s"),
619 regtab->name,
620 hashret);
621 }
622 }
623
624 /* Initialize copreg_hash hash table. */
625 if ((copreg_hash = hash_new ()) == NULL)
626 as_fatal (_("Virtual memory exhausted"));
627
628 {
629 const reg_entry *copregtab;
630
631 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
632 copregtab++)
633 {
634 hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
635 if (hashret)
636 as_fatal (_("Internal Error: Can't hash %s: %s"),
637 copregtab->name,
638 hashret);
639 }
640 }
641 /* Set linkrelax here to avoid fixups in most sections. */
642 linkrelax = 1;
643 }
644
645 /* Process constants (immediate/absolute)
646 and labels (jump targets/Memory locations). */
647
648 static void
process_label_constant(char * str,ins * crx_ins)649 process_label_constant (char *str, ins * crx_ins)
650 {
651 char *saved_input_line_pointer;
652 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
653
654 saved_input_line_pointer = input_line_pointer;
655 input_line_pointer = str;
656
657 expression (&crx_ins->exp);
658
659 switch (crx_ins->exp.X_op)
660 {
661 case O_big:
662 case O_absent:
663 /* Missing or bad expr becomes absolute 0. */
664 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
665 str);
666 crx_ins->exp.X_op = O_constant;
667 crx_ins->exp.X_add_number = 0;
668 crx_ins->exp.X_add_symbol = (symbolS *) 0;
669 crx_ins->exp.X_op_symbol = (symbolS *) 0;
670 /* Fall through. */
671
672 case O_constant:
673 cur_arg->X_op = O_constant;
674 cur_arg->constant = crx_ins->exp.X_add_number;
675 break;
676
677 case O_symbol:
678 case O_subtract:
679 case O_add:
680 cur_arg->X_op = O_symbol;
681 crx_ins->rtype = BFD_RELOC_NONE;
682 relocatable = 1;
683
684 switch (cur_arg->type)
685 {
686 case arg_cr:
687 if (IS_INSN_TYPE (LD_STOR_INS_INC))
688 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
689 else if (IS_INSN_TYPE (CSTBIT_INS)
690 || IS_INSN_TYPE (STOR_IMM_INS))
691 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
692 else
693 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
694 break;
695
696 case arg_idxr:
697 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
698 break;
699
700 case arg_c:
701 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
702 crx_ins->rtype = BFD_RELOC_CRX_REL16;
703 else if (IS_INSN_TYPE (BRANCH_INS))
704 crx_ins->rtype = BFD_RELOC_CRX_REL8;
705 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
706 || IS_INSN_TYPE (CSTBIT_INS))
707 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
708 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
709 crx_ins->rtype = BFD_RELOC_CRX_REL4;
710 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
711 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
712 break;
713
714 case arg_ic:
715 if (IS_INSN_TYPE (ARITH_INS))
716 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
717 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
718 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
719 break;
720 default:
721 break;
722 }
723 break;
724
725 default:
726 cur_arg->X_op = crx_ins->exp.X_op;
727 break;
728 }
729
730 input_line_pointer = saved_input_line_pointer;
731 return;
732 }
733
734 /* Get the values of the scale to be encoded -
735 used for the scaled index mode of addressing. */
736
737 static int
exponent2scale(int val)738 exponent2scale (int val)
739 {
740 int exponent;
741
742 /* If 'val' is 0, the following 'for' will be an endless loop. */
743 if (val == 0)
744 return 0;
745
746 for (exponent = 0; (val != 1); val >>= 1, exponent++)
747 ;
748
749 return exponent;
750 }
751
752 /* Parsing different types of operands
753 -> constants Immediate/Absolute/Relative numbers
754 -> Labels Relocatable symbols
755 -> (rbase) Register base
756 -> disp(rbase) Register relative
757 -> disp(rbase)+ Post-increment mode
758 -> disp(rbase,ridx,scl) Register index mode */
759
760 static void
set_operand(char * operand,ins * crx_ins)761 set_operand (char *operand, ins * crx_ins)
762 {
763 char *operandS; /* Pointer to start of sub-opearand. */
764 char *operandE; /* Pointer to end of sub-opearand. */
765 expressionS scale;
766 int scale_val;
767 char *input_save, c;
768 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
769
770 /* Initialize pointers. */
771 operandS = operandE = operand;
772
773 switch (cur_arg->type)
774 {
775 case arg_sc: /* Case *+0x18. */
776 case arg_ic: /* Case $0x18. */
777 operandS++;
778 case arg_c: /* Case 0x18. */
779 /* Set constant. */
780 process_label_constant (operandS, crx_ins);
781
782 if (cur_arg->type != arg_ic)
783 cur_arg->type = arg_c;
784 break;
785
786 case arg_icr: /* Case $0x18(r1). */
787 operandS++;
788 case arg_cr: /* Case 0x18(r1). */
789 /* Set displacement constant. */
790 while (*operandE != '(')
791 operandE++;
792 *operandE = '\0';
793 process_label_constant (operandS, crx_ins);
794 operandS = operandE;
795 case arg_rbase: /* Case (r1). */
796 operandS++;
797 /* Set register base. */
798 while (*operandE != ')')
799 operandE++;
800 *operandE = '\0';
801 if ((cur_arg->r = get_register (operandS)) == nullregister)
802 as_bad (_("Illegal register `%s' in Instruction `%s'"),
803 operandS, ins_parse);
804
805 if (cur_arg->type != arg_rbase)
806 cur_arg->type = arg_cr;
807 break;
808
809 case arg_idxr:
810 /* Set displacement constant. */
811 while (*operandE != '(')
812 operandE++;
813 *operandE = '\0';
814 process_label_constant (operandS, crx_ins);
815 operandS = ++operandE;
816
817 /* Set register base. */
818 while ((*operandE != ',') && (! ISSPACE (*operandE)))
819 operandE++;
820 *operandE++ = '\0';
821 if ((cur_arg->r = get_register (operandS)) == nullregister)
822 as_bad (_("Illegal register `%s' in Instruction `%s'"),
823 operandS, ins_parse);
824
825 /* Skip leading white space. */
826 while (ISSPACE (*operandE))
827 operandE++;
828 operandS = operandE;
829
830 /* Set register index. */
831 while ((*operandE != ')') && (*operandE != ','))
832 operandE++;
833 c = *operandE;
834 *operandE++ = '\0';
835
836 if ((cur_arg->i_r = get_register (operandS)) == nullregister)
837 as_bad (_("Illegal register `%s' in Instruction `%s'"),
838 operandS, ins_parse);
839
840 /* Skip leading white space. */
841 while (ISSPACE (*operandE))
842 operandE++;
843 operandS = operandE;
844
845 /* Set the scale. */
846 if (c == ')')
847 cur_arg->scale = 0;
848 else
849 {
850 while (*operandE != ')')
851 operandE++;
852 *operandE = '\0';
853
854 /* Preprocess the scale string. */
855 input_save = input_line_pointer;
856 input_line_pointer = operandS;
857 expression (&scale);
858 input_line_pointer = input_save;
859
860 scale_val = scale.X_add_number;
861
862 /* Check if the scale value is legal. */
863 if (scale_val != 1 && scale_val != 2
864 && scale_val != 4 && scale_val != 8)
865 as_bad (_("Illegal Scale - `%d'"), scale_val);
866
867 cur_arg->scale = exponent2scale (scale_val);
868 }
869 break;
870
871 default:
872 break;
873 }
874 }
875
876 /* Parse a single operand.
877 operand - Current operand to parse.
878 crx_ins - Current assembled instruction. */
879
880 static void
parse_operand(char * operand,ins * crx_ins)881 parse_operand (char *operand, ins * crx_ins)
882 {
883 int ret_val;
884 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
885
886 /* Initialize the type to NULL before parsing. */
887 cur_arg->type = nullargs;
888
889 /* Check whether this is a general processor register. */
890 if ((ret_val = get_register (operand)) != nullregister)
891 {
892 cur_arg->type = arg_r;
893 cur_arg->r = ret_val;
894 cur_arg->X_op = O_register;
895 return;
896 }
897
898 /* Check whether this is a core [special] coprocessor register. */
899 if ((ret_val = get_copregister (operand)) != nullcopregister)
900 {
901 cur_arg->type = arg_copr;
902 if (ret_val >= cs0)
903 cur_arg->type = arg_copsr;
904 cur_arg->cr = ret_val;
905 cur_arg->X_op = O_register;
906 return;
907 }
908
909 /* Deal with special characters. */
910 switch (operand[0])
911 {
912 case '$':
913 if (strchr (operand, '(') != NULL)
914 cur_arg->type = arg_icr;
915 else
916 cur_arg->type = arg_ic;
917 goto set_params;
918 break;
919
920 case '*':
921 cur_arg->type = arg_sc;
922 goto set_params;
923 break;
924
925 case '(':
926 cur_arg->type = arg_rbase;
927 goto set_params;
928 break;
929
930 default:
931 break;
932 }
933
934 if (strchr (operand, '(') != NULL)
935 {
936 if (strchr (operand, ',') != NULL
937 && (strchr (operand, ',') > strchr (operand, '(')))
938 cur_arg->type = arg_idxr;
939 else
940 cur_arg->type = arg_cr;
941 }
942 else
943 cur_arg->type = arg_c;
944 goto set_params;
945
946 /* Parse an operand according to its type. */
947 set_params:
948 cur_arg->constant = 0;
949 set_operand (operand, crx_ins);
950 }
951
952 /* Parse the various operands. Each operand is then analyzed to fillup
953 the fields in the crx_ins data structure. */
954
955 static void
parse_operands(ins * crx_ins,char * operands)956 parse_operands (ins * crx_ins, char *operands)
957 {
958 char *operandS; /* Operands string. */
959 char *operandH, *operandT; /* Single operand head/tail pointers. */
960 int allocated = 0; /* Indicates a new operands string was allocated. */
961 char *operand[MAX_OPERANDS]; /* Separating the operands. */
962 int op_num = 0; /* Current operand number we are parsing. */
963 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
964 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
965
966 /* Preprocess the list of registers, if necessary. */
967 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
968 preprocess_reglist (operands, &allocated) : operands;
969
970 while (*operandT != '\0')
971 {
972 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
973 {
974 *operandT++ = '\0';
975 operand[op_num++] = strdup (operandH);
976 operandH = operandT;
977 continue;
978 }
979
980 if (*operandT == ' ')
981 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
982
983 if (*operandT == '(')
984 bracket_flag = 1;
985 else if (*operandT == '[')
986 sq_bracket_flag = 1;
987
988 if (*operandT == ')')
989 {
990 if (bracket_flag)
991 bracket_flag = 0;
992 else
993 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
994 }
995 else if (*operandT == ']')
996 {
997 if (sq_bracket_flag)
998 sq_bracket_flag = 0;
999 else
1000 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1001 }
1002
1003 if (bracket_flag == 1 && *operandT == ')')
1004 bracket_flag = 0;
1005 else if (sq_bracket_flag == 1 && *operandT == ']')
1006 sq_bracket_flag = 0;
1007
1008 operandT++;
1009 }
1010
1011 /* Adding the last operand. */
1012 operand[op_num++] = strdup (operandH);
1013 crx_ins->nargs = op_num;
1014
1015 /* Verifying correct syntax of operands (all brackets should be closed). */
1016 if (bracket_flag || sq_bracket_flag)
1017 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1018
1019 /* Now we parse each operand separately. */
1020 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1021 {
1022 cur_arg_num = op_num;
1023 parse_operand (operand[op_num], crx_ins);
1024 free (operand[op_num]);
1025 }
1026
1027 if (allocated)
1028 free (operandS);
1029 }
1030
1031 /* Get the trap index in dispatch table, given its name.
1032 This routine is used by assembling the 'excp' instruction. */
1033
1034 static int
gettrap(char * s)1035 gettrap (char *s)
1036 {
1037 const trap_entry *trap;
1038
1039 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1040 if (strcasecmp (trap->name, s) == 0)
1041 return trap->entry;
1042
1043 as_bad (_("Unknown exception: `%s'"), s);
1044 return 0;
1045 }
1046
1047 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1048 sub-group within load/stor instruction groups.
1049 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1050 advance the instruction pointer to the start of that sub-group (that is, up
1051 to the first instruction of that type).
1052 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1053
1054 static void
handle_LoadStor(char * operands)1055 handle_LoadStor (char *operands)
1056 {
1057 /* Post-Increment instructions precede Store-Immediate instructions in
1058 CRX instruction table, hence they are handled before.
1059 This synchronization should be kept. */
1060
1061 /* Assuming Post-Increment insn has the following format :
1062 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1063 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1064 if (strstr (operands, ")+") != NULL)
1065 {
1066 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1067 instruction++;
1068 return;
1069 }
1070
1071 /* Assuming Store-Immediate insn has the following format :
1072 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1073 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1074 if (strstr (operands, "$") != NULL)
1075 while (! IS_INSN_TYPE (STOR_IMM_INS))
1076 instruction++;
1077 }
1078
1079 /* Top level module where instruction parsing starts.
1080 crx_ins - data structure holds some information.
1081 operands - holds the operands part of the whole instruction. */
1082
1083 static void
parse_insn(ins * insn,char * operands)1084 parse_insn (ins *insn, char *operands)
1085 {
1086 int i;
1087
1088 /* Handle instructions with no operands. */
1089 for (i = 0; no_op_insn[i] != NULL; i++)
1090 {
1091 if (streq (no_op_insn[i], instruction->mnemonic))
1092 {
1093 insn->nargs = 0;
1094 return;
1095 }
1096 }
1097
1098 /* Handle 'excp'/'cinv' instructions. */
1099 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1100 {
1101 insn->nargs = 1;
1102 insn->arg[0].type = arg_ic;
1103 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1104 gettrap (operands) : get_cinv_parameters (operands);
1105 insn->arg[0].X_op = O_constant;
1106 return;
1107 }
1108
1109 /* Handle load/stor unique instructions before parsing. */
1110 if (IS_INSN_TYPE (LD_STOR_INS))
1111 handle_LoadStor (operands);
1112
1113 if (operands != NULL)
1114 parse_operands (insn, operands);
1115 }
1116
1117 /* Cinv instruction requires special handling. */
1118
1119 static int
get_cinv_parameters(char * operand)1120 get_cinv_parameters (char * operand)
1121 {
1122 char *p = operand;
1123 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1124
1125 while (*++p != ']')
1126 {
1127 if (*p == ',' || *p == ' ')
1128 continue;
1129
1130 if (*p == 'd')
1131 d_used = 1;
1132 else if (*p == 'i')
1133 i_used = 1;
1134 else if (*p == 'u')
1135 u_used = 1;
1136 else if (*p == 'b')
1137 b_used = 1;
1138 else
1139 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1140 }
1141
1142 return ((b_used ? 8 : 0)
1143 + (d_used ? 4 : 0)
1144 + (i_used ? 2 : 0)
1145 + (u_used ? 1 : 0));
1146 }
1147
1148 /* Retrieve the opcode image of a given register.
1149 If the register is illegal for the current instruction,
1150 issue an error. */
1151
1152 static int
getreg_image(reg r)1153 getreg_image (reg r)
1154 {
1155 const reg_entry *reg;
1156 char *reg_name;
1157 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1158
1159 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1160 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1161 is_procreg = 1;
1162
1163 /* Check whether the register is in registers table. */
1164 if (r < MAX_REG)
1165 reg = &crx_regtab[r];
1166 /* Check whether the register is in coprocessor registers table. */
1167 else if (r < MAX_COPREG)
1168 reg = &crx_copregtab[r-MAX_REG];
1169 /* Register not found. */
1170 else
1171 {
1172 as_bad (_("Unknown register: `%d'"), r);
1173 return 0;
1174 }
1175
1176 reg_name = reg->name;
1177
1178 /* Issue a error message when register is illegal. */
1179 #define IMAGE_ERR \
1180 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1181 reg_name, ins_parse); \
1182 break;
1183
1184 switch (reg->type)
1185 {
1186 case CRX_U_REGTYPE:
1187 if (is_procreg || (instruction->flags & USER_REG))
1188 return reg->image;
1189 else
1190 IMAGE_ERR;
1191
1192 case CRX_CFG_REGTYPE:
1193 if (is_procreg)
1194 return reg->image;
1195 else
1196 IMAGE_ERR;
1197
1198 case CRX_R_REGTYPE:
1199 if (! is_procreg)
1200 return reg->image;
1201 else
1202 IMAGE_ERR;
1203
1204 case CRX_C_REGTYPE:
1205 case CRX_CS_REGTYPE:
1206 return reg->image;
1207 break;
1208
1209 default:
1210 IMAGE_ERR;
1211 }
1212
1213 return 0;
1214 }
1215
1216 /* Routine used to represent integer X using NBITS bits. */
1217
1218 static long
getconstant(long x,int nbits)1219 getconstant (long x, int nbits)
1220 {
1221 /* The following expression avoids overflow if
1222 'nbits' is the number of bits in 'bfd_vma'. */
1223 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1224 }
1225
1226 /* Print a constant value to 'output_opcode':
1227 ARG holds the operand's type and value.
1228 SHIFT represents the location of the operand to be print into.
1229 NBITS determines the size (in bits) of the constant. */
1230
1231 static void
print_constant(int nbits,int shift,argument * arg)1232 print_constant (int nbits, int shift, argument *arg)
1233 {
1234 unsigned long mask = 0;
1235
1236 long constant = getconstant (arg->constant, nbits);
1237
1238 switch (nbits)
1239 {
1240 case 32:
1241 case 28:
1242 case 24:
1243 case 22:
1244 /* mask the upper part of the constant, that is, the bits
1245 going to the lowest byte of output_opcode[0].
1246 The upper part of output_opcode[1] is always filled,
1247 therefore it is always masked with 0xFFFF. */
1248 mask = (1 << (nbits - 16)) - 1;
1249 /* Divide the constant between two consecutive words :
1250 0 1 2 3
1251 +---------+---------+---------+---------+
1252 | | X X X X | X X X X | |
1253 +---------+---------+---------+---------+
1254 output_opcode[0] output_opcode[1] */
1255
1256 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1257 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1258 break;
1259
1260 case 16:
1261 case 12:
1262 /* Special case - in arg_cr, the SHIFT represents the location
1263 of the REGISTER, not the constant, which is itself not shifted. */
1264 if (arg->type == arg_cr)
1265 {
1266 CRX_PRINT (0, constant, 0);
1267 break;
1268 }
1269
1270 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1271 always filling the upper part of output_opcode[1]. If we mistakenly
1272 write it to output_opcode[0], the constant prefix (that is, 'match')
1273 will be overriden.
1274 0 1 2 3
1275 +---------+---------+---------+---------+
1276 | 'match' | | X X X X | |
1277 +---------+---------+---------+---------+
1278 output_opcode[0] output_opcode[1] */
1279
1280 if ((instruction->size > 2) && (shift == WORD_SHIFT))
1281 CRX_PRINT (1, constant, WORD_SHIFT);
1282 else
1283 CRX_PRINT (0, constant, shift);
1284 break;
1285
1286 default:
1287 CRX_PRINT (0, constant, shift);
1288 break;
1289 }
1290 }
1291
1292 /* Print an operand to 'output_opcode', which later on will be
1293 printed to the object file:
1294 ARG holds the operand's type, size and value.
1295 SHIFT represents the printing location of operand.
1296 NBITS determines the size (in bits) of a constant operand. */
1297
1298 static void
print_operand(int nbits,int shift,argument * arg)1299 print_operand (int nbits, int shift, argument *arg)
1300 {
1301 switch (arg->type)
1302 {
1303 case arg_r:
1304 CRX_PRINT (0, getreg_image (arg->r), shift);
1305 break;
1306
1307 case arg_copr:
1308 if (arg->cr < c0 || arg->cr > c15)
1309 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1310 ins_parse);
1311 CRX_PRINT (0, getreg_image (arg->cr), shift);
1312 break;
1313
1314 case arg_copsr:
1315 if (arg->cr < cs0 || arg->cr > cs15)
1316 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1317 ins_parse);
1318 CRX_PRINT (0, getreg_image (arg->cr), shift);
1319 break;
1320
1321 case arg_idxr:
1322 /* 16 12 8 6 0
1323 +--------------------------------+
1324 | r_base | r_idx | scl| disp |
1325 +--------------------------------+ */
1326 CRX_PRINT (0, getreg_image (arg->r), 12);
1327 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1328 CRX_PRINT (0, arg->scale, 6);
1329 case arg_ic:
1330 case arg_c:
1331 print_constant (nbits, shift, arg);
1332 break;
1333
1334 case arg_rbase:
1335 CRX_PRINT (0, getreg_image (arg->r), shift);
1336 break;
1337
1338 case arg_cr:
1339 /* case base_cst4. */
1340 if (instruction->flags & DISPU4MAP)
1341 print_constant (nbits, shift + REG_SIZE, arg);
1342 else
1343 /* rbase_disps<NN> and other such cases. */
1344 print_constant (nbits, shift, arg);
1345 /* Add the register argument to the output_opcode. */
1346 CRX_PRINT (0, getreg_image (arg->r), shift);
1347 break;
1348
1349 default:
1350 break;
1351 }
1352 }
1353
1354 /* Retrieve the number of operands for the current assembled instruction. */
1355
1356 static int
get_number_of_operands(void)1357 get_number_of_operands (void)
1358 {
1359 int i;
1360
1361 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1362 ;
1363 return i;
1364 }
1365
1366 /* Verify that the number NUM can be represented in BITS bits (that is,
1367 within its permitted range), based on the instruction's FLAGS.
1368 If UPDATE is nonzero, update the value of NUM if necessary.
1369 Return OP_LEGAL upon success, actual error type upon failure. */
1370
1371 static op_err
check_range(long * num,int bits,int unsigned flags,int update)1372 check_range (long *num, int bits, int unsigned flags, int update)
1373 {
1374 long min, max;
1375 int retval = OP_LEGAL;
1376 int bin;
1377 long upper_64kb = 0xFFFF0000;
1378 long value = *num;
1379
1380 /* Verify operand value is even. */
1381 if (flags & OP_EVEN)
1382 {
1383 if (value % 2)
1384 return OP_NOT_EVEN;
1385 }
1386
1387 if (flags & OP_UPPER_64KB)
1388 {
1389 /* Check if value is to be mapped to upper 64 KB memory area. */
1390 if ((value & upper_64kb) == upper_64kb)
1391 {
1392 value -= upper_64kb;
1393 if (update)
1394 *num = value;
1395 }
1396 else
1397 return OP_NOT_UPPER_64KB;
1398 }
1399
1400 if (flags & OP_SHIFT)
1401 {
1402 value >>= 1;
1403 if (update)
1404 *num = value;
1405 }
1406 else if (flags & OP_SHIFT_DEC)
1407 {
1408 value = (value >> 1) - 1;
1409 if (update)
1410 *num = value;
1411 }
1412
1413 if (flags & OP_ESC)
1414 {
1415 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1416 if (value == 0x7e || value == 0x7f)
1417 return OP_OUT_OF_RANGE;
1418 }
1419
1420 if (flags & OP_DISPU4)
1421 {
1422 int is_dispu4 = 0;
1423
1424 int mul = (instruction->flags & DISPUB4) ? 1
1425 : (instruction->flags & DISPUW4) ? 2
1426 : (instruction->flags & DISPUD4) ? 4 : 0;
1427
1428 for (bin = 0; bin < cst4_maps; bin++)
1429 {
1430 if (value == (mul * bin))
1431 {
1432 is_dispu4 = 1;
1433 if (update)
1434 *num = bin;
1435 break;
1436 }
1437 }
1438 if (!is_dispu4)
1439 retval = OP_ILLEGAL_DISPU4;
1440 }
1441 else if (flags & OP_CST4)
1442 {
1443 int is_cst4 = 0;
1444
1445 for (bin = 0; bin < cst4_maps; bin++)
1446 {
1447 if (value == cst4_map[bin])
1448 {
1449 is_cst4 = 1;
1450 if (update)
1451 *num = bin;
1452 break;
1453 }
1454 }
1455 if (!is_cst4)
1456 retval = OP_ILLEGAL_CST4;
1457 }
1458 else if (flags & OP_SIGNED)
1459 {
1460 max = (1 << (bits - 1)) - 1;
1461 min = - (1 << (bits - 1));
1462 if ((value > max) || (value < min))
1463 retval = OP_OUT_OF_RANGE;
1464 }
1465 else if (flags & OP_UNSIGNED)
1466 {
1467 max = ((((1 << (bits - 1)) - 1) << 1) | 1);
1468 min = 0;
1469 if (((unsigned long) value > (unsigned long) max)
1470 || ((unsigned long) value < (unsigned long) min))
1471 retval = OP_OUT_OF_RANGE;
1472 }
1473 return retval;
1474 }
1475
1476 /* Assemble a single instruction:
1477 INSN is already parsed (that is, all operand values and types are set).
1478 For instruction to be assembled, we need to find an appropriate template in
1479 the instruction table, meeting the following conditions:
1480 1: Has the same number of operands.
1481 2: Has the same operand types.
1482 3: Each operand size is sufficient to represent the instruction's values.
1483 Returns 1 upon success, 0 upon failure. */
1484
1485 static int
assemble_insn(char * mnemonic,ins * insn)1486 assemble_insn (char *mnemonic, ins *insn)
1487 {
1488 /* Type of each operand in the current template. */
1489 argtype cur_type[MAX_OPERANDS];
1490 /* Size (in bits) of each operand in the current template. */
1491 unsigned int cur_size[MAX_OPERANDS];
1492 /* Flags of each operand in the current template. */
1493 unsigned int cur_flags[MAX_OPERANDS];
1494 /* Instruction type to match. */
1495 unsigned int ins_type;
1496 /* Boolean flag to mark whether a match was found. */
1497 int match = 0;
1498 int i;
1499 /* Nonzero if an instruction with same number of operands was found. */
1500 int found_same_number_of_operands = 0;
1501 /* Nonzero if an instruction with same argument types was found. */
1502 int found_same_argument_types = 0;
1503 /* Nonzero if a constant was found within the required range. */
1504 int found_const_within_range = 0;
1505 /* Argument number of an operand with invalid type. */
1506 int invalid_optype = -1;
1507 /* Argument number of an operand with invalid constant value. */
1508 int invalid_const = -1;
1509 /* Operand error (used for issuing various constant error messages). */
1510 op_err op_error, const_err = OP_LEGAL;
1511
1512 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1513 #define GET_CURRENT_DATA(FUNC, ARRAY) \
1514 for (i = 0; i < insn->nargs; i++) \
1515 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1516
1517 #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1518 #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1519 #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1520
1521 /* Instruction has no operands -> only copy the constant opcode. */
1522 if (insn->nargs == 0)
1523 {
1524 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1525 return 1;
1526 }
1527
1528 /* In some case, same mnemonic can appear with different instruction types.
1529 For example, 'storb' is supported with 3 different types :
1530 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1531 We assume that when reaching this point, the instruction type was
1532 pre-determined. We need to make sure that the type stays the same
1533 during a search for matching instruction. */
1534 ins_type = CRX_INS_TYPE(instruction->flags);
1535
1536 while (/* Check that match is still not found. */
1537 match != 1
1538 /* Check we didn't get to end of table. */
1539 && instruction->mnemonic != NULL
1540 /* Check that the actual mnemonic is still available. */
1541 && IS_INSN_MNEMONIC (mnemonic)
1542 /* Check that the instruction type wasn't changed. */
1543 && IS_INSN_TYPE(ins_type))
1544 {
1545 /* Check whether number of arguments is legal. */
1546 if (get_number_of_operands () != insn->nargs)
1547 goto next_insn;
1548 found_same_number_of_operands = 1;
1549
1550 /* Initialize arrays with data of each operand in current template. */
1551 GET_CURRENT_TYPE;
1552 GET_CURRENT_SIZE;
1553 GET_CURRENT_FLAGS;
1554
1555 /* Check for type compatibility. */
1556 for (i = 0; i < insn->nargs; i++)
1557 {
1558 if (cur_type[i] != insn->arg[i].type)
1559 {
1560 if (invalid_optype == -1)
1561 invalid_optype = i + 1;
1562 goto next_insn;
1563 }
1564 }
1565 found_same_argument_types = 1;
1566
1567 for (i = 0; i < insn->nargs; i++)
1568 {
1569 /* Reverse the operand indices for certain opcodes:
1570 Index 0 -->> 1
1571 Index 1 -->> 0
1572 Other index -->> stays the same. */
1573 int j = instruction->flags & REVERSE_MATCH ?
1574 i == 0 ? 1 :
1575 i == 1 ? 0 : i :
1576 i;
1577
1578 /* Only check range - don't update the constant's value, since the
1579 current instruction may not be the last we try to match.
1580 The constant's value will be updated later, right before printing
1581 it to the object file. */
1582 if ((insn->arg[j].X_op == O_constant)
1583 && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1584 cur_flags[j], 0)))
1585 {
1586 if (invalid_const == -1)
1587 {
1588 invalid_const = j + 1;
1589 const_err = op_error;
1590 }
1591 goto next_insn;
1592 }
1593 /* For symbols, we make sure the relocation size (which was already
1594 determined) is sufficient. */
1595 else if ((insn->arg[j].X_op == O_symbol)
1596 && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1597 > cur_size[j]))
1598 goto next_insn;
1599 }
1600 found_const_within_range = 1;
1601
1602 /* If we got till here -> Full match is found. */
1603 match = 1;
1604 break;
1605
1606 /* Try again with next instruction. */
1607 next_insn:
1608 instruction++;
1609 }
1610
1611 if (!match)
1612 {
1613 /* We haven't found a match - instruction can't be assembled. */
1614 if (!found_same_number_of_operands)
1615 as_bad (_("Incorrect number of operands"));
1616 else if (!found_same_argument_types)
1617 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1618 else if (!found_const_within_range)
1619 {
1620 switch (const_err)
1621 {
1622 case OP_OUT_OF_RANGE:
1623 as_bad (_("Operand out of range (arg %d)"), invalid_const);
1624 break;
1625 case OP_NOT_EVEN:
1626 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1627 break;
1628 case OP_ILLEGAL_DISPU4:
1629 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1630 break;
1631 case OP_ILLEGAL_CST4:
1632 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1633 break;
1634 case OP_NOT_UPPER_64KB:
1635 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1636 invalid_const);
1637 break;
1638 default:
1639 as_bad (_("Illegal operand (arg %d)"), invalid_const);
1640 break;
1641 }
1642 }
1643
1644 return 0;
1645 }
1646 else
1647 /* Full match - print the encoding to output file. */
1648 {
1649 /* Make further checkings (such that couldn't be made earlier).
1650 Warn the user if necessary. */
1651 warn_if_needed (insn);
1652
1653 /* Check whether we need to adjust the instruction pointer. */
1654 if (adjust_if_needed (insn))
1655 /* If instruction pointer was adjusted, we need to update
1656 the size of the current template operands. */
1657 GET_CURRENT_SIZE;
1658
1659 for (i = 0; i < insn->nargs; i++)
1660 {
1661 int j = instruction->flags & REVERSE_MATCH ?
1662 i == 0 ? 1 :
1663 i == 1 ? 0 : i :
1664 i;
1665
1666 /* This time, update constant value before printing it. */
1667 if ((insn->arg[j].X_op == O_constant)
1668 && (check_range (&insn->arg[j].constant, cur_size[j],
1669 cur_flags[j], 1) != OP_LEGAL))
1670 as_fatal (_("Illegal operand (arg %d)"), j+1);
1671 }
1672
1673 /* First, copy the instruction's opcode. */
1674 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1675
1676 for (i = 0; i < insn->nargs; i++)
1677 {
1678 cur_arg_num = i;
1679 print_operand (cur_size[i], instruction->operands[i].shift,
1680 &insn->arg[i]);
1681 }
1682 }
1683
1684 return 1;
1685 }
1686
1687 /* Bunch of error checkings.
1688 The checks are made after a matching instruction was found. */
1689
1690 void
warn_if_needed(ins * insn)1691 warn_if_needed (ins *insn)
1692 {
1693 /* If the post-increment address mode is used and the load/store
1694 source register is the same as rbase, the result of the
1695 instruction is undefined. */
1696 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1697 {
1698 /* Enough to verify that one of the arguments is a simple reg. */
1699 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1700 if (insn->arg[0].r == insn->arg[1].r)
1701 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1702 insn->arg[0].r);
1703 }
1704
1705 /* Some instruction assume the stack pointer as rptr operand.
1706 Issue an error when the register to be loaded is also SP. */
1707 if (instruction->flags & NO_SP)
1708 {
1709 if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1710 as_bad (_("`%s' has undefined result"), ins_parse);
1711 }
1712
1713 /* If the rptr register is specified as one of the registers to be loaded,
1714 the final contents of rptr are undefined. Thus, we issue an error. */
1715 if (instruction->flags & NO_RPTR)
1716 {
1717 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1718 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1719 getreg_image (insn->arg[0].r));
1720 }
1721 }
1722
1723 /* In some cases, we need to adjust the instruction pointer although a
1724 match was already found. Here, we gather all these cases.
1725 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1726
1727 int
adjust_if_needed(ins * insn)1728 adjust_if_needed (ins *insn)
1729 {
1730 int ret_value = 0;
1731
1732 /* Special check for 'addub $0, r0' instruction -
1733 The opcode '0000 0000 0000 0000' is not allowed. */
1734 if (IS_INSN_MNEMONIC ("addub"))
1735 {
1736 if ((instruction->operands[0].op_type == cst4)
1737 && instruction->operands[1].op_type == regr)
1738 {
1739 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1740 {
1741 instruction++;
1742 ret_value = 1;
1743 }
1744 }
1745 }
1746
1747 /* Optimization: Omit a zero displacement in bit operations,
1748 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1749 if (IS_INSN_TYPE (CSTBIT_INS))
1750 {
1751 if ((instruction->operands[1].op_type == rbase_disps12)
1752 && (insn->arg[1].X_op == O_constant)
1753 && (insn->arg[1].constant == 0))
1754 {
1755 instruction--;
1756 ret_value = 1;
1757 }
1758 }
1759
1760 return ret_value;
1761 }
1762
1763 /* Set the appropriate bit for register 'r' in 'mask'.
1764 This indicates that this register is loaded or stored by
1765 the instruction. */
1766
1767 static void
mask_reg(int r,unsigned short int * mask)1768 mask_reg (int r, unsigned short int *mask)
1769 {
1770 if ((reg)r > (reg)sp)
1771 {
1772 as_bad (_("Invalid Register in Register List"));
1773 return;
1774 }
1775
1776 *mask |= (1 << r);
1777 }
1778
1779 /* Preprocess register list - create a 16-bit mask with one bit for each
1780 of the 16 general purpose registers. If a bit is set, it indicates
1781 that this register is loaded or stored by the instruction. */
1782
1783 static char *
preprocess_reglist(char * param,int * allocated)1784 preprocess_reglist (char *param, int *allocated)
1785 {
1786 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
1787 char *regP; /* Pointer to 'reg_name' string. */
1788 int reg_counter = 0; /* Count number of parsed registers. */
1789 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
1790 char *new_param; /* New created operands string. */
1791 char *paramP = param; /* Pointer to original opearands string. */
1792 char maskstring[10]; /* Array to print the mask as a string. */
1793 int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
1794 reg r;
1795 copreg cr;
1796
1797 /* If 'param' is already in form of a number, no need to preprocess. */
1798 if (strchr (paramP, '{') == NULL)
1799 return param;
1800
1801 /* Verifying correct syntax of operand. */
1802 if (strchr (paramP, '}') == NULL)
1803 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1804
1805 while (*paramP++ != '{');
1806
1807 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1808 *allocated = 1;
1809 strncpy (new_param, param, paramP - param - 1);
1810
1811 while (*paramP != '}')
1812 {
1813 regP = paramP;
1814 memset (®_name, '\0', sizeof (reg_name));
1815
1816 while (ISALNUM (*paramP))
1817 paramP++;
1818
1819 strncpy (reg_name, regP, paramP - regP);
1820
1821 /* Coprocessor register c<N>. */
1822 if (IS_INSN_TYPE (COP_REG_INS))
1823 {
1824 if (((cr = get_copregister (reg_name)) == nullcopregister)
1825 || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1826 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1827 mask_reg (getreg_image (cr - c0), &mask);
1828 }
1829 /* Coprocessor Special register cs<N>. */
1830 else if (IS_INSN_TYPE (COPS_REG_INS))
1831 {
1832 if (((cr = get_copregister (reg_name)) == nullcopregister)
1833 || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1834 as_fatal (_("Illegal register `%s' in cop-special-register list"),
1835 reg_name);
1836 mask_reg (getreg_image (cr - cs0), &mask);
1837 }
1838 /* User register u<N>. */
1839 else if (instruction->flags & USER_REG)
1840 {
1841 if (streq(reg_name, "uhi"))
1842 {
1843 hi_found = 1;
1844 goto next_inst;
1845 }
1846 else if (streq(reg_name, "ulo"))
1847 {
1848 lo_found = 1;
1849 goto next_inst;
1850 }
1851 else if (((r = get_register (reg_name)) == nullregister)
1852 || (crx_regtab[r].type != CRX_U_REGTYPE))
1853 as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1854
1855 mask_reg (getreg_image (r - u0), &mask);
1856 }
1857 /* General purpose register r<N>. */
1858 else
1859 {
1860 if (streq(reg_name, "hi"))
1861 {
1862 hi_found = 1;
1863 goto next_inst;
1864 }
1865 else if (streq(reg_name, "lo"))
1866 {
1867 lo_found = 1;
1868 goto next_inst;
1869 }
1870 else if (((r = get_register (reg_name)) == nullregister)
1871 || (crx_regtab[r].type != CRX_R_REGTYPE))
1872 as_fatal (_("Illegal register `%s' in register list"), reg_name);
1873
1874 mask_reg (getreg_image (r - r0), &mask);
1875 }
1876
1877 if (++reg_counter > MAX_REGS_IN_MASK16)
1878 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1879 MAX_REGS_IN_MASK16);
1880
1881 next_inst:
1882 while (!ISALNUM (*paramP) && *paramP != '}')
1883 paramP++;
1884 }
1885
1886 if (*++paramP != '\0')
1887 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1888 *paramP);
1889
1890 switch (hi_found + lo_found)
1891 {
1892 case 0:
1893 /* At least one register should be specified. */
1894 if (mask == 0)
1895 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1896 ins_parse);
1897 break;
1898
1899 case 1:
1900 /* HI can't be specified without LO (and vise-versa). */
1901 as_bad (_("HI/LO registers should be specified together"));
1902 break;
1903
1904 case 2:
1905 /* HI/LO registers mustn't be masked with additional registers. */
1906 if (mask != 0)
1907 as_bad (_("HI/LO registers should be specified without additional registers"));
1908
1909 default:
1910 break;
1911 }
1912
1913 sprintf (maskstring, "$0x%x", mask);
1914 strcat (new_param, maskstring);
1915 return new_param;
1916 }
1917
1918 /* Print the instruction.
1919 Handle also cases where the instruction is relaxable/relocatable. */
1920
1921 void
print_insn(ins * insn)1922 print_insn (ins *insn)
1923 {
1924 unsigned int i, j, insn_size;
1925 char *this_frag;
1926 unsigned short words[4];
1927 int addr_mod;
1928
1929 /* Arrange the insn encodings in a WORD size array. */
1930 for (i = 0, j = 0; i < 2; i++)
1931 {
1932 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1933 words[j++] = output_opcode[i] & 0xFFFF;
1934 }
1935
1936 /* Handle relaxtion. */
1937 if ((instruction->flags & RELAXABLE) && relocatable)
1938 {
1939 int relax_subtype;
1940
1941 /* Write the maximal instruction size supported. */
1942 insn_size = INSN_MAX_SIZE;
1943
1944 /* bCC */
1945 if (IS_INSN_TYPE (BRANCH_INS))
1946 relax_subtype = 0;
1947 /* bal */
1948 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1949 relax_subtype = 3;
1950 /* cmpbr/bcop */
1951 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1952 relax_subtype = 5;
1953 else
1954 abort ();
1955
1956 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1957 4, relax_subtype,
1958 insn->exp.X_add_symbol,
1959 insn->exp.X_add_number,
1960 0);
1961 }
1962 else
1963 {
1964 insn_size = instruction->size;
1965 this_frag = frag_more (insn_size * 2);
1966
1967 /* Handle relocation. */
1968 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1969 {
1970 reloc_howto_type *reloc_howto;
1971 int size;
1972
1973 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1974
1975 if (!reloc_howto)
1976 abort ();
1977
1978 size = bfd_get_reloc_size (reloc_howto);
1979
1980 if (size < 1 || size > 4)
1981 abort ();
1982
1983 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1984 size, &insn->exp, reloc_howto->pc_relative,
1985 insn->rtype);
1986 }
1987 }
1988
1989 /* Verify a 2-byte code alignment. */
1990 addr_mod = frag_now_fix () & 1;
1991 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1992 as_bad (_("instruction address is not a multiple of 2"));
1993 frag_now->insn_addr = addr_mod;
1994 frag_now->has_code = 1;
1995
1996 /* Write the instruction encoding to frag. */
1997 for (i = 0; i < insn_size; i++)
1998 {
1999 md_number_to_chars (this_frag, (valueT) words[i], 2);
2000 this_frag += 2;
2001 }
2002 }
2003
2004 /* This is the guts of the machine-dependent assembler. OP points to a
2005 machine dependent instruction. This function is supposed to emit
2006 the frags/bytes it assembles to. */
2007
2008 void
md_assemble(char * op)2009 md_assemble (char *op)
2010 {
2011 ins crx_ins;
2012 char *param;
2013 char c;
2014
2015 /* Reset global variables for a new instruction. */
2016 reset_vars (op);
2017
2018 /* Strip the mnemonic. */
2019 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2020 ;
2021 c = *param;
2022 *param++ = '\0';
2023
2024 /* Find the instruction. */
2025 instruction = (const inst *) hash_find (crx_inst_hash, op);
2026 if (instruction == NULL)
2027 {
2028 as_bad (_("Unknown opcode: `%s'"), op);
2029 return;
2030 }
2031
2032 /* Tie dwarf2 debug info to the address at the start of the insn. */
2033 dwarf2_emit_insn (0);
2034
2035 /* Parse the instruction's operands. */
2036 parse_insn (&crx_ins, param);
2037
2038 /* Assemble the instruction - return upon failure. */
2039 if (assemble_insn (op, &crx_ins) == 0)
2040 return;
2041
2042 /* Print the instruction. */
2043 print_insn (&crx_ins);
2044 }
2045