tc-ns32k.c revision 1.1
1/* ns32k.c -- Assemble on the National Semiconductor 32k series 2 Copyright (C) 1987, 1992, 1993 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 2, 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 18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20/*#define SHOW_NUM 1*//* uncomment for debugging */ 21 22#include <stdio.h> 23#include <ctype.h> 24 25#include "as.h" 26#include "opcode/ns32k.h" 27 28#include "obstack.h" 29 30/* Macros */ 31#define IIF_ENTRIES 13 /* number of entries in iif */ 32#define PRIVATE_SIZE 256 /* size of my garbage memory */ 33#define MAX_ARGS 4 34#define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */ 35 36#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \ 37 iif.iifP[ptr].type= a1; \ 38 iif.iifP[ptr].size= c1; \ 39 iif.iifP[ptr].object= e1; \ 40 iif.iifP[ptr].object_adjust= g1; \ 41 iif.iifP[ptr].pcrel= i1; \ 42 iif.iifP[ptr].pcrel_adjust= k1; \ 43 iif.iifP[ptr].im_disp= m1; \ 44 iif.iifP[ptr].relax_substate= o1; \ 45 iif.iifP[ptr].bit_fixP= q1; \ 46 iif.iifP[ptr].addr_mode= s1; \ 47 iif.iifP[ptr].bsr= u1; 48 49#ifdef SEQUENT_COMPATABILITY 50#define LINE_COMMENT_CHARS "|" 51#define ABSOLUTE_PREFIX '@' 52#define IMMEDIATE_PREFIX '#' 53#endif 54 55#ifndef LINE_COMMENT_CHARS 56#define LINE_COMMENT_CHARS "#" 57#endif 58 59const char comment_chars[] = "#"; 60const char line_comment_chars[] = LINE_COMMENT_CHARS; 61const char line_separator_chars[] = ""; 62#if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX) 63#define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */ 64#endif 65 66struct addr_mode 67 { 68 char mode; /* addressing mode of operand (0-31) */ 69 char scaled_mode; /* mode combined with scaled mode */ 70 char scaled_reg; /* register used in scaled+1 (1-8) */ 71 char float_flag; /* set if R0..R7 was F0..F7 ie a floating-point-register */ 72 char am_size; /* estimated max size of general addr-mode parts*/ 73 char im_disp; /* if im_disp==1 we have a displacement */ 74 char pcrel; /* 1 if pcrel, this is really redundant info */ 75 char disp_suffix[2]; /* length of displacement(s), 0=undefined */ 76 char *disp[2]; /* pointer(s) at displacement(s) 77 or immediates(s) (ascii) */ 78 char index_byte; /* index byte */ 79 }; 80typedef struct addr_mode addr_modeS; 81 82 83char *freeptr, *freeptr_static; /* points at some number of free bytes */ 84struct hash_control *inst_hash_handle; 85 86struct ns32k_opcode *desc; /* pointer at description of instruction */ 87addr_modeS addr_modeP; 88const char EXP_CHARS[] = "eE"; 89const char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */ 90 91/* UPPERCASE denotes live names 92 * when an instruction is built, IIF is used as an intermidiate form to store 93 * the actual parts of the instruction. A ns32k machine instruction can 94 * be divided into a couple of sub PARTs. When an instruction is assembled 95 * the appropriate PART get an assignment. When an IIF has been completed it's 96 * converted to a FRAGment as specified in AS.H */ 97 98/* internal structs */ 99struct ns32k_option 100 { 101 char *pattern; 102 unsigned long or; 103 unsigned long and; 104 }; 105 106typedef struct 107 { 108 int type; /* how to interpret object */ 109 int size; /* Estimated max size of object */ 110 unsigned long object; /* binary data */ 111 int object_adjust; /* number added to object */ 112 int pcrel; /* True if object is pcrel */ 113 int pcrel_adjust; /* length in bytes from the 114 instruction start to the 115 displacement */ 116 int im_disp; /* True if the object is a displacement */ 117 relax_substateT relax_substate; /* Initial relaxsubstate */ 118 bit_fixS *bit_fixP; /* Pointer at bit_fix struct */ 119 int addr_mode; /* What addrmode do we associate with this iif-entry */ 120 char bsr; /* Sequent hack */ 121 } 122 123iif_entryT; /* Internal Instruction Format */ 124 125struct int_ins_form 126 { 127 int instr_size; /* Max size of instruction in bytes. */ 128 iif_entryT iifP[IIF_ENTRIES + 1]; 129 }; 130struct int_ins_form iif; 131expressionS exprP; 132char *input_line_pointer; 133/* description of the PARTs in IIF 134 *object[n]: 135 * 0 total length in bytes of entries in iif 136 * 1 opcode 137 * 2 index_byte_a 138 * 3 index_byte_b 139 * 4 disp_a_1 140 * 5 disp_a_2 141 * 6 disp_b_1 142 * 7 disp_b_2 143 * 8 imm_a 144 * 9 imm_b 145 * 10 implied1 146 * 11 implied2 147 * 148 * For every entry there is a datalength in bytes. This is stored in size[n]. 149 * 0, the objectlength is not explicitly given by the instruction 150 * and the operand is undefined. This is a case for relaxation. 151 * Reserve 4 bytes for the final object. 152 * 153 * 1, the entry contains one byte 154 * 2, the entry contains two bytes 155 * 3, the entry contains three bytes 156 * 4, the entry contains four bytes 157 * etc 158 * 159 * Furthermore, every entry has a data type identifier in type[n]. 160 * 161 * 0, the entry is void, ignore it. 162 * 1, the entry is a binary number. 163 * 2, the entry is a pointer at an expression. 164 * Where expression may be as simple as a single '1', 165 * and as complicated as foo-bar+12, 166 * foo and bar may be undefined but suffixed by :{b|w|d} to 167 * control the length of the object. 168 * 169 * 3, the entry is a pointer at a bignum struct 170 * 171 * 172 * The low-order-byte coresponds to low physical memory. 173 * Obviously a FRAGment must be created for each valid disp in PART whose 174 * datalength is undefined (to bad) . 175 * The case where just the expression is undefined is less severe and is 176 * handled by fix. Here the number of bytes in the objectfile is known. 177 * With this representation we simplify the assembly and separates the 178 * machine dependent/independent parts in a more clean way (said OE) 179 */ 180 181struct ns32k_option opt1[] = /* restore, exit */ 182{ 183 {"r0", 0x80, 0xff}, 184 {"r1", 0x40, 0xff}, 185 {"r2", 0x20, 0xff}, 186 {"r3", 0x10, 0xff}, 187 {"r4", 0x08, 0xff}, 188 {"r5", 0x04, 0xff}, 189 {"r6", 0x02, 0xff}, 190 {"r7", 0x01, 0xff}, 191 {0, 0x00, 0xff} 192}; 193struct ns32k_option opt2[] = /* save, enter */ 194{ 195 {"r0", 0x01, 0xff}, 196 {"r1", 0x02, 0xff}, 197 {"r2", 0x04, 0xff}, 198 {"r3", 0x08, 0xff}, 199 {"r4", 0x10, 0xff}, 200 {"r5", 0x20, 0xff}, 201 {"r6", 0x40, 0xff}, 202 {"r7", 0x80, 0xff}, 203 {0, 0x00, 0xff} 204}; 205struct ns32k_option opt3[] = /* setcfg */ 206{ 207 {"c", 0x8, 0xff}, 208 {"m", 0x4, 0xff}, 209 {"f", 0x2, 0xff}, 210 {"i", 0x1, 0xff}, 211 {0, 0x0, 0xff} 212}; 213struct ns32k_option opt4[] = /* cinv */ 214{ 215 {"a", 0x4, 0xff}, 216 {"i", 0x2, 0xff}, 217 {"d", 0x1, 0xff}, 218 {0, 0x0, 0xff} 219}; 220struct ns32k_option opt5[] = /* string inst */ 221{ 222 {"b", 0x2, 0xff}, 223 {"u", 0xc, 0xff}, 224 {"w", 0x4, 0xff}, 225 {0, 0x0, 0xff} 226}; 227struct ns32k_option opt6[] = /* plain reg ext,cvtp etc */ 228{ 229 {"r0", 0x00, 0xff}, 230 {"r1", 0x01, 0xff}, 231 {"r2", 0x02, 0xff}, 232 {"r3", 0x03, 0xff}, 233 {"r4", 0x04, 0xff}, 234 {"r5", 0x05, 0xff}, 235 {"r6", 0x06, 0xff}, 236 {"r7", 0x07, 0xff}, 237 {0, 0x00, 0xff} 238}; 239 240#if !defined(NS32032) && !defined(NS32532) 241#define NS32532 242#endif 243 244struct ns32k_option cpureg_532[] = /* lpr spr */ 245{ 246 {"us", 0x0, 0xff}, 247 {"dcr", 0x1, 0xff}, 248 {"bpc", 0x2, 0xff}, 249 {"dsr", 0x3, 0xff}, 250 {"car", 0x4, 0xff}, 251 {"fp", 0x8, 0xff}, 252 {"sp", 0x9, 0xff}, 253 {"sb", 0xa, 0xff}, 254 {"usp", 0xb, 0xff}, 255 {"cfg", 0xc, 0xff}, 256 {"psr", 0xd, 0xff}, 257 {"intbase", 0xe, 0xff}, 258 {"mod", 0xf, 0xff}, 259 {0, 0x00, 0xff} 260}; 261struct ns32k_option mmureg_532[] = /* lmr smr */ 262{ 263 {"mcr", 0x9, 0xff}, 264 {"msr", 0xa, 0xff}, 265 {"tear", 0xb, 0xff}, 266 {"ptb0", 0xc, 0xff}, 267 {"ptb1", 0xd, 0xff}, 268 {"ivar0", 0xe, 0xff}, 269 {"ivar1", 0xf, 0xff}, 270 {0, 0x0, 0xff} 271}; 272 273struct ns32k_option cpureg_032[] = /* lpr spr */ 274{ 275 {"upsr", 0x0, 0xff}, 276 {"fp", 0x8, 0xff}, 277 {"sp", 0x9, 0xff}, 278 {"sb", 0xa, 0xff}, 279 {"psr", 0xd, 0xff}, 280 {"intbase", 0xe, 0xff}, 281 {"mod", 0xf, 0xff}, 282 {0, 0x0, 0xff} 283}; 284struct ns32k_option mmureg_032[] = /* lmr smr */ 285{ 286 {"bpr0", 0x0, 0xff}, 287 {"bpr1", 0x1, 0xff}, 288 {"pf0", 0x4, 0xff}, 289 {"pf1", 0x5, 0xff}, 290 {"sc", 0x8, 0xff}, 291 {"msr", 0xa, 0xff}, 292 {"bcnt", 0xb, 0xff}, 293 {"ptb0", 0xc, 0xff}, 294 {"ptb1", 0xd, 0xff}, 295 {"eia", 0xf, 0xff}, 296 {0, 0x0, 0xff} 297}; 298 299#if defined(NS32532) 300struct ns32k_option *cpureg = cpureg_532; 301struct ns32k_option *mmureg = mmureg_532; 302#else 303struct ns32k_option *cpureg = cpureg_032; 304struct ns32k_option *mmureg = mmureg_032; 305#endif 306 307 308const pseudo_typeS md_pseudo_table[] = 309{ /* so far empty */ 310 {0, 0, 0} 311}; 312 313#define IND(x,y) (((x)<<2)+(y)) 314 315/* those are index's to relax groups in md_relax_table 316 ie it must be multiplied by 4 to point at a group start. Viz IND(x,y) 317 Se function relax_segment in write.c for more info */ 318 319#define BRANCH 1 320#define PCREL 2 321 322/* those are index's to entries in a relax group */ 323 324#define BYTE 0 325#define WORD 1 326#define DOUBLE 2 327#define UNDEF 3 328/* Those limits are calculated from the displacement start in memory. 329 The ns32k uses the begining of the instruction as displacement base. 330 This type of displacements could be handled here by moving the limit window 331 up or down. I choose to use an internal displacement base-adjust as there 332 are other routines that must consider this. Also, as we have two various 333 offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits 334 would have had to be used. 335 Now we dont have to think about that. */ 336 337 338const relax_typeS md_relax_table[] = 339{ 340 {1, 1, 0, 0}, 341 {1, 1, 0, 0}, 342 {1, 1, 0, 0}, 343 {1, 1, 0, 0}, 344 345 {(63), (-64), 1, IND (BRANCH, WORD)}, 346 {(8192), (-8192), 2, IND (BRANCH, DOUBLE)}, 347 {0, 0, 4, 0}, 348 {1, 1, 0, 0} 349}; 350 351/* Array used to test if mode contains displacements. 352 Value is true if mode contains displacement. */ 353 354char disp_test[] = 355{0, 0, 0, 0, 0, 0, 0, 0, 356 1, 1, 1, 1, 1, 1, 1, 1, 357 1, 1, 1, 0, 0, 1, 1, 0, 358 1, 1, 1, 1, 1, 1, 1, 1}; 359 360/* Array used to calculate max size of displacements */ 361 362char disp_size[] = 363{4, 1, 2, 0, 4}; 364 365static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr)); 366static void md_number_to_disp PARAMS ((char *buf, long val, int n)); 367static void md_number_to_imm PARAMS ((char *buf, long val, int n)); 368 369/* Parses a general operand into an addressingmode struct 370 371 in: pointer at operand in ascii form 372 pointer at addr_mode struct for result 373 the level of recursion. (always 0 or 1) 374 375 out: data in addr_mode struct 376 */ 377int 378addr_mode (operand, addr_modeP, recursive_level) 379 char *operand; 380 register addr_modeS *addr_modeP; 381 int recursive_level; 382{ 383 register char *str; 384 register int i; 385 register int strl; 386 register int mode; 387 int j; 388 mode = DEFAULT; /* default */ 389 addr_modeP->scaled_mode = 0; /* why not */ 390 addr_modeP->scaled_reg = 0; /* if 0, not scaled index */ 391 addr_modeP->float_flag = 0; 392 addr_modeP->am_size = 0; 393 addr_modeP->im_disp = 0; 394 addr_modeP->pcrel = 0; /* not set in this function */ 395 addr_modeP->disp_suffix[0] = 0; 396 addr_modeP->disp_suffix[1] = 0; 397 addr_modeP->disp[0] = NULL; 398 addr_modeP->disp[1] = NULL; 399 str = operand; 400 if (str[0] == 0) 401 { 402 return (0); 403 } /* we don't want this */ 404 strl = strlen (str); 405 switch (str[0]) 406 { 407 /* the following three case statements controls the mode-chars 408 this is the place to ed if you want to change them */ 409#ifdef ABSOLUTE_PREFIX 410 case ABSOLUTE_PREFIX: 411 if (str[strl - 1] == ']') 412 break; 413 addr_modeP->mode = 21; /* absolute */ 414 addr_modeP->disp[0] = str + 1; 415 return (-1); 416#endif 417#ifdef IMMEDIATE_PREFIX 418 case IMMEDIATE_PREFIX: 419 if (str[strl - 1] == ']') 420 break; 421 addr_modeP->mode = 20; /* immediate */ 422 addr_modeP->disp[0] = str + 1; 423 return (-1); 424#endif 425 case '.': 426 if (str[strl - 1] != ']') 427 { 428 switch (str[1]) 429 { 430 case '-': 431 case '+': 432 if (str[2] != '\000') 433 { 434 addr_modeP->mode = 27; /* pc-relativ */ 435 addr_modeP->disp[0] = str + 2; 436 return (-1); 437 } 438 default: 439 as_warn ("Invalid syntax in PC-relative addressing mode"); 440 return (0); 441 } 442 } 443 break; 444 case 'e': 445 if (str[strl - 1] != ']') 446 { 447 if ((!strncmp (str, "ext(", 4)) && strl > 7) 448 { /* external */ 449 addr_modeP->disp[0] = str + 4; 450 i = 0; 451 j = 2; 452 do 453 { /* disp[0]'s termination point */ 454 j += 1; 455 if (str[j] == '(') 456 i++; 457 if (str[j] == ')') 458 i--; 459 } 460 while (j < strl && i != 0); 461 if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+')) 462 { 463 as_warn ("Invalid syntax in External addressing mode"); 464 return (0); 465 } 466 str[j] = '\000'; /* null terminate disp[0] */ 467 addr_modeP->disp[1] = str + j + 2; 468 addr_modeP->mode = 22; 469 return (-1); 470 } 471 } 472 break; 473 default:; 474 } 475 strl = strlen (str); 476 switch (strl) 477 { 478 case 2: 479 switch (str[0]) 480 { 481 case 'f': 482 addr_modeP->float_flag = 1; 483 case 'r': 484 if (str[1] >= '0' && str[1] < '8') 485 { 486 addr_modeP->mode = str[1] - '0'; 487 return (-1); 488 } 489 } 490 case 3: 491 if (!strncmp (str, "tos", 3)) 492 { 493 addr_modeP->mode = 23;/* TopOfStack */ 494 return (-1); 495 } 496 default:; 497 } 498 if (strl > 4) 499 { 500 if (str[strl - 1] == ')') 501 { 502 if (str[strl - 2] == ')') 503 { 504 if (!strncmp (&str[strl - 5], "(fp", 3)) 505 { 506 mode = 16; /* Memory Relative */ 507 } 508 if (!strncmp (&str[strl - 5], "(sp", 3)) 509 { 510 mode = 17; 511 } 512 if (!strncmp (&str[strl - 5], "(sb", 3)) 513 { 514 mode = 18; 515 } 516 if (mode != DEFAULT) 517 { /* memory relative */ 518 addr_modeP->mode = mode; 519 j = strl - 5; /* temp for end of disp[0] */ 520 i = 0; 521 do 522 { 523 strl -= 1; 524 if (str[strl] == ')') 525 i++; 526 if (str[strl] == '(') 527 i--; 528 } 529 while (strl > -1 && i != 0); 530 if (i != 0) 531 { 532 as_warn ("Invalid syntax in Memory Relative addressing mode"); 533 return (0); 534 } 535 addr_modeP->disp[1] = str; 536 addr_modeP->disp[0] = str + strl + 1; 537 str[j] = '\000'; /* null terminate disp[0] */ 538 str[strl] = '\000'; /* null terminate disp[1] */ 539 return (-1); 540 } 541 } 542 switch (str[strl - 3]) 543 { 544 case 'r': 545 case 'R': 546 if (str[strl - 2] >= '0' && str[strl - 2] < '8' && str[strl - 4] == '(') 547 { 548 addr_modeP->mode = str[strl - 2] - '0' + 8; 549 addr_modeP->disp[0] = str; 550 str[strl - 4] = 0; 551 return (-1); /* reg rel */ 552 } 553 default: 554 if (!strncmp (&str[strl - 4], "(fp", 3)) 555 { 556 mode = 24; 557 } 558 if (!strncmp (&str[strl - 4], "(sp", 3)) 559 { 560 mode = 25; 561 } 562 if (!strncmp (&str[strl - 4], "(sb", 3)) 563 { 564 mode = 26; 565 } 566 if (!strncmp (&str[strl - 4], "(pc", 3)) 567 { 568 mode = 27; 569 } 570 if (mode != DEFAULT) 571 { 572 addr_modeP->mode = mode; 573 addr_modeP->disp[0] = str; 574 str[strl - 4] = '\0'; 575 return (-1); /* memory space */ 576 } 577 } 578 } 579 /* no trailing ')' do we have a ']' ? */ 580 if (str[strl - 1] == ']') 581 { 582 switch (str[strl - 2]) 583 { 584 case 'b': 585 mode = 28; 586 break; 587 case 'w': 588 mode = 29; 589 break; 590 case 'd': 591 mode = 30; 592 break; 593 case 'q': 594 mode = 31; 595 break; 596 default:; 597 as_warn ("Invalid scaled-indexed mode, use (b,w,d,q)"); 598 if (str[strl - 3] != ':' || str[strl - 6] != '[' || 599 str[strl - 5] == 'r' || str[strl - 4] < '0' || str[strl - 4] > '7') 600 { 601 as_warn ("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"); 602 } 603 } /* scaled index */ 604 { 605 if (recursive_level > 0) 606 { 607 as_warn ("Scaled-indexed addressing mode combined with scaled-index"); 608 return (0); 609 } 610 addr_modeP->am_size += 1; /* scaled index byte */ 611 j = str[strl - 4] - '0'; /* store temporary */ 612 str[strl - 6] = '\000'; /* nullterminate for recursive call */ 613 i = addr_mode (str, addr_modeP, 1); 614 if (!i || addr_modeP->mode == 20) 615 { 616 as_warn ("Invalid or illegal addressing mode combined with scaled-index"); 617 return (0); 618 } 619 addr_modeP->scaled_mode = addr_modeP->mode; /* store the inferior mode */ 620 addr_modeP->mode = mode; 621 addr_modeP->scaled_reg = j + 1; 622 return (-1); 623 } 624 } 625 } 626 addr_modeP->mode = DEFAULT; /* default to whatever */ 627 addr_modeP->disp[0] = str; 628 return (-1); 629} 630 631/* ptr points at string 632 addr_modeP points at struct with result 633 This routine calls addr_mode to determine the general addr.mode of 634 the operand. When this is ready it parses the displacements for size 635 specifying suffixes and determines size of immediate mode via ns32k-opcode. 636 Also builds index bytes if needed. 637 */ 638int 639get_addr_mode (ptr, addr_modeP) 640 char *ptr; 641 addr_modeS *addr_modeP; 642{ 643 int tmp; 644 addr_mode (ptr, addr_modeP, 0); 645 if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1) 646 { 647 /* resolve ambigious operands, this shouldn't 648 be necessary if one uses standard NSC operand 649 syntax. But the sequent compiler doesn't!!! 650 This finds a proper addressinging mode if it 651 is implicitly stated. See ns32k-opcode.h */ 652 (void) evaluate_expr (&exprP, ptr); /* this call takes time Sigh! */ 653 if (addr_modeP->mode == DEFAULT) 654 { 655 if (exprP.X_add_symbol || exprP.X_op_symbol) 656 { 657 addr_modeP->mode = desc->default_model; /* we have a label */ 658 } 659 else 660 { 661 addr_modeP->mode = desc->default_modec; /* we have a constant */ 662 } 663 } 664 else 665 { 666 if (exprP.X_add_symbol || exprP.X_op_symbol) 667 { 668 addr_modeP->scaled_mode = desc->default_model; 669 } 670 else 671 { 672 addr_modeP->scaled_mode = desc->default_modec; 673 } 674 } 675 /* must put this mess down in addr_mode to handle the scaled case better */ 676 } 677 /* It appears as the sequent compiler wants an absolute when we have a 678 label without @. Constants becomes immediates besides the addr case. 679 Think it does so with local labels too, not optimum, pcrel is better. 680 When I have time I will make gas check this and select pcrel when possible 681 Actually that is trivial. 682 */ 683 if (tmp = addr_modeP->scaled_reg) 684 { /* build indexbyte */ 685 tmp--; /* remember regnumber comes incremented for flagpurpose */ 686 tmp |= addr_modeP->scaled_mode << 3; 687 addr_modeP->index_byte = (char) tmp; 688 addr_modeP->am_size += 1; 689 } 690 if (disp_test[addr_modeP->mode]) 691 { /* there was a displacement, probe for length specifying suffix*/ 692 { 693 register char c; 694 register char suffix; 695 register char suffix_sub; 696 register int i; 697 register char *toP; 698 register char *fromP; 699 700 addr_modeP->pcrel = 0; 701 if (disp_test[addr_modeP->mode]) 702 { /* there is a displacement */ 703 if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27) 704 { /* do we have pcrel. mode */ 705 addr_modeP->pcrel = 1; 706 } 707 addr_modeP->im_disp = 1; 708 for (i = 0; i < 2; i++) 709 { 710 suffix_sub = suffix = 0; 711 if (toP = addr_modeP->disp[i]) 712 { /* suffix of expression, the largest size rules */ 713 fromP = toP; 714 while (c = *fromP++) 715 { 716 *toP++ = c; 717 if (c == ':') 718 { 719 switch (*fromP) 720 { 721 case '\0': 722 as_warn ("Premature end of suffix--Defaulting to d"); 723 suffix = 4; 724 continue; 725 case 'b': 726 suffix_sub = 1; 727 break; 728 case 'w': 729 suffix_sub = 2; 730 break; 731 case 'd': 732 suffix_sub = 4; 733 break; 734 default: 735 as_warn ("Bad suffix after ':' use {b|w|d} Defaulting to d"); 736 suffix = 4; 737 } 738 fromP++; 739 toP--; /* So we write over the ':' */ 740 if (suffix < suffix_sub) 741 suffix = suffix_sub; 742 } 743 } 744 *toP = '\0';/* terminate properly */ 745 addr_modeP->disp_suffix[i] = suffix; 746 addr_modeP->am_size += suffix ? suffix : 4; 747 } 748 } 749 } 750 } 751 } 752 else 753 { 754 if (addr_modeP->mode == 20) 755 { /* look in ns32k_opcode for size */ 756 addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size; 757 addr_modeP->im_disp = 0; 758 } 759 } 760 return addr_modeP->mode; 761} 762 763 764/* read an optionlist */ 765void 766optlist (str, optionP, default_map) 767 char *str; /* the string to extract options from */ 768 struct ns32k_option *optionP; /* how to search the string */ 769 unsigned long *default_map;/* default pattern and output */ 770{ 771 register int i, j, k, strlen1, strlen2; 772 register char *patternP, *strP; 773 strlen1 = strlen (str); 774 if (strlen1 < 1) 775 { 776 as_fatal ("Very short instr to option, ie you can't do it on a NULLstr"); 777 } 778 for (i = 0; optionP[i].pattern != 0; i++) 779 { 780 strlen2 = strlen (optionP[i].pattern); 781 for (j = 0; j < strlen1; j++) 782 { 783 patternP = optionP[i].pattern; 784 strP = &str[j]; 785 for (k = 0; k < strlen2; k++) 786 { 787 if (*(strP++) != *(patternP++)) 788 break; 789 } 790 if (k == strlen2) 791 { /* match */ 792 *default_map |= optionP[i].or; 793 *default_map &= optionP[i].and; 794 } 795 } 796 } 797} 798 799/* search struct for symbols 800 This function is used to get the short integer form of reg names 801 in the instructions lmr, smr, lpr, spr 802 return true if str is found in list */ 803 804int 805list_search (str, optionP, default_map) 806 char *str; /* the string to match */ 807 struct ns32k_option *optionP; /* list to search */ 808 unsigned long *default_map;/* default pattern and output */ 809{ 810 register int i; 811 for (i = 0; optionP[i].pattern != 0; i++) 812 { 813 if (!strncmp (optionP[i].pattern, str, 20)) 814 { /* use strncmp to be safe */ 815 *default_map |= optionP[i].or; 816 *default_map &= optionP[i].and; 817 return -1; 818 } 819 } 820 as_warn ("No such entry in list. (cpu/mmu register)"); 821 return 0; 822} 823 824static void 825evaluate_expr (resultP, ptr) 826 expressionS *resultP; 827 char *ptr; 828{ 829 register char *tmp_line; 830 831 tmp_line = input_line_pointer; 832 input_line_pointer = ptr; 833 expression (&exprP); 834 input_line_pointer = tmp_line; 835} 836 837/* Convert operands to iif-format and adds bitfields to the opcode. 838 Operands are parsed in such an order that the opcode is updated from 839 its most significant bit, that is when the operand need to alter the 840 opcode. 841 Be carefull not to put to objects in the same iif-slot. 842 */ 843 844void 845encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr) 846 int argc; 847 char **argv; 848 char *operandsP; 849 char *suffixP; 850 char im_size; 851 char opcode_bit_ptr; 852{ 853 register int i, j; 854 char d; 855 int pcrel, tmp, b, loop, pcrel_adjust; 856 for (loop = 0; loop < argc; loop++) 857 { 858 i = operandsP[loop << 1] - '1'; /* what operand are we supposed to work on */ 859 if (i > 3) 860 as_fatal ("Internal consistency error. check ns32k-opcode.h"); 861 pcrel = 0; 862 pcrel_adjust = 0; 863 tmp = 0; 864 switch ((d = operandsP[(loop << 1) + 1])) 865 { 866 case 'f': /* operand of sfsr turns out to be a nasty specialcase */ 867 opcode_bit_ptr -= 5; 868 case 'Z': /* float not immediate */ 869 case 'F': /* 32 bit float general form */ 870 case 'L': /* 64 bit float */ 871 case 'I': /* integer not immediate */ 872 case 'B': /* byte */ 873 case 'W': /* word */ 874 case 'D': /* double-word */ 875 case 'A': /* double-word gen-address-form ie no regs allowed */ 876 get_addr_mode (argv[i], &addr_modeP); 877 if((addr_modeP.mode == 20) && 878 (d == 'I' || d == 'Z' || d == 'A')) { 879 as_fatal(d == 'A'? "Address of immediate operand": 880 "Invalid immediate write operand."); 881 } 882 iif.instr_size += addr_modeP.am_size; 883 if (opcode_bit_ptr == desc->opcode_size) 884 b = 4; 885 else 886 b = 6; 887 for (j = b; j < (b + 2); j++) 888 { 889 if (addr_modeP.disp[j - b]) 890 { 891 IIF (j, 892 2, 893 addr_modeP.disp_suffix[j - b], 894 (unsigned long) addr_modeP.disp[j - b], 895 0, 896 addr_modeP.pcrel, 897 iif.instr_size - addr_modeP.am_size, /* this aint used (now) */ 898 addr_modeP.im_disp, 899 IND (BRANCH, BYTE), 900 NULL, 901 addr_modeP.scaled_reg ? addr_modeP.scaled_mode : addr_modeP.mode, 902 0); 903 } 904 } 905 opcode_bit_ptr -= 5; 906 iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr; 907 if (addr_modeP.scaled_reg) 908 { 909 j = b / 2; 910 IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte, 0, 0, 0, 0, 0, NULL, -1, 0); 911 } 912 break; 913 case 'b': /* multiple instruction disp */ 914 freeptr++; /* OVE:this is an useful hack */ 915 sprintf (freeptr, "((%s-1)*%d)\000", argv[i], desc->im_size); 916 argv[i] = freeptr; 917 pcrel -= 1; /* make pcrel 0 inspite of what case 'p': wants */ 918 /* fall thru */ 919 case 'p': /* displacement - pc relative addressing */ 920 pcrel += 1; 921 /* fall thru */ 922 case 'd': /* displacement */ 923 iif.instr_size += suffixP[i] ? suffixP[i] : 4; 924 IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0, 925 pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0); 926 break; 927 case 'H': /* sequent-hack: the linker wants a bit set when bsr */ 928 pcrel = 1; 929 iif.instr_size += suffixP[i] ? suffixP[i] : 4; 930 IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0, 931 pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1); 932 break; 933 case 'q': /* quick */ 934 opcode_bit_ptr -= 4; 935 IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0, 936 bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0); 937 break; 938 case 'r': /* register number (3 bits) */ 939 list_search (argv[i], opt6, &tmp); 940 opcode_bit_ptr -= 3; 941 iif.iifP[1].object |= tmp << opcode_bit_ptr; 942 break; 943 case 'O': /* setcfg instruction optionslist */ 944 optlist (argv[i], opt3, &tmp); 945 opcode_bit_ptr -= 4; 946 iif.iifP[1].object |= tmp << 15; 947 break; 948 case 'C': /* cinv instruction optionslist */ 949 optlist (argv[i], opt4, &tmp); 950 opcode_bit_ptr -= 4; 951 iif.iifP[1].object |= tmp << 15; /*insert the regtype in opcode */ 952 break; 953 case 'S': /* stringinstruction optionslist */ 954 optlist (argv[i], opt5, &tmp); 955 opcode_bit_ptr -= 4; 956 iif.iifP[1].object |= tmp << 15; 957 break; 958 case 'u': 959 case 'U': /* registerlist */ 960 IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0); 961 switch (operandsP[(i << 1) + 1]) 962 { 963 case 'u': /* restore, exit */ 964 optlist (argv[i], opt1, &iif.iifP[10].object); 965 break; 966 case 'U': /* save,enter */ 967 optlist (argv[i], opt2, &iif.iifP[10].object); 968 break; 969 } 970 iif.instr_size += 1; 971 break; 972 case 'M': /* mmu register */ 973 list_search (argv[i], mmureg, &tmp); 974 opcode_bit_ptr -= 4; 975 iif.iifP[1].object |= tmp << opcode_bit_ptr; 976 break; 977 case 'P': /* cpu register */ 978 list_search (argv[i], cpureg, &tmp); 979 opcode_bit_ptr -= 4; 980 iif.iifP[1].object |= tmp << opcode_bit_ptr; 981 break; 982 case 'g': /* inss exts */ 983 iif.instr_size += 1; /* 1 byte is allocated after the opcode */ 984 IIF (10, 2, 1, 985 (unsigned long) argv[i], /* i always 2 here */ 986 0, 0, 0, 0, 0, 987 bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* a bit_fix is targeted to the byte */ 988 -1, 0); 989 break; 990 case 'G': 991 IIF (11, 2, 42, 992 (unsigned long) argv[i], /* i always 3 here */ 993 0, 0, 0, 0, 0, 994 bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0); 995 break; 996 case 'i': 997 iif.instr_size += 1; 998 b = 2 + i; /* put the extension byte after opcode */ 999 IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0); 1000 break; 1001 default: 1002 as_fatal ("Bad opcode-table-option, check in file ns32k-opcode.h"); 1003 } 1004 } 1005} 1006 1007/* in: instruction line 1008 out: internal structure of instruction 1009 that has been prepared for direct conversion to fragment(s) and 1010 fixes in a systematical fashion 1011 Return-value = recursive_level 1012 */ 1013/* build iif of one assembly text line */ 1014int 1015parse (line, recursive_level) 1016 char *line; 1017 int recursive_level; 1018{ 1019 register char *lineptr, c, suffix_separator; 1020 register int i; 1021 int argc, arg_type; 1022 char sqr, sep; 1023 char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* no more than 4 operands */ 1024 if (recursive_level <= 0) 1025 { /* called from md_assemble */ 1026 for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++); 1027 c = *lineptr; 1028 *lineptr = '\0'; 1029 if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line))) 1030 { 1031 as_fatal ("No such opcode"); 1032 } 1033 *lineptr = c; 1034 } 1035 else 1036 { 1037 lineptr = line; 1038 } 1039 argc = 0; 1040 if (*desc->operands) 1041 { 1042 if (*lineptr++ != '\0') 1043 { 1044 sqr = '['; 1045 sep = ','; 1046 while (*lineptr != '\0') 1047 { 1048 if (desc->operands[argc << 1]) 1049 { 1050 suffix[argc] = 0; 1051 arg_type = desc->operands[(argc << 1) + 1]; 1052 switch (arg_type) 1053 { 1054 case 'd': 1055 case 'b': 1056 case 'p': 1057 case 'H': /* the operand is supposed to be a displacement */ 1058 /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */ 1059 suffix_separator = ':'; 1060 break; 1061 default: 1062 suffix_separator = '\255'; /* if this char occurs we loose */ 1063 } 1064 suffix[argc] = 0; /* 0 when no ':' is encountered */ 1065 argv[argc] = freeptr; 1066 *freeptr = '\0'; 1067 while ((c = *lineptr) != '\0' && c != sep) 1068 { 1069 if (c == sqr) 1070 { 1071 if (sqr == '[') 1072 { 1073 sqr = ']'; 1074 sep = '\0'; 1075 } 1076 else 1077 { 1078 sqr = '['; 1079 sep = ','; 1080 } 1081 } 1082 if (c == suffix_separator) 1083 { /* ':' - label/suffix separator */ 1084 switch (lineptr[1]) 1085 { 1086 case 'b': 1087 suffix[argc] = 1; 1088 break; 1089 case 'w': 1090 suffix[argc] = 2; 1091 break; 1092 case 'd': 1093 suffix[argc] = 4; 1094 break; 1095 default: 1096 as_warn ("Bad suffix, defaulting to d"); 1097 suffix[argc] = 4; 1098 if (lineptr[1] == '\0' || lineptr[1] == sep) 1099 { 1100 lineptr += 1; 1101 continue; 1102 } 1103 } 1104 lineptr += 2; 1105 continue; 1106 } 1107 *freeptr++ = c; 1108 lineptr++; 1109 } 1110 *freeptr++ = '\0'; 1111 argc += 1; 1112 if (*lineptr == '\0') 1113 continue; 1114 lineptr += 1; 1115 } 1116 else 1117 { 1118 as_fatal ("Too many operands passed to instruction"); 1119 } 1120 } 1121 } 1122 } 1123 if (argc != strlen (desc->operands) / 2) 1124 { 1125 if (strlen (desc->default_args)) 1126 { /* we can apply default, dont goof */ 1127 if (parse (desc->default_args, 1) != 1) 1128 { /* check error in default */ 1129 as_fatal ("Wrong numbers of operands in default, check ns32k-opcodes.h"); 1130 } 1131 } 1132 else 1133 { 1134 as_fatal ("Wrong number of operands"); 1135 } 1136 1137 } 1138 for (i = 0; i < IIF_ENTRIES; i++) 1139 { 1140 iif.iifP[i].type = 0; /* mark all entries as void*/ 1141 } 1142 1143 /* build opcode iif-entry */ 1144 iif.instr_size = desc->opcode_size / 8; 1145 IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0); 1146 1147 /* this call encodes operands to iif format */ 1148 if (argc) 1149 { 1150 encode_operand (argc, 1151 argv, 1152 &desc->operands[0], 1153 &suffix[0], 1154 desc->im_size, 1155 desc->opcode_size); 1156 } 1157 return recursive_level; 1158} 1159 1160 1161/* Convert iif to fragments. From this point we start to dribble with 1162 * functions in other files than this one.(Except hash.c) So, if it's 1163 * possible to make an iif for an other CPU, you don't need to know 1164 * what frags, relax, obstacks, etc is in order to port this 1165 * assembler. You only need to know if it's possible to reduce your 1166 * cpu-instruction to iif-format (takes some work) and adopt the other 1167 * md_? parts according to given instructions Note that iif was 1168 * invented for the clean ns32k`s architecure. 1169 */ 1170 1171/* GAS for the ns32k has a problem. PC relative displacements are relative 1172 * to the address of the opcode, not the address of the operand. We can 1173 * keep track of the offset between the operand and the opcode in 1174 * pcrel_adjust. That is what it is for. However, we get into trouble 1175 * where there is two or more pc-relative operands and the size of the 1176 * first one can't be determined. Then in the relax phase, the size of the 1177 * first operand will change and pcrel_adjust will no longer be correct. 1178 * In an earlier attempt to fix this, I added an extra field to frags to 1179 * keep track of how much the pcrel_adjust had changed during relax. 1180 * That meant cluttering up write.c with (more) ns32k dependent things. 1181 * The current solution is to note that operands whose size isn't determined 1182 * yet must be in the variable part of a frag. The next operand (if any)] 1183 * must be in a new frag. What we need is a way to find out where in what 1184 * frag the opcode for this operand is. 1185 * What we do is allocate and extra structure and for frags which do not 1186 * contain the opcode, use the opcode pointer to point at this new 1187 * structure. Requires that a pointer to a struct can be cast to a pointer 1188 * to char * without loss. 1189 */ 1190struct opcode_location { 1191 fragS *fragP; 1192 unsigned int offset; 1193}; 1194 1195void 1196convert_iif () 1197{ 1198 int i; 1199 bit_fixS *j; 1200 fragS *inst_frag; 1201 unsigned int inst_offset; 1202 char *inst_opcode; 1203 struct opcode_location *opcode_location; 1204 fragS *opcode_frag; 1205 char *memP; 1206 int l; 1207 int k; 1208 int rem_size; /* count the remaining bytes of instruction */ 1209 char type; 1210 char size = 0; 1211 int size_so_far = 0; /* used to calculate pcrel_adjust */ 1212 char first = 1; /* true until after the first frag of this 1213 * instruction has been done 1214 */ 1215 1216 rem_size = iif.instr_size; 1217 memP = frag_more (iif.instr_size); /* make sure we have enough bytes for instruction */ 1218 inst_opcode = memP; 1219 inst_offset = (memP - frag_now->fr_literal); 1220 inst_frag = frag_now; 1221 1222 for (i = 0; i < IIF_ENTRIES; i++) 1223 { 1224 if (type = iif.iifP[i].type) 1225 { /* the object exist, so handle it */ 1226 switch (size = iif.iifP[i].size) 1227 { 1228 case 42: 1229 size = 0; /* it's a bitfix that operates on an existing object*/ 1230 if (iif.iifP[i].bit_fixP->fx_bit_base) 1231 { /* expand fx_bit_base to point at opcode */ 1232 iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode; 1233 } 1234 case 8: /* bignum or doublefloat */ 1235 memset (memP, '\0', size); 1236 case 1: 1237 case 2: 1238 case 3: 1239 case 4: /* the final size in objectmemory is known */ 1240 j = iif.iifP[i].bit_fixP; 1241 switch (type) 1242 { 1243 case 1: /* the object is pure binary */ 1244 if (j || iif.iifP[i].pcrel) 1245 { 1246 fix_new_ns32k (frag_now, 1247 (long) (memP - frag_now->fr_literal), 1248 size, 1249 0, 1250 iif.iifP[i].object, 1251 iif.iifP[i].pcrel, 1252 (char) (first? size_so_far: 0), /*iif.iifP[i].pcrel_adjust,*/ 1253 iif.iifP[i].im_disp, 1254 j, 1255 iif.iifP[i].bsr); /* sequent hack */ 1256 } 1257 else 1258 { /* good, just put them bytes out */ 1259 switch (iif.iifP[i].im_disp) 1260 { 1261 case 0: 1262 md_number_to_chars (memP, iif.iifP[i].object, size); 1263 break; 1264 case 1: 1265 md_number_to_disp (memP, iif.iifP[i].object, size); 1266 break; 1267 default: 1268 as_fatal ("iif convert internal pcrel/binary"); 1269 } 1270 } 1271 memP += size; 1272 rem_size -= size; 1273 break; 1274 case 2: /* the object is a pointer at an expression, so unpack 1275 it, note that bignums may result from the expression 1276 */ 1277 evaluate_expr (&exprP, (char *) iif.iifP[i].object); 1278 if (exprP.X_op == O_big || size == 8) 1279 { 1280 if ((k = exprP.X_add_number) > 0) 1281 { /* we have a bignum ie a quad */ 1282 /* this can only happens in a long suffixed instruction */ 1283 memset (memP, '\0', size); /* size normally is 8 */ 1284 if (k * 2 > size) 1285 as_warn ("Bignum too big for long"); 1286 if (k == 3) 1287 memP += 2; 1288 for (l = 0; k > 0; k--, l += 2) 1289 { 1290 md_number_to_chars (memP + l, generic_bignum[l >> 1], sizeof (LITTLENUM_TYPE)); 1291 } 1292 } 1293 else 1294 { /* flonum */ 1295 LITTLENUM_TYPE words[4]; 1296 1297 switch (size) 1298 { 1299 case 4: 1300 gen_to_words (words, 2, 8); 1301 md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE)); 1302 md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE)); 1303 break; 1304 case 8: 1305 gen_to_words (words, 4, 11); 1306 md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE)); 1307 md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE)); 1308 md_number_to_imm (memP + 2 * sizeof (LITTLENUM_TYPE), (long) words[2], sizeof (LITTLENUM_TYPE)); 1309 md_number_to_imm (memP + 3 * sizeof (LITTLENUM_TYPE), (long) words[3], sizeof (LITTLENUM_TYPE)); 1310 break; 1311 } 1312 } 1313 memP += size; 1314 rem_size -= size; 1315 break; 1316 } 1317 if (j || 1318 exprP.X_add_symbol || 1319 exprP.X_op_symbol || 1320 iif.iifP[i].pcrel) 1321 { /* fixit */ 1322 /* the expression was undefined due to an undefined label */ 1323 /* create a fix so we can fix the object later */ 1324 exprP.X_add_number += iif.iifP[i].object_adjust; 1325 fix_new_ns32k_exp (frag_now, 1326 (long) (memP - frag_now->fr_literal), 1327 size, 1328 &exprP, 1329 iif.iifP[i].pcrel, 1330 (char) (first? size_so_far: 0), /*iif.iifP[i].pcrel_adjust,*/ 1331 iif.iifP[i].im_disp, 1332 j, 1333 iif.iifP[i].bsr); /* sequent hack */ 1334 1335 } 1336 else 1337 { /* good, just put them bytes out */ 1338 switch (iif.iifP[i].im_disp) 1339 { 1340 case 0: 1341 md_number_to_imm (memP, exprP.X_add_number, size); 1342 break; 1343 case 1: 1344 md_number_to_disp (memP, exprP.X_add_number, size); 1345 break; 1346 default: 1347 as_fatal ("iif convert internal pcrel/pointer"); 1348 } 1349 } 1350 memP += size; 1351 rem_size -= size; 1352 break; 1353 default: 1354 as_fatal ("Internal logic error in iif.iifP[n].type"); 1355 } 1356 break; 1357 case 0: /* To bad, the object may be undefined as far as 1358 * its final nsize in object memory is concerned. 1359 * The size of the object in objectmemory is not 1360 * explicitly given. If the object is defined its 1361 * length can be determined and a fix can replace 1362 * the frag. 1363 */ 1364 { 1365 int temp; 1366 evaluate_expr (&exprP, (char *) iif.iifP[i].object); 1367 if ((exprP.X_add_symbol || exprP.X_op_symbol) && 1368 !iif.iifP[i].pcrel) 1369 { /* OVE: hack, clamp to 4 bytes */ 1370 size = 4; /* we dont wan't to frag this, use 4 so it reaches */ 1371 fix_new_ns32k_exp (frag_now, 1372 (long) (memP - frag_now->fr_literal), 1373 size, 1374 &exprP, 1375 0, /* never iif.iifP[i].pcrel, */ 1376 (char) (first? size_so_far: 0), /*iif.iifP[i].pcrel_adjust,*/ 1377 1, /* always iif.iifP[i].im_disp, */ 1378 (bit_fixS *) 0, 0); 1379 memP += size; 1380 rem_size -= 4; 1381 break; /* exit this absolute hack */ 1382 } 1383 1384 if (exprP.X_add_symbol || exprP.X_op_symbol) 1385 { /* frag it */ 1386 if (exprP.X_op_symbol) 1387 { /* We cant relax this case */ 1388 as_fatal ("Can't relax difference"); 1389 } 1390 else 1391 { 1392 1393 /* at this stage we must undo some of the 1394 * effect caused by frag_more, ie we must make 1395 * sure that frag_var causes frag_new to creat 1396 * a valid fix-size in the frag it`s closing 1397 * * we rewind none, some or all of the 1398 * requested size we requested by the first 1399 * frag_more for this iif chunk. Note: that 1400 * we allocate 4 bytes to an object we NOT YET 1401 * know the size of, thus rem_size-4. 1402 */ 1403 1404 /* Size is not important. This gets fixed by relax, 1405 * but we assume 0 in what follows 1406 */ 1407 size = 0; 1408 1409 temp = -(rem_size - 4); 1410 obstack_blank_fast (&frags, temp); 1411 1412 { 1413 fragS *old_frag = frag_now; 1414 frag_variant (rs_machine_dependent, 1415 4, 1416 0, /* size */ 1417 IND (BRANCH, UNDEF), /* expecting the worst */ 1418 exprP.X_add_symbol, 1419 exprP.X_add_number, 1420 (first 1421 ? inst_opcode 1422 : (char *) opcode_location)); 1423 if (first) 1424 old_frag->fr_pcrel_adjust = (char) size_so_far; 1425 old_frag->fr_bsr = iif.iifP[i].bsr; 1426 } 1427 1428 if (first) { 1429 /* The opcode is really in the last frag. 1430 * overload the inst_opcode pointer. 1431 */ 1432 opcode_location 1433 = (struct opcode_location *) obstack_alloc(¬es, sizeof(struct opcode_location)); 1434 opcode_location->fragP = inst_frag; 1435 opcode_location->offset = inst_offset; 1436 1437 first = 0; 1438 } 1439 1440 rem_size -= 4; 1441 if (rem_size > 0) 1442 { 1443 memP = frag_more (rem_size); 1444 } 1445 } 1446 } 1447 else 1448 { /* Double work, this is done in md_number_to_disp */ 1449 /* exprP.X_add_number; what was this supposed to be? 1450 xoxorich. */ 1451 if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63) 1452 { 1453 size = 1; 1454 } 1455 else 1456 { 1457 if (-8192 <= exprP.X_add_number && exprP.X_add_number <= 8191) 1458 { 1459 size = 2; 1460 } 1461 else 1462 { 1463 if (-0x20000000<=exprP.X_add_number && 1464 exprP.X_add_number<=0x1fffffff) 1465 { 1466 size = 4; 1467 } 1468 else 1469 { 1470 as_warn ("Displacement to large for :d"); 1471 size = 4; 1472 } 1473 } 1474 } 1475 /* rewind the bytes not used */ 1476 temp = -(4 - size); 1477 md_number_to_disp (memP, exprP.X_add_number, size); 1478 obstack_blank_fast (&frags, temp); 1479 memP += size; 1480 rem_size -= 4; /* we allocated this amount */ 1481 } 1482 } 1483 break; 1484 default: 1485 as_fatal ("Internal logic error in iif.iifP[].type"); 1486 } 1487 size_so_far += size; 1488 size = 0; 1489 } 1490 } 1491} 1492 1493#ifdef BFD_ASSEMBLER 1494/* This functionality should really be in the bfd library */ 1495static bfd_reloc_code_real_type 1496reloc (int size, int pcrel, int type) 1497{ 1498 int length, index; 1499 bfd_reloc_code_real_type relocs[] = { 1500 BFD_RELOC_NS32K_IMM_8, 1501 BFD_RELOC_NS32K_IMM_16, 1502 BFD_RELOC_NS32K_IMM_32, 1503 BFD_RELOC_NS32K_IMM_8_PCREL, 1504 BFD_RELOC_NS32K_IMM_16_PCREL, 1505 BFD_RELOC_NS32K_IMM_32_PCREL, 1506 1507 /* ns32k displacements */ 1508 BFD_RELOC_NS32K_DISP_8, 1509 BFD_RELOC_NS32K_DISP_16, 1510 BFD_RELOC_NS32K_DISP_32, 1511 BFD_RELOC_NS32K_DISP_8_PCREL, 1512 BFD_RELOC_NS32K_DISP_16_PCREL, 1513 BFD_RELOC_NS32K_DISP_32_PCREL, 1514 1515 /* Normal 2's complement */ 1516 BFD_RELOC_8, 1517 BFD_RELOC_16, 1518 BFD_RELOC_32, 1519 BFD_RELOC_8_PCREL, 1520 BFD_RELOC_16_PCREL, 1521 BFD_RELOC_32_PCREL 1522 }; 1523 switch (size) 1524 { 1525 case 1: 1526 length = 0; 1527 break; 1528 case 2: 1529 length = 1; 1530 break; 1531 case 4: 1532 length = 2; 1533 break; 1534 default: 1535 length = -1; 1536 break; 1537 } 1538 index = length + 3 * pcrel + 6 * type; 1539 if (index >= 0 && index < sizeof(relocs)/sizeof(relocs[0])) 1540 return relocs[index]; 1541 as_bad ("Can not do %d byte %s relocation for storage type %d", size, 1542 pcrel ? "pc-relative" : "", type); 1543 return BFD_RELOC_NONE; 1544 1545} 1546 1547#endif 1548 1549void 1550md_assemble (line) 1551 char *line; 1552{ 1553 freeptr = freeptr_static; 1554 parse (line, 0); /* explode line to more fix form in iif */ 1555 convert_iif (); /* convert iif to frags, fix's etc */ 1556#ifdef SHOW_NUM 1557 printf (" \t\t\t%s\n", line); 1558#endif 1559} 1560 1561 1562void 1563md_begin () 1564{ 1565 /* build a hashtable of the instructions */ 1566 const struct ns32k_opcode *ptr; 1567 const char *stat; 1568 inst_hash_handle = hash_new (); 1569 for (ptr = ns32k_opcodes; ptr < endop; ptr++) 1570 { 1571 if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr))) 1572 { 1573 as_fatal ("Can't hash %s: %s", ptr->name, stat); /*fatal*/ 1574 } 1575 } 1576 freeptr_static = (char *) malloc (PRIVATE_SIZE); /* some private space please! */ 1577} 1578 1579/* Must be equal to MAX_PRECISON in atof-ieee.c */ 1580#define MAX_LITTLENUMS 6 1581 1582/* Turn the string pointed to by litP into a floating point constant of type 1583 type, and emit the appropriate bytes. The number of LITTLENUMS emitted 1584 is stored in *sizeP . An error message is returned, or NULL on OK. 1585 */ 1586char * 1587md_atof (type, litP, sizeP) 1588 char type; 1589 char *litP; 1590 int *sizeP; 1591{ 1592 int prec; 1593 LITTLENUM_TYPE words[MAX_LITTLENUMS]; 1594 LITTLENUM_TYPE *wordP; 1595 char *t; 1596 1597 switch (type) 1598 { 1599 case 'f': 1600 prec = 2; 1601 break; 1602 1603 case 'd': 1604 prec = 4; 1605 break; 1606 default: 1607 *sizeP = 0; 1608 return "Bad call to MD_ATOF()"; 1609 } 1610 t = atof_ieee (input_line_pointer, type, words); 1611 if (t) 1612 input_line_pointer = t; 1613 1614 *sizeP = prec * sizeof (LITTLENUM_TYPE); 1615 for (wordP = words + prec; prec--;) 1616 { 1617 md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE)); 1618 litP += sizeof (LITTLENUM_TYPE); 1619 } 1620 return 0; 1621} 1622 1623/* Convert number to chars in correct order */ 1624 1625void 1626md_number_to_chars (buf, value, nbytes) 1627 char *buf; 1628 valueT value; 1629 int nbytes; 1630{ 1631 number_to_chars_littleendian (buf, value, nbytes); 1632} 1633 1634 1635/* This is a variant of md_numbers_to_chars. The reason for its' existence 1636 is the fact that ns32k uses Huffman coded displacements. This implies 1637 that the bit order is reversed in displacements and that they are prefixed 1638 with a size-tag. 1639 1640 binary: msb -> lsb 1641 0xxxxxxx byte 1642 10xxxxxx xxxxxxxx word 1643 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word 1644 1645 This must be taken care of and we do it here! 1646 */ 1647static void 1648md_number_to_disp (buf, val, n) 1649 char *buf; 1650 long val; 1651 char n; 1652{ 1653 switch (n) 1654 { 1655 case 1: 1656 if (val < -64 || val > 63) 1657 as_warn ("Byte displacement out of range. line number not valid"); 1658 val &= 0x7f; 1659#ifdef SHOW_NUM 1660 printf ("%x ", val & 0xff); 1661#endif 1662 *buf++ = val; 1663 break; 1664 case 2: 1665 if (val < -8192 || val > 8191) 1666 as_warn ("Word displacement out of range. line number not valid"); 1667 val &= 0x3fff; 1668 val |= 0x8000; 1669#ifdef SHOW_NUM 1670 printf ("%x ", val >> 8 & 0xff); 1671#endif 1672 *buf++ = (val >> 8); 1673#ifdef SHOW_NUM 1674 printf ("%x ", val & 0xff); 1675#endif 1676 *buf++ = val; 1677 break; 1678 case 4: 1679 if (val < -0x20000000 || val >= 0x20000000) 1680 as_warn ("Double word displacement out of range"); 1681 val |= 0xc0000000; 1682#ifdef SHOW_NUM 1683 printf ("%x ", val >> 24 & 0xff); 1684#endif 1685 *buf++ = (val >> 24); 1686#ifdef SHOW_NUM 1687 printf ("%x ", val >> 16 & 0xff); 1688#endif 1689 *buf++ = (val >> 16); 1690#ifdef SHOW_NUM 1691 printf ("%x ", val >> 8 & 0xff); 1692#endif 1693 *buf++ = (val >> 8); 1694#ifdef SHOW_NUM 1695 printf ("%x ", val & 0xff); 1696#endif 1697 *buf++ = val; 1698 break; 1699 default: 1700 as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__); 1701 } 1702} 1703 1704static void 1705md_number_to_imm (buf, val, n) 1706 char *buf; 1707 long val; 1708 char n; 1709{ 1710 switch (n) 1711 { 1712 case 1: 1713#ifdef SHOW_NUM 1714 printf ("%x ", val & 0xff); 1715#endif 1716 *buf++ = val; 1717 break; 1718 case 2: 1719#ifdef SHOW_NUM 1720 printf ("%x ", val >> 8 & 0xff); 1721#endif 1722 *buf++ = (val >> 8); 1723#ifdef SHOW_NUM 1724 printf ("%x ", val & 0xff); 1725#endif 1726 *buf++ = val; 1727 break; 1728 case 4: 1729#ifdef SHOW_NUM 1730 printf ("%x ", val >> 24 & 0xff); 1731#endif 1732 *buf++ = (val >> 24); 1733#ifdef SHOW_NUM 1734 printf ("%x ", val >> 16 & 0xff); 1735#endif 1736 *buf++ = (val >> 16); 1737#ifdef SHOW_NUM 1738 printf ("%x ", val >> 8 & 0xff); 1739#endif 1740 *buf++ = (val >> 8); 1741#ifdef SHOW_NUM 1742 printf ("%x ", val & 0xff); 1743#endif 1744 *buf++ = val; 1745 break; 1746 default: 1747 as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__); 1748 } 1749} 1750 1751/* Translate internal representation of relocation info into target format. 1752 1753 OVE: on a ns32k the twiddling continues at an even deeper level 1754 here we have to distinguish between displacements and immediates. 1755 1756 The sequent has a bit for this. It also has a bit for relocobjects that 1757 points at the target for a bsr (BranchSubRoutine) !?!?!?! 1758 1759 This md_ri.... is tailored for sequent. 1760 */ 1761 1762#ifdef comment 1763void 1764md_ri_to_chars (the_bytes, ri) 1765 char *the_bytes; 1766 struct reloc_info_generic *ri; 1767{ 1768 if (ri->r_bsr) 1769 { 1770 ri->r_pcrel = 0; 1771 } /* sequent seems to want this */ 1772 md_number_to_chars (the_bytes, ri->r_address, sizeof (ri->r_address)); 1773 md_number_to_chars (the_bytes + 4, ((long) (ri->r_symbolnum) 1774 | (long) (ri->r_pcrel << 24) 1775 | (long) (ri->r_length << 25) 1776 | (long) (ri->r_extern << 27) 1777 | (long) (ri->r_bsr << 28) 1778 | (long) (ri->r_disp << 29)), 1779 4); 1780 /* the first and second md_number_to_chars never overlaps (32bit cpu case) */ 1781} 1782 1783#endif /* comment */ 1784 1785/* fast bitfiddling support */ 1786/* mask used to zero bitfield before oring in the true field */ 1787 1788static unsigned long l_mask[] = 1789{ 1790 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 1791 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 1792 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, 1793 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 1794 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, 1795 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 1796 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, 1797 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, 1798}; 1799static unsigned long r_mask[] = 1800{ 1801 0x00000000, 0x00000001, 0x00000003, 0x00000007, 1802 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 1803 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 1804 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 1805 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 1806 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 1807 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 1808 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 1809}; 1810#define MASK_BITS 31 1811/* Insert bitfield described by field_ptr and val at buf 1812 This routine is written for modification of the first 4 bytes pointed 1813 to by buf, to yield speed. 1814 The ifdef stuff is for selection between a ns32k-dependent routine 1815 and a general version. (My advice: use the general version!) 1816 */ 1817 1818static void 1819md_number_to_field (buf, val, field_ptr) 1820 register char *buf; 1821 register long val; 1822 register bit_fixS *field_ptr; 1823{ 1824 register unsigned long object; 1825 register unsigned long mask; 1826 /* define ENDIAN on a ns32k machine */ 1827#ifdef ENDIAN 1828 register unsigned long *mem_ptr; 1829#else 1830 register char *mem_ptr; 1831#endif 1832 if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max) 1833 { 1834#ifdef ENDIAN 1835 if (field_ptr->fx_bit_base) 1836 { /* override buf */ 1837 mem_ptr = (unsigned long *) field_ptr->fx_bit_base; 1838 } 1839 else 1840 { 1841 mem_ptr = (unsigned long *) buf; 1842 } 1843#else 1844 if (field_ptr->fx_bit_base) 1845 { /* override buf */ 1846 mem_ptr = (char *) field_ptr->fx_bit_base; 1847 } 1848 else 1849 { 1850 mem_ptr = buf; 1851 } 1852#endif 1853 mem_ptr += field_ptr->fx_bit_base_adj; 1854#ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */ 1855 object = *mem_ptr; /* get some bytes */ 1856#else /* OVE Goof! the machine is a m68k or dito */ 1857 /* That takes more byte fiddling */ 1858 object = 0; 1859 object |= mem_ptr[3] & 0xff; 1860 object <<= 8; 1861 object |= mem_ptr[2] & 0xff; 1862 object <<= 8; 1863 object |= mem_ptr[1] & 0xff; 1864 object <<= 8; 1865 object |= mem_ptr[0] & 0xff; 1866#endif 1867 mask = 0; 1868 mask |= (r_mask[field_ptr->fx_bit_offset]); 1869 mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]); 1870 object &= mask; 1871 val += field_ptr->fx_bit_add; 1872 object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff)); 1873#ifdef ENDIAN 1874 *mem_ptr = object; 1875#else 1876 mem_ptr[0] = (char) object; 1877 object >>= 8; 1878 mem_ptr[1] = (char) object; 1879 object >>= 8; 1880 mem_ptr[2] = (char) object; 1881 object >>= 8; 1882 mem_ptr[3] = (char) object; 1883#endif 1884 } 1885 else 1886 { 1887 as_warn ("Bit field out of range"); 1888 } 1889} 1890 1891int md_pcrel_adjust (fragS *fragP) 1892{ 1893 fragS *opcode_frag; 1894 int ret; 1895 int st = fragP->fr_subtype; 1896 unsigned int opcode_address; 1897 if ((st >> 2) == BRANCH && fragP->fr_pcrel_adjust == 0) { 1898 unsigned int offset; 1899 opcode_frag = ((struct opcode_location *) fragP->fr_opcode)->fragP; 1900 offset = ((struct opcode_location *) fragP->fr_opcode)->offset; 1901 opcode_address = offset + opcode_frag->fr_address; 1902 ret = fragP->fr_address - opcode_address; 1903 } 1904 else 1905 ret = fragP->fr_pcrel_adjust; 1906 return ret; 1907} 1908 1909int md_fix_pcrel_adjust (fixS *fixP) 1910{ 1911 fragS *fragP = fixP->fx_frag; 1912 fragS *opcode_frag; 1913 int ret; 1914 int st = fragP->fr_subtype; 1915 unsigned int opcode_address; 1916 if (fixP->fx_pcrel && fixP->fx_pcrel_adjust == 0) { 1917 unsigned int offset; 1918 opcode_frag = ((struct opcode_location *) fragP->fr_opcode)->fragP; 1919 offset = ((struct opcode_location *) fragP->fr_opcode)->offset; 1920 opcode_address = offset + opcode_frag->fr_address; 1921 ret = fragP->fr_address - opcode_address; 1922 } 1923 else 1924 ret = fixP->fx_pcrel_adjust; 1925 return ret; 1926} 1927 1928/* Apply a fixS (fixup of an instruction or data that we didn't have 1929 enough info to complete immediately) to the data in a frag. 1930 1931 On the ns32k, everything is in a different format, so we have broken 1932 out separate functions for each kind of thing we could be fixing. 1933 They all get called from here. */ 1934 1935#ifdef BFD_ASSEMBLER 1936int 1937md_apply_fix (fixP, valp) 1938 fixS *fixP; 1939 valueT *valp; 1940#else 1941void 1942md_apply_fix (fixP, val) 1943 fixS *fixP; 1944 long val; 1945#endif 1946{ 1947#ifdef BFD_ASSEMBLER 1948 long val = *valp; 1949#endif 1950 fragS *fragP = fixP->fx_frag; 1951 1952 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1953 1954 if (fixP->fx_bit_fixP) 1955 { /* Bitfields to fix, sigh */ 1956 md_number_to_field (buf, val, fixP->fx_bit_fixP); 1957 } 1958 else 1959 switch (fixP->fx_im_disp) 1960 { 1961 1962 case 0: /* Immediate field */ 1963 md_number_to_imm (buf, val, fixP->fx_size); 1964 break; 1965 1966 case 1: /* Displacement field */ 1967 /* Calculate offset */ 1968 { 1969 md_number_to_disp (buf, 1970 fixP->fx_pcrel ? val + md_fix_pcrel_adjust(fixP): val, 1971 fixP->fx_size); 1972 } 1973 break; 1974 1975 case 2: /* Pointer in a data object */ 1976 md_number_to_chars (buf, val, fixP->fx_size); 1977 break; 1978 } 1979#ifdef BSD_ASSEMBLER 1980 return 1; 1981#endif 1982} 1983 1984/* Convert a relaxed displacement to ditto in final output */ 1985 1986#ifndef BFD_ASSEMBLER 1987void 1988md_convert_frag (headers, sec, fragP) 1989 object_headers *headers; 1990 segT sec; 1991 register fragS *fragP; 1992#else 1993void 1994md_convert_frag (abfd, sec, fragP) 1995 bfd *abfd; 1996 segT sec; 1997 register fragS *fragP; 1998#endif 1999{ 2000 long disp; 2001 long ext = 0; 2002 2003 /* Address in gas core of the place to store the displacement. */ 2004 register char *buffer_address = fragP->fr_fix + fragP->fr_literal; 2005 /* Address in object code of the displacement. */ 2006 int object_address; 2007 2008 fragS *opcode_frag; 2009 2010 switch (fragP->fr_subtype) 2011 { 2012 case IND (BRANCH, BYTE): 2013 ext = 1; 2014 break; 2015 case IND (BRANCH, WORD): 2016 ext = 2; 2017 break; 2018 case IND (BRANCH, DOUBLE): 2019 ext = 4; 2020 break; 2021 } 2022 2023 if(ext == 0) 2024 return; 2025 2026 know (fragP->fr_symbol); 2027 2028 object_address = fragP->fr_fix + fragP->fr_address; 2029 /* The displacement of the address, from current location. */ 2030 disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address; 2031#ifdef BFD_ASSEMBLER 2032 disp += fragP->fr_symbol->sy_frag->fr_address; 2033#endif 2034 disp += md_pcrel_adjust(fragP); 2035 2036 md_number_to_disp (buffer_address, (long) disp, (int) ext); 2037 fragP->fr_fix += ext; 2038} 2039 2040/* This function returns the estimated size a variable object will occupy, 2041 one can say that we tries to guess the size of the objects before we 2042 actually know it */ 2043 2044int 2045md_estimate_size_before_relax (fragP, segment) 2046 register fragS *fragP; 2047 segT segment; 2048{ 2049 int old_fix; 2050 old_fix = fragP->fr_fix; 2051 switch (fragP->fr_subtype) 2052 { 2053 case IND (BRANCH, UNDEF): 2054 if (S_GET_SEGMENT (fragP->fr_symbol) == segment) 2055 { 2056 /* the symbol has been assigned a value */ 2057 fragP->fr_subtype = IND (BRANCH, BYTE); 2058 } 2059 else 2060 { 2061 /* we don't relax symbols defined in an other segment 2062 the thing to do is to assume the object will occupy 4 bytes */ 2063 fix_new_ns32k (fragP, 2064 (int) (fragP->fr_fix), 2065 4, 2066 fragP->fr_symbol, 2067 fragP->fr_offset, 2068 1, 2069 fragP->fr_pcrel_adjust, 2070 1, 2071 0, 2072 fragP->fr_bsr); /*sequent hack */ 2073 fragP->fr_fix += 4; 2074 /* fragP->fr_opcode[1]=0xff; */ 2075 frag_wane (fragP); 2076 break; 2077 } 2078 case IND (BRANCH, BYTE): 2079 fragP->fr_var += 1; 2080 break; 2081 default: 2082 break; 2083 } 2084 return fragP->fr_var + fragP->fr_fix - old_fix; 2085} 2086 2087int md_short_jump_size = 3; 2088int md_long_jump_size = 5; 2089const int md_reloc_size = 8; /* Size of relocation record */ 2090 2091void 2092md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) 2093 char *ptr; 2094 addressT from_addr, to_addr; 2095 fragS *frag; 2096 symbolS *to_symbol; 2097{ 2098 valueT offset; 2099 2100 offset = to_addr - from_addr; 2101 md_number_to_chars (ptr, (valueT) 0xEA, 1); 2102 md_number_to_disp (ptr + 1, (valueT) offset, 2); 2103} 2104 2105void 2106md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) 2107 char *ptr; 2108 addressT from_addr, to_addr; 2109 fragS *frag; 2110 symbolS *to_symbol; 2111{ 2112 valueT offset; 2113 2114 offset = to_addr - from_addr; 2115 md_number_to_chars (ptr, (valueT) 0xEA, 1); 2116 md_number_to_disp (ptr + 1, (valueT) offset, 4); 2117} 2118 2119CONST char *md_shortopts = "m:"; 2120struct option md_longopts[] = { 2121 {NULL, no_argument, NULL, 0} 2122}; 2123size_t md_longopts_size = sizeof(md_longopts); 2124 2125int 2126md_parse_option (c, arg) 2127 int c; 2128 char *arg; 2129{ 2130 switch (c) 2131 { 2132 case 'm': 2133 if (!strcmp (arg, "32032")) 2134 { 2135 cpureg = cpureg_032; 2136 mmureg = mmureg_032; 2137 } 2138 else if (!strcmp (arg, "32532")) 2139 { 2140 cpureg = cpureg_532; 2141 mmureg = mmureg_532; 2142 } 2143 else 2144 { 2145 as_bad ("invalid architecture option -m%s", arg); 2146 return 0; 2147 } 2148 break; 2149 2150 default: 2151 return 0; 2152 } 2153 2154 return 1; 2155} 2156 2157void 2158md_show_usage (stream) 2159 FILE *stream; 2160{ 2161 fprintf(stream, "\ 2162NS32K options:\n\ 2163-m32032 | -m32532 select variant of NS32K architecture\n"); 2164} 2165 2166 2167/* 2168 * bit_fix_new() 2169 * 2170 * Create a bit_fixS in obstack 'notes'. 2171 * This struct is used to profile the normal fix. If the bit_fixP is a 2172 * valid pointer (not NULL) the bit_fix data will be used to format the fix. 2173 */ 2174bit_fixS * 2175bit_fix_new (size, offset, min, max, add, base_type, base_adj) 2176 char size; /* Length of bitfield */ 2177 char offset; /* Bit offset to bitfield */ 2178 long min; /* Signextended min for bitfield */ 2179 long max; /* Signextended max for bitfield */ 2180 long add; /* Add mask, used for huffman prefix */ 2181 long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */ 2182 long base_adj; 2183{ 2184 register bit_fixS *bit_fixP; 2185 2186 bit_fixP = (bit_fixS *) obstack_alloc (¬es, sizeof (bit_fixS)); 2187 2188 bit_fixP->fx_bit_size = size; 2189 bit_fixP->fx_bit_offset = offset; 2190 bit_fixP->fx_bit_base = base_type; 2191 bit_fixP->fx_bit_base_adj = base_adj; 2192 bit_fixP->fx_bit_max = max; 2193 bit_fixP->fx_bit_min = min; 2194 bit_fixP->fx_bit_add = add; 2195 2196 return (bit_fixP); 2197} 2198 2199void 2200fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel, 2201 pcrel_adjust, im_disp, bit_fixP, bsr) 2202 fragS *frag; /* Which frag? */ 2203 int where; /* Where in that frag? */ 2204 int size; /* 1, 2 or 4 usually. */ 2205 symbolS *add_symbol; /* X_add_symbol. */ 2206 long offset; /* X_add_number. */ 2207 int pcrel; /* TRUE if PC-relative relocation. */ 2208 char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */ 2209 char im_disp; /* true if the value to write is a displacement */ 2210 bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */ 2211 char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */ 2212 2213{ 2214 fixS *fixP = fix_new (frag, where, size, add_symbol, 2215 offset, pcrel, 2216#ifdef BFD_ASSEMBLER 2217 bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp) 2218#else 2219 NO_RELOC 2220#endif 2221 ); 2222 2223 fixP->fx_pcrel_adjust = pcrel_adjust; 2224 fixP->fx_im_disp = im_disp; 2225 fixP->fx_bit_fixP = bit_fixP; 2226 fixP->fx_bsr = bsr; 2227} /* fix_new_ns32k() */ 2228 2229void 2230fix_new_ns32k_exp (frag, where, size, exp, pcrel, 2231 pcrel_adjust, im_disp, bit_fixP, bsr) 2232 fragS *frag; /* Which frag? */ 2233 int where; /* Where in that frag? */ 2234 int size; /* 1, 2 or 4 usually. */ 2235 expressionS *exp; /* Expression. */ 2236 int pcrel; /* TRUE if PC-relative relocation. */ 2237 char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */ 2238 char im_disp; /* true if the value to write is a displacement */ 2239 bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */ 2240 char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */ 2241{ 2242 fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel, 2243#ifdef BFD_ASSEMBLER 2244 bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp) 2245#else 2246 NO_RELOC 2247#endif 2248 ); 2249 2250 fixP->fx_pcrel_adjust = pcrel_adjust; 2251 fixP->fx_im_disp = im_disp; 2252 fixP->fx_bit_fixP = bit_fixP; 2253 fixP->fx_bsr = bsr; 2254} /* fix_new_ns32k() */ 2255 2256/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c. */ 2257 2258void 2259cons_fix_new_ns32k (frag, where, size, exp) 2260 fragS *frag; /* Which frag? */ 2261 int where; /* Where in that frag? */ 2262 int size; /* 1, 2 or 4 usually. */ 2263 expressionS *exp; /* Expression. */ 2264{ 2265 fix_new_ns32k_exp (frag, where, size, exp, 2266 0, 0, 2, 0, 0); 2267} 2268 2269/* We have no need to default values of symbols. */ 2270 2271symbolS * 2272md_undefined_symbol (name) 2273 char *name; 2274{ 2275 return 0; 2276} 2277 2278/* Round up a section size to the appropriate boundary. */ 2279valueT 2280md_section_align (segment, size) 2281 segT segment; 2282 valueT size; 2283{ 2284 return size; /* Byte alignment is fine */ 2285} 2286 2287/* Exactly what point is a PC-relative offset relative TO? 2288 On the National warts, they're relative to the address of the offset, 2289 with some funny adjustments in some circumstances during blue moons. 2290 (??? Is this right? FIXME-SOON) */ 2291long 2292md_pcrel_from (fixP) 2293 fixS *fixP; 2294{ 2295 long res; 2296 res = fixP->fx_where + fixP->fx_frag->fr_address; 2297#ifdef SEQUENT_COMPATABILITY 2298 if (fixP->fx_frag->fr_bsr) 2299 res += 0x12 /* FOO Kludge alert! */ 2300#endif 2301 return res; 2302} 2303 2304#ifdef BFD_ASSEMBLER 2305 2306arelent * 2307tc_gen_reloc (section, fixp) 2308 asection *section; 2309 fixS *fixp; 2310{ 2311 arelent *rel; 2312 bfd_reloc_code_real_type code; 2313 2314 code = reloc(fixp->fx_size, fixp->fx_pcrel, fixp->fx_im_disp); 2315 2316 rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent)); 2317 assert (rel != 0); 2318 rel->sym_ptr_ptr = &fixp->fx_addsy->bsym; 2319 rel->address = fixp->fx_frag->fr_address + fixp->fx_where; 2320 if (fixp->fx_pcrel) 2321 rel->addend = fixp->fx_addnumber; 2322 else 2323 rel->addend = 0; 2324 2325 rel->howto = bfd_reloc_type_lookup (stdoutput, code); 2326 if (!rel->howto) 2327 { 2328 const char *name; 2329 2330 name = S_GET_NAME (fixp->fx_addsy); 2331 if (name == NULL) 2332 name = "<unknown>"; 2333 as_fatal ("Cannot find relocation type for symbol %s, code %d", 2334 name, (int) code); 2335 } 2336 2337 return rel; 2338} 2339#else /* BFD_ASSEMBLER */ 2340 2341#ifdef OBJ_AOUT 2342void 2343tc_aout_fix_to_chars (where, fixP, segment_address_in_file) 2344 char *where; 2345 struct fix *fixP; 2346 relax_addressT segment_address_in_file; 2347{ 2348 /* 2349 * In: length of relocation (or of address) in chars: 1, 2 or 4. 2350 * Out: GNU LD relocation length code: 0, 1, or 2. 2351 */ 2352 2353 static unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2}; 2354 long r_symbolnum; 2355 2356 know (fixP->fx_addsy != NULL); 2357 2358 md_number_to_chars (where, 2359 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, 2360 4); 2361 2362 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) 2363 ? S_GET_TYPE (fixP->fx_addsy) 2364 : fixP->fx_addsy->sy_number); 2365 2366 md_number_to_chars (where + 4, 2367 ((long) (r_symbolnum) 2368 | (long) (fixP->fx_pcrel << 24) 2369 | (long) (nbytes_r_length[fixP->fx_size] << 25) 2370 | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27) 2371 | (long) (fixP->fx_bsr << 28) 2372 | (long) (fixP->fx_im_disp << 29)), 2373 4); 2374} 2375 2376#endif /* OBJ_AOUT */ 2377#endif /* BFD_ASSMEBLER */ 2378/* 2379 * Local Variables: 2380 * comment-column: 0 2381 * End: 2382 */ 2383 2384/* end of tc-ns32k.c */ 2385