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