2003-11-22 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gas / config / tc-tic30.c
CommitLineData
252b5132 1/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
a161fe53 2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
252b5132
RH
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
19d63e5d 22/* Texas Instruments TMS320C30 machine specific gas.
252b5132
RH
23 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
24 Bugs & suggestions are completely welcome. This is free software.
19d63e5d 25 Please help us make it better. */
252b5132
RH
26
27#include "as.h"
3882b010 28#include "safe-ctype.h"
252b5132 29#include "opcode/tic30.h"
167795c4
AM
30#ifdef ANSI_PROTOTYPES
31#include <stdarg.h>
32#else
33#include <varargs.h>
34#endif
252b5132 35
19d63e5d
KH
36/* Put here all non-digit non-letter charcters that may occur in an
37 operand. */
252b5132 38static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
19d63e5d
KH
39static char *ordinal_names[] = {
40 "first", "second", "third", "fourth", "fifth"
41};
252b5132
RH
42
43const int md_reloc_size = 0;
44
45const char comment_chars[] = ";";
46const char line_comment_chars[] = "*";
47const char line_separator_chars[] = "";
48
49const char *md_shortopts = "";
19d63e5d 50struct option md_longopts[] = {
252b5132
RH
51 {NULL, no_argument, NULL, 0}
52};
53
54size_t md_longopts_size = sizeof (md_longopts);
55
19d63e5d 56/* Chars that mean this number is a floating point constant. */
252b5132
RH
57/* As in 0f12.456 */
58/* or 0d1.2345e12 */
59const char FLT_CHARS[] = "fFdDxX";
60
19d63e5d
KH
61/* Chars that can be used to separate mant from exp in floating point
62 nums. */
252b5132
RH
63const char EXP_CHARS[] = "eE";
64
65/* tables for lexical analysis */
66static char opcode_chars[256];
67static char register_chars[256];
68static char operand_chars[256];
69static char space_chars[256];
70static char identifier_chars[256];
71static 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
19d63e5d 81const pseudo_typeS md_pseudo_table[] = {
252b5132
RH
82 {0, 0, 0}
83};
84
167795c4 85int debug PARAMS ((const char *string, ...));
252b5132
RH
86
87int
167795c4 88debug VPARAMS ((const char *string, ...))
252b5132
RH
89{
90 if (flag_debug)
91 {
252b5132
RH
92 char str[100];
93
167795c4
AM
94 VA_OPEN (argptr, string);
95 VA_FIXEDARG (argptr, const char *, string);
252b5132 96 vsprintf (str, string, argptr);
167795c4 97 VA_CLOSE (argptr);
252b5132
RH
98 if (str[0] == '\0')
99 return (0);
252b5132
RH
100 fputs (str, USE_STDOUT ? stdout : stderr);
101 return strlen (str);
102 }
103 else
104 return 0;
105}
252b5132
RH
106
107/* hash table for opcode lookup */
108static struct hash_control *op_hash;
109/* hash table for parallel opcode lookup */
110static struct hash_control *parop_hash;
111/* hash table for register lookup */
112static struct hash_control *reg_hash;
113/* hash table for indirect addressing lookup */
114static struct hash_control *ind_hash;
115
116void
117md_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 {
3882b010 168 if (ISLOWER (c) || ISDIGIT (c))
252b5132
RH
169 {
170 opcode_chars[c] = c;
171 register_chars[c] = c;
172 }
3882b010 173 else if (ISUPPER (c))
252b5132 174 {
3882b010 175 opcode_chars[c] = TOLOWER (c);
252b5132
RH
176 register_chars[c] = opcode_chars[c];
177 }
178 else if (c == ')' || c == '(')
179 {
180 register_chars[c] = c;
181 }
3882b010 182 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
252b5132 183 operand_chars[c] = c;
3882b010 184 if (ISDIGIT (c) || c == '-')
252b5132 185 digit_chars[c] = c;
3882b010 186 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
252b5132
RH
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
19d63e5d 209typedef struct {
252b5132 210 unsigned op_type;
19d63e5d
KH
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;
252b5132
RH
235
236int tic30_parallel_insn PARAMS ((char *));
237operand *tic30_operand PARAMS ((char *));
238char *tic30_find_parallel_insn PARAMS ((char *, char *));
239
240template *opcode;
241
19d63e5d
KH
242struct tic30_insn {
243 template *tm; /* Template of current instruction */
244 unsigned opcode; /* Final opcode */
167795c4 245 unsigned int operands; /* Number of given operands */
19d63e5d
KH
246 /* Type of operand given in instruction */
247 operand *operand_type[MAX_OPERANDS];
248 unsigned addressing_mode; /* Final addressing mode of instruction */
249};
252b5132
RH
250
251struct tic30_insn insn;
252static int found_parallel_insn;
253
254void
255md_assemble (line)
256 char *line;
257{
258 template *opcode;
259 char *current_posn;
260 char *token_start;
261 char save_char;
167795c4 262 unsigned int count;
252b5132
RH
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
1dab94dd 285 character is a q. */
252b5132
RH
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 {
167795c4
AM
408 unsigned int i;
409 unsigned int numops = insn.tm->operands;
252b5132
RH
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
1dab94dd 412 the same, then give an error, otherwise carry on. */
252b5132
RH
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;
1dab94dd 433 /* Store instruction uses the second operand for the address mode. */
252b5132
RH
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 }
1dab94dd 452 /* Now set the addressing mode for 3 operand instructions. */
252b5132
RH
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
1dab94dd 456 G addressing field of the opcode. */
252b5132
RH
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
1dab94dd 490 and added to the frag table. */
252b5132
RH
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;
1dab94dd 517 /* Create frag for instruction - all instructions are 4 bytes long. */
252b5132
RH
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
1dab94dd 714 address into 8 bits. */
252b5132
RH
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 {
1dab94dd 758 /* Check for NOP instruction without arguments. */
252b5132
RH
759 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
760 }
761 else if (insn.tm->operands == 0)
762 {
1dab94dd 763 /* Check for instructions without operands. */
252b5132
RH
764 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
765 }
766 }
767 debug ("Addressing mode: %08X\n", insn.addressing_mode);
768 {
167795c4 769 unsigned int i;
252b5132
RH
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
19d63e5d 781struct tic30_par_insn {
252b5132 782 partemplate *tm; /* Template of current parallel instruction */
167795c4 783 unsigned operands[2]; /* Number of given operands for each insn */
252b5132
RH
784 /* Type of operand given in instruction */
785 operand *operand_type[2][MAX_OPERANDS];
1dab94dd 786 int swap_operands; /* Whether to swap operands around. */
252b5132
RH
787 unsigned p_field; /* Value of p field in multiply add/sub instructions */
788 unsigned opcode; /* Final opcode */
789};
790
791struct tic30_par_insn p_insn;
792
793int
794tic30_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};
167795c4 820 unsigned int i;
252b5132
RH
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 {
167795c4 994 unsigned int i;
252b5132
RH
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
1dab94dd 1006 references, but not in any particular place. */
252b5132
RH
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
1dab94dd 1076 addressing, so there are no labels to resolve. */
252b5132
RH
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 }
1dab94dd 1168 } /* Opcode is finalised at this point for all parallel instructions. */
252b5132
RH
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 {
167795c4 1175 unsigned int i, j;
252b5132
RH
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
1185operand *
1186tic30_operand (token)
1187 char *token;
1188{
167795c4 1189 unsigned int count;
252b5132
RH
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 */
3882b010 1247 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
252b5132
RH
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
1dab94dd 1270 the value and remove it from the buffer. */
252b5132
RH
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;
167795c4 1393 if (current_op->immediate.u_number <= 31)
252b5132
RH
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
1413char *
1414tic30_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");
b75c0c92 1426 while (!is_end_of_line[(unsigned char) *next_line])
252b5132
RH
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
b75c0c92 1462 while (!is_end_of_line[(unsigned char) (c = *line)])
252b5132
RH
1463 {
1464 if (is_opcode_char (c) && search_status == NONE)
1465 {
3882b010 1466 opcode[char_ptr++] = TOLOWER (c);
252b5132
RH
1467 search_status = START_OPCODE;
1468 }
1469 else if (is_opcode_char (c) && search_status == START_OPCODE)
1470 {
3882b010 1471 opcode[char_ptr++] = TOLOWER (c);
252b5132
RH
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,
1dab94dd 1510 this function returns true if a | is found in a line. */
252b5132
RH
1511
1512int
1513tic30_unrecognized_line (c)
1514 int c;
1515{
1516 debug ("In tc_unrecognized_line\n");
1517 return (c == PARALLEL_SEPARATOR);
1518}
1519
1520int
1521md_estimate_size_before_relax (fragP, segment)
167795c4
AM
1522 fragS *fragP ATTRIBUTE_UNUSED;
1523 segT segment ATTRIBUTE_UNUSED;
252b5132
RH
1524{
1525 debug ("In md_estimate_size_before_relax()\n");
1526 return 0;
1527}
1528
1529void
1530md_convert_frag (abfd, sec, fragP)
167795c4
AM
1531 bfd *abfd ATTRIBUTE_UNUSED;
1532 segT sec ATTRIBUTE_UNUSED;
1533 register fragS *fragP ATTRIBUTE_UNUSED;
252b5132
RH
1534{
1535 debug ("In md_convert_frag()\n");
1536}
1537
94f592af
NC
1538void
1539md_apply_fix3 (fixP, valP, seg)
252b5132
RH
1540 fixS *fixP;
1541 valueT *valP;
94f592af 1542 segT seg ATTRIBUTE_UNUSED;
252b5132
RH
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;
94f592af 1554
252b5132
RH
1555 value /= INSN_SIZE;
1556 if (fixP->fx_size == 1)
94f592af
NC
1557 /* Special fix for LDP instruction. */
1558 value = (value & 0x00FF0000) >> 16;
1559
252b5132
RH
1560 debug ("new value = %ld\n", (long) value);
1561 md_number_to_chars (buf, value, fixP->fx_size);
1562 }
94f592af
NC
1563
1564 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1565 fixP->fx_done = 1;
252b5132
RH
1566}
1567
1568int
1569md_parse_option (c, arg)
167795c4
AM
1570 int c ATTRIBUTE_UNUSED;
1571 char *arg ATTRIBUTE_UNUSED;
252b5132 1572{
252b5132 1573 debug ("In md_parse_option()\n");
252b5132
RH
1574 return 0;
1575}
1576
1577void
1578md_show_usage (stream)
167795c4 1579 FILE *stream ATTRIBUTE_UNUSED;
252b5132
RH
1580{
1581 debug ("In md_show_usage()\n");
1582}
1583
1584symbolS *
1585md_undefined_symbol (name)
167795c4 1586 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1587{
1588 debug ("In md_undefined_symbol()\n");
1589 return (symbolS *) 0;
1590}
1591
1592valueT
1593md_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
1604long
1605md_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
1dab94dd 1615 is a delayed one or not, and then set the offset value appropriately. */
252b5132
RH
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
1630char *
1631md_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;
252b5132
RH
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;
b75c0c92
AM
1646 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1647 && (*input_line_pointer != ','))
252b5132
RH
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
1765void
1766md_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
1779arelent *
1780tc_gen_reloc (section, fixP)
167795c4 1781 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
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);
310b5aa2
ILT
1807 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1808 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
252b5132 1809 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
a161fe53 1810 rel->addend = 0;
252b5132
RH
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
252b5132
RH
1823void
1824md_operand (expressionP)
167795c4 1825 expressionS *expressionP ATTRIBUTE_UNUSED;
252b5132
RH
1826{
1827 debug ("In md_operand()\n");
1828}
1829
1830char output_invalid_buf[8];
1831
1832char *
1833output_invalid (c)
1834 char c;
1835{
3882b010 1836 if (ISPRINT (c))
252b5132
RH
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.271908 seconds and 4 git commands to generate.