Initial revision
[binutils.git] / gas / config / tc-tic30.c
blob61ed905e47a426269725fed16b2ef649aa64ac6a
1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998 Free Software Foundation.
3 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
5 This file is part of GAS, the GNU Assembler.
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 2, or (at your option)
10 any later version.
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.
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, 59 Temple Place - Suite 330, Boston, MA
20 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.
29 #include "as.h"
30 #include "opcode/tic30.h"
32 /* put here all non-digit non-letter charcters that may occur in an operand */
33 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
34 static char *ordinal_names[] =
35 {"first", "second", "third", "fourth", "fifth"};
37 const int md_reloc_size = 0;
39 const char comment_chars[] = ";";
40 const char line_comment_chars[] = "*";
41 const char line_separator_chars[] = "";
43 const char *md_shortopts = "";
44 struct option md_longopts[] =
46 {NULL, no_argument, NULL, 0}
49 size_t md_longopts_size = sizeof (md_longopts);
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";
56 /* Chars that can be used to separate mant from exp in floating point nums */
57 const char EXP_CHARS[] = "eE";
59 /* tables for lexical analysis */
60 static char opcode_chars[256];
61 static char register_chars[256];
62 static char operand_chars[256];
63 static char space_chars[256];
64 static char identifier_chars[256];
65 static char digit_chars[256];
67 /* lexical macros */
68 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
69 #define is_operand_char(x) (operand_chars[(unsigned char) x])
70 #define is_register_char(x) (register_chars[(unsigned char) x])
71 #define is_space_char(x) (space_chars[(unsigned char) x])
72 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
73 #define is_digit_char(x) (digit_chars[(unsigned char) x])
75 const pseudo_typeS md_pseudo_table[] =
77 {0, 0, 0}
80 #undef USE_STDOUT
81 #define USE_STDOUT 1
83 #ifdef USE_STDARG
85 #include <stdarg.h>
87 int
88 debug (const char *string,...)
90 if (flag_debug)
92 va_list argptr;
93 char str[100];
95 va_start (argptr, string);
96 vsprintf (str, string, argptr);
97 if (str[0] == '\0')
98 return (0);
99 va_end (argptr);
100 fputs (str, USE_STDOUT ? stdout : stderr);
101 return strlen (str);
103 else
104 return 0;
106 #else
108 debug (string, va_alist)
109 const char *string;
110 va_dcl
112 if (flag_debug)
114 va_list argptr;
115 char str[100];
116 int cnt;
118 va_start (argptr, string);
119 cnt = vsprintf (str, string, argptr);
120 if (str[0] == NULL)
121 return (0);
122 va_end (argptr);
123 fputs (str, USE_STDOUT ? stdout : stderr);
124 return (cnt);
126 else
127 return 0;
129 #endif
131 /* hash table for opcode lookup */
132 static struct hash_control *op_hash;
133 /* hash table for parallel opcode lookup */
134 static struct hash_control *parop_hash;
135 /* hash table for register lookup */
136 static struct hash_control *reg_hash;
137 /* hash table for indirect addressing lookup */
138 static struct hash_control *ind_hash;
140 void
141 md_begin ()
143 const char *hash_err;
144 debug ("In md_begin()\n");
145 op_hash = hash_new ();
147 const template *current_optab = tic30_optab;
148 for (; current_optab < tic30_optab_end; current_optab++)
150 hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
151 if (hash_err)
152 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
155 parop_hash = hash_new ();
157 const partemplate *current_parop = tic30_paroptab;
158 for (; current_parop < tic30_paroptab_end; current_parop++)
160 hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
161 if (hash_err)
162 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
165 reg_hash = hash_new ();
167 const reg *current_reg = tic30_regtab;
168 for (; current_reg < tic30_regtab_end; current_reg++)
170 hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
171 if (hash_err)
172 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
175 ind_hash = hash_new ();
177 const ind_addr_type *current_ind = tic30_indaddr_tab;
178 for (; current_ind < tic30_indaddrtab_end; current_ind++)
180 hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
181 if (hash_err)
182 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
185 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
187 register int c;
188 register char *p;
190 for (c = 0; c < 256; c++)
192 if (islower (c) || isdigit (c))
194 opcode_chars[c] = c;
195 register_chars[c] = c;
197 else if (isupper (c))
199 opcode_chars[c] = tolower (c);
200 register_chars[c] = opcode_chars[c];
202 else if (c == ')' || c == '(')
204 register_chars[c] = c;
206 if (isupper (c) || islower (c) || isdigit (c))
207 operand_chars[c] = c;
208 if (isdigit (c) || c == '-')
209 digit_chars[c] = c;
210 if (isalpha (c) || c == '_' || c == '.' || isdigit (c))
211 identifier_chars[c] = c;
212 if (c == ' ' || c == '\t')
213 space_chars[c] = c;
214 if (c == '_')
215 opcode_chars[c] = c;
217 for (p = operand_special_chars; *p != '\0'; p++)
218 operand_chars[(unsigned char) *p] = *p;
222 /* Address Mode OR values */
223 #define AM_Register 0x00000000
224 #define AM_Direct 0x00200000
225 #define AM_Indirect 0x00400000
226 #define AM_Immediate 0x00600000
227 #define AM_NotReq 0xFFFFFFFF
229 /* PC Relative OR values */
230 #define PC_Register 0x00000000
231 #define PC_Relative 0x02000000
233 typedef struct
235 unsigned op_type;
236 struct
238 int resolved;
239 unsigned address;
240 char *label;
241 expressionS direct_expr;
243 direct;
244 struct
246 unsigned mod;
247 int ARnum;
248 unsigned char disp;
250 indirect;
251 struct
253 unsigned opcode;
255 reg;
256 struct
258 int resolved;
259 int decimal_found;
260 float f_number;
261 int s_number;
262 unsigned int u_number;
263 char *label;
264 expressionS imm_expr;
266 immediate;
268 operand;
270 int tic30_parallel_insn PARAMS ((char *));
271 operand *tic30_operand PARAMS ((char *));
272 char *tic30_find_parallel_insn PARAMS ((char *, char *));
274 template *opcode;
276 struct tic30_insn
278 template *tm; /* Template of current instruction */
279 unsigned opcode; /* Final opcode */
280 int operands; /* Number of given operands */
281 /* Type of operand given in instruction */
282 operand *operand_type[MAX_OPERANDS];
283 unsigned addressing_mode; /* Final addressing mode of instruction */
286 struct tic30_insn insn;
287 static int found_parallel_insn;
289 void
290 md_assemble (line)
291 char *line;
293 template *opcode;
294 char *current_posn;
295 char *token_start;
296 char save_char;
297 int count;
299 debug ("In md_assemble() with argument %s\n", line);
300 memset (&insn, '\0', sizeof (insn));
301 if (found_parallel_insn)
303 debug ("Line is second part of parallel instruction\n\n");
304 found_parallel_insn = 0;
305 return;
307 if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
308 current_posn = line;
309 else
310 found_parallel_insn = 1;
311 while (is_space_char (*current_posn))
312 current_posn++;
313 token_start = current_posn;
314 if (!is_opcode_char (*current_posn))
316 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
317 return;
319 /* Check if instruction is a parallel instruction by seeing if the first
320 character is a q. */
321 if (*token_start == 'q')
323 if (tic30_parallel_insn (token_start))
325 if (found_parallel_insn)
326 free (token_start);
327 return;
330 while (is_opcode_char (*current_posn))
331 current_posn++;
332 { /* Find instruction */
333 save_char = *current_posn;
334 *current_posn = '\0';
335 opcode = (template *) hash_find (op_hash, token_start);
336 if (opcode)
338 debug ("Found instruction %s\n", opcode->name);
339 insn.tm = opcode;
341 else
343 debug ("Didn't find insn\n");
344 as_bad ("Unknown TMS320C30 instruction: %s", token_start);
345 return;
347 *current_posn = save_char;
349 if (*current_posn != END_OF_INSN)
350 { /* Find operands */
351 int paren_not_balanced;
352 int expecting_operand = 0;
353 int this_operand;
356 /* skip optional white space before operand */
357 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
359 if (!is_space_char (*current_posn))
361 as_bad ("Invalid character %s before %s operand",
362 output_invalid (*current_posn),
363 ordinal_names[insn.operands]);
364 return;
366 current_posn++;
368 token_start = current_posn; /* after white space */
369 paren_not_balanced = 0;
370 while (paren_not_balanced || *current_posn != ',')
372 if (*current_posn == END_OF_INSN)
374 if (paren_not_balanced)
376 as_bad ("Unbalanced parenthesis in %s operand.",
377 ordinal_names[insn.operands]);
378 return;
380 else
381 break; /* we are done */
383 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
385 as_bad ("Invalid character %s in %s operand",
386 output_invalid (*current_posn),
387 ordinal_names[insn.operands]);
388 return;
390 if (*current_posn == '(')
391 ++paren_not_balanced;
392 if (*current_posn == ')')
393 --paren_not_balanced;
394 current_posn++;
396 if (current_posn != token_start)
397 { /* yes, we've read in another operand */
398 this_operand = insn.operands++;
399 if (insn.operands > MAX_OPERANDS)
401 as_bad ("Spurious operands; (%d operands/instruction max)",
402 MAX_OPERANDS);
403 return;
405 /* now parse operand adding info to 'insn' as we go along */
406 save_char = *current_posn;
407 *current_posn = '\0';
408 insn.operand_type[this_operand] = tic30_operand (token_start);
409 *current_posn = save_char;
410 if (insn.operand_type[this_operand] == NULL)
411 return;
413 else
415 if (expecting_operand)
417 as_bad ("Expecting operand after ','; got nothing");
418 return;
420 if (*current_posn == ',')
422 as_bad ("Expecting operand before ','; got nothing");
423 return;
426 /* now *current_posn must be either ',' or END_OF_INSN */
427 if (*current_posn == ',')
429 if (*++current_posn == END_OF_INSN)
430 { /* just skip it, if it's \n complain */
431 as_bad ("Expecting operand after ','; got nothing");
432 return;
434 expecting_operand = 1;
437 while (*current_posn != END_OF_INSN); /* until we get end of insn */
439 debug ("Number of operands found: %d\n", insn.operands);
440 /* Check that number of operands is correct */
441 if (insn.operands != insn.tm->operands)
443 int i;
444 int numops = insn.tm->operands;
445 /* If operands are not the same, then see if any of the operands are not
446 required. Then recheck with number of given operands. If they are still not
447 the same, then give an error, otherwise carry on. */
448 for (i = 0; i < insn.tm->operands; i++)
449 if (insn.tm->operand_types[i] & NotReq)
450 numops--;
451 if (insn.operands != numops)
453 as_bad ("Incorrect number of operands given");
454 return;
457 insn.addressing_mode = AM_NotReq;
458 for (count = 0; count < insn.operands; count++)
460 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
462 debug ("Operand %d matches\n", count + 1);
463 /* If instruction has two operands and has an AddressMode modifier then set
464 addressing mode type for instruction */
465 if (insn.tm->opcode_modifier == AddressMode)
467 int addr_insn = 0;
468 /* Store instruction uses the second operand for the address mode. */
469 if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
470 addr_insn = 1;
471 if (insn.operand_type[addr_insn]->op_type & (AllReg))
472 insn.addressing_mode = AM_Register;
473 else if (insn.operand_type[addr_insn]->op_type & Direct)
474 insn.addressing_mode = AM_Direct;
475 else if (insn.operand_type[addr_insn]->op_type & Indirect)
476 insn.addressing_mode = AM_Indirect;
477 else
478 insn.addressing_mode = AM_Immediate;
481 else
483 as_bad ("The %s operand doesn't match", ordinal_names[count]);
484 return;
487 /* Now set the addressing mode for 3 operand instructions. */
488 if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
490 /* Set the addressing mode to the values used for 2 operand instructions in the
491 G addressing field of the opcode. */
492 char *p;
493 switch (insn.operand_type[0]->op_type)
495 case Rn:
496 case ARn:
497 case DPReg:
498 case OtherReg:
499 if (insn.operand_type[1]->op_type & (AllReg))
500 insn.addressing_mode = AM_Register;
501 else if (insn.operand_type[1]->op_type & Indirect)
502 insn.addressing_mode = AM_Direct;
503 else
505 /* Shouldn't make it to this stage */
506 as_bad ("Incompatible first and second operands in instruction");
507 return;
509 break;
510 case Indirect:
511 if (insn.operand_type[1]->op_type & (AllReg))
512 insn.addressing_mode = AM_Indirect;
513 else if (insn.operand_type[1]->op_type & Indirect)
514 insn.addressing_mode = AM_Immediate;
515 else
517 /* Shouldn't make it to this stage */
518 as_bad ("Incompatible first and second operands in instruction");
519 return;
521 break;
523 /* Now make up the opcode for the 3 operand instructions. As in parallel
524 instructions, there will be no unresolved values, so they can be fully formed
525 and added to the frag table. */
526 insn.opcode = insn.tm->base_opcode;
527 if (insn.operand_type[0]->op_type & Indirect)
529 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
530 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
532 else
533 insn.opcode |= (insn.operand_type[0]->reg.opcode);
534 if (insn.operand_type[1]->op_type & Indirect)
536 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
537 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
539 else
540 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
541 if (insn.operands == 3)
542 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
543 insn.opcode |= insn.addressing_mode;
544 p = frag_more (INSN_SIZE);
545 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
547 else
548 { /* Not a three operand instruction */
549 char *p;
550 int am_insn = -1;
551 insn.opcode = insn.tm->base_opcode;
552 /* Create frag for instruction - all instructions are 4 bytes long. */
553 p = frag_more (INSN_SIZE);
554 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
556 insn.opcode |= insn.addressing_mode;
557 if (insn.addressing_mode == AM_Indirect)
559 /* Determine which operand gives the addressing mode */
560 if (insn.operand_type[0]->op_type & Indirect)
561 am_insn = 0;
562 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
563 am_insn = 1;
564 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
565 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
566 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
567 if (insn.operands > 1)
568 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
569 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
571 else if (insn.addressing_mode == AM_Register)
573 insn.opcode |= (insn.operand_type[0]->reg.opcode);
574 if (insn.operands > 1)
575 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
576 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
578 else if (insn.addressing_mode == AM_Direct)
580 if (insn.operand_type[0]->op_type & Direct)
581 am_insn = 0;
582 if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
583 am_insn = 1;
584 if (insn.operands > 1)
585 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
586 if (insn.operand_type[am_insn]->direct.resolved == 1)
588 /* Resolved values can be placed straight into instruction word, and output */
589 insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
590 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
592 else
593 { /* Unresolved direct addressing mode instruction */
594 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
595 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
598 else if (insn.addressing_mode == AM_Immediate)
600 if (insn.operand_type[0]->immediate.resolved == 1)
602 char *keeploc;
603 int size;
604 if (insn.operands > 1)
605 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
606 switch (insn.tm->imm_arg_type)
608 case Imm_Float:
609 debug ("Floating point first operand\n");
610 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
611 keeploc = input_line_pointer;
612 input_line_pointer = insn.operand_type[0]->immediate.label;
613 if (md_atof ('f', p + 2, &size) != 0)
615 as_bad ("invalid short form floating point immediate operand");
616 return;
618 input_line_pointer = keeploc;
619 break;
620 case Imm_UInt:
621 debug ("Unsigned int first operand\n");
622 if (insn.operand_type[0]->immediate.decimal_found)
623 as_warn ("rounding down first operand float to unsigned int");
624 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
625 as_warn ("only lower 16-bits of first operand are used");
626 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
627 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
628 break;
629 case Imm_SInt:
630 debug ("Int first operand\n");
631 if (insn.operand_type[0]->immediate.decimal_found)
632 as_warn ("rounding down first operand float to signed int");
633 if (insn.operand_type[0]->immediate.s_number < -32768 ||
634 insn.operand_type[0]->immediate.s_number > 32767)
636 as_bad ("first operand is too large for 16-bit signed int");
637 return;
639 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
640 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
641 break;
644 else
645 { /* Unresolved immediate label */
646 if (insn.operands > 1)
647 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
648 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
649 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
653 else if (insn.tm->opcode_modifier == PCRel)
655 /* Conditional Branch and Call instructions */
656 if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
658 if (insn.operand_type[0]->op_type & (AllReg))
660 insn.opcode |= (insn.operand_type[0]->reg.opcode);
661 insn.opcode |= PC_Register;
662 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
664 else
666 insn.opcode |= PC_Relative;
667 if (insn.operand_type[0]->immediate.resolved == 1)
669 insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
670 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
672 else
674 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
675 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
679 else if ((insn.tm->operand_types[0] & ARn) == ARn)
681 /* Decrement and Branch instructions */
682 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
683 if (insn.operand_type[1]->op_type & (AllReg))
685 insn.opcode |= (insn.operand_type[1]->reg.opcode);
686 insn.opcode |= PC_Register;
687 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
689 else if (insn.operand_type[1]->immediate.resolved == 1)
691 if (insn.operand_type[0]->immediate.decimal_found)
693 as_bad ("first operand is floating point");
694 return;
696 if (insn.operand_type[0]->immediate.s_number < -32768 ||
697 insn.operand_type[0]->immediate.s_number > 32767)
699 as_bad ("first operand is too large for 16-bit signed int");
700 return;
702 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
703 insn.opcode |= PC_Relative;
704 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
706 else
708 insn.opcode |= PC_Relative;
709 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
710 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
714 else if (insn.tm->operand_types[0] == IVector)
716 /* Trap instructions */
717 if (insn.operand_type[0]->op_type & IVector)
718 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
719 else
720 { /* Shouldn't get here */
721 as_bad ("interrupt vector for trap instruction out of range");
722 return;
724 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
726 else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
728 /* Push, Pop and Rotate instructions */
729 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
730 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
732 else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
734 /* LDP Instruction needs to be tested for before the next section */
735 if (insn.operand_type[0]->op_type & Direct)
737 if (insn.operand_type[0]->direct.resolved == 1)
739 /* Direct addressing uses lower 8 bits of direct address */
740 insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
741 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
743 else
745 fixS *fix;
746 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
747 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
748 /* Ensure that the assembler doesn't complain about fitting a 24-bit
749 address into 8 bits. */
750 fix->fx_no_overflow = 1;
753 else
755 if (insn.operand_type[0]->immediate.resolved == 1)
757 /* Immediate addressing uses upper 8 bits of address */
758 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
760 as_bad ("LDP instruction needs a 24-bit operand");
761 return;
763 insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
764 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
766 else
768 fixS *fix;
769 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
770 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
771 fix->fx_no_overflow = 1;
775 else if (insn.tm->operand_types[0] & (Imm24))
777 /* Unconditional Branch and Call instructions */
778 if (insn.operand_type[0]->immediate.resolved == 1)
780 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
781 as_warn ("first operand is too large for a 24-bit displacement");
782 insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
783 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
785 else
787 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
788 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
791 else if (insn.tm->operand_types[0] & NotReq)
793 /* Check for NOP instruction without arguments. */
794 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
796 else if (insn.tm->operands == 0)
798 /* Check for instructions without operands. */
799 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
802 debug ("Addressing mode: %08X\n", insn.addressing_mode);
804 int i;
805 for (i = 0; i < insn.operands; i++)
807 if (insn.operand_type[i]->immediate.label)
808 free (insn.operand_type[i]->immediate.label);
809 free (insn.operand_type[i]);
812 debug ("Final opcode: %08X\n", insn.opcode);
813 debug ("\n");
816 struct tic30_par_insn
818 partemplate *tm; /* Template of current parallel instruction */
819 int operands[2]; /* Number of given operands for each insn */
820 /* Type of operand given in instruction */
821 operand *operand_type[2][MAX_OPERANDS];
822 int swap_operands; /* Whether to swap operands around. */
823 unsigned p_field; /* Value of p field in multiply add/sub instructions */
824 unsigned opcode; /* Final opcode */
827 struct tic30_par_insn p_insn;
830 tic30_parallel_insn (char *token)
832 static partemplate *p_opcode;
833 char *current_posn = token;
834 char *token_start;
835 char save_char;
837 debug ("In tic30_parallel_insn with %s\n", token);
838 memset (&p_insn, '\0', sizeof (p_insn));
839 while (is_opcode_char (*current_posn))
840 current_posn++;
841 { /* Find instruction */
842 save_char = *current_posn;
843 *current_posn = '\0';
844 p_opcode = (partemplate *) hash_find (parop_hash, token);
845 if (p_opcode)
847 debug ("Found instruction %s\n", p_opcode->name);
848 p_insn.tm = p_opcode;
850 else
852 char first_opcode[6] =
853 {0};
854 char second_opcode[6] =
855 {0};
856 int i;
857 int current_opcode = -1;
858 int char_ptr = 0;
860 for (i = 0; i < strlen (token); i++)
862 char ch = *(token + i);
863 if (ch == '_' && current_opcode == -1)
865 current_opcode = 0;
866 continue;
868 if (ch == '_' && current_opcode == 0)
870 current_opcode = 1;
871 char_ptr = 0;
872 continue;
874 switch (current_opcode)
876 case 0:
877 first_opcode[char_ptr++] = ch;
878 break;
879 case 1:
880 second_opcode[char_ptr++] = ch;
881 break;
884 debug ("first_opcode = %s\n", first_opcode);
885 debug ("second_opcode = %s\n", second_opcode);
886 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
887 p_opcode = (partemplate *) hash_find (parop_hash, token);
888 if (p_opcode)
890 debug ("Found instruction %s\n", p_opcode->name);
891 p_insn.tm = p_opcode;
892 p_insn.swap_operands = 1;
894 else
895 return 0;
897 *current_posn = save_char;
899 { /* Find operands */
900 int paren_not_balanced;
901 int expecting_operand = 0;
902 int found_separator = 0;
905 /* skip optional white space before operand */
906 while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
908 if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
910 as_bad ("Invalid character %s before %s operand",
911 output_invalid (*current_posn),
912 ordinal_names[insn.operands]);
913 return 1;
915 if (*current_posn == PARALLEL_SEPARATOR)
916 found_separator = 1;
917 current_posn++;
919 token_start = current_posn; /* after white space */
920 paren_not_balanced = 0;
921 while (paren_not_balanced || *current_posn != ',')
923 if (*current_posn == END_OF_INSN)
925 if (paren_not_balanced)
927 as_bad ("Unbalanced parenthesis in %s operand.",
928 ordinal_names[insn.operands]);
929 return 1;
931 else
932 break; /* we are done */
934 else if (*current_posn == PARALLEL_SEPARATOR)
936 while (is_space_char (*(current_posn - 1)))
937 current_posn--;
938 break;
940 else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
942 as_bad ("Invalid character %s in %s operand",
943 output_invalid (*current_posn),
944 ordinal_names[insn.operands]);
945 return 1;
947 if (*current_posn == '(')
948 ++paren_not_balanced;
949 if (*current_posn == ')')
950 --paren_not_balanced;
951 current_posn++;
953 if (current_posn != token_start)
954 { /* yes, we've read in another operand */
955 p_insn.operands[found_separator]++;
956 if (p_insn.operands[found_separator] > MAX_OPERANDS)
958 as_bad ("Spurious operands; (%d operands/instruction max)",
959 MAX_OPERANDS);
960 return 1;
962 /* now parse operand adding info to 'insn' as we go along */
963 save_char = *current_posn;
964 *current_posn = '\0';
965 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
966 tic30_operand (token_start);
967 *current_posn = save_char;
968 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
969 return 1;
971 else
973 if (expecting_operand)
975 as_bad ("Expecting operand after ','; got nothing");
976 return 1;
978 if (*current_posn == ',')
980 as_bad ("Expecting operand before ','; got nothing");
981 return 1;
984 /* now *current_posn must be either ',' or END_OF_INSN */
985 if (*current_posn == ',')
987 if (*++current_posn == END_OF_INSN)
988 { /* just skip it, if it's \n complain */
989 as_bad ("Expecting operand after ','; got nothing");
990 return 1;
992 expecting_operand = 1;
995 while (*current_posn != END_OF_INSN); /* until we get end of insn */
997 if (p_insn.swap_operands)
999 int temp_num, i;
1000 operand *temp_op;
1002 temp_num = p_insn.operands[0];
1003 p_insn.operands[0] = p_insn.operands[1];
1004 p_insn.operands[1] = temp_num;
1005 for (i = 0; i < MAX_OPERANDS; i++)
1007 temp_op = p_insn.operand_type[0][i];
1008 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
1009 p_insn.operand_type[1][i] = temp_op;
1012 if (p_insn.operands[0] != p_insn.tm->operands_1)
1014 as_bad ("incorrect number of operands given in the first instruction");
1015 return 1;
1017 if (p_insn.operands[1] != p_insn.tm->operands_2)
1019 as_bad ("incorrect number of operands given in the second instruction");
1020 return 1;
1022 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
1023 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
1024 { /* Now check if operands are correct */
1025 int count;
1026 int num_rn = 0;
1027 int num_ind = 0;
1028 for (count = 0; count < 2; count++)
1030 int i;
1031 for (i = 0; i < p_insn.operands[count]; i++)
1033 if ((p_insn.operand_type[count][i]->op_type &
1034 p_insn.tm->operand_types[count][i]) == 0)
1036 as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
1037 return 1;
1039 /* Get number of R register and indirect reference contained within the first
1040 two operands of each instruction. This is required for the multiply
1041 parallel instructions which require two R registers and two indirect
1042 references, but not in any particular place. */
1043 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
1044 num_rn++;
1045 else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
1046 num_ind++;
1049 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
1051 /* Check for the multiply instructions */
1052 if (num_rn != 2)
1054 as_bad ("incorrect format for multiply parallel instruction");
1055 return 1;
1057 if (num_ind != 2)
1058 { /* Shouldn't get here */
1059 as_bad ("incorrect format for multiply parallel instruction");
1060 return 1;
1062 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
1063 (p_insn.operand_type[0][2]->reg.opcode != 0x01))
1065 as_bad ("destination for multiply can only be R0 or R1");
1066 return 1;
1068 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
1069 (p_insn.operand_type[1][2]->reg.opcode != 0x03))
1071 as_bad ("destination for add/subtract can only be R2 or R3");
1072 return 1;
1074 /* Now determine the P field for the instruction */
1075 if (p_insn.operand_type[0][0]->op_type & Indirect)
1077 if (p_insn.operand_type[0][1]->op_type & Indirect)
1078 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
1079 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1080 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
1081 else
1082 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
1084 else
1086 if (p_insn.operand_type[0][1]->op_type & Rn)
1087 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
1088 else if (p_insn.operand_type[1][0]->op_type & Indirect)
1090 operand *temp;
1091 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
1092 /* Need to swap the two multiply operands around so that everything is in
1093 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1094 temp = p_insn.operand_type[0][0];
1095 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1096 p_insn.operand_type[0][1] = temp;
1098 else
1100 operand *temp;
1101 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
1102 temp = p_insn.operand_type[0][0];
1103 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
1104 p_insn.operand_type[0][1] = temp;
1109 debug ("P field: %08X\n", p_insn.p_field);
1110 /* Finalise opcode. This is easier for parallel instructions as they have to be
1111 fully resolved, there are no memory addresses allowed, except through indirect
1112 addressing, so there are no labels to resolve. */
1114 p_insn.opcode = p_insn.tm->base_opcode;
1115 switch (p_insn.tm->oporder)
1117 case OO_4op1:
1118 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1119 p_insn.opcode |= (p_insn.operand_type[0][0]->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][1]->reg.opcode << 22);
1124 break;
1125 case OO_4op2:
1126 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1127 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1128 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1129 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1130 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1131 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1132 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1133 as_warn ("loading the same register in parallel operation");
1134 break;
1135 case OO_4op3:
1136 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1137 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1138 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1139 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1140 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1141 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1142 break;
1143 case OO_5op1:
1144 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1145 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1146 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1147 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1148 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1149 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1150 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1151 break;
1152 case OO_5op2:
1153 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1154 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1155 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1156 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1157 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1158 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1159 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1160 break;
1161 case OO_PField:
1162 p_insn.opcode |= p_insn.p_field;
1163 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1164 p_insn.opcode |= 0x00800000;
1165 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1166 p_insn.opcode |= 0x00400000;
1167 switch (p_insn.p_field)
1169 case 0x00000000:
1170 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1171 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1172 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1173 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1174 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1175 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1176 break;
1177 case 0x01000000:
1178 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1179 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1180 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1181 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1182 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1183 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1184 break;
1185 case 0x02000000:
1186 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1187 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1188 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1189 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1190 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1191 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1192 break;
1193 case 0x03000000:
1194 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1195 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1196 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1197 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1198 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1199 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1200 break;
1202 break;
1204 } /* Opcode is finalised at this point for all parallel instructions. */
1205 { /* Output opcode */
1206 char *p;
1207 p = frag_more (INSN_SIZE);
1208 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1211 int i, j;
1212 for (i = 0; i < 2; i++)
1213 for (j = 0; j < p_insn.operands[i]; j++)
1214 free (p_insn.operand_type[i][j]);
1216 debug ("Final opcode: %08X\n", p_insn.opcode);
1217 debug ("\n");
1218 return 1;
1221 operand *
1222 tic30_operand (token)
1223 char *token;
1225 int count;
1226 char ind_buffer[strlen (token)];
1227 operand *current_op;
1229 debug ("In tic30_operand with %s\n", token);
1230 current_op = (operand *) malloc (sizeof (operand));
1231 memset (current_op, '\0', sizeof (operand));
1232 if (*token == DIRECT_REFERENCE)
1234 char *token_posn = token + 1;
1235 int direct_label = 0;
1236 debug ("Found direct reference\n");
1237 while (*token_posn)
1239 if (!is_digit_char (*token_posn))
1240 direct_label = 1;
1241 token_posn++;
1243 if (direct_label)
1245 char *save_input_line_pointer;
1246 segT retval;
1247 debug ("Direct reference is a label\n");
1248 current_op->direct.label = token + 1;
1249 save_input_line_pointer = input_line_pointer;
1250 input_line_pointer = token + 1;
1251 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1252 retval = expression (&current_op->direct.direct_expr);
1253 debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
1254 debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
1255 debug ("Segment: %d\n", retval);
1256 input_line_pointer = save_input_line_pointer;
1257 if (current_op->direct.direct_expr.X_op == O_constant)
1259 current_op->direct.address = current_op->direct.direct_expr.X_add_number;
1260 current_op->direct.resolved = 1;
1263 else
1265 debug ("Direct reference is a number\n");
1266 current_op->direct.address = atoi (token + 1);
1267 current_op->direct.resolved = 1;
1269 current_op->op_type = Direct;
1271 else if (*token == INDIRECT_REFERENCE)
1272 { /* Indirect reference operand */
1273 int found_ar = 0;
1274 int found_disp = 0;
1275 int ar_number = -1;
1276 int disp_number = 0;
1277 int buffer_posn = 1;
1278 ind_addr_type *ind_addr_op;
1279 debug ("Found indirect reference\n");
1280 ind_buffer[0] = *token;
1281 for (count = 1; count < strlen (token); count++)
1282 { /* Strip operand */
1283 ind_buffer[buffer_posn] = tolower (*(token + count));
1284 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
1285 (*(token + count) == 'r' || *(token + count) == 'R'))
1287 /* AR reference is found, so get its number and remove it from the buffer
1288 so it can pass through hash_find() */
1289 if (found_ar)
1291 as_bad ("More than one AR register found in indirect reference");
1292 return NULL;
1294 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
1296 as_bad ("Illegal AR register in indirect reference");
1297 return NULL;
1299 ar_number = *(token + count + 1) - '0';
1300 found_ar = 1;
1301 count++;
1303 if (*(token + count) == '(')
1305 /* Parenthesis found, so check if a displacement value is inside. If so, get
1306 the value and remove it from the buffer. */
1307 if (is_digit_char (*(token + count + 1)))
1309 char disp[10];
1310 int disp_posn = 0;
1312 if (found_disp)
1314 as_bad ("More than one displacement found in indirect reference");
1315 return NULL;
1317 count++;
1318 while (*(token + count) != ')')
1320 if (!is_digit_char (*(token + count)))
1322 as_bad ("Invalid displacement in indirect reference");
1323 return NULL;
1325 disp[disp_posn++] = *(token + (count++));
1327 disp[disp_posn] = '\0';
1328 disp_number = atoi (disp);
1329 count--;
1330 found_disp = 1;
1333 buffer_posn++;
1335 ind_buffer[buffer_posn] = '\0';
1336 if (!found_ar)
1338 as_bad ("AR register not found in indirect reference");
1339 return NULL;
1341 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
1342 if (ind_addr_op)
1344 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
1345 if (ind_addr_op->displacement == IMPLIED_DISP)
1347 found_disp = 1;
1348 disp_number = 1;
1350 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
1352 /* Maybe an implied displacement of 1 again */
1353 as_bad ("required displacement wasn't given in indirect reference");
1354 return 0;
1357 else
1359 as_bad ("illegal indirect reference");
1360 return NULL;
1362 if (found_disp && (disp_number < 0 || disp_number > 255))
1364 as_bad ("displacement must be an unsigned 8-bit number");
1365 return NULL;
1367 current_op->indirect.mod = ind_addr_op->modfield;
1368 current_op->indirect.disp = disp_number;
1369 current_op->indirect.ARnum = ar_number;
1370 current_op->op_type = Indirect;
1372 else
1374 reg *regop = (reg *) hash_find (reg_hash, token);
1375 if (regop)
1377 debug ("Found register operand: %s\n", regop->name);
1378 if (regop->regtype == REG_ARn)
1379 current_op->op_type = ARn;
1380 else if (regop->regtype == REG_Rn)
1381 current_op->op_type = Rn;
1382 else if (regop->regtype == REG_DP)
1383 current_op->op_type = DPReg;
1384 else
1385 current_op->op_type = OtherReg;
1386 current_op->reg.opcode = regop->opcode;
1388 else
1390 if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
1392 char *save_input_line_pointer;
1393 segT retval;
1394 debug ("Probably a label: %s\n", token);
1395 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1396 strcpy (current_op->immediate.label, token);
1397 current_op->immediate.label[strlen (token)] = '\0';
1398 save_input_line_pointer = input_line_pointer;
1399 input_line_pointer = token;
1400 debug ("Current input_line_pointer: %s\n", input_line_pointer);
1401 retval = expression (&current_op->immediate.imm_expr);
1402 debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
1403 debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
1404 debug ("Segment: %d\n", retval);
1405 input_line_pointer = save_input_line_pointer;
1406 if (current_op->immediate.imm_expr.X_op == O_constant)
1408 current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
1409 current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
1410 current_op->immediate.resolved = 1;
1413 else
1415 unsigned count;
1416 debug ("Found a number or displacement\n");
1417 for (count = 0; count < strlen (token); count++)
1418 if (*(token + count) == '.')
1419 current_op->immediate.decimal_found = 1;
1420 current_op->immediate.label = (char *) malloc (strlen (token) + 1);
1421 strcpy (current_op->immediate.label, token);
1422 current_op->immediate.label[strlen (token)] = '\0';
1423 current_op->immediate.f_number = (float) atof (token);
1424 current_op->immediate.s_number = (int) atoi (token);
1425 current_op->immediate.u_number = (unsigned int) atoi (token);
1426 current_op->immediate.resolved = 1;
1428 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
1429 if (current_op->immediate.u_number >= 0 && current_op->immediate.u_number <= 31)
1430 current_op->op_type |= IVector;
1433 return current_op;
1436 /* next_line points to the next line after the current instruction (current_line).
1437 Search for the parallel bars, and if found, merge two lines into internal syntax
1438 for a parallel instruction:
1439 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1440 By this stage, all comments are scrubbed, and only the bare lines are given.
1443 #define NONE 0
1444 #define START_OPCODE 1
1445 #define END_OPCODE 2
1446 #define START_OPERANDS 3
1447 #define END_OPERANDS 4
1449 char *
1450 tic30_find_parallel_insn (current_line, next_line)
1451 char *current_line;
1452 char *next_line;
1454 int found_parallel = 0;
1455 char first_opcode[256];
1456 char second_opcode[256];
1457 char first_operands[256];
1458 char second_operands[256];
1459 char *parallel_insn;
1461 debug ("In tic30_find_parallel_insn()\n");
1462 while (!is_end_of_line[(int) *next_line])
1464 if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
1466 found_parallel = 1;
1467 next_line++;
1468 break;
1470 next_line++;
1472 if (!found_parallel)
1473 return NULL;
1474 debug ("Found a parallel instruction\n");
1476 int i;
1477 char *opcode, *operands, *line;
1479 for (i = 0; i < 2; i++)
1481 if (i == 0)
1483 opcode = &first_opcode[0];
1484 operands = &first_operands[0];
1485 line = current_line;
1487 else
1489 opcode = &second_opcode[0];
1490 operands = &second_operands[0];
1491 line = next_line;
1494 int search_status = NONE;
1495 int char_ptr = 0;
1496 char c;
1498 while (!is_end_of_line[(int) (c = *line)] && *line)
1500 if (is_opcode_char (c) && search_status == NONE)
1502 opcode[char_ptr++] = tolower (c);
1503 search_status = START_OPCODE;
1505 else if (is_opcode_char (c) && search_status == START_OPCODE)
1507 opcode[char_ptr++] = tolower (c);
1509 else if (!is_opcode_char (c) && search_status == START_OPCODE)
1511 opcode[char_ptr] = '\0';
1512 char_ptr = 0;
1513 search_status = END_OPCODE;
1515 else if (is_operand_char (c) && search_status == START_OPERANDS)
1517 operands[char_ptr++] = c;
1519 if (is_operand_char (c) && search_status == END_OPCODE)
1521 operands[char_ptr++] = c;
1522 search_status = START_OPERANDS;
1524 line++;
1526 if (search_status != START_OPERANDS)
1527 return NULL;
1528 operands[char_ptr] = '\0';
1532 parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
1533 strlen (second_opcode) + strlen (second_operands) + 8);
1534 sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
1535 debug ("parallel insn = %s\n", parallel_insn);
1536 return parallel_insn;
1539 #undef NONE
1540 #undef START_OPCODE
1541 #undef END_OPCODE
1542 #undef START_OPERANDS
1543 #undef END_OPERANDS
1545 /* In order to get gas to ignore any | chars at the start of a line,
1546 this function returns true if a | is found in a line. */
1549 tic30_unrecognized_line (c)
1550 int c;
1552 debug ("In tc_unrecognized_line\n");
1553 return (c == PARALLEL_SEPARATOR);
1557 md_estimate_size_before_relax (fragP, segment)
1558 fragS *fragP;
1559 segT segment;
1561 debug ("In md_estimate_size_before_relax()\n");
1562 return 0;
1565 void
1566 md_convert_frag (abfd, sec, fragP)
1567 bfd *abfd;
1568 segT sec;
1569 register fragS *fragP;
1571 debug ("In md_convert_frag()\n");
1575 md_apply_fix (fixP, valP)
1576 fixS *fixP;
1577 valueT *valP;
1579 valueT value = *valP;
1581 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1582 debug ("Values in fixP\n");
1583 debug ("fx_size = %d\n", fixP->fx_size);
1584 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1585 debug ("fx_where = %d\n", fixP->fx_where);
1586 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1588 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1589 value /= INSN_SIZE;
1590 if (fixP->fx_size == 1)
1591 { /* Special fix for LDP instruction. */
1592 value = (value & 0x00FF0000) >> 16;
1594 debug ("new value = %ld\n", (long) value);
1595 md_number_to_chars (buf, value, fixP->fx_size);
1597 return 1;
1601 md_parse_option (c, arg)
1602 int c;
1603 char *arg;
1605 int i;
1607 debug ("In md_parse_option()\n");
1608 for (i = 0; i < c; i++)
1610 printf ("%c\n", arg[c]);
1612 return 0;
1615 void
1616 md_show_usage (stream)
1617 FILE *stream;
1619 debug ("In md_show_usage()\n");
1622 symbolS *
1623 md_undefined_symbol (name)
1624 char *name;
1626 debug ("In md_undefined_symbol()\n");
1627 return (symbolS *) 0;
1630 valueT
1631 md_section_align (segment, size)
1632 segT segment;
1633 valueT size;
1635 debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
1636 size = (size + 3) / 4;
1637 size *= 4;
1638 debug ("New size value = %d\n", size);
1639 return size;
1642 long
1643 md_pcrel_from (fixP)
1644 fixS *fixP;
1646 int offset;
1648 debug ("In md_pcrel_from()\n");
1649 debug ("fx_where = %d\n", fixP->fx_where);
1650 debug ("fx_size = %d\n", fixP->fx_size);
1651 /* Find the opcode that represents the current instruction in the fr_literal
1652 storage area, and check bit 21. Bit 21 contains whether the current instruction
1653 is a delayed one or not, and then set the offset value appropriately. */
1654 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1655 offset = 3;
1656 else
1657 offset = 1;
1658 debug ("offset = %d\n", offset);
1659 /* PC Relative instructions have a format:
1660 displacement = Label - (PC + offset)
1661 This function returns PC + offset where:
1662 fx_where - fx_size = PC
1663 INSN_SIZE * offset = offset number of instructions
1665 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1668 char *
1669 md_atof (what_statement_type, literalP, sizeP)
1670 int what_statement_type;
1671 char *literalP;
1672 int *sizeP;
1674 int prec;
1675 char *token;
1676 char keepval;
1677 unsigned long value;
1678 /* char *atof_ieee (); */
1679 float float_value;
1680 debug ("In md_atof()\n");
1681 debug ("precision = %c\n", what_statement_type);
1682 debug ("literal = %s\n", literalP);
1683 debug ("line = ");
1684 token = input_line_pointer;
1685 while (!is_end_of_line[(unsigned) *input_line_pointer] && (*input_line_pointer) && (*input_line_pointer != ','))
1687 debug ("%c", *input_line_pointer);
1688 input_line_pointer++;
1690 keepval = *input_line_pointer;
1691 *input_line_pointer = '\0';
1692 debug ("\n");
1693 float_value = (float) atof (token);
1694 *input_line_pointer = keepval;
1695 debug ("float_value = %f\n", float_value);
1696 switch (what_statement_type)
1698 case 'f':
1699 case 'F':
1700 case 's':
1701 case 'S':
1702 prec = 2;
1703 break;
1705 case 'd':
1706 case 'D':
1707 case 'r':
1708 case 'R':
1709 prec = 4;
1710 break;
1712 default:
1713 *sizeP = 0;
1714 return "Bad call to MD_ATOF()";
1716 if (float_value == 0.0)
1718 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1720 else
1722 unsigned long exp, sign, mant, tmsfloat;
1723 tmsfloat = *((long *) &float_value);
1724 sign = tmsfloat & 0x80000000;
1725 mant = tmsfloat & 0x007FFFFF;
1726 exp = tmsfloat & 0x7F800000;
1727 exp <<= 1;
1728 if (exp == 0xFF000000)
1730 if (mant == 0)
1731 value = 0x7F7FFFFF;
1732 else if (sign == 0)
1733 value = 0x7F7FFFFF;
1734 else
1735 value = 0x7F800000;
1737 else
1739 exp -= 0x7F000000;
1740 if (sign)
1742 mant = mant & 0x007FFFFF;
1743 mant = -mant;
1744 mant = mant & 0x00FFFFFF;
1745 if (mant == 0)
1747 mant |= 0x00800000;
1748 exp = (long) exp - 0x01000000;
1751 tmsfloat = exp | mant;
1752 value = tmsfloat;
1754 if (prec == 2)
1756 long exp, mant;
1758 if (tmsfloat == 0x80000000)
1760 value = 0x8000;
1762 else
1764 value = 0;
1765 exp = (tmsfloat & 0xFF000000);
1766 exp >>= 24;
1767 mant = tmsfloat & 0x007FFFFF;
1768 if (tmsfloat & 0x00800000)
1770 mant |= 0xFF000000;
1771 mant += 0x00000800;
1772 mant >>= 12;
1773 mant |= 0x00000800;
1774 mant &= 0x0FFF;
1775 if (exp > 7)
1776 value = 0x7800;
1778 else
1780 mant |= 0x00800000;
1781 mant += 0x00000800;
1782 exp += (mant >> 24);
1783 mant >>= 12;
1784 mant &= 0x07FF;
1785 if (exp > 7)
1786 value = 0x77FF;
1788 if (exp < -8)
1789 value = 0x8000;
1790 if (value == 0)
1792 mant = (exp << 12) | mant;
1793 value = mant & 0xFFFF;
1798 md_number_to_chars (literalP, value, prec);
1799 *sizeP = prec;
1800 return 0;
1803 void
1804 md_number_to_chars (buf, val, n)
1805 char *buf;
1806 valueT val;
1807 int n;
1809 debug ("In md_number_to_chars()\n");
1810 number_to_chars_bigendian (buf, val, n);
1811 /* number_to_chars_littleendian(buf,val,n); */
1814 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1815 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1817 arelent *
1818 tc_gen_reloc (section, fixP)
1819 asection *section;
1820 fixS *fixP;
1822 arelent *rel;
1823 bfd_reloc_code_real_type code = 0;
1825 debug ("In tc_gen_reloc()\n");
1826 debug ("fixP.size = %d\n", fixP->fx_size);
1827 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1828 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1829 switch (F (fixP->fx_size, fixP->fx_pcrel))
1831 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1832 MAP (2, 0, BFD_RELOC_16);
1833 MAP (3, 0, BFD_RELOC_24);
1834 MAP (2, 1, BFD_RELOC_16_PCREL);
1835 MAP (4, 0, BFD_RELOC_32);
1836 default:
1837 as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
1838 fixP->fx_pcrel ? "pc-relative " : "");
1840 #undef MAP
1841 #undef F
1843 rel = (arelent *) xmalloc (sizeof (arelent));
1844 assert (rel != 0);
1845 rel->sym_ptr_ptr = &fixP->fx_addsy->bsym;
1846 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1847 if (fixP->fx_pcrel)
1848 rel->addend = fixP->fx_addnumber;
1849 else
1850 rel->addend = 0;
1851 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1852 if (!rel->howto)
1854 const char *name;
1855 name = S_GET_NAME (fixP->fx_addsy);
1856 if (name == NULL)
1857 name = "<unknown>";
1858 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
1860 return rel;
1863 void
1864 tc_aout_pre_write_hook ()
1866 debug ("In tc_aout_pre_write_hook()\n");
1869 void
1870 md_operand (expressionP)
1871 expressionS *expressionP;
1873 debug ("In md_operand()\n");
1876 char output_invalid_buf[8];
1878 char *
1879 output_invalid (c)
1880 char c;
1882 if (isprint (c))
1883 sprintf (output_invalid_buf, "'%c'", c);
1884 else
1885 sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
1886 return output_invalid_buf;