1 /* tc-bfin.c -- Assembler for the ADI Blackfin. 2 Copyright (C) 2005-2016 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 21 #include "as.h" 22 #include "struc-symbol.h" 23 #include "bfin-defs.h" 24 #include "obstack.h" 25 #include "safe-ctype.h" 26 #ifdef OBJ_ELF 27 #include "dwarf2dbg.h" 28 #endif 29 #include "libbfd.h" 30 #include "elf/common.h" 31 #include "elf/bfin.h" 32 33 extern int yyparse (void); 34 struct yy_buffer_state; 35 typedef struct yy_buffer_state *YY_BUFFER_STATE; 36 extern YY_BUFFER_STATE yy_scan_string (const char *yy_str); 37 extern void yy_delete_buffer (YY_BUFFER_STATE b); 38 static parse_state parse (char *line); 39 40 /* Global variables. */ 41 struct bfin_insn *insn; 42 int last_insn_size; 43 44 extern struct obstack mempool; 45 FILE *errorf; 46 47 /* Flags to set in the elf header */ 48 #define DEFAULT_FLAGS 0 49 50 #ifdef OBJ_FDPIC_ELF 51 # define DEFAULT_FDPIC EF_BFIN_FDPIC 52 #else 53 # define DEFAULT_FDPIC 0 54 #endif 55 56 static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC; 57 static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0; 58 59 /* Blackfin specific function to handle FD-PIC pointer initializations. */ 60 61 static void 62 bfin_pic_ptr (int nbytes) 63 { 64 expressionS exp; 65 char *p; 66 67 if (nbytes != 4) 68 abort (); 69 70 #ifdef md_flush_pending_output 71 md_flush_pending_output (); 72 #endif 73 74 if (is_it_end_of_statement ()) 75 { 76 demand_empty_rest_of_line (); 77 return; 78 } 79 80 #ifdef md_cons_align 81 md_cons_align (nbytes); 82 #endif 83 84 do 85 { 86 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC; 87 88 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0) 89 { 90 input_line_pointer += 9; 91 expression (&exp); 92 if (*input_line_pointer == ')') 93 input_line_pointer++; 94 else 95 as_bad (_("missing ')'")); 96 } 97 else 98 error ("missing funcdesc in picptr"); 99 100 p = frag_more (4); 101 memset (p, 0, 4); 102 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0, 103 reloc_type); 104 } 105 while (*input_line_pointer++ == ','); 106 107 input_line_pointer--; /* Put terminator back into stream. */ 108 demand_empty_rest_of_line (); 109 } 110 111 static void 112 bfin_s_bss (int ignore ATTRIBUTE_UNUSED) 113 { 114 int temp; 115 116 temp = get_absolute_expression (); 117 subseg_set (bss_section, (subsegT) temp); 118 demand_empty_rest_of_line (); 119 } 120 121 const pseudo_typeS md_pseudo_table[] = { 122 {"align", s_align_bytes, 0}, 123 {"byte2", cons, 2}, 124 {"byte4", cons, 4}, 125 {"picptr", bfin_pic_ptr, 4}, 126 {"code", obj_elf_section, 0}, 127 {"db", cons, 1}, 128 {"dd", cons, 4}, 129 {"dw", cons, 2}, 130 {"p", s_ignore, 0}, 131 {"pdata", s_ignore, 0}, 132 {"var", s_ignore, 0}, 133 {"bss", bfin_s_bss, 0}, 134 {0, 0, 0} 135 }; 136 137 /* Characters that are used to denote comments and line separators. */ 138 const char comment_chars[] = "#"; 139 const char line_comment_chars[] = "#"; 140 const char line_separator_chars[] = ";"; 141 142 /* Characters that can be used to separate the mantissa from the 143 exponent in floating point numbers. */ 144 const char EXP_CHARS[] = "eE"; 145 146 /* Characters that mean this number is a floating point constant. 147 As in 0f12.456 or 0d1.2345e12. */ 148 const char FLT_CHARS[] = "fFdDxX"; 149 150 typedef enum bfin_cpu_type 151 { 152 BFIN_CPU_UNKNOWN, 153 BFIN_CPU_BF504, 154 BFIN_CPU_BF506, 155 BFIN_CPU_BF512, 156 BFIN_CPU_BF514, 157 BFIN_CPU_BF516, 158 BFIN_CPU_BF518, 159 BFIN_CPU_BF522, 160 BFIN_CPU_BF523, 161 BFIN_CPU_BF524, 162 BFIN_CPU_BF525, 163 BFIN_CPU_BF526, 164 BFIN_CPU_BF527, 165 BFIN_CPU_BF531, 166 BFIN_CPU_BF532, 167 BFIN_CPU_BF533, 168 BFIN_CPU_BF534, 169 BFIN_CPU_BF536, 170 BFIN_CPU_BF537, 171 BFIN_CPU_BF538, 172 BFIN_CPU_BF539, 173 BFIN_CPU_BF542, 174 BFIN_CPU_BF542M, 175 BFIN_CPU_BF544, 176 BFIN_CPU_BF544M, 177 BFIN_CPU_BF547, 178 BFIN_CPU_BF547M, 179 BFIN_CPU_BF548, 180 BFIN_CPU_BF548M, 181 BFIN_CPU_BF549, 182 BFIN_CPU_BF549M, 183 BFIN_CPU_BF561, 184 BFIN_CPU_BF592, 185 } bfin_cpu_t; 186 187 bfin_cpu_t bfin_cpu_type = BFIN_CPU_UNKNOWN; 188 /* -msi-revision support. There are three special values: 189 -1 -msi-revision=none. 190 0xffff -msi-revision=any. */ 191 int bfin_si_revision; 192 193 unsigned int bfin_anomaly_checks = 0; 194 195 struct bfin_cpu 196 { 197 const char *name; 198 bfin_cpu_t type; 199 int si_revision; 200 unsigned int anomaly_checks; 201 }; 202 203 struct bfin_cpu bfin_cpus[] = 204 { 205 {"bf504", BFIN_CPU_BF504, 0x0000, AC_05000074}, 206 207 {"bf506", BFIN_CPU_BF506, 0x0000, AC_05000074}, 208 209 {"bf512", BFIN_CPU_BF512, 0x0002, AC_05000074}, 210 {"bf512", BFIN_CPU_BF512, 0x0001, AC_05000074}, 211 {"bf512", BFIN_CPU_BF512, 0x0000, AC_05000074}, 212 213 {"bf514", BFIN_CPU_BF514, 0x0002, AC_05000074}, 214 {"bf514", BFIN_CPU_BF514, 0x0001, AC_05000074}, 215 {"bf514", BFIN_CPU_BF514, 0x0000, AC_05000074}, 216 217 {"bf516", BFIN_CPU_BF516, 0x0002, AC_05000074}, 218 {"bf516", BFIN_CPU_BF516, 0x0001, AC_05000074}, 219 {"bf516", BFIN_CPU_BF516, 0x0000, AC_05000074}, 220 221 {"bf518", BFIN_CPU_BF518, 0x0002, AC_05000074}, 222 {"bf518", BFIN_CPU_BF518, 0x0001, AC_05000074}, 223 {"bf518", BFIN_CPU_BF518, 0x0000, AC_05000074}, 224 225 {"bf522", BFIN_CPU_BF522, 0x0002, AC_05000074}, 226 {"bf522", BFIN_CPU_BF522, 0x0001, AC_05000074}, 227 {"bf522", BFIN_CPU_BF522, 0x0000, AC_05000074}, 228 229 {"bf523", BFIN_CPU_BF523, 0x0002, AC_05000074}, 230 {"bf523", BFIN_CPU_BF523, 0x0001, AC_05000074}, 231 {"bf523", BFIN_CPU_BF523, 0x0000, AC_05000074}, 232 233 {"bf524", BFIN_CPU_BF524, 0x0002, AC_05000074}, 234 {"bf524", BFIN_CPU_BF524, 0x0001, AC_05000074}, 235 {"bf524", BFIN_CPU_BF524, 0x0000, AC_05000074}, 236 237 {"bf525", BFIN_CPU_BF525, 0x0002, AC_05000074}, 238 {"bf525", BFIN_CPU_BF525, 0x0001, AC_05000074}, 239 {"bf525", BFIN_CPU_BF525, 0x0000, AC_05000074}, 240 241 {"bf526", BFIN_CPU_BF526, 0x0002, AC_05000074}, 242 {"bf526", BFIN_CPU_BF526, 0x0001, AC_05000074}, 243 {"bf526", BFIN_CPU_BF526, 0x0000, AC_05000074}, 244 245 {"bf527", BFIN_CPU_BF527, 0x0002, AC_05000074}, 246 {"bf527", BFIN_CPU_BF527, 0x0001, AC_05000074}, 247 {"bf527", BFIN_CPU_BF527, 0x0000, AC_05000074}, 248 249 {"bf531", BFIN_CPU_BF531, 0x0006, AC_05000074}, 250 {"bf531", BFIN_CPU_BF531, 0x0005, AC_05000074}, 251 {"bf531", BFIN_CPU_BF531, 0x0004, AC_05000074}, 252 {"bf531", BFIN_CPU_BF531, 0x0003, AC_05000074}, 253 254 {"bf532", BFIN_CPU_BF532, 0x0006, AC_05000074}, 255 {"bf532", BFIN_CPU_BF532, 0x0005, AC_05000074}, 256 {"bf532", BFIN_CPU_BF532, 0x0004, AC_05000074}, 257 {"bf532", BFIN_CPU_BF532, 0x0003, AC_05000074}, 258 259 {"bf533", BFIN_CPU_BF533, 0x0006, AC_05000074}, 260 {"bf533", BFIN_CPU_BF533, 0x0005, AC_05000074}, 261 {"bf533", BFIN_CPU_BF533, 0x0004, AC_05000074}, 262 {"bf533", BFIN_CPU_BF533, 0x0003, AC_05000074}, 263 264 {"bf534", BFIN_CPU_BF534, 0x0003, AC_05000074}, 265 {"bf534", BFIN_CPU_BF534, 0x0002, AC_05000074}, 266 {"bf534", BFIN_CPU_BF534, 0x0001, AC_05000074}, 267 268 {"bf536", BFIN_CPU_BF536, 0x0003, AC_05000074}, 269 {"bf536", BFIN_CPU_BF536, 0x0002, AC_05000074}, 270 {"bf536", BFIN_CPU_BF536, 0x0001, AC_05000074}, 271 272 {"bf537", BFIN_CPU_BF537, 0x0003, AC_05000074}, 273 {"bf537", BFIN_CPU_BF537, 0x0002, AC_05000074}, 274 {"bf537", BFIN_CPU_BF537, 0x0001, AC_05000074}, 275 276 {"bf538", BFIN_CPU_BF538, 0x0005, AC_05000074}, 277 {"bf538", BFIN_CPU_BF538, 0x0004, AC_05000074}, 278 {"bf538", BFIN_CPU_BF538, 0x0003, AC_05000074}, 279 {"bf538", BFIN_CPU_BF538, 0x0002, AC_05000074}, 280 281 {"bf539", BFIN_CPU_BF539, 0x0005, AC_05000074}, 282 {"bf539", BFIN_CPU_BF539, 0x0004, AC_05000074}, 283 {"bf539", BFIN_CPU_BF539, 0x0003, AC_05000074}, 284 {"bf539", BFIN_CPU_BF539, 0x0002, AC_05000074}, 285 286 {"bf542m", BFIN_CPU_BF542M, 0x0003, AC_05000074}, 287 288 {"bf542", BFIN_CPU_BF542, 0x0004, AC_05000074}, 289 {"bf542", BFIN_CPU_BF542, 0x0002, AC_05000074}, 290 {"bf542", BFIN_CPU_BF542, 0x0001, AC_05000074}, 291 {"bf542", BFIN_CPU_BF542, 0x0000, AC_05000074}, 292 293 {"bf544m", BFIN_CPU_BF544M, 0x0003, AC_05000074}, 294 295 {"bf544", BFIN_CPU_BF544, 0x0004, AC_05000074}, 296 {"bf544", BFIN_CPU_BF544, 0x0002, AC_05000074}, 297 {"bf544", BFIN_CPU_BF544, 0x0001, AC_05000074}, 298 {"bf544", BFIN_CPU_BF544, 0x0000, AC_05000074}, 299 300 {"bf547m", BFIN_CPU_BF547M, 0x0003, AC_05000074}, 301 302 {"bf547", BFIN_CPU_BF547, 0x0004, AC_05000074}, 303 {"bf547", BFIN_CPU_BF547, 0x0002, AC_05000074}, 304 {"bf547", BFIN_CPU_BF547, 0x0001, AC_05000074}, 305 {"bf547", BFIN_CPU_BF547, 0x0000, AC_05000074}, 306 307 {"bf548m", BFIN_CPU_BF548M, 0x0003, AC_05000074}, 308 309 {"bf548", BFIN_CPU_BF548, 0x0004, AC_05000074}, 310 {"bf548", BFIN_CPU_BF548, 0x0002, AC_05000074}, 311 {"bf548", BFIN_CPU_BF548, 0x0001, AC_05000074}, 312 {"bf548", BFIN_CPU_BF548, 0x0000, AC_05000074}, 313 314 {"bf549m", BFIN_CPU_BF549M, 0x0003, AC_05000074}, 315 316 {"bf549", BFIN_CPU_BF549, 0x0004, AC_05000074}, 317 {"bf549", BFIN_CPU_BF549, 0x0002, AC_05000074}, 318 {"bf549", BFIN_CPU_BF549, 0x0001, AC_05000074}, 319 {"bf549", BFIN_CPU_BF549, 0x0000, AC_05000074}, 320 321 {"bf561", BFIN_CPU_BF561, 0x0005, AC_05000074}, 322 {"bf561", BFIN_CPU_BF561, 0x0003, AC_05000074}, 323 {"bf561", BFIN_CPU_BF561, 0x0002, AC_05000074}, 324 325 {"bf592", BFIN_CPU_BF592, 0x0001, AC_05000074}, 326 {"bf592", BFIN_CPU_BF592, 0x0000, AC_05000074}, 327 }; 328 329 /* Define bfin-specific command-line options (there are none). */ 330 const char *md_shortopts = ""; 331 332 #define OPTION_FDPIC (OPTION_MD_BASE) 333 #define OPTION_NOPIC (OPTION_MD_BASE + 1) 334 #define OPTION_MCPU (OPTION_MD_BASE + 2) 335 336 struct option md_longopts[] = 337 { 338 { "mcpu", required_argument, NULL, OPTION_MCPU }, 339 { "mfdpic", no_argument, NULL, OPTION_FDPIC }, 340 { "mnopic", no_argument, NULL, OPTION_NOPIC }, 341 { "mno-fdpic", no_argument, NULL, OPTION_NOPIC }, 342 { NULL, no_argument, NULL, 0 }, 343 }; 344 345 size_t md_longopts_size = sizeof (md_longopts); 346 347 348 int 349 md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED) 350 { 351 switch (c) 352 { 353 default: 354 return 0; 355 356 case OPTION_MCPU: 357 { 358 const char *q; 359 unsigned int i; 360 361 for (i = 0; i < ARRAY_SIZE (bfin_cpus); i++) 362 { 363 const char *p = bfin_cpus[i].name; 364 if (strncmp (arg, p, strlen (p)) == 0) 365 break; 366 } 367 368 if (i == ARRAY_SIZE (bfin_cpus)) 369 as_fatal ("-mcpu=%s is not valid", arg); 370 371 bfin_cpu_type = bfin_cpus[i].type; 372 373 q = arg + strlen (bfin_cpus[i].name); 374 375 if (*q == '\0') 376 { 377 bfin_si_revision = bfin_cpus[i].si_revision; 378 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks; 379 } 380 else if (strcmp (q, "-none") == 0) 381 bfin_si_revision = -1; 382 else if (strcmp (q, "-any") == 0) 383 { 384 bfin_si_revision = 0xffff; 385 while (i < ARRAY_SIZE (bfin_cpus) 386 && bfin_cpus[i].type == bfin_cpu_type) 387 { 388 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks; 389 i++; 390 } 391 } 392 else 393 { 394 unsigned int si_major, si_minor; 395 int rev_len, n; 396 397 rev_len = strlen (q); 398 399 if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2 400 || n != rev_len 401 || si_major > 0xff || si_minor > 0xff) 402 { 403 invalid_silicon_revision: 404 as_fatal ("-mcpu=%s has invalid silicon revision", arg); 405 } 406 407 bfin_si_revision = (si_major << 8) | si_minor; 408 409 while (i < ARRAY_SIZE (bfin_cpus) 410 && bfin_cpus[i].type == bfin_cpu_type 411 && bfin_cpus[i].si_revision != bfin_si_revision) 412 i++; 413 414 if (i == ARRAY_SIZE (bfin_cpus) 415 || bfin_cpus[i].type != bfin_cpu_type) 416 goto invalid_silicon_revision; 417 418 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks; 419 } 420 421 break; 422 } 423 424 case OPTION_FDPIC: 425 bfin_flags |= EF_BFIN_FDPIC; 426 bfin_pic_flag = "-mfdpic"; 427 break; 428 429 case OPTION_NOPIC: 430 bfin_flags &= ~(EF_BFIN_FDPIC); 431 bfin_pic_flag = 0; 432 break; 433 } 434 435 return 1; 436 } 437 438 void 439 md_show_usage (FILE * stream) 440 { 441 fprintf (stream, _(" Blackfin specific assembler options:\n")); 442 fprintf (stream, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n")); 443 fprintf (stream, _(" -mfdpic assemble for the FDPIC ABI\n")); 444 fprintf (stream, _(" -mno-fdpic/-mnopic disable -mfdpic\n")); 445 } 446 447 /* Perform machine-specific initializations. */ 448 void 449 md_begin (void) 450 { 451 /* Set the ELF flags if desired. */ 452 if (bfin_flags) 453 bfd_set_private_flags (stdoutput, bfin_flags); 454 455 /* Set the default machine type. */ 456 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0)) 457 as_warn (_("Could not set architecture and machine.")); 458 459 /* Ensure that lines can begin with '(', for multiple 460 register stack pops. */ 461 lex_type ['('] = LEX_BEGIN_NAME; 462 463 #ifdef OBJ_ELF 464 record_alignment (text_section, 2); 465 record_alignment (data_section, 2); 466 record_alignment (bss_section, 2); 467 #endif 468 469 errorf = stderr; 470 obstack_init (&mempool); 471 472 #ifdef DEBUG 473 extern int debug_codeselection; 474 debug_codeselection = 1; 475 #endif 476 477 last_insn_size = 0; 478 } 479 480 /* Perform the main parsing, and assembly of the input here. Also, 481 call the required routines for alignment and fixups here. 482 This is called for every line that contains real assembly code. */ 483 484 void 485 md_assemble (char *line) 486 { 487 char *toP = 0; 488 int size, insn_size; 489 struct bfin_insn *tmp_insn; 490 size_t len; 491 static size_t buffer_len = 0; 492 static char *current_inputline; 493 parse_state state; 494 495 len = strlen (line); 496 if (len + 2 > buffer_len) 497 { 498 buffer_len = len + 40; 499 current_inputline = XRESIZEVEC (char, current_inputline, buffer_len); 500 } 501 memcpy (current_inputline, line, len); 502 current_inputline[len] = ';'; 503 current_inputline[len + 1] = '\0'; 504 505 state = parse (current_inputline); 506 if (state == NO_INSN_GENERATED) 507 return; 508 509 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next) 510 if (!tmp_insn->reloc || !tmp_insn->exp->symbol) 511 insn_size += 2; 512 513 if (insn_size) 514 toP = frag_more (insn_size); 515 516 last_insn_size = insn_size; 517 518 #ifdef DEBUG 519 printf ("INS:"); 520 #endif 521 while (insn) 522 { 523 if (insn->reloc && insn->exp->symbol) 524 { 525 char *prev_toP = toP - 2; 526 switch (insn->reloc) 527 { 528 case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 529 case BFD_RELOC_24_PCREL: 530 case BFD_RELOC_BFIN_16_LOW: 531 case BFD_RELOC_BFIN_16_HIGH: 532 size = 4; 533 break; 534 default: 535 size = 2; 536 } 537 538 /* Following if condition checks for the arithmetic relocations. 539 If the case then it doesn't required to generate the code. 540 It has been assumed that, their ID will be contiguous. */ 541 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc 542 && BFD_ARELOC_BFIN_COMP >= insn->reloc) 543 || insn->reloc == BFD_RELOC_BFIN_16_IMM) 544 { 545 size = 2; 546 } 547 if (insn->reloc == BFD_ARELOC_BFIN_CONST 548 || insn->reloc == BFD_ARELOC_BFIN_PUSH) 549 size = 4; 550 551 fix_new (frag_now, 552 (prev_toP - frag_now->fr_literal), 553 size, insn->exp->symbol, insn->exp->value, 554 insn->pcrel, insn->reloc); 555 } 556 else 557 { 558 md_number_to_chars (toP, insn->value, 2); 559 toP += 2; 560 } 561 562 #ifdef DEBUG 563 printf (" reloc :"); 564 printf (" %02x%02x", ((unsigned char *) &insn->value)[0], 565 ((unsigned char *) &insn->value)[1]); 566 printf ("\n"); 567 #endif 568 insn = insn->next; 569 } 570 #ifdef OBJ_ELF 571 dwarf2_emit_insn (insn_size); 572 #endif 573 574 while (*line++ != '\0') 575 if (*line == '\n') 576 bump_line_counters (); 577 } 578 579 /* Parse one line of instructions, and generate opcode for it. 580 To parse the line, YACC and LEX are used, because the instruction set 581 syntax doesn't confirm to the AT&T assembly syntax. 582 To call a YACC & LEX generated parser, we must provide the input via 583 a FILE stream, otherwise stdin is used by default. Below the input 584 to the function will be put into a temporary file, then the generated 585 parser uses the temporary file for parsing. */ 586 587 static parse_state 588 parse (char *line) 589 { 590 parse_state state; 591 YY_BUFFER_STATE buffstate; 592 593 buffstate = yy_scan_string (line); 594 595 /* our lex requires setting the start state to keyword 596 every line as the first word may be a keyword. 597 Fixes a bug where we could not have keywords as labels. */ 598 set_start_state (); 599 600 /* Call yyparse here. */ 601 state = yyparse (); 602 if (state == SEMANTIC_ERROR) 603 { 604 as_bad (_("Parse failed.")); 605 insn = 0; 606 } 607 608 yy_delete_buffer (buffstate); 609 return state; 610 } 611 612 /* We need to handle various expressions properly. 613 Such as, [SP--] = 34, concerned by md_assemble(). */ 614 615 void 616 md_operand (expressionS * expressionP) 617 { 618 if (*input_line_pointer == '[') 619 { 620 as_tsktsk ("We found a '['!"); 621 input_line_pointer++; 622 expression (expressionP); 623 } 624 } 625 626 /* Handle undefined symbols. */ 627 symbolS * 628 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 629 { 630 return (symbolS *) 0; 631 } 632 633 int 634 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, 635 segT segment ATTRIBUTE_UNUSED) 636 { 637 return 0; 638 } 639 640 /* Convert from target byte order to host byte order. */ 641 642 static int 643 md_chars_to_number (char *val, int n) 644 { 645 int retval; 646 647 for (retval = 0; n--;) 648 { 649 retval <<= 8; 650 retval |= val[n]; 651 } 652 return retval; 653 } 654 655 void 656 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED) 657 { 658 char *where = fixP->fx_frag->fr_literal + fixP->fx_where; 659 660 long value = *valueP; 661 long newval; 662 663 switch (fixP->fx_r_type) 664 { 665 case BFD_RELOC_BFIN_GOT: 666 case BFD_RELOC_BFIN_GOT17M4: 667 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 668 fixP->fx_no_overflow = 1; 669 newval = md_chars_to_number (where, 2); 670 newval |= 0x0 & 0x7f; 671 md_number_to_chars (where, newval, 2); 672 break; 673 674 case BFD_RELOC_BFIN_10_PCREL: 675 if (!value) 676 break; 677 if (value < -1024 || value > 1022) 678 as_bad_where (fixP->fx_file, fixP->fx_line, 679 _("pcrel too far BFD_RELOC_BFIN_10")); 680 681 /* 11 bit offset even numbered, so we remove right bit. */ 682 value = value >> 1; 683 newval = md_chars_to_number (where, 2); 684 newval |= value & 0x03ff; 685 md_number_to_chars (where, newval, 2); 686 break; 687 688 case BFD_RELOC_BFIN_12_PCREL_JUMP: 689 case BFD_RELOC_BFIN_12_PCREL_JUMP_S: 690 case BFD_RELOC_12_PCREL: 691 if (!value) 692 break; 693 694 if (value < -4096 || value > 4094) 695 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12")); 696 /* 13 bit offset even numbered, so we remove right bit. */ 697 value = value >> 1; 698 newval = md_chars_to_number (where, 2); 699 newval |= value & 0xfff; 700 md_number_to_chars (where, newval, 2); 701 break; 702 703 case BFD_RELOC_BFIN_16_LOW: 704 case BFD_RELOC_BFIN_16_HIGH: 705 fixP->fx_done = FALSE; 706 break; 707 708 case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 709 case BFD_RELOC_BFIN_24_PCREL_CALL_X: 710 case BFD_RELOC_24_PCREL: 711 if (!value) 712 break; 713 714 if (value < -16777216 || value > 16777214) 715 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24")); 716 717 /* 25 bit offset even numbered, so we remove right bit. */ 718 value = value >> 1; 719 value++; 720 721 md_number_to_chars (where - 2, value >> 16, 1); 722 md_number_to_chars (where, value, 1); 723 md_number_to_chars (where + 1, value >> 8, 1); 724 break; 725 726 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */ 727 if (!value) 728 break; 729 if (value < 4 || value > 30) 730 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5")); 731 value = value >> 1; 732 newval = md_chars_to_number (where, 1); 733 newval = (newval & 0xf0) | (value & 0xf); 734 md_number_to_chars (where, newval, 1); 735 break; 736 737 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */ 738 if (!value) 739 break; 740 value += 2; 741 if (value < 4 || value > 2046) 742 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL")); 743 /* 11 bit unsigned even, so we remove right bit. */ 744 value = value >> 1; 745 newval = md_chars_to_number (where, 2); 746 newval |= value & 0x03ff; 747 md_number_to_chars (where, newval, 2); 748 break; 749 750 case BFD_RELOC_8: 751 if (value < -0x80 || value >= 0x7f) 752 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8")); 753 md_number_to_chars (where, value, 1); 754 break; 755 756 case BFD_RELOC_BFIN_16_IMM: 757 case BFD_RELOC_16: 758 if (value < -0x8000 || value >= 0x7fff) 759 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16")); 760 md_number_to_chars (where, value, 2); 761 break; 762 763 case BFD_RELOC_32: 764 md_number_to_chars (where, value, 4); 765 break; 766 767 case BFD_RELOC_BFIN_PLTPC: 768 md_number_to_chars (where, value, 2); 769 break; 770 771 case BFD_RELOC_BFIN_FUNCDESC: 772 case BFD_RELOC_VTABLE_INHERIT: 773 case BFD_RELOC_VTABLE_ENTRY: 774 fixP->fx_done = FALSE; 775 break; 776 777 default: 778 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type)) 779 { 780 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type); 781 return; 782 } 783 } 784 785 if (!fixP->fx_addsy) 786 fixP->fx_done = TRUE; 787 788 } 789 790 /* Round up a section size to the appropriate boundary. */ 791 valueT 792 md_section_align (segT segment, valueT size) 793 { 794 int boundary = bfd_get_section_alignment (stdoutput, segment); 795 return ((size + (1 << boundary) - 1) & -(1 << boundary)); 796 } 797 798 799 const char * 800 md_atof (int type, char * litP, int * sizeP) 801 { 802 return ieee_md_atof (type, litP, sizeP, FALSE); 803 } 804 805 806 /* If while processing a fixup, a reloc really needs to be created 807 then it is done here. */ 808 809 arelent * 810 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) 811 { 812 arelent *reloc; 813 814 reloc = XNEW (arelent); 815 reloc->sym_ptr_ptr = XNEW (asymbol *); 816 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 817 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 818 819 reloc->addend = fixp->fx_offset; 820 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 821 822 if (reloc->howto == (reloc_howto_type *) NULL) 823 { 824 as_bad_where (fixp->fx_file, fixp->fx_line, 825 /* xgettext:c-format. */ 826 _("reloc %d not supported by object file format"), 827 (int) fixp->fx_r_type); 828 829 xfree (reloc); 830 831 return NULL; 832 } 833 834 return reloc; 835 } 836 837 /* The location from which a PC relative jump should be calculated, 838 given a PC relative reloc. */ 839 840 long 841 md_pcrel_from_section (fixS *fixP, segT sec) 842 { 843 if (fixP->fx_addsy != (symbolS *) NULL 844 && (!S_IS_DEFINED (fixP->fx_addsy) 845 || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 846 { 847 /* The symbol is undefined (or is defined but not in this section). 848 Let the linker figure it out. */ 849 return 0; 850 } 851 return fixP->fx_frag->fr_address + fixP->fx_where; 852 } 853 854 /* Return true if the fix can be handled by GAS, false if it must 855 be passed through to the linker. */ 856 857 bfd_boolean 858 bfin_fix_adjustable (fixS *fixP) 859 { 860 switch (fixP->fx_r_type) 861 { 862 /* Adjust_reloc_syms doesn't know about the GOT. */ 863 case BFD_RELOC_BFIN_GOT: 864 case BFD_RELOC_BFIN_PLTPC: 865 /* We need the symbol name for the VTABLE entries. */ 866 case BFD_RELOC_VTABLE_INHERIT: 867 case BFD_RELOC_VTABLE_ENTRY: 868 return 0; 869 870 default: 871 return 1; 872 } 873 } 874 875 /* Special extra functions that help bfin-parse.y perform its job. */ 876 877 struct obstack mempool; 878 879 INSTR_T 880 conscode (INSTR_T head, INSTR_T tail) 881 { 882 if (!head) 883 return tail; 884 head->next = tail; 885 return head; 886 } 887 888 INSTR_T 889 conctcode (INSTR_T head, INSTR_T tail) 890 { 891 INSTR_T temp = (head); 892 if (!head) 893 return tail; 894 while (temp->next) 895 temp = temp->next; 896 temp->next = tail; 897 898 return head; 899 } 900 901 INSTR_T 902 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel) 903 { 904 /* Assert that the symbol is not an operator. */ 905 gas_assert (symbol->type == Expr_Node_Reloc); 906 907 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel); 908 909 } 910 911 INSTR_T 912 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel) 913 { 914 code->reloc = reloc; 915 code->exp = mkexpr (0, symbol_find_or_make (symbol)); 916 code->pcrel = pcrel; 917 return code; 918 } 919 920 INSTR_T 921 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel) 922 { 923 code->reloc = reloc; 924 code->exp = mkexpr (value, symbol_find_or_make (symbol)); 925 code->pcrel = pcrel; 926 return code; 927 } 928 929 INSTR_T 930 gencode (unsigned long x) 931 { 932 INSTR_T cell = XOBNEW (&mempool, struct bfin_insn); 933 memset (cell, 0, sizeof (struct bfin_insn)); 934 cell->value = (x); 935 return cell; 936 } 937 938 int reloc; 939 int ninsns; 940 int count_insns; 941 942 static void * 943 allocate (size_t n) 944 { 945 return obstack_alloc (&mempool, n); 946 } 947 948 Expr_Node * 949 Expr_Node_Create (Expr_Node_Type type, 950 Expr_Node_Value value, 951 Expr_Node *Left_Child, 952 Expr_Node *Right_Child) 953 { 954 955 956 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node)); 957 node->type = type; 958 node->value = value; 959 node->Left_Child = Left_Child; 960 node->Right_Child = Right_Child; 961 return node; 962 } 963 964 static const char *con = ".__constant"; 965 static const char *op = ".__operator"; 966 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head); 967 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc); 968 969 INSTR_T 970 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc) 971 { 972 /* Top level reloction expression generator VDSP style. 973 If the relocation is just by itself, generate one item 974 else generate this convoluted expression. */ 975 976 INSTR_T note = NULL_CODE; 977 INSTR_T note1 = NULL_CODE; 978 int pcrel = 1; /* Is the parent reloc pcrelative? 979 This calculation here and HOWTO should match. */ 980 981 if (parent_reloc) 982 { 983 /* If it's 32 bit quantity then 16bit code needs to be added. */ 984 int value = 0; 985 986 if (head->type == Expr_Node_Constant) 987 { 988 /* If note1 is not null code, we have to generate a right 989 aligned value for the constant. Otherwise the reloc is 990 a part of the basic command and the yacc file 991 generates this. */ 992 value = head->value.i_value; 993 } 994 switch (parent_reloc) 995 { 996 /* Some relocations will need to allocate extra words. */ 997 case BFD_RELOC_BFIN_16_IMM: 998 case BFD_RELOC_BFIN_16_LOW: 999 case BFD_RELOC_BFIN_16_HIGH: 1000 note1 = conscode (gencode (value), NULL_CODE); 1001 pcrel = 0; 1002 break; 1003 case BFD_RELOC_BFIN_PLTPC: 1004 note1 = conscode (gencode (value), NULL_CODE); 1005 pcrel = 0; 1006 break; 1007 case BFD_RELOC_16: 1008 case BFD_RELOC_BFIN_GOT: 1009 case BFD_RELOC_BFIN_GOT17M4: 1010 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 1011 note1 = conscode (gencode (value), NULL_CODE); 1012 pcrel = 0; 1013 break; 1014 case BFD_RELOC_24_PCREL: 1015 case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 1016 case BFD_RELOC_BFIN_24_PCREL_CALL_X: 1017 /* These offsets are even numbered pcrel. */ 1018 note1 = conscode (gencode (value >> 1), NULL_CODE); 1019 break; 1020 default: 1021 note1 = NULL_CODE; 1022 } 1023 } 1024 if (head->type == Expr_Node_Constant) 1025 note = note1; 1026 else if (head->type == Expr_Node_Reloc) 1027 { 1028 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel); 1029 if (note1 != NULL_CODE) 1030 note = conscode (note1, note); 1031 } 1032 else if (head->type == Expr_Node_Binop 1033 && (head->value.op_value == Expr_Op_Type_Add 1034 || head->value.op_value == Expr_Op_Type_Sub) 1035 && head->Left_Child->type == Expr_Node_Reloc 1036 && head->Right_Child->type == Expr_Node_Constant) 1037 { 1038 int val = head->Right_Child->value.i_value; 1039 if (head->value.op_value == Expr_Op_Type_Sub) 1040 val = -val; 1041 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value, 1042 parent_reloc, val, 0), 1043 NULL_CODE); 1044 if (note1 != NULL_CODE) 1045 note = conscode (note1, note); 1046 } 1047 else 1048 { 1049 /* Call the recursive function. */ 1050 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel); 1051 if (note1 != NULL_CODE) 1052 note = conscode (note1, note); 1053 note = conctcode (Expr_Node_Gen_Reloc_R (head), note); 1054 } 1055 return note; 1056 } 1057 1058 static INSTR_T 1059 Expr_Node_Gen_Reloc_R (Expr_Node * head) 1060 { 1061 1062 INSTR_T note = 0; 1063 INSTR_T note1 = 0; 1064 1065 switch (head->type) 1066 { 1067 case Expr_Node_Constant: 1068 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE); 1069 break; 1070 case Expr_Node_Reloc: 1071 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE); 1072 break; 1073 case Expr_Node_Binop: 1074 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child)); 1075 switch (head->value.op_value) 1076 { 1077 case Expr_Op_Type_Add: 1078 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE)); 1079 break; 1080 case Expr_Op_Type_Sub: 1081 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE)); 1082 break; 1083 case Expr_Op_Type_Mult: 1084 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE)); 1085 break; 1086 case Expr_Op_Type_Div: 1087 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE)); 1088 break; 1089 case Expr_Op_Type_Mod: 1090 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE)); 1091 break; 1092 case Expr_Op_Type_Lshift: 1093 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE)); 1094 break; 1095 case Expr_Op_Type_Rshift: 1096 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE)); 1097 break; 1098 case Expr_Op_Type_BAND: 1099 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE)); 1100 break; 1101 case Expr_Op_Type_BOR: 1102 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE)); 1103 break; 1104 case Expr_Op_Type_BXOR: 1105 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE)); 1106 break; 1107 case Expr_Op_Type_LAND: 1108 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE)); 1109 break; 1110 case Expr_Op_Type_LOR: 1111 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE)); 1112 break; 1113 default: 1114 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__); 1115 1116 1117 } 1118 break; 1119 case Expr_Node_Unop: 1120 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE); 1121 switch (head->value.op_value) 1122 { 1123 case Expr_Op_Type_NEG: 1124 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE)); 1125 break; 1126 case Expr_Op_Type_COMP: 1127 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE)); 1128 break; 1129 default: 1130 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__); 1131 } 1132 break; 1133 default: 1134 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__); 1135 } 1136 return note; 1137 } 1138 1139 /* Blackfin opcode generation. */ 1141 1142 /* These functions are called by the generated parser 1143 (from bfin-parse.y), the register type classification 1144 happens in bfin-lex.l. */ 1145 1146 #include "bfin-aux.h" 1147 #include "opcode/bfin.h" 1148 1149 #define INIT(t) t c_code = init_##t 1150 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x) 1151 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f) 1152 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x) 1153 1154 #define HI(x) ((x >> 16) & 0xffff) 1155 #define LO(x) ((x ) & 0xffff) 1156 1157 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4) 1158 1159 #define GEN_OPCODE32() \ 1160 conscode (gencode (HI (c_code.opcode)), \ 1161 conscode (gencode (LO (c_code.opcode)), NULL_CODE)) 1162 1163 #define GEN_OPCODE16() \ 1164 conscode (gencode (c_code.opcode), NULL_CODE) 1165 1166 1167 /* 32 BIT INSTRUCTIONS. */ 1168 1169 1170 /* DSP32 instruction generation. */ 1171 1172 INSTR_T 1173 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P, 1174 int h01, int h11, int h00, int h10, int op0, 1175 REG_T dst, REG_T src0, REG_T src1, int w0) 1176 { 1177 INIT (DSP32Mac); 1178 1179 ASSIGN (op0); 1180 ASSIGN (op1); 1181 ASSIGN (MM); 1182 ASSIGN (mmod); 1183 ASSIGN (w0); 1184 ASSIGN (w1); 1185 ASSIGN (h01); 1186 ASSIGN (h11); 1187 ASSIGN (h00); 1188 ASSIGN (h10); 1189 ASSIGN (P); 1190 1191 /* If we have full reg assignments, mask out LSB to encode 1192 single or simultaneous even/odd register moves. */ 1193 if (P) 1194 { 1195 dst->regno &= 0x06; 1196 } 1197 1198 ASSIGN_R (dst); 1199 ASSIGN_R (src0); 1200 ASSIGN_R (src1); 1201 1202 return GEN_OPCODE32 (); 1203 } 1204 1205 INSTR_T 1206 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P, 1207 int h01, int h11, int h00, int h10, int op0, 1208 REG_T dst, REG_T src0, REG_T src1, int w0) 1209 { 1210 INIT (DSP32Mult); 1211 1212 ASSIGN (op0); 1213 ASSIGN (op1); 1214 ASSIGN (MM); 1215 ASSIGN (mmod); 1216 ASSIGN (w0); 1217 ASSIGN (w1); 1218 ASSIGN (h01); 1219 ASSIGN (h11); 1220 ASSIGN (h00); 1221 ASSIGN (h10); 1222 ASSIGN (P); 1223 1224 if (P) 1225 { 1226 dst->regno &= 0x06; 1227 } 1228 1229 ASSIGN_R (dst); 1230 ASSIGN_R (src0); 1231 ASSIGN_R (src1); 1232 1233 return GEN_OPCODE32 (); 1234 } 1235 1236 INSTR_T 1237 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x, 1238 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1) 1239 { 1240 INIT (DSP32Alu); 1241 1242 ASSIGN (HL); 1243 ASSIGN (aopcde); 1244 ASSIGN (aop); 1245 ASSIGN (s); 1246 ASSIGN (x); 1247 ASSIGN_R (dst0); 1248 ASSIGN_R (dst1); 1249 ASSIGN_R (src0); 1250 ASSIGN_R (src1); 1251 1252 return GEN_OPCODE32 (); 1253 } 1254 1255 INSTR_T 1256 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0, 1257 REG_T src1, int sop, int HLs) 1258 { 1259 INIT (DSP32Shift); 1260 1261 ASSIGN (sopcde); 1262 ASSIGN (sop); 1263 ASSIGN (HLs); 1264 1265 ASSIGN_R (dst0); 1266 ASSIGN_R (src0); 1267 ASSIGN_R (src1); 1268 1269 return GEN_OPCODE32 (); 1270 } 1271 1272 INSTR_T 1273 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag, 1274 REG_T src1, int sop, int HLs) 1275 { 1276 INIT (DSP32ShiftImm); 1277 1278 ASSIGN (sopcde); 1279 ASSIGN (sop); 1280 ASSIGN (HLs); 1281 1282 ASSIGN_R (dst0); 1283 ASSIGN (immag); 1284 ASSIGN_R (src1); 1285 1286 return GEN_OPCODE32 (); 1287 } 1288 1289 /* LOOP SETUP. */ 1290 1291 INSTR_T 1292 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop, 1293 Expr_Node * peoffset, REG_T reg) 1294 { 1295 int soffset, eoffset; 1296 INIT (LoopSetup); 1297 1298 soffset = (EXPR_VALUE (psoffset) >> 1); 1299 ASSIGN (soffset); 1300 eoffset = (EXPR_VALUE (peoffset) >> 1); 1301 ASSIGN (eoffset); 1302 ASSIGN (rop); 1303 ASSIGN_R (c); 1304 ASSIGN_R (reg); 1305 1306 return 1307 conscode (gencode (HI (c_code.opcode)), 1308 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL), 1309 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL)))); 1310 1311 } 1312 1313 /* Call, Link. */ 1314 1315 INSTR_T 1316 bfin_gen_calla (Expr_Node * addr, int S) 1317 { 1318 int val; 1319 int high_val; 1320 int rel = 0; 1321 INIT (CALLa); 1322 1323 switch(S){ 1324 case 0 : rel = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break; 1325 case 1 : rel = BFD_RELOC_24_PCREL; break; 1326 case 2 : rel = BFD_RELOC_BFIN_PLTPC; break; 1327 default : break; 1328 } 1329 1330 ASSIGN (S); 1331 1332 val = EXPR_VALUE (addr) >> 1; 1333 high_val = val >> 16; 1334 1335 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)), 1336 Expr_Node_Gen_Reloc (addr, rel)); 1337 } 1338 1339 INSTR_T 1340 bfin_gen_linkage (int R, int framesize) 1341 { 1342 INIT (Linkage); 1343 1344 ASSIGN (R); 1345 ASSIGN (framesize); 1346 1347 return GEN_OPCODE32 (); 1348 } 1349 1350 1351 /* Load and Store. */ 1352 1353 INSTR_T 1354 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int rel) 1355 { 1356 int grp, hword; 1357 unsigned val = EXPR_VALUE (phword); 1358 INIT (LDIMMhalf); 1359 1360 ASSIGN (H); 1361 ASSIGN (S); 1362 ASSIGN (Z); 1363 1364 ASSIGN_R (reg); 1365 grp = (GROUP (reg)); 1366 ASSIGN (grp); 1367 if (rel == 2) 1368 { 1369 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM)); 1370 } 1371 else if (rel == 1) 1372 { 1373 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW)); 1374 } 1375 else 1376 { 1377 hword = val; 1378 ASSIGN (hword); 1379 } 1380 return GEN_OPCODE32 (); 1381 } 1382 1383 INSTR_T 1384 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset) 1385 { 1386 INIT (LDSTidxI); 1387 1388 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z)) 1389 { 1390 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1391 return 0; 1392 } 1393 1394 ASSIGN_R (ptr); 1395 ASSIGN_R (reg); 1396 ASSIGN (W); 1397 ASSIGN (sz); 1398 1399 ASSIGN (Z); 1400 1401 if (poffset->type != Expr_Node_Constant) 1402 { 1403 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */ 1404 /* distinguish between R0 = [P5 + symbol@GOT] and 1405 P5 = [P5 + _current_shared_library_p5_offset_] 1406 */ 1407 if (poffset->type == Expr_Node_Reloc 1408 && !strcmp (poffset->value.s_value, 1409 "_current_shared_library_p5_offset_")) 1410 { 1411 return conscode (gencode (HI (c_code.opcode)), 1412 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16)); 1413 } 1414 else if (poffset->type != Expr_Node_GOT_Reloc) 1415 abort (); 1416 1417 return conscode (gencode (HI (c_code.opcode)), 1418 Expr_Node_Gen_Reloc(poffset->Left_Child, 1419 poffset->value.i_value)); 1420 } 1421 else 1422 { 1423 int value, offset; 1424 switch (sz) 1425 { /* load/store access size */ 1426 case 0: /* 32 bit */ 1427 value = EXPR_VALUE (poffset) >> 2; 1428 break; 1429 case 1: /* 16 bit */ 1430 value = EXPR_VALUE (poffset) >> 1; 1431 break; 1432 case 2: /* 8 bit */ 1433 value = EXPR_VALUE (poffset); 1434 break; 1435 default: 1436 abort (); 1437 } 1438 1439 offset = (value & 0xffff); 1440 ASSIGN (offset); 1441 return GEN_OPCODE32 (); 1442 } 1443 } 1444 1445 1446 INSTR_T 1447 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W) 1448 { 1449 INIT (LDST); 1450 1451 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z)) 1452 { 1453 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1454 return 0; 1455 } 1456 1457 ASSIGN_R (ptr); 1458 ASSIGN_R (reg); 1459 ASSIGN (aop); 1460 ASSIGN (sz); 1461 ASSIGN (Z); 1462 ASSIGN (W); 1463 1464 return GEN_OPCODE16 (); 1465 } 1466 1467 INSTR_T 1468 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int opc) 1469 { 1470 int offset; 1471 int value = 0; 1472 INIT (LDSTii); 1473 1474 if (!IS_PREG (*ptr)) 1475 { 1476 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1477 return 0; 1478 } 1479 1480 switch (opc) 1481 { 1482 case 1: 1483 case 2: 1484 value = EXPR_VALUE (poffset) >> 1; 1485 break; 1486 case 0: 1487 case 3: 1488 value = EXPR_VALUE (poffset) >> 2; 1489 break; 1490 } 1491 1492 ASSIGN_R (ptr); 1493 ASSIGN_R (reg); 1494 1495 offset = value; 1496 ASSIGN (offset); 1497 ASSIGN (W); 1498 ASSIGNF (opc, op); 1499 1500 return GEN_OPCODE16 (); 1501 } 1502 1503 INSTR_T 1504 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W) 1505 { 1506 /* Set bit 4 if it's a Preg. */ 1507 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0); 1508 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1; 1509 INIT (LDSTiiFP); 1510 ASSIGN (reg); 1511 ASSIGN (offset); 1512 ASSIGN (W); 1513 1514 return GEN_OPCODE16 (); 1515 } 1516 1517 INSTR_T 1518 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx) 1519 { 1520 INIT (LDSTpmod); 1521 1522 ASSIGN_R (ptr); 1523 ASSIGN_R (reg); 1524 ASSIGN (aop); 1525 ASSIGN (W); 1526 ASSIGN_R (idx); 1527 1528 return GEN_OPCODE16 (); 1529 } 1530 1531 INSTR_T 1532 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m) 1533 { 1534 INIT (DspLDST); 1535 1536 ASSIGN_R (i); 1537 ASSIGN_R (reg); 1538 ASSIGN (aop); 1539 ASSIGN (W); 1540 ASSIGN (m); 1541 1542 return GEN_OPCODE16 (); 1543 } 1544 1545 INSTR_T 1546 bfin_gen_logi2op (int opc, int src, int dst) 1547 { 1548 INIT (LOGI2op); 1549 1550 ASSIGN (opc); 1551 ASSIGN (src); 1552 ASSIGN (dst); 1553 1554 return GEN_OPCODE16 (); 1555 } 1556 1557 INSTR_T 1558 bfin_gen_brcc (int T, int B, Expr_Node * poffset) 1559 { 1560 int offset; 1561 INIT (BRCC); 1562 1563 ASSIGN (T); 1564 ASSIGN (B); 1565 offset = ((EXPR_VALUE (poffset) >> 1)); 1566 ASSIGN (offset); 1567 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL)); 1568 } 1569 1570 INSTR_T 1571 bfin_gen_ujump (Expr_Node * poffset) 1572 { 1573 int offset; 1574 INIT (UJump); 1575 1576 offset = ((EXPR_VALUE (poffset) >> 1)); 1577 ASSIGN (offset); 1578 1579 return conscode (gencode (c_code.opcode), 1580 Expr_Node_Gen_Reloc ( 1581 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S)); 1582 } 1583 1584 INSTR_T 1585 bfin_gen_alu2op (REG_T dst, REG_T src, int opc) 1586 { 1587 INIT (ALU2op); 1588 1589 ASSIGN_R (dst); 1590 ASSIGN_R (src); 1591 ASSIGN (opc); 1592 1593 return GEN_OPCODE16 (); 1594 } 1595 1596 INSTR_T 1597 bfin_gen_compi2opd (REG_T dst, int src, int opc) 1598 { 1599 INIT (COMPI2opD); 1600 1601 ASSIGN_R (dst); 1602 ASSIGN (src); 1603 ASSIGNF (opc, op); 1604 1605 return GEN_OPCODE16 (); 1606 } 1607 1608 INSTR_T 1609 bfin_gen_compi2opp (REG_T dst, int src, int opc) 1610 { 1611 INIT (COMPI2opP); 1612 1613 ASSIGN_R (dst); 1614 ASSIGN (src); 1615 ASSIGNF (opc, op); 1616 1617 return GEN_OPCODE16 (); 1618 } 1619 1620 INSTR_T 1621 bfin_gen_dagmodik (REG_T i, int opc) 1622 { 1623 INIT (DagMODik); 1624 1625 ASSIGN_R (i); 1626 ASSIGNF (opc, op); 1627 1628 return GEN_OPCODE16 (); 1629 } 1630 1631 INSTR_T 1632 bfin_gen_dagmodim (REG_T i, REG_T m, int opc, int br) 1633 { 1634 INIT (DagMODim); 1635 1636 ASSIGN_R (i); 1637 ASSIGN_R (m); 1638 ASSIGNF (opc, op); 1639 ASSIGN (br); 1640 1641 return GEN_OPCODE16 (); 1642 } 1643 1644 INSTR_T 1645 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc) 1646 { 1647 INIT (PTR2op); 1648 1649 ASSIGN_R (dst); 1650 ASSIGN_R (src); 1651 ASSIGN (opc); 1652 1653 return GEN_OPCODE16 (); 1654 } 1655 1656 INSTR_T 1657 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc) 1658 { 1659 INIT (COMP3op); 1660 1661 ASSIGN_R (src0); 1662 ASSIGN_R (src1); 1663 ASSIGN_R (dst); 1664 ASSIGN (opc); 1665 1666 return GEN_OPCODE16 (); 1667 } 1668 1669 INSTR_T 1670 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G) 1671 { 1672 INIT (CCflag); 1673 1674 ASSIGN_R (x); 1675 ASSIGN (y); 1676 ASSIGN (opc); 1677 ASSIGN (I); 1678 ASSIGN (G); 1679 1680 return GEN_OPCODE16 (); 1681 } 1682 1683 INSTR_T 1684 bfin_gen_ccmv (REG_T src, REG_T dst, int T) 1685 { 1686 int s, d; 1687 INIT (CCmv); 1688 1689 ASSIGN_R (src); 1690 ASSIGN_R (dst); 1691 s = (GROUP (src)); 1692 ASSIGN (s); 1693 d = (GROUP (dst)); 1694 ASSIGN (d); 1695 ASSIGN (T); 1696 1697 return GEN_OPCODE16 (); 1698 } 1699 1700 INSTR_T 1701 bfin_gen_cc2stat (int cbit, int opc, int D) 1702 { 1703 INIT (CC2stat); 1704 1705 ASSIGN (cbit); 1706 ASSIGNF (opc, op); 1707 ASSIGN (D); 1708 1709 return GEN_OPCODE16 (); 1710 } 1711 1712 INSTR_T 1713 bfin_gen_regmv (REG_T src, REG_T dst) 1714 { 1715 int gs, gd; 1716 INIT (RegMv); 1717 1718 ASSIGN_R (src); 1719 ASSIGN_R (dst); 1720 1721 gs = (GROUP (src)); 1722 ASSIGN (gs); 1723 gd = (GROUP (dst)); 1724 ASSIGN (gd); 1725 1726 return GEN_OPCODE16 (); 1727 } 1728 1729 INSTR_T 1730 bfin_gen_cc2dreg (int opc, REG_T reg) 1731 { 1732 INIT (CC2dreg); 1733 1734 ASSIGNF (opc, op); 1735 ASSIGN_R (reg); 1736 1737 return GEN_OPCODE16 (); 1738 } 1739 1740 INSTR_T 1741 bfin_gen_progctrl (int prgfunc, int poprnd) 1742 { 1743 INIT (ProgCtrl); 1744 1745 ASSIGN (prgfunc); 1746 ASSIGN (poprnd); 1747 1748 return GEN_OPCODE16 (); 1749 } 1750 1751 INSTR_T 1752 bfin_gen_cactrl (REG_T reg, int a, int opc) 1753 { 1754 INIT (CaCTRL); 1755 1756 ASSIGN_R (reg); 1757 ASSIGN (a); 1758 ASSIGNF (opc, op); 1759 1760 return GEN_OPCODE16 (); 1761 } 1762 1763 INSTR_T 1764 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W) 1765 { 1766 INIT (PushPopMultiple); 1767 1768 ASSIGN (dr); 1769 ASSIGN (pr); 1770 ASSIGN (d); 1771 ASSIGN (p); 1772 ASSIGN (W); 1773 1774 return GEN_OPCODE16 (); 1775 } 1776 1777 INSTR_T 1778 bfin_gen_pushpopreg (REG_T reg, int W) 1779 { 1780 int grp; 1781 INIT (PushPopReg); 1782 1783 ASSIGN_R (reg); 1784 grp = (GROUP (reg)); 1785 ASSIGN (grp); 1786 ASSIGN (W); 1787 1788 return GEN_OPCODE16 (); 1789 } 1790 1791 /* Pseudo Debugging Support. */ 1792 1793 INSTR_T 1794 bfin_gen_pseudodbg (int fn, int reg, int grp) 1795 { 1796 INIT (PseudoDbg); 1797 1798 ASSIGN (fn); 1799 ASSIGN (reg); 1800 ASSIGN (grp); 1801 1802 return GEN_OPCODE16 (); 1803 } 1804 1805 INSTR_T 1806 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected) 1807 { 1808 int grp; 1809 INIT (PseudoDbg_Assert); 1810 1811 ASSIGN (dbgop); 1812 ASSIGN_R (regtest); 1813 grp = GROUP (regtest); 1814 ASSIGN (grp); 1815 ASSIGN (expected); 1816 1817 return GEN_OPCODE32 (); 1818 } 1819 1820 INSTR_T 1821 bfin_gen_pseudochr (int ch) 1822 { 1823 INIT (PseudoChr); 1824 1825 ASSIGN (ch); 1826 1827 return GEN_OPCODE16 (); 1828 } 1829 1830 /* Multiple instruction generation. */ 1831 1832 INSTR_T 1833 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2) 1834 { 1835 INSTR_T walk; 1836 1837 /* If it's a 0, convert into MNOP. */ 1838 if (dsp32) 1839 { 1840 walk = dsp32->next; 1841 SET_MULTI_INSTRUCTION_BIT (dsp32); 1842 } 1843 else 1844 { 1845 dsp32 = gencode (0xc803); 1846 walk = gencode (0x1800); 1847 dsp32->next = walk; 1848 } 1849 1850 if (!dsp16_grp1) 1851 { 1852 dsp16_grp1 = gencode (0x0000); 1853 } 1854 1855 if (!dsp16_grp2) 1856 { 1857 dsp16_grp2 = gencode (0x0000); 1858 } 1859 1860 walk->next = dsp16_grp1; 1861 dsp16_grp1->next = dsp16_grp2; 1862 dsp16_grp2->next = NULL_CODE; 1863 1864 return dsp32; 1865 } 1866 1867 INSTR_T 1868 bfin_gen_loop (Expr_Node *exp, REG_T reg, int rop, REG_T preg) 1869 { 1870 const char *loopsym; 1871 char *lbeginsym, *lendsym; 1872 Expr_Node_Value lbeginval, lendval; 1873 Expr_Node *lbegin, *lend; 1874 symbolS *sym; 1875 1876 loopsym = exp->value.s_value; 1877 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5); 1878 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5); 1879 1880 lbeginsym[0] = 0; 1881 lendsym[0] = 0; 1882 1883 strcat (lbeginsym, "L$L$"); 1884 strcat (lbeginsym, loopsym); 1885 strcat (lbeginsym, "__BEGIN"); 1886 1887 strcat (lendsym, "L$L$"); 1888 strcat (lendsym, loopsym); 1889 strcat (lendsym, "__END"); 1890 1891 lbeginval.s_value = lbeginsym; 1892 lendval.s_value = lendsym; 1893 1894 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL); 1895 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL); 1896 1897 sym = symbol_find(loopsym); 1898 if (!S_IS_LOCAL (sym) || (S_IS_LOCAL (sym) && !symbol_used_p (sym))) 1899 symbol_remove (sym, &symbol_rootP, &symbol_lastP); 1900 1901 return bfin_gen_loopsetup (lbegin, reg, rop, lend, preg); 1902 } 1903 1904 void 1905 bfin_loop_attempt_create_label (Expr_Node *exp, int is_begin) 1906 { 1907 char *name; 1908 name = fb_label_name (exp->value.i_value, is_begin); 1909 exp->value.s_value = xstrdup (name); 1910 exp->type = Expr_Node_Reloc; 1911 } 1912 1913 void 1914 bfin_loop_beginend (Expr_Node *exp, int begin) 1915 { 1916 const char *loopsym; 1917 char *label_name; 1918 symbolS *linelabel; 1919 const char *suffix = begin ? "__BEGIN" : "__END"; 1920 1921 loopsym = exp->value.s_value; 1922 label_name = (char *) xmalloc (strlen (loopsym) + strlen (suffix) + 5); 1923 1924 label_name[0] = 0; 1925 1926 strcat (label_name, "L$L$"); 1927 strcat (label_name, loopsym); 1928 strcat (label_name, suffix); 1929 1930 linelabel = colon (label_name); 1931 1932 /* LOOP_END follows the last instruction in the loop. 1933 Adjust label address. */ 1934 if (!begin) 1935 ((struct local_symbol *) linelabel)->lsy_value -= last_insn_size; 1936 } 1937 1938 bfd_boolean 1939 bfin_eol_in_insn (char *line) 1940 { 1941 /* Allow a new-line to appear in the middle of a multi-issue instruction. */ 1942 1943 char *temp = line; 1944 1945 if (*line != '\n') 1946 return FALSE; 1947 1948 /* A semi-colon followed by a newline is always the end of a line. */ 1949 if (line[-1] == ';') 1950 return FALSE; 1951 1952 if (line[-1] == '|') 1953 return TRUE; 1954 1955 /* If the || is on the next line, there might be leading whitespace. */ 1956 temp++; 1957 while (*temp == ' ' || *temp == '\t') temp++; 1958 1959 if (*temp == '|') 1960 return TRUE; 1961 1962 return FALSE; 1963 } 1964 1965 bfd_boolean 1966 bfin_start_label (char *s) 1967 { 1968 while (*s != 0) 1969 { 1970 if (*s == '(' || *s == '[') 1971 return FALSE; 1972 s++; 1973 } 1974 1975 return TRUE; 1976 } 1977 1978 int 1979 bfin_force_relocation (struct fix *fixp) 1980 { 1981 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW 1982 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH) 1983 return TRUE; 1984 1985 return generic_force_reloc (fixp); 1986 } 1987 1988 /* This is a stripped down version of the disassembler. The only thing it 1990 does is return a mask of registers modified by an instruction. Only 1991 instructions that can occur in a parallel-issue bundle are handled, and 1992 only the registers that can cause a conflict are recorded. */ 1993 1994 #define DREG_MASK(n) (0x101 << (n)) 1995 #define DREGH_MASK(n) (0x100 << (n)) 1996 #define DREGL_MASK(n) (0x001 << (n)) 1997 #define IREG_MASK(n) (1 << ((n) + 16)) 1998 1999 static int 2000 decode_ProgCtrl_0 (int iw0) 2001 { 2002 if (iw0 == 0) 2003 return 0; 2004 abort (); 2005 } 2006 2007 static int 2008 decode_LDSTpmod_0 (int iw0) 2009 { 2010 /* LDSTpmod 2011 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2012 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......| 2013 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2014 int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask); 2015 int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask); 2016 int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask); 2017 int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask); 2018 int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask); 2019 2020 if (aop == 1 && W == 0 && idx == ptr) 2021 return DREGL_MASK (reg); 2022 else if (aop == 2 && W == 0 && idx == ptr) 2023 return DREGH_MASK (reg); 2024 else if (aop == 1 && W == 1 && idx == ptr) 2025 return 0; 2026 else if (aop == 2 && W == 1 && idx == ptr) 2027 return 0; 2028 else if (aop == 0 && W == 0) 2029 return DREG_MASK (reg); 2030 else if (aop == 1 && W == 0) 2031 return DREGL_MASK (reg); 2032 else if (aop == 2 && W == 0) 2033 return DREGH_MASK (reg); 2034 else if (aop == 3 && W == 0) 2035 return DREG_MASK (reg); 2036 else if (aop == 3 && W == 1) 2037 return DREG_MASK (reg); 2038 else if (aop == 0 && W == 1) 2039 return 0; 2040 else if (aop == 1 && W == 1) 2041 return 0; 2042 else if (aop == 2 && W == 1) 2043 return 0; 2044 else 2045 return 0; 2046 2047 return 2; 2048 } 2049 2050 static int 2051 decode_dagMODim_0 (int iw0) 2052 { 2053 /* dagMODim 2054 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2055 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....| 2056 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2057 int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask); 2058 int opc = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask); 2059 2060 if (opc == 0 || opc == 1) 2061 return IREG_MASK (i); 2062 else 2063 return 0; 2064 2065 return 2; 2066 } 2067 2068 static int 2069 decode_dagMODik_0 (int iw0) 2070 { 2071 /* dagMODik 2072 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2073 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....| 2074 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2075 int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask); 2076 return IREG_MASK (i); 2077 } 2078 2079 /* GOOD */ 2080 static int 2081 decode_dspLDST_0 (int iw0) 2082 { 2083 /* dspLDST 2084 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2085 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......| 2086 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2087 int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask); 2088 int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask); 2089 int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask); 2090 int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask); 2091 int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask); 2092 2093 if (aop == 0 && W == 0 && m == 0) 2094 return DREG_MASK (reg) | IREG_MASK (i); 2095 else if (aop == 0 && W == 0 && m == 1) 2096 return DREGL_MASK (reg) | IREG_MASK (i); 2097 else if (aop == 0 && W == 0 && m == 2) 2098 return DREGH_MASK (reg) | IREG_MASK (i); 2099 else if (aop == 1 && W == 0 && m == 0) 2100 return DREG_MASK (reg) | IREG_MASK (i); 2101 else if (aop == 1 && W == 0 && m == 1) 2102 return DREGL_MASK (reg) | IREG_MASK (i); 2103 else if (aop == 1 && W == 0 && m == 2) 2104 return DREGH_MASK (reg) | IREG_MASK (i); 2105 else if (aop == 2 && W == 0 && m == 0) 2106 return DREG_MASK (reg); 2107 else if (aop == 2 && W == 0 && m == 1) 2108 return DREGL_MASK (reg); 2109 else if (aop == 2 && W == 0 && m == 2) 2110 return DREGH_MASK (reg); 2111 else if (aop == 0 && W == 1 && m == 0) 2112 return IREG_MASK (i); 2113 else if (aop == 0 && W == 1 && m == 1) 2114 return IREG_MASK (i); 2115 else if (aop == 0 && W == 1 && m == 2) 2116 return IREG_MASK (i); 2117 else if (aop == 1 && W == 1 && m == 0) 2118 return IREG_MASK (i); 2119 else if (aop == 1 && W == 1 && m == 1) 2120 return IREG_MASK (i); 2121 else if (aop == 1 && W == 1 && m == 2) 2122 return IREG_MASK (i); 2123 else if (aop == 2 && W == 1 && m == 0) 2124 return 0; 2125 else if (aop == 2 && W == 1 && m == 1) 2126 return 0; 2127 else if (aop == 2 && W == 1 && m == 2) 2128 return 0; 2129 else if (aop == 3 && W == 0) 2130 return DREG_MASK (reg) | IREG_MASK (i); 2131 else if (aop == 3 && W == 1) 2132 return IREG_MASK (i); 2133 2134 abort (); 2135 } 2136 2137 /* GOOD */ 2138 static int 2139 decode_LDST_0 (int iw0) 2140 { 2141 /* LDST 2142 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2143 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......| 2144 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2145 int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask); 2146 int W = ((iw0 >> LDST_W_bits) & LDST_W_mask); 2147 int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask); 2148 int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask); 2149 int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask); 2150 2151 if (aop == 0 && sz == 0 && Z == 0 && W == 0) 2152 return DREG_MASK (reg); 2153 else if (aop == 0 && sz == 0 && Z == 1 && W == 0) 2154 return 0; 2155 else if (aop == 0 && sz == 1 && Z == 0 && W == 0) 2156 return DREG_MASK (reg); 2157 else if (aop == 0 && sz == 1 && Z == 1 && W == 0) 2158 return DREG_MASK (reg); 2159 else if (aop == 0 && sz == 2 && Z == 0 && W == 0) 2160 return DREG_MASK (reg); 2161 else if (aop == 0 && sz == 2 && Z == 1 && W == 0) 2162 return DREG_MASK (reg); 2163 else if (aop == 1 && sz == 0 && Z == 0 && W == 0) 2164 return DREG_MASK (reg); 2165 else if (aop == 1 && sz == 0 && Z == 1 && W == 0) 2166 return 0; 2167 else if (aop == 1 && sz == 1 && Z == 0 && W == 0) 2168 return DREG_MASK (reg); 2169 else if (aop == 1 && sz == 1 && Z == 1 && W == 0) 2170 return DREG_MASK (reg); 2171 else if (aop == 1 && sz == 2 && Z == 0 && W == 0) 2172 return DREG_MASK (reg); 2173 else if (aop == 1 && sz == 2 && Z == 1 && W == 0) 2174 return DREG_MASK (reg); 2175 else if (aop == 2 && sz == 0 && Z == 0 && W == 0) 2176 return DREG_MASK (reg); 2177 else if (aop == 2 && sz == 0 && Z == 1 && W == 0) 2178 return 0; 2179 else if (aop == 2 && sz == 1 && Z == 0 && W == 0) 2180 return DREG_MASK (reg); 2181 else if (aop == 2 && sz == 1 && Z == 1 && W == 0) 2182 return DREG_MASK (reg); 2183 else if (aop == 2 && sz == 2 && Z == 0 && W == 0) 2184 return DREG_MASK (reg); 2185 else if (aop == 2 && sz == 2 && Z == 1 && W == 0) 2186 return DREG_MASK (reg); 2187 else if (aop == 0 && sz == 0 && Z == 0 && W == 1) 2188 return 0; 2189 else if (aop == 0 && sz == 0 && Z == 1 && W == 1) 2190 return 0; 2191 else if (aop == 0 && sz == 1 && Z == 0 && W == 1) 2192 return 0; 2193 else if (aop == 0 && sz == 2 && Z == 0 && W == 1) 2194 return 0; 2195 else if (aop == 1 && sz == 0 && Z == 0 && W == 1) 2196 return 0; 2197 else if (aop == 1 && sz == 0 && Z == 1 && W == 1) 2198 return 0; 2199 else if (aop == 1 && sz == 1 && Z == 0 && W == 1) 2200 return 0; 2201 else if (aop == 1 && sz == 2 && Z == 0 && W == 1) 2202 return 0; 2203 else if (aop == 2 && sz == 0 && Z == 0 && W == 1) 2204 return 0; 2205 else if (aop == 2 && sz == 0 && Z == 1 && W == 1) 2206 return 0; 2207 else if (aop == 2 && sz == 1 && Z == 0 && W == 1) 2208 return 0; 2209 else if (aop == 2 && sz == 2 && Z == 0 && W == 1) 2210 return 0; 2211 2212 abort (); 2213 } 2214 2215 static int 2216 decode_LDSTiiFP_0 (int iw0) 2217 { 2218 /* LDSTiiFP 2219 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2220 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........| 2221 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2222 int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask); 2223 int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask); 2224 2225 if (W == 0) 2226 return reg < 8 ? DREG_MASK (reg) : 0; 2227 else 2228 return 0; 2229 } 2230 2231 static int 2232 decode_LDSTii_0 (int iw0) 2233 { 2234 /* LDSTii 2235 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2236 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......| 2237 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2238 int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask); 2239 int opc = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask); 2240 int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask); 2241 2242 if (W == 0 && opc != 3) 2243 return DREG_MASK (reg); 2244 else if (W == 0 && opc == 3) 2245 return 0; 2246 else if (W == 1 && opc == 0) 2247 return 0; 2248 else if (W == 1 && opc == 1) 2249 return 0; 2250 else if (W == 1 && opc == 3) 2251 return 0; 2252 2253 abort (); 2254 } 2255 2256 static int 2257 decode_dsp32mac_0 (int iw0, int iw1) 2258 { 2259 int result = 0; 2260 /* dsp32mac 2261 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2262 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...| 2263 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..| 2264 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2265 int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask); 2266 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask); 2267 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask); 2268 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask); 2269 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask); 2270 int MM = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask); 2271 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask); 2272 int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask); 2273 2274 if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3) 2275 return 0; 2276 2277 if (op1 == 3 && MM) 2278 return 0; 2279 2280 if ((w1 || w0) && mmod == M_W32) 2281 return 0; 2282 2283 if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0) 2284 return 0; 2285 2286 if (w1 == 1 || op1 != 3) 2287 { 2288 if (w1) 2289 { 2290 if (P) 2291 return DREG_MASK (dst + 1); 2292 else 2293 return DREGH_MASK (dst); 2294 } 2295 } 2296 2297 if (w0 == 1 || op0 != 3) 2298 { 2299 if (w0) 2300 { 2301 if (P) 2302 return DREG_MASK (dst); 2303 else 2304 return DREGL_MASK (dst); 2305 } 2306 } 2307 2308 return result; 2309 } 2310 2311 static int 2312 decode_dsp32mult_0 (int iw0, int iw1) 2313 { 2314 /* dsp32mult 2315 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2316 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...| 2317 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..| 2318 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2319 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask); 2320 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask); 2321 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask); 2322 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask); 2323 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask); 2324 int result = 0; 2325 2326 if (w1 == 0 && w0 == 0) 2327 return 0; 2328 2329 if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0) 2330 return 0; 2331 2332 if (w1) 2333 { 2334 if (P) 2335 return DREG_MASK (dst | 1); 2336 else 2337 return DREGH_MASK (dst); 2338 } 2339 2340 if (w0) 2341 { 2342 if (P) 2343 return DREG_MASK (dst); 2344 else 2345 return DREGL_MASK (dst); 2346 } 2347 2348 return result; 2349 } 2350 2351 static int 2352 decode_dsp32alu_0 (int iw0, int iw1) 2353 { 2354 /* dsp32alu 2355 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2356 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............| 2357 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......| 2358 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2359 int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask); 2360 int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask); 2361 int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask); 2362 int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask); 2363 int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask); 2364 int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask); 2365 int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask); 2366 2367 if (aop == 0 && aopcde == 9 && s == 0) 2368 return 0; 2369 else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0) 2370 return 0; 2371 else if (aop >= x * 2 && aopcde == 5) 2372 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2373 else if (HL == 0 && aopcde == 2) 2374 return DREGL_MASK (dst0); 2375 else if (HL == 1 && aopcde == 2) 2376 return DREGH_MASK (dst0); 2377 else if (HL == 0 && aopcde == 3) 2378 return DREGL_MASK (dst0); 2379 else if (HL == 1 && aopcde == 3) 2380 return DREGH_MASK (dst0); 2381 2382 else if (aop == 0 && aopcde == 9 && s == 1) 2383 return 0; 2384 else if (aop == 1 && aopcde == 9 && s == 0) 2385 return 0; 2386 else if (aop == 2 && aopcde == 9 && s == 1) 2387 return 0; 2388 else if (aop == 3 && aopcde == 9 && s == 0) 2389 return 0; 2390 else if (aopcde == 8) 2391 return 0; 2392 else if (aop == 0 && aopcde == 11) 2393 return DREG_MASK (dst0); 2394 else if (aop == 1 && aopcde == 11) 2395 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2396 else if (aopcde == 11) 2397 return 0; 2398 else if (aopcde == 22) 2399 return DREG_MASK (dst0); 2400 2401 else if ((aop == 0 || aop == 1) && aopcde == 14) 2402 return 0; 2403 else if (aop == 3 && HL == 0 && aopcde == 14) 2404 return 0; 2405 2406 else if (aop == 3 && HL == 0 && aopcde == 15) 2407 return DREG_MASK (dst0); 2408 2409 else if (aop == 1 && aopcde == 16) 2410 return 0; 2411 2412 else if (aop == 0 && aopcde == 16) 2413 return 0; 2414 2415 else if (aop == 3 && HL == 0 && aopcde == 16) 2416 return 0; 2417 2418 else if (aop == 3 && HL == 0 && aopcde == 7) 2419 return DREG_MASK (dst0); 2420 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7) 2421 return DREG_MASK (dst0); 2422 2423 else if (aop == 0 && aopcde == 12) 2424 return DREG_MASK (dst0); 2425 else if (aop == 1 && aopcde == 12) 2426 return DREG_MASK (dst0) | DREG_MASK (dst1); 2427 else if (aop == 3 && aopcde == 12) 2428 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2429 2430 else if (aopcde == 0) 2431 return DREG_MASK (dst0); 2432 else if (aopcde == 1) 2433 return DREG_MASK (dst0) | DREG_MASK (dst1); 2434 2435 else if (aop == 0 && aopcde == 10) 2436 return DREGL_MASK (dst0); 2437 else if (aop == 1 && aopcde == 10) 2438 return DREGL_MASK (dst0); 2439 2440 else if ((aop == 1 || aop == 0) && aopcde == 4) 2441 return DREG_MASK (dst0); 2442 else if (aop == 2 && aopcde == 4) 2443 return DREG_MASK (dst0) | DREG_MASK (dst1); 2444 2445 else if (aop == 0 && aopcde == 17) 2446 return DREG_MASK (dst0) | DREG_MASK (dst1); 2447 else if (aop == 1 && aopcde == 17) 2448 return DREG_MASK (dst0) | DREG_MASK (dst1); 2449 else if (aop == 0 && aopcde == 18) 2450 return 0; 2451 else if (aop == 3 && aopcde == 18) 2452 return 0; 2453 2454 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6) 2455 return DREG_MASK (dst0); 2456 2457 else if ((aop == 0 || aop == 1) && aopcde == 20) 2458 return DREG_MASK (dst0); 2459 2460 else if ((aop == 0 || aop == 1) && aopcde == 21) 2461 return DREG_MASK (dst0) | DREG_MASK (dst1); 2462 2463 else if (aop == 0 && aopcde == 23 && HL == 1) 2464 return DREG_MASK (dst0); 2465 else if (aop == 0 && aopcde == 23 && HL == 0) 2466 return DREG_MASK (dst0); 2467 2468 else if (aop == 0 && aopcde == 24) 2469 return DREG_MASK (dst0); 2470 else if (aop == 1 && aopcde == 24) 2471 return DREG_MASK (dst0) | DREG_MASK (dst1); 2472 else if (aopcde == 13) 2473 return DREG_MASK (dst0) | DREG_MASK (dst1); 2474 else 2475 return 0; 2476 2477 return 4; 2478 } 2479 2480 static int 2481 decode_dsp32shift_0 (int iw0, int iw1) 2482 { 2483 /* dsp32shift 2484 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2485 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............| 2486 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......| 2487 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2488 int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask); 2489 int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask); 2490 int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask); 2491 int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask); 2492 int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask); 2493 int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask); 2494 2495 if (sop == 0 && sopcde == 0) 2496 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2497 else if (sop == 1 && sopcde == 0) 2498 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2499 else if (sop == 2 && sopcde == 0) 2500 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2501 else if (sop == 0 && sopcde == 3) 2502 return 0; 2503 else if (sop == 1 && sopcde == 3) 2504 return 0; 2505 else if (sop == 2 && sopcde == 3) 2506 return 0; 2507 else if (sop == 3 && sopcde == 3) 2508 return DREG_MASK (dst0); 2509 else if (sop == 0 && sopcde == 1) 2510 return DREG_MASK (dst0); 2511 else if (sop == 1 && sopcde == 1) 2512 return DREG_MASK (dst0); 2513 else if (sop == 2 && sopcde == 1) 2514 return DREG_MASK (dst0); 2515 else if (sopcde == 2) 2516 return DREG_MASK (dst0); 2517 else if (sopcde == 4) 2518 return DREG_MASK (dst0); 2519 else if (sop == 0 && sopcde == 5) 2520 return DREGL_MASK (dst0); 2521 else if (sop == 1 && sopcde == 5) 2522 return DREGL_MASK (dst0); 2523 else if (sop == 2 && sopcde == 5) 2524 return DREGL_MASK (dst0); 2525 else if (sop == 0 && sopcde == 6) 2526 return DREGL_MASK (dst0); 2527 else if (sop == 1 && sopcde == 6) 2528 return DREGL_MASK (dst0); 2529 else if (sop == 3 && sopcde == 6) 2530 return DREGL_MASK (dst0); 2531 else if (sop == 0 && sopcde == 7) 2532 return DREGL_MASK (dst0); 2533 else if (sop == 1 && sopcde == 7) 2534 return DREGL_MASK (dst0); 2535 else if (sop == 2 && sopcde == 7) 2536 return DREGL_MASK (dst0); 2537 else if (sop == 3 && sopcde == 7) 2538 return DREGL_MASK (dst0); 2539 else if (sop == 0 && sopcde == 8) 2540 return DREG_MASK (src0) | DREG_MASK (src1); 2541 #if 0 2542 { 2543 OUTS (outf, "BITMUX ("); 2544 OUTS (outf, dregs (src0)); 2545 OUTS (outf, ", "); 2546 OUTS (outf, dregs (src1)); 2547 OUTS (outf, ", A0) (ASR)"); 2548 } 2549 #endif 2550 else if (sop == 1 && sopcde == 8) 2551 return DREG_MASK (src0) | DREG_MASK (src1); 2552 #if 0 2553 { 2554 OUTS (outf, "BITMUX ("); 2555 OUTS (outf, dregs (src0)); 2556 OUTS (outf, ", "); 2557 OUTS (outf, dregs (src1)); 2558 OUTS (outf, ", A0) (ASL)"); 2559 } 2560 #endif 2561 else if (sopcde == 9) 2562 return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0); 2563 else if (sopcde == 10) 2564 return DREG_MASK (dst0); 2565 else if (sop == 0 && sopcde == 11) 2566 return DREGL_MASK (dst0); 2567 else if (sop == 1 && sopcde == 11) 2568 return DREGL_MASK (dst0); 2569 else if (sop == 0 && sopcde == 12) 2570 return 0; 2571 else if (sop == 1 && sopcde == 12) 2572 return DREGL_MASK (dst0); 2573 else if (sop == 0 && sopcde == 13) 2574 return DREG_MASK (dst0); 2575 else if (sop == 1 && sopcde == 13) 2576 return DREG_MASK (dst0); 2577 else if (sop == 2 && sopcde == 13) 2578 return DREG_MASK (dst0); 2579 2580 abort (); 2581 } 2582 2583 static int 2584 decode_dsp32shiftimm_0 (int iw0, int iw1) 2585 { 2586 /* dsp32shiftimm 2587 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2588 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............| 2589 |.sop...|.HLs...|.dst0......|.immag.................|.src1......| 2590 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2591 int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask); 2592 int bit8 = ((iw1 >> 8) & 0x1); 2593 int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask); 2594 int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask); 2595 int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask); 2596 2597 2598 if (sop == 0 && sopcde == 0) 2599 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2600 else if (sop == 1 && sopcde == 0 && bit8 == 0) 2601 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2602 else if (sop == 1 && sopcde == 0 && bit8 == 1) 2603 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2604 else if (sop == 2 && sopcde == 0 && bit8 == 0) 2605 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2606 else if (sop == 2 && sopcde == 0 && bit8 == 1) 2607 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2608 else if (sop == 2 && sopcde == 3 && HLs == 1) 2609 return 0; 2610 else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0) 2611 return 0; 2612 else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1) 2613 return 0; 2614 else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0) 2615 return 0; 2616 else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1) 2617 return 0; 2618 else if (sop == 1 && sopcde == 3 && HLs == 0) 2619 return 0; 2620 else if (sop == 1 && sopcde == 3 && HLs == 1) 2621 return 0; 2622 else if (sop == 2 && sopcde == 3 && HLs == 0) 2623 return 0; 2624 else if (sop == 1 && sopcde == 1 && bit8 == 0) 2625 return DREG_MASK (dst0); 2626 else if (sop == 1 && sopcde == 1 && bit8 == 1) 2627 return DREG_MASK (dst0); 2628 else if (sop == 2 && sopcde == 1 && bit8 == 1) 2629 return DREG_MASK (dst0); 2630 else if (sop == 2 && sopcde == 1 && bit8 == 0) 2631 return DREG_MASK (dst0); 2632 else if (sop == 0 && sopcde == 1) 2633 return DREG_MASK (dst0); 2634 else if (sop == 1 && sopcde == 2) 2635 return DREG_MASK (dst0); 2636 else if (sop == 2 && sopcde == 2 && bit8 == 1) 2637 return DREG_MASK (dst0); 2638 else if (sop == 2 && sopcde == 2 && bit8 == 0) 2639 return DREG_MASK (dst0); 2640 else if (sop == 3 && sopcde == 2) 2641 return DREG_MASK (dst0); 2642 else if (sop == 0 && sopcde == 2) 2643 return DREG_MASK (dst0); 2644 2645 abort (); 2646 } 2647 2648 int 2649 insn_regmask (int iw0, int iw1) 2650 { 2651 if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800) 2652 return 0; /* MNOP */ 2653 else if ((iw0 & 0xff00) == 0x0000) 2654 return decode_ProgCtrl_0 (iw0); 2655 else if ((iw0 & 0xffc0) == 0x0240) 2656 abort (); 2657 else if ((iw0 & 0xff80) == 0x0100) 2658 abort (); 2659 else if ((iw0 & 0xfe00) == 0x0400) 2660 abort (); 2661 else if ((iw0 & 0xfe00) == 0x0600) 2662 abort (); 2663 else if ((iw0 & 0xf800) == 0x0800) 2664 abort (); 2665 else if ((iw0 & 0xffe0) == 0x0200) 2666 abort (); 2667 else if ((iw0 & 0xff00) == 0x0300) 2668 abort (); 2669 else if ((iw0 & 0xf000) == 0x1000) 2670 abort (); 2671 else if ((iw0 & 0xf000) == 0x2000) 2672 abort (); 2673 else if ((iw0 & 0xf000) == 0x3000) 2674 abort (); 2675 else if ((iw0 & 0xfc00) == 0x4000) 2676 abort (); 2677 else if ((iw0 & 0xfe00) == 0x4400) 2678 abort (); 2679 else if ((iw0 & 0xf800) == 0x4800) 2680 abort (); 2681 else if ((iw0 & 0xf000) == 0x5000) 2682 abort (); 2683 else if ((iw0 & 0xf800) == 0x6000) 2684 abort (); 2685 else if ((iw0 & 0xf800) == 0x6800) 2686 abort (); 2687 else if ((iw0 & 0xf000) == 0x8000) 2688 return decode_LDSTpmod_0 (iw0); 2689 else if ((iw0 & 0xff60) == 0x9e60) 2690 return decode_dagMODim_0 (iw0); 2691 else if ((iw0 & 0xfff0) == 0x9f60) 2692 return decode_dagMODik_0 (iw0); 2693 else if ((iw0 & 0xfc00) == 0x9c00) 2694 return decode_dspLDST_0 (iw0); 2695 else if ((iw0 & 0xf000) == 0x9000) 2696 return decode_LDST_0 (iw0); 2697 else if ((iw0 & 0xfc00) == 0xb800) 2698 return decode_LDSTiiFP_0 (iw0); 2699 else if ((iw0 & 0xe000) == 0xA000) 2700 return decode_LDSTii_0 (iw0); 2701 else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000) 2702 abort (); 2703 else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000) 2704 abort (); 2705 else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000) 2706 abort (); 2707 else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000) 2708 abort (); 2709 else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000) 2710 abort (); 2711 else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000) 2712 return decode_dsp32mac_0 (iw0, iw1); 2713 else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000) 2714 return decode_dsp32mult_0 (iw0, iw1); 2715 else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000) 2716 return decode_dsp32alu_0 (iw0, iw1); 2717 else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000) 2718 return decode_dsp32shift_0 (iw0, iw1); 2719 else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000) 2720 return decode_dsp32shiftimm_0 (iw0, iw1); 2721 else if ((iw0 & 0xff00) == 0xf800) 2722 abort (); 2723 else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000) 2724 abort (); 2725 2726 abort (); 2727 } 2728