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