1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998 Free Software Foundation.
3 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 Texas Instruments TMS320C30 machine specific gas.
24 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25 Bugs & suggestions are completely welcome. This is free software.
26 Please help us make it better.
30 #include "opcode/tic30.h"
32 /* put here all non-digit non-letter charcters that may occur in an operand */
33 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
34 static char *ordinal_names[] =
35 {"first", "second", "third", "fourth", "fifth"};
37 const int md_reloc_size = 0;
38 int md_long_jump_size = 0;
39 int md_short_jump_size = 0;
41 const char comment_chars[] = ";";
42 const char line_comment_chars[] = "*";
43 const char line_separator_chars[] = "";
45 const char *md_shortopts = "";
46 struct option md_longopts[] =
48 {NULL, no_argument, NULL, 0}
51 size_t md_longopts_size = sizeof (md_longopts);
53 /* Chars that mean this number is a floating point constant */
56 const char FLT_CHARS[] = "fFdDxX";
58 /* Chars that can be used to separate mant from exp in floating point nums */
59 const char EXP_CHARS[] = "eE";
61 /* tables for lexical analysis */
62 static char opcode_chars[256];
63 static char register_chars[256];
64 static char operand_chars[256];
65 static char space_chars[256];
66 static char identifier_chars[256];
67 static char digit_chars[256];
70 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
71 #define is_operand_char(x) (operand_chars[(unsigned char) x])
72 #define is_register_char(x) (register_chars[(unsigned char) x])
73 #define is_space_char(x) (space_chars[(unsigned char) x])
74 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
75 #define is_digit_char(x) (digit_chars[(unsigned char) x])
77 const pseudo_typeS md_pseudo_table[] =
90 debug (const char *string,...)
97 va_start (argptr, string);
98 vsprintf (str, string, argptr);
102 fputs (str, USE_STDOUT ? stdout : stderr);
110 debug (string, va_alist)
120 va_start (argptr, string);
121 cnt = vsprintf (str, string, argptr);
125 fputs (str, USE_STDOUT ? stdout : stderr);
133 /* hash table for opcode lookup */
134 static struct hash_control *op_hash;
135 /* hash table for parallel opcode lookup */
136 static struct hash_control *parop_hash;
137 /* hash table for register lookup */
138 static struct hash_control *reg_hash;
139 /* hash table for indirect addressing lookup */
140 static struct hash_control *ind_hash;
145 const char *hash_err;
146 debug ("In md_begin()\n");
147 op_hash = hash_new ();
149 const template *current_optab = tic30_optab;
150 for (; current_optab < tic30_optab_end; current_optab++)
152 hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
154 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
157 parop_hash = hash_new ();
159 const partemplate *current_parop = tic30_paroptab;
160 for (; current_parop < tic30_paroptab_end; current_parop++)
162 hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
164 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
167 reg_hash = hash_new ();
169 const reg *current_reg = tic30_regtab;
170 for (; current_reg < tic30_regtab_end; current_reg++)
172 hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
174 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
177 ind_hash = hash_new ();
179 const ind_addr_type *current_ind = tic30_indaddr_tab;
180 for (; current_ind < tic30_indaddrtab_end; current_ind++)
182 hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
184 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
187 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
192 for (c = 0; c < 256; c++)
194 if (islower (c) || isdigit (c))
197 register_chars[c] = c;
199 else if (isupper (c))
201 opcode_chars[c] = tolower (c);
202 register_chars[c] = opcode_chars[c];
204 else if (c == ')' || c == '(')
206 register_chars[c] = c;
208 if (isupper (c) || islower (c) || isdigit (c))
209 operand_chars[c] = c;
210 if (isdigit (c) || c == '-')
212 if (isalpha (c) || c == '_' || c == '.' || isdigit (c))
213 identifier_chars[c] = c;
214 if (c == ' ' || c == '\t')
219 for (p = operand_special_chars; *p != '\0'; p++)
220 operand_chars[(unsigned char) *p] = *p;
224 /* Address Mode OR values */
225 #define AM_Register 0x00000000
226 #define AM_Direct 0x00200000
227 #define AM_Indirect 0x00400000
228 #define AM_Immediate 0x00600000
229 #define AM_NotReq 0xFFFFFFFF
231 /* PC Relative OR values */
232 #define PC_Register 0x00000000
233 #define PC_Relative 0x02000000
243 expressionS direct_expr;
264 unsigned int u_number;
266 expressionS imm_expr;
272 int tic30_parallel_insn PARAMS ((char *));
273 operand *tic30_operand PARAMS ((char *));
274 char *tic30_find_parallel_insn PARAMS ((char *, char *));
280 template *tm; /* Template of current instruction */
281 unsigned opcode; /* Final opcode */
282 int operands; /* Number of given operands */
283 /* Type of operand given in instruction */
284 operand *operand_type[MAX_OPERANDS];
285 unsigned addressing_mode; /* Final addressing mode of instruction */
288 struct tic30_insn insn;
289 static int found_parallel_insn;
301 debug ("In md_assemble() with argument %s\n", line);
302 memset (&insn, '\0', sizeof (insn));
303 if (found_parallel_insn)
305 debug ("Line is second part of parallel instruction\n\n");
306 found_parallel_insn = 0;
309 if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
312 found_parallel_insn = 1;
313 while (is_space_char (*current_posn))
315 token_start = current_posn;
316 if (!is_opcode_char (*current_posn))
318 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
321 /* Check if instruction is a parallel instruction by seeing if the first
323 if (*token_start == 'q')
325 if (tic30_parallel_insn (token_start))
327 if (found_parallel_insn)
332 while (is_opcode_char (*current_posn))
334 { /* Find instruction */
335 save_char = *current_posn;
336 *current_posn = '\0';
337 opcode = (template *) hash_find (op_hash, token_start);
340 debug ("Found instruction %s\n", opcode->name);
345 debug ("Didn't find insn\n");
346 as_bad ("Unknown TMS320C30 instruction: %s", token_start);
349 *current_posn = save_char;
351 if (*current_posn != END_OF_INSN)
352 { /* Find operands */
353 int paren_not_balanced;
354 int expecting_operand = 0;
358 /* skip optional white space before operand */
359 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
361 if (!is_space_char (*current_posn))
363 as_bad ("Invalid character %s before %s operand",
364 output_invalid (*current_posn),
365 ordinal_names[insn.operands]);
370 token_start = current_posn; /* after white space */
371 paren_not_balanced = 0;
372 while (paren_not_balanced || *current_posn != ',')
374 if (*current_posn == END_OF_INSN)
376 if (paren_not_balanced)
378 as_bad ("Unbalanced parenthesis in %s operand.",
379 ordinal_names[insn.operands]);
383 break; /* we are done */
385 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
387 as_bad ("Invalid character %s in %s operand",
388 output_invalid (*current_posn),
389 ordinal_names[insn.operands]);
392 if (*current_posn == '(')
393 ++paren_not_balanced;
394 if (*current_posn == ')')
395 --paren_not_balanced;
398 if (current_posn != token_start)
399 { /* yes, we've read in another operand */
400 this_operand = insn.operands++;
401 if (insn.operands > MAX_OPERANDS)
403 as_bad ("Spurious operands; (%d operands/instruction max)",
407 /* now parse operand adding info to 'insn' as we go along */
408 save_char = *current_posn;
409 *current_posn = '\0';
410 insn.operand_type[this_operand] = tic30_operand (token_start);
411 *current_posn = save_char;
412 if (insn.operand_type[this_operand] == NULL)
417 if (expecting_operand)
419 as_bad ("Expecting operand after ','; got nothing");
422 if (*current_posn == ',')
424 as_bad ("Expecting operand before ','; got nothing");
428 /* now *current_posn must be either ',' or END_OF_INSN */
429 if (*current_posn == ',')
431 if (*++current_posn == END_OF_INSN)
432 { /* just skip it, if it's \n complain */
433 as_bad ("Expecting operand after ','; got nothing");
436 expecting_operand = 1;
439 while (*current_posn != END_OF_INSN); /* until we get end of insn */
441 debug ("Number of operands found: %d\n", insn.operands);
442 /* Check that number of operands is correct */
443 if (insn.operands != insn.tm->operands)
446 int numops = insn.tm->operands;
447 /* If operands are not the same, then see if any of the operands are not
448 required. Then recheck with number of given operands. If they are still not
449 the same, then give an error, otherwise carry on. */
450 for (i = 0; i < insn.tm->operands; i++)
451 if (insn.tm->operand_types[i] & NotReq)
453 if (insn.operands != numops)
455 as_bad ("Incorrect number of operands given");
459 insn.addressing_mode = AM_NotReq;
460 for (count = 0; count < insn.operands; count++)
462 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
464 debug ("Operand %d matches\n", count + 1);
465 /* If instruction has two operands and has an AddressMode modifier then set
466 addressing mode type for instruction */
467 if (insn.tm->opcode_modifier == AddressMode)
470 /* Store instruction uses the second operand for the address mode. */
471 if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
473 if (insn.operand_type[addr_insn]->op_type & (AllReg))
474 insn.addressing_mode = AM_Register;
475 else if (insn.operand_type[addr_insn]->op_type & Direct)
476 insn.addressing_mode = AM_Direct;
477 else if (insn.operand_type[addr_insn]->op_type & Indirect)
478 insn.addressing_mode = AM_Indirect;
480 insn.addressing_mode = AM_Immediate;
485 as_bad ("The %s operand doesn't match", ordinal_names[count]);
489 /* Now set the addressing mode for 3 operand instructions. */
490 if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
492 /* Set the addressing mode to the values used for 2 operand instructions in the
493 G addressing field of the opcode. */
495 switch (insn.operand_type[0]->op_type)
501 if (insn.operand_type[1]->op_type & (AllReg))
502 insn.addressing_mode = AM_Register;
503 else if (insn.operand_type[1]->op_type & Indirect)
504 insn.addressing_mode = AM_Direct;
507 /* Shouldn't make it to this stage */
508 as_bad ("Incompatible first and second operands in instruction");
513 if (insn.operand_type[1]->op_type & (AllReg))
514 insn.addressing_mode = AM_Indirect;
515 else if (insn.operand_type[1]->op_type & Indirect)
516 insn.addressing_mode = AM_Immediate;
519 /* Shouldn't make it to this stage */
520 as_bad ("Incompatible first and second operands in instruction");
525 /* Now make up the opcode for the 3 operand instructions. As in parallel
526 instructions, there will be no unresolved values, so they can be fully formed
527 and added to the frag table. */
528 insn.opcode = insn.tm->base_opcode;
529 if (insn.operand_type[0]->op_type & Indirect)
531 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
532 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
535 insn.opcode |= (insn.operand_type[0]->reg.opcode);
536 if (insn.operand_type[1]->op_type & Indirect)
538 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
539 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
542 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
543 if (insn.operands == 3)
544 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
545 insn.opcode |= insn.addressing_mode;
546 p = frag_more (INSN_SIZE);
547 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
550 { /* Not a three operand instruction */
553 insn.opcode = insn.tm->base_opcode;
554 /* Create frag for instruction - all instructions are 4 bytes long. */
555 p = frag_more (INSN_SIZE);
556 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
558 insn.opcode |= insn.addressing_mode;
559 if (insn.addressing_mode == AM_Indirect)
561 /* Determine which operand gives the addressing mode */
562 if (insn.operand_type[0]->op_type & Indirect)
564 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
566 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
567 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
568 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
569 if (insn.operands > 1)
570 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
571 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
573 else if (insn.addressing_mode == AM_Register)
575 insn.opcode |= (insn.operand_type[0]->reg.opcode);
576 if (insn.operands > 1)
577 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
578 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
580 else if (insn.addressing_mode == AM_Direct)
582 if (insn.operand_type[0]->op_type & Direct)
584 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
586 if (insn.operands > 1)
587 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
588 if (insn.operand_type[am_insn]->direct.resolved == 1)
590 /* Resolved values can be placed straight into instruction word, and output */
591 insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
592 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
595 { /* Unresolved direct addressing mode instruction */
596 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
597 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
600 else if (insn.addressing_mode == AM_Immediate)
602 if (insn.operand_type[0]->immediate.resolved == 1)
606 if (insn.operands > 1)
607 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
608 switch (insn.tm->imm_arg_type)
611 debug ("Floating point first operand\n");
612 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
613 keeploc = input_line_pointer;
614 input_line_pointer = insn.operand_type[0]->immediate.label;
615 if (md_atof ('f', p + 2, &size) != 0)
617 as_bad ("invalid short form floating point immediate operand");
620 input_line_pointer = keeploc;
623 debug ("Unsigned int first operand\n");
624 if (insn.operand_type[0]->immediate.decimal_found)
625 as_warn ("rounding down first operand float to unsigned int");
626 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
627 as_warn ("only lower 16-bits of first operand are used");
628 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
629 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
632 debug ("Int first operand\n");
633 if (insn.operand_type[0]->immediate.decimal_found)
634 as_warn ("rounding down first operand float to signed int");
635 if (insn.operand_type[0]->immediate.s_number < -32768 ||
636 insn.operand_type[0]->immediate.s_number > 32767)
638 as_bad ("first operand is too large for 16-bit signed int");
641 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
642 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
647 { /* Unresolved immediate label */
648 if (insn.operands > 1)
649 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
650 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
651 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
655 else if (insn.tm->opcode_modifier == PCRel)
657 /* Conditional Branch and Call instructions */
658 if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
660 if (insn.operand_type[0]->op_type & (AllReg))
662 insn.opcode |= (insn.operand_type[0]->reg.opcode);
663 insn.opcode |= PC_Register;
664 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
668 insn.opcode |= PC_Relative;
669 if (insn.operand_type[0]->immediate.resolved == 1)
671 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
672 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
676 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
677 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
681 else if ((insn.tm->operand_types[0] & ARn) == ARn)
683 /* Decrement and Branch instructions */
684 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
685 if (insn.operand_type[1]->op_type & (AllReg))
687 insn.opcode |= (insn.operand_type[1]->reg.opcode);
688 insn.opcode |= PC_Register;
689 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
691 else if (insn.operand_type[1]->immediate.resolved == 1)
693 if (insn.operand_type[0]->immediate.decimal_found)
695 as_bad ("first operand is floating point");
698 if (insn.operand_type[0]->immediate.s_number < -32768 ||
699 insn.operand_type[0]->immediate.s_number > 32767)
701 as_bad ("first operand is too large for 16-bit signed int");
704 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
705 insn.opcode |= PC_Relative;
706 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
710 insn.opcode |= PC_Relative;
711 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
712 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
716 else if (insn.tm->operand_types[0] == IVector)
718 /* Trap instructions */
719 if (insn.operand_type[0]->op_type & IVector)
720 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
722 { /* Shouldn't get here */
723 as_bad ("interrupt vector for trap instruction out of range");
726 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
728 else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
730 /* Push, Pop and Rotate instructions */
731 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
732 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
734 else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
736 /* LDP Instruction needs to be tested for before the next section */
737 if (insn.operand_type[0]->op_type & Direct)
739 if (insn.operand_type[0]->direct.resolved == 1)
741 /* Direct addressing uses lower 8 bits of direct address */
742 insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
743 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
748 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
749 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
750 /* Ensure that the assembler doesn't complain about fitting a 24-bit
751 address into 8 bits. */
752 fix->fx_no_overflow = 1;
757 if (insn.operand_type[0]->immediate.resolved == 1)
759 /* Immediate addressing uses upper 8 bits of address */
760 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
762 as_bad ("LDP instruction needs a 24-bit operand");
765 insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
766 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
771 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
772 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
773 fix->fx_no_overflow = 1;
777 else if (insn.tm->operand_types[0] & (Imm24))
779 /* Unconditional Branch and Call instructions */
780 if (insn.operand_type[0]->immediate.resolved == 1)
782 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
783 as_warn ("first operand is too large for a 24-bit displacement");
784 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
785 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
789 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
790 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
793 else if (insn.tm->operand_types[0] & NotReq)
795 /* Check for NOP instruction without arguments. */
796 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
798 else if (insn.tm->operands == 0)
800 /* Check for instructions without operands. */
801 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
804 debug ("Addressing mode: %08X\n", insn.addressing_mode);
807 for (i = 0; i < insn.operands; i++)
809 if (insn.operand_type[i]->immediate.label)
810 free (insn.operand_type[i]->immediate.label);
811 free (insn.operand_type[i]);
814 debug ("Final opcode: %08X\n", insn.opcode);
818 struct tic30_par_insn
820 partemplate *tm; /* Template of current parallel instruction */
821 int operands[2]; /* Number of given operands for each insn */
822 /* Type of operand given in instruction */
823 operand *operand_type[2][MAX_OPERANDS];
824 int swap_operands; /* Whether to swap operands around. */
825 unsigned p_field; /* Value of p field in multiply add/sub instructions */
826 unsigned opcode; /* Final opcode */
829 struct tic30_par_insn p_insn;
832 tic30_parallel_insn (char *token)
834 static partemplate *p_opcode;
835 char *current_posn = token;
839 debug ("In tic30_parallel_insn with %s\n", token);
840 memset (&p_insn, '\0', sizeof (p_insn));
841 while (is_opcode_char (*current_posn))
843 { /* Find instruction */
844 save_char = *current_posn;
845 *current_posn = '\0';
846 p_opcode = (partemplate *) hash_find (parop_hash, token);
849 debug ("Found instruction %s\n", p_opcode->name);
850 p_insn.tm = p_opcode;
854 char first_opcode[6] =
856 char second_opcode[6] =
859 int current_opcode = -1;
862 for (i = 0; i < strlen (token); i++)
864 char ch = *(token + i);
865 if (ch == '_' && current_opcode == -1)
870 if (ch == '_' && current_opcode == 0)
876 switch (current_opcode)
879 first_opcode[char_ptr++] = ch;
882 second_opcode[char_ptr++] = ch;
886 debug ("first_opcode = %s\n", first_opcode);
887 debug ("second_opcode = %s\n", second_opcode);
888 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
889 p_opcode = (partemplate *) hash_find (parop_hash, token);
892 debug ("Found instruction %s\n", p_opcode->name);
893 p_insn.tm = p_opcode;
894 p_insn.swap_operands = 1;
899 *current_posn = save_char;
901 { /* Find operands */
902 int paren_not_balanced;
903 int expecting_operand = 0;
904 int found_separator = 0;
907 /* skip optional white space before operand */
908 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
910 if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
912 as_bad ("Invalid character %s before %s operand",
913 output_invalid (*current_posn),
914 ordinal_names[insn.operands]);
917 if (*current_posn == PARALLEL_SEPARATOR)
921 token_start = current_posn; /* after white space */
922 paren_not_balanced = 0;
923 while (paren_not_balanced || *current_posn != ',')
925 if (*current_posn == END_OF_INSN)
927 if (paren_not_balanced)
929 as_bad ("Unbalanced parenthesis in %s operand.",
930 ordinal_names[insn.operands]);
934 break; /* we are done */
936 else if (*current_posn == PARALLEL_SEPARATOR)
938 while (is_space_char (*(current_posn - 1)))
942 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
944 as_bad ("Invalid character %s in %s operand",
945 output_invalid (*current_posn),
946 ordinal_names[insn.operands]);
949 if (*current_posn == '(')
950 ++paren_not_balanced;
951 if (*current_posn == ')')
952 --paren_not_balanced;
955 if (current_posn != token_start)
956 { /* yes, we've read in another operand */
957 p_insn.operands[found_separator]++;
958 if (p_insn.operands[found_separator] > MAX_OPERANDS)
960 as_bad ("Spurious operands; (%d operands/instruction max)",
964 /* now parse operand adding info to 'insn' as we go along */
965 save_char = *current_posn;
966 *current_posn = '\0';
967 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
968 tic30_operand (token_start);
969 *current_posn = save_char;
970 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
975 if (expecting_operand)
977 as_bad ("Expecting operand after ','; got nothing");
980 if (*current_posn == ',')
982 as_bad ("Expecting operand before ','; got nothing");
986 /* now *current_posn must be either ',' or END_OF_INSN */
987 if (*current_posn == ',')
989 if (*++current_posn == END_OF_INSN)
990 { /* just skip it, if it's \n complain */
991 as_bad ("Expecting operand after ','; got nothing");
994 expecting_operand = 1;
997 while (*current_posn != END_OF_INSN); /* until we get end of insn */
999 if (p_insn.swap_operands)
1004 temp_num = p_insn.operands[0];
1005 p_insn.operands[0] = p_insn.operands[1];
1006 p_insn.operands[1] = temp_num;
1007 for (i = 0; i < MAX_OPERANDS; i++)
1009 temp_op = p_insn.operand_type[0][i];
1010 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
1011 p_insn.operand_type[1][i] = temp_op;
1014 if (p_insn.operands[0] != p_insn.tm->operands_1)
1016 as_bad ("incorrect number of operands given in the first instruction");
1019 if (p_insn.operands[1] != p_insn.tm->operands_2)
1021 as_bad ("incorrect number of operands given in the second instruction");
1024 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
1025 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
1026 { /* Now check if operands are correct */
1030 for (count = 0; count < 2; count++)
1033 for (i = 0; i < p_insn.operands[count]; i++)
1035 if ((p_insn.operand_type[count][i]->op_type &
1036 p_insn.tm->operand_types[count][i]) == 0)
1038 as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
1041 /* Get number of R register and indirect reference contained within the first
1042 two operands of each instruction. This is required for the multiply
1043 parallel instructions which require two R registers and two indirect
1044 references, but not in any particular place. */
1045 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
1047 else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
1051 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
1053 /* Check for the multiply instructions */
1056 as_bad ("incorrect format for multiply parallel instruction");
1060 { /* Shouldn't get here */
1061 as_bad ("incorrect format for multiply parallel instruction");
1064 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
1065 (p_insn.operand_type[0][2]->reg.opcode != 0x01))
1067 as_bad ("destination for multiply can only be R0 or R1");
1070 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
1071 (p_insn.operand_type[1][2]->reg.opcode != 0x03))
1073 as_bad ("destination for add/subtract can only be R2 or R3");
1076 /* Now determine the P field for the instruction */
1077 if (p_insn.operand_type[0][0]->op_type & Indirect)
1079 if (p_insn.operand_type[0][1]->op_type & Indirect)
1080 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
1081 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1082 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
1084 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
1088 if (p_insn.operand_type[0][1]->op_type & Rn)
1089 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
1090 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1093 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
1094 /* Need to swap the two multiply operands around so that everything is in
1095 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1096 temp = p_insn.operand_type[0][0];
1097 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1098 p_insn.operand_type[0][1] = temp;
1103 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
1104 temp = p_insn.operand_type[0][0];
1105 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1106 p_insn.operand_type[0][1] = temp;
1111 debug ("P field: %08X\n", p_insn.p_field);
1112 /* Finalise opcode. This is easier for parallel instructions as they have to be
1113 fully resolved, there are no memory addresses allowed, except through indirect
1114 addressing, so there are no labels to resolve. */
1116 p_insn.opcode = p_insn.tm->base_opcode;
1117 switch (p_insn.tm->oporder)
1120 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1121 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1122 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1123 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1124 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1125 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1128 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1129 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1130 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1131 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1132 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1133 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1134 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1135 as_warn ("loading the same register in parallel operation");
1138 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1139 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1140 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1141 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1142 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1143 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1146 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1147 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1148 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1149 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1150 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1151 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1152 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1155 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1156 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1157 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1158 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1159 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1160 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1161 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1164 p_insn.opcode |= p_insn.p_field;
1165 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1166 p_insn.opcode |= 0x00800000;
1167 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1168 p_insn.opcode |= 0x00400000;
1169 switch (p_insn.p_field)
1172 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1173 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1174 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1175 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1176 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1177 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1180 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1181 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1182 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1183 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1184 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1185 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1188 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1189 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1190 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1191 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1192 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1193 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1196 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1197 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1198 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1199 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1200 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1201 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1206 } /* Opcode is finalised at this point for all parallel instructions. */
1207 { /* Output opcode */
1209 p = frag_more (INSN_SIZE);
1210 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1214 for (i = 0; i < 2; i++)
1215 for (j = 0; j < p_insn.operands[i]; j++)
1216 free (p_insn.operand_type[i][j]);
1218 debug ("Final opcode: %08X\n", p_insn.opcode);
1224 tic30_operand (token)
1228 char ind_buffer[strlen (token)];
1229 operand *current_op;
1231 debug ("In tic30_operand with %s\n", token);
1232 current_op = (operand *) malloc (sizeof (operand));
1233 memset (current_op, '\0', sizeof (operand));
1234 if (*token == DIRECT_REFERENCE)
1236 char *token_posn = token + 1;
1237 int direct_label = 0;
1238 debug ("Found direct reference\n");
1241 if (!is_digit_char (*token_posn))
1247 char *save_input_line_pointer;
1249 debug ("Direct reference is a label\n");
1250 current_op->direct.label = token + 1;
1251 save_input_line_pointer = input_line_pointer;
1252 input_line_pointer = token + 1;
1253 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1254 retval = expression (¤t_op->direct.direct_expr);
1255 debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
1256 debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
1257 debug ("Segment: %d\n", retval);
1258 input_line_pointer = save_input_line_pointer;
1259 if (current_op->direct.direct_expr.X_op == O_constant)
1261 current_op->direct.address = current_op->direct.direct_expr.X_add_number;
1262 current_op->direct.resolved = 1;
1267 debug ("Direct reference is a number\n");
1268 current_op->direct.address = atoi (token + 1);
1269 current_op->direct.resolved = 1;
1271 current_op->op_type = Direct;
1273 else if (*token == INDIRECT_REFERENCE)
1274 { /* Indirect reference operand */
1278 int disp_number = 0;
1279 int buffer_posn = 1;
1280 ind_addr_type *ind_addr_op;
1281 debug ("Found indirect reference\n");
1282 ind_buffer[0] = *token;
1283 for (count = 1; count < strlen (token); count++)
1284 { /* Strip operand */
1285 ind_buffer[buffer_posn] = tolower (*(token + count));
1286 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
1287 (*(token + count) == 'r' || *(token + count) == 'R'))
1289 /* AR reference is found, so get its number and remove it from the buffer
1290 so it can pass through hash_find() */
1293 as_bad ("More than one AR register found in indirect reference");
1296 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
1298 as_bad ("Illegal AR register in indirect reference");
1301 ar_number = *(token + count + 1) - '0';
1305 if (*(token + count) == '(')
1307 /* Parenthesis found, so check if a displacement value is inside. If so, get
1308 the value and remove it from the buffer. */
1309 if (is_digit_char (*(token + count + 1)))
1316 as_bad ("More than one displacement found in indirect reference");
1320 while (*(token + count) != ')')
1322 if (!is_digit_char (*(token + count)))
1324 as_bad ("Invalid displacement in indirect reference");
1327 disp[disp_posn++] = *(token + (count++));
1329 disp[disp_posn] = '\0';
1330 disp_number = atoi (disp);
1337 ind_buffer[buffer_posn] = '\0';
1340 as_bad ("AR register not found in indirect reference");
1343 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
1346 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
1347 if (ind_addr_op->displacement == IMPLIED_DISP)
1352 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
1354 /* Maybe an implied displacement of 1 again */
1355 as_bad ("required displacement wasn't given in indirect reference");
1361 as_bad ("illegal indirect reference");
1364 if (found_disp && (disp_number < 0 || disp_number > 255))
1366 as_bad ("displacement must be an unsigned 8-bit number");
1369 current_op->indirect.mod = ind_addr_op->modfield;
1370 current_op->indirect.disp = disp_number;
1371 current_op->indirect.ARnum = ar_number;
1372 current_op->op_type = Indirect;
1376 reg *regop = (reg *) hash_find (reg_hash, token);
1379 debug ("Found register operand: %s\n", regop->name);
1380 if (regop->regtype == REG_ARn)
1381 current_op->op_type = ARn;
1382 else if (regop->regtype == REG_Rn)
1383 current_op->op_type = Rn;
1384 else if (regop->regtype == REG_DP)
1385 current_op->op_type = DPReg;
1387 current_op->op_type = OtherReg;
1388 current_op->reg.opcode = regop->opcode;
1392 if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
1394 char *save_input_line_pointer;
1396 debug ("Probably a label: %s\n", token);
1397 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1398 strcpy (current_op->immediate.label, token);
1399 current_op->immediate.label[strlen (token)] = '\0';
1400 save_input_line_pointer = input_line_pointer;
1401 input_line_pointer = token;
1402 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1403 retval = expression (¤t_op->immediate.imm_expr);
1404 debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
1405 debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
1406 debug ("Segment: %d\n", retval);
1407 input_line_pointer = save_input_line_pointer;
1408 if (current_op->immediate.imm_expr.X_op == O_constant)
1410 current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
1411 current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
1412 current_op->immediate.resolved = 1;
1418 debug ("Found a number or displacement\n");
1419 for (count = 0; count < strlen (token); count++)
1420 if (*(token + count) == '.')
1421 current_op->immediate.decimal_found = 1;
1422 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1423 strcpy (current_op->immediate.label, token);
1424 current_op->immediate.label[strlen (token)] = '\0';
1425 current_op->immediate.f_number = (float) atof (token);
1426 current_op->immediate.s_number = (int) atoi (token);
1427 current_op->immediate.u_number = (unsigned int) atoi (token);
1428 current_op->immediate.resolved = 1;
1430 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
1431 if (current_op->immediate.u_number >= 0 && current_op->immediate.u_number <= 31)
1432 current_op->op_type |= IVector;
1438 /* next_line points to the next line after the current instruction (current_line).
1439 Search for the parallel bars, and if found, merge two lines into internal syntax
1440 for a parallel instruction:
1441 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1442 By this stage, all comments are scrubbed, and only the bare lines are given.
1446 #define START_OPCODE 1
1447 #define END_OPCODE 2
1448 #define START_OPERANDS 3
1449 #define END_OPERANDS 4
1452 tic30_find_parallel_insn (current_line, next_line)
1456 int found_parallel = 0;
1457 char first_opcode[256];
1458 char second_opcode[256];
1459 char first_operands[256];
1460 char second_operands[256];
1461 char *parallel_insn;
1463 debug ("In tic30_find_parallel_insn()\n");
1464 while (!is_end_of_line[(int) *next_line])
1466 if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
1474 if (!found_parallel)
1476 debug ("Found a parallel instruction\n");
1479 char *opcode, *operands, *line;
1481 for (i = 0; i < 2; i++)
1485 opcode = &first_opcode[0];
1486 operands = &first_operands[0];
1487 line = current_line;
1491 opcode = &second_opcode[0];
1492 operands = &second_operands[0];
1496 int search_status = NONE;
1500 while (!is_end_of_line[(int) (c = *line)] && *line)
1502 if (is_opcode_char (c) && search_status == NONE)
1504 opcode[char_ptr++] = tolower (c);
1505 search_status = START_OPCODE;
1507 else if (is_opcode_char (c) && search_status == START_OPCODE)
1509 opcode[char_ptr++] = tolower (c);
1511 else if (!is_opcode_char (c) && search_status == START_OPCODE)
1513 opcode[char_ptr] = '\0';
1515 search_status = END_OPCODE;
1517 else if (is_operand_char (c) && search_status == START_OPERANDS)
1519 operands[char_ptr++] = c;
1521 if (is_operand_char (c) && search_status == END_OPCODE)
1523 operands[char_ptr++] = c;
1524 search_status = START_OPERANDS;
1528 if (search_status != START_OPERANDS)
1530 operands[char_ptr] = '\0';
1534 parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
1535 strlen (second_opcode) + strlen (second_operands) + 8);
1536 sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
1537 debug ("parallel insn = %s\n", parallel_insn);
1538 return parallel_insn;
1544 #undef START_OPERANDS
1547 /* In order to get gas to ignore any | chars at the start of a line,
1548 this function returns true if a | is found in a line. */
1551 tic30_unrecognized_line (c)
1554 debug ("In tc_unrecognized_line\n");
1555 return (c == PARALLEL_SEPARATOR);
1559 md_estimate_size_before_relax (fragP, segment)
1563 debug ("In md_estimate_size_before_relax()\n");
1568 md_convert_frag (abfd, sec, fragP)
1571 register fragS *fragP;
1573 debug ("In md_convert_frag()\n");
1577 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
1579 addressT from_addr, to_addr;
1583 debug ("In md_create_short_jump()\n");
1587 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
1589 addressT from_addr, to_addr;
1593 debug ("In md_create_long_jump()\n");
1597 md_apply_fix (fixP, valP)
1601 valueT value = *valP;
1603 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1604 debug ("Values in fixP\n");
1605 debug ("fx_size = %d\n", fixP->fx_size);
1606 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1607 debug ("fx_where = %d\n", fixP->fx_where);
1608 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1610 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1612 if (fixP->fx_size == 1)
1613 { /* Special fix for LDP instruction. */
1614 value = (value & 0x00FF0000) >> 16;
1616 debug ("new value = %ld\n", (long) value);
1617 md_number_to_chars (buf, value, fixP->fx_size);
1623 md_parse_option (c, arg)
1629 debug ("In md_parse_option()\n");
1630 for (i = 0; i < c; i++)
1632 printf ("%c\n", arg[c]);
1638 md_show_usage (stream)
1641 debug ("In md_show_usage()\n");
1645 md_undefined_symbol (name)
1648 debug ("In md_undefined_symbol()\n");
1649 return (symbolS *) 0;
1653 md_section_align (segment, size)
1657 debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
1658 size = (size + 3) / 4;
1660 debug ("New size value = %d\n", size);
1665 md_pcrel_from (fixP)
1670 debug ("In md_pcrel_from()\n");
1671 debug ("fx_where = %d\n", fixP->fx_where);
1672 debug ("fx_size = %d\n", fixP->fx_size);
1673 /* Find the opcode that represents the current instruction in the fr_literal
1674 storage area, and check bit 21. Bit 21 contains whether the current instruction
1675 is a delayed one or not, and then set the offset value appropriately. */
1676 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1680 debug ("offset = %d\n", offset);
1681 /* PC Relative instructions have a format:
1682 displacement = Label - (PC + offset)
1683 This function returns PC + offset where:
1684 fx_where - fx_size = PC
1685 INSN_SIZE * offset = offset number of instructions
1687 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1691 md_atof (what_statement_type, literalP, sizeP)
1692 int what_statement_type;
1699 unsigned long value;
1700 /* char *atof_ieee (); */
1702 debug ("In md_atof()\n");
1703 debug ("precision = %c\n", what_statement_type);
1704 debug ("literal = %s\n", literalP);
1706 token = input_line_pointer;
1707 while (!is_end_of_line[(unsigned) *input_line_pointer] && (*input_line_pointer) && (*input_line_pointer != ','))
1709 debug ("%c", *input_line_pointer);
1710 input_line_pointer++;
1712 keepval = *input_line_pointer;
1713 *input_line_pointer = '\0';
1715 float_value = (float) atof (token);
1716 *input_line_pointer = keepval;
1717 debug ("float_value = %f\n", float_value);
1718 switch (what_statement_type)
1736 return "Bad call to MD_ATOF()";
1738 if (float_value == 0.0)
1740 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1744 unsigned long exp, sign, mant, tmsfloat;
1745 tmsfloat = *((long *) &float_value);
1746 sign = tmsfloat & 0x80000000;
1747 mant = tmsfloat & 0x007FFFFF;
1748 exp = tmsfloat & 0x7F800000;
1750 if (exp == 0xFF000000)
1764 mant = mant & 0x007FFFFF;
1766 mant = mant & 0x00FFFFFF;
1770 exp = (long) exp - 0x01000000;
1773 tmsfloat = exp | mant;
1780 if (tmsfloat == 0x80000000)
1787 exp = (tmsfloat & 0xFF000000);
1789 mant = tmsfloat & 0x007FFFFF;
1790 if (tmsfloat & 0x00800000)
1804 exp += (mant >> 24);
1814 mant = (exp << 12) | mant;
1815 value = mant & 0xFFFF;
1820 md_number_to_chars (literalP, value, prec);
1826 md_number_to_chars (buf, val, n)
1831 debug ("In md_number_to_chars()\n");
1832 number_to_chars_bigendian (buf, val, n);
1833 /* number_to_chars_littleendian(buf,val,n); */
1836 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1837 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1840 tc_gen_reloc (section, fixP)
1845 bfd_reloc_code_real_type code = 0;
1847 debug ("In tc_gen_reloc()\n");
1848 debug ("fixP.size = %d\n", fixP->fx_size);
1849 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1850 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1851 switch (F (fixP->fx_size, fixP->fx_pcrel))
1853 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1854 MAP (2, 0, BFD_RELOC_16);
1855 MAP (3, 0, BFD_RELOC_24);
1856 MAP (2, 1, BFD_RELOC_16_PCREL);
1857 MAP (4, 0, BFD_RELOC_32);
1859 as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
1860 fixP->fx_pcrel ? "pc-relative " : "");
1865 rel = (arelent *) xmalloc (sizeof (arelent));
1867 rel->sym_ptr_ptr = &fixP->fx_addsy->bsym;
1868 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1870 rel->addend = fixP->fx_addnumber;
1873 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1877 name = S_GET_NAME (fixP->fx_addsy);
1880 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
1886 tc_aout_pre_write_hook ()
1888 debug ("In tc_aout_pre_write_hook()\n");
1892 md_operand (expressionP)
1893 expressionS *expressionP;
1895 debug ("In md_operand()\n");
1898 char output_invalid_buf[8];
1905 sprintf (output_invalid_buf, "'%c'", c);
1907 sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
1908 return output_invalid_buf;