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