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