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