1 1.1 christos /* tc-dlx.c -- Assemble for the DLX 2 1.10 christos Copyright (C) 2002-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GAS, the GNU Assembler. 5 1.1 christos 6 1.1 christos GAS is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3, or (at your option) 9 1.1 christos any later version. 10 1.1 christos 11 1.1 christos GAS is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free 18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 christos 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos /* Initially created by Kuang Hwa Lin, 3/20/2002. */ 22 1.1 christos 23 1.1 christos #include "as.h" 24 1.1 christos #include "safe-ctype.h" 25 1.1 christos #include "tc-dlx.h" 26 1.1 christos #include "opcode/dlx.h" 27 1.5 christos #include "elf/dlx.h" 28 1.5 christos #include "bfd/elf32-dlx.h" 29 1.1 christos 30 1.1 christos /* Make it easier to clone this machine desc into another one. */ 31 1.1 christos #define machine_opcode dlx_opcode 32 1.1 christos #define machine_opcodes dlx_opcodes 33 1.1 christos #define machine_ip dlx_ip 34 1.1 christos #define machine_it dlx_it 35 1.1 christos 36 1.1 christos #define NO_RELOC BFD_RELOC_NONE 37 1.1 christos #define RELOC_DLX_REL26 BFD_RELOC_DLX_JMP26 38 1.1 christos #define RELOC_DLX_16 BFD_RELOC_16 39 1.1 christos #define RELOC_DLX_REL16 BFD_RELOC_16_PCREL_S2 40 1.1 christos #define RELOC_DLX_HI16 BFD_RELOC_HI16_S 41 1.1 christos #define RELOC_DLX_LO16 BFD_RELOC_LO16 42 1.1 christos #define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT 43 1.1 christos #define RELOC_DLX_VTENTRY BFD_RELOC_VTABLE_ENTRY 44 1.1 christos 45 1.1 christos /* handle of the OPCODE hash table */ 46 1.8 christos static htab_t op_hash = NULL; 47 1.1 christos 48 1.1 christos struct machine_it 49 1.1 christos { 50 1.1 christos char *error; 51 1.1 christos unsigned long opcode; 52 1.1 christos struct nlist *nlistp; 53 1.1 christos expressionS exp; 54 1.1 christos int pcrel; 55 1.1 christos int size; 56 1.1 christos int reloc_offset; /* Offset of reloc within insn. */ 57 1.5 christos bfd_reloc_code_real_type reloc; 58 1.1 christos int HI; 59 1.1 christos int LO; 60 1.1 christos } 61 1.1 christos the_insn; 62 1.1 christos 63 1.1 christos /* This array holds the chars that always start a comment. If the 64 1.1 christos pre-processor is disabled, these aren't very useful. */ 65 1.1 christos const char comment_chars[] = ";"; 66 1.1 christos 67 1.1 christos /* This array holds the chars that only start a comment at the beginning of 68 1.1 christos a line. If the line seems to have the form '# 123 filename' 69 1.1 christos .line and .file directives will appear in the pre-processed output. */ 70 1.1 christos /* Note that input_file.c hand checks for '#' at the beginning of the 71 1.1 christos first line of the input file. This is because the compiler outputs 72 1.1 christos #NO_APP at the beginning of its output. */ 73 1.1 christos /* Also note that comments like this one will always work. */ 74 1.1 christos const char line_comment_chars[] = "#"; 75 1.1 christos 76 1.1 christos /* We needed an unused char for line separation to work around the 77 1.1 christos lack of macros, using sed and such. */ 78 1.1 christos const char line_separator_chars[] = "@"; 79 1.1 christos 80 1.1 christos /* Chars that can be used to separate mant from exp in floating point nums. */ 81 1.1 christos const char EXP_CHARS[] = "eE"; 82 1.1 christos 83 1.1 christos /* Chars that mean this number is a floating point constant. 84 1.1 christos As in 0f12.456 85 1.1 christos or 0d1.2345e12. */ 86 1.1 christos const char FLT_CHARS[] = "rRsSfFdDxXpP"; 87 1.1 christos 88 1.1 christos static void 89 1.5 christos insert_sreg (const char *regname, int regnum) 90 1.1 christos { 91 1.1 christos /* Must be large enough to hold the names of the special registers. */ 92 1.1 christos char buf[80]; 93 1.1 christos int i; 94 1.1 christos 95 1.8 christos symbol_table_insert (symbol_new (regname, reg_section, 96 1.8 christos &zero_address_frag, regnum)); 97 1.1 christos for (i = 0; regname[i]; i++) 98 1.1 christos buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i]; 99 1.1 christos buf[i] = '\0'; 100 1.1 christos 101 1.8 christos symbol_table_insert (symbol_new (buf, reg_section, 102 1.8 christos &zero_address_frag, regnum)); 103 1.1 christos } 104 1.1 christos 105 1.1 christos /* Install symbol definitions for assorted special registers. 106 1.1 christos See MIPS Assembly Language Programmer's Guide page 1-4 */ 107 1.1 christos 108 1.1 christos static void 109 1.1 christos define_some_regs (void) 110 1.1 christos { 111 1.1 christos /* Software representation. */ 112 1.1 christos insert_sreg ("zero", 0); 113 1.1 christos insert_sreg ("at", 1); 114 1.1 christos insert_sreg ("v0", 2); 115 1.1 christos insert_sreg ("v1", 3); 116 1.1 christos insert_sreg ("a0", 4); 117 1.1 christos insert_sreg ("a1", 5); 118 1.1 christos insert_sreg ("a2", 6); 119 1.1 christos insert_sreg ("a3", 7); 120 1.1 christos insert_sreg ("t0", 8); 121 1.1 christos insert_sreg ("t1", 9); 122 1.1 christos insert_sreg ("t2", 10); 123 1.1 christos insert_sreg ("t3", 11); 124 1.1 christos insert_sreg ("t4", 12); 125 1.1 christos insert_sreg ("t5", 13); 126 1.1 christos insert_sreg ("t6", 14); 127 1.1 christos insert_sreg ("t7", 15); 128 1.1 christos insert_sreg ("s0", 16); 129 1.1 christos insert_sreg ("s1", 17); 130 1.1 christos insert_sreg ("s2", 18); 131 1.1 christos insert_sreg ("s3", 19); 132 1.1 christos insert_sreg ("s4", 20); 133 1.1 christos insert_sreg ("s5", 21); 134 1.1 christos insert_sreg ("s6", 22); 135 1.1 christos insert_sreg ("s7", 23); 136 1.1 christos insert_sreg ("t8", 24); 137 1.1 christos insert_sreg ("t9", 25); 138 1.1 christos insert_sreg ("k0", 26); 139 1.1 christos insert_sreg ("k1", 27); 140 1.1 christos insert_sreg ("gp", 28); 141 1.1 christos insert_sreg ("sp", 29); 142 1.1 christos insert_sreg ("fp", 30); 143 1.1 christos insert_sreg ("ra", 31); 144 1.1 christos /* Special registers. */ 145 1.1 christos insert_sreg ("pc", 0); 146 1.1 christos insert_sreg ("npc", 1); 147 1.1 christos insert_sreg ("iad", 2); 148 1.1 christos } 149 1.1 christos 150 1.1 christos /* Subroutine check the string to match an register. */ 151 1.1 christos 152 1.1 christos static int 153 1.1 christos match_sft_register (char *name) 154 1.1 christos { 155 1.1 christos #define MAX_REG_NO 35 156 1.1 christos /* Currently we have 35 software registers defined - 157 1.1 christos we borrowed from MIPS. */ 158 1.5 christos static const char *soft_reg[] = 159 1.1 christos { 160 1.1 christos "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 161 1.1 christos "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", 162 1.1 christos "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1", 163 1.1 christos "gp", "sp", "fp", "ra", "pc", "npc", "iad", 164 1.1 christos "EndofTab" /* End of the Table indicator */ 165 1.1 christos }; 166 1.1 christos char low_name[21], *ptr; 167 1.1 christos int idx; 168 1.1 christos 169 1.1 christos for (ptr = name,idx = 0; *ptr != '\0'; ptr++) 170 1.1 christos low_name[idx++] = TOLOWER (*ptr); 171 1.1 christos 172 1.1 christos low_name[idx] = '\0'; 173 1.1 christos idx = 0; 174 1.1 christos 175 1.1 christos while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0])) 176 1.1 christos idx += 1; 177 1.1 christos 178 1.1 christos return idx < MAX_REG_NO; 179 1.1 christos } 180 1.1 christos 181 1.1 christos /* Subroutine check the string to match an register. */ 182 1.1 christos 183 1.1 christos static int 184 1.1 christos is_ldst_registers (char *name) 185 1.1 christos { 186 1.1 christos char *ptr = name; 187 1.1 christos 188 1.1 christos /* The first character of the register name got to be either %, $, r of R. */ 189 1.1 christos if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R') 190 1.10 christos && ISDIGIT (ptr[1])) 191 1.1 christos return 1; 192 1.1 christos 193 1.1 christos /* Now check the software register representation. */ 194 1.1 christos return match_sft_register (ptr); 195 1.1 christos } 196 1.1 christos 197 1.1 christos /* Subroutine of s_proc so targets can choose a different default prefix. 198 1.1 christos If DEFAULT_PREFIX is NULL, use the target's "leading char". */ 199 1.1 christos 200 1.1 christos static void 201 1.1 christos s_proc (int end_p) 202 1.1 christos { 203 1.1 christos /* Record the current function so that we can issue an error message for 204 1.1 christos misplaced .func,.endfunc, and also so that .endfunc needs no 205 1.1 christos arguments. */ 206 1.1 christos static char *current_name; 207 1.1 christos static char *current_label; 208 1.1 christos 209 1.1 christos if (end_p) 210 1.1 christos { 211 1.1 christos if (current_name == NULL) 212 1.1 christos { 213 1.1 christos as_bad (_("missing .proc")); 214 1.1 christos ignore_rest_of_line (); 215 1.1 christos return; 216 1.1 christos } 217 1.1 christos 218 1.1 christos current_name = current_label = NULL; 219 1.1 christos SKIP_WHITESPACE (); 220 1.10 christos while (!is_end_of_stmt (*input_line_pointer)) 221 1.1 christos input_line_pointer++; 222 1.1 christos } 223 1.1 christos else 224 1.1 christos { 225 1.1 christos char *name, *label; 226 1.1 christos char delim1, delim2; 227 1.1 christos 228 1.1 christos if (current_name != NULL) 229 1.1 christos { 230 1.1 christos as_bad (_(".endfunc missing for previous .proc")); 231 1.1 christos ignore_rest_of_line (); 232 1.1 christos return; 233 1.1 christos } 234 1.1 christos 235 1.3 christos delim1 = get_symbol_name (&name); 236 1.1 christos name = xstrdup (name); 237 1.10 christos restore_line_pointer (delim1); 238 1.10 christos SKIP_WHITESPACE (); 239 1.1 christos 240 1.1 christos if (*input_line_pointer != ',') 241 1.1 christos { 242 1.1 christos char leading_char = 0; 243 1.1 christos 244 1.1 christos leading_char = bfd_get_symbol_leading_char (stdoutput); 245 1.1 christos /* Missing entry point, use function's name with the leading 246 1.1 christos char prepended. */ 247 1.1 christos if (leading_char) 248 1.1 christos { 249 1.1 christos unsigned len = strlen (name) + 1; 250 1.5 christos label = XNEWVEC (char, len + 1); 251 1.1 christos label[0] = leading_char; 252 1.1 christos memcpy (label + 1, name, len); 253 1.1 christos } 254 1.1 christos else 255 1.1 christos label = name; 256 1.1 christos } 257 1.1 christos else 258 1.1 christos { 259 1.1 christos ++input_line_pointer; 260 1.1 christos SKIP_WHITESPACE (); 261 1.3 christos delim2 = get_symbol_name (&label); 262 1.1 christos label = xstrdup (label); 263 1.3 christos (void) restore_line_pointer (delim2); 264 1.1 christos } 265 1.1 christos 266 1.1 christos current_name = name; 267 1.1 christos current_label = label; 268 1.1 christos } 269 1.1 christos demand_empty_rest_of_line (); 270 1.1 christos } 271 1.1 christos 272 1.1 christos /* This function is called once, at assembler startup time. It should 273 1.1 christos set up all the tables, etc., that the MD part of the assembler will 274 1.1 christos need. */ 275 1.1 christos 276 1.1 christos void 277 1.1 christos md_begin (void) 278 1.1 christos { 279 1.1 christos unsigned int i; 280 1.1 christos 281 1.1 christos /* Create a new hash table. */ 282 1.8 christos op_hash = str_htab_create (); 283 1.1 christos 284 1.1 christos /* Hash up all the opcodes for fast use later. */ 285 1.1 christos for (i = 0; i < num_dlx_opcodes; i++) 286 1.1 christos { 287 1.1 christos const char *name = machine_opcodes[i].name; 288 1.8 christos if (str_hash_insert (op_hash, name, &machine_opcodes[i], 0) != NULL) 289 1.8 christos as_fatal (_("duplicate %s"), name); 290 1.1 christos } 291 1.1 christos 292 1.1 christos define_some_regs (); 293 1.1 christos } 294 1.1 christos 295 1.1 christos /* This function will check the opcode and return 1 if the opcode is one 296 1.1 christos of the load/store instruction, and it will fix the operand string to 297 1.1 christos the standard form so we can use the standard parse_operand routine. */ 298 1.1 christos 299 1.1 christos #define READ_OP 0x100 300 1.1 christos #define WRITE_OP 0x200 301 1.1 christos static char iBuf[81]; 302 1.1 christos 303 1.1 christos static char * 304 1.1 christos dlx_parse_loadop (char * str) 305 1.1 christos { 306 1.1 christos char *ptr = str; 307 1.1 christos int idx = 0; 308 1.1 christos 309 1.1 christos /* The last pair of ()/[] is the register, all other are the 310 1.1 christos reloc displacement, and if there is a register then it ought 311 1.1 christos to have a pair of ()/[] 312 1.1 christos This is not necessarily true, what if the load instruction come 313 1.1 christos without the register and with %hi/%lo modifier? */ 314 1.1 christos for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++) 315 1.1 christos ; 316 1.1 christos 317 1.1 christos if (idx == 72) 318 1.1 christos { 319 1.1 christos badoperand_load: 320 1.1 christos as_bad (_("Bad operand for a load instruction: <%s>"), str); 321 1.1 christos return NULL; 322 1.1 christos } 323 1.1 christos else 324 1.1 christos { 325 1.1 christos int i, pb = 0; 326 1.1 christos int m2 = 0; 327 1.1 christos char rs1[7], rd[7], endm, match = '0'; 328 1.1 christos char imm[72]; 329 1.1 christos 330 1.1 christos idx -= 1; 331 1.1 christos switch (str[idx]) 332 1.1 christos { 333 1.1 christos case ')': 334 1.1 christos match = '('; 335 1.1 christos endm = ')'; 336 1.1 christos break; 337 1.1 christos case ']': 338 1.1 christos match = '['; 339 1.1 christos endm = ']'; 340 1.1 christos break; 341 1.1 christos default: 342 1.1 christos /* No register indicated, fill in zero. */ 343 1.1 christos rs1[0] = 'r'; 344 1.1 christos rs1[1] = '0'; 345 1.1 christos rs1[2] = '\0'; 346 1.1 christos match = 0; 347 1.1 christos endm = 0; 348 1.1 christos m2 = 1; 349 1.1 christos } 350 1.1 christos 351 1.1 christos if (!m2) 352 1.1 christos { 353 1.1 christos /* Searching for (/[ which will match the ]/). */ 354 1.1 christos for (pb = idx - 1; str[pb] != match; pb -= 1) 355 1.1 christos /* Match can only be either '[' or '(', if it is 356 1.1 christos '(' then this can be a normal expression, we'll treat 357 1.1 christos it as an operand. */ 358 1.1 christos if (str[pb] == endm || pb < (idx - 5)) 359 1.1 christos goto load_no_rs1; 360 1.1 christos pb += 1; 361 1.1 christos 362 1.1 christos for (i = 0; (pb + i) < idx; i++) 363 1.1 christos rs1[i] = str[pb+i]; 364 1.1 christos 365 1.1 christos rs1[i] = '\0'; 366 1.1 christos 367 1.1 christos if (is_ldst_registers (& rs1[0])) 368 1.1 christos /* Point to the last character of the imm. */ 369 1.1 christos pb -= 1; 370 1.1 christos else 371 1.1 christos { 372 1.1 christos load_no_rs1: 373 1.1 christos if (match == '[') 374 1.1 christos goto badoperand_load; 375 1.1 christos /* No register indicated, fill in zero and restore the imm. */ 376 1.1 christos rs1[0] = 'r'; 377 1.1 christos rs1[1] = '0'; 378 1.1 christos rs1[2] = '\0'; 379 1.1 christos m2 = 1; 380 1.1 christos } 381 1.1 christos } 382 1.1 christos 383 1.1 christos /* Duplicate the first register. */ 384 1.1 christos for (i = 0; i < 7 && str[i] != ','; i++) 385 1.1 christos rd[i] = ptr[i]; 386 1.1 christos 387 1.1 christos if (str[i] != ',') 388 1.1 christos goto badoperand_load; 389 1.1 christos else 390 1.1 christos rd[i] = '\0'; 391 1.1 christos 392 1.1 christos /* Copy the immd. */ 393 1.1 christos if (m2) 394 1.1 christos /* Put the '\0' back in. */ 395 1.1 christos pb = idx + 1; 396 1.1 christos 397 1.1 christos for (i++, m2 = 0; i < pb; m2++,i++) 398 1.1 christos imm[m2] = ptr[i]; 399 1.1 christos 400 1.1 christos imm[m2] = '\0'; 401 1.1 christos 402 1.1 christos /* Assemble the instruction to gas internal format. */ 403 1.1 christos for (i = 0; rd[i] != '\0'; i++) 404 1.1 christos iBuf[i] = rd[i]; 405 1.1 christos 406 1.1 christos iBuf[i++] = ','; 407 1.1 christos 408 1.1 christos for (pb = 0 ; rs1[pb] != '\0'; i++, pb++) 409 1.1 christos iBuf[i] = rs1[pb]; 410 1.1 christos 411 1.1 christos iBuf[i++] = ','; 412 1.1 christos 413 1.1 christos for (pb = 0; imm[pb] != '\0'; i++, pb++) 414 1.1 christos iBuf[i] = imm[pb]; 415 1.1 christos 416 1.1 christos iBuf[i] = '\0'; 417 1.1 christos return iBuf; 418 1.1 christos } 419 1.1 christos } 420 1.1 christos 421 1.1 christos static char * 422 1.1 christos dlx_parse_storeop (char * str) 423 1.1 christos { 424 1.1 christos char *ptr = str; 425 1.1 christos int idx = 0; 426 1.1 christos 427 1.1 christos /* Search for the ','. */ 428 1.1 christos for (idx = 0; idx < 72 && ptr[idx] != ','; idx++) 429 1.1 christos ; 430 1.1 christos 431 1.1 christos if (idx == 72) 432 1.1 christos { 433 1.1 christos badoperand_store: 434 1.1 christos as_bad (_("Bad operand for a store instruction: <%s>"), str); 435 1.1 christos return NULL; 436 1.1 christos } 437 1.1 christos else 438 1.1 christos { 439 1.1 christos /* idx now points to the ','. */ 440 1.1 christos int i, pb = 0; 441 1.1 christos int comma = idx; 442 1.1 christos int m2 = 0; 443 1.1 christos char rs1[7], rd[7], endm, match = '0'; 444 1.1 christos char imm[72]; 445 1.1 christos 446 1.1 christos /* Now parse the '(' and ')', and make idx point to ')'. */ 447 1.1 christos idx -= 1; 448 1.1 christos switch (str[idx]) 449 1.1 christos { 450 1.1 christos case ')': 451 1.1 christos match = '('; 452 1.1 christos endm = ')'; 453 1.1 christos break; 454 1.1 christos case ']': 455 1.1 christos match = '['; 456 1.1 christos endm = ']'; 457 1.1 christos break; 458 1.1 christos default: 459 1.1 christos /* No register indicated, fill in zero. */ 460 1.1 christos rs1[0] = 'r'; 461 1.1 christos rs1[1] = '0'; 462 1.1 christos rs1[2] = '\0'; 463 1.1 christos match = 0; 464 1.1 christos endm = 0; 465 1.1 christos m2 = 1; 466 1.1 christos } 467 1.1 christos 468 1.1 christos if (!m2) 469 1.1 christos { 470 1.1 christos /* Searching for (/[ which will match the ]/). */ 471 1.1 christos for (pb = idx - 1; str[pb] != match; pb -= 1) 472 1.1 christos if (pb < (idx - 5) || str[pb] == endm) 473 1.1 christos goto store_no_rs1; 474 1.1 christos pb += 1; 475 1.1 christos 476 1.1 christos for (i = 0; (pb + i) < idx; i++) 477 1.1 christos rs1[i] = str[pb + i]; 478 1.1 christos 479 1.1 christos rs1[i] = '\0'; 480 1.1 christos 481 1.1 christos if (is_ldst_registers (& rs1[0])) 482 1.1 christos /* Point to the last character of the imm. */ 483 1.1 christos pb -= 1; 484 1.1 christos else 485 1.1 christos { 486 1.1 christos store_no_rs1: 487 1.1 christos if (match == '[') 488 1.1 christos goto badoperand_store; 489 1.1 christos 490 1.1 christos /* No register indicated, fill in zero and restore the imm. */ 491 1.1 christos rs1[0] = 'r'; 492 1.1 christos rs1[1] = '0'; 493 1.1 christos rs1[2] = '\0'; 494 1.1 christos pb = comma; 495 1.1 christos } 496 1.1 christos } 497 1.1 christos else 498 1.1 christos /* No register was specified. */ 499 1.1 christos pb = comma; 500 1.1 christos 501 1.1 christos /* Duplicate the first register. */ 502 1.10 christos for (i = comma + 1; is_whitespace (str[i]); i++) 503 1.1 christos ; 504 1.1 christos 505 1.1 christos for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++) 506 1.1 christos { 507 1.10 christos if (!is_whitespace (str[i])) 508 1.1 christos rd[m2] = str[i]; 509 1.1 christos else 510 1.1 christos goto badoperand_store; 511 1.1 christos } 512 1.1 christos 513 1.1 christos if (str[i] != '\0') 514 1.1 christos goto badoperand_store; 515 1.1 christos else 516 1.1 christos rd[m2] = '\0'; 517 1.1 christos 518 1.1 christos /* Copy the immd. */ 519 1.1 christos for (i = 0; i < pb; i++) 520 1.1 christos imm[i] = ptr[i]; 521 1.1 christos 522 1.1 christos imm[i] = '\0'; 523 1.1 christos 524 1.1 christos /* Assemble the instruction to gas internal format. */ 525 1.1 christos for (i = 0; rd[i] != '\0'; i++) 526 1.1 christos iBuf[i] = rd[i]; 527 1.1 christos iBuf[i++] = ','; 528 1.1 christos for (pb = 0 ; rs1[pb] != '\0'; i++, pb++) 529 1.1 christos iBuf[i] = rs1[pb]; 530 1.1 christos iBuf[i++] = ','; 531 1.1 christos for (pb = 0; imm[pb] != '\0'; i++, pb++) 532 1.1 christos iBuf[i] = imm[pb]; 533 1.1 christos iBuf[i] = '\0'; 534 1.1 christos return iBuf; 535 1.1 christos } 536 1.1 christos } 537 1.1 christos 538 1.1 christos static char * 539 1.1 christos fix_ld_st_operand (unsigned long opcode, char* str) 540 1.1 christos { 541 1.1 christos /* Check the opcode. */ 542 1.10 christos switch (opcode) 543 1.1 christos { 544 1.1 christos case LBOP: 545 1.1 christos case LBUOP: 546 1.1 christos case LSBUOP: 547 1.1 christos case LHOP: 548 1.1 christos case LHUOP: 549 1.1 christos case LSHUOP: 550 1.1 christos case LWOP: 551 1.1 christos case LSWOP: 552 1.1 christos return dlx_parse_loadop (str); 553 1.1 christos case SBOP: 554 1.1 christos case SHOP: 555 1.1 christos case SWOP: 556 1.1 christos return dlx_parse_storeop (str); 557 1.1 christos default: 558 1.1 christos return str; 559 1.1 christos } 560 1.1 christos } 561 1.1 christos 562 1.1 christos static int 563 1.1 christos hilo_modifier_ok (char *s) 564 1.1 christos { 565 1.1 christos char *ptr = s; 566 1.1 christos int idx, count = 1; 567 1.1 christos 568 1.1 christos if (*ptr != '(') 569 1.1 christos return 1; 570 1.1 christos 571 1.1 christos for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1) 572 1.1 christos { 573 1.1 christos if (count == 0) 574 1.1 christos return count; 575 1.1 christos 576 1.1 christos if (ptr[idx] == '(') 577 1.1 christos count += 1; 578 1.1 christos 579 1.1 christos if (ptr[idx] == ')') 580 1.1 christos count -= 1; 581 1.1 christos } 582 1.1 christos 583 1.1 christos return (count == 0) ? 1:0; 584 1.1 christos } 585 1.1 christos 586 1.1 christos static char * 587 1.1 christos parse_operand (char *s, expressionS *operandp) 588 1.1 christos { 589 1.1 christos char *save = input_line_pointer; 590 1.1 christos char *new_pos; 591 1.1 christos 592 1.1 christos the_insn.HI = the_insn.LO = 0; 593 1.1 christos 594 1.1 christos /* Search for %hi and %lo, make a mark and skip it. */ 595 1.8 christos if (startswith (s, "%hi")) 596 1.1 christos { 597 1.1 christos s += 3; 598 1.1 christos the_insn.HI = 1; 599 1.1 christos } 600 1.1 christos else 601 1.1 christos { 602 1.8 christos if (startswith (s, "%lo")) 603 1.1 christos { 604 1.1 christos s += 3; 605 1.1 christos the_insn.LO = 1; 606 1.1 christos } 607 1.1 christos else 608 1.1 christos the_insn.LO = 0; 609 1.1 christos } 610 1.1 christos 611 1.1 christos if (the_insn.HI || the_insn.LO) 612 1.1 christos { 613 1.1 christos if (!hilo_modifier_ok (s)) 614 1.1 christos as_bad (_("Expression Error for operand modifier %%hi/%%lo\n")); 615 1.1 christos } 616 1.1 christos 617 1.1 christos /* Check for the % and $ register representation */ 618 1.1 christos if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R') 619 1.10 christos && ISDIGIT (s[1])) 620 1.1 christos { 621 1.1 christos /* We have a numeric register expression. No biggy. */ 622 1.1 christos s += 1; 623 1.1 christos input_line_pointer = s; 624 1.1 christos (void) expression (operandp); 625 1.1 christos if (operandp->X_op != O_constant 626 1.1 christos || operandp->X_add_number > 31) 627 1.1 christos as_bad (_("Invalid expression after %%%%\n")); 628 1.1 christos operandp->X_op = O_register; 629 1.1 christos } 630 1.1 christos else 631 1.1 christos { 632 1.1 christos /* Normal operand parsing. */ 633 1.1 christos input_line_pointer = s; 634 1.1 christos (void) expression (operandp); 635 1.9 christos resolve_register (operandp); 636 1.1 christos } 637 1.1 christos 638 1.1 christos new_pos = input_line_pointer; 639 1.1 christos input_line_pointer = save; 640 1.1 christos return new_pos; 641 1.1 christos } 642 1.1 christos 643 1.1 christos /* Instruction parsing. Takes a string containing the opcode. 644 1.1 christos Operands are at input_line_pointer. Output is in the_insn. 645 1.1 christos Warnings or errors are generated. */ 646 1.1 christos 647 1.1 christos static void 648 1.1 christos machine_ip (char *str) 649 1.1 christos { 650 1.1 christos char *s; 651 1.1 christos const char *args; 652 1.1 christos struct machine_opcode *insn; 653 1.1 christos unsigned long opcode; 654 1.1 christos expressionS the_operand; 655 1.1 christos expressionS *operand = &the_operand; 656 1.1 christos unsigned int reg, reg_shift = 0; 657 1.1 christos 658 1.3 christos memset (&the_insn, '\0', sizeof (the_insn)); 659 1.3 christos the_insn.reloc = NO_RELOC; 660 1.3 christos 661 1.1 christos /* Fixup the opcode string to all lower cases, and also 662 1.1 christos allow numerical digits. */ 663 1.1 christos s = str; 664 1.1 christos 665 1.1 christos if (ISALPHA (*s)) 666 1.1 christos for (; ISALNUM (*s); ++s) 667 1.1 christos if (ISUPPER (*s)) 668 1.1 christos *s = TOLOWER (*s); 669 1.1 christos 670 1.1 christos switch (*s) 671 1.1 christos { 672 1.1 christos case '\0': 673 1.1 christos break; 674 1.1 christos 675 1.1 christos default: 676 1.10 christos if (is_whitespace (*s)) 677 1.10 christos { 678 1.10 christos *s++ = '\0'; 679 1.10 christos break; 680 1.10 christos } 681 1.1 christos as_bad (_("Unknown opcode: `%s'"), str); 682 1.1 christos return; 683 1.1 christos } 684 1.1 christos 685 1.3 christos /* Hash the opcode, insn will have the string from opcode table. */ 686 1.10 christos if ((insn = str_hash_find (op_hash, str)) == NULL) 687 1.1 christos { 688 1.1 christos /* Handle the ret and return macro here. */ 689 1.1 christos if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0)) 690 1.3 christos the_insn.opcode = JROP | 0x03e00000; /* 0x03e00000 = r31 << 21 */ 691 1.1 christos else 692 1.1 christos as_bad (_("Unknown opcode `%s'."), str); 693 1.1 christos 694 1.1 christos return; 695 1.1 christos } 696 1.1 christos 697 1.1 christos opcode = insn->opcode; 698 1.1 christos 699 1.1 christos /* Set the sip reloc HI16 flag. */ 700 1.1 christos if (!set_dlx_skip_hi16_flag (1)) 701 1.1 christos as_bad (_("Can not set dlx_skip_hi16_flag")); 702 1.1 christos 703 1.1 christos /* Fix the operand string if it is one of load store instructions. */ 704 1.1 christos s = fix_ld_st_operand (opcode, s); 705 1.1 christos 706 1.1 christos /* Build the opcode, checking as we go to make sure that the 707 1.1 christos operands match. 708 1.1 christos If an operand matches, we modify the_insn or opcode appropriately, 709 1.1 christos and do a "continue". If an operand fails to match, we "break". */ 710 1.1 christos if (insn->args[0] != '\0' && insn->args[0] != 'N') 711 1.1 christos { 712 1.1 christos /* Prime the pump. */ 713 1.1 christos if (*s == '\0') 714 1.1 christos { 715 1.1 christos as_bad (_("Missing arguments for opcode <%s>."), str); 716 1.1 christos return; 717 1.1 christos } 718 1.1 christos else 719 1.1 christos s = parse_operand (s, operand); 720 1.1 christos } 721 1.1 christos else if (insn->args[0] == 'N') 722 1.1 christos { 723 1.1 christos /* Clean up the insn and done! */ 724 1.1 christos the_insn.opcode = opcode; 725 1.1 christos return; 726 1.1 christos } 727 1.1 christos 728 1.1 christos /* Parse through the args (this is from opcode table), *s point to 729 1.1 christos the current character of the instruction stream. */ 730 1.1 christos for (args = insn->args;; ++args) 731 1.1 christos { 732 1.1 christos switch (*args) 733 1.1 christos { 734 1.1 christos /* End of Line. */ 735 1.1 christos case '\0': 736 1.1 christos /* End of args. */ 737 1.1 christos if (*s == '\0') 738 1.1 christos { 739 1.1 christos /* We are truly done. */ 740 1.1 christos the_insn.opcode = opcode; 741 1.1 christos /* Clean up the HI and LO mark. */ 742 1.1 christos the_insn.HI = 0; 743 1.1 christos the_insn.LO = 0; 744 1.1 christos return; 745 1.1 christos } 746 1.1 christos 747 1.1 christos the_insn.HI = 0; 748 1.1 christos the_insn.LO = 0; 749 1.1 christos as_bad (_("Too many operands: %s"), s); 750 1.1 christos break; 751 1.1 christos 752 1.1 christos /* ',' Args separator */ 753 1.1 christos case ',': 754 1.1 christos /* Must match a comma. */ 755 1.1 christos if (*s++ == ',') 756 1.1 christos { 757 1.1 christos /* Parse next operand. */ 758 1.1 christos s = parse_operand (s, operand); 759 1.1 christos continue; 760 1.1 christos } 761 1.1 christos break; 762 1.1 christos 763 1.1 christos /* It can be a 'a' register or 'i' operand. */ 764 1.1 christos case 'P': 765 1.1 christos /* Macro move operand/reg. */ 766 1.1 christos if (operand->X_op == O_register) 767 1.1 christos { 768 1.6 christos /* It's a register. */ 769 1.1 christos reg_shift = 21; 770 1.1 christos goto general_reg; 771 1.1 christos } 772 1.6 christos /* Fall through. */ 773 1.1 christos 774 1.1 christos /* The immediate 16 bits literal, bit 0-15. */ 775 1.1 christos case 'i': 776 1.1 christos /* offset, unsigned. */ 777 1.1 christos case 'I': 778 1.1 christos /* offset, signed. */ 779 1.1 christos if (operand->X_op == O_constant) 780 1.1 christos { 781 1.1 christos if (the_insn.HI) 782 1.1 christos operand->X_add_number >>= 16; 783 1.1 christos 784 1.1 christos opcode |= operand->X_add_number & 0xFFFF; 785 1.1 christos 786 1.1 christos if (the_insn.HI && the_insn.LO) 787 1.1 christos as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s); 788 1.1 christos else 789 1.1 christos { 790 1.1 christos the_insn.HI = 0; 791 1.1 christos the_insn.LO = 0; 792 1.1 christos } 793 1.1 christos continue; 794 1.1 christos } 795 1.1 christos 796 1.3 christos the_insn.reloc = (the_insn.HI) ? RELOC_DLX_HI16 797 1.1 christos : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16); 798 1.1 christos the_insn.reloc_offset = 2; 799 1.1 christos the_insn.size = 2; 800 1.1 christos the_insn.pcrel = 0; 801 1.1 christos the_insn.exp = * operand; 802 1.1 christos the_insn.HI = 0; 803 1.1 christos the_insn.LO = 0; 804 1.1 christos continue; 805 1.1 christos 806 1.1 christos case 'd': 807 1.1 christos /* offset, signed. */ 808 1.1 christos if (operand->X_op == O_constant) 809 1.1 christos { 810 1.1 christos opcode |= operand->X_add_number & 0xFFFF; 811 1.1 christos continue; 812 1.1 christos } 813 1.1 christos the_insn.reloc = RELOC_DLX_REL16; 814 1.1 christos the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */ 815 1.1 christos the_insn.size = 4; 816 1.1 christos the_insn.pcrel = 1; 817 1.1 christos the_insn.exp = *operand; 818 1.1 christos continue; 819 1.1 christos 820 1.1 christos /* The immediate 26 bits literal, bit 0-25. */ 821 1.1 christos case 'D': 822 1.1 christos /* offset, signed. */ 823 1.1 christos if (operand->X_op == O_constant) 824 1.1 christos { 825 1.1 christos opcode |= operand->X_add_number & 0x3FFFFFF; 826 1.1 christos continue; 827 1.1 christos } 828 1.1 christos the_insn.reloc = RELOC_DLX_REL26; 829 1.1 christos the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */ 830 1.1 christos the_insn.size = 4; 831 1.1 christos the_insn.pcrel = 1; 832 1.1 christos the_insn.exp = *operand; 833 1.1 christos continue; 834 1.1 christos 835 1.1 christos /* Type 'a' Register. */ 836 1.1 christos case 'a': 837 1.1 christos /* A general register at bits 21-25, rs1. */ 838 1.1 christos reg_shift = 21; 839 1.1 christos goto general_reg; 840 1.1 christos 841 1.1 christos /* Type 'b' Register. */ 842 1.1 christos case 'b': 843 1.1 christos /* A general register at bits 16-20, rs2/rd. */ 844 1.1 christos reg_shift = 16; 845 1.1 christos goto general_reg; 846 1.1 christos 847 1.1 christos /* Type 'c' Register. */ 848 1.1 christos case 'c': 849 1.1 christos /* A general register at bits 11-15, rd. */ 850 1.1 christos reg_shift = 11; 851 1.1 christos 852 1.1 christos general_reg: 853 1.1 christos know (operand->X_add_symbol == 0); 854 1.1 christos know (operand->X_op_symbol == 0); 855 1.1 christos reg = operand->X_add_number; 856 1.1 christos if (reg & 0xffffffe0) 857 1.1 christos as_fatal (_("failed regnum sanity check.")); 858 1.1 christos else 859 1.1 christos /* Got the register, now figure out where it goes in the opcode. */ 860 1.1 christos opcode |= reg << reg_shift; 861 1.1 christos 862 1.1 christos switch (*args) 863 1.1 christos { 864 1.1 christos case 'a': 865 1.1 christos case 'b': 866 1.1 christos case 'c': 867 1.1 christos case 'P': 868 1.1 christos continue; 869 1.1 christos } 870 1.1 christos as_fatal (_("failed general register sanity check.")); 871 1.1 christos break; 872 1.1 christos 873 1.1 christos default: 874 1.1 christos BAD_CASE (*args); 875 1.1 christos } 876 1.1 christos 877 1.1 christos /* Types or values of args don't match. */ 878 1.1 christos as_bad (_("Invalid operands")); 879 1.1 christos return; 880 1.1 christos } 881 1.1 christos } 882 1.1 christos 883 1.1 christos /* Assemble a single instruction. Its label has already been handled 884 1.1 christos by the generic front end. We just parse opcode and operands, and 885 1.1 christos produce the bytes of data and relocation. */ 886 1.1 christos 887 1.1 christos void 888 1.1 christos md_assemble (char *str) 889 1.1 christos { 890 1.1 christos char *toP; 891 1.1 christos fixS *fixP; 892 1.1 christos bit_fixS *bitP; 893 1.1 christos 894 1.1 christos know (str); 895 1.1 christos machine_ip (str); 896 1.1 christos toP = frag_more (4); 897 1.1 christos dwarf2_emit_insn (4); 898 1.1 christos 899 1.1 christos /* Put out the opcode. */ 900 1.1 christos md_number_to_chars (toP, the_insn.opcode, 4); 901 1.1 christos 902 1.1 christos /* Put out the symbol-dependent stuff. */ 903 1.1 christos if (the_insn.reloc != NO_RELOC) 904 1.1 christos { 905 1.1 christos fixP = fix_new_exp (frag_now, 906 1.1 christos (toP - frag_now->fr_literal + the_insn.reloc_offset), 907 1.1 christos the_insn.size, & the_insn.exp, the_insn.pcrel, 908 1.1 christos the_insn.reloc); 909 1.1 christos 910 1.1 christos /* Turn off complaints that the addend is 911 1.1 christos too large for things like foo+100000@ha. */ 912 1.1 christos switch (the_insn.reloc) 913 1.1 christos { 914 1.1 christos case RELOC_DLX_HI16: 915 1.1 christos case RELOC_DLX_LO16: 916 1.1 christos fixP->fx_no_overflow = 1; 917 1.1 christos break; 918 1.1 christos default: 919 1.1 christos break; 920 1.1 christos } 921 1.1 christos 922 1.1 christos switch (fixP->fx_r_type) 923 1.1 christos { 924 1.1 christos case RELOC_DLX_REL26: 925 1.5 christos bitP = XNEW (bit_fixS); 926 1.1 christos bitP->fx_bit_size = 26; 927 1.1 christos bitP->fx_bit_offset = 25; 928 1.1 christos bitP->fx_bit_base = the_insn.opcode & 0xFC000000; 929 1.1 christos bitP->fx_bit_base_adj = 0; 930 1.1 christos bitP->fx_bit_max = 0; 931 1.1 christos bitP->fx_bit_min = 0; 932 1.1 christos bitP->fx_bit_add = 0x03FFFFFF; 933 1.1 christos fixP->fx_bit_fixP = bitP; 934 1.1 christos break; 935 1.1 christos case RELOC_DLX_LO16: 936 1.1 christos case RELOC_DLX_REL16: 937 1.5 christos bitP = XNEW (bit_fixS); 938 1.1 christos bitP->fx_bit_size = 16; 939 1.1 christos bitP->fx_bit_offset = 15; 940 1.1 christos bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000; 941 1.1 christos bitP->fx_bit_base_adj = 0; 942 1.1 christos bitP->fx_bit_max = 0; 943 1.1 christos bitP->fx_bit_min = 0; 944 1.1 christos bitP->fx_bit_add = 0x0000FFFF; 945 1.1 christos fixP->fx_bit_fixP = bitP; 946 1.1 christos break; 947 1.1 christos case RELOC_DLX_HI16: 948 1.5 christos bitP = XNEW (bit_fixS); 949 1.1 christos bitP->fx_bit_size = 16; 950 1.1 christos bitP->fx_bit_offset = 15; 951 1.1 christos bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000; 952 1.1 christos bitP->fx_bit_base_adj = 0; 953 1.1 christos bitP->fx_bit_max = 0; 954 1.1 christos bitP->fx_bit_min = 0; 955 1.1 christos bitP->fx_bit_add = 0x0000FFFF; 956 1.1 christos fixP->fx_bit_fixP = bitP; 957 1.1 christos break; 958 1.1 christos default: 959 1.1 christos fixP->fx_bit_fixP = NULL; 960 1.1 christos break; 961 1.1 christos } 962 1.1 christos } 963 1.1 christos } 964 1.1 christos 965 1.1 christos /* This is identical to the md_atof in m68k.c. I think this is right, 966 1.1 christos but I'm not sure. Dlx will not use it anyway, so I just leave it 967 1.1 christos here for now. */ 968 1.1 christos 969 1.5 christos const char * 970 1.1 christos md_atof (int type, char *litP, int *sizeP) 971 1.1 christos { 972 1.8 christos return ieee_md_atof (type, litP, sizeP, true); 973 1.1 christos } 974 1.1 christos 975 1.1 christos /* Write out big-endian. */ 976 1.1 christos void 977 1.1 christos md_number_to_chars (char *buf, valueT val, int n) 978 1.1 christos { 979 1.1 christos number_to_chars_bigendian (buf, val, n); 980 1.1 christos } 981 1.1 christos 982 1.8 christos bool 983 1.1 christos md_dlx_fix_adjustable (fixS *fixP) 984 1.1 christos { 985 1.1 christos /* We need the symbol name for the VTABLE entries. */ 986 1.1 christos return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT 987 1.1 christos && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY); 988 1.1 christos } 989 1.1 christos 990 1.1 christos void 991 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 992 1.1 christos { 993 1.1 christos long val = *valP; 994 1.1 christos char *place = fixP->fx_where + fixP->fx_frag->fr_literal; 995 1.1 christos 996 1.1 christos switch (fixP->fx_r_type) 997 1.1 christos { 998 1.1 christos case RELOC_DLX_LO16: 999 1.1 christos case RELOC_DLX_REL16: 1000 1.1 christos if (fixP->fx_bit_fixP != NULL) 1001 1.1 christos { 1002 1.1 christos val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base; 1003 1.1 christos free (fixP->fx_bit_fixP); 1004 1.1 christos fixP->fx_bit_fixP = NULL; 1005 1.1 christos } 1006 1.1 christos break; 1007 1.1 christos 1008 1.1 christos case RELOC_DLX_HI16: 1009 1.1 christos if (fixP->fx_bit_fixP != NULL) 1010 1.1 christos { 1011 1.1 christos val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base; 1012 1.1 christos free (fixP->fx_bit_fixP); 1013 1.1 christos fixP->fx_bit_fixP = NULL; 1014 1.1 christos } 1015 1.1 christos break; 1016 1.1 christos 1017 1.1 christos case RELOC_DLX_REL26: 1018 1.1 christos if (fixP->fx_bit_fixP != NULL) 1019 1.1 christos { 1020 1.1 christos val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base; 1021 1.1 christos free (fixP->fx_bit_fixP); 1022 1.1 christos fixP->fx_bit_fixP = NULL; 1023 1.1 christos } 1024 1.1 christos break; 1025 1.1 christos 1026 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 1027 1.1 christos /* This borrowed from tc-ppc.c on a whim. */ 1028 1.1 christos fixP->fx_done = 0; 1029 1.1 christos if (fixP->fx_addsy 1030 1.1 christos && !S_IS_DEFINED (fixP->fx_addsy) 1031 1.1 christos && !S_IS_WEAK (fixP->fx_addsy)) 1032 1.1 christos S_SET_WEAK (fixP->fx_addsy); 1033 1.1 christos return; 1034 1.1 christos 1035 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 1036 1.1 christos fixP->fx_done = 0; 1037 1.1 christos return; 1038 1.1 christos 1039 1.1 christos default: 1040 1.1 christos break; 1041 1.1 christos } 1042 1.1 christos 1043 1.1 christos number_to_chars_bigendian (place, val, fixP->fx_size); 1044 1.1 christos if (fixP->fx_addsy == NULL) 1045 1.1 christos fixP->fx_done = 1; 1046 1.7 christos if (fixP->fx_bit_fixP != NULL) 1047 1.7 christos fixP->fx_no_overflow = 1; 1048 1.1 christos } 1049 1.1 christos 1050 1.10 christos const char md_shortopts[] = ""; 1051 1.1 christos 1052 1.10 christos const struct option md_longopts[] = 1053 1.1 christos { 1054 1.1 christos {NULL, no_argument, NULL, 0} 1055 1.1 christos }; 1056 1.1 christos 1057 1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 1058 1.1 christos 1059 1.1 christos int 1060 1.1 christos md_parse_option (int c ATTRIBUTE_UNUSED, 1061 1.5 christos const char *arg ATTRIBUTE_UNUSED) 1062 1.1 christos { 1063 1.1 christos return 0; 1064 1.1 christos } 1065 1.1 christos 1066 1.1 christos void 1067 1.1 christos md_show_usage (FILE *stream ATTRIBUTE_UNUSED) 1068 1.1 christos { 1069 1.1 christos } 1070 1.1 christos 1071 1.1 christos /* This is called when a line is unrecognized. */ 1072 1.1 christos 1073 1.1 christos int 1074 1.1 christos dlx_unrecognized_line (int c) 1075 1.1 christos { 1076 1.1 christos int lab; 1077 1.1 christos char *s; 1078 1.1 christos 1079 1.1 christos if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0])) 1080 1.1 christos return 0; 1081 1.1 christos 1082 1.1 christos s = input_line_pointer; 1083 1.1 christos 1084 1.1 christos lab = 0; 1085 1.1 christos while (ISDIGIT ((unsigned char) *s)) 1086 1.1 christos { 1087 1.1 christos lab = lab * 10 + *s - '0'; 1088 1.1 christos ++s; 1089 1.1 christos } 1090 1.1 christos 1091 1.1 christos if (*s != ':') 1092 1.1 christos /* Not a label definition. */ 1093 1.1 christos return 0; 1094 1.1 christos 1095 1.1 christos if (dollar_label_defined (lab)) 1096 1.1 christos { 1097 1.1 christos as_bad (_("label \"$%d\" redefined"), lab); 1098 1.1 christos return 0; 1099 1.1 christos } 1100 1.1 christos 1101 1.1 christos define_dollar_label (lab); 1102 1.1 christos colon (dollar_label_name (lab, 0)); 1103 1.1 christos input_line_pointer = s + 1; 1104 1.1 christos 1105 1.1 christos return 1; 1106 1.1 christos } 1107 1.1 christos 1108 1.1 christos /* Default the values of symbols known that should be "predefined". We 1109 1.1 christos don't bother to predefine them unless you actually use one, since there 1110 1.1 christos are a lot of them. */ 1111 1.1 christos 1112 1.1 christos symbolS * 1113 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1114 1.1 christos { 1115 1.1 christos return NULL; 1116 1.1 christos } 1117 1.1 christos 1118 1.1 christos /* Parse an operand that is machine-specific, the function was called 1119 1.1 christos in expr.c by operand() function, when everything failed before it 1120 1.1 christos call a quit. */ 1121 1.1 christos 1122 1.1 christos void 1123 1.1 christos md_operand (expressionS* expressionP) 1124 1.1 christos { 1125 1.1 christos /* Check for the #number representation */ 1126 1.1 christos if (input_line_pointer[0] == '#' && 1127 1.10 christos ISDIGIT (input_line_pointer[1])) 1128 1.1 christos { 1129 1.1 christos /* We have a numeric number expression. No biggy. */ 1130 1.1 christos input_line_pointer += 1; /* Skip # */ 1131 1.1 christos 1132 1.1 christos (void) expression (expressionP); 1133 1.1 christos 1134 1.1 christos if (expressionP->X_op != O_constant) 1135 1.1 christos as_bad (_("Invalid expression after # number\n")); 1136 1.1 christos } 1137 1.1 christos 1138 1.1 christos return; 1139 1.1 christos } 1140 1.1 christos 1141 1.1 christos /* Round up a section size to the appropriate boundary. */ 1142 1.1 christos 1143 1.1 christos valueT 1144 1.1 christos md_section_align (segT segment ATTRIBUTE_UNUSED, 1145 1.1 christos valueT size) 1146 1.1 christos { 1147 1.1 christos /* Byte alignment is fine. */ 1148 1.1 christos return size; 1149 1.1 christos } 1150 1.1 christos 1151 1.1 christos /* Exactly what point is a PC-relative offset relative TO? 1152 1.1 christos On the 29000, they're relative to the address of the instruction, 1153 1.1 christos which we have set up as the address of the fixup too. */ 1154 1.1 christos 1155 1.1 christos long 1156 1.1 christos md_pcrel_from (fixS* fixP) 1157 1.1 christos { 1158 1.1 christos return 4 + fixP->fx_where + fixP->fx_frag->fr_address; 1159 1.1 christos } 1160 1.1 christos 1161 1.1 christos /* Translate internal representation of relocation info to BFD target 1162 1.1 christos format. 1163 1.1 christos FIXME: To what extent can we get all relevant targets to use this? 1164 1.1 christos The above FIXME is from a29k, but I think it is also needed here. */ 1165 1.1 christos 1166 1.1 christos arelent * 1167 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1168 1.1 christos fixS *fixP) 1169 1.1 christos { 1170 1.1 christos arelent * reloc; 1171 1.1 christos 1172 1.10 christos reloc = notes_alloc (sizeof (arelent)); 1173 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 1174 1.10 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 1175 1.10 christos 1176 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); 1177 1.1 christos if (reloc->howto == NULL) 1178 1.1 christos { 1179 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1180 1.1 christos _("internal error: can't export reloc type %d (`%s')"), 1181 1.1 christos fixP->fx_r_type, 1182 1.1 christos bfd_get_reloc_code_name (fixP->fx_r_type)); 1183 1.1 christos return NULL; 1184 1.1 christos } 1185 1.1 christos 1186 1.1 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); 1187 1.1 christos 1188 1.1 christos reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 1189 1.1 christos 1190 1.1 christos if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 1191 1.1 christos reloc->address = fixP->fx_offset; 1192 1.1 christos reloc->addend = 0; 1193 1.1 christos 1194 1.1 christos return reloc; 1195 1.1 christos } 1196 1.1 christos 1197 1.1 christos const pseudo_typeS 1198 1.1 christos dlx_pseudo_table[] = 1199 1.1 christos { 1200 1.1 christos /* Some additional ops that are used by gcc-dlx. */ 1201 1.1 christos {"asciiz", stringer, 8 + 1}, 1202 1.1 christos {"half", cons, 2}, 1203 1.1 christos {"dword", cons, 8}, 1204 1.1 christos {"word", cons, 4}, 1205 1.1 christos {"proc", s_proc, 0}, 1206 1.1 christos {"endproc", s_proc, 1}, 1207 1.1 christos {NULL, NULL, 0} 1208 1.1 christos }; 1209 1.1 christos 1210 1.1 christos void 1211 1.1 christos dlx_pop_insert (void) 1212 1.1 christos { 1213 1.1 christos pop_insert (dlx_pseudo_table); 1214 1.1 christos return ; 1215 1.1 christos } 1216