1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x. 2 Copyright (C) 1997-2024 Free Software Foundation, Inc. 3 4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz) 5 6 This file is part of GAS, the GNU Assembler. 7 8 GAS is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 GAS is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GAS; see the file COPYING. If not, write to 20 the Free Software Foundation, 51 Franklin Street - Fifth Floor, 21 Boston, MA 02110-1301, USA. */ 22 /* 23 TODOs: 24 ------ 25 26 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It 27 should be possible to define a 32-bits pattern. 28 29 o .align: Implement a 'bu' insn if the number of nop's exceeds 4 30 within the align frag. if(fragsize>4words) insert bu fragend+1 31 first. 32 33 o .usect if has symbol on previous line not implemented 34 35 o .sym, .eos, .stag, .etag, .member not implemented 36 37 o Evaluation of constant floating point expressions (expr.c needs 38 work!) 39 40 o Support 'abc' constants (that is 0x616263). */ 41 42 #include "as.h" 43 #include "safe-ctype.h" 44 #include "opcode/tic4x.h" 45 #include "subsegs.h" 46 47 /* OK, we accept a syntax similar to the other well known C30 48 assembly tools. With TIC4X_ALT_SYNTAX defined we are more 49 flexible, allowing a more Unix-like syntax: `%' in front of 50 register names, `#' in front of immediate constants, and 51 not requiring `@' in front of direct addresses. */ 52 53 #define TIC4X_ALT_SYNTAX 54 55 /* Handle of the inst mnemonic hash table. */ 56 static htab_t tic4x_op_hash = NULL; 57 58 /* Handle asg pseudo. */ 59 static htab_t tic4x_asg_hash = NULL; 60 61 static unsigned int tic4x_cpu = 0; /* Default to TMS320C40. */ 62 static unsigned int tic4x_revision = 0; /* CPU revision */ 63 static unsigned int tic4x_idle2 = 0; /* Idle2 support */ 64 static unsigned int tic4x_lowpower = 0; /* Lowpower support */ 65 static unsigned int tic4x_enhanced = 0; /* Enhanced opcode support */ 66 static unsigned int tic4x_big_model = 0; /* Default to small memory model. */ 67 static unsigned int tic4x_reg_args = 0; /* Default to args passed on stack. */ 68 static unsigned long tic4x_oplevel = 0; /* Opcode level */ 69 70 #define OPTION_CPU 'm' 71 #define OPTION_BIG (OPTION_MD_BASE + 1) 72 #define OPTION_SMALL (OPTION_MD_BASE + 2) 73 #define OPTION_MEMPARM (OPTION_MD_BASE + 3) 74 #define OPTION_REGPARM (OPTION_MD_BASE + 4) 75 #define OPTION_IDLE2 (OPTION_MD_BASE + 5) 76 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6) 77 #define OPTION_ENHANCED (OPTION_MD_BASE + 7) 78 #define OPTION_REV (OPTION_MD_BASE + 8) 79 80 const char *md_shortopts = "bm:prs"; 81 struct option md_longopts[] = 82 { 83 { "mcpu", required_argument, NULL, OPTION_CPU }, 84 { "mdsp", required_argument, NULL, OPTION_CPU }, 85 { "mbig", no_argument, NULL, OPTION_BIG }, 86 { "msmall", no_argument, NULL, OPTION_SMALL }, 87 { "mmemparm", no_argument, NULL, OPTION_MEMPARM }, 88 { "mregparm", no_argument, NULL, OPTION_REGPARM }, 89 { "midle2", no_argument, NULL, OPTION_IDLE2 }, 90 { "mlowpower", no_argument, NULL, OPTION_LOWPOWER }, 91 { "menhanced", no_argument, NULL, OPTION_ENHANCED }, 92 { "mrev", required_argument, NULL, OPTION_REV }, 93 { NULL, no_argument, NULL, 0 } 94 }; 95 96 size_t md_longopts_size = sizeof (md_longopts); 97 98 99 typedef enum 100 { 101 M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT, 102 M_IMMED_F, M_PARALLEL, M_HI 103 } 104 tic4x_addr_mode_t; 105 106 typedef struct tic4x_operand 107 { 108 tic4x_addr_mode_t mode; /* Addressing mode. */ 109 expressionS expr; /* Expression. */ 110 int disp; /* Displacement for indirect addressing. */ 111 int aregno; /* Aux. register number. */ 112 LITTLENUM_TYPE fwords[MAX_LITTLENUMS]; /* Float immed. number. */ 113 } 114 tic4x_operand_t; 115 116 typedef struct tic4x_insn 117 { 118 char name[TIC4X_NAME_MAX]; /* Mnemonic of instruction. */ 119 unsigned int in_use; /* True if in_use. */ 120 unsigned int parallel; /* True if parallel instruction. */ 121 unsigned int nchars; /* This is always 4 for the C30. */ 122 unsigned long opcode; /* Opcode number. */ 123 expressionS exp; /* Expression required for relocation. */ 124 /* Relocation type required. */ 125 bfd_reloc_code_real_type reloc; 126 int pcrel; /* True if relocation PC relative. */ 127 char *pname; /* Name of instruction in parallel. */ 128 unsigned int num_operands; /* Number of operands in total. */ 129 tic4x_inst_t *inst; /* Pointer to first template. */ 130 tic4x_operand_t operands[TIC4X_OPERANDS_MAX]; 131 } 132 tic4x_insn_t; 133 134 static tic4x_insn_t the_insn; /* Info about our instruction. */ 135 static tic4x_insn_t *insn = &the_insn; 136 137 static void tic4x_asg (int); 138 static void tic4x_bss (int); 139 static void tic4x_globl (int); 140 static void tic4x_cons (int); 141 static void tic4x_stringer (int); 142 static void tic4x_eval (int); 143 static void tic4x_newblock (int); 144 static void tic4x_sect (int); 145 static void tic4x_set (int); 146 static void tic4x_usect (int); 147 static void tic4x_version (int); 148 149 150 const pseudo_typeS 151 md_pseudo_table[] = 152 { 153 {"align", s_align_bytes, 32}, 154 {"ascii", tic4x_stringer, 1}, 155 {"asciz", tic4x_stringer, 0}, 156 {"asg", tic4x_asg, 0}, 157 {"block", s_space, 4}, 158 {"byte", tic4x_cons, 1}, 159 {"bss", tic4x_bss, 0}, 160 {"copy", s_include, 0}, 161 {"def", tic4x_globl, 0}, 162 {"equ", tic4x_set, 0}, 163 {"eval", tic4x_eval, 0}, 164 {"global", tic4x_globl, 0}, 165 {"globl", tic4x_globl, 0}, 166 {"hword", tic4x_cons, 2}, 167 {"ieee", float_cons, 'i'}, 168 {"int", tic4x_cons, 4}, /* .int allocates 4 bytes. */ 169 {"ldouble", float_cons, 'e'}, 170 {"newblock", tic4x_newblock, 0}, 171 {"ref", s_ignore, 0}, /* All undefined treated as external. */ 172 {"set", tic4x_set, 0}, 173 {"sect", tic4x_sect, 1}, /* Define named section. */ 174 {"space", s_space, 4}, 175 {"string", tic4x_stringer, 0}, 176 {"usect", tic4x_usect, 0}, /* Reserve space in uninit. named sect. */ 177 {"version", tic4x_version, 0}, 178 {"word", tic4x_cons, 4}, /* .word allocates 4 bytes. */ 179 {"xdef", tic4x_globl, 0}, 180 {NULL, 0, 0}, 181 }; 182 183 int md_short_jump_size = 4; 184 int md_long_jump_size = 4; 185 186 /* This array holds the chars that always start a comment. If the 187 pre-processor is disabled, these aren't very useful. */ 188 #ifdef TIC4X_ALT_SYNTAX 189 const char comment_chars[] = ";!"; 190 #else 191 const char comment_chars[] = ";"; 192 #endif 193 194 /* This array holds the chars that only start a comment at the beginning of 195 a line. If the line seems to have the form '# 123 filename' 196 .line and .file directives will appear in the pre-processed output. 197 Note that input_file.c hand checks for '#' at the beginning of the 198 first line of the input file. This is because the compiler outputs 199 #NO_APP at the beginning of its output. 200 Also note that comments like this one will always work. */ 201 const char line_comment_chars[] = "#*"; 202 203 /* We needed an unused char for line separation to work around the 204 lack of macros, using sed and such. */ 205 const char line_separator_chars[] = "&"; 206 207 /* Chars that can be used to separate mant from exp in floating point nums. */ 208 const char EXP_CHARS[] = "eE"; 209 210 /* Chars that mean this number is a floating point constant. */ 211 /* As in 0f12.456 */ 212 /* or 0d1.2345e12 */ 213 const char FLT_CHARS[] = "fFilsS"; 214 215 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be 216 changed in read.c. Ideally it shouldn't have to know about it at 217 all, but nothing is ideal around here. */ 218 219 /* Flonums returned here. */ 220 extern FLONUM_TYPE generic_floating_point_number; 221 222 /* Precision in LittleNums. */ 223 #define MAX_PRECISION (4) /* It's a bit overkill for us, but the code 224 requires it... */ 225 #define S_PRECISION (1) /* Short float constants 16-bit. */ 226 #define F_PRECISION (2) /* Float and double types 32-bit. */ 227 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */ 228 #define GUARD (2) 229 230 /* Turn generic_floating_point_number into a real short/float/double. */ 231 static int 232 tic4x_gen_to_words (FLONUM_TYPE flonum, LITTLENUM_TYPE *words, int precision) 233 { 234 int return_value = 0; 235 LITTLENUM_TYPE *p; /* Littlenum pointer. */ 236 int mantissa_bits; /* Bits in mantissa field. */ 237 int exponent_bits; /* Bits in exponent field. */ 238 int exponent; 239 unsigned int sone; /* Scaled one. */ 240 unsigned int sfract; /* Scaled fraction. */ 241 unsigned int smant; /* Scaled mantissa. */ 242 unsigned int tmp; 243 unsigned int mover; /* Mantissa overflow bits */ 244 unsigned int rbit; /* Round bit. */ 245 int shift; /* Shift count. */ 246 247 /* NOTE: Svein Seldal <Svein@dev.seldal.com> 248 The code in this function is altered slightly to support floats 249 with 31-bits mantissas, thus the documentation below may be a 250 little bit inaccurate. 251 252 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz> 253 Here is how a generic floating point number is stored using 254 flonums (an extension of bignums) where p is a pointer to an 255 array of LITTLENUMs. 256 257 For example 2e-3 is stored with exp = -4 and 258 bits[0] = 0x0000 259 bits[1] = 0x0000 260 bits[2] = 0x4fde 261 bits[3] = 0x978d 262 bits[4] = 0x126e 263 bits[5] = 0x0083 264 with low = &bits[2], high = &bits[5], and leader = &bits[5]. 265 266 This number can be written as 267 0x0083126e978d4fde.00000000 * 65536**-4 or 268 0x0.0083126e978d4fde * 65536**0 or 269 0x0.83126e978d4fde * 2**-8 = 2e-3 270 271 Note that low points to the 65536**0 littlenum (bits[2]) and 272 leader points to the most significant non-zero littlenum 273 (bits[5]). 274 275 TMS320C3X floating point numbers are a bit of a strange beast. 276 The 32-bit flavour has the 8 MSBs representing the exponent in 277 twos complement format (-128 to +127). There is then a sign bit 278 followed by 23 bits of mantissa. The mantissa is expressed in 279 twos complement format with the binary point after the most 280 significant non sign bit. The bit after the binary point is 281 suppressed since it is the complement of the sign bit. The 282 effective mantissa is thus 24 bits. Zero is represented by an 283 exponent of -128. 284 285 The 16-bit flavour has the 4 MSBs representing the exponent in 286 twos complement format (-8 to +7). There is then a sign bit 287 followed by 11 bits of mantissa. The mantissa is expressed in 288 twos complement format with the binary point after the most 289 significant non sign bit. The bit after the binary point is 290 suppressed since it is the complement of the sign bit. The 291 effective mantissa is thus 12 bits. Zero is represented by an 292 exponent of -8. For example, 293 294 number norm mant m x e s i fraction f 295 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1) 296 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1) 297 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0) 298 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0) 299 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0) 300 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1) 301 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2) 302 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2) 303 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1) 304 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0) 305 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0) 306 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0) 307 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1) 308 309 where e is the exponent, s is the sign bit, i is the implied bit, 310 and f is the fraction stored in the mantissa field. 311 312 num = (1 + f) * 2^x = m * 2^e if s = 0 313 num = (-2 + f) * 2^x = -m * 2^e if s = 1 314 where 0 <= f < 1.0 and 1.0 <= m < 2.0 315 316 The fraction (f) and exponent (e) fields for the TMS320C3X format 317 can be derived from the normalised mantissa (m) and exponent (x) using: 318 319 f = m - 1, e = x if s = 0 320 f = 2 - m, e = x if s = 1 and m != 1.0 321 f = 0, e = x - 1 if s = 1 and m = 1.0 322 f = 0, e = -8 if m = 0 323 324 325 OK, the other issue we have to consider is rounding since the 326 mantissa has a much higher potential precision than what we can 327 represent. To do this we add half the smallest storable fraction. 328 We then have to renormalise the number to allow for overflow. 329 330 To convert a generic flonum into a TMS320C3X floating point 331 number, here's what we try to do.... 332 333 The first thing is to generate a normalised mantissa (m) where 334 1.0 <= m < 2 and to convert the exponent from base 16 to base 2. 335 We desire the binary point to be placed after the most significant 336 non zero bit. This process is done in two steps: firstly, the 337 littlenum with the most significant non zero bit is located (this 338 is done for us since leader points to this littlenum) and the 339 binary point (which is currently after the LSB of the littlenum 340 pointed to by low) is moved to before the MSB of the littlenum 341 pointed to by leader. This requires the exponent to be adjusted 342 by leader - low + 1. In the earlier example, the new exponent is 343 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert 344 the exponent to base 2 by multiplying the exponent by 16 (log2 345 65536). The exponent base 2 is thus also zero. 346 347 The second step is to hunt for the most significant non zero bit 348 in the leader littlenum. We do this by left shifting a copy of 349 the leader littlenum until bit 16 is set (0x10000) and counting 350 the number of shifts, S, required. The number of shifts then has to 351 be added to correct the exponent (base 2). For our example, this 352 will require 9 shifts and thus our normalised exponent (base 2) is 353 0 + 9 = 9. Note that the worst case scenario is when the leader 354 littlenum is 1, thus requiring 16 shifts. 355 356 We now have to left shift the other littlenums by the same amount, 357 propagating the shifted bits into the more significant littlenums. 358 To save a lot of unnecessary shifting we only have to consider 359 two or three littlenums, since the greatest number of mantissa 360 bits required is 24 + 1 rounding bit. While two littlenums 361 provide 32 bits of precision, the most significant littlenum 362 may only contain a single significant bit and thus an extra 363 littlenum is required. 364 365 Denoting the number of bits in the fraction field as F, we require 366 G = F + 2 bits (one extra bit is for rounding, the other gets 367 suppressed). Say we required S shifts to find the most 368 significant bit in the leader littlenum, the number of left shifts 369 required to move this bit into bit position G - 1 is L = G + S - 17. 370 Note that this shift count may be negative for the short floating 371 point flavour (where F = 11 and thus G = 13 and potentially S < 3). 372 If L > 0 we have to shunt the next littlenum into position. Bit 373 15 (the MSB) of the next littlenum needs to get moved into position 374 L - 1 (If L > 15 we need all the bits of this littlenum and 375 some more from the next one.). We subtract 16 from L and use this 376 as the left shift count; the resultant value we or with the 377 previous result. If L > 0, we repeat this operation. */ 378 379 if (precision != S_PRECISION) 380 words[1] = 0x0000; 381 if (precision == E_PRECISION) 382 words[2] = words[3] = 0x0000; 383 384 /* 0.0e0 or NaN seen. */ 385 if (flonum.low > flonum.leader /* = 0.0e0 */ 386 || flonum.sign == 0 /* = NaN */ 387 || flonum.sign == 'Q' || flonum.sign == 'q' /* = QNaN */ 388 || flonum.sign == 'S' || flonum.sign == 's') /* = SNaN */ 389 { 390 if (flonum.sign != '+' && flonum.sign != '-') 391 as_bad (_("Nan, using zero.")); 392 words[0] = 0x8000; 393 return return_value; 394 } 395 396 if (flonum.sign == 'P') 397 { 398 /* +INF: Replace with maximum float. */ 399 if (precision == S_PRECISION) 400 words[0] = 0x77ff; 401 else 402 { 403 words[0] = 0x7f7f; 404 words[1] = 0xffff; 405 } 406 if (precision == E_PRECISION) 407 { 408 words[2] = 0x7fff; 409 words[3] = 0xffff; 410 } 411 return return_value; 412 } 413 else if (flonum.sign == 'N') 414 { 415 /* -INF: Replace with maximum float. */ 416 if (precision == S_PRECISION) 417 words[0] = 0x7800; 418 else 419 words[0] = 0x7f80; 420 if (precision == E_PRECISION) 421 words[2] = 0x8000; 422 return return_value; 423 } 424 425 exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16; 426 427 if (!(tmp = *flonum.leader)) 428 abort (); /* Hmmm. */ 429 shift = 0; /* Find position of first sig. bit. */ 430 while (tmp >>= 1) 431 shift++; 432 exponent -= (16 - shift); /* Adjust exponent. */ 433 434 if (precision == S_PRECISION) /* Allow 1 rounding bit. */ 435 { 436 exponent_bits = 4; 437 mantissa_bits = 11; 438 } 439 else if(precision == F_PRECISION) 440 { 441 exponent_bits = 8; 442 mantissa_bits = 23; 443 } 444 else /* E_PRECISION */ 445 { 446 exponent_bits = 8; 447 mantissa_bits = 31; 448 } 449 450 shift = mantissa_bits - shift; 451 452 smant = 0; 453 mover = 0; 454 rbit = 0; 455 /* Store the mantissa data into smant and the roundbit into rbit */ 456 for (p = flonum.leader; p >= flonum.low && shift > -16; p--) 457 { 458 tmp = shift >= 0 ? (unsigned) *p << shift : (unsigned) *p >> -shift; 459 rbit = shift < 0 ? (((unsigned) *p >> (-shift-1)) & 0x1) : 0; 460 smant |= tmp; 461 shift -= 16; 462 } 463 464 /* OK, we've got our scaled mantissa so let's round it up */ 465 if(rbit) 466 { 467 /* If the mantissa is going to overflow when added, lets store 468 the extra bit in mover. */ 469 if (smant == (1u << mantissa_bits << 1) - 1) 470 mover=1; 471 smant++; 472 } 473 474 /* Get the scaled one value */ 475 sone = 1u << mantissa_bits; 476 477 /* The number may be unnormalised so renormalise it... */ 478 if(mover) 479 { 480 smant >>= 1; 481 smant |= sone; /* Insert the bit from mover into smant */ 482 exponent++; 483 } 484 485 /* The binary point is now between bit positions 11 and 10 or 23 and 22, 486 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the 487 bit at mantissa_bits - 1 should be set. */ 488 if (!(sone&smant)) 489 abort (); /* Ooops. */ 490 491 if (flonum.sign == '+') 492 sfract = smant - sone; /* smant - 1.0. */ 493 else 494 { 495 /* This seems to work. */ 496 if (smant == sone) 497 { 498 exponent--; 499 sfract = 0; 500 } 501 else 502 { 503 sfract = -smant & (sone-1); /* 2.0 - smant. */ 504 } 505 sfract |= sone; /* Insert sign bit. */ 506 } 507 508 if (abs (exponent) >= (1 << (exponent_bits - 1))) 509 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits); 510 511 /* Force exponent to fit in desired field width. */ 512 exponent &= (1 << (exponent_bits)) - 1; 513 514 if (precision == E_PRECISION) 515 { 516 /* Map the float part first (100% equal format as F_PRECISION) */ 517 words[0] = exponent << (mantissa_bits+1-24); 518 words[0] |= sfract >> 24; 519 words[1] = sfract >> 8; 520 521 /* Map the mantissa in the next */ 522 words[2] = sfract >> 16; 523 words[3] = sfract & 0xffff; 524 } 525 else 526 { 527 /* Insert the exponent data into the word */ 528 sfract |= (unsigned) exponent << (mantissa_bits + 1); 529 530 if (precision == S_PRECISION) 531 words[0] = sfract; 532 else 533 { 534 words[0] = sfract >> 16; 535 words[1] = sfract & 0xffff; 536 } 537 } 538 539 return return_value; 540 } 541 542 /* Returns pointer past text consumed. */ 543 static char * 544 tic4x_atof (char *str, char what_kind, LITTLENUM_TYPE *words) 545 { 546 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are 547 zeroed, the last contain flonum bits. */ 548 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; 549 char *return_value; 550 /* Number of 16-bit words in the format. */ 551 int precision; 552 FLONUM_TYPE save_gen_flonum; 553 554 /* We have to save the generic_floating_point_number because it 555 contains storage allocation about the array of LITTLENUMs where 556 the value is actually stored. We will allocate our own array of 557 littlenums below, but have to restore the global one on exit. */ 558 save_gen_flonum = generic_floating_point_number; 559 560 return_value = str; 561 generic_floating_point_number.low = bits + MAX_PRECISION; 562 generic_floating_point_number.high = NULL; 563 generic_floating_point_number.leader = NULL; 564 generic_floating_point_number.exponent = 0; 565 generic_floating_point_number.sign = '\0'; 566 567 /* Use more LittleNums than seems necessary: the highest flonum may 568 have 15 leading 0 bits, so could be useless. */ 569 570 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); 571 572 switch (what_kind) 573 { 574 case 's': 575 case 'S': 576 precision = S_PRECISION; 577 break; 578 579 case 'd': 580 case 'D': 581 case 'f': 582 case 'F': 583 precision = F_PRECISION; 584 break; 585 586 case 'E': 587 case 'e': 588 precision = E_PRECISION; 589 break; 590 591 default: 592 as_bad (_("Invalid floating point number")); 593 return (NULL); 594 } 595 596 generic_floating_point_number.high 597 = generic_floating_point_number.low + precision - 1 + GUARD; 598 599 if (atof_generic (&return_value, ".", EXP_CHARS, 600 &generic_floating_point_number)) 601 { 602 as_bad (_("Invalid floating point number")); 603 return (NULL); 604 } 605 606 tic4x_gen_to_words (generic_floating_point_number, 607 words, precision); 608 609 /* Restore the generic_floating_point_number's storage alloc (and 610 everything else). */ 611 generic_floating_point_number = save_gen_flonum; 612 613 return return_value; 614 } 615 616 static void 617 tic4x_insert_reg (const char *regname, int regnum) 618 { 619 char buf[32]; 620 int i; 621 622 symbol_table_insert (symbol_new (regname, reg_section, 623 &zero_address_frag, regnum)); 624 for (i = 0; regname[i]; i++) 625 buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i]; 626 buf[i] = '\0'; 627 628 symbol_table_insert (symbol_new (buf, reg_section, 629 &zero_address_frag, regnum)); 630 } 631 632 static void 633 tic4x_insert_sym (const char *symname, int value) 634 { 635 symbolS *symbolP; 636 637 symbolP = symbol_new (symname, absolute_section, 638 &zero_address_frag, value); 639 SF_SET_LOCAL (symbolP); 640 symbol_table_insert (symbolP); 641 } 642 643 static char * 644 tic4x_expression (char *str, expressionS *exp) 645 { 646 char *s; 647 char *t; 648 649 t = input_line_pointer; /* Save line pointer. */ 650 input_line_pointer = str; 651 expression (exp); 652 resolve_register (exp); 653 s = input_line_pointer; 654 input_line_pointer = t; /* Restore line pointer. */ 655 return s; /* Return pointer to where parsing stopped. */ 656 } 657 658 static char * 659 tic4x_expression_abs (char *str, offsetT *value) 660 { 661 char *s; 662 char *t; 663 664 t = input_line_pointer; /* Save line pointer. */ 665 input_line_pointer = str; 666 *value = get_absolute_expression (); 667 s = input_line_pointer; 668 input_line_pointer = t; /* Restore line pointer. */ 669 return s; 670 } 671 672 static void 673 tic4x_emit_char (char c, int b) 674 { 675 expressionS exp; 676 677 exp.X_op = O_constant; 678 exp.X_add_number = c; 679 emit_expr (&exp, b); 680 } 681 682 static void 683 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED, 684 segT seg ATTRIBUTE_UNUSED, 685 int size, 686 symbolS *symbolP) 687 { 688 /* Note that the size is in words 689 so we multiply it by 4 to get the number of bytes to allocate. */ 690 691 /* If we have symbol: .usect ".fred", size etc., 692 the symbol needs to point to the first location reserved 693 by the pseudo op. */ 694 695 if (size) 696 { 697 char *p; 698 699 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, 700 (symbolS *) symbolP, 701 size * OCTETS_PER_BYTE, (char *) 0); 702 *p = 0; 703 } 704 } 705 706 /* .asg ["]character-string["], symbol */ 707 static void 708 tic4x_asg (int x ATTRIBUTE_UNUSED) 709 { 710 char c; 711 char *name; 712 char *str; 713 size_t len; 714 715 SKIP_WHITESPACE (); 716 str = input_line_pointer; 717 718 /* Skip string expression. */ 719 while (*input_line_pointer != ',' && *input_line_pointer) 720 input_line_pointer++; 721 if (*input_line_pointer != ',') 722 { 723 as_bad (_("Comma expected\n")); 724 return; 725 } 726 len = input_line_pointer - str; 727 str = notes_memdup (str, len, len + 1); 728 input_line_pointer++; 729 c = get_symbol_name (&name); /* Get terminator. */ 730 name = notes_strdup (name); 731 str_hash_insert (tic4x_asg_hash, name, str, 1); 732 (void) restore_line_pointer (c); 733 demand_empty_rest_of_line (); 734 } 735 736 /* .bss symbol, size */ 737 static void 738 tic4x_bss (int x ATTRIBUTE_UNUSED) 739 { 740 char c; 741 char *name; 742 char *p; 743 offsetT size; 744 segT current_seg; 745 subsegT current_subseg; 746 symbolS *symbolP; 747 748 current_seg = now_seg; /* Save current seg. */ 749 current_subseg = now_subseg; /* Save current subseg. */ 750 751 SKIP_WHITESPACE (); 752 c = get_symbol_name (&name); /* Get terminator. */ 753 if (c == '"') 754 c = * ++ input_line_pointer; 755 if (c != ',') 756 { 757 as_bad (_(".bss size argument missing\n")); 758 return; 759 } 760 761 input_line_pointer = 762 tic4x_expression_abs (++input_line_pointer, &size); 763 if (size < 0) 764 { 765 as_bad (_(".bss size %ld < 0!"), (long) size); 766 return; 767 } 768 subseg_set (bss_section, 0); 769 symbolP = symbol_find_or_make (name); 770 771 if (S_GET_SEGMENT (symbolP) == bss_section) 772 symbol_get_frag (symbolP)->fr_symbol = 0; 773 774 symbol_set_frag (symbolP, frag_now); 775 776 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, 777 size * OCTETS_PER_BYTE, (char *) 0); 778 *p = 0; /* Fill char. */ 779 780 S_SET_SEGMENT (symbolP, bss_section); 781 782 /* The symbol may already have been created with a preceding 783 ".globl" directive -- be careful not to step on storage class 784 in that case. Otherwise, set it to static. */ 785 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT) 786 S_SET_STORAGE_CLASS (symbolP, C_STAT); 787 788 subseg_set (current_seg, current_subseg); /* Restore current seg. */ 789 demand_empty_rest_of_line (); 790 } 791 792 static void 793 tic4x_globl (int ignore ATTRIBUTE_UNUSED) 794 { 795 char *name; 796 int c; 797 symbolS *symbolP; 798 799 do 800 { 801 c = get_symbol_name (&name); 802 symbolP = symbol_find_or_make (name); 803 *input_line_pointer = c; 804 SKIP_WHITESPACE_AFTER_NAME (); 805 S_SET_STORAGE_CLASS (symbolP, C_EXT); 806 S_SET_EXTERNAL (symbolP); 807 if (c == ',') 808 { 809 input_line_pointer++; 810 SKIP_WHITESPACE (); 811 if (*input_line_pointer == '\n') 812 c = '\n'; 813 } 814 } 815 while (c == ','); 816 817 demand_empty_rest_of_line (); 818 } 819 820 /* Handle .byte, .word. .int, .long */ 821 static void 822 tic4x_cons (int bytes) 823 { 824 unsigned int c; 825 do 826 { 827 SKIP_WHITESPACE (); 828 if (*input_line_pointer == '"') 829 { 830 input_line_pointer++; 831 while (is_a_char (c = next_char_of_string ())) 832 tic4x_emit_char (c, 4); 833 know (input_line_pointer[-1] == '\"'); 834 } 835 else 836 { 837 expressionS exp; 838 839 input_line_pointer = tic4x_expression (input_line_pointer, &exp); 840 if (exp.X_op == O_constant) 841 { 842 switch (bytes) 843 { 844 case 1: 845 exp.X_add_number &= 255; 846 break; 847 case 2: 848 exp.X_add_number &= 65535; 849 break; 850 } 851 } 852 /* Perhaps we should disallow .byte and .hword with 853 a non constant expression that will require relocation. */ 854 emit_expr (&exp, 4); 855 } 856 } 857 while (*input_line_pointer++ == ','); 858 859 input_line_pointer--; /* Put terminator back into stream. */ 860 demand_empty_rest_of_line (); 861 } 862 863 /* Handle .ascii, .asciz, .string */ 864 static void 865 tic4x_stringer (int append_zero) 866 { 867 int bytes; 868 unsigned int c; 869 870 bytes = 0; 871 do 872 { 873 SKIP_WHITESPACE (); 874 if (*input_line_pointer == '"') 875 { 876 input_line_pointer++; 877 while (is_a_char (c = next_char_of_string ())) 878 { 879 tic4x_emit_char (c, 1); 880 bytes++; 881 } 882 883 if (append_zero) 884 { 885 tic4x_emit_char (c, 1); 886 bytes++; 887 } 888 889 know (input_line_pointer[-1] == '\"'); 890 } 891 else 892 { 893 expressionS exp; 894 895 input_line_pointer = tic4x_expression (input_line_pointer, &exp); 896 if (exp.X_op != O_constant) 897 { 898 as_bad (_("Non-constant symbols not allowed\n")); 899 return; 900 } 901 exp.X_add_number &= 255; /* Limit number to 8-bit */ 902 emit_expr (&exp, 1); 903 bytes++; 904 } 905 } 906 while (*input_line_pointer++ == ','); 907 908 /* Fill out the rest of the expression with 0's to fill up a full word */ 909 if ( bytes&0x3 ) 910 tic4x_emit_char (0, 4-(bytes&0x3)); 911 912 input_line_pointer--; /* Put terminator back into stream. */ 913 demand_empty_rest_of_line (); 914 } 915 916 /* .eval expression, symbol */ 917 static void 918 tic4x_eval (int x ATTRIBUTE_UNUSED) 919 { 920 char c; 921 offsetT value; 922 char *name; 923 924 SKIP_WHITESPACE (); 925 input_line_pointer = 926 tic4x_expression_abs (input_line_pointer, &value); 927 if (*input_line_pointer++ != ',') 928 { 929 as_bad (_("Symbol missing\n")); 930 return; 931 } 932 c = get_symbol_name (&name); /* Get terminator. */ 933 tic4x_insert_sym (name, value); 934 (void) restore_line_pointer (c); 935 demand_empty_rest_of_line (); 936 } 937 938 /* Reset local labels. */ 939 static void 940 tic4x_newblock (int x ATTRIBUTE_UNUSED) 941 { 942 dollar_label_clear (); 943 } 944 945 /* .sect "section-name" [, value] */ 946 /* .sect ["]section-name[:subsection-name]["] [, value] */ 947 static void 948 tic4x_sect (int x ATTRIBUTE_UNUSED) 949 { 950 char c; 951 char *section_name; 952 char *name; 953 segT seg; 954 offsetT num; 955 956 SKIP_WHITESPACE (); 957 if (*input_line_pointer == '"') 958 input_line_pointer++; 959 c = get_symbol_name (§ion_name); /* Get terminator. */ 960 if (c == '"') 961 c = * ++ input_line_pointer; 962 input_line_pointer++; /* Skip null symbol terminator. */ 963 name = xstrdup (section_name); 964 965 /* TI C from version 5.0 allows a section name to contain a 966 subsection name as well. The subsection name is separated by a 967 ':' from the section name. Currently we scan the subsection 968 name and discard it. 969 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */ 970 if (c == ':') 971 { 972 char *subname; 973 c = get_symbol_name (&subname); /* Get terminator. */ 974 if (c == '"') 975 c = * ++ input_line_pointer; 976 input_line_pointer++; /* Skip null symbol terminator. */ 977 as_warn (_(".sect: subsection name ignored")); 978 } 979 980 /* We might still have a '"' to discard, but the character after a 981 symbol name will be overwritten with a \0 by get_symbol_name() 982 [VK]. */ 983 984 if (c == ',') 985 input_line_pointer = 986 tic4x_expression_abs (input_line_pointer, &num); 987 else if (*input_line_pointer == ',') 988 { 989 input_line_pointer = 990 tic4x_expression_abs (++input_line_pointer, &num); 991 } 992 else 993 num = 0; 994 995 seg = subseg_new (name, num); 996 if (line_label != NULL) 997 { 998 S_SET_SEGMENT (line_label, seg); 999 symbol_set_frag (line_label, frag_now); 1000 } 1001 1002 if (bfd_section_flags (seg) == SEC_NO_FLAGS) 1003 { 1004 if (!bfd_set_section_flags (seg, SEC_DATA)) 1005 as_warn (_("Error setting flags for \"%s\": %s"), name, 1006 bfd_errmsg (bfd_get_error ())); 1007 } 1008 1009 /* If the last character overwritten by get_symbol_name() was an 1010 end-of-line, we must restore it or the end of the line will not be 1011 recognised and scanning extends into the next line, stopping with 1012 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz> 1013 if this is not true). */ 1014 if (is_end_of_line[(unsigned char) c]) 1015 *(--input_line_pointer) = c; 1016 1017 demand_empty_rest_of_line (); 1018 } 1019 1020 /* symbol[:] .set value or .set symbol, value */ 1021 static void 1022 tic4x_set (int x ATTRIBUTE_UNUSED) 1023 { 1024 symbolS *symbolP; 1025 1026 SKIP_WHITESPACE (); 1027 if ((symbolP = line_label) == NULL) 1028 { 1029 char c; 1030 char *name; 1031 1032 c = get_symbol_name (&name); /* Get terminator. */ 1033 if (c == '"') 1034 c = * ++ input_line_pointer; 1035 if (c != ',') 1036 { 1037 as_bad (_(".set syntax invalid\n")); 1038 ignore_rest_of_line (); 1039 return; 1040 } 1041 ++input_line_pointer; 1042 symbolP = symbol_find_or_make (name); 1043 } 1044 else 1045 symbol_table_insert (symbolP); 1046 1047 pseudo_set (symbolP); 1048 demand_empty_rest_of_line (); 1049 } 1050 1051 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */ 1052 static void 1053 tic4x_usect (int x ATTRIBUTE_UNUSED) 1054 { 1055 char c; 1056 char *name; 1057 char *section_name; 1058 segT seg; 1059 offsetT size, alignment_flag; 1060 segT current_seg; 1061 subsegT current_subseg; 1062 1063 current_seg = now_seg; /* save current seg. */ 1064 current_subseg = now_subseg; /* save current subseg. */ 1065 1066 SKIP_WHITESPACE (); 1067 if (*input_line_pointer == '"') 1068 input_line_pointer++; 1069 c = get_symbol_name (§ion_name); /* Get terminator. */ 1070 if (c == '"') 1071 c = * ++ input_line_pointer; 1072 input_line_pointer++; /* Skip null symbol terminator. */ 1073 name = xstrdup (section_name); 1074 1075 if (c == ',') 1076 input_line_pointer = 1077 tic4x_expression_abs (input_line_pointer, &size); 1078 else if (*input_line_pointer == ',') 1079 { 1080 input_line_pointer = 1081 tic4x_expression_abs (++input_line_pointer, &size); 1082 } 1083 else 1084 size = 0; 1085 1086 /* Read a possibly present third argument (alignment flag) [VK]. */ 1087 if (*input_line_pointer == ',') 1088 { 1089 input_line_pointer = 1090 tic4x_expression_abs (++input_line_pointer, &alignment_flag); 1091 } 1092 else 1093 alignment_flag = 0; 1094 if (alignment_flag) 1095 as_warn (_(".usect: non-zero alignment flag ignored")); 1096 1097 seg = subseg_new (name, 0); 1098 if (line_label != NULL) 1099 { 1100 S_SET_SEGMENT (line_label, seg); 1101 symbol_set_frag (line_label, frag_now); 1102 S_SET_VALUE (line_label, frag_now_fix ()); 1103 } 1104 seg_info (seg)->bss = 1; /* Uninitialised data. */ 1105 if (!bfd_set_section_flags (seg, SEC_ALLOC)) 1106 as_warn (_("Error setting flags for \"%s\": %s"), name, 1107 bfd_errmsg (bfd_get_error ())); 1108 tic4x_seg_alloc (name, seg, size, line_label); 1109 1110 if (S_GET_STORAGE_CLASS (line_label) != C_EXT) 1111 S_SET_STORAGE_CLASS (line_label, C_STAT); 1112 1113 subseg_set (current_seg, current_subseg); /* Restore current seg. */ 1114 demand_empty_rest_of_line (); 1115 } 1116 1117 /* .version cpu-version. */ 1118 static void 1119 tic4x_version (int x ATTRIBUTE_UNUSED) 1120 { 1121 offsetT temp; 1122 1123 input_line_pointer = 1124 tic4x_expression_abs (input_line_pointer, &temp); 1125 if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp)) 1126 as_bad (_("This assembler does not support processor generation %ld"), 1127 (long) temp); 1128 1129 if (tic4x_cpu && temp != (offsetT) tic4x_cpu) 1130 as_warn (_("Changing processor generation on fly not supported...")); 1131 tic4x_cpu = temp; 1132 demand_empty_rest_of_line (); 1133 } 1134 1135 static void 1136 tic4x_init_regtable (void) 1137 { 1138 unsigned int i; 1139 1140 for (i = 0; i < tic3x_num_registers; i++) 1141 tic4x_insert_reg (tic3x_registers[i].name, 1142 tic3x_registers[i].regno); 1143 1144 if (IS_CPU_TIC4X (tic4x_cpu)) 1145 { 1146 /* Add additional Tic4x registers, overriding some C3x ones. */ 1147 for (i = 0; i < tic4x_num_registers; i++) 1148 tic4x_insert_reg (tic4x_registers[i].name, 1149 tic4x_registers[i].regno); 1150 } 1151 } 1152 1153 static void 1154 tic4x_init_symbols (void) 1155 { 1156 /* The TI tools accept case insensitive versions of these symbols, 1157 we don't ! 1158 1159 For TI C/Asm 5.0 1160 1161 .TMS320xx 30,31,32,40,or 44 set according to -v flag 1162 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32 1163 .C30 1 or 0 1 if -v30 1164 .C31 1 or 0 1 if -v31 1165 .C32 1 or 0 1 if -v32 1166 .C4X or .C4x 1 or 0 1 if -v40, or -v44 1167 .C40 1 or 0 1 if -v40 1168 .C44 1 or 0 1 if -v44 1169 1170 .REGPARM 1 or 0 1 if -mr option used 1171 .BIGMODEL 1 or 0 1 if -mb option used 1172 1173 These symbols are currently supported but will be removed in a 1174 later version: 1175 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32 1176 .TMS320C31 1 or 0 1 if -v31 1177 .TMS320C32 1 or 0 1 if -v32 1178 .TMS320C40 1 or 0 1 if -v40, or -v44 1179 .TMS320C44 1 or 0 1 if -v44 1180 1181 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide, 1182 1997, SPRU035C, p. 3-17/3-18. */ 1183 tic4x_insert_sym (".REGPARM", tic4x_reg_args); 1184 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args); 1185 tic4x_insert_sym (".BIGMODEL", tic4x_big_model); 1186 tic4x_insert_sym (".C30INTERRUPT", 0); 1187 tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu); 1188 tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33); 1189 tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33); 1190 tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44); 1191 tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44); 1192 /* Do we need to have the following symbols also in lower case? */ 1193 tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33); 1194 tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33); 1195 tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31); 1196 tic4x_insert_sym (".tms320C31", tic4x_cpu == 31); 1197 tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32); 1198 tic4x_insert_sym (".tms320C32", tic4x_cpu == 32); 1199 tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33); 1200 tic4x_insert_sym (".tms320C33", tic4x_cpu == 33); 1201 tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0); 1202 tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0); 1203 tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44); 1204 tic4x_insert_sym (".tms320C44", tic4x_cpu == 44); 1205 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */ 1206 tic4x_insert_sym (".tmx320C40", 0); 1207 } 1208 1209 /* Insert a new instruction template into hash table. */ 1210 static void 1211 tic4x_inst_insert (const tic4x_inst_t *inst) 1212 { 1213 static char prev_name[16]; 1214 1215 /* Only insert the first name if have several similar entries. */ 1216 if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0') 1217 return; 1218 1219 if (str_hash_insert (tic4x_op_hash, inst->name, inst, 0) != NULL) 1220 as_fatal (_("duplicate %s"), inst->name); 1221 1222 strcpy (prev_name, inst->name); 1223 } 1224 1225 /* Make a new instruction template. */ 1226 static tic4x_inst_t * 1227 tic4x_inst_make (const char *name, unsigned long opcode, const char *args) 1228 { 1229 static tic4x_inst_t *insts = NULL; 1230 static char *names = NULL; 1231 static int iindex = 0; 1232 1233 if (insts == NULL) 1234 { 1235 /* Allocate memory to store name strings. */ 1236 names = XNEWVEC (char, 8192); 1237 /* Allocate memory for additional insts. */ 1238 insts = XNEWVEC (tic4x_inst_t, 1024); 1239 } 1240 insts[iindex].name = names; 1241 insts[iindex].opcode = opcode; 1242 insts[iindex].opmask = 0xffffffff; 1243 insts[iindex].args = args; 1244 iindex++; 1245 1246 while (*name) 1247 *names++ = *name++; 1248 *names++ = '\0'; 1249 1250 return &insts[iindex - 1]; 1251 } 1252 1253 /* Add instruction template, creating dynamic templates as required. */ 1254 static void 1255 tic4x_inst_add (const tic4x_inst_t *insts) 1256 { 1257 const char *s = insts->name; 1258 char *d; 1259 unsigned int i; 1260 char name[16]; 1261 1262 d = name; 1263 1264 /* We do not care about INSNs that is not a part of our 1265 oplevel setting. */ 1266 if ((insts->oplevel & tic4x_oplevel) == 0) 1267 return; 1268 1269 while (1) 1270 { 1271 switch (*s) 1272 { 1273 case 'B': 1274 case 'C': 1275 /* Dynamically create all the conditional insts. */ 1276 for (i = 0; i < tic4x_num_conds; i++) 1277 { 1278 tic4x_inst_t *inst; 1279 int k = 0; 1280 const char *c = tic4x_conds[i].name; 1281 char *e = d; 1282 1283 while (*c) 1284 *e++ = *c++; 1285 c = s + 1; 1286 while (*c) 1287 *e++ = *c++; 1288 *e = '\0'; 1289 1290 /* If instruction found then have already processed it. */ 1291 if (str_hash_find (tic4x_op_hash, name)) 1292 return; 1293 1294 do 1295 { 1296 inst = tic4x_inst_make (name, insts[k].opcode + 1297 (tic4x_conds[i].cond << 1298 (*s == 'B' ? 16 : 23)), 1299 insts[k].args); 1300 if (k == 0) /* Save strcmp() with following func. */ 1301 tic4x_inst_insert (inst); 1302 k++; 1303 } 1304 while (!strcmp (insts->name, 1305 insts[k].name)); 1306 } 1307 return; 1308 1309 case '\0': 1310 tic4x_inst_insert (insts); 1311 return; 1312 1313 default: 1314 *d++ = *s++; 1315 break; 1316 } 1317 } 1318 } 1319 1320 /* This function is called once, at assembler startup time. It should 1321 set up all the tables, etc., that the MD part of the assembler will 1322 need. */ 1323 void 1324 md_begin (void) 1325 { 1326 unsigned int i; 1327 1328 /* Setup the proper opcode level according to the 1329 commandline parameters */ 1330 tic4x_oplevel = OP_C3X; 1331 1332 if ( IS_CPU_TIC4X(tic4x_cpu) ) 1333 tic4x_oplevel |= OP_C4X; 1334 1335 if ( ( tic4x_cpu == 31 && tic4x_revision >= 6) 1336 || (tic4x_cpu == 32 && tic4x_revision >= 2) 1337 || (tic4x_cpu == 33) 1338 || tic4x_enhanced ) 1339 tic4x_oplevel |= OP_ENH; 1340 1341 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7) 1342 || (tic4x_cpu == 31 && tic4x_revision >= 5) 1343 || (tic4x_cpu == 32) 1344 || tic4x_lowpower ) 1345 tic4x_oplevel |= OP_LPWR; 1346 1347 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7) 1348 || (tic4x_cpu == 31 && tic4x_revision >= 5) 1349 || (tic4x_cpu == 32) 1350 || (tic4x_cpu == 33) 1351 || (tic4x_cpu == 40 && tic4x_revision >= 5) 1352 || (tic4x_cpu == 44) 1353 || tic4x_idle2 ) 1354 tic4x_oplevel |= OP_IDLE2; 1355 1356 /* Create hash table for mnemonics. */ 1357 tic4x_op_hash = str_htab_create (); 1358 1359 /* Create hash table for asg pseudo. */ 1360 tic4x_asg_hash = str_htab_create (); 1361 1362 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */ 1363 for (i = 0; i < tic4x_num_insts; i++) 1364 tic4x_inst_add (tic4x_insts + i); 1365 1366 /* Create dummy inst to avoid errors accessing end of table. */ 1367 tic4x_inst_make ("", 0, ""); 1368 1369 /* Add registers to symbol table. */ 1370 tic4x_init_regtable (); 1371 1372 /* Add predefined symbols to symbol table. */ 1373 tic4x_init_symbols (); 1374 } 1375 1376 void 1377 tic4x_md_finish (void) 1378 { 1379 bfd_set_arch_mach (stdoutput, bfd_arch_tic4x, 1380 IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x); 1381 } 1382 1383 static int 1384 tic4x_indirect_parse (tic4x_operand_t *operand, 1385 const tic4x_indirect_t *indirect) 1386 { 1387 const char *n = indirect->name; 1388 char *s = input_line_pointer; 1389 char *b; 1390 symbolS *symbolP; 1391 char name[32]; 1392 1393 operand->disp = 0; 1394 for (; *n; n++) 1395 { 1396 switch (*n) 1397 { 1398 case 'a': /* Need to match aux register. */ 1399 b = name; 1400 #ifdef TIC4X_ALT_SYNTAX 1401 if (*s == '%') 1402 s++; 1403 #endif 1404 while (ISALNUM (*s)) 1405 *b++ = *s++; 1406 *b++ = '\0'; 1407 if (!(symbolP = symbol_find (name))) 1408 return 0; 1409 1410 if (S_GET_SEGMENT (symbolP) != reg_section) 1411 return 0; 1412 1413 operand->aregno = S_GET_VALUE (symbolP); 1414 if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7) 1415 break; 1416 1417 as_bad (_("Auxiliary register AR0--AR7 required for indirect")); 1418 return -1; 1419 1420 case 'd': /* Need to match constant for disp. */ 1421 #ifdef TIC4X_ALT_SYNTAX 1422 if (*s == '%') /* expr() will die if we don't skip this. */ 1423 s++; 1424 #endif 1425 s = tic4x_expression (s, &operand->expr); 1426 if (operand->expr.X_op != O_constant) 1427 return 0; 1428 operand->disp = operand->expr.X_add_number; 1429 if (operand->disp < 0 || operand->disp > 255) 1430 { 1431 as_bad (_("Bad displacement %d (require 0--255)\n"), 1432 operand->disp); 1433 return -1; 1434 } 1435 break; 1436 1437 case 'y': /* Need to match IR0. */ 1438 case 'z': /* Need to match IR1. */ 1439 #ifdef TIC4X_ALT_SYNTAX 1440 if (*s == '%') 1441 s++; 1442 #endif 1443 s = tic4x_expression (s, &operand->expr); 1444 if (operand->expr.X_op != O_register) 1445 return 0; 1446 if (operand->expr.X_add_number != REG_IR0 1447 && operand->expr.X_add_number != REG_IR1) 1448 { 1449 as_bad (_("Index register IR0,IR1 required for displacement")); 1450 return -1; 1451 } 1452 1453 if (*n == 'y' && operand->expr.X_add_number == REG_IR0) 1454 break; 1455 if (*n == 'z' && operand->expr.X_add_number == REG_IR1) 1456 break; 1457 return 0; 1458 1459 case '(': 1460 if (*s != '(') /* No displacement, assume to be 1. */ 1461 { 1462 operand->disp = 1; 1463 while (*n != ')') 1464 n++; 1465 } 1466 else 1467 s++; 1468 break; 1469 1470 default: 1471 if (TOLOWER (*s) != *n) 1472 return 0; 1473 s++; 1474 } 1475 } 1476 if (*s != ' ' && *s != ',' && *s != '\0') 1477 return 0; 1478 input_line_pointer = s; 1479 return 1; 1480 } 1481 1482 static char * 1483 tic4x_operand_parse (char *s, tic4x_operand_t *operand) 1484 { 1485 unsigned int i; 1486 char c; 1487 int ret; 1488 expressionS *exp = &operand->expr; 1489 char *save = input_line_pointer; 1490 char *str; 1491 char *new_pointer; 1492 struct hash_entry *entry = NULL; 1493 1494 input_line_pointer = s; 1495 SKIP_WHITESPACE (); 1496 1497 c = get_symbol_name (&str); /* Get terminator. */ 1498 new_pointer = input_line_pointer; 1499 if (strlen (str) && (entry = str_hash_find (tic4x_asg_hash, str)) != NULL) 1500 { 1501 (void) restore_line_pointer (c); 1502 input_line_pointer = (char *) entry; 1503 } 1504 else 1505 { 1506 (void) restore_line_pointer (c); 1507 input_line_pointer = str; 1508 } 1509 1510 operand->mode = M_UNKNOWN; 1511 switch (*input_line_pointer) 1512 { 1513 #ifdef TIC4X_ALT_SYNTAX 1514 case '%': 1515 input_line_pointer = tic4x_expression (++input_line_pointer, exp); 1516 if (exp->X_op != O_register) 1517 as_bad (_("Expecting a register name")); 1518 operand->mode = M_REGISTER; 1519 break; 1520 1521 case '^': 1522 /* Denotes high 16 bits. */ 1523 input_line_pointer = tic4x_expression (++input_line_pointer, exp); 1524 if (exp->X_op == O_constant) 1525 operand->mode = M_IMMED; 1526 else if (exp->X_op == O_big) 1527 { 1528 if (exp->X_add_number) 1529 as_bad (_("Number too large")); /* bignum required */ 1530 else 1531 { 1532 tic4x_gen_to_words (generic_floating_point_number, 1533 operand->fwords, S_PRECISION); 1534 operand->mode = M_IMMED_F; 1535 } 1536 } 1537 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */ 1538 /* WARNING : The TI C40 assembler cannot do this. */ 1539 else if (exp->X_op == O_symbol) 1540 operand->mode = M_HI; 1541 else 1542 as_bad (_("Expecting a constant value")); 1543 break; 1544 1545 case '#': 1546 input_line_pointer = tic4x_expression (++input_line_pointer, exp); 1547 if (exp->X_op == O_constant) 1548 operand->mode = M_IMMED; 1549 else if (exp->X_op == O_big) 1550 { 1551 if (exp->X_add_number > 0) 1552 as_bad (_("Number too large")); /* bignum required. */ 1553 else 1554 { 1555 tic4x_gen_to_words (generic_floating_point_number, 1556 operand->fwords, S_PRECISION); 1557 operand->mode = M_IMMED_F; 1558 } 1559 } 1560 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */ 1561 /* WARNING : The TI C40 assembler cannot do this. */ 1562 else if (exp->X_op == O_symbol) 1563 operand->mode = M_IMMED; 1564 else 1565 as_bad (_("Expecting a constant value")); 1566 break; 1567 1568 case '\\': 1569 #endif 1570 case '@': 1571 input_line_pointer = tic4x_expression (++input_line_pointer, exp); 1572 if (exp->X_op != O_constant && exp->X_op != O_symbol) 1573 as_bad (_("Bad direct addressing construct %s"), s); 1574 if (exp->X_op == O_constant) 1575 { 1576 if (exp->X_add_number < 0) 1577 as_bad (_("Direct value of %ld is not suitable"), 1578 (long) exp->X_add_number); 1579 } 1580 operand->mode = M_DIRECT; 1581 break; 1582 1583 case '*': 1584 ret = -1; 1585 for (i = 0; i < tic4x_num_indirects; i++) 1586 if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i]))) 1587 break; 1588 if (ret < 0) 1589 break; 1590 if (i < tic4x_num_indirects) 1591 { 1592 operand->mode = M_INDIRECT; 1593 /* Indirect addressing mode number. */ 1594 operand->expr.X_add_number = tic4x_indirects[i].modn; 1595 /* Convert *+ARn(0) to *ARn etc. Maybe we should 1596 squeal about silly ones? */ 1597 if (operand->expr.X_add_number < 0x08 && !operand->disp) 1598 operand->expr.X_add_number = 0x18; 1599 } 1600 else 1601 as_bad (_("Unknown indirect addressing mode")); 1602 break; 1603 1604 default: 1605 operand->mode = M_IMMED; /* Assume immediate. */ 1606 str = input_line_pointer; 1607 input_line_pointer = tic4x_expression (input_line_pointer, exp); 1608 if (exp->X_op == O_register) 1609 { 1610 know (exp->X_add_symbol == 0); 1611 know (exp->X_op_symbol == 0); 1612 operand->mode = M_REGISTER; 1613 break; 1614 } 1615 else if (exp->X_op == O_big) 1616 { 1617 if (exp->X_add_number > 0) 1618 as_bad (_("Number too large")); /* bignum required. */ 1619 else 1620 { 1621 tic4x_gen_to_words (generic_floating_point_number, 1622 operand->fwords, S_PRECISION); 1623 operand->mode = M_IMMED_F; 1624 } 1625 break; 1626 } 1627 #ifdef TIC4X_ALT_SYNTAX 1628 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */ 1629 else if (exp->X_op == O_symbol) 1630 { 1631 operand->mode = M_DIRECT; 1632 break; 1633 } 1634 #endif 1635 } 1636 if (entry == NULL) 1637 new_pointer = input_line_pointer; 1638 input_line_pointer = save; 1639 return new_pointer; 1640 } 1641 1642 static int 1643 tic4x_operands_match (tic4x_inst_t *inst, tic4x_insn_t *tinsn, int check) 1644 { 1645 const char *args = inst->args; 1646 unsigned long opcode = inst->opcode; 1647 int num_operands = tinsn->num_operands; 1648 tic4x_operand_t *operand = tinsn->operands; 1649 expressionS *exp = &operand->expr; 1650 int ret = 1; 1651 int reg; 1652 1653 /* Build the opcode, checking as we go to make sure that the 1654 operands match. 1655 1656 If an operand matches, we modify insn or opcode appropriately, 1657 and do a "continue". If an operand fails to match, we "break". */ 1658 1659 tinsn->nchars = 4; /* Instructions always 4 bytes. */ 1660 tinsn->reloc = NO_RELOC; 1661 tinsn->pcrel = 0; 1662 1663 if (*args == '\0') 1664 { 1665 tinsn->opcode = opcode; 1666 return num_operands == 0; 1667 } 1668 1669 for (;; ++args) 1670 { 1671 switch (*args) 1672 { 1673 1674 case '\0': /* End of args. */ 1675 if (num_operands == 1) 1676 { 1677 tinsn->opcode = opcode; 1678 return ret; 1679 } 1680 break; /* Too many operands. */ 1681 1682 case '#': /* This is only used for ldp. */ 1683 if (operand->mode != M_DIRECT && operand->mode != M_IMMED) 1684 break; 1685 /* While this looks like a direct addressing mode, we actually 1686 use an immediate mode form of ldiu or ldpk instruction. */ 1687 if (exp->X_op == O_constant) 1688 { 1689 if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 ) 1690 || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) ) 1691 { 1692 INSERTS (opcode, exp->X_add_number, 15, 0); 1693 continue; 1694 } 1695 else 1696 { 1697 if (!check) 1698 as_bad (_("Immediate value of %ld is too large for ldf"), 1699 (long) exp->X_add_number); 1700 ret = -1; 1701 continue; 1702 } 1703 } 1704 else if (exp->X_op == O_symbol) 1705 { 1706 tinsn->reloc = BFD_RELOC_HI16; 1707 tinsn->exp = *exp; 1708 continue; 1709 } 1710 break; /* Not direct (dp) addressing. */ 1711 1712 case '@': /* direct. */ 1713 if (operand->mode != M_DIRECT) 1714 break; 1715 if (exp->X_op == O_constant) 1716 { 1717 /* Store only the 16 LSBs of the number. */ 1718 INSERTS (opcode, exp->X_add_number, 15, 0); 1719 continue; 1720 } 1721 else if (exp->X_op == O_symbol) 1722 { 1723 tinsn->reloc = BFD_RELOC_LO16; 1724 tinsn->exp = *exp; 1725 continue; 1726 } 1727 break; /* Not direct addressing. */ 1728 1729 case 'A': 1730 if (operand->mode != M_REGISTER) 1731 break; 1732 reg = exp->X_add_number; 1733 if (reg >= REG_AR0 && reg <= REG_AR7) 1734 INSERTU (opcode, reg - REG_AR0, 24, 22); 1735 else 1736 { 1737 if (!check) 1738 as_bad (_("Destination register must be ARn")); 1739 ret = -1; 1740 } 1741 continue; 1742 1743 case 'B': /* Unsigned integer immediate. */ 1744 /* Allow br label or br @label. */ 1745 if (operand->mode != M_IMMED && operand->mode != M_DIRECT) 1746 break; 1747 if (exp->X_op == O_constant) 1748 { 1749 if (exp->X_add_number < (1 << 24)) 1750 { 1751 INSERTU (opcode, exp->X_add_number, 23, 0); 1752 continue; 1753 } 1754 else 1755 { 1756 if (!check) 1757 as_bad (_("Immediate value of %ld is too large"), 1758 (long) exp->X_add_number); 1759 ret = -1; 1760 continue; 1761 } 1762 } 1763 if (IS_CPU_TIC4X (tic4x_cpu)) 1764 { 1765 tinsn->reloc = BFD_RELOC_24_PCREL; 1766 tinsn->pcrel = 1; 1767 } 1768 else 1769 { 1770 tinsn->reloc = BFD_RELOC_24; 1771 tinsn->pcrel = 0; 1772 } 1773 tinsn->exp = *exp; 1774 continue; 1775 1776 case 'C': 1777 if (!IS_CPU_TIC4X (tic4x_cpu)) 1778 break; 1779 if (operand->mode != M_INDIRECT) 1780 break; 1781 /* Require either *+ARn(disp) or *ARn. */ 1782 if (operand->expr.X_add_number != 0 1783 && operand->expr.X_add_number != 0x18) 1784 { 1785 if (!check) 1786 as_bad (_("Invalid indirect addressing mode")); 1787 ret = -1; 1788 continue; 1789 } 1790 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0); 1791 INSERTU (opcode, operand->disp, 7, 3); 1792 continue; 1793 1794 case 'E': 1795 if (!(operand->mode == M_REGISTER)) 1796 break; 1797 INSERTU (opcode, exp->X_add_number, 7, 0); 1798 continue; 1799 1800 case 'e': 1801 if (!(operand->mode == M_REGISTER)) 1802 break; 1803 reg = exp->X_add_number; 1804 if ( (reg >= REG_R0 && reg <= REG_R7) 1805 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) ) 1806 INSERTU (opcode, reg, 7, 0); 1807 else 1808 { 1809 if (!check) 1810 as_bad (_("Register must be Rn")); 1811 ret = -1; 1812 } 1813 continue; 1814 1815 case 'F': 1816 if (operand->mode != M_IMMED_F 1817 && !(operand->mode == M_IMMED && exp->X_op == O_constant)) 1818 break; 1819 1820 if (operand->mode != M_IMMED_F) 1821 { 1822 /* OK, we 've got something like cmpf 0, r0 1823 Why can't they stick in a bloody decimal point ?! */ 1824 char string[16]; 1825 1826 /* Create floating point number string. */ 1827 sprintf (string, "%d.0", (int) exp->X_add_number); 1828 tic4x_atof (string, 's', operand->fwords); 1829 } 1830 1831 INSERTU (opcode, operand->fwords[0], 15, 0); 1832 continue; 1833 1834 case 'G': 1835 if (operand->mode != M_REGISTER) 1836 break; 1837 INSERTU (opcode, exp->X_add_number, 15, 8); 1838 continue; 1839 1840 case 'g': 1841 if (operand->mode != M_REGISTER) 1842 break; 1843 reg = exp->X_add_number; 1844 if ( (reg >= REG_R0 && reg <= REG_R7) 1845 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) ) 1846 INSERTU (opcode, reg, 15, 8); 1847 else 1848 { 1849 if (!check) 1850 as_bad (_("Register must be Rn")); 1851 ret = -1; 1852 } 1853 continue; 1854 1855 case 'H': 1856 if (operand->mode != M_REGISTER) 1857 break; 1858 reg = exp->X_add_number; 1859 if (reg >= REG_R0 && reg <= REG_R7) 1860 INSERTU (opcode, reg - REG_R0, 18, 16); 1861 else 1862 { 1863 if (!check) 1864 as_bad (_("Register must be R0--R7")); 1865 ret = -1; 1866 } 1867 continue; 1868 1869 case 'i': 1870 if ( operand->mode == M_REGISTER 1871 && tic4x_oplevel & OP_ENH ) 1872 { 1873 reg = exp->X_add_number; 1874 INSERTU (opcode, reg, 4, 0); 1875 INSERTU (opcode, 7, 7, 5); 1876 continue; 1877 } 1878 /* Fallthrough */ 1879 1880 case 'I': 1881 if (operand->mode != M_INDIRECT) 1882 break; 1883 if (operand->disp != 0 && operand->disp != 1) 1884 { 1885 if (IS_CPU_TIC4X (tic4x_cpu)) 1886 break; 1887 if (!check) 1888 as_bad (_("Invalid indirect addressing mode displacement %d"), 1889 operand->disp); 1890 ret = -1; 1891 continue; 1892 } 1893 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0); 1894 INSERTU (opcode, operand->expr.X_add_number, 7, 3); 1895 continue; 1896 1897 case 'j': 1898 if ( operand->mode == M_REGISTER 1899 && tic4x_oplevel & OP_ENH ) 1900 { 1901 reg = exp->X_add_number; 1902 INSERTU (opcode, reg, 12, 8); 1903 INSERTU (opcode, 7, 15, 13); 1904 continue; 1905 } 1906 /* Fallthrough */ 1907 1908 case 'J': 1909 if (operand->mode != M_INDIRECT) 1910 break; 1911 if (operand->disp != 0 && operand->disp != 1) 1912 { 1913 if (IS_CPU_TIC4X (tic4x_cpu)) 1914 break; 1915 if (!check) 1916 as_bad (_("Invalid indirect addressing mode displacement %d"), 1917 operand->disp); 1918 ret = -1; 1919 continue; 1920 } 1921 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8); 1922 INSERTU (opcode, operand->expr.X_add_number, 15, 11); 1923 continue; 1924 1925 case 'K': 1926 if (operand->mode != M_REGISTER) 1927 break; 1928 reg = exp->X_add_number; 1929 if (reg >= REG_R0 && reg <= REG_R7) 1930 INSERTU (opcode, reg - REG_R0, 21, 19); 1931 else 1932 { 1933 if (!check) 1934 as_bad (_("Register must be R0--R7")); 1935 ret = -1; 1936 } 1937 continue; 1938 1939 case 'L': 1940 if (operand->mode != M_REGISTER) 1941 break; 1942 reg = exp->X_add_number; 1943 if (reg >= REG_R0 && reg <= REG_R7) 1944 INSERTU (opcode, reg - REG_R0, 24, 22); 1945 else 1946 { 1947 if (!check) 1948 as_bad (_("Register must be R0--R7")); 1949 ret = -1; 1950 } 1951 continue; 1952 1953 case 'M': 1954 if (operand->mode != M_REGISTER) 1955 break; 1956 reg = exp->X_add_number; 1957 if (reg == REG_R2 || reg == REG_R3) 1958 INSERTU (opcode, reg - REG_R2, 22, 22); 1959 else 1960 { 1961 if (!check) 1962 as_bad (_("Destination register must be R2 or R3")); 1963 ret = -1; 1964 } 1965 continue; 1966 1967 case 'N': 1968 if (operand->mode != M_REGISTER) 1969 break; 1970 reg = exp->X_add_number; 1971 if (reg == REG_R0 || reg == REG_R1) 1972 INSERTU (opcode, reg - REG_R0, 23, 23); 1973 else 1974 { 1975 if (!check) 1976 as_bad (_("Destination register must be R0 or R1")); 1977 ret = -1; 1978 } 1979 continue; 1980 1981 case 'O': 1982 if (!IS_CPU_TIC4X (tic4x_cpu)) 1983 break; 1984 if (operand->mode != M_INDIRECT) 1985 break; 1986 /* Require either *+ARn(disp) or *ARn. */ 1987 if (operand->expr.X_add_number != 0 1988 && operand->expr.X_add_number != 0x18) 1989 { 1990 if (!check) 1991 as_bad (_("Invalid indirect addressing mode")); 1992 ret = -1; 1993 continue; 1994 } 1995 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8); 1996 INSERTU (opcode, operand->disp, 15, 11); 1997 continue; 1998 1999 case 'P': /* PC relative displacement. */ 2000 /* Allow br label or br @label. */ 2001 if (operand->mode != M_IMMED && operand->mode != M_DIRECT) 2002 break; 2003 if (exp->X_op == O_constant) 2004 { 2005 if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767) 2006 { 2007 INSERTS (opcode, exp->X_add_number, 15, 0); 2008 continue; 2009 } 2010 else 2011 { 2012 if (!check) 2013 as_bad (_("Displacement value of %ld is too large"), 2014 (long) exp->X_add_number); 2015 ret = -1; 2016 continue; 2017 } 2018 } 2019 tinsn->reloc = BFD_RELOC_16_PCREL; 2020 tinsn->pcrel = 1; 2021 tinsn->exp = *exp; 2022 continue; 2023 2024 case 'Q': 2025 if (operand->mode != M_REGISTER) 2026 break; 2027 reg = exp->X_add_number; 2028 INSERTU (opcode, reg, 15, 0); 2029 continue; 2030 2031 case 'q': 2032 if (operand->mode != M_REGISTER) 2033 break; 2034 reg = exp->X_add_number; 2035 if ( (reg >= REG_R0 && reg <= REG_R7) 2036 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) ) 2037 INSERTU (opcode, reg, 15, 0); 2038 else 2039 { 2040 if (!check) 2041 as_bad (_("Register must be Rn")); 2042 ret = -1; 2043 } 2044 continue; 2045 2046 case 'R': 2047 if (operand->mode != M_REGISTER) 2048 break; 2049 reg = exp->X_add_number; 2050 INSERTU (opcode, reg, 20, 16); 2051 continue; 2052 2053 case 'r': 2054 if (operand->mode != M_REGISTER) 2055 break; 2056 reg = exp->X_add_number; 2057 if ( (reg >= REG_R0 && reg <= REG_R7) 2058 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) ) 2059 INSERTU (opcode, reg, 20, 16); 2060 else 2061 { 2062 if (!check) 2063 as_bad (_("Register must be Rn")); 2064 ret = -1; 2065 } 2066 continue; 2067 2068 case 'S': /* Short immediate int. */ 2069 if (operand->mode != M_IMMED && operand->mode != M_HI) 2070 break; 2071 if (exp->X_op == O_big) 2072 { 2073 if (!check) 2074 as_bad (_("Floating point number not valid in expression")); 2075 ret = -1; 2076 continue; 2077 } 2078 if (exp->X_op == O_constant) 2079 { 2080 if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535) 2081 { 2082 INSERTS (opcode, exp->X_add_number, 15, 0); 2083 continue; 2084 } 2085 else 2086 { 2087 if (!check) 2088 as_bad (_("Signed immediate value %ld too large"), 2089 (long) exp->X_add_number); 2090 ret = -1; 2091 continue; 2092 } 2093 } 2094 else if (exp->X_op == O_symbol) 2095 { 2096 if (operand->mode == M_HI) 2097 { 2098 tinsn->reloc = BFD_RELOC_HI16; 2099 } 2100 else 2101 { 2102 tinsn->reloc = BFD_RELOC_LO16; 2103 } 2104 tinsn->exp = *exp; 2105 continue; 2106 } 2107 /* Handle cases like ldi foo - $, ar0 where foo 2108 is a forward reference. Perhaps we should check 2109 for X_op == O_symbol and disallow things like 2110 ldi foo, ar0. */ 2111 tinsn->reloc = BFD_RELOC_16; 2112 tinsn->exp = *exp; 2113 continue; 2114 2115 case 'T': /* 5-bit immediate value for tic4x stik. */ 2116 if (!IS_CPU_TIC4X (tic4x_cpu)) 2117 break; 2118 if (operand->mode != M_IMMED) 2119 break; 2120 if (exp->X_op == O_constant) 2121 { 2122 if (exp->X_add_number < 16 && exp->X_add_number >= -16) 2123 { 2124 INSERTS (opcode, exp->X_add_number, 20, 16); 2125 continue; 2126 } 2127 else 2128 { 2129 if (!check) 2130 as_bad (_("Immediate value of %ld is too large"), 2131 (long) exp->X_add_number); 2132 ret = -1; 2133 continue; 2134 } 2135 } 2136 break; /* No relocations allowed. */ 2137 2138 case 'U': /* Unsigned integer immediate. */ 2139 if (operand->mode != M_IMMED && operand->mode != M_HI) 2140 break; 2141 if (exp->X_op == O_constant) 2142 { 2143 if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0) 2144 { 2145 INSERTU (opcode, exp->X_add_number, 15, 0); 2146 continue; 2147 } 2148 else 2149 { 2150 if (!check) 2151 as_bad (_("Unsigned immediate value %ld too large"), 2152 (long) exp->X_add_number); 2153 ret = -1; 2154 continue; 2155 } 2156 } 2157 else if (exp->X_op == O_symbol) 2158 { 2159 if (operand->mode == M_HI) 2160 tinsn->reloc = BFD_RELOC_HI16; 2161 else 2162 tinsn->reloc = BFD_RELOC_LO16; 2163 2164 tinsn->exp = *exp; 2165 continue; 2166 } 2167 tinsn->reloc = BFD_RELOC_16; 2168 tinsn->exp = *exp; 2169 continue; 2170 2171 case 'V': /* Trap numbers (immediate field). */ 2172 if (operand->mode != M_IMMED) 2173 break; 2174 if (exp->X_op == O_constant) 2175 { 2176 if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu)) 2177 { 2178 INSERTU (opcode, exp->X_add_number, 8, 0); 2179 continue; 2180 } 2181 else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu)) 2182 { 2183 INSERTU (opcode, exp->X_add_number | 0x20, 5, 0); 2184 continue; 2185 } 2186 else 2187 { 2188 if (!check) 2189 as_bad (_("Immediate value of %ld is too large"), 2190 (long) exp->X_add_number); 2191 ret = -1; 2192 continue; 2193 } 2194 } 2195 break; /* No relocations allowed. */ 2196 2197 case 'W': /* Short immediate int (0--7). */ 2198 if (!IS_CPU_TIC4X (tic4x_cpu)) 2199 break; 2200 if (operand->mode != M_IMMED) 2201 break; 2202 if (exp->X_op == O_big) 2203 { 2204 if (!check) 2205 as_bad (_("Floating point number not valid in expression")); 2206 ret = -1; 2207 continue; 2208 } 2209 if (exp->X_op == O_constant) 2210 { 2211 if (exp->X_add_number >= -256 && exp->X_add_number <= 127) 2212 { 2213 INSERTS (opcode, exp->X_add_number, 7, 0); 2214 continue; 2215 } 2216 else 2217 { 2218 if (!check) 2219 as_bad (_("Immediate value %ld too large"), 2220 (long) exp->X_add_number); 2221 ret = -1; 2222 continue; 2223 } 2224 } 2225 tinsn->reloc = BFD_RELOC_16; 2226 tinsn->exp = *exp; 2227 continue; 2228 2229 case 'X': /* Expansion register for tic4x. */ 2230 if (operand->mode != M_REGISTER) 2231 break; 2232 reg = exp->X_add_number; 2233 if (reg >= REG_IVTP && reg <= REG_TVTP) 2234 INSERTU (opcode, reg - REG_IVTP, 4, 0); 2235 else 2236 { 2237 if (!check) 2238 as_bad (_("Register must be ivtp or tvtp")); 2239 ret = -1; 2240 } 2241 continue; 2242 2243 case 'Y': /* Address register for tic4x lda. */ 2244 if (operand->mode != M_REGISTER) 2245 break; 2246 reg = exp->X_add_number; 2247 if (reg >= REG_AR0 && reg <= REG_SP) 2248 INSERTU (opcode, reg, 20, 16); 2249 else 2250 { 2251 if (!check) 2252 as_bad (_("Register must be address register")); 2253 ret = -1; 2254 } 2255 continue; 2256 2257 case 'Z': /* Expansion register for tic4x. */ 2258 if (operand->mode != M_REGISTER) 2259 break; 2260 reg = exp->X_add_number; 2261 if (reg >= REG_IVTP && reg <= REG_TVTP) 2262 INSERTU (opcode, reg - REG_IVTP, 20, 16); 2263 else 2264 { 2265 if (!check) 2266 as_bad (_("Register must be ivtp or tvtp")); 2267 ret = -1; 2268 } 2269 continue; 2270 2271 case '*': 2272 if (operand->mode != M_INDIRECT) 2273 break; 2274 INSERTS (opcode, operand->disp, 7, 0); 2275 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8); 2276 INSERTU (opcode, operand->expr.X_add_number, 15, 11); 2277 continue; 2278 2279 case '|': /* treat as `,' if have ldi_ldi form. */ 2280 if (tinsn->parallel) 2281 { 2282 if (--num_operands < 0) 2283 break; /* Too few operands. */ 2284 operand++; 2285 if (operand->mode != M_PARALLEL) 2286 break; 2287 } 2288 /* Fall through. */ 2289 2290 case ',': /* Another operand. */ 2291 if (--num_operands < 0) 2292 break; /* Too few operands. */ 2293 operand++; 2294 exp = &operand->expr; 2295 continue; 2296 2297 case ';': /* Another optional operand. */ 2298 if (num_operands == 1 || operand[1].mode == M_PARALLEL) 2299 continue; 2300 if (--num_operands < 0) 2301 break; /* Too few operands. */ 2302 operand++; 2303 exp = &operand->expr; 2304 continue; 2305 2306 default: 2307 BAD_CASE (*args); 2308 } 2309 return 0; 2310 } 2311 } 2312 2313 static void 2314 tic4x_insn_check (tic4x_insn_t *tinsn) 2315 { 2316 2317 if (!strcmp (tinsn->name, "lda")) 2318 { 2319 if (tinsn->num_operands < 2 || tinsn->num_operands > 2) 2320 as_fatal ("Illegal internal LDA insn definition"); 2321 2322 if (tinsn->operands[0].mode == M_REGISTER 2323 && tinsn->operands[1].mode == M_REGISTER 2324 && tinsn->operands[0].expr.X_add_number == tinsn->operands[1].expr.X_add_number ) 2325 as_bad (_("Source and destination register should not be equal")); 2326 } 2327 else if (!strcmp (tinsn->name, "ldi_ldi") 2328 || !strcmp (tinsn->name, "ldi1_ldi2") 2329 || !strcmp (tinsn->name, "ldi2_ldi1") 2330 || !strcmp (tinsn->name, "ldf_ldf") 2331 || !strcmp (tinsn->name, "ldf1_ldf2") 2332 || !strcmp (tinsn->name, "ldf2_ldf1") ) 2333 { 2334 if (tinsn->num_operands < 4 || tinsn->num_operands > 5) 2335 as_fatal ("Illegal internal %s insn definition", tinsn->name); 2336 2337 if (tinsn->operands[1].mode == M_REGISTER 2338 && tinsn->operands[tinsn->num_operands-1].mode == M_REGISTER 2339 && tinsn->operands[1].expr.X_add_number == tinsn->operands[tinsn->num_operands-1].expr.X_add_number ) 2340 as_warn (_("Equal parallel destination registers, one result will be discarded")); 2341 } 2342 } 2343 2344 static void 2345 tic4x_insn_output (tic4x_insn_t *tinsn) 2346 { 2347 char *dst; 2348 2349 /* Grab another fragment for opcode. */ 2350 dst = frag_more (tinsn->nchars); 2351 2352 /* Put out opcode word as a series of bytes in little endian order. */ 2353 md_number_to_chars (dst, tinsn->opcode, tinsn->nchars); 2354 2355 /* Put out the symbol-dependent stuff. */ 2356 if (tinsn->reloc != NO_RELOC) 2357 { 2358 /* Where is the offset into the fragment for this instruction. */ 2359 fix_new_exp (frag_now, 2360 dst - frag_now->fr_literal, /* where */ 2361 tinsn->nchars, /* size */ 2362 &tinsn->exp, 2363 tinsn->pcrel, 2364 tinsn->reloc); 2365 } 2366 } 2367 2368 /* Parse the operands. */ 2369 static int 2370 tic4x_operands_parse (char *s, tic4x_operand_t *operands, int num_operands) 2371 { 2372 if (!*s) 2373 return num_operands; 2374 2375 do 2376 s = tic4x_operand_parse (s, &operands[num_operands++]); 2377 while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ','); 2378 2379 if (num_operands > TIC4X_OPERANDS_MAX) 2380 { 2381 as_bad (_("Too many operands scanned")); 2382 return -1; 2383 } 2384 return num_operands; 2385 } 2386 2387 /* Assemble a single instruction. Its label has already been handled 2388 by the generic front end. We just parse mnemonic and operands, and 2389 produce the bytes of data and relocation. */ 2390 void 2391 md_assemble (char *str) 2392 { 2393 int ok = 0; 2394 char *s; 2395 int i; 2396 int parsed = 0; 2397 size_t len; 2398 tic4x_inst_t *inst; /* Instruction template. */ 2399 tic4x_inst_t *first_inst; 2400 2401 /* Scan for parallel operators */ 2402 if (str) 2403 { 2404 s = str; 2405 while (*s && *s != '|') 2406 s++; 2407 2408 if (*s && s[1]=='|') 2409 { 2410 if(insn->parallel) 2411 { 2412 as_bad (_("Parallel opcode cannot contain more than two instructions")); 2413 insn->parallel = 0; 2414 insn->in_use = 0; 2415 return; 2416 } 2417 2418 /* Lets take care of the first part of the parallel insn */ 2419 *s++ = 0; 2420 md_assemble(str); 2421 insn->parallel = 1; 2422 str = ++s; 2423 /* .. and let the second run though here */ 2424 } 2425 } 2426 2427 if (str && insn->parallel) 2428 { 2429 /* Find mnemonic (second part of parallel instruction). */ 2430 s = str; 2431 /* Skip past instruction mnemonic. */ 2432 while (*s && *s != ' ') 2433 s++; 2434 if (*s) /* Null terminate for str_hash_find. */ 2435 *s++ = '\0'; /* and skip past null. */ 2436 len = strlen (insn->name); 2437 snprintf (insn->name + len, TIC4X_NAME_MAX - len, "_%s", str); 2438 2439 insn->operands[insn->num_operands++].mode = M_PARALLEL; 2440 2441 if ((i = tic4x_operands_parse 2442 (s, insn->operands, insn->num_operands)) < 0) 2443 { 2444 insn->parallel = 0; 2445 insn->in_use = 0; 2446 return; 2447 } 2448 insn->num_operands = i; 2449 parsed = 1; 2450 } 2451 2452 if (insn->in_use) 2453 { 2454 if ((insn->inst = (struct tic4x_inst *) 2455 str_hash_find (tic4x_op_hash, insn->name)) == NULL) 2456 { 2457 as_bad (_("Unknown opcode `%s'."), insn->name); 2458 insn->parallel = 0; 2459 insn->in_use = 0; 2460 return; 2461 } 2462 2463 inst = insn->inst; 2464 first_inst = NULL; 2465 do 2466 { 2467 ok = tic4x_operands_match (inst, insn, 1); 2468 if (ok < 0) 2469 { 2470 if (!first_inst) 2471 first_inst = inst; 2472 ok = 0; 2473 } 2474 } 2475 while (!ok && !strcmp (inst->name, inst[1].name) && inst++); 2476 2477 if (ok > 0) 2478 { 2479 tic4x_insn_check (insn); 2480 tic4x_insn_output (insn); 2481 } 2482 else if (!ok) 2483 { 2484 if (first_inst) 2485 tic4x_operands_match (first_inst, insn, 0); 2486 as_bad (_("Invalid operands for %s"), insn->name); 2487 } 2488 else 2489 as_bad (_("Invalid instruction %s"), insn->name); 2490 } 2491 2492 if (str && !parsed) 2493 { 2494 /* Find mnemonic. */ 2495 s = str; 2496 while (*s && *s != ' ') /* Skip past instruction mnemonic. */ 2497 s++; 2498 if (*s) /* Null terminate for str_hash_find. */ 2499 *s++ = '\0'; /* and skip past null. */ 2500 strncpy (insn->name, str, TIC4X_NAME_MAX - 1); 2501 insn->name[TIC4X_NAME_MAX - 1] = '\0'; 2502 2503 if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0) 2504 { 2505 insn->inst = NULL; /* Flag that error occurred. */ 2506 insn->parallel = 0; 2507 insn->in_use = 0; 2508 return; 2509 } 2510 insn->num_operands = i; 2511 insn->in_use = 1; 2512 } 2513 else 2514 insn->in_use = 0; 2515 insn->parallel = 0; 2516 } 2517 2518 void 2519 tic4x_cleanup (void) 2520 { 2521 if (insn->in_use) 2522 md_assemble (NULL); 2523 } 2524 2525 /* Turn a string in input_line_pointer into a floating point constant 2526 of type type, and store the appropriate bytes in *litP. The number 2527 of chars emitted is stored in *sizeP. An error message is 2528 returned, or NULL on OK. */ 2529 2530 const char * 2531 md_atof (int type, char *litP, int *sizeP) 2532 { 2533 int prec; 2534 int ieee; 2535 LITTLENUM_TYPE words[MAX_LITTLENUMS]; 2536 LITTLENUM_TYPE *wordP; 2537 char *t; 2538 2539 switch (type) 2540 { 2541 case 's': /* .single */ 2542 case 'S': 2543 ieee = 0; 2544 prec = 1; 2545 break; 2546 2547 case 'd': /* .double */ 2548 case 'D': 2549 case 'f': /* .float */ 2550 case 'F': 2551 ieee = 0; 2552 prec = 2; /* 1 32-bit word */ 2553 break; 2554 2555 case 'i': /* .ieee */ 2556 case 'I': 2557 prec = 2; 2558 ieee = 1; 2559 type = 'f'; /* Rewrite type to be usable by atof_ieee(). */ 2560 break; 2561 2562 case 'e': /* .ldouble */ 2563 case 'E': 2564 prec = 4; /* 2 32-bit words */ 2565 ieee = 0; 2566 break; 2567 2568 default: 2569 *sizeP = 0; 2570 return _("Unrecognized or unsupported floating point constant"); 2571 } 2572 2573 if (ieee) 2574 t = atof_ieee (input_line_pointer, type, words); 2575 else 2576 t = tic4x_atof (input_line_pointer, type, words); 2577 if (t) 2578 input_line_pointer = t; 2579 *sizeP = prec * sizeof (LITTLENUM_TYPE); 2580 2581 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with 2582 little endian byte order. */ 2583 /* SES: However it is required to put the words (32-bits) out in the 2584 correct order, hence we write 2 and 2 littlenums in little endian 2585 order, while we keep the original order on successive words. */ 2586 for (wordP = words; wordP<(words+prec) ; wordP+=2) 2587 { 2588 if (wordP < (words + prec - 1)) /* Dump wordP[1] (if we have one). */ 2589 { 2590 md_number_to_chars (litP, (valueT) (wordP[1]), 2591 sizeof (LITTLENUM_TYPE)); 2592 litP += sizeof (LITTLENUM_TYPE); 2593 } 2594 2595 /* Dump wordP[0] */ 2596 md_number_to_chars (litP, (valueT) (wordP[0]), 2597 sizeof (LITTLENUM_TYPE)); 2598 litP += sizeof (LITTLENUM_TYPE); 2599 } 2600 return NULL; 2601 } 2602 2603 void 2604 md_apply_fix (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED) 2605 { 2606 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 2607 valueT val = *value; 2608 2609 switch (fixP->fx_r_type) 2610 { 2611 case BFD_RELOC_HI16: 2612 val >>= 16; 2613 break; 2614 2615 case BFD_RELOC_LO16: 2616 val &= 0xffff; 2617 break; 2618 default: 2619 break; 2620 } 2621 2622 switch (fixP->fx_r_type) 2623 { 2624 case BFD_RELOC_32: 2625 buf[3] = val >> 24; 2626 /* Fall through. */ 2627 case BFD_RELOC_24: 2628 case BFD_RELOC_24_PCREL: 2629 buf[2] = val >> 16; 2630 /* Fall through. */ 2631 case BFD_RELOC_16: 2632 case BFD_RELOC_16_PCREL: 2633 case BFD_RELOC_LO16: 2634 case BFD_RELOC_HI16: 2635 buf[1] = val >> 8; 2636 buf[0] = val; 2637 break; 2638 2639 case NO_RELOC: 2640 default: 2641 as_bad (_("Bad relocation type: 0x%02x"), fixP->fx_r_type); 2642 break; 2643 } 2644 2645 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1; 2646 } 2647 2648 /* Should never be called for tic4x. */ 2649 void 2650 md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, 2651 segT sec ATTRIBUTE_UNUSED, 2652 fragS *fragP ATTRIBUTE_UNUSED) 2653 { 2654 as_fatal ("md_convert_frag"); 2655 } 2656 2657 /* Should never be called for tic4x. */ 2658 void 2659 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED, 2660 addressT from_addr ATTRIBUTE_UNUSED, 2661 addressT to_addr ATTRIBUTE_UNUSED, 2662 fragS *frag ATTRIBUTE_UNUSED, 2663 symbolS *to_symbol ATTRIBUTE_UNUSED) 2664 { 2665 as_fatal ("md_create_short_jmp\n"); 2666 } 2667 2668 /* Should never be called for tic4x. */ 2669 void 2670 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED, 2671 addressT from_addr ATTRIBUTE_UNUSED, 2672 addressT to_addr ATTRIBUTE_UNUSED, 2673 fragS *frag ATTRIBUTE_UNUSED, 2674 symbolS *to_symbol ATTRIBUTE_UNUSED) 2675 { 2676 as_fatal ("md_create_long_jump\n"); 2677 } 2678 2679 /* Should never be called for tic4x. */ 2680 int 2681 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 2682 segT segtype ATTRIBUTE_UNUSED) 2683 { 2684 as_fatal ("md_estimate_size_before_relax\n"); 2685 return 0; 2686 } 2687 2688 2689 int 2690 md_parse_option (int c, const char *arg) 2691 { 2692 switch (c) 2693 { 2694 case OPTION_CPU: /* cpu brand */ 2695 if (TOLOWER (*arg) == 'c') 2696 arg++; 2697 tic4x_cpu = atoi (arg); 2698 if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu)) 2699 as_warn (_("Unsupported processor generation %d"), tic4x_cpu); 2700 break; 2701 2702 case OPTION_REV: /* cpu revision */ 2703 tic4x_revision = atoi (arg); 2704 break; 2705 2706 case 'b': 2707 as_warn (_("Option -b is depreciated, please use -mbig")); 2708 /* Fall through. */ 2709 case OPTION_BIG: /* big model */ 2710 tic4x_big_model = 1; 2711 break; 2712 2713 case 'p': 2714 as_warn (_("Option -p is depreciated, please use -mmemparm")); 2715 /* Fall through. */ 2716 case OPTION_MEMPARM: /* push args */ 2717 tic4x_reg_args = 0; 2718 break; 2719 2720 case 'r': 2721 as_warn (_("Option -r is depreciated, please use -mregparm")); 2722 /* Fall through. */ 2723 case OPTION_REGPARM: /* register args */ 2724 tic4x_reg_args = 1; 2725 break; 2726 2727 case 's': 2728 as_warn (_("Option -s is depreciated, please use -msmall")); 2729 /* Fall through. */ 2730 case OPTION_SMALL: /* small model */ 2731 tic4x_big_model = 0; 2732 break; 2733 2734 case OPTION_IDLE2: 2735 tic4x_idle2 = 1; 2736 break; 2737 2738 case OPTION_LOWPOWER: 2739 tic4x_lowpower = 1; 2740 break; 2741 2742 case OPTION_ENHANCED: 2743 tic4x_enhanced = 1; 2744 break; 2745 2746 default: 2747 return 0; 2748 } 2749 2750 return 1; 2751 } 2752 2753 void 2754 md_show_usage (FILE *stream) 2755 { 2756 fprintf (stream, 2757 _("\nTIC4X options:\n" 2758 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n" 2759 " 30 - TMS320C30\n" 2760 " 31 - TMS320C31, TMS320LC31\n" 2761 " 32 - TMS320C32\n" 2762 " 33 - TMS320VC33\n" 2763 " 40 - TMS320C40\n" 2764 " 44 - TMS320C44\n" 2765 " -mrev=REV set cpu hardware revision (integer numbers).\n" 2766 " Combinations of -mcpu and -mrev will enable/disable\n" 2767 " the appropriate options (-midle2, -mlowpower and\n" 2768 " -menhanced) according to the selected type\n" 2769 " -mbig select big memory model\n" 2770 " -msmall select small memory model (default)\n" 2771 " -mregparm select register parameters (default)\n" 2772 " -mmemparm select memory parameters\n" 2773 " -midle2 enable IDLE2 support\n" 2774 " -mlowpower enable LOPOWER and MAXSPEED support\n" 2775 " -menhanced enable enhanced opcode support\n")); 2776 } 2777 2778 /* This is called when a line is unrecognized. This is used to handle 2779 definitions of TI C3x tools style local labels $n where n is a single 2780 decimal digit. */ 2781 int 2782 tic4x_unrecognized_line (int c) 2783 { 2784 int lab; 2785 char *s; 2786 2787 if (c != '$' || ! ISDIGIT (input_line_pointer[0])) 2788 return 0; 2789 2790 s = input_line_pointer; 2791 2792 /* Let's allow multiple digit local labels. */ 2793 lab = 0; 2794 while (ISDIGIT (*s)) 2795 { 2796 lab = lab * 10 + *s - '0'; 2797 s++; 2798 } 2799 2800 if (dollar_label_defined (lab)) 2801 { 2802 as_bad (_("Label \"$%d\" redefined"), lab); 2803 return 0; 2804 } 2805 2806 define_dollar_label (lab); 2807 colon (dollar_label_name (lab, 0)); 2808 input_line_pointer = s + 1; 2809 2810 return 1; 2811 } 2812 2813 /* Handle local labels peculiar to us referred to in an expression. */ 2814 symbolS * 2815 md_undefined_symbol (char *name) 2816 { 2817 /* Look for local labels of the form $n. */ 2818 if (name[0] == '$' && ISDIGIT (name[1])) 2819 { 2820 symbolS *symbolP; 2821 char *s = name + 1; 2822 int lab = 0; 2823 2824 while (ISDIGIT ((unsigned char) *s)) 2825 { 2826 lab = lab * 10 + *s - '0'; 2827 s++; 2828 } 2829 if (dollar_label_defined (lab)) 2830 { 2831 name = dollar_label_name (lab, 0); 2832 symbolP = symbol_find (name); 2833 } 2834 else 2835 { 2836 name = dollar_label_name (lab, 1); 2837 symbolP = symbol_find_or_make (name); 2838 } 2839 2840 return symbolP; 2841 } 2842 return NULL; 2843 } 2844 2845 /* Parse an operand that is machine-specific. */ 2846 void 2847 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED) 2848 { 2849 } 2850 2851 /* Round up a section size to the appropriate boundary---do we need this? */ 2852 valueT 2853 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) 2854 { 2855 return size; /* Byte (i.e., 32-bit) alignment is fine? */ 2856 } 2857 2858 static int 2859 tic4x_pc_offset (unsigned int op) 2860 { 2861 /* Determine the PC offset for a C[34]x instruction. 2862 This could be simplified using some boolean algebra 2863 but at the expense of readability. */ 2864 switch (op >> 24) 2865 { 2866 case 0x60: /* br */ 2867 case 0x62: /* call (C4x) */ 2868 case 0x64: /* rptb (C4x) */ 2869 return 1; 2870 case 0x61: /* brd */ 2871 case 0x63: /* laj */ 2872 case 0x65: /* rptbd (C4x) */ 2873 return 3; 2874 case 0x66: /* swi */ 2875 case 0x67: 2876 return 0; 2877 default: 2878 break; 2879 } 2880 2881 switch ((op & 0xffe00000) >> 20) 2882 { 2883 case 0x6a0: /* bB */ 2884 case 0x720: /* callB */ 2885 case 0x740: /* trapB */ 2886 return 1; 2887 2888 case 0x6a2: /* bBd */ 2889 case 0x6a6: /* bBat */ 2890 case 0x6aa: /* bBaf */ 2891 case 0x722: /* lajB */ 2892 case 0x748: /* latB */ 2893 case 0x798: /* rptbd */ 2894 return 3; 2895 2896 default: 2897 break; 2898 } 2899 2900 switch ((op & 0xfe200000) >> 20) 2901 { 2902 case 0x6e0: /* dbB */ 2903 return 1; 2904 2905 case 0x6e2: /* dbBd */ 2906 return 3; 2907 2908 default: 2909 break; 2910 } 2911 2912 return 0; 2913 } 2914 2915 /* Exactly what point is a PC-relative offset relative TO? 2916 With the C3x we have the following: 2917 DBcond, Bcond disp + PC + 1 => PC 2918 DBcondD, BcondD disp + PC + 3 => PC 2919 */ 2920 long 2921 md_pcrel_from (fixS *fixP) 2922 { 2923 unsigned char *buf; 2924 unsigned int op; 2925 2926 buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where; 2927 op = ((unsigned) buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 2928 2929 return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) + 2930 tic4x_pc_offset (op); 2931 } 2932 2933 /* Fill the alignment area with NOP's on .text, unless fill-data 2934 was specified. */ 2935 int 2936 tic4x_do_align (int alignment, 2937 const char *fill, 2938 int len, 2939 int max) 2940 { 2941 /* Because we are talking lwords, not bytes, adjust alignment to do words */ 2942 alignment += 2; 2943 2944 if (alignment != 0 && !need_pass_2) 2945 { 2946 if (fill == NULL) 2947 { 2948 if (subseg_text_p (now_seg)) 2949 { 2950 char nop[4]; 2951 2952 md_number_to_chars (nop, TIC_NOP_OPCODE, 4); 2953 frag_align_pattern (alignment, nop, sizeof (nop), max); 2954 } 2955 else 2956 frag_align (alignment, 0, max); 2957 } 2958 else if (len <= 1) 2959 frag_align (alignment, *fill, max); 2960 else 2961 frag_align_pattern (alignment, fill, len, max); 2962 } 2963 2964 /* Return 1 to skip the default alignment function */ 2965 return 1; 2966 } 2967 2968 /* Look for and remove parallel instruction operator ||. */ 2969 void 2970 tic4x_start_line (void) 2971 { 2972 char *s = input_line_pointer; 2973 2974 SKIP_WHITESPACE (); 2975 2976 /* If parallel instruction prefix found at start of line, skip it. */ 2977 if (*input_line_pointer == '|' && input_line_pointer[1] == '|') 2978 { 2979 if (insn->in_use) 2980 { 2981 insn->parallel = 1; 2982 input_line_pointer ++; 2983 *input_line_pointer = ' '; 2984 /* So line counters get bumped. */ 2985 input_line_pointer[-1] = '\n'; 2986 } 2987 } 2988 else 2989 { 2990 /* Write out the previous insn here */ 2991 if (insn->in_use) 2992 md_assemble (NULL); 2993 input_line_pointer = s; 2994 } 2995 } 2996 2997 arelent * 2998 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixP) 2999 { 3000 arelent *reloc; 3001 3002 reloc = XNEW (arelent); 3003 3004 reloc->sym_ptr_ptr = XNEW (asymbol *); 3005 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 3006 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 3007 reloc->address /= OCTETS_PER_BYTE; 3008 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); 3009 if (reloc->howto == (reloc_howto_type *) NULL) 3010 { 3011 as_bad_where (fixP->fx_file, fixP->fx_line, 3012 _("Reloc %d not supported by object file format"), 3013 (int) fixP->fx_r_type); 3014 return NULL; 3015 } 3016 3017 if (fixP->fx_r_type == BFD_RELOC_HI16) 3018 reloc->addend = fixP->fx_offset; 3019 else 3020 reloc->addend = fixP->fx_addnumber; 3021 3022 return reloc; 3023 } 3024