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