]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-tic30.c
Update the address and phone number of the FSF
[thirdparty/binutils-gdb.git] / gas / config / tc-tic30.c
1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23 /* Texas Instruments TMS320C30 machine specific gas.
24 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25 Bugs & suggestions are completely welcome. This is free software.
26 Please help us make it better. */
27
28 #include "as.h"
29 #include "safe-ctype.h"
30 #include "opcode/tic30.h"
31 #ifdef ANSI_PROTOTYPES
32 #include <stdarg.h>
33 #else
34 #include <varargs.h>
35 #endif
36
37 /* Put here all non-digit non-letter characters that may occur in an
38 operand. */
39 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
40 static char *ordinal_names[] =
41 {
42 "first", "second", "third", "fourth", "fifth"
43 };
44
45 const int md_reloc_size = 0;
46
47 const char comment_chars[] = ";";
48 const char line_comment_chars[] = "*";
49 const char line_separator_chars[] = "";
50
51 const char *md_shortopts = "";
52 struct option md_longopts[] =
53 {
54 {NULL, no_argument, NULL, 0}
55 };
56
57 size_t md_longopts_size = sizeof (md_longopts);
58
59 /* Chars that mean this number is a floating point constant.
60 As in 0f12.456
61 or 0d1.2345e12. */
62 const char FLT_CHARS[] = "fFdDxX";
63
64 /* Chars that can be used to separate mant from exp in floating point
65 nums. */
66 const char EXP_CHARS[] = "eE";
67
68 /* Tables for lexical analysis. */
69 static char opcode_chars[256];
70 static char register_chars[256];
71 static char operand_chars[256];
72 static char space_chars[256];
73 static char identifier_chars[256];
74 static char digit_chars[256];
75
76 /* Lexical macros. */
77 #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
78 #define is_operand_char(x) (operand_chars [(unsigned char) x])
79 #define is_register_char(x) (register_chars [(unsigned char) x])
80 #define is_space_char(x) (space_chars [(unsigned char) x])
81 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
82 #define is_digit_char(x) (digit_chars [(unsigned char) x])
83
84 const pseudo_typeS md_pseudo_table[] =
85 {
86 {0, 0, 0}
87 };
88
89 static int
90 debug (const char *string, ...)
91 {
92 if (flag_debug)
93 {
94 char str[100];
95
96 VA_OPEN (argptr, string);
97 VA_FIXEDARG (argptr, const char *, string);
98 vsprintf (str, string, argptr);
99 VA_CLOSE (argptr);
100 if (str[0] == '\0')
101 return (0);
102 fputs (str, USE_STDOUT ? stdout : stderr);
103 return strlen (str);
104 }
105 else
106 return 0;
107 }
108
109 /* Hash table for opcode lookup. */
110 static struct hash_control *op_hash;
111 /* Hash table for parallel opcode lookup. */
112 static struct hash_control *parop_hash;
113 /* Hash table for register lookup. */
114 static struct hash_control *reg_hash;
115 /* Hash table for indirect addressing lookup. */
116 static struct hash_control *ind_hash;
117
118 void
119 md_begin (void)
120 {
121 const char *hash_err;
122
123 debug ("In md_begin()\n");
124 op_hash = hash_new ();
125
126 {
127 const template *current_optab = tic30_optab;
128
129 for (; current_optab < tic30_optab_end; current_optab++)
130 {
131 hash_err = hash_insert (op_hash, current_optab->name,
132 (char *) current_optab);
133 if (hash_err)
134 as_fatal ("Internal Error: Can't Hash %s: %s",
135 current_optab->name, hash_err);
136 }
137 }
138
139 parop_hash = hash_new ();
140
141 {
142 const partemplate *current_parop = tic30_paroptab;
143
144 for (; current_parop < tic30_paroptab_end; current_parop++)
145 {
146 hash_err = hash_insert (parop_hash, current_parop->name,
147 (char *) current_parop);
148 if (hash_err)
149 as_fatal ("Internal Error: Can't Hash %s: %s",
150 current_parop->name, hash_err);
151 }
152 }
153
154 reg_hash = hash_new ();
155
156 {
157 const reg *current_reg = tic30_regtab;
158
159 for (; current_reg < tic30_regtab_end; current_reg++)
160 {
161 hash_err = hash_insert (reg_hash, current_reg->name,
162 (char *) current_reg);
163 if (hash_err)
164 as_fatal ("Internal Error: Can't Hash %s: %s",
165 current_reg->name, hash_err);
166 }
167 }
168
169 ind_hash = hash_new ();
170
171 {
172 const ind_addr_type *current_ind = tic30_indaddr_tab;
173
174 for (; current_ind < tic30_indaddrtab_end; current_ind++)
175 {
176 hash_err = hash_insert (ind_hash, current_ind->syntax,
177 (char *) current_ind);
178 if (hash_err)
179 as_fatal ("Internal Error: Can't Hash %s: %s",
180 current_ind->syntax, hash_err);
181 }
182 }
183
184 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
185 {
186 int c;
187 char *p;
188
189 for (c = 0; c < 256; c++)
190 {
191 if (ISLOWER (c) || ISDIGIT (c))
192 {
193 opcode_chars[c] = c;
194 register_chars[c] = c;
195 }
196 else if (ISUPPER (c))
197 {
198 opcode_chars[c] = TOLOWER (c);
199 register_chars[c] = opcode_chars[c];
200 }
201 else if (c == ')' || c == '(')
202 register_chars[c] = c;
203
204 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
205 operand_chars[c] = c;
206
207 if (ISDIGIT (c) || c == '-')
208 digit_chars[c] = c;
209
210 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
211 identifier_chars[c] = c;
212
213 if (c == ' ' || c == '\t')
214 space_chars[c] = c;
215
216 if (c == '_')
217 opcode_chars[c] = c;
218 }
219 for (p = operand_special_chars; *p != '\0'; p++)
220 operand_chars[(unsigned char) *p] = *p;
221 }
222 }
223
224 /* Address Mode OR values. */
225 #define AM_Register 0x00000000
226 #define AM_Direct 0x00200000
227 #define AM_Indirect 0x00400000
228 #define AM_Immediate 0x00600000
229 #define AM_NotReq 0xFFFFFFFF
230
231 /* PC Relative OR values. */
232 #define PC_Register 0x00000000
233 #define PC_Relative 0x02000000
234
235 typedef struct
236 {
237 unsigned op_type;
238 struct
239 {
240 int resolved;
241 unsigned address;
242 char *label;
243 expressionS direct_expr;
244 } direct;
245 struct
246 {
247 unsigned mod;
248 int ARnum;
249 unsigned char disp;
250 } indirect;
251 struct
252 {
253 unsigned opcode;
254 } reg;
255 struct
256 {
257 int resolved;
258 int decimal_found;
259 float f_number;
260 int s_number;
261 unsigned int u_number;
262 char *label;
263 expressionS imm_expr;
264 } immediate;
265 } operand;
266
267 template *opcode;
268
269 struct tic30_insn
270 {
271 template *tm; /* Template of current instruction. */
272 unsigned opcode; /* Final opcode. */
273 unsigned int operands; /* Number of given operands. */
274 /* Type of operand given in instruction. */
275 operand *operand_type[MAX_OPERANDS];
276 unsigned addressing_mode; /* Final addressing mode of instruction. */
277 };
278
279 struct tic30_insn insn;
280 static int found_parallel_insn;
281
282 static char output_invalid_buf[8];
283
284 static char *
285 output_invalid (char c)
286 {
287 if (ISPRINT (c))
288 sprintf (output_invalid_buf, "'%c'", c);
289 else
290 sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
291 return output_invalid_buf;
292 }
293
294 /* next_line points to the next line after the current instruction
295 (current_line). Search for the parallel bars, and if found, merge two
296 lines into internal syntax for a parallel instruction:
297 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
298 By this stage, all comments are scrubbed, and only the bare lines are
299 given. */
300
301 #define NONE 0
302 #define START_OPCODE 1
303 #define END_OPCODE 2
304 #define START_OPERANDS 3
305 #define END_OPERANDS 4
306
307 static char *
308 tic30_find_parallel_insn (char *current_line, char *next_line)
309 {
310 int found_parallel = 0;
311 char first_opcode[256];
312 char second_opcode[256];
313 char first_operands[256];
314 char second_operands[256];
315 char *parallel_insn;
316
317 debug ("In tic30_find_parallel_insn()\n");
318 while (!is_end_of_line[(unsigned char) *next_line])
319 {
320 if (*next_line == PARALLEL_SEPARATOR
321 && *(next_line + 1) == PARALLEL_SEPARATOR)
322 {
323 found_parallel = 1;
324 next_line++;
325 break;
326 }
327 next_line++;
328 }
329 if (!found_parallel)
330 return NULL;
331 debug ("Found a parallel instruction\n");
332
333 {
334 int i;
335 char *opcode, *operands, *line;
336
337 for (i = 0; i < 2; i++)
338 {
339 if (i == 0)
340 {
341 opcode = &first_opcode[0];
342 operands = &first_operands[0];
343 line = current_line;
344 }
345 else
346 {
347 opcode = &second_opcode[0];
348 operands = &second_operands[0];
349 line = next_line;
350 }
351
352 {
353 int search_status = NONE;
354 int char_ptr = 0;
355 char c;
356
357 while (!is_end_of_line[(unsigned char) (c = *line)])
358 {
359 if (is_opcode_char (c) && search_status == NONE)
360 {
361 opcode[char_ptr++] = TOLOWER (c);
362 search_status = START_OPCODE;
363 }
364 else if (is_opcode_char (c) && search_status == START_OPCODE)
365 opcode[char_ptr++] = TOLOWER (c);
366 else if (!is_opcode_char (c) && search_status == START_OPCODE)
367 {
368 opcode[char_ptr] = '\0';
369 char_ptr = 0;
370 search_status = END_OPCODE;
371 }
372 else if (is_operand_char (c) && search_status == START_OPERANDS)
373 operands[char_ptr++] = c;
374
375 if (is_operand_char (c) && search_status == END_OPCODE)
376 {
377 operands[char_ptr++] = c;
378 search_status = START_OPERANDS;
379 }
380
381 line++;
382 }
383 if (search_status != START_OPERANDS)
384 return NULL;
385 operands[char_ptr] = '\0';
386 }
387 }
388 }
389 parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
390 + strlen (second_opcode) + strlen (second_operands) + 8);
391 sprintf (parallel_insn, "q_%s_%s %s | %s",
392 first_opcode, second_opcode,
393 first_operands, second_operands);
394 debug ("parallel insn = %s\n", parallel_insn);
395 return parallel_insn;
396 }
397
398 #undef NONE
399 #undef START_OPCODE
400 #undef END_OPCODE
401 #undef START_OPERANDS
402 #undef END_OPERANDS
403
404 static operand *
405 tic30_operand (char *token)
406 {
407 unsigned int count;
408 char ind_buffer[strlen (token)];
409 operand *current_op;
410
411 debug ("In tic30_operand with %s\n", token);
412 current_op = malloc (sizeof (* current_op));
413 memset (current_op, '\0', sizeof (operand));
414
415 if (*token == DIRECT_REFERENCE)
416 {
417 char *token_posn = token + 1;
418 int direct_label = 0;
419
420 debug ("Found direct reference\n");
421 while (*token_posn)
422 {
423 if (!is_digit_char (*token_posn))
424 direct_label = 1;
425 token_posn++;
426 }
427
428 if (direct_label)
429 {
430 char *save_input_line_pointer;
431 segT retval;
432
433 debug ("Direct reference is a label\n");
434 current_op->direct.label = token + 1;
435 save_input_line_pointer = input_line_pointer;
436 input_line_pointer = token + 1;
437 debug ("Current input_line_pointer: %s\n", input_line_pointer);
438 retval = expression (&current_op->direct.direct_expr);
439
440 debug ("Expression type: %d\n",
441 current_op->direct.direct_expr.X_op);
442 debug ("Expression addnum: %d\n",
443 current_op->direct.direct_expr.X_add_number);
444 debug ("Segment: %d\n", retval);
445
446 input_line_pointer = save_input_line_pointer;
447
448 if (current_op->direct.direct_expr.X_op == O_constant)
449 {
450 current_op->direct.address =
451 current_op->direct.direct_expr.X_add_number;
452 current_op->direct.resolved = 1;
453 }
454 }
455 else
456 {
457 debug ("Direct reference is a number\n");
458 current_op->direct.address = atoi (token + 1);
459 current_op->direct.resolved = 1;
460 }
461 current_op->op_type = Direct;
462 }
463 else if (*token == INDIRECT_REFERENCE)
464 {
465 /* Indirect reference operand. */
466 int found_ar = 0;
467 int found_disp = 0;
468 int ar_number = -1;
469 int disp_number = 0;
470 int buffer_posn = 1;
471 ind_addr_type *ind_addr_op;
472
473 debug ("Found indirect reference\n");
474 ind_buffer[0] = *token;
475
476 for (count = 1; count < strlen (token); count++)
477 {
478 /* Strip operand. */
479 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
480
481 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
482 && (*(token + count) == 'r' || *(token + count) == 'R'))
483 {
484 /* AR reference is found, so get its number and remove
485 it from the buffer so it can pass through hash_find(). */
486 if (found_ar)
487 {
488 as_bad ("More than one AR register found in indirect reference");
489 return NULL;
490 }
491 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
492 {
493 as_bad ("Illegal AR register in indirect reference");
494 return NULL;
495 }
496 ar_number = *(token + count + 1) - '0';
497 found_ar = 1;
498 count++;
499 }
500
501 if (*(token + count) == '(')
502 {
503 /* Parenthesis found, so check if a displacement value is
504 inside. If so, get the value and remove it from the
505 buffer. */
506 if (is_digit_char (*(token + count + 1)))
507 {
508 char disp[10];
509 int disp_posn = 0;
510
511 if (found_disp)
512 {
513 as_bad ("More than one displacement found in indirect reference");
514 return NULL;
515 }
516 count++;
517 while (*(token + count) != ')')
518 {
519 if (!is_digit_char (*(token + count)))
520 {
521 as_bad ("Invalid displacement in indirect reference");
522 return NULL;
523 }
524 disp[disp_posn++] = *(token + (count++));
525 }
526 disp[disp_posn] = '\0';
527 disp_number = atoi (disp);
528 count--;
529 found_disp = 1;
530 }
531 }
532 buffer_posn++;
533 }
534
535 ind_buffer[buffer_posn] = '\0';
536 if (!found_ar)
537 {
538 as_bad ("AR register not found in indirect reference");
539 return NULL;
540 }
541
542 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
543 if (ind_addr_op)
544 {
545 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
546 if (ind_addr_op->displacement == IMPLIED_DISP)
547 {
548 found_disp = 1;
549 disp_number = 1;
550 }
551 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
552 {
553 /* Maybe an implied displacement of 1 again. */
554 as_bad ("required displacement wasn't given in indirect reference");
555 return 0;
556 }
557 }
558 else
559 {
560 as_bad ("illegal indirect reference");
561 return NULL;
562 }
563
564 if (found_disp && (disp_number < 0 || disp_number > 255))
565 {
566 as_bad ("displacement must be an unsigned 8-bit number");
567 return NULL;
568 }
569
570 current_op->indirect.mod = ind_addr_op->modfield;
571 current_op->indirect.disp = disp_number;
572 current_op->indirect.ARnum = ar_number;
573 current_op->op_type = Indirect;
574 }
575 else
576 {
577 reg *regop = (reg *) hash_find (reg_hash, token);
578
579 if (regop)
580 {
581 debug ("Found register operand: %s\n", regop->name);
582 if (regop->regtype == REG_ARn)
583 current_op->op_type = ARn;
584 else if (regop->regtype == REG_Rn)
585 current_op->op_type = Rn;
586 else if (regop->regtype == REG_DP)
587 current_op->op_type = DPReg;
588 else
589 current_op->op_type = OtherReg;
590 current_op->reg.opcode = regop->opcode;
591 }
592 else
593 {
594 if (!is_digit_char (*token)
595 || *(token + 1) == 'x'
596 || strchr (token, 'h'))
597 {
598 char *save_input_line_pointer;
599 segT retval;
600
601 debug ("Probably a label: %s\n", token);
602 current_op->immediate.label = malloc (strlen (token) + 1);
603 strcpy (current_op->immediate.label, token);
604 current_op->immediate.label[strlen (token)] = '\0';
605 save_input_line_pointer = input_line_pointer;
606 input_line_pointer = token;
607
608 debug ("Current input_line_pointer: %s\n", input_line_pointer);
609 retval = expression (&current_op->immediate.imm_expr);
610 debug ("Expression type: %d\n",
611 current_op->immediate.imm_expr.X_op);
612 debug ("Expression addnum: %d\n",
613 current_op->immediate.imm_expr.X_add_number);
614 debug ("Segment: %d\n", retval);
615 input_line_pointer = save_input_line_pointer;
616
617 if (current_op->immediate.imm_expr.X_op == O_constant)
618 {
619 current_op->immediate.s_number
620 = current_op->immediate.imm_expr.X_add_number;
621 current_op->immediate.u_number
622 = (unsigned int) current_op->immediate.imm_expr.X_add_number;
623 current_op->immediate.resolved = 1;
624 }
625 }
626 else
627 {
628 unsigned count;
629
630 debug ("Found a number or displacement\n");
631 for (count = 0; count < strlen (token); count++)
632 if (*(token + count) == '.')
633 current_op->immediate.decimal_found = 1;
634 current_op->immediate.label = malloc (strlen (token) + 1);
635 strcpy (current_op->immediate.label, token);
636 current_op->immediate.label[strlen (token)] = '\0';
637 current_op->immediate.f_number = (float) atof (token);
638 current_op->immediate.s_number = (int) atoi (token);
639 current_op->immediate.u_number = (unsigned int) atoi (token);
640 current_op->immediate.resolved = 1;
641 }
642 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
643 if (current_op->immediate.u_number <= 31)
644 current_op->op_type |= IVector;
645 }
646 }
647 return current_op;
648 }
649
650 struct tic30_par_insn
651 {
652 partemplate *tm; /* Template of current parallel instruction. */
653 unsigned operands[2]; /* Number of given operands for each insn. */
654 /* Type of operand given in instruction. */
655 operand *operand_type[2][MAX_OPERANDS];
656 int swap_operands; /* Whether to swap operands around. */
657 unsigned p_field; /* Value of p field in multiply add/sub instructions. */
658 unsigned opcode; /* Final opcode. */
659 };
660
661 struct tic30_par_insn p_insn;
662
663 static int
664 tic30_parallel_insn (char *token)
665 {
666 static partemplate *p_opcode;
667 char *current_posn = token;
668 char *token_start;
669 char save_char;
670
671 debug ("In tic30_parallel_insn with %s\n", token);
672 memset (&p_insn, '\0', sizeof (p_insn));
673
674 while (is_opcode_char (*current_posn))
675 current_posn++;
676 {
677 /* Find instruction. */
678 save_char = *current_posn;
679 *current_posn = '\0';
680 p_opcode = (partemplate *) hash_find (parop_hash, token);
681 if (p_opcode)
682 {
683 debug ("Found instruction %s\n", p_opcode->name);
684 p_insn.tm = p_opcode;
685 }
686 else
687 {
688 char first_opcode[6] = {0};
689 char second_opcode[6] = {0};
690 unsigned int i;
691 int current_opcode = -1;
692 int char_ptr = 0;
693
694 for (i = 0; i < strlen (token); i++)
695 {
696 char ch = *(token + i);
697
698 if (ch == '_' && current_opcode == -1)
699 {
700 current_opcode = 0;
701 continue;
702 }
703
704 if (ch == '_' && current_opcode == 0)
705 {
706 current_opcode = 1;
707 char_ptr = 0;
708 continue;
709 }
710
711 switch (current_opcode)
712 {
713 case 0:
714 first_opcode[char_ptr++] = ch;
715 break;
716 case 1:
717 second_opcode[char_ptr++] = ch;
718 break;
719 }
720 }
721
722 debug ("first_opcode = %s\n", first_opcode);
723 debug ("second_opcode = %s\n", second_opcode);
724 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
725 p_opcode = (partemplate *) hash_find (parop_hash, token);
726
727 if (p_opcode)
728 {
729 debug ("Found instruction %s\n", p_opcode->name);
730 p_insn.tm = p_opcode;
731 p_insn.swap_operands = 1;
732 }
733 else
734 return 0;
735 }
736 *current_posn = save_char;
737 }
738
739 {
740 /* Find operands. */
741 int paren_not_balanced;
742 int expecting_operand = 0;
743 int found_separator = 0;
744
745 do
746 {
747 /* Skip optional white space before operand. */
748 while (!is_operand_char (*current_posn)
749 && *current_posn != END_OF_INSN)
750 {
751 if (!is_space_char (*current_posn)
752 && *current_posn != PARALLEL_SEPARATOR)
753 {
754 as_bad ("Invalid character %s before %s operand",
755 output_invalid (*current_posn),
756 ordinal_names[insn.operands]);
757 return 1;
758 }
759 if (*current_posn == PARALLEL_SEPARATOR)
760 found_separator = 1;
761 current_posn++;
762 }
763
764 token_start = current_posn;
765 paren_not_balanced = 0;
766
767 while (paren_not_balanced || *current_posn != ',')
768 {
769 if (*current_posn == END_OF_INSN)
770 {
771 if (paren_not_balanced)
772 {
773 as_bad ("Unbalanced parenthesis in %s operand.",
774 ordinal_names[insn.operands]);
775 return 1;
776 }
777 else
778 break;
779 }
780 else if (*current_posn == PARALLEL_SEPARATOR)
781 {
782 while (is_space_char (*(current_posn - 1)))
783 current_posn--;
784 break;
785 }
786 else if (!is_operand_char (*current_posn)
787 && !is_space_char (*current_posn))
788 {
789 as_bad ("Invalid character %s in %s operand",
790 output_invalid (*current_posn),
791 ordinal_names[insn.operands]);
792 return 1;
793 }
794
795 if (*current_posn == '(')
796 ++paren_not_balanced;
797 if (*current_posn == ')')
798 --paren_not_balanced;
799 current_posn++;
800 }
801
802 if (current_posn != token_start)
803 {
804 /* Yes, we've read in another operand. */
805 p_insn.operands[found_separator]++;
806 if (p_insn.operands[found_separator] > MAX_OPERANDS)
807 {
808 as_bad ("Spurious operands; (%d operands/instruction max)",
809 MAX_OPERANDS);
810 return 1;
811 }
812
813 /* Now parse operand adding info to 'insn' as we go along. */
814 save_char = *current_posn;
815 *current_posn = '\0';
816 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
817 tic30_operand (token_start);
818 *current_posn = save_char;
819 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
820 return 1;
821 }
822 else
823 {
824 if (expecting_operand)
825 {
826 as_bad ("Expecting operand after ','; got nothing");
827 return 1;
828 }
829 if (*current_posn == ',')
830 {
831 as_bad ("Expecting operand before ','; got nothing");
832 return 1;
833 }
834 }
835
836 /* Now *current_posn must be either ',' or END_OF_INSN. */
837 if (*current_posn == ',')
838 {
839 if (*++current_posn == END_OF_INSN)
840 {
841 /* Just skip it, if it's \n complain. */
842 as_bad ("Expecting operand after ','; got nothing");
843 return 1;
844 }
845 expecting_operand = 1;
846 }
847 }
848 while (*current_posn != END_OF_INSN);
849 }
850
851 if (p_insn.swap_operands)
852 {
853 int temp_num, i;
854 operand *temp_op;
855
856 temp_num = p_insn.operands[0];
857 p_insn.operands[0] = p_insn.operands[1];
858 p_insn.operands[1] = temp_num;
859 for (i = 0; i < MAX_OPERANDS; i++)
860 {
861 temp_op = p_insn.operand_type[0][i];
862 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
863 p_insn.operand_type[1][i] = temp_op;
864 }
865 }
866
867 if (p_insn.operands[0] != p_insn.tm->operands_1)
868 {
869 as_bad ("incorrect number of operands given in the first instruction");
870 return 1;
871 }
872
873 if (p_insn.operands[1] != p_insn.tm->operands_2)
874 {
875 as_bad ("incorrect number of operands given in the second instruction");
876 return 1;
877 }
878
879 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
880 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
881
882 {
883 /* Now check if operands are correct. */
884 int count;
885 int num_rn = 0;
886 int num_ind = 0;
887
888 for (count = 0; count < 2; count++)
889 {
890 unsigned int i;
891 for (i = 0; i < p_insn.operands[count]; i++)
892 {
893 if ((p_insn.operand_type[count][i]->op_type &
894 p_insn.tm->operand_types[count][i]) == 0)
895 {
896 as_bad ("%s instruction, operand %d doesn't match",
897 ordinal_names[count], i + 1);
898 return 1;
899 }
900
901 /* Get number of R register and indirect reference contained
902 within the first two operands of each instruction. This is
903 required for the multiply parallel instructions which require
904 two R registers and two indirect references, but not in any
905 particular place. */
906 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
907 num_rn++;
908 else if ((p_insn.operand_type[count][i]->op_type & Indirect)
909 && i < 2)
910 num_ind++;
911 }
912 }
913
914 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
915 == (Indirect | Rn))
916 {
917 /* Check for the multiply instructions. */
918 if (num_rn != 2)
919 {
920 as_bad ("incorrect format for multiply parallel instruction");
921 return 1;
922 }
923
924 if (num_ind != 2)
925 {
926 /* Shouldn't get here. */
927 as_bad ("incorrect format for multiply parallel instruction");
928 return 1;
929 }
930
931 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
932 && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
933 {
934 as_bad ("destination for multiply can only be R0 or R1");
935 return 1;
936 }
937
938 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
939 && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
940 {
941 as_bad ("destination for add/subtract can only be R2 or R3");
942 return 1;
943 }
944
945 /* Now determine the P field for the instruction. */
946 if (p_insn.operand_type[0][0]->op_type & Indirect)
947 {
948 if (p_insn.operand_type[0][1]->op_type & Indirect)
949 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
950 else if (p_insn.operand_type[1][0]->op_type & Indirect)
951 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
952 else
953 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
954 }
955 else
956 {
957 if (p_insn.operand_type[0][1]->op_type & Rn)
958 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
959 else if (p_insn.operand_type[1][0]->op_type & Indirect)
960 {
961 operand *temp;
962 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
963 /* Need to swap the two multiply operands around so that
964 everything is in its place for the opcode makeup.
965 ie so Ind * Rn, Ind +/- Rn. */
966 temp = p_insn.operand_type[0][0];
967 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
968 p_insn.operand_type[0][1] = temp;
969 }
970 else
971 {
972 operand *temp;
973 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
974 temp = p_insn.operand_type[0][0];
975 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
976 p_insn.operand_type[0][1] = temp;
977 }
978 }
979 }
980 }
981
982 debug ("P field: %08X\n", p_insn.p_field);
983
984 /* Finalise opcode. This is easier for parallel instructions as they have
985 to be fully resolved, there are no memory addresses allowed, except
986 through indirect addressing, so there are no labels to resolve. */
987 p_insn.opcode = p_insn.tm->base_opcode;
988
989 switch (p_insn.tm->oporder)
990 {
991 case OO_4op1:
992 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
993 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
994 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
995 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
996 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
997 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
998 break;
999
1000 case OO_4op2:
1001 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1002 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1003 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1004 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1005 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1006 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1007 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1008 as_warn ("loading the same register in parallel operation");
1009 break;
1010
1011 case OO_4op3:
1012 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1013 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1014 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1015 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1016 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1017 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1018 break;
1019
1020 case OO_5op1:
1021 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1022 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1023 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1024 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1025 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1026 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1027 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1028 break;
1029
1030 case OO_5op2:
1031 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1032 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1033 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1034 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1035 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1036 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1037 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1038 break;
1039
1040 case OO_PField:
1041 p_insn.opcode |= p_insn.p_field;
1042 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1043 p_insn.opcode |= 0x00800000;
1044 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1045 p_insn.opcode |= 0x00400000;
1046
1047 switch (p_insn.p_field)
1048 {
1049 case 0x00000000:
1050 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1051 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1052 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1053 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1054 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1055 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1056 break;
1057 case 0x01000000:
1058 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1059 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1060 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1061 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1062 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1063 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1064 break;
1065 case 0x02000000:
1066 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1067 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1068 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1069 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1070 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1071 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1072 break;
1073 case 0x03000000:
1074 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1075 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1076 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1077 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1078 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1079 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1080 break;
1081 }
1082 break;
1083 }
1084
1085 {
1086 char *p;
1087
1088 p = frag_more (INSN_SIZE);
1089 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1090 }
1091
1092 {
1093 unsigned int i, j;
1094
1095 for (i = 0; i < 2; i++)
1096 for (j = 0; j < p_insn.operands[i]; j++)
1097 free (p_insn.operand_type[i][j]);
1098 }
1099
1100 debug ("Final opcode: %08X\n", p_insn.opcode);
1101 debug ("\n");
1102
1103 return 1;
1104 }
1105
1106 /* In order to get gas to ignore any | chars at the start of a line,
1107 this function returns true if a | is found in a line. */
1108
1109 int
1110 tic30_unrecognized_line (int c)
1111 {
1112 debug ("In tc_unrecognized_line\n");
1113 return (c == PARALLEL_SEPARATOR);
1114 }
1115
1116 int
1117 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1118 segT segment ATTRIBUTE_UNUSED)
1119 {
1120 debug ("In md_estimate_size_before_relax()\n");
1121 return 0;
1122 }
1123
1124 void
1125 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1126 segT sec ATTRIBUTE_UNUSED,
1127 register fragS *fragP ATTRIBUTE_UNUSED)
1128 {
1129 debug ("In md_convert_frag()\n");
1130 }
1131
1132 void
1133 md_apply_fix3 (fixS *fixP,
1134 valueT *valP,
1135 segT seg ATTRIBUTE_UNUSED)
1136 {
1137 valueT value = *valP;
1138
1139 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1140 debug ("Values in fixP\n");
1141 debug ("fx_size = %d\n", fixP->fx_size);
1142 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1143 debug ("fx_where = %d\n", fixP->fx_where);
1144 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1145 {
1146 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1147
1148 value /= INSN_SIZE;
1149 if (fixP->fx_size == 1)
1150 /* Special fix for LDP instruction. */
1151 value = (value & 0x00FF0000) >> 16;
1152
1153 debug ("new value = %ld\n", (long) value);
1154 md_number_to_chars (buf, value, fixP->fx_size);
1155 }
1156
1157 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1158 fixP->fx_done = 1;
1159 }
1160
1161 int
1162 md_parse_option (int c ATTRIBUTE_UNUSED,
1163 char *arg ATTRIBUTE_UNUSED)
1164 {
1165 debug ("In md_parse_option()\n");
1166 return 0;
1167 }
1168
1169 void
1170 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1171 {
1172 debug ("In md_show_usage()\n");
1173 }
1174
1175 symbolS *
1176 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1177 {
1178 debug ("In md_undefined_symbol()\n");
1179 return (symbolS *) 0;
1180 }
1181
1182 valueT
1183 md_section_align (segT segment, valueT size)
1184 {
1185 debug ("In md_section_align() segment = %d and size = %d\n",
1186 segment, size);
1187 size = (size + 3) / 4;
1188 size *= 4;
1189 debug ("New size value = %d\n", size);
1190 return size;
1191 }
1192
1193 long
1194 md_pcrel_from (fixS *fixP)
1195 {
1196 int offset;
1197
1198 debug ("In md_pcrel_from()\n");
1199 debug ("fx_where = %d\n", fixP->fx_where);
1200 debug ("fx_size = %d\n", fixP->fx_size);
1201 /* Find the opcode that represents the current instruction in the
1202 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1203 current instruction is a delayed one or not, and then set the offset
1204 value appropriately. */
1205 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1206 offset = 3;
1207 else
1208 offset = 1;
1209 debug ("offset = %d\n", offset);
1210 /* PC Relative instructions have a format:
1211 displacement = Label - (PC + offset)
1212 This function returns PC + offset where:
1213 fx_where - fx_size = PC
1214 INSN_SIZE * offset = offset number of instructions. */
1215 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1216 }
1217
1218 char *
1219 md_atof (int what_statement_type,
1220 char *literalP,
1221 int *sizeP)
1222 {
1223 int prec;
1224 char *token;
1225 char keepval;
1226 unsigned long value;
1227 float float_value;
1228
1229 debug ("In md_atof()\n");
1230 debug ("precision = %c\n", what_statement_type);
1231 debug ("literal = %s\n", literalP);
1232 debug ("line = ");
1233 token = input_line_pointer;
1234 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1235 && (*input_line_pointer != ','))
1236 {
1237 debug ("%c", *input_line_pointer);
1238 input_line_pointer++;
1239 }
1240
1241 keepval = *input_line_pointer;
1242 *input_line_pointer = '\0';
1243 debug ("\n");
1244 float_value = (float) atof (token);
1245 *input_line_pointer = keepval;
1246 debug ("float_value = %f\n", float_value);
1247
1248 switch (what_statement_type)
1249 {
1250 case 'f':
1251 case 'F':
1252 case 's':
1253 case 'S':
1254 prec = 2;
1255 break;
1256
1257 case 'd':
1258 case 'D':
1259 case 'r':
1260 case 'R':
1261 prec = 4;
1262 break;
1263
1264 default:
1265 *sizeP = 0;
1266 return "Bad call to MD_ATOF()";
1267 }
1268
1269 if (float_value == 0.0)
1270 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1271 else
1272 {
1273 unsigned long exp, sign, mant, tmsfloat;
1274 union
1275 {
1276 float f;
1277 long l;
1278 }
1279 converter;
1280
1281 converter.f = float_value;
1282 tmsfloat = converter.l;
1283 sign = tmsfloat & 0x80000000;
1284 mant = tmsfloat & 0x007FFFFF;
1285 exp = tmsfloat & 0x7F800000;
1286 exp <<= 1;
1287 if (exp == 0xFF000000)
1288 {
1289 if (mant == 0)
1290 value = 0x7F7FFFFF;
1291 else if (sign == 0)
1292 value = 0x7F7FFFFF;
1293 else
1294 value = 0x7F800000;
1295 }
1296 else
1297 {
1298 exp -= 0x7F000000;
1299 if (sign)
1300 {
1301 mant = mant & 0x007FFFFF;
1302 mant = -mant;
1303 mant = mant & 0x00FFFFFF;
1304 if (mant == 0)
1305 {
1306 mant |= 0x00800000;
1307 exp = (long) exp - 0x01000000;
1308 }
1309 }
1310 tmsfloat = exp | mant;
1311 value = tmsfloat;
1312 }
1313 if (prec == 2)
1314 {
1315 long exp, mant;
1316
1317 if (tmsfloat == 0x80000000)
1318 value = 0x8000;
1319 else
1320 {
1321 value = 0;
1322 exp = (tmsfloat & 0xFF000000);
1323 exp >>= 24;
1324 mant = tmsfloat & 0x007FFFFF;
1325 if (tmsfloat & 0x00800000)
1326 {
1327 mant |= 0xFF000000;
1328 mant += 0x00000800;
1329 mant >>= 12;
1330 mant |= 0x00000800;
1331 mant &= 0x0FFF;
1332 if (exp > 7)
1333 value = 0x7800;
1334 }
1335 else
1336 {
1337 mant |= 0x00800000;
1338 mant += 0x00000800;
1339 exp += (mant >> 24);
1340 mant >>= 12;
1341 mant &= 0x07FF;
1342 if (exp > 7)
1343 value = 0x77FF;
1344 }
1345 if (exp < -8)
1346 value = 0x8000;
1347 if (value == 0)
1348 {
1349 mant = (exp << 12) | mant;
1350 value = mant & 0xFFFF;
1351 }
1352 }
1353 }
1354 }
1355 md_number_to_chars (literalP, value, prec);
1356 *sizeP = prec;
1357 return 0;
1358 }
1359
1360 void
1361 md_number_to_chars (char *buf, valueT val, int n)
1362 {
1363 debug ("In md_number_to_chars()\n");
1364 number_to_chars_bigendian (buf, val, n);
1365 }
1366
1367 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1368 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1369
1370 arelent *
1371 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1372 {
1373 arelent *rel;
1374 bfd_reloc_code_real_type code = 0;
1375
1376 debug ("In tc_gen_reloc()\n");
1377 debug ("fixP.size = %d\n", fixP->fx_size);
1378 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1379 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1380
1381 switch (F (fixP->fx_size, fixP->fx_pcrel))
1382 {
1383 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1384 MAP (2, 0, BFD_RELOC_16);
1385 MAP (3, 0, BFD_RELOC_24);
1386 MAP (2, 1, BFD_RELOC_16_PCREL);
1387 MAP (4, 0, BFD_RELOC_32);
1388 default:
1389 as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
1390 fixP->fx_pcrel ? "pc-relative " : "");
1391 }
1392 #undef MAP
1393 #undef F
1394
1395 rel = xmalloc (sizeof (* rel));
1396 assert (rel != 0);
1397 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1398 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1399 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1400 rel->addend = 0;
1401 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1402 if (!rel->howto)
1403 {
1404 const char *name;
1405
1406 name = S_GET_NAME (fixP->fx_addsy);
1407 if (name == NULL)
1408 name = "<unknown>";
1409 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1410 name, bfd_get_reloc_code_name (code));
1411 }
1412 return rel;
1413 }
1414
1415 void
1416 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1417 {
1418 debug ("In md_operand()\n");
1419 }
1420
1421 void
1422 md_assemble (char *line)
1423 {
1424 template *opcode;
1425 char *current_posn;
1426 char *token_start;
1427 char save_char;
1428 unsigned int count;
1429
1430 debug ("In md_assemble() with argument %s\n", line);
1431 memset (&insn, '\0', sizeof (insn));
1432 if (found_parallel_insn)
1433 {
1434 debug ("Line is second part of parallel instruction\n\n");
1435 found_parallel_insn = 0;
1436 return;
1437 }
1438 if ((current_posn =
1439 tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1440 current_posn = line;
1441 else
1442 found_parallel_insn = 1;
1443
1444 while (is_space_char (*current_posn))
1445 current_posn++;
1446
1447 token_start = current_posn;
1448
1449 if (!is_opcode_char (*current_posn))
1450 {
1451 as_bad ("Invalid character %s in opcode",
1452 output_invalid (*current_posn));
1453 return;
1454 }
1455 /* Check if instruction is a parallel instruction
1456 by seeing if the first character is a q. */
1457 if (*token_start == 'q')
1458 {
1459 if (tic30_parallel_insn (token_start))
1460 {
1461 if (found_parallel_insn)
1462 free (token_start);
1463 return;
1464 }
1465 }
1466 while (is_opcode_char (*current_posn))
1467 current_posn++;
1468 {
1469 /* Find instruction. */
1470 save_char = *current_posn;
1471 *current_posn = '\0';
1472 opcode = (template *) hash_find (op_hash, token_start);
1473 if (opcode)
1474 {
1475 debug ("Found instruction %s\n", opcode->name);
1476 insn.tm = opcode;
1477 }
1478 else
1479 {
1480 debug ("Didn't find insn\n");
1481 as_bad ("Unknown TMS320C30 instruction: %s", token_start);
1482 return;
1483 }
1484 *current_posn = save_char;
1485 }
1486
1487 if (*current_posn != END_OF_INSN)
1488 {
1489 /* Find operands. */
1490 int paren_not_balanced;
1491 int expecting_operand = 0;
1492 int this_operand;
1493 do
1494 {
1495 /* Skip optional white space before operand. */
1496 while (!is_operand_char (*current_posn)
1497 && *current_posn != END_OF_INSN)
1498 {
1499 if (!is_space_char (*current_posn))
1500 {
1501 as_bad ("Invalid character %s before %s operand",
1502 output_invalid (*current_posn),
1503 ordinal_names[insn.operands]);
1504 return;
1505 }
1506 current_posn++;
1507 }
1508 token_start = current_posn;
1509 paren_not_balanced = 0;
1510 while (paren_not_balanced || *current_posn != ',')
1511 {
1512 if (*current_posn == END_OF_INSN)
1513 {
1514 if (paren_not_balanced)
1515 {
1516 as_bad ("Unbalanced parenthesis in %s operand.",
1517 ordinal_names[insn.operands]);
1518 return;
1519 }
1520 else
1521 break;
1522 }
1523 else if (!is_operand_char (*current_posn)
1524 && !is_space_char (*current_posn))
1525 {
1526 as_bad ("Invalid character %s in %s operand",
1527 output_invalid (*current_posn),
1528 ordinal_names[insn.operands]);
1529 return;
1530 }
1531 if (*current_posn == '(')
1532 ++paren_not_balanced;
1533 if (*current_posn == ')')
1534 --paren_not_balanced;
1535 current_posn++;
1536 }
1537 if (current_posn != token_start)
1538 {
1539 /* Yes, we've read in another operand. */
1540 this_operand = insn.operands++;
1541 if (insn.operands > MAX_OPERANDS)
1542 {
1543 as_bad ("Spurious operands; (%d operands/instruction max)",
1544 MAX_OPERANDS);
1545 return;
1546 }
1547
1548 /* Now parse operand adding info to 'insn' as we go along. */
1549 save_char = *current_posn;
1550 *current_posn = '\0';
1551 insn.operand_type[this_operand] = tic30_operand (token_start);
1552 *current_posn = save_char;
1553 if (insn.operand_type[this_operand] == NULL)
1554 return;
1555 }
1556 else
1557 {
1558 if (expecting_operand)
1559 {
1560 as_bad ("Expecting operand after ','; got nothing");
1561 return;
1562 }
1563 if (*current_posn == ',')
1564 {
1565 as_bad ("Expecting operand before ','; got nothing");
1566 return;
1567 }
1568 }
1569
1570 /* Now *current_posn must be either ',' or END_OF_INSN. */
1571 if (*current_posn == ',')
1572 {
1573 if (*++current_posn == END_OF_INSN)
1574 {
1575 /* Just skip it, if it's \n complain. */
1576 as_bad ("Expecting operand after ','; got nothing");
1577 return;
1578 }
1579 expecting_operand = 1;
1580 }
1581 }
1582 while (*current_posn != END_OF_INSN);
1583 }
1584
1585 debug ("Number of operands found: %d\n", insn.operands);
1586
1587 /* Check that number of operands is correct. */
1588 if (insn.operands != insn.tm->operands)
1589 {
1590 unsigned int i;
1591 unsigned int numops = insn.tm->operands;
1592
1593 /* If operands are not the same, then see if any of the operands are
1594 not required. Then recheck with number of given operands. If they
1595 are still not the same, then give an error, otherwise carry on. */
1596 for (i = 0; i < insn.tm->operands; i++)
1597 if (insn.tm->operand_types[i] & NotReq)
1598 numops--;
1599 if (insn.operands != numops)
1600 {
1601 as_bad ("Incorrect number of operands given");
1602 return;
1603 }
1604 }
1605 insn.addressing_mode = AM_NotReq;
1606 for (count = 0; count < insn.operands; count++)
1607 {
1608 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1609 {
1610 debug ("Operand %d matches\n", count + 1);
1611 /* If instruction has two operands and has an AddressMode
1612 modifier then set addressing mode type for instruction. */
1613 if (insn.tm->opcode_modifier == AddressMode)
1614 {
1615 int addr_insn = 0;
1616 /* Store instruction uses the second
1617 operand for the address mode. */
1618 if ((insn.tm->operand_types[1] & (Indirect | Direct))
1619 == (Indirect | Direct))
1620 addr_insn = 1;
1621
1622 if (insn.operand_type[addr_insn]->op_type & (AllReg))
1623 insn.addressing_mode = AM_Register;
1624 else if (insn.operand_type[addr_insn]->op_type & Direct)
1625 insn.addressing_mode = AM_Direct;
1626 else if (insn.operand_type[addr_insn]->op_type & Indirect)
1627 insn.addressing_mode = AM_Indirect;
1628 else
1629 insn.addressing_mode = AM_Immediate;
1630 }
1631 }
1632 else
1633 {
1634 as_bad ("The %s operand doesn't match", ordinal_names[count]);
1635 return;
1636 }
1637 }
1638
1639 /* Now set the addressing mode for 3 operand instructions. */
1640 if ((insn.tm->operand_types[0] & op3T1)
1641 && (insn.tm->operand_types[1] & op3T2))
1642 {
1643 /* Set the addressing mode to the values used for 2 operand
1644 instructions in the G addressing field of the opcode. */
1645 char *p;
1646 switch (insn.operand_type[0]->op_type)
1647 {
1648 case Rn:
1649 case ARn:
1650 case DPReg:
1651 case OtherReg:
1652 if (insn.operand_type[1]->op_type & (AllReg))
1653 insn.addressing_mode = AM_Register;
1654 else if (insn.operand_type[1]->op_type & Indirect)
1655 insn.addressing_mode = AM_Direct;
1656 else
1657 {
1658 /* Shouldn't make it to this stage. */
1659 as_bad ("Incompatible first and second operands in instruction");
1660 return;
1661 }
1662 break;
1663 case Indirect:
1664 if (insn.operand_type[1]->op_type & (AllReg))
1665 insn.addressing_mode = AM_Indirect;
1666 else if (insn.operand_type[1]->op_type & Indirect)
1667 insn.addressing_mode = AM_Immediate;
1668 else
1669 {
1670 /* Shouldn't make it to this stage. */
1671 as_bad ("Incompatible first and second operands in instruction");
1672 return;
1673 }
1674 break;
1675 }
1676 /* Now make up the opcode for the 3 operand instructions. As in
1677 parallel instructions, there will be no unresolved values, so they
1678 can be fully formed and added to the frag table. */
1679 insn.opcode = insn.tm->base_opcode;
1680 if (insn.operand_type[0]->op_type & Indirect)
1681 {
1682 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1683 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1684 }
1685 else
1686 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1687
1688 if (insn.operand_type[1]->op_type & Indirect)
1689 {
1690 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1691 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1692 }
1693 else
1694 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1695
1696 if (insn.operands == 3)
1697 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1698
1699 insn.opcode |= insn.addressing_mode;
1700 p = frag_more (INSN_SIZE);
1701 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1702 }
1703 else
1704 {
1705 /* Not a three operand instruction. */
1706 char *p;
1707 int am_insn = -1;
1708 insn.opcode = insn.tm->base_opcode;
1709 /* Create frag for instruction - all instructions are 4 bytes long. */
1710 p = frag_more (INSN_SIZE);
1711 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1712 {
1713 insn.opcode |= insn.addressing_mode;
1714 if (insn.addressing_mode == AM_Indirect)
1715 {
1716 /* Determine which operand gives the addressing mode. */
1717 if (insn.operand_type[0]->op_type & Indirect)
1718 am_insn = 0;
1719 if ((insn.operands > 1)
1720 && (insn.operand_type[1]->op_type & Indirect))
1721 am_insn = 1;
1722 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1723 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1724 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1725 if (insn.operands > 1)
1726 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1727 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1728 }
1729 else if (insn.addressing_mode == AM_Register)
1730 {
1731 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1732 if (insn.operands > 1)
1733 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1734 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1735 }
1736 else if (insn.addressing_mode == AM_Direct)
1737 {
1738 if (insn.operand_type[0]->op_type & Direct)
1739 am_insn = 0;
1740 if ((insn.operands > 1)
1741 && (insn.operand_type[1]->op_type & Direct))
1742 am_insn = 1;
1743 if (insn.operands > 1)
1744 insn.opcode |=
1745 (insn.operand_type[! am_insn]->reg.opcode << 16);
1746 if (insn.operand_type[am_insn]->direct.resolved == 1)
1747 {
1748 /* Resolved values can be placed straight
1749 into instruction word, and output. */
1750 insn.opcode |=
1751 (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1752 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1753 }
1754 else
1755 {
1756 /* Unresolved direct addressing mode instruction. */
1757 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1758 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1759 & insn.operand_type[am_insn]->direct.direct_expr,
1760 0, 0);
1761 }
1762 }
1763 else if (insn.addressing_mode == AM_Immediate)
1764 {
1765 if (insn.operand_type[0]->immediate.resolved == 1)
1766 {
1767 char *keeploc;
1768 int size;
1769
1770 if (insn.operands > 1)
1771 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1772
1773 switch (insn.tm->imm_arg_type)
1774 {
1775 case Imm_Float:
1776 debug ("Floating point first operand\n");
1777 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1778
1779 keeploc = input_line_pointer;
1780 input_line_pointer =
1781 insn.operand_type[0]->immediate.label;
1782
1783 if (md_atof ('f', p + 2, & size) != 0)
1784 {
1785 as_bad ("invalid short form floating point immediate operand");
1786 return;
1787 }
1788
1789 input_line_pointer = keeploc;
1790 break;
1791
1792 case Imm_UInt:
1793 debug ("Unsigned int first operand\n");
1794 if (insn.operand_type[0]->immediate.decimal_found)
1795 as_warn ("rounding down first operand float to unsigned int");
1796 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1797 as_warn ("only lower 16-bits of first operand are used");
1798 insn.opcode |=
1799 (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1800 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1801 break;
1802
1803 case Imm_SInt:
1804 debug ("Int first operand\n");
1805
1806 if (insn.operand_type[0]->immediate.decimal_found)
1807 as_warn ("rounding down first operand float to signed int");
1808
1809 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1810 insn.operand_type[0]->immediate.s_number > 32767)
1811 {
1812 as_bad ("first operand is too large for 16-bit signed int");
1813 return;
1814 }
1815 insn.opcode |=
1816 (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1817 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1818 break;
1819 }
1820 }
1821 else
1822 {
1823 /* Unresolved immediate label. */
1824 if (insn.operands > 1)
1825 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1826 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1827 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1828 & insn.operand_type[0]->immediate.imm_expr,
1829 0, 0);
1830 }
1831 }
1832 }
1833 else if (insn.tm->opcode_modifier == PCRel)
1834 {
1835 /* Conditional Branch and Call instructions. */
1836 if ((insn.tm->operand_types[0] & (AllReg | Disp))
1837 == (AllReg | Disp))
1838 {
1839 if (insn.operand_type[0]->op_type & (AllReg))
1840 {
1841 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1842 insn.opcode |= PC_Register;
1843 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1844 }
1845 else
1846 {
1847 insn.opcode |= PC_Relative;
1848 if (insn.operand_type[0]->immediate.resolved == 1)
1849 {
1850 insn.opcode |=
1851 (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1852 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1853 }
1854 else
1855 {
1856 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1857 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1858 2, & insn.operand_type[0]->immediate.imm_expr,
1859 1, 0);
1860 }
1861 }
1862 }
1863 else if ((insn.tm->operand_types[0] & ARn) == ARn)
1864 {
1865 /* Decrement and Branch instructions. */
1866 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1867 if (insn.operand_type[1]->op_type & (AllReg))
1868 {
1869 insn.opcode |= (insn.operand_type[1]->reg.opcode);
1870 insn.opcode |= PC_Register;
1871 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1872 }
1873 else if (insn.operand_type[1]->immediate.resolved == 1)
1874 {
1875 if (insn.operand_type[0]->immediate.decimal_found)
1876 {
1877 as_bad ("first operand is floating point");
1878 return;
1879 }
1880 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1881 insn.operand_type[0]->immediate.s_number > 32767)
1882 {
1883 as_bad ("first operand is too large for 16-bit signed int");
1884 return;
1885 }
1886 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1887 insn.opcode |= PC_Relative;
1888 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1889 }
1890 else
1891 {
1892 insn.opcode |= PC_Relative;
1893 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1894 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1895 & insn.operand_type[1]->immediate.imm_expr,
1896 1, 0);
1897 }
1898 }
1899 }
1900 else if (insn.tm->operand_types[0] == IVector)
1901 {
1902 /* Trap instructions. */
1903 if (insn.operand_type[0]->op_type & IVector)
1904 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1905 else
1906 {
1907 /* Shouldn't get here. */
1908 as_bad ("interrupt vector for trap instruction out of range");
1909 return;
1910 }
1911 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1912 }
1913 else if (insn.tm->opcode_modifier == StackOp
1914 || insn.tm->opcode_modifier == Rotate)
1915 {
1916 /* Push, Pop and Rotate instructions. */
1917 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1918 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1919 }
1920 else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1921 == (Abs24 | Direct))
1922 {
1923 /* LDP Instruction needs to be tested
1924 for before the next section. */
1925 if (insn.operand_type[0]->op_type & Direct)
1926 {
1927 if (insn.operand_type[0]->direct.resolved == 1)
1928 {
1929 /* Direct addressing uses lower 8 bits of direct address. */
1930 insn.opcode |=
1931 (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1932 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1933 }
1934 else
1935 {
1936 fixS *fix;
1937
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]->direct.direct_expr, 0, 0);
1941 /* Ensure that the assembler doesn't complain
1942 about fitting a 24-bit address into 8 bits. */
1943 fix->fx_no_overflow = 1;
1944 }
1945 }
1946 else
1947 {
1948 if (insn.operand_type[0]->immediate.resolved == 1)
1949 {
1950 /* Immediate addressing uses upper 8 bits of address. */
1951 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1952 {
1953 as_bad ("LDP instruction needs a 24-bit operand");
1954 return;
1955 }
1956 insn.opcode |=
1957 ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1958 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1959 }
1960 else
1961 {
1962 fixS *fix;
1963 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1964 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1965 1, &insn.operand_type[0]->immediate.imm_expr,
1966 0, 0);
1967 fix->fx_no_overflow = 1;
1968 }
1969 }
1970 }
1971 else if (insn.tm->operand_types[0] & (Imm24))
1972 {
1973 /* Unconditional Branch and Call instructions. */
1974 if (insn.operand_type[0]->immediate.resolved == 1)
1975 {
1976 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1977 as_warn ("first operand is too large for a 24-bit displacement");
1978 insn.opcode |=
1979 (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1980 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1981 }
1982 else
1983 {
1984 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1985 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1986 & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1987 }
1988 }
1989 else if (insn.tm->operand_types[0] & NotReq)
1990 /* Check for NOP instruction without arguments. */
1991 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1992
1993 else if (insn.tm->operands == 0)
1994 /* Check for instructions without operands. */
1995 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1996 }
1997 debug ("Addressing mode: %08X\n", insn.addressing_mode);
1998 {
1999 unsigned int i;
2000
2001 for (i = 0; i < insn.operands; i++)
2002 {
2003 if (insn.operand_type[i]->immediate.label)
2004 free (insn.operand_type[i]->immediate.label);
2005 free (insn.operand_type[i]);
2006 }
2007 }
2008 debug ("Final opcode: %08X\n", insn.opcode);
2009 debug ("\n");
2010 }
2011