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