Fix building for the s390 target with clang
[binutils-gdb.git] / gas / config / tc-tic30.c
blob9d3b2dbc4b9efb90d507dfff8610642f4bd23d0f
1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998-2023 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)
10 any later version.
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
20 02110-1301, USA. */
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. */
27 #include "as.h"
28 #include "safe-ctype.h"
29 #include "opcode/tic30.h"
31 /* Put here all non-digit non-letter characters that may occur in an
32 operand. */
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.
52 As in 0f12.456
53 or 0d1.2345e12. */
54 const char FLT_CHARS[] = "fFdDxX";
56 /* Chars that can be used to separate mant from exp in floating point
57 nums. */
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];
68 /* Lexical macros. */
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[] =
78 {0, 0, 0}
81 static int ATTRIBUTE_PRINTF_1
82 debug (const char *string, ...)
84 if (flag_debug)
86 char str[100];
87 va_list argptr;
89 va_start (argptr, string);
90 vsprintf (str, string, argptr);
91 va_end (argptr);
92 if (str[0] == '\0')
93 return (0);
94 fputs (str, USE_STDOUT ? stdout : stderr);
95 return strlen (str);
97 else
98 return 0;
101 /* Hash table for opcode lookup. */
102 static htab_t op_hash;
103 /* Hash table for parallel opcode lookup. */
104 static htab_t parop_hash;
105 /* Hash table for register lookup. */
106 static htab_t reg_hash;
107 /* Hash table for indirect addressing lookup. */
108 static htab_t ind_hash;
110 void
111 md_begin (void)
113 debug ("In md_begin()\n");
114 op_hash = str_htab_create ();
117 const insn_template *current_optab = tic30_optab;
119 for (; current_optab < tic30_optab_end; current_optab++)
120 if (str_hash_insert (op_hash, current_optab->name, current_optab, 0))
121 as_fatal (_("duplicate %s"), current_optab->name);
124 parop_hash = str_htab_create ();
127 const partemplate *current_parop = tic30_paroptab;
129 for (; current_parop < tic30_paroptab_end; current_parop++)
130 if (str_hash_insert (parop_hash, current_parop->name, current_parop, 0))
131 as_fatal (_("duplicate %s"), current_parop->name);
134 reg_hash = str_htab_create ();
137 const reg *current_reg = tic30_regtab;
139 for (; current_reg < tic30_regtab_end; current_reg++)
140 if (str_hash_insert (reg_hash, current_reg->name, current_reg, 0))
141 as_fatal (_("duplicate %s"), current_reg->name);
144 ind_hash = str_htab_create ();
147 const ind_addr_type *current_ind = tic30_indaddr_tab;
149 for (; current_ind < tic30_indaddrtab_end; current_ind++)
150 if (str_hash_insert (ind_hash, current_ind->syntax, current_ind, 0))
151 as_fatal (_("duplicate %s"), current_ind->syntax);
154 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
156 int c;
157 char *p;
159 for (c = 0; c < 256; c++)
161 if (ISLOWER (c) || ISDIGIT (c))
163 opcode_chars[c] = c;
164 register_chars[c] = c;
166 else if (ISUPPER (c))
168 opcode_chars[c] = TOLOWER (c);
169 register_chars[c] = opcode_chars[c];
171 else if (c == ')' || c == '(')
172 register_chars[c] = c;
174 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
175 operand_chars[c] = c;
177 if (ISDIGIT (c) || c == '-')
178 digit_chars[c] = c;
180 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
181 identifier_chars[c] = c;
183 if (c == ' ' || c == '\t')
184 space_chars[c] = c;
186 if (c == '_')
187 opcode_chars[c] = c;
189 for (p = operand_special_chars; *p != '\0'; p++)
190 operand_chars[(unsigned char) *p] = *p;
194 /* Address Mode OR values. */
195 #define AM_Register 0x00000000
196 #define AM_Direct 0x00200000
197 #define AM_Indirect 0x00400000
198 #define AM_Immediate 0x00600000
199 #define AM_NotReq 0xFFFFFFFF
201 /* PC Relative OR values. */
202 #define PC_Register 0x00000000
203 #define PC_Relative 0x02000000
205 typedef struct
207 unsigned op_type;
208 struct
210 int resolved;
211 unsigned address;
212 char *label;
213 expressionS direct_expr;
214 } direct;
215 struct
217 unsigned mod;
218 int ARnum;
219 unsigned char disp;
220 } indirect;
221 struct
223 unsigned opcode;
224 } reg;
225 struct
227 int resolved;
228 int decimal_found;
229 float f_number;
230 int s_number;
231 unsigned int u_number;
232 char *label;
233 expressionS imm_expr;
234 } immediate;
235 } operand;
237 insn_template *opcode;
239 struct tic30_insn
241 insn_template *tm; /* Template of current instruction. */
242 unsigned opcode; /* Final opcode. */
243 unsigned int operands; /* Number of given operands. */
244 /* Type of operand given in instruction. */
245 operand *operand_type[MAX_OPERANDS];
246 unsigned addressing_mode; /* Final addressing mode of instruction. */
249 struct tic30_insn insn;
250 static int found_parallel_insn;
252 static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
254 static char *
255 output_invalid (char c)
257 if (ISPRINT (c))
258 snprintf (output_invalid_buf, sizeof (output_invalid_buf),
259 "'%c'", c);
260 else
261 snprintf (output_invalid_buf, sizeof (output_invalid_buf),
262 "(0x%x)", (unsigned char) c);
263 return output_invalid_buf;
266 /* next_line points to the next line after the current instruction
267 (current_line). Search for the parallel bars, and if found, merge two
268 lines into internal syntax for a parallel instruction:
269 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
270 By this stage, all comments are scrubbed, and only the bare lines are
271 given. */
273 #define NONE 0
274 #define START_OPCODE 1
275 #define END_OPCODE 2
276 #define START_OPERANDS 3
277 #define END_OPERANDS 4
279 static char *
280 tic30_find_parallel_insn (char *current_line, char *next_line)
282 int found_parallel = 0;
283 char first_opcode[256];
284 char second_opcode[256];
285 char first_operands[256];
286 char second_operands[256];
287 char *parallel_insn;
289 debug ("In tic30_find_parallel_insn()\n");
290 while (!is_end_of_line[(unsigned char) *next_line])
292 if (*next_line == PARALLEL_SEPARATOR
293 && *(next_line + 1) == PARALLEL_SEPARATOR)
295 found_parallel = 1;
296 next_line++;
297 break;
299 next_line++;
301 if (!found_parallel)
302 return NULL;
303 debug ("Found a parallel instruction\n");
306 int i;
307 char *op, *operands, *line;
309 for (i = 0; i < 2; i++)
311 if (i == 0)
313 op = &first_opcode[0];
314 operands = &first_operands[0];
315 line = current_line;
317 else
319 op = &second_opcode[0];
320 operands = &second_operands[0];
321 line = next_line;
325 int search_status = NONE;
326 int char_ptr = 0;
327 char c;
329 while (!is_end_of_line[(unsigned char) (c = *line)])
331 if (is_opcode_char (c) && search_status == NONE)
333 op[char_ptr++] = TOLOWER (c);
334 search_status = START_OPCODE;
336 else if (is_opcode_char (c) && search_status == START_OPCODE)
337 op[char_ptr++] = TOLOWER (c);
338 else if (!is_opcode_char (c) && search_status == START_OPCODE)
340 op[char_ptr] = '\0';
341 char_ptr = 0;
342 search_status = END_OPCODE;
344 else if (is_operand_char (c) && search_status == START_OPERANDS)
345 operands[char_ptr++] = c;
347 if (is_operand_char (c) && search_status == END_OPCODE)
349 operands[char_ptr++] = c;
350 search_status = START_OPERANDS;
353 line++;
355 if (search_status != START_OPERANDS)
356 return NULL;
357 operands[char_ptr] = '\0';
362 parallel_insn = concat ("q_", first_opcode, "_", second_opcode, " ",
363 first_operands, " | ", second_operands,
364 (char *) NULL);
365 debug ("parallel insn = %s\n", parallel_insn);
366 return parallel_insn;
369 #undef NONE
370 #undef START_OPCODE
371 #undef END_OPCODE
372 #undef START_OPERANDS
373 #undef END_OPERANDS
375 static operand *
376 tic30_operand (char *token)
378 unsigned int count;
379 operand *current_op;
381 debug ("In tic30_operand with %s\n", token);
382 current_op = XCNEW (operand);
384 if (*token == DIRECT_REFERENCE)
386 char *token_posn = token + 1;
387 int direct_label = 0;
389 debug ("Found direct reference\n");
390 while (*token_posn)
392 if (!is_digit_char (*token_posn))
393 direct_label = 1;
394 token_posn++;
397 if (direct_label)
399 char *save_input_line_pointer;
400 segT retval;
402 debug ("Direct reference is a label\n");
403 current_op->direct.label = token + 1;
404 save_input_line_pointer = input_line_pointer;
405 input_line_pointer = token + 1;
406 debug ("Current input_line_pointer: %s\n", input_line_pointer);
407 retval = expression (&current_op->direct.direct_expr);
409 debug ("Expression type: %d\n",
410 current_op->direct.direct_expr.X_op);
411 debug ("Expression addnum: %ld\n",
412 (long) current_op->direct.direct_expr.X_add_number);
413 debug ("Segment: %p\n", retval);
415 input_line_pointer = save_input_line_pointer;
417 if (current_op->direct.direct_expr.X_op == O_constant)
419 current_op->direct.address =
420 current_op->direct.direct_expr.X_add_number;
421 current_op->direct.resolved = 1;
424 else
426 debug ("Direct reference is a number\n");
427 current_op->direct.address = atoi (token + 1);
428 current_op->direct.resolved = 1;
430 current_op->op_type = Direct;
432 else if (*token == INDIRECT_REFERENCE)
434 /* Indirect reference operand. */
435 int found_ar = 0;
436 int found_disp = 0;
437 int ar_number = -1;
438 int disp_number = 0;
439 int buffer_posn = 1;
440 ind_addr_type *ind_addr_op;
441 char * ind_buffer;
443 ind_buffer = XNEWVEC (char, strlen (token));
445 debug ("Found indirect reference\n");
446 ind_buffer[0] = *token;
448 for (count = 1; count < strlen (token); count++)
450 /* Strip operand. */
451 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
453 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
454 && (*(token + count) == 'r' || *(token + count) == 'R'))
456 /* AR reference is found, so get its number and remove
457 it from the buffer so it can pass through str_hash_find(). */
458 if (found_ar)
460 as_bad (_("More than one AR register found in indirect reference"));
461 free (ind_buffer);
462 return NULL;
464 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
466 as_bad (_("Illegal AR register in indirect reference"));
467 free (ind_buffer);
468 return NULL;
470 ar_number = *(token + count + 1) - '0';
471 found_ar = 1;
472 count++;
475 if (*(token + count) == '(')
477 /* Parenthesis found, so check if a displacement value is
478 inside. If so, get the value and remove it from the
479 buffer. */
480 if (is_digit_char (*(token + count + 1)))
482 char disp[10];
483 int disp_posn = 0;
485 if (found_disp)
487 as_bad (_("More than one displacement found in indirect reference"));
488 free (ind_buffer);
489 return NULL;
491 count++;
492 while (*(token + count) != ')')
494 if (!is_digit_char (*(token + count)))
496 as_bad (_("Invalid displacement in indirect reference"));
497 free (ind_buffer);
498 return NULL;
500 disp[disp_posn++] = *(token + (count++));
502 disp[disp_posn] = '\0';
503 disp_number = atoi (disp);
504 count--;
505 found_disp = 1;
508 buffer_posn++;
511 ind_buffer[buffer_posn] = '\0';
512 if (!found_ar)
514 as_bad (_("AR register not found in indirect reference"));
515 free (ind_buffer);
516 return NULL;
519 ind_addr_op = (ind_addr_type *) str_hash_find (ind_hash, ind_buffer);
520 if (ind_addr_op)
522 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
523 if (ind_addr_op->displacement == IMPLIED_DISP)
525 found_disp = 1;
526 disp_number = 1;
528 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
530 /* Maybe an implied displacement of 1 again. */
531 as_bad (_("required displacement wasn't given in indirect reference"));
532 free (ind_buffer);
533 return NULL;
536 else
538 as_bad (_("illegal indirect reference"));
539 free (ind_buffer);
540 return NULL;
543 if (found_disp && (disp_number < 0 || disp_number > 255))
545 as_bad (_("displacement must be an unsigned 8-bit number"));
546 free (ind_buffer);
547 return NULL;
550 current_op->indirect.mod = ind_addr_op->modfield;
551 current_op->indirect.disp = disp_number;
552 current_op->indirect.ARnum = ar_number;
553 current_op->op_type = Indirect;
554 free (ind_buffer);
556 else
558 reg *regop = (reg *) str_hash_find (reg_hash, token);
560 if (regop)
562 debug ("Found register operand: %s\n", regop->name);
563 if (regop->regtype == REG_ARn)
564 current_op->op_type = ARn;
565 else if (regop->regtype == REG_Rn)
566 current_op->op_type = Rn;
567 else if (regop->regtype == REG_DP)
568 current_op->op_type = DPReg;
569 else
570 current_op->op_type = OtherReg;
571 current_op->reg.opcode = regop->opcode;
573 else
575 if (!is_digit_char (*token)
576 || *(token + 1) == 'x'
577 || strchr (token, 'h'))
579 char *save_input_line_pointer;
580 segT retval;
582 debug ("Probably a label: %s\n", token);
583 current_op->immediate.label = xstrdup (token);
584 save_input_line_pointer = input_line_pointer;
585 input_line_pointer = token;
587 debug ("Current input_line_pointer: %s\n", input_line_pointer);
588 retval = expression (&current_op->immediate.imm_expr);
589 debug ("Expression type: %d\n",
590 current_op->immediate.imm_expr.X_op);
591 debug ("Expression addnum: %ld\n",
592 (long) current_op->immediate.imm_expr.X_add_number);
593 debug ("Segment: %p\n", retval);
594 input_line_pointer = save_input_line_pointer;
596 if (current_op->immediate.imm_expr.X_op == O_constant)
598 current_op->immediate.s_number
599 = current_op->immediate.imm_expr.X_add_number;
600 current_op->immediate.u_number
601 = (unsigned int) current_op->immediate.imm_expr.X_add_number;
602 current_op->immediate.resolved = 1;
605 else
607 debug ("Found a number or displacement\n");
608 for (count = 0; count < strlen (token); count++)
609 if (*(token + count) == '.')
610 current_op->immediate.decimal_found = 1;
611 current_op->immediate.label = xstrdup (token);
612 current_op->immediate.f_number = (float) atof (token);
613 current_op->immediate.s_number = (int) atoi (token);
614 current_op->immediate.u_number = (unsigned int) atoi (token);
615 current_op->immediate.resolved = 1;
617 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
618 if (current_op->immediate.u_number <= 31)
619 current_op->op_type |= IVector;
622 return current_op;
625 struct tic30_par_insn
627 partemplate *tm; /* Template of current parallel instruction. */
628 unsigned operands[2]; /* Number of given operands for each insn. */
629 /* Type of operand given in instruction. */
630 operand *operand_type[2][MAX_OPERANDS];
631 int swap_operands; /* Whether to swap operands around. */
632 unsigned p_field; /* Value of p field in multiply add/sub instructions. */
633 unsigned opcode; /* Final opcode. */
636 struct tic30_par_insn p_insn;
638 static int
639 tic30_parallel_insn (char *token)
641 static partemplate *p_opcode;
642 char *current_posn = token;
643 char *token_start;
644 char save_char;
646 debug ("In tic30_parallel_insn with %s\n", token);
647 memset (&p_insn, '\0', sizeof (p_insn));
649 while (is_opcode_char (*current_posn))
650 current_posn++;
652 /* Find instruction. */
653 save_char = *current_posn;
654 *current_posn = '\0';
655 p_opcode = (partemplate *) str_hash_find (parop_hash, token);
656 if (p_opcode)
658 debug ("Found instruction %s\n", p_opcode->name);
659 p_insn.tm = p_opcode;
661 else
663 char first_opcode[6] = {0};
664 char second_opcode[6] = {0};
665 unsigned int i;
666 int current_opcode = -1;
667 int char_ptr = 0;
669 for (i = 0; i < strlen (token); i++)
671 char ch = *(token + i);
673 if (ch == '_' && current_opcode == -1)
675 current_opcode = 0;
676 continue;
679 if (ch == '_' && current_opcode == 0)
681 current_opcode = 1;
682 char_ptr = 0;
683 continue;
686 switch (current_opcode)
688 case 0:
689 first_opcode[char_ptr++] = ch;
690 break;
691 case 1:
692 second_opcode[char_ptr++] = ch;
693 break;
697 debug ("first_opcode = %s\n", first_opcode);
698 debug ("second_opcode = %s\n", second_opcode);
699 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
700 p_opcode = (partemplate *) str_hash_find (parop_hash, token);
702 if (p_opcode)
704 debug ("Found instruction %s\n", p_opcode->name);
705 p_insn.tm = p_opcode;
706 p_insn.swap_operands = 1;
708 else
709 return 0;
711 *current_posn = save_char;
715 /* Find operands. */
716 int paren_not_balanced;
717 int expecting_operand = 0;
718 int found_separator = 0;
722 /* Skip optional white space before operand. */
723 while (!is_operand_char (*current_posn)
724 && *current_posn != END_OF_INSN)
726 if (!is_space_char (*current_posn)
727 && *current_posn != PARALLEL_SEPARATOR)
729 as_bad (_("Invalid character %s before %s operand"),
730 output_invalid (*current_posn),
731 ordinal_names[insn.operands]);
732 return 1;
734 if (*current_posn == PARALLEL_SEPARATOR)
735 found_separator = 1;
736 current_posn++;
739 token_start = current_posn;
740 paren_not_balanced = 0;
742 while (paren_not_balanced || *current_posn != ',')
744 if (*current_posn == END_OF_INSN)
746 if (paren_not_balanced)
748 as_bad (_("Unbalanced parenthesis in %s operand."),
749 ordinal_names[insn.operands]);
750 return 1;
752 else
753 break;
755 else if (*current_posn == PARALLEL_SEPARATOR)
757 while (is_space_char (*(current_posn - 1)))
758 current_posn--;
759 break;
761 else if (!is_operand_char (*current_posn)
762 && !is_space_char (*current_posn))
764 as_bad (_("Invalid character %s in %s operand"),
765 output_invalid (*current_posn),
766 ordinal_names[insn.operands]);
767 return 1;
770 if (*current_posn == '(')
771 ++paren_not_balanced;
772 if (*current_posn == ')')
773 --paren_not_balanced;
774 current_posn++;
777 if (current_posn != token_start)
779 /* Yes, we've read in another operand. */
780 p_insn.operands[found_separator]++;
781 if (p_insn.operands[found_separator] > MAX_OPERANDS)
783 as_bad (_("Spurious operands; (%d operands/instruction max)"),
784 MAX_OPERANDS);
785 return 1;
788 /* Now parse operand adding info to 'insn' as we go along. */
789 save_char = *current_posn;
790 *current_posn = '\0';
791 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
792 tic30_operand (token_start);
793 *current_posn = save_char;
794 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
795 return 1;
797 else
799 if (expecting_operand)
801 as_bad (_("Expecting operand after ','; got nothing"));
802 return 1;
804 if (*current_posn == ',')
806 as_bad (_("Expecting operand before ','; got nothing"));
807 return 1;
811 /* Now *current_posn must be either ',' or END_OF_INSN. */
812 if (*current_posn == ',')
814 if (*++current_posn == END_OF_INSN)
816 /* Just skip it, if it's \n complain. */
817 as_bad (_("Expecting operand after ','; got nothing"));
818 return 1;
820 expecting_operand = 1;
823 while (*current_posn != END_OF_INSN);
826 if (p_insn.swap_operands)
828 int temp_num, i;
829 operand *temp_op;
831 temp_num = p_insn.operands[0];
832 p_insn.operands[0] = p_insn.operands[1];
833 p_insn.operands[1] = temp_num;
834 for (i = 0; i < MAX_OPERANDS; i++)
836 temp_op = p_insn.operand_type[0][i];
837 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
838 p_insn.operand_type[1][i] = temp_op;
842 if (p_insn.operands[0] != p_insn.tm->operands_1)
844 as_bad (_("incorrect number of operands given in the first instruction"));
845 return 1;
848 if (p_insn.operands[1] != p_insn.tm->operands_2)
850 as_bad (_("incorrect number of operands given in the second instruction"));
851 return 1;
854 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
855 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
858 /* Now check if operands are correct. */
859 int count;
860 int num_rn = 0;
861 int num_ind = 0;
863 for (count = 0; count < 2; count++)
865 unsigned int i;
866 for (i = 0; i < p_insn.operands[count]; i++)
868 if ((p_insn.operand_type[count][i]->op_type &
869 p_insn.tm->operand_types[count][i]) == 0)
871 as_bad (_("%s instruction, operand %d doesn't match"),
872 ordinal_names[count], i + 1);
873 return 1;
876 /* Get number of R register and indirect reference contained
877 within the first two operands of each instruction. This is
878 required for the multiply parallel instructions which require
879 two R registers and two indirect references, but not in any
880 particular place. */
881 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
882 num_rn++;
883 else if ((p_insn.operand_type[count][i]->op_type & Indirect)
884 && i < 2)
885 num_ind++;
889 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
890 == (Indirect | Rn))
892 /* Check for the multiply instructions. */
893 if (num_rn != 2)
895 as_bad (_("incorrect format for multiply parallel instruction"));
896 return 1;
899 if (num_ind != 2)
901 /* Shouldn't get here. */
902 as_bad (_("incorrect format for multiply parallel instruction"));
903 return 1;
906 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
907 && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
909 as_bad (_("destination for multiply can only be R0 or R1"));
910 return 1;
913 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
914 && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
916 as_bad (_("destination for add/subtract can only be R2 or R3"));
917 return 1;
920 /* Now determine the P field for the instruction. */
921 if (p_insn.operand_type[0][0]->op_type & Indirect)
923 if (p_insn.operand_type[0][1]->op_type & Indirect)
924 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
925 else if (p_insn.operand_type[1][0]->op_type & Indirect)
926 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
927 else
928 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
930 else
932 if (p_insn.operand_type[0][1]->op_type & Rn)
933 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
934 else if (p_insn.operand_type[1][0]->op_type & Indirect)
936 operand *temp;
937 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
938 /* Need to swap the two multiply operands around so that
939 everything is in its place for the opcode makeup.
940 ie so Ind * Rn, Ind +/- Rn. */
941 temp = p_insn.operand_type[0][0];
942 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
943 p_insn.operand_type[0][1] = temp;
945 else
947 operand *temp;
948 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
949 temp = p_insn.operand_type[0][0];
950 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
951 p_insn.operand_type[0][1] = temp;
957 debug ("P field: %08X\n", p_insn.p_field);
959 /* Finalise opcode. This is easier for parallel instructions as they have
960 to be fully resolved, there are no memory addresses allowed, except
961 through indirect addressing, so there are no labels to resolve. */
962 p_insn.opcode = p_insn.tm->base_opcode;
964 switch (p_insn.tm->oporder)
966 case OO_4op1:
967 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
968 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
969 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
970 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
971 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
972 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
973 break;
975 case OO_4op2:
976 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
977 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
978 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
979 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
980 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
981 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
982 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
983 as_warn (_("loading the same register in parallel operation"));
984 break;
986 case OO_4op3:
987 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
988 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
989 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
990 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
991 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
992 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
993 break;
995 case OO_5op1:
996 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
997 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
998 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
999 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1000 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1001 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1002 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1003 break;
1005 case OO_5op2:
1006 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1007 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1008 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1009 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1010 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1011 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1012 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1013 break;
1015 case OO_PField:
1016 p_insn.opcode |= p_insn.p_field;
1017 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1018 p_insn.opcode |= 0x00800000;
1019 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1020 p_insn.opcode |= 0x00400000;
1022 switch (p_insn.p_field)
1024 case 0x00000000:
1025 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1026 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1027 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1028 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1029 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1030 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1031 break;
1032 case 0x01000000:
1033 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1034 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1035 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1036 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1037 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1038 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1039 break;
1040 case 0x02000000:
1041 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1042 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1043 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1044 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1045 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1046 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1047 break;
1048 case 0x03000000:
1049 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1050 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1051 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1052 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1053 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1054 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1055 break;
1057 break;
1061 char *p;
1063 p = frag_more (INSN_SIZE);
1064 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1068 unsigned int i, j;
1070 for (i = 0; i < 2; i++)
1071 for (j = 0; j < p_insn.operands[i]; j++)
1072 free (p_insn.operand_type[i][j]);
1075 debug ("Final opcode: %08X\n", p_insn.opcode);
1076 debug ("\n");
1078 return 1;
1081 /* In order to get gas to ignore any | chars at the start of a line,
1082 this function returns true if a | is found in a line. */
1085 tic30_unrecognized_line (int c)
1087 debug ("In tc_unrecognized_line\n");
1088 return (c == PARALLEL_SEPARATOR);
1092 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1093 segT segment ATTRIBUTE_UNUSED)
1095 debug ("In md_estimate_size_before_relax()\n");
1096 return 0;
1099 void
1100 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1101 segT sec ATTRIBUTE_UNUSED,
1102 fragS *fragP ATTRIBUTE_UNUSED)
1104 debug ("In md_convert_frag()\n");
1107 void
1108 md_apply_fix (fixS *fixP,
1109 valueT *valP,
1110 segT seg ATTRIBUTE_UNUSED)
1112 valueT value = *valP;
1114 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1115 debug ("Values in fixP\n");
1116 debug ("fx_size = %d\n", fixP->fx_size);
1117 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1118 debug ("fx_where = %ld\n", fixP->fx_where);
1119 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1121 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1123 value /= INSN_SIZE;
1124 if (fixP->fx_size == 1)
1125 /* Special fix for LDP instruction. */
1126 value = (value & 0x00FF0000) >> 16;
1128 debug ("new value = %ld\n", (long) value);
1129 md_number_to_chars (buf, value, fixP->fx_size);
1132 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1133 fixP->fx_done = 1;
1137 md_parse_option (int c ATTRIBUTE_UNUSED,
1138 const char *arg ATTRIBUTE_UNUSED)
1140 debug ("In md_parse_option()\n");
1141 return 0;
1144 void
1145 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1147 debug ("In md_show_usage()\n");
1150 symbolS *
1151 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1153 debug ("In md_undefined_symbol()\n");
1154 return (symbolS *) 0;
1157 valueT
1158 md_section_align (segT segment, valueT size)
1160 debug ("In md_section_align() segment = %p and size = %lu\n",
1161 segment, (unsigned long) size);
1162 size = (size + 3) / 4;
1163 size *= 4;
1164 debug ("New size value = %lu\n", (unsigned long) size);
1165 return size;
1168 long
1169 md_pcrel_from (fixS *fixP)
1171 int offset;
1173 debug ("In md_pcrel_from()\n");
1174 debug ("fx_where = %ld\n", fixP->fx_where);
1175 debug ("fx_size = %d\n", fixP->fx_size);
1176 /* Find the opcode that represents the current instruction in the
1177 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1178 current instruction is a delayed one or not, and then set the offset
1179 value appropriately. */
1180 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1181 offset = 3;
1182 else
1183 offset = 1;
1184 debug ("offset = %d\n", offset);
1185 /* PC Relative instructions have a format:
1186 displacement = Label - (PC + offset)
1187 This function returns PC + offset where:
1188 fx_where - fx_size = PC
1189 INSN_SIZE * offset = offset number of instructions. */
1190 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1193 const char *
1194 md_atof (int what_statement_type,
1195 char *literalP,
1196 int *sizeP)
1198 int prec;
1199 char *token;
1200 char keepval;
1201 unsigned long value;
1202 float float_value;
1204 debug ("In md_atof()\n");
1205 debug ("precision = %c\n", what_statement_type);
1206 debug ("literal = %s\n", literalP);
1207 debug ("line = ");
1208 token = input_line_pointer;
1209 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1210 && (*input_line_pointer != ','))
1212 debug ("%c", *input_line_pointer);
1213 input_line_pointer++;
1216 keepval = *input_line_pointer;
1217 *input_line_pointer = '\0';
1218 debug ("\n");
1219 float_value = (float) atof (token);
1220 *input_line_pointer = keepval;
1221 debug ("float_value = %f\n", float_value);
1223 switch (what_statement_type)
1225 case 'f':
1226 case 'F':
1227 case 's':
1228 case 'S':
1229 prec = 2;
1230 break;
1232 case 'd':
1233 case 'D':
1234 case 'r':
1235 case 'R':
1236 prec = 4;
1237 break;
1239 default:
1240 *sizeP = 0;
1241 return _("Unrecognized or unsupported floating point constant");
1244 if (float_value == 0.0)
1245 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1246 else
1248 unsigned long exp, sign, mant, tmsfloat;
1249 union
1251 float f;
1252 long l;
1254 converter;
1256 converter.f = float_value;
1257 tmsfloat = converter.l;
1258 sign = tmsfloat & 0x80000000;
1259 mant = tmsfloat & 0x007FFFFF;
1260 exp = tmsfloat & 0x7F800000;
1261 exp <<= 1;
1262 if (exp == 0xFF000000)
1264 if (mant == 0)
1265 value = 0x7F7FFFFF;
1266 else if (sign == 0)
1267 value = 0x7F7FFFFF;
1268 else
1269 value = 0x7F800000;
1271 else
1273 exp -= 0x7F000000;
1274 if (sign)
1276 mant = mant & 0x007FFFFF;
1277 mant = -mant;
1278 mant = mant & 0x00FFFFFF;
1279 if (mant == 0)
1281 mant |= 0x00800000;
1282 exp = (long) exp - 0x01000000;
1285 tmsfloat = exp | mant;
1286 value = tmsfloat;
1288 if (prec == 2)
1290 long expon, mantis;
1292 if (tmsfloat == 0x80000000)
1293 value = 0x8000;
1294 else
1296 value = 0;
1297 expon = (tmsfloat & 0xFF000000);
1298 expon >>= 24;
1299 mantis = tmsfloat & 0x007FFFFF;
1300 if (tmsfloat & 0x00800000)
1302 mantis |= 0xFF000000;
1303 mantis += 0x00000800;
1304 mantis >>= 12;
1305 mantis |= 0x00000800;
1306 mantis &= 0x0FFF;
1307 if (expon > 7)
1308 value = 0x7800;
1310 else
1312 mantis |= 0x00800000;
1313 mantis += 0x00000800;
1314 expon += (mantis >> 24);
1315 mantis >>= 12;
1316 mantis &= 0x07FF;
1317 if (expon > 7)
1318 value = 0x77FF;
1320 if (expon < -8)
1321 value = 0x8000;
1322 if (value == 0)
1324 mantis = (expon << 12) | mantis;
1325 value = mantis & 0xFFFF;
1330 md_number_to_chars (literalP, value, prec);
1331 *sizeP = prec;
1332 return NULL;
1335 void
1336 md_number_to_chars (char *buf, valueT val, int n)
1338 debug ("In md_number_to_chars()\n");
1339 number_to_chars_bigendian (buf, val, n);
1342 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1343 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1345 arelent *
1346 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1348 arelent *rel;
1349 bfd_reloc_code_real_type code = 0;
1351 debug ("In tc_gen_reloc()\n");
1352 debug ("fixP.size = %d\n", fixP->fx_size);
1353 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1354 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1356 switch (F (fixP->fx_size, fixP->fx_pcrel))
1358 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1359 MAP (2, 0, BFD_RELOC_16);
1360 MAP (3, 0, BFD_RELOC_24);
1361 MAP (2, 1, BFD_RELOC_16_PCREL);
1362 MAP (4, 0, BFD_RELOC_32);
1363 default:
1364 as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1365 fixP->fx_pcrel ? _("pc-relative ") : "");
1367 #undef MAP
1368 #undef F
1370 rel = XNEW (arelent);
1371 gas_assert (rel != 0);
1372 rel->sym_ptr_ptr = XNEW (asymbol *);
1373 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1374 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1375 rel->addend = 0;
1376 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1377 if (!rel->howto)
1379 const char *name;
1381 name = S_GET_NAME (fixP->fx_addsy);
1382 if (name == NULL)
1383 name = "<unknown>";
1384 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1385 name, bfd_get_reloc_code_name (code));
1387 return rel;
1390 void
1391 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1393 debug ("In md_operand()\n");
1396 void
1397 md_assemble (char *line)
1399 insn_template *op;
1400 char *current_posn;
1401 char *token_start;
1402 char save_char;
1403 unsigned int count;
1405 debug ("In md_assemble() with argument %s\n", line);
1406 memset (&insn, '\0', sizeof (insn));
1407 if (found_parallel_insn)
1409 debug ("Line is second part of parallel instruction\n\n");
1410 found_parallel_insn = 0;
1411 return;
1413 if ((current_posn =
1414 tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1415 current_posn = line;
1416 else
1417 found_parallel_insn = 1;
1419 while (is_space_char (*current_posn))
1420 current_posn++;
1422 token_start = current_posn;
1424 if (!is_opcode_char (*current_posn))
1426 as_bad (_("Invalid character %s in opcode"),
1427 output_invalid (*current_posn));
1428 return;
1430 /* Check if instruction is a parallel instruction
1431 by seeing if the first character is a q. */
1432 if (*token_start == 'q')
1434 if (tic30_parallel_insn (token_start))
1436 if (found_parallel_insn)
1437 free (token_start);
1438 return;
1441 while (is_opcode_char (*current_posn))
1442 current_posn++;
1444 /* Find instruction. */
1445 save_char = *current_posn;
1446 *current_posn = '\0';
1447 op = (insn_template *) str_hash_find (op_hash, token_start);
1448 if (op)
1450 debug ("Found instruction %s\n", op->name);
1451 insn.tm = op;
1453 else
1455 debug ("Didn't find insn\n");
1456 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1457 return;
1459 *current_posn = save_char;
1462 if (*current_posn != END_OF_INSN)
1464 /* Find operands. */
1465 int paren_not_balanced;
1466 int expecting_operand = 0;
1467 int this_operand;
1470 /* Skip optional white space before operand. */
1471 while (!is_operand_char (*current_posn)
1472 && *current_posn != END_OF_INSN)
1474 if (!is_space_char (*current_posn))
1476 as_bad (_("Invalid character %s before %s operand"),
1477 output_invalid (*current_posn),
1478 ordinal_names[insn.operands]);
1479 return;
1481 current_posn++;
1483 token_start = current_posn;
1484 paren_not_balanced = 0;
1485 while (paren_not_balanced || *current_posn != ',')
1487 if (*current_posn == END_OF_INSN)
1489 if (paren_not_balanced)
1491 as_bad (_("Unbalanced parenthesis in %s operand."),
1492 ordinal_names[insn.operands]);
1493 return;
1495 else
1496 break;
1498 else if (!is_operand_char (*current_posn)
1499 && !is_space_char (*current_posn))
1501 as_bad (_("Invalid character %s in %s operand"),
1502 output_invalid (*current_posn),
1503 ordinal_names[insn.operands]);
1504 return;
1506 if (*current_posn == '(')
1507 ++paren_not_balanced;
1508 if (*current_posn == ')')
1509 --paren_not_balanced;
1510 current_posn++;
1512 if (current_posn != token_start)
1514 /* Yes, we've read in another operand. */
1515 this_operand = insn.operands++;
1516 if (insn.operands > MAX_OPERANDS)
1518 as_bad (_("Spurious operands; (%d operands/instruction max)"),
1519 MAX_OPERANDS);
1520 return;
1523 /* Now parse operand adding info to 'insn' as we go along. */
1524 save_char = *current_posn;
1525 *current_posn = '\0';
1526 insn.operand_type[this_operand] = tic30_operand (token_start);
1527 *current_posn = save_char;
1528 if (insn.operand_type[this_operand] == NULL)
1529 return;
1531 else
1533 if (expecting_operand)
1535 as_bad (_("Expecting operand after ','; got nothing"));
1536 return;
1538 if (*current_posn == ',')
1540 as_bad (_("Expecting operand before ','; got nothing"));
1541 return;
1545 /* Now *current_posn must be either ',' or END_OF_INSN. */
1546 if (*current_posn == ',')
1548 if (*++current_posn == END_OF_INSN)
1550 /* Just skip it, if it's \n complain. */
1551 as_bad (_("Expecting operand after ','; got nothing"));
1552 return;
1554 expecting_operand = 1;
1557 while (*current_posn != END_OF_INSN);
1560 debug ("Number of operands found: %d\n", insn.operands);
1562 /* Check that number of operands is correct. */
1563 if (insn.operands != insn.tm->operands)
1565 unsigned int i;
1566 unsigned int numops = insn.tm->operands;
1568 /* If operands are not the same, then see if any of the operands are
1569 not required. Then recheck with number of given operands. If they
1570 are still not the same, then give an error, otherwise carry on. */
1571 for (i = 0; i < insn.tm->operands; i++)
1572 if (insn.tm->operand_types[i] & NotReq)
1573 numops--;
1574 if (insn.operands != numops)
1576 as_bad (_("Incorrect number of operands given"));
1577 return;
1580 insn.addressing_mode = AM_NotReq;
1581 for (count = 0; count < insn.operands; count++)
1583 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1585 debug ("Operand %d matches\n", count + 1);
1586 /* If instruction has two operands and has an AddressMode
1587 modifier then set addressing mode type for instruction. */
1588 if (insn.tm->opcode_modifier == AddressMode)
1590 int addr_insn = 0;
1591 /* Store instruction uses the second
1592 operand for the address mode. */
1593 if ((insn.tm->operand_types[1] & (Indirect | Direct))
1594 == (Indirect | Direct))
1595 addr_insn = 1;
1597 if (insn.operand_type[addr_insn]->op_type & (AllReg))
1598 insn.addressing_mode = AM_Register;
1599 else if (insn.operand_type[addr_insn]->op_type & Direct)
1600 insn.addressing_mode = AM_Direct;
1601 else if (insn.operand_type[addr_insn]->op_type & Indirect)
1602 insn.addressing_mode = AM_Indirect;
1603 else
1604 insn.addressing_mode = AM_Immediate;
1607 else
1609 as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1610 return;
1614 /* Now set the addressing mode for 3 operand instructions. */
1615 if ((insn.tm->operand_types[0] & op3T1)
1616 && (insn.tm->operand_types[1] & op3T2))
1618 /* Set the addressing mode to the values used for 2 operand
1619 instructions in the G addressing field of the opcode. */
1620 char *p;
1621 switch (insn.operand_type[0]->op_type)
1623 case Rn:
1624 case ARn:
1625 case DPReg:
1626 case OtherReg:
1627 if (insn.operand_type[1]->op_type & (AllReg))
1628 insn.addressing_mode = AM_Register;
1629 else if (insn.operand_type[1]->op_type & Indirect)
1630 insn.addressing_mode = AM_Direct;
1631 else
1633 /* Shouldn't make it to this stage. */
1634 as_bad (_("Incompatible first and second operands in instruction"));
1635 return;
1637 break;
1638 case Indirect:
1639 if (insn.operand_type[1]->op_type & (AllReg))
1640 insn.addressing_mode = AM_Indirect;
1641 else if (insn.operand_type[1]->op_type & Indirect)
1642 insn.addressing_mode = AM_Immediate;
1643 else
1645 /* Shouldn't make it to this stage. */
1646 as_bad (_("Incompatible first and second operands in instruction"));
1647 return;
1649 break;
1651 /* Now make up the opcode for the 3 operand instructions. As in
1652 parallel instructions, there will be no unresolved values, so they
1653 can be fully formed and added to the frag table. */
1654 insn.opcode = insn.tm->base_opcode;
1655 if (insn.operand_type[0]->op_type & Indirect)
1657 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1658 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1660 else
1661 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1663 if (insn.operand_type[1]->op_type & Indirect)
1665 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1666 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1668 else
1669 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1671 if (insn.operands == 3)
1672 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1674 insn.opcode |= insn.addressing_mode;
1675 p = frag_more (INSN_SIZE);
1676 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1678 else
1680 /* Not a three operand instruction. */
1681 char *p;
1682 int am_insn = -1;
1683 insn.opcode = insn.tm->base_opcode;
1684 /* Create frag for instruction - all instructions are 4 bytes long. */
1685 p = frag_more (INSN_SIZE);
1686 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1688 insn.opcode |= insn.addressing_mode;
1689 if (insn.addressing_mode == AM_Indirect)
1691 /* Determine which operand gives the addressing mode. */
1692 if (insn.operand_type[0]->op_type & Indirect)
1693 am_insn = 0;
1694 if ((insn.operands > 1)
1695 && (insn.operand_type[1]->op_type & Indirect))
1696 am_insn = 1;
1697 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1698 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1699 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1700 if (insn.operands > 1)
1701 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1702 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1704 else if (insn.addressing_mode == AM_Register)
1706 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1707 if (insn.operands > 1)
1708 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1709 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1711 else if (insn.addressing_mode == AM_Direct)
1713 if (insn.operand_type[0]->op_type & Direct)
1714 am_insn = 0;
1715 if ((insn.operands > 1)
1716 && (insn.operand_type[1]->op_type & Direct))
1717 am_insn = 1;
1718 if (insn.operands > 1)
1719 insn.opcode |=
1720 (insn.operand_type[! am_insn]->reg.opcode << 16);
1721 if (insn.operand_type[am_insn]->direct.resolved == 1)
1723 /* Resolved values can be placed straight
1724 into instruction word, and output. */
1725 insn.opcode |=
1726 (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1727 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1729 else
1731 /* Unresolved direct addressing mode instruction. */
1732 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1733 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1734 & insn.operand_type[am_insn]->direct.direct_expr,
1735 0, 0);
1738 else if (insn.addressing_mode == AM_Immediate)
1740 if (insn.operand_type[0]->immediate.resolved == 1)
1742 char *keeploc;
1743 int size;
1745 if (insn.operands > 1)
1746 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1748 switch (insn.tm->imm_arg_type)
1750 case Imm_Float:
1751 debug ("Floating point first operand\n");
1752 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1754 keeploc = input_line_pointer;
1755 input_line_pointer =
1756 insn.operand_type[0]->immediate.label;
1758 if (md_atof ('f', p + 2, & size) != 0)
1760 as_bad (_("invalid short form floating point immediate operand"));
1761 return;
1764 input_line_pointer = keeploc;
1765 break;
1767 case Imm_UInt:
1768 debug ("Unsigned int first operand\n");
1769 if (insn.operand_type[0]->immediate.decimal_found)
1770 as_warn (_("rounding down first operand float to unsigned int"));
1771 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1772 as_warn (_("only lower 16-bits of first operand are used"));
1773 insn.opcode |=
1774 (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1775 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1776 break;
1778 case Imm_SInt:
1779 debug ("Int first operand\n");
1781 if (insn.operand_type[0]->immediate.decimal_found)
1782 as_warn (_("rounding down first operand float to signed int"));
1784 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1785 insn.operand_type[0]->immediate.s_number > 32767)
1787 as_bad (_("first operand is too large for 16-bit signed int"));
1788 return;
1790 insn.opcode |=
1791 (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1792 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1793 break;
1796 else
1798 /* Unresolved immediate label. */
1799 if (insn.operands > 1)
1800 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1801 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1802 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1803 & insn.operand_type[0]->immediate.imm_expr,
1804 0, 0);
1808 else if (insn.tm->opcode_modifier == PCRel)
1810 /* Conditional Branch and Call instructions. */
1811 if ((insn.tm->operand_types[0] & (AllReg | Disp))
1812 == (AllReg | Disp))
1814 if (insn.operand_type[0]->op_type & (AllReg))
1816 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1817 insn.opcode |= PC_Register;
1818 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1820 else
1822 insn.opcode |= PC_Relative;
1823 if (insn.operand_type[0]->immediate.resolved == 1)
1825 insn.opcode |=
1826 (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1827 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1829 else
1831 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1832 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1833 2, & insn.operand_type[0]->immediate.imm_expr,
1834 1, 0);
1838 else if ((insn.tm->operand_types[0] & ARn) == ARn)
1840 /* Decrement and Branch instructions. */
1841 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1842 if (insn.operand_type[1]->op_type & (AllReg))
1844 insn.opcode |= (insn.operand_type[1]->reg.opcode);
1845 insn.opcode |= PC_Register;
1846 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1848 else if (insn.operand_type[1]->immediate.resolved == 1)
1850 if (insn.operand_type[0]->immediate.decimal_found)
1852 as_bad (_("first operand is floating point"));
1853 return;
1855 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1856 insn.operand_type[0]->immediate.s_number > 32767)
1858 as_bad (_("first operand is too large for 16-bit signed int"));
1859 return;
1861 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1862 insn.opcode |= PC_Relative;
1863 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1865 else
1867 insn.opcode |= PC_Relative;
1868 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1869 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1870 & insn.operand_type[1]->immediate.imm_expr,
1871 1, 0);
1875 else if (insn.tm->operand_types[0] == IVector)
1877 /* Trap instructions. */
1878 if (insn.operand_type[0]->op_type & IVector)
1879 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1880 else
1882 /* Shouldn't get here. */
1883 as_bad (_("interrupt vector for trap instruction out of range"));
1884 return;
1886 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1888 else if (insn.tm->opcode_modifier == StackOp
1889 || insn.tm->opcode_modifier == Rotate)
1891 /* Push, Pop and Rotate instructions. */
1892 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1893 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1895 else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1896 == (Abs24 | Direct))
1898 /* LDP Instruction needs to be tested
1899 for before the next section. */
1900 if (insn.operand_type[0]->op_type & Direct)
1902 if (insn.operand_type[0]->direct.resolved == 1)
1904 /* Direct addressing uses lower 8 bits of direct address. */
1905 insn.opcode |=
1906 (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1907 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1909 else
1911 fixS *fix;
1913 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1914 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1915 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1916 /* Ensure that the assembler doesn't complain
1917 about fitting a 24-bit address into 8 bits. */
1918 fix->fx_no_overflow = 1;
1921 else
1923 if (insn.operand_type[0]->immediate.resolved == 1)
1925 /* Immediate addressing uses upper 8 bits of address. */
1926 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1928 as_bad (_("LDP instruction needs a 24-bit operand"));
1929 return;
1931 insn.opcode |=
1932 ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1933 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1935 else
1937 fixS *fix;
1938 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1939 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1940 1, &insn.operand_type[0]->immediate.imm_expr,
1941 0, 0);
1942 fix->fx_no_overflow = 1;
1946 else if (insn.tm->operand_types[0] & (Imm24))
1948 /* Unconditional Branch and Call instructions. */
1949 if (insn.operand_type[0]->immediate.resolved == 1)
1951 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1952 as_warn (_("first operand is too large for a 24-bit displacement"));
1953 insn.opcode |=
1954 (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1955 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1957 else
1959 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1960 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1961 & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1964 else if (insn.tm->operand_types[0] & NotReq)
1965 /* Check for NOP instruction without arguments. */
1966 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1968 else if (insn.tm->operands == 0)
1969 /* Check for instructions without operands. */
1970 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1972 debug ("Addressing mode: %08X\n", insn.addressing_mode);
1974 unsigned int i;
1976 for (i = 0; i < insn.operands; i++)
1978 free (insn.operand_type[i]->immediate.label);
1979 free (insn.operand_type[i]);
1982 debug ("Final opcode: %08X\n", insn.opcode);
1983 debug ("\n");