1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998-2016 Free Software Foundation, Inc.
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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
22 /* Texas Instruments TMS320C30 machine specific gas.
23 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
24 Bugs & suggestions are completely welcome. This is free software.
25 Please help us make it better. */
28 #include "safe-ctype.h"
29 #include "opcode/tic30.h"
31 /* Put here all non-digit non-letter characters that may occur in an
33 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
34 static const char *ordinal_names[] =
36 N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
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
58 const char EXP_CHARS[] = "eE";
60 /* Tables for lexical analysis. */
61 static char opcode_chars[256];
62 static char register_chars[256];
63 static char operand_chars[256];
64 static char space_chars[256];
65 static char identifier_chars[256];
66 static char digit_chars[256];
69 #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
70 #define is_operand_char(x) (operand_chars [(unsigned char) x])
71 #define is_register_char(x) (register_chars [(unsigned char) x])
72 #define is_space_char(x) (space_chars [(unsigned char) x])
73 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
74 #define is_digit_char(x) (digit_chars [(unsigned char) x])
76 const pseudo_typeS md_pseudo_table[] =
81 static int ATTRIBUTE_PRINTF_1
82 debug (const char *string, ...)
89 va_start (argptr, string);
90 vsprintf (str, string, argptr);
94 fputs (str, USE_STDOUT ? stdout : stderr);
101 /* Hash table for opcode lookup. */
102 static struct hash_control *op_hash;
103 /* Hash table for parallel opcode lookup. */
104 static struct hash_control *parop_hash;
105 /* Hash table for register lookup. */
106 static struct hash_control *reg_hash;
107 /* Hash table for indirect addressing lookup. */
108 static struct hash_control *ind_hash;
113 const char *hash_err;
115 debug ("In md_begin()\n");
116 op_hash = hash_new ();
119 const insn_template *current_optab = tic30_optab;
121 for (; current_optab < tic30_optab_end; current_optab++)
123 hash_err = hash_insert (op_hash, current_optab->name,
124 (char *) current_optab);
126 as_fatal ("Internal Error: Can't Hash %s: %s",
127 current_optab->name, hash_err);
131 parop_hash = hash_new ();
134 const partemplate *current_parop = tic30_paroptab;
136 for (; current_parop < tic30_paroptab_end; current_parop++)
138 hash_err = hash_insert (parop_hash, current_parop->name,
139 (char *) current_parop);
141 as_fatal ("Internal Error: Can't Hash %s: %s",
142 current_parop->name, hash_err);
146 reg_hash = hash_new ();
149 const reg *current_reg = tic30_regtab;
151 for (; current_reg < tic30_regtab_end; current_reg++)
153 hash_err = hash_insert (reg_hash, current_reg->name,
154 (char *) current_reg);
156 as_fatal ("Internal Error: Can't Hash %s: %s",
157 current_reg->name, hash_err);
161 ind_hash = hash_new ();
164 const ind_addr_type *current_ind = tic30_indaddr_tab;
166 for (; current_ind < tic30_indaddrtab_end; current_ind++)
168 hash_err = hash_insert (ind_hash, current_ind->syntax,
169 (char *) current_ind);
171 as_fatal ("Internal Error: Can't Hash %s: %s",
172 current_ind->syntax, hash_err);
176 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
181 for (c = 0; c < 256; c++)
183 if (ISLOWER (c) || ISDIGIT (c))
186 register_chars[c] = c;
188 else if (ISUPPER (c))
190 opcode_chars[c] = TOLOWER (c);
191 register_chars[c] = opcode_chars[c];
193 else if (c == ')' || c == '(')
194 register_chars[c] = c;
196 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
197 operand_chars[c] = c;
199 if (ISDIGIT (c) || c == '-')
202 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
203 identifier_chars[c] = c;
205 if (c == ' ' || c == '\t')
211 for (p = operand_special_chars; *p != '\0'; p++)
212 operand_chars[(unsigned char) *p] = *p;
216 /* Address Mode OR values. */
217 #define AM_Register 0x00000000
218 #define AM_Direct 0x00200000
219 #define AM_Indirect 0x00400000
220 #define AM_Immediate 0x00600000
221 #define AM_NotReq 0xFFFFFFFF
223 /* PC Relative OR values. */
224 #define PC_Register 0x00000000
225 #define PC_Relative 0x02000000
235 expressionS direct_expr;
253 unsigned int u_number;
255 expressionS imm_expr;
259 insn_template *opcode;
263 insn_template *tm; /* Template of current instruction. */
264 unsigned opcode; /* Final opcode. */
265 unsigned int operands; /* Number of given operands. */
266 /* Type of operand given in instruction. */
267 operand *operand_type[MAX_OPERANDS];
268 unsigned addressing_mode; /* Final addressing mode of instruction. */
271 struct tic30_insn insn;
272 static int found_parallel_insn;
274 static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
277 output_invalid (char c)
280 snprintf (output_invalid_buf, sizeof (output_invalid_buf),
283 snprintf (output_invalid_buf, sizeof (output_invalid_buf),
284 "(0x%x)", (unsigned char) c);
285 return output_invalid_buf;
288 /* next_line points to the next line after the current instruction
289 (current_line). Search for the parallel bars, and if found, merge two
290 lines into internal syntax for a parallel instruction:
291 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
292 By this stage, all comments are scrubbed, and only the bare lines are
296 #define START_OPCODE 1
298 #define START_OPERANDS 3
299 #define END_OPERANDS 4
302 tic30_find_parallel_insn (char *current_line, char *next_line)
304 int found_parallel = 0;
305 char first_opcode[256];
306 char second_opcode[256];
307 char first_operands[256];
308 char second_operands[256];
311 debug ("In tic30_find_parallel_insn()\n");
312 while (!is_end_of_line[(unsigned char) *next_line])
314 if (*next_line == PARALLEL_SEPARATOR
315 && *(next_line + 1) == PARALLEL_SEPARATOR)
325 debug ("Found a parallel instruction\n");
329 char *op, *operands, *line;
331 for (i = 0; i < 2; i++)
335 op = &first_opcode[0];
336 operands = &first_operands[0];
341 op = &second_opcode[0];
342 operands = &second_operands[0];
347 int search_status = NONE;
351 while (!is_end_of_line[(unsigned char) (c = *line)])
353 if (is_opcode_char (c) && search_status == NONE)
355 op[char_ptr++] = TOLOWER (c);
356 search_status = START_OPCODE;
358 else if (is_opcode_char (c) && search_status == START_OPCODE)
359 op[char_ptr++] = TOLOWER (c);
360 else if (!is_opcode_char (c) && search_status == START_OPCODE)
364 search_status = END_OPCODE;
366 else if (is_operand_char (c) && search_status == START_OPERANDS)
367 operands[char_ptr++] = c;
369 if (is_operand_char (c) && search_status == END_OPCODE)
371 operands[char_ptr++] = c;
372 search_status = START_OPERANDS;
377 if (search_status != START_OPERANDS)
379 operands[char_ptr] = '\0';
383 parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
384 + strlen (second_opcode) + strlen (second_operands) + 8);
385 sprintf (parallel_insn, "q_%s_%s %s | %s",
386 first_opcode, second_opcode,
387 first_operands, second_operands);
388 debug ("parallel insn = %s\n", parallel_insn);
389 return parallel_insn;
395 #undef START_OPERANDS
399 tic30_operand (char *token)
404 debug ("In tic30_operand with %s\n", token);
405 current_op = malloc (sizeof (* current_op));
406 memset (current_op, '\0', sizeof (operand));
408 if (*token == DIRECT_REFERENCE)
410 char *token_posn = token + 1;
411 int direct_label = 0;
413 debug ("Found direct reference\n");
416 if (!is_digit_char (*token_posn))
423 char *save_input_line_pointer;
426 debug ("Direct reference is a label\n");
427 current_op->direct.label = token + 1;
428 save_input_line_pointer = input_line_pointer;
429 input_line_pointer = token + 1;
430 debug ("Current input_line_pointer: %s\n", input_line_pointer);
431 retval = expression (¤t_op->direct.direct_expr);
433 debug ("Expression type: %d\n",
434 current_op->direct.direct_expr.X_op);
435 debug ("Expression addnum: %ld\n",
436 (long) current_op->direct.direct_expr.X_add_number);
437 debug ("Segment: %p\n", retval);
439 input_line_pointer = save_input_line_pointer;
441 if (current_op->direct.direct_expr.X_op == O_constant)
443 current_op->direct.address =
444 current_op->direct.direct_expr.X_add_number;
445 current_op->direct.resolved = 1;
450 debug ("Direct reference is a number\n");
451 current_op->direct.address = atoi (token + 1);
452 current_op->direct.resolved = 1;
454 current_op->op_type = Direct;
456 else if (*token == INDIRECT_REFERENCE)
458 /* Indirect reference operand. */
464 ind_addr_type *ind_addr_op;
467 ind_buffer = xmalloc (strlen (token));
469 debug ("Found indirect reference\n");
470 ind_buffer[0] = *token;
472 for (count = 1; count < strlen (token); count++)
475 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
477 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
478 && (*(token + count) == 'r' || *(token + count) == 'R'))
480 /* AR reference is found, so get its number and remove
481 it from the buffer so it can pass through hash_find(). */
484 as_bad (_("More than one AR register found in indirect reference"));
488 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
490 as_bad (_("Illegal AR register in indirect reference"));
494 ar_number = *(token + count + 1) - '0';
499 if (*(token + count) == '(')
501 /* Parenthesis found, so check if a displacement value is
502 inside. If so, get the value and remove it from the
504 if (is_digit_char (*(token + count + 1)))
511 as_bad (_("More than one displacement found in indirect reference"));
516 while (*(token + count) != ')')
518 if (!is_digit_char (*(token + count)))
520 as_bad (_("Invalid displacement in indirect reference"));
524 disp[disp_posn++] = *(token + (count++));
526 disp[disp_posn] = '\0';
527 disp_number = atoi (disp);
535 ind_buffer[buffer_posn] = '\0';
538 as_bad (_("AR register not found in indirect reference"));
543 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
546 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
547 if (ind_addr_op->displacement == IMPLIED_DISP)
552 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
554 /* Maybe an implied displacement of 1 again. */
555 as_bad (_("required displacement wasn't given in indirect reference"));
562 as_bad (_("illegal indirect reference"));
567 if (found_disp && (disp_number < 0 || disp_number > 255))
569 as_bad (_("displacement must be an unsigned 8-bit number"));
574 current_op->indirect.mod = ind_addr_op->modfield;
575 current_op->indirect.disp = disp_number;
576 current_op->indirect.ARnum = ar_number;
577 current_op->op_type = Indirect;
582 reg *regop = (reg *) hash_find (reg_hash, token);
586 debug ("Found register operand: %s\n", regop->name);
587 if (regop->regtype == REG_ARn)
588 current_op->op_type = ARn;
589 else if (regop->regtype == REG_Rn)
590 current_op->op_type = Rn;
591 else if (regop->regtype == REG_DP)
592 current_op->op_type = DPReg;
594 current_op->op_type = OtherReg;
595 current_op->reg.opcode = regop->opcode;
599 if (!is_digit_char (*token)
600 || *(token + 1) == 'x'
601 || strchr (token, 'h'))
603 char *save_input_line_pointer;
606 debug ("Probably a label: %s\n", token);
607 current_op->immediate.label = malloc (strlen (token) + 1);
608 strcpy (current_op->immediate.label, token);
609 current_op->immediate.label[strlen (token)] = '\0';
610 save_input_line_pointer = input_line_pointer;
611 input_line_pointer = token;
613 debug ("Current input_line_pointer: %s\n", input_line_pointer);
614 retval = expression (¤t_op->immediate.imm_expr);
615 debug ("Expression type: %d\n",
616 current_op->immediate.imm_expr.X_op);
617 debug ("Expression addnum: %ld\n",
618 (long) current_op->immediate.imm_expr.X_add_number);
619 debug ("Segment: %p\n", retval);
620 input_line_pointer = save_input_line_pointer;
622 if (current_op->immediate.imm_expr.X_op == O_constant)
624 current_op->immediate.s_number
625 = current_op->immediate.imm_expr.X_add_number;
626 current_op->immediate.u_number
627 = (unsigned int) current_op->immediate.imm_expr.X_add_number;
628 current_op->immediate.resolved = 1;
633 debug ("Found a number or displacement\n");
634 for (count = 0; count < strlen (token); count++)
635 if (*(token + count) == '.')
636 current_op->immediate.decimal_found = 1;
637 current_op->immediate.label = malloc (strlen (token) + 1);
638 strcpy (current_op->immediate.label, token);
639 current_op->immediate.label[strlen (token)] = '\0';
640 current_op->immediate.f_number = (float) atof (token);
641 current_op->immediate.s_number = (int) atoi (token);
642 current_op->immediate.u_number = (unsigned int) atoi (token);
643 current_op->immediate.resolved = 1;
645 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
646 if (current_op->immediate.u_number <= 31)
647 current_op->op_type |= IVector;
653 struct tic30_par_insn
655 partemplate *tm; /* Template of current parallel instruction. */
656 unsigned operands[2]; /* Number of given operands for each insn. */
657 /* Type of operand given in instruction. */
658 operand *operand_type[2][MAX_OPERANDS];
659 int swap_operands; /* Whether to swap operands around. */
660 unsigned p_field; /* Value of p field in multiply add/sub instructions. */
661 unsigned opcode; /* Final opcode. */
664 struct tic30_par_insn p_insn;
667 tic30_parallel_insn (char *token)
669 static partemplate *p_opcode;
670 char *current_posn = token;
674 debug ("In tic30_parallel_insn with %s\n", token);
675 memset (&p_insn, '\0', sizeof (p_insn));
677 while (is_opcode_char (*current_posn))
680 /* Find instruction. */
681 save_char = *current_posn;
682 *current_posn = '\0';
683 p_opcode = (partemplate *) hash_find (parop_hash, token);
686 debug ("Found instruction %s\n", p_opcode->name);
687 p_insn.tm = p_opcode;
691 char first_opcode[6] = {0};
692 char second_opcode[6] = {0};
694 int current_opcode = -1;
697 for (i = 0; i < strlen (token); i++)
699 char ch = *(token + i);
701 if (ch == '_' && current_opcode == -1)
707 if (ch == '_' && current_opcode == 0)
714 switch (current_opcode)
717 first_opcode[char_ptr++] = ch;
720 second_opcode[char_ptr++] = ch;
725 debug ("first_opcode = %s\n", first_opcode);
726 debug ("second_opcode = %s\n", second_opcode);
727 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
728 p_opcode = (partemplate *) hash_find (parop_hash, token);
732 debug ("Found instruction %s\n", p_opcode->name);
733 p_insn.tm = p_opcode;
734 p_insn.swap_operands = 1;
739 *current_posn = save_char;
744 int paren_not_balanced;
745 int expecting_operand = 0;
746 int found_separator = 0;
750 /* Skip optional white space before operand. */
751 while (!is_operand_char (*current_posn)
752 && *current_posn != END_OF_INSN)
754 if (!is_space_char (*current_posn)
755 && *current_posn != PARALLEL_SEPARATOR)
757 as_bad (_("Invalid character %s before %s operand"),
758 output_invalid (*current_posn),
759 ordinal_names[insn.operands]);
762 if (*current_posn == PARALLEL_SEPARATOR)
767 token_start = current_posn;
768 paren_not_balanced = 0;
770 while (paren_not_balanced || *current_posn != ',')
772 if (*current_posn == END_OF_INSN)
774 if (paren_not_balanced)
776 as_bad (_("Unbalanced parenthesis in %s operand."),
777 ordinal_names[insn.operands]);
783 else if (*current_posn == PARALLEL_SEPARATOR)
785 while (is_space_char (*(current_posn - 1)))
789 else if (!is_operand_char (*current_posn)
790 && !is_space_char (*current_posn))
792 as_bad (_("Invalid character %s in %s operand"),
793 output_invalid (*current_posn),
794 ordinal_names[insn.operands]);
798 if (*current_posn == '(')
799 ++paren_not_balanced;
800 if (*current_posn == ')')
801 --paren_not_balanced;
805 if (current_posn != token_start)
807 /* Yes, we've read in another operand. */
808 p_insn.operands[found_separator]++;
809 if (p_insn.operands[found_separator] > MAX_OPERANDS)
811 as_bad (_("Spurious operands; (%d operands/instruction max)"),
816 /* Now parse operand adding info to 'insn' as we go along. */
817 save_char = *current_posn;
818 *current_posn = '\0';
819 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
820 tic30_operand (token_start);
821 *current_posn = save_char;
822 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
827 if (expecting_operand)
829 as_bad (_("Expecting operand after ','; got nothing"));
832 if (*current_posn == ',')
834 as_bad (_("Expecting operand before ','; got nothing"));
839 /* Now *current_posn must be either ',' or END_OF_INSN. */
840 if (*current_posn == ',')
842 if (*++current_posn == END_OF_INSN)
844 /* Just skip it, if it's \n complain. */
845 as_bad (_("Expecting operand after ','; got nothing"));
848 expecting_operand = 1;
851 while (*current_posn != END_OF_INSN);
854 if (p_insn.swap_operands)
859 temp_num = p_insn.operands[0];
860 p_insn.operands[0] = p_insn.operands[1];
861 p_insn.operands[1] = temp_num;
862 for (i = 0; i < MAX_OPERANDS; i++)
864 temp_op = p_insn.operand_type[0][i];
865 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
866 p_insn.operand_type[1][i] = temp_op;
870 if (p_insn.operands[0] != p_insn.tm->operands_1)
872 as_bad (_("incorrect number of operands given in the first instruction"));
876 if (p_insn.operands[1] != p_insn.tm->operands_2)
878 as_bad (_("incorrect number of operands given in the second instruction"));
882 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
883 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
886 /* Now check if operands are correct. */
891 for (count = 0; count < 2; count++)
894 for (i = 0; i < p_insn.operands[count]; i++)
896 if ((p_insn.operand_type[count][i]->op_type &
897 p_insn.tm->operand_types[count][i]) == 0)
899 as_bad (_("%s instruction, operand %d doesn't match"),
900 ordinal_names[count], i + 1);
904 /* Get number of R register and indirect reference contained
905 within the first two operands of each instruction. This is
906 required for the multiply parallel instructions which require
907 two R registers and two indirect references, but not in any
909 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
911 else if ((p_insn.operand_type[count][i]->op_type & Indirect)
917 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
920 /* Check for the multiply instructions. */
923 as_bad (_("incorrect format for multiply parallel instruction"));
929 /* Shouldn't get here. */
930 as_bad (_("incorrect format for multiply parallel instruction"));
934 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
935 && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
937 as_bad (_("destination for multiply can only be R0 or R1"));
941 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
942 && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
944 as_bad (_("destination for add/subtract can only be R2 or R3"));
948 /* Now determine the P field for the instruction. */
949 if (p_insn.operand_type[0][0]->op_type & Indirect)
951 if (p_insn.operand_type[0][1]->op_type & Indirect)
952 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
953 else if (p_insn.operand_type[1][0]->op_type & Indirect)
954 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
956 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
960 if (p_insn.operand_type[0][1]->op_type & Rn)
961 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
962 else if (p_insn.operand_type[1][0]->op_type & Indirect)
965 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
966 /* Need to swap the two multiply operands around so that
967 everything is in its place for the opcode makeup.
968 ie so Ind * Rn, Ind +/- Rn. */
969 temp = p_insn.operand_type[0][0];
970 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
971 p_insn.operand_type[0][1] = temp;
976 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
977 temp = p_insn.operand_type[0][0];
978 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
979 p_insn.operand_type[0][1] = temp;
985 debug ("P field: %08X\n", p_insn.p_field);
987 /* Finalise opcode. This is easier for parallel instructions as they have
988 to be fully resolved, there are no memory addresses allowed, except
989 through indirect addressing, so there are no labels to resolve. */
990 p_insn.opcode = p_insn.tm->base_opcode;
992 switch (p_insn.tm->oporder)
995 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
996 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
997 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
998 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
999 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1000 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1004 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1005 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1006 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1007 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1008 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1009 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1010 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1011 as_warn (_("loading the same register in parallel operation"));
1015 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1016 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1017 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1018 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1019 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1020 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1024 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1025 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1026 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1027 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1028 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1029 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1030 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1034 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1035 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1036 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1037 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1038 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1039 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1040 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1044 p_insn.opcode |= p_insn.p_field;
1045 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1046 p_insn.opcode |= 0x00800000;
1047 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1048 p_insn.opcode |= 0x00400000;
1050 switch (p_insn.p_field)
1053 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1054 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1055 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1056 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1057 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1058 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1061 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1062 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1063 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1064 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1065 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1066 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1069 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1070 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1071 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1072 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1073 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1074 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1077 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1078 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1079 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1080 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1081 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1082 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1091 p = frag_more (INSN_SIZE);
1092 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1098 for (i = 0; i < 2; i++)
1099 for (j = 0; j < p_insn.operands[i]; j++)
1100 free (p_insn.operand_type[i][j]);
1103 debug ("Final opcode: %08X\n", p_insn.opcode);
1109 /* In order to get gas to ignore any | chars at the start of a line,
1110 this function returns true if a | is found in a line. */
1113 tic30_unrecognized_line (int c)
1115 debug ("In tc_unrecognized_line\n");
1116 return (c == PARALLEL_SEPARATOR);
1120 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1121 segT segment ATTRIBUTE_UNUSED)
1123 debug ("In md_estimate_size_before_relax()\n");
1128 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1129 segT sec ATTRIBUTE_UNUSED,
1130 fragS *fragP ATTRIBUTE_UNUSED)
1132 debug ("In md_convert_frag()\n");
1136 md_apply_fix (fixS *fixP,
1138 segT seg ATTRIBUTE_UNUSED)
1140 valueT value = *valP;
1142 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1143 debug ("Values in fixP\n");
1144 debug ("fx_size = %d\n", fixP->fx_size);
1145 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1146 debug ("fx_where = %ld\n", fixP->fx_where);
1147 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1149 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1152 if (fixP->fx_size == 1)
1153 /* Special fix for LDP instruction. */
1154 value = (value & 0x00FF0000) >> 16;
1156 debug ("new value = %ld\n", (long) value);
1157 md_number_to_chars (buf, value, fixP->fx_size);
1160 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1165 md_parse_option (int c ATTRIBUTE_UNUSED,
1166 const char *arg ATTRIBUTE_UNUSED)
1168 debug ("In md_parse_option()\n");
1173 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1175 debug ("In md_show_usage()\n");
1179 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1181 debug ("In md_undefined_symbol()\n");
1182 return (symbolS *) 0;
1186 md_section_align (segT segment, valueT size)
1188 debug ("In md_section_align() segment = %p and size = %lu\n",
1189 segment, (unsigned long) size);
1190 size = (size + 3) / 4;
1192 debug ("New size value = %lu\n", (unsigned long) size);
1197 md_pcrel_from (fixS *fixP)
1201 debug ("In md_pcrel_from()\n");
1202 debug ("fx_where = %ld\n", fixP->fx_where);
1203 debug ("fx_size = %d\n", fixP->fx_size);
1204 /* Find the opcode that represents the current instruction in the
1205 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1206 current instruction is a delayed one or not, and then set the offset
1207 value appropriately. */
1208 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1212 debug ("offset = %d\n", offset);
1213 /* PC Relative instructions have a format:
1214 displacement = Label - (PC + offset)
1215 This function returns PC + offset where:
1216 fx_where - fx_size = PC
1217 INSN_SIZE * offset = offset number of instructions. */
1218 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1222 md_atof (int what_statement_type,
1229 unsigned long value;
1232 debug ("In md_atof()\n");
1233 debug ("precision = %c\n", what_statement_type);
1234 debug ("literal = %s\n", literalP);
1236 token = input_line_pointer;
1237 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1238 && (*input_line_pointer != ','))
1240 debug ("%c", *input_line_pointer);
1241 input_line_pointer++;
1244 keepval = *input_line_pointer;
1245 *input_line_pointer = '\0';
1247 float_value = (float) atof (token);
1248 *input_line_pointer = keepval;
1249 debug ("float_value = %f\n", float_value);
1251 switch (what_statement_type)
1269 return _("Unrecognized or unsupported floating point constant");
1272 if (float_value == 0.0)
1273 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1276 unsigned long exp, sign, mant, tmsfloat;
1284 converter.f = float_value;
1285 tmsfloat = converter.l;
1286 sign = tmsfloat & 0x80000000;
1287 mant = tmsfloat & 0x007FFFFF;
1288 exp = tmsfloat & 0x7F800000;
1290 if (exp == 0xFF000000)
1304 mant = mant & 0x007FFFFF;
1306 mant = mant & 0x00FFFFFF;
1310 exp = (long) exp - 0x01000000;
1313 tmsfloat = exp | mant;
1320 if (tmsfloat == 0x80000000)
1325 expon = (tmsfloat & 0xFF000000);
1327 mantis = tmsfloat & 0x007FFFFF;
1328 if (tmsfloat & 0x00800000)
1330 mantis |= 0xFF000000;
1331 mantis += 0x00000800;
1333 mantis |= 0x00000800;
1340 mantis |= 0x00800000;
1341 mantis += 0x00000800;
1342 expon += (mantis >> 24);
1352 mantis = (expon << 12) | mantis;
1353 value = mantis & 0xFFFF;
1358 md_number_to_chars (literalP, value, prec);
1364 md_number_to_chars (char *buf, valueT val, int n)
1366 debug ("In md_number_to_chars()\n");
1367 number_to_chars_bigendian (buf, val, n);
1370 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1371 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1374 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1377 bfd_reloc_code_real_type code = 0;
1379 debug ("In tc_gen_reloc()\n");
1380 debug ("fixP.size = %d\n", fixP->fx_size);
1381 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1382 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1384 switch (F (fixP->fx_size, fixP->fx_pcrel))
1386 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1387 MAP (2, 0, BFD_RELOC_16);
1388 MAP (3, 0, BFD_RELOC_24);
1389 MAP (2, 1, BFD_RELOC_16_PCREL);
1390 MAP (4, 0, BFD_RELOC_32);
1392 as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1393 fixP->fx_pcrel ? _("pc-relative ") : "");
1398 rel = xmalloc (sizeof (* rel));
1399 gas_assert (rel != 0);
1400 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1401 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1402 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1404 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1409 name = S_GET_NAME (fixP->fx_addsy);
1412 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1413 name, bfd_get_reloc_code_name (code));
1419 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1421 debug ("In md_operand()\n");
1425 md_assemble (char *line)
1433 debug ("In md_assemble() with argument %s\n", line);
1434 memset (&insn, '\0', sizeof (insn));
1435 if (found_parallel_insn)
1437 debug ("Line is second part of parallel instruction\n\n");
1438 found_parallel_insn = 0;
1442 tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1443 current_posn = line;
1445 found_parallel_insn = 1;
1447 while (is_space_char (*current_posn))
1450 token_start = current_posn;
1452 if (!is_opcode_char (*current_posn))
1454 as_bad (_("Invalid character %s in opcode"),
1455 output_invalid (*current_posn));
1458 /* Check if instruction is a parallel instruction
1459 by seeing if the first character is a q. */
1460 if (*token_start == 'q')
1462 if (tic30_parallel_insn (token_start))
1464 if (found_parallel_insn)
1469 while (is_opcode_char (*current_posn))
1472 /* Find instruction. */
1473 save_char = *current_posn;
1474 *current_posn = '\0';
1475 op = (insn_template *) hash_find (op_hash, token_start);
1478 debug ("Found instruction %s\n", op->name);
1483 debug ("Didn't find insn\n");
1484 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1487 *current_posn = save_char;
1490 if (*current_posn != END_OF_INSN)
1492 /* Find operands. */
1493 int paren_not_balanced;
1494 int expecting_operand = 0;
1498 /* Skip optional white space before operand. */
1499 while (!is_operand_char (*current_posn)
1500 && *current_posn != END_OF_INSN)
1502 if (!is_space_char (*current_posn))
1504 as_bad (_("Invalid character %s before %s operand"),
1505 output_invalid (*current_posn),
1506 ordinal_names[insn.operands]);
1511 token_start = current_posn;
1512 paren_not_balanced = 0;
1513 while (paren_not_balanced || *current_posn != ',')
1515 if (*current_posn == END_OF_INSN)
1517 if (paren_not_balanced)
1519 as_bad (_("Unbalanced parenthesis in %s operand."),
1520 ordinal_names[insn.operands]);
1526 else if (!is_operand_char (*current_posn)
1527 && !is_space_char (*current_posn))
1529 as_bad (_("Invalid character %s in %s operand"),
1530 output_invalid (*current_posn),
1531 ordinal_names[insn.operands]);
1534 if (*current_posn == '(')
1535 ++paren_not_balanced;
1536 if (*current_posn == ')')
1537 --paren_not_balanced;
1540 if (current_posn != token_start)
1542 /* Yes, we've read in another operand. */
1543 this_operand = insn.operands++;
1544 if (insn.operands > MAX_OPERANDS)
1546 as_bad (_("Spurious operands; (%d operands/instruction max)"),
1551 /* Now parse operand adding info to 'insn' as we go along. */
1552 save_char = *current_posn;
1553 *current_posn = '\0';
1554 insn.operand_type[this_operand] = tic30_operand (token_start);
1555 *current_posn = save_char;
1556 if (insn.operand_type[this_operand] == NULL)
1561 if (expecting_operand)
1563 as_bad (_("Expecting operand after ','; got nothing"));
1566 if (*current_posn == ',')
1568 as_bad (_("Expecting operand before ','; got nothing"));
1573 /* Now *current_posn must be either ',' or END_OF_INSN. */
1574 if (*current_posn == ',')
1576 if (*++current_posn == END_OF_INSN)
1578 /* Just skip it, if it's \n complain. */
1579 as_bad (_("Expecting operand after ','; got nothing"));
1582 expecting_operand = 1;
1585 while (*current_posn != END_OF_INSN);
1588 debug ("Number of operands found: %d\n", insn.operands);
1590 /* Check that number of operands is correct. */
1591 if (insn.operands != insn.tm->operands)
1594 unsigned int numops = insn.tm->operands;
1596 /* If operands are not the same, then see if any of the operands are
1597 not required. Then recheck with number of given operands. If they
1598 are still not the same, then give an error, otherwise carry on. */
1599 for (i = 0; i < insn.tm->operands; i++)
1600 if (insn.tm->operand_types[i] & NotReq)
1602 if (insn.operands != numops)
1604 as_bad (_("Incorrect number of operands given"));
1608 insn.addressing_mode = AM_NotReq;
1609 for (count = 0; count < insn.operands; count++)
1611 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1613 debug ("Operand %d matches\n", count + 1);
1614 /* If instruction has two operands and has an AddressMode
1615 modifier then set addressing mode type for instruction. */
1616 if (insn.tm->opcode_modifier == AddressMode)
1619 /* Store instruction uses the second
1620 operand for the address mode. */
1621 if ((insn.tm->operand_types[1] & (Indirect | Direct))
1622 == (Indirect | Direct))
1625 if (insn.operand_type[addr_insn]->op_type & (AllReg))
1626 insn.addressing_mode = AM_Register;
1627 else if (insn.operand_type[addr_insn]->op_type & Direct)
1628 insn.addressing_mode = AM_Direct;
1629 else if (insn.operand_type[addr_insn]->op_type & Indirect)
1630 insn.addressing_mode = AM_Indirect;
1632 insn.addressing_mode = AM_Immediate;
1637 as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1642 /* Now set the addressing mode for 3 operand instructions. */
1643 if ((insn.tm->operand_types[0] & op3T1)
1644 && (insn.tm->operand_types[1] & op3T2))
1646 /* Set the addressing mode to the values used for 2 operand
1647 instructions in the G addressing field of the opcode. */
1649 switch (insn.operand_type[0]->op_type)
1655 if (insn.operand_type[1]->op_type & (AllReg))
1656 insn.addressing_mode = AM_Register;
1657 else if (insn.operand_type[1]->op_type & Indirect)
1658 insn.addressing_mode = AM_Direct;
1661 /* Shouldn't make it to this stage. */
1662 as_bad (_("Incompatible first and second operands in instruction"));
1667 if (insn.operand_type[1]->op_type & (AllReg))
1668 insn.addressing_mode = AM_Indirect;
1669 else if (insn.operand_type[1]->op_type & Indirect)
1670 insn.addressing_mode = AM_Immediate;
1673 /* Shouldn't make it to this stage. */
1674 as_bad (_("Incompatible first and second operands in instruction"));
1679 /* Now make up the opcode for the 3 operand instructions. As in
1680 parallel instructions, there will be no unresolved values, so they
1681 can be fully formed and added to the frag table. */
1682 insn.opcode = insn.tm->base_opcode;
1683 if (insn.operand_type[0]->op_type & Indirect)
1685 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1686 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1689 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1691 if (insn.operand_type[1]->op_type & Indirect)
1693 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1694 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1697 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1699 if (insn.operands == 3)
1700 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1702 insn.opcode |= insn.addressing_mode;
1703 p = frag_more (INSN_SIZE);
1704 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1708 /* Not a three operand instruction. */
1711 insn.opcode = insn.tm->base_opcode;
1712 /* Create frag for instruction - all instructions are 4 bytes long. */
1713 p = frag_more (INSN_SIZE);
1714 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1716 insn.opcode |= insn.addressing_mode;
1717 if (insn.addressing_mode == AM_Indirect)
1719 /* Determine which operand gives the addressing mode. */
1720 if (insn.operand_type[0]->op_type & Indirect)
1722 if ((insn.operands > 1)
1723 && (insn.operand_type[1]->op_type & Indirect))
1725 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1726 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1727 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1728 if (insn.operands > 1)
1729 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1730 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1732 else if (insn.addressing_mode == AM_Register)
1734 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1735 if (insn.operands > 1)
1736 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1737 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1739 else if (insn.addressing_mode == AM_Direct)
1741 if (insn.operand_type[0]->op_type & Direct)
1743 if ((insn.operands > 1)
1744 && (insn.operand_type[1]->op_type & Direct))
1746 if (insn.operands > 1)
1748 (insn.operand_type[! am_insn]->reg.opcode << 16);
1749 if (insn.operand_type[am_insn]->direct.resolved == 1)
1751 /* Resolved values can be placed straight
1752 into instruction word, and output. */
1754 (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1755 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1759 /* Unresolved direct addressing mode instruction. */
1760 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1761 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1762 & insn.operand_type[am_insn]->direct.direct_expr,
1766 else if (insn.addressing_mode == AM_Immediate)
1768 if (insn.operand_type[0]->immediate.resolved == 1)
1773 if (insn.operands > 1)
1774 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1776 switch (insn.tm->imm_arg_type)
1779 debug ("Floating point first operand\n");
1780 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1782 keeploc = input_line_pointer;
1783 input_line_pointer =
1784 insn.operand_type[0]->immediate.label;
1786 if (md_atof ('f', p + 2, & size) != 0)
1788 as_bad (_("invalid short form floating point immediate operand"));
1792 input_line_pointer = keeploc;
1796 debug ("Unsigned int first operand\n");
1797 if (insn.operand_type[0]->immediate.decimal_found)
1798 as_warn (_("rounding down first operand float to unsigned int"));
1799 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1800 as_warn (_("only lower 16-bits of first operand are used"));
1802 (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1803 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1807 debug ("Int first operand\n");
1809 if (insn.operand_type[0]->immediate.decimal_found)
1810 as_warn (_("rounding down first operand float to signed int"));
1812 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1813 insn.operand_type[0]->immediate.s_number > 32767)
1815 as_bad (_("first operand is too large for 16-bit signed int"));
1819 (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1820 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1826 /* Unresolved immediate label. */
1827 if (insn.operands > 1)
1828 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1829 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1830 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1831 & insn.operand_type[0]->immediate.imm_expr,
1836 else if (insn.tm->opcode_modifier == PCRel)
1838 /* Conditional Branch and Call instructions. */
1839 if ((insn.tm->operand_types[0] & (AllReg | Disp))
1842 if (insn.operand_type[0]->op_type & (AllReg))
1844 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1845 insn.opcode |= PC_Register;
1846 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1850 insn.opcode |= PC_Relative;
1851 if (insn.operand_type[0]->immediate.resolved == 1)
1854 (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1855 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1859 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1860 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1861 2, & insn.operand_type[0]->immediate.imm_expr,
1866 else if ((insn.tm->operand_types[0] & ARn) == ARn)
1868 /* Decrement and Branch instructions. */
1869 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1870 if (insn.operand_type[1]->op_type & (AllReg))
1872 insn.opcode |= (insn.operand_type[1]->reg.opcode);
1873 insn.opcode |= PC_Register;
1874 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1876 else if (insn.operand_type[1]->immediate.resolved == 1)
1878 if (insn.operand_type[0]->immediate.decimal_found)
1880 as_bad (_("first operand is floating point"));
1883 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1884 insn.operand_type[0]->immediate.s_number > 32767)
1886 as_bad (_("first operand is too large for 16-bit signed int"));
1889 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1890 insn.opcode |= PC_Relative;
1891 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1895 insn.opcode |= PC_Relative;
1896 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1897 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1898 & insn.operand_type[1]->immediate.imm_expr,
1903 else if (insn.tm->operand_types[0] == IVector)
1905 /* Trap instructions. */
1906 if (insn.operand_type[0]->op_type & IVector)
1907 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1910 /* Shouldn't get here. */
1911 as_bad (_("interrupt vector for trap instruction out of range"));
1914 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1916 else if (insn.tm->opcode_modifier == StackOp
1917 || insn.tm->opcode_modifier == Rotate)
1919 /* Push, Pop and Rotate instructions. */
1920 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1921 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1923 else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1924 == (Abs24 | Direct))
1926 /* LDP Instruction needs to be tested
1927 for before the next section. */
1928 if (insn.operand_type[0]->op_type & Direct)
1930 if (insn.operand_type[0]->direct.resolved == 1)
1932 /* Direct addressing uses lower 8 bits of direct address. */
1934 (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1935 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1941 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1942 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1943 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1944 /* Ensure that the assembler doesn't complain
1945 about fitting a 24-bit address into 8 bits. */
1946 fix->fx_no_overflow = 1;
1951 if (insn.operand_type[0]->immediate.resolved == 1)
1953 /* Immediate addressing uses upper 8 bits of address. */
1954 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1956 as_bad (_("LDP instruction needs a 24-bit operand"));
1960 ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1961 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1966 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1967 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1968 1, &insn.operand_type[0]->immediate.imm_expr,
1970 fix->fx_no_overflow = 1;
1974 else if (insn.tm->operand_types[0] & (Imm24))
1976 /* Unconditional Branch and Call instructions. */
1977 if (insn.operand_type[0]->immediate.resolved == 1)
1979 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1980 as_warn (_("first operand is too large for a 24-bit displacement"));
1982 (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1983 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1987 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1988 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1989 & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1992 else if (insn.tm->operand_types[0] & NotReq)
1993 /* Check for NOP instruction without arguments. */
1994 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1996 else if (insn.tm->operands == 0)
1997 /* Check for instructions without operands. */
1998 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
2000 debug ("Addressing mode: %08X\n", insn.addressing_mode);
2004 for (i = 0; i < insn.operands; i++)
2006 if (insn.operand_type[i]->immediate.label)
2007 free (insn.operand_type[i]->immediate.label);
2008 free (insn.operand_type[i]);
2011 debug ("Final opcode: %08X\n", insn.opcode);