1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998, 1999, 2000 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;
39 const char comment_chars[] = ";";
40 const char line_comment_chars[] = "*";
41 const char line_separator_chars[] = "";
43 const char *md_shortopts = "";
44 struct option md_longopts[] =
46 {NULL, no_argument, NULL, 0}
49 size_t md_longopts_size = sizeof (md_longopts);
51 /* Chars that mean this number is a floating point constant */
54 const char FLT_CHARS[] = "fFdDxX";
56 /* Chars that can be used to separate mant from exp in floating point nums */
57 const char EXP_CHARS[] = "eE";
59 /* tables for lexical analysis */
60 static char opcode_chars[256];
61 static char register_chars[256];
62 static char operand_chars[256];
63 static char space_chars[256];
64 static char identifier_chars[256];
65 static char digit_chars[256];
68 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
69 #define is_operand_char(x) (operand_chars[(unsigned char) x])
70 #define is_register_char(x) (register_chars[(unsigned char) x])
71 #define is_space_char(x) (space_chars[(unsigned char) x])
72 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
73 #define is_digit_char(x) (digit_chars[(unsigned char) x])
75 const pseudo_typeS md_pseudo_table[] =
88 debug (const char *string,...)
95 va_start (argptr, string);
96 vsprintf (str, string, argptr);
100 fputs (str, USE_STDOUT ? stdout : stderr);
108 debug (string, va_alist)
118 va_start (argptr, string);
119 cnt = vsprintf (str, string, argptr);
123 fputs (str, USE_STDOUT ? stdout : stderr);
131 /* hash table for opcode lookup */
132 static struct hash_control *op_hash;
133 /* hash table for parallel opcode lookup */
134 static struct hash_control *parop_hash;
135 /* hash table for register lookup */
136 static struct hash_control *reg_hash;
137 /* hash table for indirect addressing lookup */
138 static struct hash_control *ind_hash;
143 const char *hash_err;
144 debug ("In md_begin()\n");
145 op_hash = hash_new ();
147 const template *current_optab = tic30_optab;
148 for (; current_optab < tic30_optab_end; current_optab++)
150 hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
152 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
155 parop_hash = hash_new ();
157 const partemplate *current_parop = tic30_paroptab;
158 for (; current_parop < tic30_paroptab_end; current_parop++)
160 hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
162 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
165 reg_hash = hash_new ();
167 const reg *current_reg = tic30_regtab;
168 for (; current_reg < tic30_regtab_end; current_reg++)
170 hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
172 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
175 ind_hash = hash_new ();
177 const ind_addr_type *current_ind = tic30_indaddr_tab;
178 for (; current_ind < tic30_indaddrtab_end; current_ind++)
180 hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
182 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
185 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
190 for (c = 0; c < 256; c++)
192 if (islower (c) || isdigit (c))
195 register_chars[c] = c;
197 else if (isupper (c))
199 opcode_chars[c] = tolower (c);
200 register_chars[c] = opcode_chars[c];
202 else if (c == ')' || c == '(')
204 register_chars[c] = c;
206 if (isupper (c) || islower (c) || isdigit (c))
207 operand_chars[c] = c;
208 if (isdigit (c) || c == '-')
210 if (isalpha (c) || c == '_' || c == '.' || isdigit (c))
211 identifier_chars[c] = c;
212 if (c == ' ' || c == '\t')
217 for (p = operand_special_chars; *p != '\0'; p++)
218 operand_chars[(unsigned char) *p] = *p;
222 /* Address Mode OR values */
223 #define AM_Register 0x00000000
224 #define AM_Direct 0x00200000
225 #define AM_Indirect 0x00400000
226 #define AM_Immediate 0x00600000
227 #define AM_NotReq 0xFFFFFFFF
229 /* PC Relative OR values */
230 #define PC_Register 0x00000000
231 #define PC_Relative 0x02000000
241 expressionS direct_expr;
262 unsigned int u_number;
264 expressionS imm_expr;
270 int tic30_parallel_insn PARAMS ((char *));
271 operand *tic30_operand PARAMS ((char *));
272 char *tic30_find_parallel_insn PARAMS ((char *, char *));
278 template *tm; /* Template of current instruction */
279 unsigned opcode; /* Final opcode */
280 int operands; /* Number of given operands */
281 /* Type of operand given in instruction */
282 operand *operand_type[MAX_OPERANDS];
283 unsigned addressing_mode; /* Final addressing mode of instruction */
286 struct tic30_insn insn;
287 static int found_parallel_insn;
299 debug ("In md_assemble() with argument %s\n", line);
300 memset (&insn, '\0', sizeof (insn));
301 if (found_parallel_insn)
303 debug ("Line is second part of parallel instruction\n\n");
304 found_parallel_insn = 0;
307 if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
310 found_parallel_insn = 1;
311 while (is_space_char (*current_posn))
313 token_start = current_posn;
314 if (!is_opcode_char (*current_posn))
316 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
319 /* Check if instruction is a parallel instruction by seeing if the first
321 if (*token_start == 'q')
323 if (tic30_parallel_insn (token_start))
325 if (found_parallel_insn)
330 while (is_opcode_char (*current_posn))
332 { /* Find instruction */
333 save_char = *current_posn;
334 *current_posn = '\0';
335 opcode = (template *) hash_find (op_hash, token_start);
338 debug ("Found instruction %s\n", opcode->name);
343 debug ("Didn't find insn\n");
344 as_bad ("Unknown TMS320C30 instruction: %s", token_start);
347 *current_posn = save_char;
349 if (*current_posn != END_OF_INSN)
350 { /* Find operands */
351 int paren_not_balanced;
352 int expecting_operand = 0;
356 /* skip optional white space before operand */
357 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
359 if (!is_space_char (*current_posn))
361 as_bad ("Invalid character %s before %s operand",
362 output_invalid (*current_posn),
363 ordinal_names[insn.operands]);
368 token_start = current_posn; /* after white space */
369 paren_not_balanced = 0;
370 while (paren_not_balanced || *current_posn != ',')
372 if (*current_posn == END_OF_INSN)
374 if (paren_not_balanced)
376 as_bad ("Unbalanced parenthesis in %s operand.",
377 ordinal_names[insn.operands]);
381 break; /* we are done */
383 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
385 as_bad ("Invalid character %s in %s operand",
386 output_invalid (*current_posn),
387 ordinal_names[insn.operands]);
390 if (*current_posn == '(')
391 ++paren_not_balanced;
392 if (*current_posn == ')')
393 --paren_not_balanced;
396 if (current_posn != token_start)
397 { /* yes, we've read in another operand */
398 this_operand = insn.operands++;
399 if (insn.operands > MAX_OPERANDS)
401 as_bad ("Spurious operands; (%d operands/instruction max)",
405 /* now parse operand adding info to 'insn' as we go along */
406 save_char = *current_posn;
407 *current_posn = '\0';
408 insn.operand_type[this_operand] = tic30_operand (token_start);
409 *current_posn = save_char;
410 if (insn.operand_type[this_operand] == NULL)
415 if (expecting_operand)
417 as_bad ("Expecting operand after ','; got nothing");
420 if (*current_posn == ',')
422 as_bad ("Expecting operand before ','; got nothing");
426 /* now *current_posn must be either ',' or END_OF_INSN */
427 if (*current_posn == ',')
429 if (*++current_posn == END_OF_INSN)
430 { /* just skip it, if it's \n complain */
431 as_bad ("Expecting operand after ','; got nothing");
434 expecting_operand = 1;
437 while (*current_posn != END_OF_INSN); /* until we get end of insn */
439 debug ("Number of operands found: %d\n", insn.operands);
440 /* Check that number of operands is correct */
441 if (insn.operands != insn.tm->operands)
444 int numops = insn.tm->operands;
445 /* If operands are not the same, then see if any of the operands are not
446 required. Then recheck with number of given operands. If they are still not
447 the same, then give an error, otherwise carry on. */
448 for (i = 0; i < insn.tm->operands; i++)
449 if (insn.tm->operand_types[i] & NotReq)
451 if (insn.operands != numops)
453 as_bad ("Incorrect number of operands given");
457 insn.addressing_mode = AM_NotReq;
458 for (count = 0; count < insn.operands; count++)
460 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
462 debug ("Operand %d matches\n", count + 1);
463 /* If instruction has two operands and has an AddressMode modifier then set
464 addressing mode type for instruction */
465 if (insn.tm->opcode_modifier == AddressMode)
468 /* Store instruction uses the second operand for the address mode. */
469 if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
471 if (insn.operand_type[addr_insn]->op_type & (AllReg))
472 insn.addressing_mode = AM_Register;
473 else if (insn.operand_type[addr_insn]->op_type & Direct)
474 insn.addressing_mode = AM_Direct;
475 else if (insn.operand_type[addr_insn]->op_type & Indirect)
476 insn.addressing_mode = AM_Indirect;
478 insn.addressing_mode = AM_Immediate;
483 as_bad ("The %s operand doesn't match", ordinal_names[count]);
487 /* Now set the addressing mode for 3 operand instructions. */
488 if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
490 /* Set the addressing mode to the values used for 2 operand instructions in the
491 G addressing field of the opcode. */
493 switch (insn.operand_type[0]->op_type)
499 if (insn.operand_type[1]->op_type & (AllReg))
500 insn.addressing_mode = AM_Register;
501 else if (insn.operand_type[1]->op_type & Indirect)
502 insn.addressing_mode = AM_Direct;
505 /* Shouldn't make it to this stage */
506 as_bad ("Incompatible first and second operands in instruction");
511 if (insn.operand_type[1]->op_type & (AllReg))
512 insn.addressing_mode = AM_Indirect;
513 else if (insn.operand_type[1]->op_type & Indirect)
514 insn.addressing_mode = AM_Immediate;
517 /* Shouldn't make it to this stage */
518 as_bad ("Incompatible first and second operands in instruction");
523 /* Now make up the opcode for the 3 operand instructions. As in parallel
524 instructions, there will be no unresolved values, so they can be fully formed
525 and added to the frag table. */
526 insn.opcode = insn.tm->base_opcode;
527 if (insn.operand_type[0]->op_type & Indirect)
529 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
530 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
533 insn.opcode |= (insn.operand_type[0]->reg.opcode);
534 if (insn.operand_type[1]->op_type & Indirect)
536 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
537 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
540 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
541 if (insn.operands == 3)
542 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
543 insn.opcode |= insn.addressing_mode;
544 p = frag_more (INSN_SIZE);
545 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
548 { /* Not a three operand instruction */
551 insn.opcode = insn.tm->base_opcode;
552 /* Create frag for instruction - all instructions are 4 bytes long. */
553 p = frag_more (INSN_SIZE);
554 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
556 insn.opcode |= insn.addressing_mode;
557 if (insn.addressing_mode == AM_Indirect)
559 /* Determine which operand gives the addressing mode */
560 if (insn.operand_type[0]->op_type & Indirect)
562 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
564 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
565 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
566 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
567 if (insn.operands > 1)
568 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
569 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
571 else if (insn.addressing_mode == AM_Register)
573 insn.opcode |= (insn.operand_type[0]->reg.opcode);
574 if (insn.operands > 1)
575 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
576 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
578 else if (insn.addressing_mode == AM_Direct)
580 if (insn.operand_type[0]->op_type & Direct)
582 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
584 if (insn.operands > 1)
585 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
586 if (insn.operand_type[am_insn]->direct.resolved == 1)
588 /* Resolved values can be placed straight into instruction word, and output */
589 insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
590 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
593 { /* Unresolved direct addressing mode instruction */
594 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
595 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
598 else if (insn.addressing_mode == AM_Immediate)
600 if (insn.operand_type[0]->immediate.resolved == 1)
604 if (insn.operands > 1)
605 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
606 switch (insn.tm->imm_arg_type)
609 debug ("Floating point first operand\n");
610 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
611 keeploc = input_line_pointer;
612 input_line_pointer = insn.operand_type[0]->immediate.label;
613 if (md_atof ('f', p + 2, &size) != 0)
615 as_bad ("invalid short form floating point immediate operand");
618 input_line_pointer = keeploc;
621 debug ("Unsigned int first operand\n");
622 if (insn.operand_type[0]->immediate.decimal_found)
623 as_warn ("rounding down first operand float to unsigned int");
624 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
625 as_warn ("only lower 16-bits of first operand are used");
626 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
627 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
630 debug ("Int first operand\n");
631 if (insn.operand_type[0]->immediate.decimal_found)
632 as_warn ("rounding down first operand float to signed int");
633 if (insn.operand_type[0]->immediate.s_number < -32768 ||
634 insn.operand_type[0]->immediate.s_number > 32767)
636 as_bad ("first operand is too large for 16-bit signed int");
639 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
640 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
645 { /* Unresolved immediate label */
646 if (insn.operands > 1)
647 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
648 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
649 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
653 else if (insn.tm->opcode_modifier == PCRel)
655 /* Conditional Branch and Call instructions */
656 if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
658 if (insn.operand_type[0]->op_type & (AllReg))
660 insn.opcode |= (insn.operand_type[0]->reg.opcode);
661 insn.opcode |= PC_Register;
662 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
666 insn.opcode |= PC_Relative;
667 if (insn.operand_type[0]->immediate.resolved == 1)
669 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
670 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
674 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
675 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
679 else if ((insn.tm->operand_types[0] & ARn) == ARn)
681 /* Decrement and Branch instructions */
682 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
683 if (insn.operand_type[1]->op_type & (AllReg))
685 insn.opcode |= (insn.operand_type[1]->reg.opcode);
686 insn.opcode |= PC_Register;
687 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
689 else if (insn.operand_type[1]->immediate.resolved == 1)
691 if (insn.operand_type[0]->immediate.decimal_found)
693 as_bad ("first operand is floating point");
696 if (insn.operand_type[0]->immediate.s_number < -32768 ||
697 insn.operand_type[0]->immediate.s_number > 32767)
699 as_bad ("first operand is too large for 16-bit signed int");
702 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
703 insn.opcode |= PC_Relative;
704 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
708 insn.opcode |= PC_Relative;
709 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
710 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
714 else if (insn.tm->operand_types[0] == IVector)
716 /* Trap instructions */
717 if (insn.operand_type[0]->op_type & IVector)
718 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
720 { /* Shouldn't get here */
721 as_bad ("interrupt vector for trap instruction out of range");
724 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
726 else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
728 /* Push, Pop and Rotate instructions */
729 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
730 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
732 else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
734 /* LDP Instruction needs to be tested for before the next section */
735 if (insn.operand_type[0]->op_type & Direct)
737 if (insn.operand_type[0]->direct.resolved == 1)
739 /* Direct addressing uses lower 8 bits of direct address */
740 insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
741 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
746 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
747 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
748 /* Ensure that the assembler doesn't complain about fitting a 24-bit
749 address into 8 bits. */
750 fix->fx_no_overflow = 1;
755 if (insn.operand_type[0]->immediate.resolved == 1)
757 /* Immediate addressing uses upper 8 bits of address */
758 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
760 as_bad ("LDP instruction needs a 24-bit operand");
763 insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
764 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
769 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
770 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
771 fix->fx_no_overflow = 1;
775 else if (insn.tm->operand_types[0] & (Imm24))
777 /* Unconditional Branch and Call instructions */
778 if (insn.operand_type[0]->immediate.resolved == 1)
780 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
781 as_warn ("first operand is too large for a 24-bit displacement");
782 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
783 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
787 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
788 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
791 else if (insn.tm->operand_types[0] & NotReq)
793 /* Check for NOP instruction without arguments. */
794 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
796 else if (insn.tm->operands == 0)
798 /* Check for instructions without operands. */
799 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
802 debug ("Addressing mode: %08X\n", insn.addressing_mode);
805 for (i = 0; i < insn.operands; i++)
807 if (insn.operand_type[i]->immediate.label)
808 free (insn.operand_type[i]->immediate.label);
809 free (insn.operand_type[i]);
812 debug ("Final opcode: %08X\n", insn.opcode);
816 struct tic30_par_insn
818 partemplate *tm; /* Template of current parallel instruction */
819 int operands[2]; /* Number of given operands for each insn */
820 /* Type of operand given in instruction */
821 operand *operand_type[2][MAX_OPERANDS];
822 int swap_operands; /* Whether to swap operands around. */
823 unsigned p_field; /* Value of p field in multiply add/sub instructions */
824 unsigned opcode; /* Final opcode */
827 struct tic30_par_insn p_insn;
830 tic30_parallel_insn (char *token)
832 static partemplate *p_opcode;
833 char *current_posn = token;
837 debug ("In tic30_parallel_insn with %s\n", token);
838 memset (&p_insn, '\0', sizeof (p_insn));
839 while (is_opcode_char (*current_posn))
841 { /* Find instruction */
842 save_char = *current_posn;
843 *current_posn = '\0';
844 p_opcode = (partemplate *) hash_find (parop_hash, token);
847 debug ("Found instruction %s\n", p_opcode->name);
848 p_insn.tm = p_opcode;
852 char first_opcode[6] =
854 char second_opcode[6] =
857 int current_opcode = -1;
860 for (i = 0; i < strlen (token); i++)
862 char ch = *(token + i);
863 if (ch == '_' && current_opcode == -1)
868 if (ch == '_' && current_opcode == 0)
874 switch (current_opcode)
877 first_opcode[char_ptr++] = ch;
880 second_opcode[char_ptr++] = ch;
884 debug ("first_opcode = %s\n", first_opcode);
885 debug ("second_opcode = %s\n", second_opcode);
886 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
887 p_opcode = (partemplate *) hash_find (parop_hash, token);
890 debug ("Found instruction %s\n", p_opcode->name);
891 p_insn.tm = p_opcode;
892 p_insn.swap_operands = 1;
897 *current_posn = save_char;
899 { /* Find operands */
900 int paren_not_balanced;
901 int expecting_operand = 0;
902 int found_separator = 0;
905 /* skip optional white space before operand */
906 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
908 if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
910 as_bad ("Invalid character %s before %s operand",
911 output_invalid (*current_posn),
912 ordinal_names[insn.operands]);
915 if (*current_posn == PARALLEL_SEPARATOR)
919 token_start = current_posn; /* after white space */
920 paren_not_balanced = 0;
921 while (paren_not_balanced || *current_posn != ',')
923 if (*current_posn == END_OF_INSN)
925 if (paren_not_balanced)
927 as_bad ("Unbalanced parenthesis in %s operand.",
928 ordinal_names[insn.operands]);
932 break; /* we are done */
934 else if (*current_posn == PARALLEL_SEPARATOR)
936 while (is_space_char (*(current_posn - 1)))
940 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
942 as_bad ("Invalid character %s in %s operand",
943 output_invalid (*current_posn),
944 ordinal_names[insn.operands]);
947 if (*current_posn == '(')
948 ++paren_not_balanced;
949 if (*current_posn == ')')
950 --paren_not_balanced;
953 if (current_posn != token_start)
954 { /* yes, we've read in another operand */
955 p_insn.operands[found_separator]++;
956 if (p_insn.operands[found_separator] > MAX_OPERANDS)
958 as_bad ("Spurious operands; (%d operands/instruction max)",
962 /* now parse operand adding info to 'insn' as we go along */
963 save_char = *current_posn;
964 *current_posn = '\0';
965 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
966 tic30_operand (token_start);
967 *current_posn = save_char;
968 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
973 if (expecting_operand)
975 as_bad ("Expecting operand after ','; got nothing");
978 if (*current_posn == ',')
980 as_bad ("Expecting operand before ','; got nothing");
984 /* now *current_posn must be either ',' or END_OF_INSN */
985 if (*current_posn == ',')
987 if (*++current_posn == END_OF_INSN)
988 { /* just skip it, if it's \n complain */
989 as_bad ("Expecting operand after ','; got nothing");
992 expecting_operand = 1;
995 while (*current_posn != END_OF_INSN); /* until we get end of insn */
997 if (p_insn.swap_operands)
1002 temp_num = p_insn.operands[0];
1003 p_insn.operands[0] = p_insn.operands[1];
1004 p_insn.operands[1] = temp_num;
1005 for (i = 0; i < MAX_OPERANDS; i++)
1007 temp_op = p_insn.operand_type[0][i];
1008 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
1009 p_insn.operand_type[1][i] = temp_op;
1012 if (p_insn.operands[0] != p_insn.tm->operands_1)
1014 as_bad ("incorrect number of operands given in the first instruction");
1017 if (p_insn.operands[1] != p_insn.tm->operands_2)
1019 as_bad ("incorrect number of operands given in the second instruction");
1022 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
1023 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
1024 { /* Now check if operands are correct */
1028 for (count = 0; count < 2; count++)
1031 for (i = 0; i < p_insn.operands[count]; i++)
1033 if ((p_insn.operand_type[count][i]->op_type &
1034 p_insn.tm->operand_types[count][i]) == 0)
1036 as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
1039 /* Get number of R register and indirect reference contained within the first
1040 two operands of each instruction. This is required for the multiply
1041 parallel instructions which require two R registers and two indirect
1042 references, but not in any particular place. */
1043 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
1045 else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
1049 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
1051 /* Check for the multiply instructions */
1054 as_bad ("incorrect format for multiply parallel instruction");
1058 { /* Shouldn't get here */
1059 as_bad ("incorrect format for multiply parallel instruction");
1062 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
1063 (p_insn.operand_type[0][2]->reg.opcode != 0x01))
1065 as_bad ("destination for multiply can only be R0 or R1");
1068 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
1069 (p_insn.operand_type[1][2]->reg.opcode != 0x03))
1071 as_bad ("destination for add/subtract can only be R2 or R3");
1074 /* Now determine the P field for the instruction */
1075 if (p_insn.operand_type[0][0]->op_type & Indirect)
1077 if (p_insn.operand_type[0][1]->op_type & Indirect)
1078 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
1079 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1080 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
1082 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
1086 if (p_insn.operand_type[0][1]->op_type & Rn)
1087 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
1088 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1091 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
1092 /* Need to swap the two multiply operands around so that everything is in
1093 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1094 temp = p_insn.operand_type[0][0];
1095 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1096 p_insn.operand_type[0][1] = temp;
1101 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
1102 temp = p_insn.operand_type[0][0];
1103 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1104 p_insn.operand_type[0][1] = temp;
1109 debug ("P field: %08X\n", p_insn.p_field);
1110 /* Finalise opcode. This is easier for parallel instructions as they have to be
1111 fully resolved, there are no memory addresses allowed, except through indirect
1112 addressing, so there are no labels to resolve. */
1114 p_insn.opcode = p_insn.tm->base_opcode;
1115 switch (p_insn.tm->oporder)
1118 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1119 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1120 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1121 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1122 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1123 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1126 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1127 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1128 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1129 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1130 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1131 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1132 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1133 as_warn ("loading the same register in parallel operation");
1136 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1137 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1138 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1139 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1140 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1141 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1144 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1145 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1146 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1147 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1148 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1149 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1150 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1153 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1154 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1155 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1156 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1157 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1158 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1159 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1162 p_insn.opcode |= p_insn.p_field;
1163 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1164 p_insn.opcode |= 0x00800000;
1165 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1166 p_insn.opcode |= 0x00400000;
1167 switch (p_insn.p_field)
1170 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1171 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1172 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1173 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1174 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1175 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1178 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1179 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1180 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1181 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1182 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1183 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1186 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1187 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1188 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1189 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1190 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1191 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1194 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1195 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1196 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1197 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1198 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1199 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1204 } /* Opcode is finalised at this point for all parallel instructions. */
1205 { /* Output opcode */
1207 p = frag_more (INSN_SIZE);
1208 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1212 for (i = 0; i < 2; i++)
1213 for (j = 0; j < p_insn.operands[i]; j++)
1214 free (p_insn.operand_type[i][j]);
1216 debug ("Final opcode: %08X\n", p_insn.opcode);
1222 tic30_operand (token)
1226 char ind_buffer[strlen (token)];
1227 operand *current_op;
1229 debug ("In tic30_operand with %s\n", token);
1230 current_op = (operand *) malloc (sizeof (operand));
1231 memset (current_op, '\0', sizeof (operand));
1232 if (*token == DIRECT_REFERENCE)
1234 char *token_posn = token + 1;
1235 int direct_label = 0;
1236 debug ("Found direct reference\n");
1239 if (!is_digit_char (*token_posn))
1245 char *save_input_line_pointer;
1247 debug ("Direct reference is a label\n");
1248 current_op->direct.label = token + 1;
1249 save_input_line_pointer = input_line_pointer;
1250 input_line_pointer = token + 1;
1251 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1252 retval = expression (¤t_op->direct.direct_expr);
1253 debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
1254 debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
1255 debug ("Segment: %d\n", retval);
1256 input_line_pointer = save_input_line_pointer;
1257 if (current_op->direct.direct_expr.X_op == O_constant)
1259 current_op->direct.address = current_op->direct.direct_expr.X_add_number;
1260 current_op->direct.resolved = 1;
1265 debug ("Direct reference is a number\n");
1266 current_op->direct.address = atoi (token + 1);
1267 current_op->direct.resolved = 1;
1269 current_op->op_type = Direct;
1271 else if (*token == INDIRECT_REFERENCE)
1272 { /* Indirect reference operand */
1276 int disp_number = 0;
1277 int buffer_posn = 1;
1278 ind_addr_type *ind_addr_op;
1279 debug ("Found indirect reference\n");
1280 ind_buffer[0] = *token;
1281 for (count = 1; count < strlen (token); count++)
1282 { /* Strip operand */
1283 ind_buffer[buffer_posn] = tolower (*(token + count));
1284 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
1285 (*(token + count) == 'r' || *(token + count) == 'R'))
1287 /* AR reference is found, so get its number and remove it from the buffer
1288 so it can pass through hash_find() */
1291 as_bad ("More than one AR register found in indirect reference");
1294 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
1296 as_bad ("Illegal AR register in indirect reference");
1299 ar_number = *(token + count + 1) - '0';
1303 if (*(token + count) == '(')
1305 /* Parenthesis found, so check if a displacement value is inside. If so, get
1306 the value and remove it from the buffer. */
1307 if (is_digit_char (*(token + count + 1)))
1314 as_bad ("More than one displacement found in indirect reference");
1318 while (*(token + count) != ')')
1320 if (!is_digit_char (*(token + count)))
1322 as_bad ("Invalid displacement in indirect reference");
1325 disp[disp_posn++] = *(token + (count++));
1327 disp[disp_posn] = '\0';
1328 disp_number = atoi (disp);
1335 ind_buffer[buffer_posn] = '\0';
1338 as_bad ("AR register not found in indirect reference");
1341 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
1344 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
1345 if (ind_addr_op->displacement == IMPLIED_DISP)
1350 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
1352 /* Maybe an implied displacement of 1 again */
1353 as_bad ("required displacement wasn't given in indirect reference");
1359 as_bad ("illegal indirect reference");
1362 if (found_disp && (disp_number < 0 || disp_number > 255))
1364 as_bad ("displacement must be an unsigned 8-bit number");
1367 current_op->indirect.mod = ind_addr_op->modfield;
1368 current_op->indirect.disp = disp_number;
1369 current_op->indirect.ARnum = ar_number;
1370 current_op->op_type = Indirect;
1374 reg *regop = (reg *) hash_find (reg_hash, token);
1377 debug ("Found register operand: %s\n", regop->name);
1378 if (regop->regtype == REG_ARn)
1379 current_op->op_type = ARn;
1380 else if (regop->regtype == REG_Rn)
1381 current_op->op_type = Rn;
1382 else if (regop->regtype == REG_DP)
1383 current_op->op_type = DPReg;
1385 current_op->op_type = OtherReg;
1386 current_op->reg.opcode = regop->opcode;
1390 if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
1392 char *save_input_line_pointer;
1394 debug ("Probably a label: %s\n", token);
1395 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1396 strcpy (current_op->immediate.label, token);
1397 current_op->immediate.label[strlen (token)] = '\0';
1398 save_input_line_pointer = input_line_pointer;
1399 input_line_pointer = token;
1400 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1401 retval = expression (¤t_op->immediate.imm_expr);
1402 debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
1403 debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
1404 debug ("Segment: %d\n", retval);
1405 input_line_pointer = save_input_line_pointer;
1406 if (current_op->immediate.imm_expr.X_op == O_constant)
1408 current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
1409 current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
1410 current_op->immediate.resolved = 1;
1416 debug ("Found a number or displacement\n");
1417 for (count = 0; count < strlen (token); count++)
1418 if (*(token + count) == '.')
1419 current_op->immediate.decimal_found = 1;
1420 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1421 strcpy (current_op->immediate.label, token);
1422 current_op->immediate.label[strlen (token)] = '\0';
1423 current_op->immediate.f_number = (float) atof (token);
1424 current_op->immediate.s_number = (int) atoi (token);
1425 current_op->immediate.u_number = (unsigned int) atoi (token);
1426 current_op->immediate.resolved = 1;
1428 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
1429 if (current_op->immediate.u_number >= 0 && current_op->immediate.u_number <= 31)
1430 current_op->op_type |= IVector;
1436 /* next_line points to the next line after the current instruction (current_line).
1437 Search for the parallel bars, and if found, merge two lines into internal syntax
1438 for a parallel instruction:
1439 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1440 By this stage, all comments are scrubbed, and only the bare lines are given.
1444 #define START_OPCODE 1
1445 #define END_OPCODE 2
1446 #define START_OPERANDS 3
1447 #define END_OPERANDS 4
1450 tic30_find_parallel_insn (current_line, next_line)
1454 int found_parallel = 0;
1455 char first_opcode[256];
1456 char second_opcode[256];
1457 char first_operands[256];
1458 char second_operands[256];
1459 char *parallel_insn;
1461 debug ("In tic30_find_parallel_insn()\n");
1462 while (!is_end_of_line[(unsigned char) *next_line])
1464 if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
1472 if (!found_parallel)
1474 debug ("Found a parallel instruction\n");
1477 char *opcode, *operands, *line;
1479 for (i = 0; i < 2; i++)
1483 opcode = &first_opcode[0];
1484 operands = &first_operands[0];
1485 line = current_line;
1489 opcode = &second_opcode[0];
1490 operands = &second_operands[0];
1494 int search_status = NONE;
1498 while (!is_end_of_line[(unsigned char) (c = *line)])
1500 if (is_opcode_char (c) && search_status == NONE)
1502 opcode[char_ptr++] = tolower (c);
1503 search_status = START_OPCODE;
1505 else if (is_opcode_char (c) && search_status == START_OPCODE)
1507 opcode[char_ptr++] = tolower (c);
1509 else if (!is_opcode_char (c) && search_status == START_OPCODE)
1511 opcode[char_ptr] = '\0';
1513 search_status = END_OPCODE;
1515 else if (is_operand_char (c) && search_status == START_OPERANDS)
1517 operands[char_ptr++] = c;
1519 if (is_operand_char (c) && search_status == END_OPCODE)
1521 operands[char_ptr++] = c;
1522 search_status = START_OPERANDS;
1526 if (search_status != START_OPERANDS)
1528 operands[char_ptr] = '\0';
1532 parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
1533 strlen (second_opcode) + strlen (second_operands) + 8);
1534 sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
1535 debug ("parallel insn = %s\n", parallel_insn);
1536 return parallel_insn;
1542 #undef START_OPERANDS
1545 /* In order to get gas to ignore any | chars at the start of a line,
1546 this function returns true if a | is found in a line. */
1549 tic30_unrecognized_line (c)
1552 debug ("In tc_unrecognized_line\n");
1553 return (c == PARALLEL_SEPARATOR);
1557 md_estimate_size_before_relax (fragP, segment)
1561 debug ("In md_estimate_size_before_relax()\n");
1566 md_convert_frag (abfd, sec, fragP)
1569 register fragS *fragP;
1571 debug ("In md_convert_frag()\n");
1575 md_apply_fix (fixP, valP)
1579 valueT value = *valP;
1581 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1582 debug ("Values in fixP\n");
1583 debug ("fx_size = %d\n", fixP->fx_size);
1584 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1585 debug ("fx_where = %d\n", fixP->fx_where);
1586 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1588 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1590 if (fixP->fx_size == 1)
1591 { /* Special fix for LDP instruction. */
1592 value = (value & 0x00FF0000) >> 16;
1594 debug ("new value = %ld\n", (long) value);
1595 md_number_to_chars (buf, value, fixP->fx_size);
1601 md_parse_option (c, arg)
1607 debug ("In md_parse_option()\n");
1608 for (i = 0; i < c; i++)
1610 printf ("%c\n", arg[c]);
1616 md_show_usage (stream)
1619 debug ("In md_show_usage()\n");
1623 md_undefined_symbol (name)
1626 debug ("In md_undefined_symbol()\n");
1627 return (symbolS *) 0;
1631 md_section_align (segment, size)
1635 debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
1636 size = (size + 3) / 4;
1638 debug ("New size value = %d\n", size);
1643 md_pcrel_from (fixP)
1648 debug ("In md_pcrel_from()\n");
1649 debug ("fx_where = %d\n", fixP->fx_where);
1650 debug ("fx_size = %d\n", fixP->fx_size);
1651 /* Find the opcode that represents the current instruction in the fr_literal
1652 storage area, and check bit 21. Bit 21 contains whether the current instruction
1653 is a delayed one or not, and then set the offset value appropriately. */
1654 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1658 debug ("offset = %d\n", offset);
1659 /* PC Relative instructions have a format:
1660 displacement = Label - (PC + offset)
1661 This function returns PC + offset where:
1662 fx_where - fx_size = PC
1663 INSN_SIZE * offset = offset number of instructions
1665 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1669 md_atof (what_statement_type, literalP, sizeP)
1670 int what_statement_type;
1677 unsigned long value;
1678 /* char *atof_ieee (); */
1680 debug ("In md_atof()\n");
1681 debug ("precision = %c\n", what_statement_type);
1682 debug ("literal = %s\n", literalP);
1684 token = input_line_pointer;
1685 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1686 && (*input_line_pointer != ','))
1688 debug ("%c", *input_line_pointer);
1689 input_line_pointer++;
1691 keepval = *input_line_pointer;
1692 *input_line_pointer = '\0';
1694 float_value = (float) atof (token);
1695 *input_line_pointer = keepval;
1696 debug ("float_value = %f\n", float_value);
1697 switch (what_statement_type)
1715 return "Bad call to MD_ATOF()";
1717 if (float_value == 0.0)
1719 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1723 unsigned long exp, sign, mant, tmsfloat;
1724 tmsfloat = *((long *) &float_value);
1725 sign = tmsfloat & 0x80000000;
1726 mant = tmsfloat & 0x007FFFFF;
1727 exp = tmsfloat & 0x7F800000;
1729 if (exp == 0xFF000000)
1743 mant = mant & 0x007FFFFF;
1745 mant = mant & 0x00FFFFFF;
1749 exp = (long) exp - 0x01000000;
1752 tmsfloat = exp | mant;
1759 if (tmsfloat == 0x80000000)
1766 exp = (tmsfloat & 0xFF000000);
1768 mant = tmsfloat & 0x007FFFFF;
1769 if (tmsfloat & 0x00800000)
1783 exp += (mant >> 24);
1793 mant = (exp << 12) | mant;
1794 value = mant & 0xFFFF;
1799 md_number_to_chars (literalP, value, prec);
1805 md_number_to_chars (buf, val, n)
1810 debug ("In md_number_to_chars()\n");
1811 number_to_chars_bigendian (buf, val, n);
1812 /* number_to_chars_littleendian(buf,val,n); */
1815 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1816 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1819 tc_gen_reloc (section, fixP)
1824 bfd_reloc_code_real_type code = 0;
1826 debug ("In tc_gen_reloc()\n");
1827 debug ("fixP.size = %d\n", fixP->fx_size);
1828 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1829 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1830 switch (F (fixP->fx_size, fixP->fx_pcrel))
1832 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1833 MAP (2, 0, BFD_RELOC_16);
1834 MAP (3, 0, BFD_RELOC_24);
1835 MAP (2, 1, BFD_RELOC_16_PCREL);
1836 MAP (4, 0, BFD_RELOC_32);
1838 as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
1839 fixP->fx_pcrel ? "pc-relative " : "");
1844 rel = (arelent *) xmalloc (sizeof (arelent));
1846 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1847 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1848 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1850 rel->addend = fixP->fx_addnumber;
1853 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1857 name = S_GET_NAME (fixP->fx_addsy);
1860 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
1866 tc_aout_pre_write_hook ()
1868 debug ("In tc_aout_pre_write_hook()\n");
1872 md_operand (expressionP)
1873 expressionS *expressionP;
1875 debug ("In md_operand()\n");
1878 char output_invalid_buf[8];
1885 sprintf (output_invalid_buf, "'%c'", c);
1887 sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
1888 return output_invalid_buf;