1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 /* Texas Instruments TMS320C30 machine specific gas.
24 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25 Bugs & suggestions are completely welcome. This is free software.
26 Please help us make it better. */
29 #include "safe-ctype.h"
30 #include "opcode/tic30.h"
31 #ifdef ANSI_PROTOTYPES
37 /* Put here all non-digit non-letter characters that may occur in an
39 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
40 static char *ordinal_names
[] = {
41 "first", "second", "third", "fourth", "fifth"
44 const int md_reloc_size
= 0;
46 const char comment_chars
[] = ";";
47 const char line_comment_chars
[] = "*";
48 const char line_separator_chars
[] = "";
50 const char *md_shortopts
= "";
51 struct option md_longopts
[] = {
52 {NULL
, no_argument
, NULL
, 0}
55 size_t md_longopts_size
= sizeof (md_longopts
);
57 /* Chars that mean this number is a floating point constant. */
60 const char FLT_CHARS
[] = "fFdDxX";
62 /* Chars that can be used to separate mant from exp in floating point
64 const char EXP_CHARS
[] = "eE";
66 /* tables for lexical analysis */
67 static char opcode_chars
[256];
68 static char register_chars
[256];
69 static char operand_chars
[256];
70 static char space_chars
[256];
71 static char identifier_chars
[256];
72 static char digit_chars
[256];
75 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
76 #define is_operand_char(x) (operand_chars[(unsigned char) x])
77 #define is_register_char(x) (register_chars[(unsigned char) x])
78 #define is_space_char(x) (space_chars[(unsigned char) x])
79 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
80 #define is_digit_char(x) (digit_chars[(unsigned char) x])
82 const pseudo_typeS md_pseudo_table
[] = {
86 int debug
PARAMS ((const char *string
, ...));
89 debug
VPARAMS ((const char *string
, ...))
95 VA_OPEN (argptr
, string
);
96 VA_FIXEDARG (argptr
, const char *, string
);
97 vsprintf (str
, string
, argptr
);
101 fputs (str
, USE_STDOUT
? stdout
: stderr
);
108 /* hash table for opcode lookup */
109 static struct hash_control
*op_hash
;
110 /* hash table for parallel opcode lookup */
111 static struct hash_control
*parop_hash
;
112 /* hash table for register lookup */
113 static struct hash_control
*reg_hash
;
114 /* hash table for indirect addressing lookup */
115 static struct hash_control
*ind_hash
;
120 const char *hash_err
;
121 debug ("In md_begin()\n");
122 op_hash
= hash_new ();
124 const template *current_optab
= tic30_optab
;
125 for (; current_optab
< tic30_optab_end
; current_optab
++)
127 hash_err
= hash_insert (op_hash
, current_optab
->name
, (char *) current_optab
);
129 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab
->name
, hash_err
);
132 parop_hash
= hash_new ();
134 const partemplate
*current_parop
= tic30_paroptab
;
135 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
137 hash_err
= hash_insert (parop_hash
, current_parop
->name
, (char *) current_parop
);
139 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop
->name
, hash_err
);
142 reg_hash
= hash_new ();
144 const reg
*current_reg
= tic30_regtab
;
145 for (; current_reg
< tic30_regtab_end
; current_reg
++)
147 hash_err
= hash_insert (reg_hash
, current_reg
->name
, (char *) current_reg
);
149 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg
->name
, hash_err
);
152 ind_hash
= hash_new ();
154 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
155 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
157 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
, (char *) current_ind
);
159 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind
->syntax
, hash_err
);
162 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
167 for (c
= 0; c
< 256; c
++)
169 if (ISLOWER (c
) || ISDIGIT (c
))
172 register_chars
[c
] = c
;
174 else if (ISUPPER (c
))
176 opcode_chars
[c
] = TOLOWER (c
);
177 register_chars
[c
] = opcode_chars
[c
];
179 else if (c
== ')' || c
== '(')
181 register_chars
[c
] = c
;
183 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
184 operand_chars
[c
] = c
;
185 if (ISDIGIT (c
) || c
== '-')
187 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
188 identifier_chars
[c
] = c
;
189 if (c
== ' ' || c
== '\t')
194 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
195 operand_chars
[(unsigned char) *p
] = *p
;
199 /* Address Mode OR values */
200 #define AM_Register 0x00000000
201 #define AM_Direct 0x00200000
202 #define AM_Indirect 0x00400000
203 #define AM_Immediate 0x00600000
204 #define AM_NotReq 0xFFFFFFFF
206 /* PC Relative OR values */
207 #define PC_Register 0x00000000
208 #define PC_Relative 0x02000000
216 expressionS direct_expr
;
231 unsigned int u_number
;
233 expressionS imm_expr
;
237 int tic30_parallel_insn
PARAMS ((char *));
238 operand
*tic30_operand
PARAMS ((char *));
239 char *tic30_find_parallel_insn
PARAMS ((char *, char *));
244 template *tm
; /* Template of current instruction */
245 unsigned opcode
; /* Final opcode */
246 unsigned int operands
; /* Number of given operands */
247 /* Type of operand given in instruction */
248 operand
*operand_type
[MAX_OPERANDS
];
249 unsigned addressing_mode
; /* Final addressing mode of instruction */
252 struct tic30_insn insn
;
253 static int found_parallel_insn
;
265 debug ("In md_assemble() with argument %s\n", line
);
266 memset (&insn
, '\0', sizeof (insn
));
267 if (found_parallel_insn
)
269 debug ("Line is second part of parallel instruction\n\n");
270 found_parallel_insn
= 0;
273 if ((current_posn
= tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
276 found_parallel_insn
= 1;
277 while (is_space_char (*current_posn
))
279 token_start
= current_posn
;
280 if (!is_opcode_char (*current_posn
))
282 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn
));
285 /* Check if instruction is a parallel instruction by seeing if the first
287 if (*token_start
== 'q')
289 if (tic30_parallel_insn (token_start
))
291 if (found_parallel_insn
)
296 while (is_opcode_char (*current_posn
))
298 { /* Find instruction */
299 save_char
= *current_posn
;
300 *current_posn
= '\0';
301 opcode
= (template *) hash_find (op_hash
, token_start
);
304 debug ("Found instruction %s\n", opcode
->name
);
309 debug ("Didn't find insn\n");
310 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
313 *current_posn
= save_char
;
315 if (*current_posn
!= END_OF_INSN
)
316 { /* Find operands */
317 int paren_not_balanced
;
318 int expecting_operand
= 0;
322 /* skip optional white space before operand */
323 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
325 if (!is_space_char (*current_posn
))
327 as_bad ("Invalid character %s before %s operand",
328 output_invalid (*current_posn
),
329 ordinal_names
[insn
.operands
]);
334 token_start
= current_posn
; /* after white space */
335 paren_not_balanced
= 0;
336 while (paren_not_balanced
|| *current_posn
!= ',')
338 if (*current_posn
== END_OF_INSN
)
340 if (paren_not_balanced
)
342 as_bad ("Unbalanced parenthesis in %s operand.",
343 ordinal_names
[insn
.operands
]);
347 break; /* we are done */
349 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
351 as_bad ("Invalid character %s in %s operand",
352 output_invalid (*current_posn
),
353 ordinal_names
[insn
.operands
]);
356 if (*current_posn
== '(')
357 ++paren_not_balanced
;
358 if (*current_posn
== ')')
359 --paren_not_balanced
;
362 if (current_posn
!= token_start
)
363 { /* yes, we've read in another operand */
364 this_operand
= insn
.operands
++;
365 if (insn
.operands
> MAX_OPERANDS
)
367 as_bad ("Spurious operands; (%d operands/instruction max)",
371 /* now parse operand adding info to 'insn' as we go along */
372 save_char
= *current_posn
;
373 *current_posn
= '\0';
374 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
375 *current_posn
= save_char
;
376 if (insn
.operand_type
[this_operand
] == NULL
)
381 if (expecting_operand
)
383 as_bad ("Expecting operand after ','; got nothing");
386 if (*current_posn
== ',')
388 as_bad ("Expecting operand before ','; got nothing");
392 /* now *current_posn must be either ',' or END_OF_INSN */
393 if (*current_posn
== ',')
395 if (*++current_posn
== END_OF_INSN
)
396 { /* just skip it, if it's \n complain */
397 as_bad ("Expecting operand after ','; got nothing");
400 expecting_operand
= 1;
403 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
405 debug ("Number of operands found: %d\n", insn
.operands
);
406 /* Check that number of operands is correct */
407 if (insn
.operands
!= insn
.tm
->operands
)
410 unsigned int numops
= insn
.tm
->operands
;
411 /* If operands are not the same, then see if any of the operands are not
412 required. Then recheck with number of given operands. If they are still not
413 the same, then give an error, otherwise carry on. */
414 for (i
= 0; i
< insn
.tm
->operands
; i
++)
415 if (insn
.tm
->operand_types
[i
] & NotReq
)
417 if (insn
.operands
!= numops
)
419 as_bad ("Incorrect number of operands given");
423 insn
.addressing_mode
= AM_NotReq
;
424 for (count
= 0; count
< insn
.operands
; count
++)
426 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
428 debug ("Operand %d matches\n", count
+ 1);
429 /* If instruction has two operands and has an AddressMode modifier then set
430 addressing mode type for instruction */
431 if (insn
.tm
->opcode_modifier
== AddressMode
)
434 /* Store instruction uses the second operand for the address mode. */
435 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
)) == (Indirect
| Direct
))
437 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
438 insn
.addressing_mode
= AM_Register
;
439 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
440 insn
.addressing_mode
= AM_Direct
;
441 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
442 insn
.addressing_mode
= AM_Indirect
;
444 insn
.addressing_mode
= AM_Immediate
;
449 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
453 /* Now set the addressing mode for 3 operand instructions. */
454 if ((insn
.tm
->operand_types
[0] & op3T1
) && (insn
.tm
->operand_types
[1] & op3T2
))
456 /* Set the addressing mode to the values used for 2 operand instructions in the
457 G addressing field of the opcode. */
459 switch (insn
.operand_type
[0]->op_type
)
465 if (insn
.operand_type
[1]->op_type
& (AllReg
))
466 insn
.addressing_mode
= AM_Register
;
467 else if (insn
.operand_type
[1]->op_type
& Indirect
)
468 insn
.addressing_mode
= AM_Direct
;
471 /* Shouldn't make it to this stage */
472 as_bad ("Incompatible first and second operands in instruction");
477 if (insn
.operand_type
[1]->op_type
& (AllReg
))
478 insn
.addressing_mode
= AM_Indirect
;
479 else if (insn
.operand_type
[1]->op_type
& Indirect
)
480 insn
.addressing_mode
= AM_Immediate
;
483 /* Shouldn't make it to this stage */
484 as_bad ("Incompatible first and second operands in instruction");
489 /* Now make up the opcode for the 3 operand instructions. As in parallel
490 instructions, there will be no unresolved values, so they can be fully formed
491 and added to the frag table. */
492 insn
.opcode
= insn
.tm
->base_opcode
;
493 if (insn
.operand_type
[0]->op_type
& Indirect
)
495 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
496 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
499 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
500 if (insn
.operand_type
[1]->op_type
& Indirect
)
502 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
503 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
506 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
507 if (insn
.operands
== 3)
508 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
509 insn
.opcode
|= insn
.addressing_mode
;
510 p
= frag_more (INSN_SIZE
);
511 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
514 { /* Not a three operand instruction */
517 insn
.opcode
= insn
.tm
->base_opcode
;
518 /* Create frag for instruction - all instructions are 4 bytes long. */
519 p
= frag_more (INSN_SIZE
);
520 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
522 insn
.opcode
|= insn
.addressing_mode
;
523 if (insn
.addressing_mode
== AM_Indirect
)
525 /* Determine which operand gives the addressing mode */
526 if (insn
.operand_type
[0]->op_type
& Indirect
)
528 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Indirect
))
530 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
531 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
532 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
533 if (insn
.operands
> 1)
534 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
535 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
537 else if (insn
.addressing_mode
== AM_Register
)
539 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
540 if (insn
.operands
> 1)
541 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
542 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
544 else if (insn
.addressing_mode
== AM_Direct
)
546 if (insn
.operand_type
[0]->op_type
& Direct
)
548 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Direct
))
550 if (insn
.operands
> 1)
551 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
552 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
554 /* Resolved values can be placed straight into instruction word, and output */
555 insn
.opcode
|= (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
556 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
559 { /* Unresolved direct addressing mode instruction */
560 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
561 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[am_insn
]->direct
.direct_expr
, 0, 0);
564 else if (insn
.addressing_mode
== AM_Immediate
)
566 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
570 if (insn
.operands
> 1)
571 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
572 switch (insn
.tm
->imm_arg_type
)
575 debug ("Floating point first operand\n");
576 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
577 keeploc
= input_line_pointer
;
578 input_line_pointer
= insn
.operand_type
[0]->immediate
.label
;
579 if (md_atof ('f', p
+ 2, &size
) != 0)
581 as_bad ("invalid short form floating point immediate operand");
584 input_line_pointer
= keeploc
;
587 debug ("Unsigned int first operand\n");
588 if (insn
.operand_type
[0]->immediate
.decimal_found
)
589 as_warn ("rounding down first operand float to unsigned int");
590 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
591 as_warn ("only lower 16-bits of first operand are used");
592 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
593 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
596 debug ("Int first operand\n");
597 if (insn
.operand_type
[0]->immediate
.decimal_found
)
598 as_warn ("rounding down first operand float to signed int");
599 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
600 insn
.operand_type
[0]->immediate
.s_number
> 32767)
602 as_bad ("first operand is too large for 16-bit signed int");
605 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
606 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
611 { /* Unresolved immediate label */
612 if (insn
.operands
> 1)
613 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
614 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
615 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
619 else if (insn
.tm
->opcode_modifier
== PCRel
)
621 /* Conditional Branch and Call instructions */
622 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
)) == (AllReg
| Disp
))
624 if (insn
.operand_type
[0]->op_type
& (AllReg
))
626 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
627 insn
.opcode
|= PC_Register
;
628 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
632 insn
.opcode
|= PC_Relative
;
633 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
635 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
636 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
640 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
641 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 1, 0);
645 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
647 /* Decrement and Branch instructions */
648 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
649 if (insn
.operand_type
[1]->op_type
& (AllReg
))
651 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
652 insn
.opcode
|= PC_Register
;
653 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
655 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
657 if (insn
.operand_type
[0]->immediate
.decimal_found
)
659 as_bad ("first operand is floating point");
662 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
663 insn
.operand_type
[0]->immediate
.s_number
> 32767)
665 as_bad ("first operand is too large for 16-bit signed int");
668 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
669 insn
.opcode
|= PC_Relative
;
670 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
674 insn
.opcode
|= PC_Relative
;
675 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
676 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2, &insn
.operand_type
[1]->immediate
.imm_expr
, 1, 0);
680 else if (insn
.tm
->operand_types
[0] == IVector
)
682 /* Trap instructions */
683 if (insn
.operand_type
[0]->op_type
& IVector
)
684 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
686 { /* Shouldn't get here */
687 as_bad ("interrupt vector for trap instruction out of range");
690 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
692 else if (insn
.tm
->opcode_modifier
== StackOp
|| insn
.tm
->opcode_modifier
== Rotate
)
694 /* Push, Pop and Rotate instructions */
695 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
696 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
698 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
)) == (Abs24
| Direct
))
700 /* LDP Instruction needs to be tested for before the next section */
701 if (insn
.operand_type
[0]->op_type
& Direct
)
703 if (insn
.operand_type
[0]->direct
.resolved
== 1)
705 /* Direct addressing uses lower 8 bits of direct address */
706 insn
.opcode
|= (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
707 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
712 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
713 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
714 /* Ensure that the assembler doesn't complain about fitting a 24-bit
715 address into 8 bits. */
716 fix
->fx_no_overflow
= 1;
721 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
723 /* Immediate addressing uses upper 8 bits of address */
724 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
726 as_bad ("LDP instruction needs a 24-bit operand");
729 insn
.opcode
|= ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
730 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
735 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
736 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
737 fix
->fx_no_overflow
= 1;
741 else if (insn
.tm
->operand_types
[0] & (Imm24
))
743 /* Unconditional Branch and Call instructions */
744 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
746 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
747 as_warn ("first operand is too large for a 24-bit displacement");
748 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
749 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
753 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
754 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
757 else if (insn
.tm
->operand_types
[0] & NotReq
)
759 /* Check for NOP instruction without arguments. */
760 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
762 else if (insn
.tm
->operands
== 0)
764 /* Check for instructions without operands. */
765 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
768 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
771 for (i
= 0; i
< insn
.operands
; i
++)
773 if (insn
.operand_type
[i
]->immediate
.label
)
774 free (insn
.operand_type
[i
]->immediate
.label
);
775 free (insn
.operand_type
[i
]);
778 debug ("Final opcode: %08X\n", insn
.opcode
);
782 struct tic30_par_insn
{
783 partemplate
*tm
; /* Template of current parallel instruction */
784 unsigned operands
[2]; /* Number of given operands for each insn */
785 /* Type of operand given in instruction */
786 operand
*operand_type
[2][MAX_OPERANDS
];
787 int swap_operands
; /* Whether to swap operands around. */
788 unsigned p_field
; /* Value of p field in multiply add/sub instructions */
789 unsigned opcode
; /* Final opcode */
792 struct tic30_par_insn p_insn
;
795 tic30_parallel_insn (char *token
)
797 static partemplate
*p_opcode
;
798 char *current_posn
= token
;
802 debug ("In tic30_parallel_insn with %s\n", token
);
803 memset (&p_insn
, '\0', sizeof (p_insn
));
804 while (is_opcode_char (*current_posn
))
806 { /* Find instruction */
807 save_char
= *current_posn
;
808 *current_posn
= '\0';
809 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
812 debug ("Found instruction %s\n", p_opcode
->name
);
813 p_insn
.tm
= p_opcode
;
817 char first_opcode
[6] =
819 char second_opcode
[6] =
822 int current_opcode
= -1;
825 for (i
= 0; i
< strlen (token
); i
++)
827 char ch
= *(token
+ i
);
828 if (ch
== '_' && current_opcode
== -1)
833 if (ch
== '_' && current_opcode
== 0)
839 switch (current_opcode
)
842 first_opcode
[char_ptr
++] = ch
;
845 second_opcode
[char_ptr
++] = ch
;
849 debug ("first_opcode = %s\n", first_opcode
);
850 debug ("second_opcode = %s\n", second_opcode
);
851 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
852 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
855 debug ("Found instruction %s\n", p_opcode
->name
);
856 p_insn
.tm
= p_opcode
;
857 p_insn
.swap_operands
= 1;
862 *current_posn
= save_char
;
864 { /* Find operands */
865 int paren_not_balanced
;
866 int expecting_operand
= 0;
867 int found_separator
= 0;
870 /* skip optional white space before operand */
871 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
873 if (!is_space_char (*current_posn
) && *current_posn
!= PARALLEL_SEPARATOR
)
875 as_bad ("Invalid character %s before %s operand",
876 output_invalid (*current_posn
),
877 ordinal_names
[insn
.operands
]);
880 if (*current_posn
== PARALLEL_SEPARATOR
)
884 token_start
= current_posn
; /* after white space */
885 paren_not_balanced
= 0;
886 while (paren_not_balanced
|| *current_posn
!= ',')
888 if (*current_posn
== END_OF_INSN
)
890 if (paren_not_balanced
)
892 as_bad ("Unbalanced parenthesis in %s operand.",
893 ordinal_names
[insn
.operands
]);
897 break; /* we are done */
899 else if (*current_posn
== PARALLEL_SEPARATOR
)
901 while (is_space_char (*(current_posn
- 1)))
905 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
907 as_bad ("Invalid character %s in %s operand",
908 output_invalid (*current_posn
),
909 ordinal_names
[insn
.operands
]);
912 if (*current_posn
== '(')
913 ++paren_not_balanced
;
914 if (*current_posn
== ')')
915 --paren_not_balanced
;
918 if (current_posn
!= token_start
)
919 { /* yes, we've read in another operand */
920 p_insn
.operands
[found_separator
]++;
921 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
923 as_bad ("Spurious operands; (%d operands/instruction max)",
927 /* now parse operand adding info to 'insn' as we go along */
928 save_char
= *current_posn
;
929 *current_posn
= '\0';
930 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
931 tic30_operand (token_start
);
932 *current_posn
= save_char
;
933 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
938 if (expecting_operand
)
940 as_bad ("Expecting operand after ','; got nothing");
943 if (*current_posn
== ',')
945 as_bad ("Expecting operand before ','; got nothing");
949 /* now *current_posn must be either ',' or END_OF_INSN */
950 if (*current_posn
== ',')
952 if (*++current_posn
== END_OF_INSN
)
953 { /* just skip it, if it's \n complain */
954 as_bad ("Expecting operand after ','; got nothing");
957 expecting_operand
= 1;
960 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
962 if (p_insn
.swap_operands
)
967 temp_num
= p_insn
.operands
[0];
968 p_insn
.operands
[0] = p_insn
.operands
[1];
969 p_insn
.operands
[1] = temp_num
;
970 for (i
= 0; i
< MAX_OPERANDS
; i
++)
972 temp_op
= p_insn
.operand_type
[0][i
];
973 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
974 p_insn
.operand_type
[1][i
] = temp_op
;
977 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
979 as_bad ("incorrect number of operands given in the first instruction");
982 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
984 as_bad ("incorrect number of operands given in the second instruction");
987 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
988 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
989 { /* Now check if operands are correct */
993 for (count
= 0; count
< 2; count
++)
996 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
998 if ((p_insn
.operand_type
[count
][i
]->op_type
&
999 p_insn
.tm
->operand_types
[count
][i
]) == 0)
1001 as_bad ("%s instruction, operand %d doesn't match", ordinal_names
[count
], i
+ 1);
1004 /* Get number of R register and indirect reference contained within the first
1005 two operands of each instruction. This is required for the multiply
1006 parallel instructions which require two R registers and two indirect
1007 references, but not in any particular place. */
1008 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
1010 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
) && i
< 2)
1014 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
)) == (Indirect
| Rn
))
1016 /* Check for the multiply instructions */
1019 as_bad ("incorrect format for multiply parallel instruction");
1023 { /* Shouldn't get here */
1024 as_bad ("incorrect format for multiply parallel instruction");
1027 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00) &&
1028 (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
1030 as_bad ("destination for multiply can only be R0 or R1");
1033 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02) &&
1034 (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
1036 as_bad ("destination for add/subtract can only be R2 or R3");
1039 /* Now determine the P field for the instruction */
1040 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
1042 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
1043 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn */
1044 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1045 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn */
1047 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind */
1051 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
1052 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind */
1053 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1056 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn */
1057 /* Need to swap the two multiply operands around so that everything is in
1058 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1059 temp
= p_insn
.operand_type
[0][0];
1060 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1061 p_insn
.operand_type
[0][1] = temp
;
1066 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind */
1067 temp
= p_insn
.operand_type
[0][0];
1068 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1069 p_insn
.operand_type
[0][1] = temp
;
1074 debug ("P field: %08X\n", p_insn
.p_field
);
1075 /* Finalise opcode. This is easier for parallel instructions as they have to be
1076 fully resolved, there are no memory addresses allowed, except through indirect
1077 addressing, so there are no labels to resolve. */
1079 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
1080 switch (p_insn
.tm
->oporder
)
1083 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1084 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1085 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1086 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1087 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1088 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1091 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1092 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1093 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1094 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1095 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1096 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1097 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1098 as_warn ("loading the same register in parallel operation");
1101 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1102 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1103 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1104 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1105 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1106 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1109 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1110 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1111 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1112 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1113 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1114 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1115 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1118 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1119 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1120 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1121 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1122 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1123 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1124 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1127 p_insn
.opcode
|= p_insn
.p_field
;
1128 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1129 p_insn
.opcode
|= 0x00800000;
1130 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1131 p_insn
.opcode
|= 0x00400000;
1132 switch (p_insn
.p_field
)
1135 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1136 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1137 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1138 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1139 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1140 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1143 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1144 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1145 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1146 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1147 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1148 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1151 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1152 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1153 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1154 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1155 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1156 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1159 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1160 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1161 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1162 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1163 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1164 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1169 } /* Opcode is finalised at this point for all parallel instructions. */
1170 { /* Output opcode */
1172 p
= frag_more (INSN_SIZE
);
1173 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1177 for (i
= 0; i
< 2; i
++)
1178 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1179 free (p_insn
.operand_type
[i
][j
]);
1181 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1187 tic30_operand (token
)
1191 char ind_buffer
[strlen (token
)];
1192 operand
*current_op
;
1194 debug ("In tic30_operand with %s\n", token
);
1195 current_op
= (operand
*) malloc (sizeof (operand
));
1196 memset (current_op
, '\0', sizeof (operand
));
1197 if (*token
== DIRECT_REFERENCE
)
1199 char *token_posn
= token
+ 1;
1200 int direct_label
= 0;
1201 debug ("Found direct reference\n");
1204 if (!is_digit_char (*token_posn
))
1210 char *save_input_line_pointer
;
1212 debug ("Direct reference is a label\n");
1213 current_op
->direct
.label
= token
+ 1;
1214 save_input_line_pointer
= input_line_pointer
;
1215 input_line_pointer
= token
+ 1;
1216 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1217 retval
= expression (¤t_op
->direct
.direct_expr
);
1218 debug ("Expression type: %d\n", current_op
->direct
.direct_expr
.X_op
);
1219 debug ("Expression addnum: %d\n", current_op
->direct
.direct_expr
.X_add_number
);
1220 debug ("Segment: %d\n", retval
);
1221 input_line_pointer
= save_input_line_pointer
;
1222 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
1224 current_op
->direct
.address
= current_op
->direct
.direct_expr
.X_add_number
;
1225 current_op
->direct
.resolved
= 1;
1230 debug ("Direct reference is a number\n");
1231 current_op
->direct
.address
= atoi (token
+ 1);
1232 current_op
->direct
.resolved
= 1;
1234 current_op
->op_type
= Direct
;
1236 else if (*token
== INDIRECT_REFERENCE
)
1237 { /* Indirect reference operand */
1241 int disp_number
= 0;
1242 int buffer_posn
= 1;
1243 ind_addr_type
*ind_addr_op
;
1244 debug ("Found indirect reference\n");
1245 ind_buffer
[0] = *token
;
1246 for (count
= 1; count
< strlen (token
); count
++)
1247 { /* Strip operand */
1248 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
1249 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A') &&
1250 (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
1252 /* AR reference is found, so get its number and remove it from the buffer
1253 so it can pass through hash_find() */
1256 as_bad ("More than one AR register found in indirect reference");
1259 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
1261 as_bad ("Illegal AR register in indirect reference");
1264 ar_number
= *(token
+ count
+ 1) - '0';
1268 if (*(token
+ count
) == '(')
1270 /* Parenthesis found, so check if a displacement value is inside. If so, get
1271 the value and remove it from the buffer. */
1272 if (is_digit_char (*(token
+ count
+ 1)))
1279 as_bad ("More than one displacement found in indirect reference");
1283 while (*(token
+ count
) != ')')
1285 if (!is_digit_char (*(token
+ count
)))
1287 as_bad ("Invalid displacement in indirect reference");
1290 disp
[disp_posn
++] = *(token
+ (count
++));
1292 disp
[disp_posn
] = '\0';
1293 disp_number
= atoi (disp
);
1300 ind_buffer
[buffer_posn
] = '\0';
1303 as_bad ("AR register not found in indirect reference");
1306 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
1309 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
1310 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
1315 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
1317 /* Maybe an implied displacement of 1 again */
1318 as_bad ("required displacement wasn't given in indirect reference");
1324 as_bad ("illegal indirect reference");
1327 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
1329 as_bad ("displacement must be an unsigned 8-bit number");
1332 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
1333 current_op
->indirect
.disp
= disp_number
;
1334 current_op
->indirect
.ARnum
= ar_number
;
1335 current_op
->op_type
= Indirect
;
1339 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
1342 debug ("Found register operand: %s\n", regop
->name
);
1343 if (regop
->regtype
== REG_ARn
)
1344 current_op
->op_type
= ARn
;
1345 else if (regop
->regtype
== REG_Rn
)
1346 current_op
->op_type
= Rn
;
1347 else if (regop
->regtype
== REG_DP
)
1348 current_op
->op_type
= DPReg
;
1350 current_op
->op_type
= OtherReg
;
1351 current_op
->reg
.opcode
= regop
->opcode
;
1355 if (!is_digit_char (*token
) || *(token
+ 1) == 'x' || strchr (token
, 'h'))
1357 char *save_input_line_pointer
;
1359 debug ("Probably a label: %s\n", token
);
1360 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1361 strcpy (current_op
->immediate
.label
, token
);
1362 current_op
->immediate
.label
[strlen (token
)] = '\0';
1363 save_input_line_pointer
= input_line_pointer
;
1364 input_line_pointer
= token
;
1365 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1366 retval
= expression (¤t_op
->immediate
.imm_expr
);
1367 debug ("Expression type: %d\n", current_op
->immediate
.imm_expr
.X_op
);
1368 debug ("Expression addnum: %d\n", current_op
->immediate
.imm_expr
.X_add_number
);
1369 debug ("Segment: %d\n", retval
);
1370 input_line_pointer
= save_input_line_pointer
;
1371 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
1373 current_op
->immediate
.s_number
= current_op
->immediate
.imm_expr
.X_add_number
;
1374 current_op
->immediate
.u_number
= (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
1375 current_op
->immediate
.resolved
= 1;
1381 debug ("Found a number or displacement\n");
1382 for (count
= 0; count
< strlen (token
); count
++)
1383 if (*(token
+ count
) == '.')
1384 current_op
->immediate
.decimal_found
= 1;
1385 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1386 strcpy (current_op
->immediate
.label
, token
);
1387 current_op
->immediate
.label
[strlen (token
)] = '\0';
1388 current_op
->immediate
.f_number
= (float) atof (token
);
1389 current_op
->immediate
.s_number
= (int) atoi (token
);
1390 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
1391 current_op
->immediate
.resolved
= 1;
1393 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
1394 if (current_op
->immediate
.u_number
<= 31)
1395 current_op
->op_type
|= IVector
;
1401 /* next_line points to the next line after the current instruction (current_line).
1402 Search for the parallel bars, and if found, merge two lines into internal syntax
1403 for a parallel instruction:
1404 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1405 By this stage, all comments are scrubbed, and only the bare lines are given.
1409 #define START_OPCODE 1
1410 #define END_OPCODE 2
1411 #define START_OPERANDS 3
1412 #define END_OPERANDS 4
1415 tic30_find_parallel_insn (current_line
, next_line
)
1419 int found_parallel
= 0;
1420 char first_opcode
[256];
1421 char second_opcode
[256];
1422 char first_operands
[256];
1423 char second_operands
[256];
1424 char *parallel_insn
;
1426 debug ("In tic30_find_parallel_insn()\n");
1427 while (!is_end_of_line
[(unsigned char) *next_line
])
1429 if (*next_line
== PARALLEL_SEPARATOR
&& *(next_line
+ 1) == PARALLEL_SEPARATOR
)
1437 if (!found_parallel
)
1439 debug ("Found a parallel instruction\n");
1442 char *opcode
, *operands
, *line
;
1444 for (i
= 0; i
< 2; i
++)
1448 opcode
= &first_opcode
[0];
1449 operands
= &first_operands
[0];
1450 line
= current_line
;
1454 opcode
= &second_opcode
[0];
1455 operands
= &second_operands
[0];
1459 int search_status
= NONE
;
1463 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
1465 if (is_opcode_char (c
) && search_status
== NONE
)
1467 opcode
[char_ptr
++] = TOLOWER (c
);
1468 search_status
= START_OPCODE
;
1470 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
1472 opcode
[char_ptr
++] = TOLOWER (c
);
1474 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
1476 opcode
[char_ptr
] = '\0';
1478 search_status
= END_OPCODE
;
1480 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
1482 operands
[char_ptr
++] = c
;
1484 if (is_operand_char (c
) && search_status
== END_OPCODE
)
1486 operands
[char_ptr
++] = c
;
1487 search_status
= START_OPERANDS
;
1491 if (search_status
!= START_OPERANDS
)
1493 operands
[char_ptr
] = '\0';
1497 parallel_insn
= (char *) malloc (strlen (first_opcode
) + strlen (first_operands
) +
1498 strlen (second_opcode
) + strlen (second_operands
) + 8);
1499 sprintf (parallel_insn
, "q_%s_%s %s | %s", first_opcode
, second_opcode
, first_operands
, second_operands
);
1500 debug ("parallel insn = %s\n", parallel_insn
);
1501 return parallel_insn
;
1507 #undef START_OPERANDS
1510 /* In order to get gas to ignore any | chars at the start of a line,
1511 this function returns true if a | is found in a line. */
1514 tic30_unrecognized_line (c
)
1517 debug ("In tc_unrecognized_line\n");
1518 return (c
== PARALLEL_SEPARATOR
);
1522 md_estimate_size_before_relax (fragP
, segment
)
1523 fragS
*fragP ATTRIBUTE_UNUSED
;
1524 segT segment ATTRIBUTE_UNUSED
;
1526 debug ("In md_estimate_size_before_relax()\n");
1531 md_convert_frag (abfd
, sec
, fragP
)
1532 bfd
*abfd ATTRIBUTE_UNUSED
;
1533 segT sec ATTRIBUTE_UNUSED
;
1534 register fragS
*fragP ATTRIBUTE_UNUSED
;
1536 debug ("In md_convert_frag()\n");
1540 md_apply_fix3 (fixP
, valP
, seg
)
1543 segT seg ATTRIBUTE_UNUSED
;
1545 valueT value
= *valP
;
1547 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1548 debug ("Values in fixP\n");
1549 debug ("fx_size = %d\n", fixP
->fx_size
);
1550 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1551 debug ("fx_where = %d\n", fixP
->fx_where
);
1552 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1554 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1557 if (fixP
->fx_size
== 1)
1558 /* Special fix for LDP instruction. */
1559 value
= (value
& 0x00FF0000) >> 16;
1561 debug ("new value = %ld\n", (long) value
);
1562 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1565 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1570 md_parse_option (c
, arg
)
1571 int c ATTRIBUTE_UNUSED
;
1572 char *arg ATTRIBUTE_UNUSED
;
1574 debug ("In md_parse_option()\n");
1579 md_show_usage (stream
)
1580 FILE *stream ATTRIBUTE_UNUSED
;
1582 debug ("In md_show_usage()\n");
1586 md_undefined_symbol (name
)
1587 char *name ATTRIBUTE_UNUSED
;
1589 debug ("In md_undefined_symbol()\n");
1590 return (symbolS
*) 0;
1594 md_section_align (segment
, size
)
1598 debug ("In md_section_align() segment = %d and size = %d\n", segment
, size
);
1599 size
= (size
+ 3) / 4;
1601 debug ("New size value = %d\n", size
);
1606 md_pcrel_from (fixP
)
1611 debug ("In md_pcrel_from()\n");
1612 debug ("fx_where = %d\n", fixP
->fx_where
);
1613 debug ("fx_size = %d\n", fixP
->fx_size
);
1614 /* Find the opcode that represents the current instruction in the fr_literal
1615 storage area, and check bit 21. Bit 21 contains whether the current instruction
1616 is a delayed one or not, and then set the offset value appropriately. */
1617 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1621 debug ("offset = %d\n", offset
);
1622 /* PC Relative instructions have a format:
1623 displacement = Label - (PC + offset)
1624 This function returns PC + offset where:
1625 fx_where - fx_size = PC
1626 INSN_SIZE * offset = offset number of instructions
1628 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1632 md_atof (what_statement_type
, literalP
, sizeP
)
1633 int what_statement_type
;
1640 unsigned long value
;
1642 debug ("In md_atof()\n");
1643 debug ("precision = %c\n", what_statement_type
);
1644 debug ("literal = %s\n", literalP
);
1646 token
= input_line_pointer
;
1647 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1648 && (*input_line_pointer
!= ','))
1650 debug ("%c", *input_line_pointer
);
1651 input_line_pointer
++;
1653 keepval
= *input_line_pointer
;
1654 *input_line_pointer
= '\0';
1656 float_value
= (float) atof (token
);
1657 *input_line_pointer
= keepval
;
1658 debug ("float_value = %f\n", float_value
);
1659 switch (what_statement_type
)
1677 return "Bad call to MD_ATOF()";
1679 if (float_value
== 0.0)
1681 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1685 unsigned long exp
, sign
, mant
, tmsfloat
;
1686 tmsfloat
= *((long *) &float_value
);
1687 sign
= tmsfloat
& 0x80000000;
1688 mant
= tmsfloat
& 0x007FFFFF;
1689 exp
= tmsfloat
& 0x7F800000;
1691 if (exp
== 0xFF000000)
1705 mant
= mant
& 0x007FFFFF;
1707 mant
= mant
& 0x00FFFFFF;
1711 exp
= (long) exp
- 0x01000000;
1714 tmsfloat
= exp
| mant
;
1721 if (tmsfloat
== 0x80000000)
1728 exp
= (tmsfloat
& 0xFF000000);
1730 mant
= tmsfloat
& 0x007FFFFF;
1731 if (tmsfloat
& 0x00800000)
1745 exp
+= (mant
>> 24);
1755 mant
= (exp
<< 12) | mant
;
1756 value
= mant
& 0xFFFF;
1761 md_number_to_chars (literalP
, value
, prec
);
1767 md_number_to_chars (buf
, val
, n
)
1772 debug ("In md_number_to_chars()\n");
1773 number_to_chars_bigendian (buf
, val
, n
);
1774 /* number_to_chars_littleendian(buf,val,n); */
1777 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1778 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1781 tc_gen_reloc (section
, fixP
)
1782 asection
*section ATTRIBUTE_UNUSED
;
1786 bfd_reloc_code_real_type code
= 0;
1788 debug ("In tc_gen_reloc()\n");
1789 debug ("fixP.size = %d\n", fixP
->fx_size
);
1790 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1791 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1792 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1794 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1795 MAP (2, 0, BFD_RELOC_16
);
1796 MAP (3, 0, BFD_RELOC_24
);
1797 MAP (2, 1, BFD_RELOC_16_PCREL
);
1798 MAP (4, 0, BFD_RELOC_32
);
1800 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1801 fixP
->fx_pcrel
? "pc-relative " : "");
1806 rel
= (arelent
*) xmalloc (sizeof (arelent
));
1808 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1809 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1810 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1812 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1816 name
= S_GET_NAME (fixP
->fx_addsy
);
1819 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name
, bfd_get_reloc_code_name (code
));
1825 md_operand (expressionP
)
1826 expressionS
*expressionP ATTRIBUTE_UNUSED
;
1828 debug ("In md_operand()\n");
1831 char output_invalid_buf
[8];
1838 sprintf (output_invalid_buf
, "'%c'", c
);
1840 sprintf (output_invalid_buf
, "(0x%x)", (unsigned) c
);
1841 return output_invalid_buf
;