]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-tic30.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-tic30.c
1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
3 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
4
5 This file is part of GAS, the GNU Assembler.
6
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.
11
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.
16
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. */
21
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. */
26
27 #include "as.h"
28 #include "safe-ctype.h"
29 #include "opcode/tic30.h"
30
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[] =
35 {
36 N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
37 };
38
39 const char comment_chars[] = ";";
40 const char line_comment_chars[] = "*";
41 const char line_separator_chars[] = "";
42
43 const char *md_shortopts = "";
44 struct option md_longopts[] =
45 {
46 {NULL, no_argument, NULL, 0}
47 };
48
49 size_t md_longopts_size = sizeof (md_longopts);
50
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";
55
56 /* Chars that can be used to separate mant from exp in floating point
57 nums. */
58 const char EXP_CHARS[] = "eE";
59
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];
67
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])
75
76 const pseudo_typeS md_pseudo_table[] =
77 {
78 {0, 0, 0}
79 };
80
81 static int ATTRIBUTE_PRINTF_1
82 debug (const char *string, ...)
83 {
84 if (flag_debug)
85 {
86 char str[100];
87 va_list argptr;
88
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);
96 }
97 else
98 return 0;
99 }
100
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;
109
110 void
111 md_begin (void)
112 {
113 debug ("In md_begin()\n");
114 op_hash = str_htab_create ();
115
116 {
117 const insn_template *current_optab = tic30_optab;
118
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);
122 }
123
124 parop_hash = str_htab_create ();
125
126 {
127 const partemplate *current_parop = tic30_paroptab;
128
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);
132 }
133
134 reg_hash = str_htab_create ();
135
136 {
137 const reg *current_reg = tic30_regtab;
138
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);
142 }
143
144 ind_hash = str_htab_create ();
145
146 {
147 const ind_addr_type *current_ind = tic30_indaddr_tab;
148
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);
152 }
153
154 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
155 {
156 int c;
157 char *p;
158
159 for (c = 0; c < 256; c++)
160 {
161 if (ISLOWER (c) || ISDIGIT (c))
162 {
163 opcode_chars[c] = c;
164 register_chars[c] = c;
165 }
166 else if (ISUPPER (c))
167 {
168 opcode_chars[c] = TOLOWER (c);
169 register_chars[c] = opcode_chars[c];
170 }
171 else if (c == ')' || c == '(')
172 register_chars[c] = c;
173
174 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
175 operand_chars[c] = c;
176
177 if (ISDIGIT (c) || c == '-')
178 digit_chars[c] = c;
179
180 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
181 identifier_chars[c] = c;
182
183 if (c == ' ' || c == '\t')
184 space_chars[c] = c;
185
186 if (c == '_')
187 opcode_chars[c] = c;
188 }
189 for (p = operand_special_chars; *p != '\0'; p++)
190 operand_chars[(unsigned char) *p] = *p;
191 }
192 }
193
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
200
201 /* PC Relative OR values. */
202 #define PC_Register 0x00000000
203 #define PC_Relative 0x02000000
204
205 typedef struct
206 {
207 unsigned op_type;
208 struct
209 {
210 int resolved;
211 unsigned address;
212 char *label;
213 expressionS direct_expr;
214 } direct;
215 struct
216 {
217 unsigned mod;
218 int ARnum;
219 unsigned char disp;
220 } indirect;
221 struct
222 {
223 unsigned opcode;
224 } reg;
225 struct
226 {
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;
236
237 insn_template *opcode;
238
239 struct tic30_insn
240 {
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. */
247 };
248
249 struct tic30_insn insn;
250 static int found_parallel_insn;
251
252 static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
253
254 static char *
255 output_invalid (char c)
256 {
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;
264 }
265
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. */
272
273 #define NONE 0
274 #define START_OPCODE 1
275 #define END_OPCODE 2
276 #define START_OPERANDS 3
277 #define END_OPERANDS 4
278
279 static char *
280 tic30_find_parallel_insn (char *current_line, char *next_line)
281 {
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;
288
289 debug ("In tic30_find_parallel_insn()\n");
290 while (!is_end_of_line[(unsigned char) *next_line])
291 {
292 if (*next_line == PARALLEL_SEPARATOR
293 && *(next_line + 1) == PARALLEL_SEPARATOR)
294 {
295 found_parallel = 1;
296 next_line++;
297 break;
298 }
299 next_line++;
300 }
301 if (!found_parallel)
302 return NULL;
303 debug ("Found a parallel instruction\n");
304
305 {
306 int i;
307 char *op, *operands, *line;
308
309 for (i = 0; i < 2; i++)
310 {
311 if (i == 0)
312 {
313 op = &first_opcode[0];
314 operands = &first_operands[0];
315 line = current_line;
316 }
317 else
318 {
319 op = &second_opcode[0];
320 operands = &second_operands[0];
321 line = next_line;
322 }
323
324 {
325 int search_status = NONE;
326 int char_ptr = 0;
327 char c;
328
329 while (!is_end_of_line[(unsigned char) (c = *line)])
330 {
331 if (is_opcode_char (c) && search_status == NONE)
332 {
333 op[char_ptr++] = TOLOWER (c);
334 search_status = START_OPCODE;
335 }
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)
339 {
340 op[char_ptr] = '\0';
341 char_ptr = 0;
342 search_status = END_OPCODE;
343 }
344 else if (is_operand_char (c) && search_status == START_OPERANDS)
345 operands[char_ptr++] = c;
346
347 if (is_operand_char (c) && search_status == END_OPCODE)
348 {
349 operands[char_ptr++] = c;
350 search_status = START_OPERANDS;
351 }
352
353 line++;
354 }
355 if (search_status != START_OPERANDS)
356 return NULL;
357 operands[char_ptr] = '\0';
358 }
359 }
360 }
361
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;
367 }
368
369 #undef NONE
370 #undef START_OPCODE
371 #undef END_OPCODE
372 #undef START_OPERANDS
373 #undef END_OPERANDS
374
375 static operand *
376 tic30_operand (char *token)
377 {
378 unsigned int count;
379 operand *current_op;
380
381 debug ("In tic30_operand with %s\n", token);
382 current_op = XCNEW (operand);
383
384 if (*token == DIRECT_REFERENCE)
385 {
386 char *token_posn = token + 1;
387 int direct_label = 0;
388
389 debug ("Found direct reference\n");
390 while (*token_posn)
391 {
392 if (!is_digit_char (*token_posn))
393 direct_label = 1;
394 token_posn++;
395 }
396
397 if (direct_label)
398 {
399 char *save_input_line_pointer;
400 segT retval;
401
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);
408
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);
414
415 input_line_pointer = save_input_line_pointer;
416
417 if (current_op->direct.direct_expr.X_op == O_constant)
418 {
419 current_op->direct.address =
420 current_op->direct.direct_expr.X_add_number;
421 current_op->direct.resolved = 1;
422 }
423 }
424 else
425 {
426 debug ("Direct reference is a number\n");
427 current_op->direct.address = atoi (token + 1);
428 current_op->direct.resolved = 1;
429 }
430 current_op->op_type = Direct;
431 }
432 else if (*token == INDIRECT_REFERENCE)
433 {
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;
442
443 ind_buffer = XNEWVEC (char, strlen (token));
444
445 debug ("Found indirect reference\n");
446 ind_buffer[0] = *token;
447
448 for (count = 1; count < strlen (token); count++)
449 {
450 /* Strip operand. */
451 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
452
453 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
454 && (*(token + count) == 'r' || *(token + count) == 'R'))
455 {
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)
459 {
460 as_bad (_("More than one AR register found in indirect reference"));
461 free (ind_buffer);
462 return NULL;
463 }
464 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
465 {
466 as_bad (_("Illegal AR register in indirect reference"));
467 free (ind_buffer);
468 return NULL;
469 }
470 ar_number = *(token + count + 1) - '0';
471 found_ar = 1;
472 count++;
473 }
474
475 if (*(token + count) == '(')
476 {
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)))
481 {
482 char disp[10];
483 int disp_posn = 0;
484
485 if (found_disp)
486 {
487 as_bad (_("More than one displacement found in indirect reference"));
488 free (ind_buffer);
489 return NULL;
490 }
491 count++;
492 while (*(token + count) != ')')
493 {
494 if (!is_digit_char (*(token + count)))
495 {
496 as_bad (_("Invalid displacement in indirect reference"));
497 free (ind_buffer);
498 return NULL;
499 }
500 disp[disp_posn++] = *(token + (count++));
501 }
502 disp[disp_posn] = '\0';
503 disp_number = atoi (disp);
504 count--;
505 found_disp = 1;
506 }
507 }
508 buffer_posn++;
509 }
510
511 ind_buffer[buffer_posn] = '\0';
512 if (!found_ar)
513 {
514 as_bad (_("AR register not found in indirect reference"));
515 free (ind_buffer);
516 return NULL;
517 }
518
519 ind_addr_op = (ind_addr_type *) str_hash_find (ind_hash, ind_buffer);
520 if (ind_addr_op)
521 {
522 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
523 if (ind_addr_op->displacement == IMPLIED_DISP)
524 {
525 found_disp = 1;
526 disp_number = 1;
527 }
528 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
529 {
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;
534 }
535 }
536 else
537 {
538 as_bad (_("illegal indirect reference"));
539 free (ind_buffer);
540 return NULL;
541 }
542
543 if (found_disp && (disp_number < 0 || disp_number > 255))
544 {
545 as_bad (_("displacement must be an unsigned 8-bit number"));
546 free (ind_buffer);
547 return NULL;
548 }
549
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);
555 }
556 else
557 {
558 reg *regop = (reg *) str_hash_find (reg_hash, token);
559
560 if (regop)
561 {
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;
572 }
573 else
574 {
575 if (!is_digit_char (*token)
576 || *(token + 1) == 'x'
577 || strchr (token, 'h'))
578 {
579 char *save_input_line_pointer;
580 segT retval;
581
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;
586
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;
595
596 if (current_op->immediate.imm_expr.X_op == O_constant)
597 {
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;
603 }
604 }
605 else
606 {
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;
616 }
617 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
618 if (current_op->immediate.u_number <= 31)
619 current_op->op_type |= IVector;
620 }
621 }
622 return current_op;
623 }
624
625 struct tic30_par_insn
626 {
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. */
634 };
635
636 struct tic30_par_insn p_insn;
637
638 static int
639 tic30_parallel_insn (char *token)
640 {
641 static partemplate *p_opcode;
642 char *current_posn = token;
643 char *token_start;
644 char save_char;
645
646 debug ("In tic30_parallel_insn with %s\n", token);
647 memset (&p_insn, '\0', sizeof (p_insn));
648
649 while (is_opcode_char (*current_posn))
650 current_posn++;
651 {
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)
657 {
658 debug ("Found instruction %s\n", p_opcode->name);
659 p_insn.tm = p_opcode;
660 }
661 else
662 {
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;
668
669 for (i = 0; i < strlen (token); i++)
670 {
671 char ch = *(token + i);
672
673 if (ch == '_' && current_opcode == -1)
674 {
675 current_opcode = 0;
676 continue;
677 }
678
679 if (ch == '_' && current_opcode == 0)
680 {
681 current_opcode = 1;
682 char_ptr = 0;
683 continue;
684 }
685
686 switch (current_opcode)
687 {
688 case 0:
689 first_opcode[char_ptr++] = ch;
690 break;
691 case 1:
692 second_opcode[char_ptr++] = ch;
693 break;
694 }
695 }
696
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);
701
702 if (p_opcode)
703 {
704 debug ("Found instruction %s\n", p_opcode->name);
705 p_insn.tm = p_opcode;
706 p_insn.swap_operands = 1;
707 }
708 else
709 return 0;
710 }
711 *current_posn = save_char;
712 }
713
714 {
715 /* Find operands. */
716 int paren_not_balanced;
717 int expecting_operand = 0;
718 int found_separator = 0;
719
720 do
721 {
722 /* Skip optional white space before operand. */
723 while (!is_operand_char (*current_posn)
724 && *current_posn != END_OF_INSN)
725 {
726 if (!is_space_char (*current_posn)
727 && *current_posn != PARALLEL_SEPARATOR)
728 {
729 as_bad (_("Invalid character %s before %s operand"),
730 output_invalid (*current_posn),
731 ordinal_names[insn.operands]);
732 return 1;
733 }
734 if (*current_posn == PARALLEL_SEPARATOR)
735 found_separator = 1;
736 current_posn++;
737 }
738
739 token_start = current_posn;
740 paren_not_balanced = 0;
741
742 while (paren_not_balanced || *current_posn != ',')
743 {
744 if (*current_posn == END_OF_INSN)
745 {
746 if (paren_not_balanced)
747 {
748 as_bad (_("Unbalanced parenthesis in %s operand."),
749 ordinal_names[insn.operands]);
750 return 1;
751 }
752 else
753 break;
754 }
755 else if (*current_posn == PARALLEL_SEPARATOR)
756 {
757 while (is_space_char (*(current_posn - 1)))
758 current_posn--;
759 break;
760 }
761 else if (!is_operand_char (*current_posn)
762 && !is_space_char (*current_posn))
763 {
764 as_bad (_("Invalid character %s in %s operand"),
765 output_invalid (*current_posn),
766 ordinal_names[insn.operands]);
767 return 1;
768 }
769
770 if (*current_posn == '(')
771 ++paren_not_balanced;
772 if (*current_posn == ')')
773 --paren_not_balanced;
774 current_posn++;
775 }
776
777 if (current_posn != token_start)
778 {
779 /* Yes, we've read in another operand. */
780 p_insn.operands[found_separator]++;
781 if (p_insn.operands[found_separator] > MAX_OPERANDS)
782 {
783 as_bad (_("Spurious operands; (%d operands/instruction max)"),
784 MAX_OPERANDS);
785 return 1;
786 }
787
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;
796 }
797 else
798 {
799 if (expecting_operand)
800 {
801 as_bad (_("Expecting operand after ','; got nothing"));
802 return 1;
803 }
804 if (*current_posn == ',')
805 {
806 as_bad (_("Expecting operand before ','; got nothing"));
807 return 1;
808 }
809 }
810
811 /* Now *current_posn must be either ',' or END_OF_INSN. */
812 if (*current_posn == ',')
813 {
814 if (*++current_posn == END_OF_INSN)
815 {
816 /* Just skip it, if it's \n complain. */
817 as_bad (_("Expecting operand after ','; got nothing"));
818 return 1;
819 }
820 expecting_operand = 1;
821 }
822 }
823 while (*current_posn != END_OF_INSN);
824 }
825
826 if (p_insn.swap_operands)
827 {
828 int temp_num, i;
829 operand *temp_op;
830
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++)
835 {
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;
839 }
840 }
841
842 if (p_insn.operands[0] != p_insn.tm->operands_1)
843 {
844 as_bad (_("incorrect number of operands given in the first instruction"));
845 return 1;
846 }
847
848 if (p_insn.operands[1] != p_insn.tm->operands_2)
849 {
850 as_bad (_("incorrect number of operands given in the second instruction"));
851 return 1;
852 }
853
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]);
856
857 {
858 /* Now check if operands are correct. */
859 int count;
860 int num_rn = 0;
861 int num_ind = 0;
862
863 for (count = 0; count < 2; count++)
864 {
865 unsigned int i;
866 for (i = 0; i < p_insn.operands[count]; i++)
867 {
868 if ((p_insn.operand_type[count][i]->op_type &
869 p_insn.tm->operand_types[count][i]) == 0)
870 {
871 as_bad (_("%s instruction, operand %d doesn't match"),
872 ordinal_names[count], i + 1);
873 return 1;
874 }
875
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++;
886 }
887 }
888
889 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
890 == (Indirect | Rn))
891 {
892 /* Check for the multiply instructions. */
893 if (num_rn != 2)
894 {
895 as_bad (_("incorrect format for multiply parallel instruction"));
896 return 1;
897 }
898
899 if (num_ind != 2)
900 {
901 /* Shouldn't get here. */
902 as_bad (_("incorrect format for multiply parallel instruction"));
903 return 1;
904 }
905
906 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
907 && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
908 {
909 as_bad (_("destination for multiply can only be R0 or R1"));
910 return 1;
911 }
912
913 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
914 && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
915 {
916 as_bad (_("destination for add/subtract can only be R2 or R3"));
917 return 1;
918 }
919
920 /* Now determine the P field for the instruction. */
921 if (p_insn.operand_type[0][0]->op_type & Indirect)
922 {
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. */
929 }
930 else
931 {
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)
935 {
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;
944 }
945 else
946 {
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;
952 }
953 }
954 }
955 }
956
957 debug ("P field: %08X\n", p_insn.p_field);
958
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;
963
964 switch (p_insn.tm->oporder)
965 {
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;
974
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;
985
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;
994
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;
1004
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;
1014
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;
1021
1022 switch (p_insn.p_field)
1023 {
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;
1056 }
1057 break;
1058 }
1059
1060 {
1061 char *p;
1062
1063 p = frag_more (INSN_SIZE);
1064 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1065 }
1066
1067 {
1068 unsigned int i, j;
1069
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]);
1073 }
1074
1075 debug ("Final opcode: %08X\n", p_insn.opcode);
1076 debug ("\n");
1077
1078 return 1;
1079 }
1080
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. */
1083
1084 int
1085 tic30_unrecognized_line (int c)
1086 {
1087 debug ("In tc_unrecognized_line\n");
1088 return (c == PARALLEL_SEPARATOR);
1089 }
1090
1091 int
1092 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1093 segT segment ATTRIBUTE_UNUSED)
1094 {
1095 debug ("In md_estimate_size_before_relax()\n");
1096 return 0;
1097 }
1098
1099 void
1100 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1101 segT sec ATTRIBUTE_UNUSED,
1102 fragS *fragP ATTRIBUTE_UNUSED)
1103 {
1104 debug ("In md_convert_frag()\n");
1105 }
1106
1107 void
1108 md_apply_fix (fixS *fixP,
1109 valueT *valP,
1110 segT seg ATTRIBUTE_UNUSED)
1111 {
1112 valueT value = *valP;
1113
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);
1120 {
1121 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1122
1123 value /= INSN_SIZE;
1124 if (fixP->fx_size == 1)
1125 /* Special fix for LDP instruction. */
1126 value = (value & 0x00FF0000) >> 16;
1127
1128 debug ("new value = %ld\n", (long) value);
1129 md_number_to_chars (buf, value, fixP->fx_size);
1130 }
1131
1132 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1133 fixP->fx_done = 1;
1134 }
1135
1136 int
1137 md_parse_option (int c ATTRIBUTE_UNUSED,
1138 const char *arg ATTRIBUTE_UNUSED)
1139 {
1140 debug ("In md_parse_option()\n");
1141 return 0;
1142 }
1143
1144 void
1145 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1146 {
1147 debug ("In md_show_usage()\n");
1148 }
1149
1150 symbolS *
1151 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1152 {
1153 debug ("In md_undefined_symbol()\n");
1154 return (symbolS *) 0;
1155 }
1156
1157 valueT
1158 md_section_align (segT segment, valueT size)
1159 {
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;
1166 }
1167
1168 long
1169 md_pcrel_from (fixS *fixP)
1170 {
1171 int offset;
1172
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);
1191 }
1192
1193 const char *
1194 md_atof (int what_statement_type,
1195 char *literalP,
1196 int *sizeP)
1197 {
1198 int prec;
1199 char *token;
1200 char keepval;
1201 unsigned long value;
1202 float float_value;
1203
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 != ','))
1211 {
1212 debug ("%c", *input_line_pointer);
1213 input_line_pointer++;
1214 }
1215
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);
1222
1223 switch (what_statement_type)
1224 {
1225 case 'f':
1226 case 'F':
1227 case 's':
1228 case 'S':
1229 prec = 2;
1230 break;
1231
1232 case 'd':
1233 case 'D':
1234 case 'r':
1235 case 'R':
1236 prec = 4;
1237 break;
1238
1239 default:
1240 *sizeP = 0;
1241 return _("Unrecognized or unsupported floating point constant");
1242 }
1243
1244 if (float_value == 0.0)
1245 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1246 else
1247 {
1248 unsigned long exp, sign, mant, tmsfloat;
1249 union
1250 {
1251 float f;
1252 long l;
1253 }
1254 converter;
1255
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)
1263 {
1264 if (mant == 0)
1265 value = 0x7F7FFFFF;
1266 else if (sign == 0)
1267 value = 0x7F7FFFFF;
1268 else
1269 value = 0x7F800000;
1270 }
1271 else
1272 {
1273 exp -= 0x7F000000;
1274 if (sign)
1275 {
1276 mant = mant & 0x007FFFFF;
1277 mant = -mant;
1278 mant = mant & 0x00FFFFFF;
1279 if (mant == 0)
1280 {
1281 mant |= 0x00800000;
1282 exp = (long) exp - 0x01000000;
1283 }
1284 }
1285 tmsfloat = exp | mant;
1286 value = tmsfloat;
1287 }
1288 if (prec == 2)
1289 {
1290 long expon, mantis;
1291
1292 if (tmsfloat == 0x80000000)
1293 value = 0x8000;
1294 else
1295 {
1296 value = 0;
1297 expon = (tmsfloat & 0xFF000000);
1298 expon >>= 24;
1299 mantis = tmsfloat & 0x007FFFFF;
1300 if (tmsfloat & 0x00800000)
1301 {
1302 mantis |= 0xFF000000;
1303 mantis += 0x00000800;
1304 mantis >>= 12;
1305 mantis |= 0x00000800;
1306 mantis &= 0x0FFF;
1307 if (expon > 7)
1308 value = 0x7800;
1309 }
1310 else
1311 {
1312 mantis |= 0x00800000;
1313 mantis += 0x00000800;
1314 expon += (mantis >> 24);
1315 mantis >>= 12;
1316 mantis &= 0x07FF;
1317 if (expon > 7)
1318 value = 0x77FF;
1319 }
1320 if (expon < -8)
1321 value = 0x8000;
1322 if (value == 0)
1323 {
1324 mantis = (expon << 12) | mantis;
1325 value = mantis & 0xFFFF;
1326 }
1327 }
1328 }
1329 }
1330 md_number_to_chars (literalP, value, prec);
1331 *sizeP = prec;
1332 return NULL;
1333 }
1334
1335 void
1336 md_number_to_chars (char *buf, valueT val, int n)
1337 {
1338 debug ("In md_number_to_chars()\n");
1339 number_to_chars_bigendian (buf, val, n);
1340 }
1341
1342 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1343 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1344
1345 arelent *
1346 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1347 {
1348 arelent *rel;
1349 bfd_reloc_code_real_type code = 0;
1350
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));
1355
1356 switch (F (fixP->fx_size, fixP->fx_pcrel))
1357 {
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 ") : "");
1366 }
1367 #undef MAP
1368 #undef F
1369
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)
1378 {
1379 const char *name;
1380
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));
1386 }
1387 return rel;
1388 }
1389
1390 void
1391 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1392 {
1393 debug ("In md_operand()\n");
1394 }
1395
1396 void
1397 md_assemble (char *line)
1398 {
1399 insn_template *op;
1400 char *current_posn;
1401 char *token_start;
1402 char save_char;
1403 unsigned int count;
1404
1405 debug ("In md_assemble() with argument %s\n", line);
1406 memset (&insn, '\0', sizeof (insn));
1407 if (found_parallel_insn)
1408 {
1409 debug ("Line is second part of parallel instruction\n\n");
1410 found_parallel_insn = 0;
1411 return;
1412 }
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;
1418
1419 while (is_space_char (*current_posn))
1420 current_posn++;
1421
1422 token_start = current_posn;
1423
1424 if (!is_opcode_char (*current_posn))
1425 {
1426 as_bad (_("Invalid character %s in opcode"),
1427 output_invalid (*current_posn));
1428 return;
1429 }
1430 /* Check if instruction is a parallel instruction
1431 by seeing if the first character is a q. */
1432 if (*token_start == 'q')
1433 {
1434 if (tic30_parallel_insn (token_start))
1435 {
1436 if (found_parallel_insn)
1437 free (token_start);
1438 return;
1439 }
1440 }
1441 while (is_opcode_char (*current_posn))
1442 current_posn++;
1443 {
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)
1449 {
1450 debug ("Found instruction %s\n", op->name);
1451 insn.tm = op;
1452 }
1453 else
1454 {
1455 debug ("Didn't find insn\n");
1456 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1457 return;
1458 }
1459 *current_posn = save_char;
1460 }
1461
1462 if (*current_posn != END_OF_INSN)
1463 {
1464 /* Find operands. */
1465 int paren_not_balanced;
1466 int expecting_operand = 0;
1467 int this_operand;
1468 do
1469 {
1470 /* Skip optional white space before operand. */
1471 while (!is_operand_char (*current_posn)
1472 && *current_posn != END_OF_INSN)
1473 {
1474 if (!is_space_char (*current_posn))
1475 {
1476 as_bad (_("Invalid character %s before %s operand"),
1477 output_invalid (*current_posn),
1478 ordinal_names[insn.operands]);
1479 return;
1480 }
1481 current_posn++;
1482 }
1483 token_start = current_posn;
1484 paren_not_balanced = 0;
1485 while (paren_not_balanced || *current_posn != ',')
1486 {
1487 if (*current_posn == END_OF_INSN)
1488 {
1489 if (paren_not_balanced)
1490 {
1491 as_bad (_("Unbalanced parenthesis in %s operand."),
1492 ordinal_names[insn.operands]);
1493 return;
1494 }
1495 else
1496 break;
1497 }
1498 else if (!is_operand_char (*current_posn)
1499 && !is_space_char (*current_posn))
1500 {
1501 as_bad (_("Invalid character %s in %s operand"),
1502 output_invalid (*current_posn),
1503 ordinal_names[insn.operands]);
1504 return;
1505 }
1506 if (*current_posn == '(')
1507 ++paren_not_balanced;
1508 if (*current_posn == ')')
1509 --paren_not_balanced;
1510 current_posn++;
1511 }
1512 if (current_posn != token_start)
1513 {
1514 /* Yes, we've read in another operand. */
1515 this_operand = insn.operands++;
1516 if (insn.operands > MAX_OPERANDS)
1517 {
1518 as_bad (_("Spurious operands; (%d operands/instruction max)"),
1519 MAX_OPERANDS);
1520 return;
1521 }
1522
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;
1530 }
1531 else
1532 {
1533 if (expecting_operand)
1534 {
1535 as_bad (_("Expecting operand after ','; got nothing"));
1536 return;
1537 }
1538 if (*current_posn == ',')
1539 {
1540 as_bad (_("Expecting operand before ','; got nothing"));
1541 return;
1542 }
1543 }
1544
1545 /* Now *current_posn must be either ',' or END_OF_INSN. */
1546 if (*current_posn == ',')
1547 {
1548 if (*++current_posn == END_OF_INSN)
1549 {
1550 /* Just skip it, if it's \n complain. */
1551 as_bad (_("Expecting operand after ','; got nothing"));
1552 return;
1553 }
1554 expecting_operand = 1;
1555 }
1556 }
1557 while (*current_posn != END_OF_INSN);
1558 }
1559
1560 debug ("Number of operands found: %d\n", insn.operands);
1561
1562 /* Check that number of operands is correct. */
1563 if (insn.operands != insn.tm->operands)
1564 {
1565 unsigned int i;
1566 unsigned int numops = insn.tm->operands;
1567
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)
1575 {
1576 as_bad (_("Incorrect number of operands given"));
1577 return;
1578 }
1579 }
1580 insn.addressing_mode = AM_NotReq;
1581 for (count = 0; count < insn.operands; count++)
1582 {
1583 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1584 {
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)
1589 {
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;
1596
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;
1605 }
1606 }
1607 else
1608 {
1609 as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1610 return;
1611 }
1612 }
1613
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))
1617 {
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)
1622 {
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
1632 {
1633 /* Shouldn't make it to this stage. */
1634 as_bad (_("Incompatible first and second operands in instruction"));
1635 return;
1636 }
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
1644 {
1645 /* Shouldn't make it to this stage. */
1646 as_bad (_("Incompatible first and second operands in instruction"));
1647 return;
1648 }
1649 break;
1650 }
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)
1656 {
1657 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1658 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1659 }
1660 else
1661 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1662
1663 if (insn.operand_type[1]->op_type & Indirect)
1664 {
1665 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1666 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1667 }
1668 else
1669 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1670
1671 if (insn.operands == 3)
1672 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1673
1674 insn.opcode |= insn.addressing_mode;
1675 p = frag_more (INSN_SIZE);
1676 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1677 }
1678 else
1679 {
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))
1687 {
1688 insn.opcode |= insn.addressing_mode;
1689 if (insn.addressing_mode == AM_Indirect)
1690 {
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);
1703 }
1704 else if (insn.addressing_mode == AM_Register)
1705 {
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);
1710 }
1711 else if (insn.addressing_mode == AM_Direct)
1712 {
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)
1722 {
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);
1728 }
1729 else
1730 {
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);
1736 }
1737 }
1738 else if (insn.addressing_mode == AM_Immediate)
1739 {
1740 if (insn.operand_type[0]->immediate.resolved == 1)
1741 {
1742 char *keeploc;
1743 int size;
1744
1745 if (insn.operands > 1)
1746 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1747
1748 switch (insn.tm->imm_arg_type)
1749 {
1750 case Imm_Float:
1751 debug ("Floating point first operand\n");
1752 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1753
1754 keeploc = input_line_pointer;
1755 input_line_pointer =
1756 insn.operand_type[0]->immediate.label;
1757
1758 if (md_atof ('f', p + 2, & size) != 0)
1759 {
1760 as_bad (_("invalid short form floating point immediate operand"));
1761 return;
1762 }
1763
1764 input_line_pointer = keeploc;
1765 break;
1766
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;
1777
1778 case Imm_SInt:
1779 debug ("Int first operand\n");
1780
1781 if (insn.operand_type[0]->immediate.decimal_found)
1782 as_warn (_("rounding down first operand float to signed int"));
1783
1784 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1785 insn.operand_type[0]->immediate.s_number > 32767)
1786 {
1787 as_bad (_("first operand is too large for 16-bit signed int"));
1788 return;
1789 }
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;
1794 }
1795 }
1796 else
1797 {
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);
1805 }
1806 }
1807 }
1808 else if (insn.tm->opcode_modifier == PCRel)
1809 {
1810 /* Conditional Branch and Call instructions. */
1811 if ((insn.tm->operand_types[0] & (AllReg | Disp))
1812 == (AllReg | Disp))
1813 {
1814 if (insn.operand_type[0]->op_type & (AllReg))
1815 {
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);
1819 }
1820 else
1821 {
1822 insn.opcode |= PC_Relative;
1823 if (insn.operand_type[0]->immediate.resolved == 1)
1824 {
1825 insn.opcode |=
1826 (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1827 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1828 }
1829 else
1830 {
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);
1835 }
1836 }
1837 }
1838 else if ((insn.tm->operand_types[0] & ARn) == ARn)
1839 {
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))
1843 {
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);
1847 }
1848 else if (insn.operand_type[1]->immediate.resolved == 1)
1849 {
1850 if (insn.operand_type[0]->immediate.decimal_found)
1851 {
1852 as_bad (_("first operand is floating point"));
1853 return;
1854 }
1855 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1856 insn.operand_type[0]->immediate.s_number > 32767)
1857 {
1858 as_bad (_("first operand is too large for 16-bit signed int"));
1859 return;
1860 }
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);
1864 }
1865 else
1866 {
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);
1872 }
1873 }
1874 }
1875 else if (insn.tm->operand_types[0] == IVector)
1876 {
1877 /* Trap instructions. */
1878 if (insn.operand_type[0]->op_type & IVector)
1879 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1880 else
1881 {
1882 /* Shouldn't get here. */
1883 as_bad (_("interrupt vector for trap instruction out of range"));
1884 return;
1885 }
1886 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1887 }
1888 else if (insn.tm->opcode_modifier == StackOp
1889 || insn.tm->opcode_modifier == Rotate)
1890 {
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);
1894 }
1895 else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1896 == (Abs24 | Direct))
1897 {
1898 /* LDP Instruction needs to be tested
1899 for before the next section. */
1900 if (insn.operand_type[0]->op_type & Direct)
1901 {
1902 if (insn.operand_type[0]->direct.resolved == 1)
1903 {
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);
1908 }
1909 else
1910 {
1911 fixS *fix;
1912
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;
1919 }
1920 }
1921 else
1922 {
1923 if (insn.operand_type[0]->immediate.resolved == 1)
1924 {
1925 /* Immediate addressing uses upper 8 bits of address. */
1926 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1927 {
1928 as_bad (_("LDP instruction needs a 24-bit operand"));
1929 return;
1930 }
1931 insn.opcode |=
1932 ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1933 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1934 }
1935 else
1936 {
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;
1943 }
1944 }
1945 }
1946 else if (insn.tm->operand_types[0] & (Imm24))
1947 {
1948 /* Unconditional Branch and Call instructions. */
1949 if (insn.operand_type[0]->immediate.resolved == 1)
1950 {
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);
1956 }
1957 else
1958 {
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);
1962 }
1963 }
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);
1967
1968 else if (insn.tm->operands == 0)
1969 /* Check for instructions without operands. */
1970 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1971 }
1972 debug ("Addressing mode: %08X\n", insn.addressing_mode);
1973 {
1974 unsigned int i;
1975
1976 for (i = 0; i < insn.operands; i++)
1977 {
1978 free (insn.operand_type[i]->immediate.label);
1979 free (insn.operand_type[i]);
1980 }
1981 }
1982 debug ("Final opcode: %08X\n", insn.opcode);
1983 debug ("\n");
1984 }