Fix typo introduced by previous delta
[binutils.git] / gas / config / tc-tic30.c
blob7234741c9b81990cd643ebd45c8a6264921ce8c6
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)
6 This file is part of GAS, the GNU Assembler.
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.
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.
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, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
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. */
28 #include "as.h"
29 #include "safe-ctype.h"
30 #include "opcode/tic30.h"
31 #ifdef ANSI_PROTOTYPES
32 #include <stdarg.h>
33 #else
34 #include <varargs.h>
35 #endif
37 /* Put here all non-digit non-letter characters that may occur in an
38 operand. */
39 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
40 static char *ordinal_names[] = {
41 "first", "second", "third", "fourth", "fifth"
44 const int md_reloc_size = 0;
46 const char comment_chars[] = ";";
47 const char line_comment_chars[] = "*";
48 const char line_separator_chars[] = "";
50 const char *md_shortopts = "";
51 struct option md_longopts[] = {
52 {NULL, no_argument, NULL, 0}
55 size_t md_longopts_size = sizeof (md_longopts);
57 /* Chars that mean this number is a floating point constant. */
58 /* As in 0f12.456 */
59 /* or 0d1.2345e12 */
60 const char FLT_CHARS[] = "fFdDxX";
62 /* Chars that can be used to separate mant from exp in floating point
63 nums. */
64 const char EXP_CHARS[] = "eE";
66 /* tables for lexical analysis */
67 static char opcode_chars[256];
68 static char register_chars[256];
69 static char operand_chars[256];
70 static char space_chars[256];
71 static char identifier_chars[256];
72 static char digit_chars[256];
74 /* lexical macros */
75 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
76 #define is_operand_char(x) (operand_chars[(unsigned char) x])
77 #define is_register_char(x) (register_chars[(unsigned char) x])
78 #define is_space_char(x) (space_chars[(unsigned char) x])
79 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
80 #define is_digit_char(x) (digit_chars[(unsigned char) x])
82 const pseudo_typeS md_pseudo_table[] = {
83 {0, 0, 0}
86 int debug PARAMS ((const char *string, ...));
88 int
89 debug VPARAMS ((const char *string, ...))
91 if (flag_debug)
93 char str[100];
95 VA_OPEN (argptr, string);
96 VA_FIXEDARG (argptr, const char *, string);
97 vsprintf (str, string, argptr);
98 VA_CLOSE (argptr);
99 if (str[0] == '\0')
100 return (0);
101 fputs (str, USE_STDOUT ? stdout : stderr);
102 return strlen (str);
104 else
105 return 0;
108 /* hash table for opcode lookup */
109 static struct hash_control *op_hash;
110 /* hash table for parallel opcode lookup */
111 static struct hash_control *parop_hash;
112 /* hash table for register lookup */
113 static struct hash_control *reg_hash;
114 /* hash table for indirect addressing lookup */
115 static struct hash_control *ind_hash;
117 void
118 md_begin ()
120 const char *hash_err;
121 debug ("In md_begin()\n");
122 op_hash = hash_new ();
124 const template *current_optab = tic30_optab;
125 for (; current_optab < tic30_optab_end; current_optab++)
127 hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
128 if (hash_err)
129 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
132 parop_hash = hash_new ();
134 const partemplate *current_parop = tic30_paroptab;
135 for (; current_parop < tic30_paroptab_end; current_parop++)
137 hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
138 if (hash_err)
139 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
142 reg_hash = hash_new ();
144 const reg *current_reg = tic30_regtab;
145 for (; current_reg < tic30_regtab_end; current_reg++)
147 hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
148 if (hash_err)
149 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
152 ind_hash = hash_new ();
154 const ind_addr_type *current_ind = tic30_indaddr_tab;
155 for (; current_ind < tic30_indaddrtab_end; current_ind++)
157 hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
158 if (hash_err)
159 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
162 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
164 register int c;
165 register char *p;
167 for (c = 0; c < 256; c++)
169 if (ISLOWER (c) || ISDIGIT (c))
171 opcode_chars[c] = c;
172 register_chars[c] = c;
174 else if (ISUPPER (c))
176 opcode_chars[c] = TOLOWER (c);
177 register_chars[c] = opcode_chars[c];
179 else if (c == ')' || c == '(')
181 register_chars[c] = c;
183 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
184 operand_chars[c] = c;
185 if (ISDIGIT (c) || c == '-')
186 digit_chars[c] = c;
187 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
188 identifier_chars[c] = c;
189 if (c == ' ' || c == '\t')
190 space_chars[c] = c;
191 if (c == '_')
192 opcode_chars[c] = c;
194 for (p = operand_special_chars; *p != '\0'; p++)
195 operand_chars[(unsigned char) *p] = *p;
199 /* Address Mode OR values */
200 #define AM_Register 0x00000000
201 #define AM_Direct 0x00200000
202 #define AM_Indirect 0x00400000
203 #define AM_Immediate 0x00600000
204 #define AM_NotReq 0xFFFFFFFF
206 /* PC Relative OR values */
207 #define PC_Register 0x00000000
208 #define PC_Relative 0x02000000
210 typedef struct {
211 unsigned op_type;
212 struct {
213 int resolved;
214 unsigned address;
215 char *label;
216 expressionS direct_expr;
217 } direct;
218 struct {
219 unsigned mod;
220 int ARnum;
221 unsigned char disp;
222 } indirect;
223 struct {
224 unsigned opcode;
225 } reg;
226 struct {
227 int resolved;
228 int decimal_found;
229 float f_number;
230 int s_number;
231 unsigned int u_number;
232 char *label;
233 expressionS imm_expr;
234 } immediate;
235 } operand;
237 int tic30_parallel_insn PARAMS ((char *));
238 operand *tic30_operand PARAMS ((char *));
239 char *tic30_find_parallel_insn PARAMS ((char *, char *));
241 template *opcode;
243 struct tic30_insn {
244 template *tm; /* Template of current instruction */
245 unsigned opcode; /* Final opcode */
246 unsigned int operands; /* Number of given operands */
247 /* Type of operand given in instruction */
248 operand *operand_type[MAX_OPERANDS];
249 unsigned addressing_mode; /* Final addressing mode of instruction */
252 struct tic30_insn insn;
253 static int found_parallel_insn;
255 void
256 md_assemble (line)
257 char *line;
259 template *opcode;
260 char *current_posn;
261 char *token_start;
262 char save_char;
263 unsigned int count;
265 debug ("In md_assemble() with argument %s\n", line);
266 memset (&insn, '\0', sizeof (insn));
267 if (found_parallel_insn)
269 debug ("Line is second part of parallel instruction\n\n");
270 found_parallel_insn = 0;
271 return;
273 if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
274 current_posn = line;
275 else
276 found_parallel_insn = 1;
277 while (is_space_char (*current_posn))
278 current_posn++;
279 token_start = current_posn;
280 if (!is_opcode_char (*current_posn))
282 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
283 return;
285 /* Check if instruction is a parallel instruction by seeing if the first
286 character is a q. */
287 if (*token_start == 'q')
289 if (tic30_parallel_insn (token_start))
291 if (found_parallel_insn)
292 free (token_start);
293 return;
296 while (is_opcode_char (*current_posn))
297 current_posn++;
298 { /* Find instruction */
299 save_char = *current_posn;
300 *current_posn = '\0';
301 opcode = (template *) hash_find (op_hash, token_start);
302 if (opcode)
304 debug ("Found instruction %s\n", opcode->name);
305 insn.tm = opcode;
307 else
309 debug ("Didn't find insn\n");
310 as_bad ("Unknown TMS320C30 instruction: %s", token_start);
311 return;
313 *current_posn = save_char;
315 if (*current_posn != END_OF_INSN)
316 { /* Find operands */
317 int paren_not_balanced;
318 int expecting_operand = 0;
319 int this_operand;
322 /* skip optional white space before operand */
323 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
325 if (!is_space_char (*current_posn))
327 as_bad ("Invalid character %s before %s operand",
328 output_invalid (*current_posn),
329 ordinal_names[insn.operands]);
330 return;
332 current_posn++;
334 token_start = current_posn; /* after white space */
335 paren_not_balanced = 0;
336 while (paren_not_balanced || *current_posn != ',')
338 if (*current_posn == END_OF_INSN)
340 if (paren_not_balanced)
342 as_bad ("Unbalanced parenthesis in %s operand.",
343 ordinal_names[insn.operands]);
344 return;
346 else
347 break; /* we are done */
349 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
351 as_bad ("Invalid character %s in %s operand",
352 output_invalid (*current_posn),
353 ordinal_names[insn.operands]);
354 return;
356 if (*current_posn == '(')
357 ++paren_not_balanced;
358 if (*current_posn == ')')
359 --paren_not_balanced;
360 current_posn++;
362 if (current_posn != token_start)
363 { /* yes, we've read in another operand */
364 this_operand = insn.operands++;
365 if (insn.operands > MAX_OPERANDS)
367 as_bad ("Spurious operands; (%d operands/instruction max)",
368 MAX_OPERANDS);
369 return;
371 /* now parse operand adding info to 'insn' as we go along */
372 save_char = *current_posn;
373 *current_posn = '\0';
374 insn.operand_type[this_operand] = tic30_operand (token_start);
375 *current_posn = save_char;
376 if (insn.operand_type[this_operand] == NULL)
377 return;
379 else
381 if (expecting_operand)
383 as_bad ("Expecting operand after ','; got nothing");
384 return;
386 if (*current_posn == ',')
388 as_bad ("Expecting operand before ','; got nothing");
389 return;
392 /* now *current_posn must be either ',' or END_OF_INSN */
393 if (*current_posn == ',')
395 if (*++current_posn == END_OF_INSN)
396 { /* just skip it, if it's \n complain */
397 as_bad ("Expecting operand after ','; got nothing");
398 return;
400 expecting_operand = 1;
403 while (*current_posn != END_OF_INSN); /* until we get end of insn */
405 debug ("Number of operands found: %d\n", insn.operands);
406 /* Check that number of operands is correct */
407 if (insn.operands != insn.tm->operands)
409 unsigned int i;
410 unsigned int numops = insn.tm->operands;
411 /* If operands are not the same, then see if any of the operands are not
412 required. Then recheck with number of given operands. If they are still not
413 the same, then give an error, otherwise carry on. */
414 for (i = 0; i < insn.tm->operands; i++)
415 if (insn.tm->operand_types[i] & NotReq)
416 numops--;
417 if (insn.operands != numops)
419 as_bad ("Incorrect number of operands given");
420 return;
423 insn.addressing_mode = AM_NotReq;
424 for (count = 0; count < insn.operands; count++)
426 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
428 debug ("Operand %d matches\n", count + 1);
429 /* If instruction has two operands and has an AddressMode modifier then set
430 addressing mode type for instruction */
431 if (insn.tm->opcode_modifier == AddressMode)
433 int addr_insn = 0;
434 /* Store instruction uses the second operand for the address mode. */
435 if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
436 addr_insn = 1;
437 if (insn.operand_type[addr_insn]->op_type & (AllReg))
438 insn.addressing_mode = AM_Register;
439 else if (insn.operand_type[addr_insn]->op_type & Direct)
440 insn.addressing_mode = AM_Direct;
441 else if (insn.operand_type[addr_insn]->op_type & Indirect)
442 insn.addressing_mode = AM_Indirect;
443 else
444 insn.addressing_mode = AM_Immediate;
447 else
449 as_bad ("The %s operand doesn't match", ordinal_names[count]);
450 return;
453 /* Now set the addressing mode for 3 operand instructions. */
454 if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
456 /* Set the addressing mode to the values used for 2 operand instructions in the
457 G addressing field of the opcode. */
458 char *p;
459 switch (insn.operand_type[0]->op_type)
461 case Rn:
462 case ARn:
463 case DPReg:
464 case OtherReg:
465 if (insn.operand_type[1]->op_type & (AllReg))
466 insn.addressing_mode = AM_Register;
467 else if (insn.operand_type[1]->op_type & Indirect)
468 insn.addressing_mode = AM_Direct;
469 else
471 /* Shouldn't make it to this stage */
472 as_bad ("Incompatible first and second operands in instruction");
473 return;
475 break;
476 case Indirect:
477 if (insn.operand_type[1]->op_type & (AllReg))
478 insn.addressing_mode = AM_Indirect;
479 else if (insn.operand_type[1]->op_type & Indirect)
480 insn.addressing_mode = AM_Immediate;
481 else
483 /* Shouldn't make it to this stage */
484 as_bad ("Incompatible first and second operands in instruction");
485 return;
487 break;
489 /* Now make up the opcode for the 3 operand instructions. As in parallel
490 instructions, there will be no unresolved values, so they can be fully formed
491 and added to the frag table. */
492 insn.opcode = insn.tm->base_opcode;
493 if (insn.operand_type[0]->op_type & Indirect)
495 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
496 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
498 else
499 insn.opcode |= (insn.operand_type[0]->reg.opcode);
500 if (insn.operand_type[1]->op_type & Indirect)
502 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
503 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
505 else
506 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
507 if (insn.operands == 3)
508 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
509 insn.opcode |= insn.addressing_mode;
510 p = frag_more (INSN_SIZE);
511 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
513 else
514 { /* Not a three operand instruction */
515 char *p;
516 int am_insn = -1;
517 insn.opcode = insn.tm->base_opcode;
518 /* Create frag for instruction - all instructions are 4 bytes long. */
519 p = frag_more (INSN_SIZE);
520 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
522 insn.opcode |= insn.addressing_mode;
523 if (insn.addressing_mode == AM_Indirect)
525 /* Determine which operand gives the addressing mode */
526 if (insn.operand_type[0]->op_type & Indirect)
527 am_insn = 0;
528 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
529 am_insn = 1;
530 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
531 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
532 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
533 if (insn.operands > 1)
534 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
535 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
537 else if (insn.addressing_mode == AM_Register)
539 insn.opcode |= (insn.operand_type[0]->reg.opcode);
540 if (insn.operands > 1)
541 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
542 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
544 else if (insn.addressing_mode == AM_Direct)
546 if (insn.operand_type[0]->op_type & Direct)
547 am_insn = 0;
548 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
549 am_insn = 1;
550 if (insn.operands > 1)
551 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
552 if (insn.operand_type[am_insn]->direct.resolved == 1)
554 /* Resolved values can be placed straight into instruction word, and output */
555 insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
556 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
558 else
559 { /* Unresolved direct addressing mode instruction */
560 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
561 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
564 else if (insn.addressing_mode == AM_Immediate)
566 if (insn.operand_type[0]->immediate.resolved == 1)
568 char *keeploc;
569 int size;
570 if (insn.operands > 1)
571 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
572 switch (insn.tm->imm_arg_type)
574 case Imm_Float:
575 debug ("Floating point first operand\n");
576 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
577 keeploc = input_line_pointer;
578 input_line_pointer = insn.operand_type[0]->immediate.label;
579 if (md_atof ('f', p + 2, &size) != 0)
581 as_bad ("invalid short form floating point immediate operand");
582 return;
584 input_line_pointer = keeploc;
585 break;
586 case Imm_UInt:
587 debug ("Unsigned int first operand\n");
588 if (insn.operand_type[0]->immediate.decimal_found)
589 as_warn ("rounding down first operand float to unsigned int");
590 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
591 as_warn ("only lower 16-bits of first operand are used");
592 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
593 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
594 break;
595 case Imm_SInt:
596 debug ("Int first operand\n");
597 if (insn.operand_type[0]->immediate.decimal_found)
598 as_warn ("rounding down first operand float to signed int");
599 if (insn.operand_type[0]->immediate.s_number < -32768 ||
600 insn.operand_type[0]->immediate.s_number > 32767)
602 as_bad ("first operand is too large for 16-bit signed int");
603 return;
605 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
606 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
607 break;
610 else
611 { /* Unresolved immediate label */
612 if (insn.operands > 1)
613 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
614 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
615 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
619 else if (insn.tm->opcode_modifier == PCRel)
621 /* Conditional Branch and Call instructions */
622 if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
624 if (insn.operand_type[0]->op_type & (AllReg))
626 insn.opcode |= (insn.operand_type[0]->reg.opcode);
627 insn.opcode |= PC_Register;
628 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
630 else
632 insn.opcode |= PC_Relative;
633 if (insn.operand_type[0]->immediate.resolved == 1)
635 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
636 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
638 else
640 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
641 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
645 else if ((insn.tm->operand_types[0] & ARn) == ARn)
647 /* Decrement and Branch instructions */
648 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
649 if (insn.operand_type[1]->op_type & (AllReg))
651 insn.opcode |= (insn.operand_type[1]->reg.opcode);
652 insn.opcode |= PC_Register;
653 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
655 else if (insn.operand_type[1]->immediate.resolved == 1)
657 if (insn.operand_type[0]->immediate.decimal_found)
659 as_bad ("first operand is floating point");
660 return;
662 if (insn.operand_type[0]->immediate.s_number < -32768 ||
663 insn.operand_type[0]->immediate.s_number > 32767)
665 as_bad ("first operand is too large for 16-bit signed int");
666 return;
668 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
669 insn.opcode |= PC_Relative;
670 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
672 else
674 insn.opcode |= PC_Relative;
675 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
676 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
680 else if (insn.tm->operand_types[0] == IVector)
682 /* Trap instructions */
683 if (insn.operand_type[0]->op_type & IVector)
684 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
685 else
686 { /* Shouldn't get here */
687 as_bad ("interrupt vector for trap instruction out of range");
688 return;
690 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
692 else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
694 /* Push, Pop and Rotate instructions */
695 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
696 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
698 else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
700 /* LDP Instruction needs to be tested for before the next section */
701 if (insn.operand_type[0]->op_type & Direct)
703 if (insn.operand_type[0]->direct.resolved == 1)
705 /* Direct addressing uses lower 8 bits of direct address */
706 insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
707 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
709 else
711 fixS *fix;
712 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
713 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
714 /* Ensure that the assembler doesn't complain about fitting a 24-bit
715 address into 8 bits. */
716 fix->fx_no_overflow = 1;
719 else
721 if (insn.operand_type[0]->immediate.resolved == 1)
723 /* Immediate addressing uses upper 8 bits of address */
724 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
726 as_bad ("LDP instruction needs a 24-bit operand");
727 return;
729 insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
730 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
732 else
734 fixS *fix;
735 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
736 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
737 fix->fx_no_overflow = 1;
741 else if (insn.tm->operand_types[0] & (Imm24))
743 /* Unconditional Branch and Call instructions */
744 if (insn.operand_type[0]->immediate.resolved == 1)
746 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
747 as_warn ("first operand is too large for a 24-bit displacement");
748 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
749 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
751 else
753 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
754 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
757 else if (insn.tm->operand_types[0] & NotReq)
759 /* Check for NOP instruction without arguments. */
760 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
762 else if (insn.tm->operands == 0)
764 /* Check for instructions without operands. */
765 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
768 debug ("Addressing mode: %08X\n", insn.addressing_mode);
770 unsigned int i;
771 for (i = 0; i < insn.operands; i++)
773 if (insn.operand_type[i]->immediate.label)
774 free (insn.operand_type[i]->immediate.label);
775 free (insn.operand_type[i]);
778 debug ("Final opcode: %08X\n", insn.opcode);
779 debug ("\n");
782 struct tic30_par_insn {
783 partemplate *tm; /* Template of current parallel instruction */
784 unsigned operands[2]; /* Number of given operands for each insn */
785 /* Type of operand given in instruction */
786 operand *operand_type[2][MAX_OPERANDS];
787 int swap_operands; /* Whether to swap operands around. */
788 unsigned p_field; /* Value of p field in multiply add/sub instructions */
789 unsigned opcode; /* Final opcode */
792 struct tic30_par_insn p_insn;
795 tic30_parallel_insn (char *token)
797 static partemplate *p_opcode;
798 char *current_posn = token;
799 char *token_start;
800 char save_char;
802 debug ("In tic30_parallel_insn with %s\n", token);
803 memset (&p_insn, '\0', sizeof (p_insn));
804 while (is_opcode_char (*current_posn))
805 current_posn++;
806 { /* Find instruction */
807 save_char = *current_posn;
808 *current_posn = '\0';
809 p_opcode = (partemplate *) hash_find (parop_hash, token);
810 if (p_opcode)
812 debug ("Found instruction %s\n", p_opcode->name);
813 p_insn.tm = p_opcode;
815 else
817 char first_opcode[6] =
818 {0};
819 char second_opcode[6] =
820 {0};
821 unsigned int i;
822 int current_opcode = -1;
823 int char_ptr = 0;
825 for (i = 0; i < strlen (token); i++)
827 char ch = *(token + i);
828 if (ch == '_' && current_opcode == -1)
830 current_opcode = 0;
831 continue;
833 if (ch == '_' && current_opcode == 0)
835 current_opcode = 1;
836 char_ptr = 0;
837 continue;
839 switch (current_opcode)
841 case 0:
842 first_opcode[char_ptr++] = ch;
843 break;
844 case 1:
845 second_opcode[char_ptr++] = ch;
846 break;
849 debug ("first_opcode = %s\n", first_opcode);
850 debug ("second_opcode = %s\n", second_opcode);
851 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
852 p_opcode = (partemplate *) hash_find (parop_hash, token);
853 if (p_opcode)
855 debug ("Found instruction %s\n", p_opcode->name);
856 p_insn.tm = p_opcode;
857 p_insn.swap_operands = 1;
859 else
860 return 0;
862 *current_posn = save_char;
864 { /* Find operands */
865 int paren_not_balanced;
866 int expecting_operand = 0;
867 int found_separator = 0;
870 /* skip optional white space before operand */
871 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
873 if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
875 as_bad ("Invalid character %s before %s operand",
876 output_invalid (*current_posn),
877 ordinal_names[insn.operands]);
878 return 1;
880 if (*current_posn == PARALLEL_SEPARATOR)
881 found_separator = 1;
882 current_posn++;
884 token_start = current_posn; /* after white space */
885 paren_not_balanced = 0;
886 while (paren_not_balanced || *current_posn != ',')
888 if (*current_posn == END_OF_INSN)
890 if (paren_not_balanced)
892 as_bad ("Unbalanced parenthesis in %s operand.",
893 ordinal_names[insn.operands]);
894 return 1;
896 else
897 break; /* we are done */
899 else if (*current_posn == PARALLEL_SEPARATOR)
901 while (is_space_char (*(current_posn - 1)))
902 current_posn--;
903 break;
905 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
907 as_bad ("Invalid character %s in %s operand",
908 output_invalid (*current_posn),
909 ordinal_names[insn.operands]);
910 return 1;
912 if (*current_posn == '(')
913 ++paren_not_balanced;
914 if (*current_posn == ')')
915 --paren_not_balanced;
916 current_posn++;
918 if (current_posn != token_start)
919 { /* yes, we've read in another operand */
920 p_insn.operands[found_separator]++;
921 if (p_insn.operands[found_separator] > MAX_OPERANDS)
923 as_bad ("Spurious operands; (%d operands/instruction max)",
924 MAX_OPERANDS);
925 return 1;
927 /* now parse operand adding info to 'insn' as we go along */
928 save_char = *current_posn;
929 *current_posn = '\0';
930 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
931 tic30_operand (token_start);
932 *current_posn = save_char;
933 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
934 return 1;
936 else
938 if (expecting_operand)
940 as_bad ("Expecting operand after ','; got nothing");
941 return 1;
943 if (*current_posn == ',')
945 as_bad ("Expecting operand before ','; got nothing");
946 return 1;
949 /* now *current_posn must be either ',' or END_OF_INSN */
950 if (*current_posn == ',')
952 if (*++current_posn == END_OF_INSN)
953 { /* just skip it, if it's \n complain */
954 as_bad ("Expecting operand after ','; got nothing");
955 return 1;
957 expecting_operand = 1;
960 while (*current_posn != END_OF_INSN); /* until we get end of insn */
962 if (p_insn.swap_operands)
964 int temp_num, i;
965 operand *temp_op;
967 temp_num = p_insn.operands[0];
968 p_insn.operands[0] = p_insn.operands[1];
969 p_insn.operands[1] = temp_num;
970 for (i = 0; i < MAX_OPERANDS; i++)
972 temp_op = p_insn.operand_type[0][i];
973 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
974 p_insn.operand_type[1][i] = temp_op;
977 if (p_insn.operands[0] != p_insn.tm->operands_1)
979 as_bad ("incorrect number of operands given in the first instruction");
980 return 1;
982 if (p_insn.operands[1] != p_insn.tm->operands_2)
984 as_bad ("incorrect number of operands given in the second instruction");
985 return 1;
987 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
988 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
989 { /* Now check if operands are correct */
990 int count;
991 int num_rn = 0;
992 int num_ind = 0;
993 for (count = 0; count < 2; count++)
995 unsigned int i;
996 for (i = 0; i < p_insn.operands[count]; i++)
998 if ((p_insn.operand_type[count][i]->op_type &
999 p_insn.tm->operand_types[count][i]) == 0)
1001 as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
1002 return 1;
1004 /* Get number of R register and indirect reference contained within the first
1005 two operands of each instruction. This is required for the multiply
1006 parallel instructions which require two R registers and two indirect
1007 references, but not in any particular place. */
1008 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
1009 num_rn++;
1010 else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
1011 num_ind++;
1014 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
1016 /* Check for the multiply instructions */
1017 if (num_rn != 2)
1019 as_bad ("incorrect format for multiply parallel instruction");
1020 return 1;
1022 if (num_ind != 2)
1023 { /* Shouldn't get here */
1024 as_bad ("incorrect format for multiply parallel instruction");
1025 return 1;
1027 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
1028 (p_insn.operand_type[0][2]->reg.opcode != 0x01))
1030 as_bad ("destination for multiply can only be R0 or R1");
1031 return 1;
1033 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
1034 (p_insn.operand_type[1][2]->reg.opcode != 0x03))
1036 as_bad ("destination for add/subtract can only be R2 or R3");
1037 return 1;
1039 /* Now determine the P field for the instruction */
1040 if (p_insn.operand_type[0][0]->op_type & Indirect)
1042 if (p_insn.operand_type[0][1]->op_type & Indirect)
1043 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
1044 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1045 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
1046 else
1047 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
1049 else
1051 if (p_insn.operand_type[0][1]->op_type & Rn)
1052 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
1053 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1055 operand *temp;
1056 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
1057 /* Need to swap the two multiply operands around so that everything is in
1058 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1059 temp = p_insn.operand_type[0][0];
1060 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1061 p_insn.operand_type[0][1] = temp;
1063 else
1065 operand *temp;
1066 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
1067 temp = p_insn.operand_type[0][0];
1068 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1069 p_insn.operand_type[0][1] = temp;
1074 debug ("P field: %08X\n", p_insn.p_field);
1075 /* Finalise opcode. This is easier for parallel instructions as they have to be
1076 fully resolved, there are no memory addresses allowed, except through indirect
1077 addressing, so there are no labels to resolve. */
1079 p_insn.opcode = p_insn.tm->base_opcode;
1080 switch (p_insn.tm->oporder)
1082 case OO_4op1:
1083 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1084 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1085 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1086 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1087 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1088 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1089 break;
1090 case OO_4op2:
1091 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1092 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1093 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1094 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1095 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1096 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1097 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1098 as_warn ("loading the same register in parallel operation");
1099 break;
1100 case OO_4op3:
1101 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1102 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1103 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1104 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1105 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1106 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1107 break;
1108 case OO_5op1:
1109 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1110 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1111 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1112 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1113 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1114 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1115 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1116 break;
1117 case OO_5op2:
1118 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1119 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1120 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1121 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1122 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1123 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1124 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1125 break;
1126 case OO_PField:
1127 p_insn.opcode |= p_insn.p_field;
1128 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1129 p_insn.opcode |= 0x00800000;
1130 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1131 p_insn.opcode |= 0x00400000;
1132 switch (p_insn.p_field)
1134 case 0x00000000:
1135 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1136 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1137 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1138 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1139 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1140 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1141 break;
1142 case 0x01000000:
1143 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1144 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1145 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1146 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1147 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1148 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1149 break;
1150 case 0x02000000:
1151 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1152 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1153 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1154 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1155 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1156 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1157 break;
1158 case 0x03000000:
1159 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1160 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1161 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1162 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1163 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1164 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1165 break;
1167 break;
1169 } /* Opcode is finalised at this point for all parallel instructions. */
1170 { /* Output opcode */
1171 char *p;
1172 p = frag_more (INSN_SIZE);
1173 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1176 unsigned int i, j;
1177 for (i = 0; i < 2; i++)
1178 for (j = 0; j < p_insn.operands[i]; j++)
1179 free (p_insn.operand_type[i][j]);
1181 debug ("Final opcode: %08X\n", p_insn.opcode);
1182 debug ("\n");
1183 return 1;
1186 operand *
1187 tic30_operand (token)
1188 char *token;
1190 unsigned int count;
1191 char ind_buffer[strlen (token)];
1192 operand *current_op;
1194 debug ("In tic30_operand with %s\n", token);
1195 current_op = (operand *) malloc (sizeof (operand));
1196 memset (current_op, '\0', sizeof (operand));
1197 if (*token == DIRECT_REFERENCE)
1199 char *token_posn = token + 1;
1200 int direct_label = 0;
1201 debug ("Found direct reference\n");
1202 while (*token_posn)
1204 if (!is_digit_char (*token_posn))
1205 direct_label = 1;
1206 token_posn++;
1208 if (direct_label)
1210 char *save_input_line_pointer;
1211 segT retval;
1212 debug ("Direct reference is a label\n");
1213 current_op->direct.label = token + 1;
1214 save_input_line_pointer = input_line_pointer;
1215 input_line_pointer = token + 1;
1216 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1217 retval = expression (&current_op->direct.direct_expr);
1218 debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
1219 debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
1220 debug ("Segment: %d\n", retval);
1221 input_line_pointer = save_input_line_pointer;
1222 if (current_op->direct.direct_expr.X_op == O_constant)
1224 current_op->direct.address = current_op->direct.direct_expr.X_add_number;
1225 current_op->direct.resolved = 1;
1228 else
1230 debug ("Direct reference is a number\n");
1231 current_op->direct.address = atoi (token + 1);
1232 current_op->direct.resolved = 1;
1234 current_op->op_type = Direct;
1236 else if (*token == INDIRECT_REFERENCE)
1237 { /* Indirect reference operand */
1238 int found_ar = 0;
1239 int found_disp = 0;
1240 int ar_number = -1;
1241 int disp_number = 0;
1242 int buffer_posn = 1;
1243 ind_addr_type *ind_addr_op;
1244 debug ("Found indirect reference\n");
1245 ind_buffer[0] = *token;
1246 for (count = 1; count < strlen (token); count++)
1247 { /* Strip operand */
1248 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
1249 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
1250 (*(token + count) == 'r' || *(token + count) == 'R'))
1252 /* AR reference is found, so get its number and remove it from the buffer
1253 so it can pass through hash_find() */
1254 if (found_ar)
1256 as_bad ("More than one AR register found in indirect reference");
1257 return NULL;
1259 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
1261 as_bad ("Illegal AR register in indirect reference");
1262 return NULL;
1264 ar_number = *(token + count + 1) - '0';
1265 found_ar = 1;
1266 count++;
1268 if (*(token + count) == '(')
1270 /* Parenthesis found, so check if a displacement value is inside. If so, get
1271 the value and remove it from the buffer. */
1272 if (is_digit_char (*(token + count + 1)))
1274 char disp[10];
1275 int disp_posn = 0;
1277 if (found_disp)
1279 as_bad ("More than one displacement found in indirect reference");
1280 return NULL;
1282 count++;
1283 while (*(token + count) != ')')
1285 if (!is_digit_char (*(token + count)))
1287 as_bad ("Invalid displacement in indirect reference");
1288 return NULL;
1290 disp[disp_posn++] = *(token + (count++));
1292 disp[disp_posn] = '\0';
1293 disp_number = atoi (disp);
1294 count--;
1295 found_disp = 1;
1298 buffer_posn++;
1300 ind_buffer[buffer_posn] = '\0';
1301 if (!found_ar)
1303 as_bad ("AR register not found in indirect reference");
1304 return NULL;
1306 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
1307 if (ind_addr_op)
1309 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
1310 if (ind_addr_op->displacement == IMPLIED_DISP)
1312 found_disp = 1;
1313 disp_number = 1;
1315 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
1317 /* Maybe an implied displacement of 1 again */
1318 as_bad ("required displacement wasn't given in indirect reference");
1319 return 0;
1322 else
1324 as_bad ("illegal indirect reference");
1325 return NULL;
1327 if (found_disp && (disp_number < 0 || disp_number > 255))
1329 as_bad ("displacement must be an unsigned 8-bit number");
1330 return NULL;
1332 current_op->indirect.mod = ind_addr_op->modfield;
1333 current_op->indirect.disp = disp_number;
1334 current_op->indirect.ARnum = ar_number;
1335 current_op->op_type = Indirect;
1337 else
1339 reg *regop = (reg *) hash_find (reg_hash, token);
1340 if (regop)
1342 debug ("Found register operand: %s\n", regop->name);
1343 if (regop->regtype == REG_ARn)
1344 current_op->op_type = ARn;
1345 else if (regop->regtype == REG_Rn)
1346 current_op->op_type = Rn;
1347 else if (regop->regtype == REG_DP)
1348 current_op->op_type = DPReg;
1349 else
1350 current_op->op_type = OtherReg;
1351 current_op->reg.opcode = regop->opcode;
1353 else
1355 if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
1357 char *save_input_line_pointer;
1358 segT retval;
1359 debug ("Probably a label: %s\n", token);
1360 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1361 strcpy (current_op->immediate.label, token);
1362 current_op->immediate.label[strlen (token)] = '\0';
1363 save_input_line_pointer = input_line_pointer;
1364 input_line_pointer = token;
1365 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1366 retval = expression (&current_op->immediate.imm_expr);
1367 debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
1368 debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
1369 debug ("Segment: %d\n", retval);
1370 input_line_pointer = save_input_line_pointer;
1371 if (current_op->immediate.imm_expr.X_op == O_constant)
1373 current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
1374 current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
1375 current_op->immediate.resolved = 1;
1378 else
1380 unsigned count;
1381 debug ("Found a number or displacement\n");
1382 for (count = 0; count < strlen (token); count++)
1383 if (*(token + count) == '.')
1384 current_op->immediate.decimal_found = 1;
1385 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1386 strcpy (current_op->immediate.label, token);
1387 current_op->immediate.label[strlen (token)] = '\0';
1388 current_op->immediate.f_number = (float) atof (token);
1389 current_op->immediate.s_number = (int) atoi (token);
1390 current_op->immediate.u_number = (unsigned int) atoi (token);
1391 current_op->immediate.resolved = 1;
1393 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
1394 if (current_op->immediate.u_number <= 31)
1395 current_op->op_type |= IVector;
1398 return current_op;
1401 /* next_line points to the next line after the current instruction (current_line).
1402 Search for the parallel bars, and if found, merge two lines into internal syntax
1403 for a parallel instruction:
1404 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1405 By this stage, all comments are scrubbed, and only the bare lines are given.
1408 #define NONE 0
1409 #define START_OPCODE 1
1410 #define END_OPCODE 2
1411 #define START_OPERANDS 3
1412 #define END_OPERANDS 4
1414 char *
1415 tic30_find_parallel_insn (current_line, next_line)
1416 char *current_line;
1417 char *next_line;
1419 int found_parallel = 0;
1420 char first_opcode[256];
1421 char second_opcode[256];
1422 char first_operands[256];
1423 char second_operands[256];
1424 char *parallel_insn;
1426 debug ("In tic30_find_parallel_insn()\n");
1427 while (!is_end_of_line[(unsigned char) *next_line])
1429 if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
1431 found_parallel = 1;
1432 next_line++;
1433 break;
1435 next_line++;
1437 if (!found_parallel)
1438 return NULL;
1439 debug ("Found a parallel instruction\n");
1441 int i;
1442 char *opcode, *operands, *line;
1444 for (i = 0; i < 2; i++)
1446 if (i == 0)
1448 opcode = &first_opcode[0];
1449 operands = &first_operands[0];
1450 line = current_line;
1452 else
1454 opcode = &second_opcode[0];
1455 operands = &second_operands[0];
1456 line = next_line;
1459 int search_status = NONE;
1460 int char_ptr = 0;
1461 char c;
1463 while (!is_end_of_line[(unsigned char) (c = *line)])
1465 if (is_opcode_char (c) && search_status == NONE)
1467 opcode[char_ptr++] = TOLOWER (c);
1468 search_status = START_OPCODE;
1470 else if (is_opcode_char (c) && search_status == START_OPCODE)
1472 opcode[char_ptr++] = TOLOWER (c);
1474 else if (!is_opcode_char (c) && search_status == START_OPCODE)
1476 opcode[char_ptr] = '\0';
1477 char_ptr = 0;
1478 search_status = END_OPCODE;
1480 else if (is_operand_char (c) && search_status == START_OPERANDS)
1482 operands[char_ptr++] = c;
1484 if (is_operand_char (c) && search_status == END_OPCODE)
1486 operands[char_ptr++] = c;
1487 search_status = START_OPERANDS;
1489 line++;
1491 if (search_status != START_OPERANDS)
1492 return NULL;
1493 operands[char_ptr] = '\0';
1497 parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
1498 strlen (second_opcode) + strlen (second_operands) + 8);
1499 sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
1500 debug ("parallel insn = %s\n", parallel_insn);
1501 return parallel_insn;
1504 #undef NONE
1505 #undef START_OPCODE
1506 #undef END_OPCODE
1507 #undef START_OPERANDS
1508 #undef END_OPERANDS
1510 /* In order to get gas to ignore any | chars at the start of a line,
1511 this function returns true if a | is found in a line. */
1514 tic30_unrecognized_line (c)
1515 int c;
1517 debug ("In tc_unrecognized_line\n");
1518 return (c == PARALLEL_SEPARATOR);
1522 md_estimate_size_before_relax (fragP, segment)
1523 fragS *fragP ATTRIBUTE_UNUSED;
1524 segT segment ATTRIBUTE_UNUSED;
1526 debug ("In md_estimate_size_before_relax()\n");
1527 return 0;
1530 void
1531 md_convert_frag (abfd, sec, fragP)
1532 bfd *abfd ATTRIBUTE_UNUSED;
1533 segT sec ATTRIBUTE_UNUSED;
1534 register fragS *fragP ATTRIBUTE_UNUSED;
1536 debug ("In md_convert_frag()\n");
1539 void
1540 md_apply_fix3 (fixP, valP, seg)
1541 fixS *fixP;
1542 valueT *valP;
1543 segT seg ATTRIBUTE_UNUSED;
1545 valueT value = *valP;
1547 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1548 debug ("Values in fixP\n");
1549 debug ("fx_size = %d\n", fixP->fx_size);
1550 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1551 debug ("fx_where = %d\n", fixP->fx_where);
1552 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1554 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1556 value /= INSN_SIZE;
1557 if (fixP->fx_size == 1)
1558 /* Special fix for LDP instruction. */
1559 value = (value & 0x00FF0000) >> 16;
1561 debug ("new value = %ld\n", (long) value);
1562 md_number_to_chars (buf, value, fixP->fx_size);
1565 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1566 fixP->fx_done = 1;
1570 md_parse_option (c, arg)
1571 int c ATTRIBUTE_UNUSED;
1572 char *arg ATTRIBUTE_UNUSED;
1574 debug ("In md_parse_option()\n");
1575 return 0;
1578 void
1579 md_show_usage (stream)
1580 FILE *stream ATTRIBUTE_UNUSED;
1582 debug ("In md_show_usage()\n");
1585 symbolS *
1586 md_undefined_symbol (name)
1587 char *name ATTRIBUTE_UNUSED;
1589 debug ("In md_undefined_symbol()\n");
1590 return (symbolS *) 0;
1593 valueT
1594 md_section_align (segment, size)
1595 segT segment;
1596 valueT size;
1598 debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
1599 size = (size + 3) / 4;
1600 size *= 4;
1601 debug ("New size value = %d\n", size);
1602 return size;
1605 long
1606 md_pcrel_from (fixP)
1607 fixS *fixP;
1609 int offset;
1611 debug ("In md_pcrel_from()\n");
1612 debug ("fx_where = %d\n", fixP->fx_where);
1613 debug ("fx_size = %d\n", fixP->fx_size);
1614 /* Find the opcode that represents the current instruction in the fr_literal
1615 storage area, and check bit 21. Bit 21 contains whether the current instruction
1616 is a delayed one or not, and then set the offset value appropriately. */
1617 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1618 offset = 3;
1619 else
1620 offset = 1;
1621 debug ("offset = %d\n", offset);
1622 /* PC Relative instructions have a format:
1623 displacement = Label - (PC + offset)
1624 This function returns PC + offset where:
1625 fx_where - fx_size = PC
1626 INSN_SIZE * offset = offset number of instructions
1628 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1631 char *
1632 md_atof (what_statement_type, literalP, sizeP)
1633 int what_statement_type;
1634 char *literalP;
1635 int *sizeP;
1637 int prec;
1638 char *token;
1639 char keepval;
1640 unsigned long value;
1641 float float_value;
1642 debug ("In md_atof()\n");
1643 debug ("precision = %c\n", what_statement_type);
1644 debug ("literal = %s\n", literalP);
1645 debug ("line = ");
1646 token = input_line_pointer;
1647 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1648 && (*input_line_pointer != ','))
1650 debug ("%c", *input_line_pointer);
1651 input_line_pointer++;
1653 keepval = *input_line_pointer;
1654 *input_line_pointer = '\0';
1655 debug ("\n");
1656 float_value = (float) atof (token);
1657 *input_line_pointer = keepval;
1658 debug ("float_value = %f\n", float_value);
1659 switch (what_statement_type)
1661 case 'f':
1662 case 'F':
1663 case 's':
1664 case 'S':
1665 prec = 2;
1666 break;
1668 case 'd':
1669 case 'D':
1670 case 'r':
1671 case 'R':
1672 prec = 4;
1673 break;
1675 default:
1676 *sizeP = 0;
1677 return "Bad call to MD_ATOF()";
1679 if (float_value == 0.0)
1681 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1683 else
1685 unsigned long exp, sign, mant, tmsfloat;
1686 tmsfloat = *((long *) &float_value);
1687 sign = tmsfloat & 0x80000000;
1688 mant = tmsfloat & 0x007FFFFF;
1689 exp = tmsfloat & 0x7F800000;
1690 exp <<= 1;
1691 if (exp == 0xFF000000)
1693 if (mant == 0)
1694 value = 0x7F7FFFFF;
1695 else if (sign == 0)
1696 value = 0x7F7FFFFF;
1697 else
1698 value = 0x7F800000;
1700 else
1702 exp -= 0x7F000000;
1703 if (sign)
1705 mant = mant & 0x007FFFFF;
1706 mant = -mant;
1707 mant = mant & 0x00FFFFFF;
1708 if (mant == 0)
1710 mant |= 0x00800000;
1711 exp = (long) exp - 0x01000000;
1714 tmsfloat = exp | mant;
1715 value = tmsfloat;
1717 if (prec == 2)
1719 long exp, mant;
1721 if (tmsfloat == 0x80000000)
1723 value = 0x8000;
1725 else
1727 value = 0;
1728 exp = (tmsfloat & 0xFF000000);
1729 exp >>= 24;
1730 mant = tmsfloat & 0x007FFFFF;
1731 if (tmsfloat & 0x00800000)
1733 mant |= 0xFF000000;
1734 mant += 0x00000800;
1735 mant >>= 12;
1736 mant |= 0x00000800;
1737 mant &= 0x0FFF;
1738 if (exp > 7)
1739 value = 0x7800;
1741 else
1743 mant |= 0x00800000;
1744 mant += 0x00000800;
1745 exp += (mant >> 24);
1746 mant >>= 12;
1747 mant &= 0x07FF;
1748 if (exp > 7)
1749 value = 0x77FF;
1751 if (exp < -8)
1752 value = 0x8000;
1753 if (value == 0)
1755 mant = (exp << 12) | mant;
1756 value = mant & 0xFFFF;
1761 md_number_to_chars (literalP, value, prec);
1762 *sizeP = prec;
1763 return 0;
1766 void
1767 md_number_to_chars (buf, val, n)
1768 char *buf;
1769 valueT val;
1770 int n;
1772 debug ("In md_number_to_chars()\n");
1773 number_to_chars_bigendian (buf, val, n);
1774 /* number_to_chars_littleendian(buf,val,n); */
1777 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1778 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1780 arelent *
1781 tc_gen_reloc (section, fixP)
1782 asection *section ATTRIBUTE_UNUSED;
1783 fixS *fixP;
1785 arelent *rel;
1786 bfd_reloc_code_real_type code = 0;
1788 debug ("In tc_gen_reloc()\n");
1789 debug ("fixP.size = %d\n", fixP->fx_size);
1790 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1791 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1792 switch (F (fixP->fx_size, fixP->fx_pcrel))
1794 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1795 MAP (2, 0, BFD_RELOC_16);
1796 MAP (3, 0, BFD_RELOC_24);
1797 MAP (2, 1, BFD_RELOC_16_PCREL);
1798 MAP (4, 0, BFD_RELOC_32);
1799 default:
1800 as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
1801 fixP->fx_pcrel ? "pc-relative " : "");
1803 #undef MAP
1804 #undef F
1806 rel = (arelent *) xmalloc (sizeof (arelent));
1807 assert (rel != 0);
1808 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1809 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1810 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1811 rel->addend = 0;
1812 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1813 if (!rel->howto)
1815 const char *name;
1816 name = S_GET_NAME (fixP->fx_addsy);
1817 if (name == NULL)
1818 name = "<unknown>";
1819 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
1821 return rel;
1824 void
1825 md_operand (expressionP)
1826 expressionS *expressionP ATTRIBUTE_UNUSED;
1828 debug ("In md_operand()\n");
1831 char output_invalid_buf[8];
1833 char *
1834 output_invalid (c)
1835 char c;
1837 if (ISPRINT (c))
1838 sprintf (output_invalid_buf, "'%c'", c);
1839 else
1840 sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
1841 return output_invalid_buf;