1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 /* Texas Instruments TMS320C30 machine specific gas.
23 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
24 Bugs & suggestions are completely welcome. This is free software.
25 Please help us make it better. */
28 #include "safe-ctype.h"
29 #include "opcode/tic30.h"
31 /* Put here all non-digit non-letter charcters that may occur in an
33 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
34 static char *ordinal_names
[] = {
35 "first", "second", "third", "fourth", "fifth"
38 const int md_reloc_size
= 0;
40 const char comment_chars
[] = ";";
41 const char line_comment_chars
[] = "*";
42 const char line_separator_chars
[] = "";
44 const char *md_shortopts
= "";
45 struct option md_longopts
[] = {
46 {NULL
, no_argument
, NULL
, 0}
49 size_t md_longopts_size
= sizeof (md_longopts
);
51 /* Chars that mean this number is a floating point constant. */
54 const char FLT_CHARS
[] = "fFdDxX";
56 /* Chars that can be used to separate mant from exp in floating point
58 const char EXP_CHARS
[] = "eE";
60 /* tables for lexical analysis */
61 static char opcode_chars
[256];
62 static char register_chars
[256];
63 static char operand_chars
[256];
64 static char space_chars
[256];
65 static char identifier_chars
[256];
66 static char digit_chars
[256];
69 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
70 #define is_operand_char(x) (operand_chars[(unsigned char) x])
71 #define is_register_char(x) (register_chars[(unsigned char) x])
72 #define is_space_char(x) (space_chars[(unsigned char) x])
73 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
74 #define is_digit_char(x) (digit_chars[(unsigned char) x])
76 const pseudo_typeS md_pseudo_table
[] = {
85 debug (const char *string
, ...)
92 va_start (argptr
, string
);
93 vsprintf (str
, string
, argptr
);
97 fputs (str
, USE_STDOUT
? stdout
: stderr
);
105 debug (string
, va_alist
)
115 va_start (argptr
, string
);
116 cnt
= vsprintf (str
, string
, argptr
);
120 fputs (str
, USE_STDOUT
? stdout
: stderr
);
128 /* hash table for opcode lookup */
129 static struct hash_control
*op_hash
;
130 /* hash table for parallel opcode lookup */
131 static struct hash_control
*parop_hash
;
132 /* hash table for register lookup */
133 static struct hash_control
*reg_hash
;
134 /* hash table for indirect addressing lookup */
135 static struct hash_control
*ind_hash
;
140 const char *hash_err
;
141 debug ("In md_begin()\n");
142 op_hash
= hash_new ();
144 const template *current_optab
= tic30_optab
;
145 for (; current_optab
< tic30_optab_end
; current_optab
++)
147 hash_err
= hash_insert (op_hash
, current_optab
->name
, (char *) current_optab
);
149 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab
->name
, hash_err
);
152 parop_hash
= hash_new ();
154 const partemplate
*current_parop
= tic30_paroptab
;
155 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
157 hash_err
= hash_insert (parop_hash
, current_parop
->name
, (char *) current_parop
);
159 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop
->name
, hash_err
);
162 reg_hash
= hash_new ();
164 const reg
*current_reg
= tic30_regtab
;
165 for (; current_reg
< tic30_regtab_end
; current_reg
++)
167 hash_err
= hash_insert (reg_hash
, current_reg
->name
, (char *) current_reg
);
169 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg
->name
, hash_err
);
172 ind_hash
= hash_new ();
174 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
175 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
177 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
, (char *) current_ind
);
179 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind
->syntax
, hash_err
);
182 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
187 for (c
= 0; c
< 256; c
++)
189 if (ISLOWER (c
) || ISDIGIT (c
))
192 register_chars
[c
] = c
;
194 else if (ISUPPER (c
))
196 opcode_chars
[c
] = TOLOWER (c
);
197 register_chars
[c
] = opcode_chars
[c
];
199 else if (c
== ')' || c
== '(')
201 register_chars
[c
] = c
;
203 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
204 operand_chars
[c
] = c
;
205 if (ISDIGIT (c
) || c
== '-')
207 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
208 identifier_chars
[c
] = c
;
209 if (c
== ' ' || c
== '\t')
214 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
215 operand_chars
[(unsigned char) *p
] = *p
;
219 /* Address Mode OR values */
220 #define AM_Register 0x00000000
221 #define AM_Direct 0x00200000
222 #define AM_Indirect 0x00400000
223 #define AM_Immediate 0x00600000
224 #define AM_NotReq 0xFFFFFFFF
226 /* PC Relative OR values */
227 #define PC_Register 0x00000000
228 #define PC_Relative 0x02000000
236 expressionS direct_expr
;
251 unsigned int u_number
;
253 expressionS imm_expr
;
257 int tic30_parallel_insn
PARAMS ((char *));
258 operand
*tic30_operand
PARAMS ((char *));
259 char *tic30_find_parallel_insn
PARAMS ((char *, char *));
264 template *tm
; /* Template of current instruction */
265 unsigned opcode
; /* Final opcode */
266 int operands
; /* Number of given operands */
267 /* Type of operand given in instruction */
268 operand
*operand_type
[MAX_OPERANDS
];
269 unsigned addressing_mode
; /* Final addressing mode of instruction */
272 struct tic30_insn insn
;
273 static int found_parallel_insn
;
285 debug ("In md_assemble() with argument %s\n", line
);
286 memset (&insn
, '\0', sizeof (insn
));
287 if (found_parallel_insn
)
289 debug ("Line is second part of parallel instruction\n\n");
290 found_parallel_insn
= 0;
293 if ((current_posn
= tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
296 found_parallel_insn
= 1;
297 while (is_space_char (*current_posn
))
299 token_start
= current_posn
;
300 if (!is_opcode_char (*current_posn
))
302 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn
));
305 /* Check if instruction is a parallel instruction by seeing if the first
307 if (*token_start
== 'q')
309 if (tic30_parallel_insn (token_start
))
311 if (found_parallel_insn
)
316 while (is_opcode_char (*current_posn
))
318 { /* Find instruction */
319 save_char
= *current_posn
;
320 *current_posn
= '\0';
321 opcode
= (template *) hash_find (op_hash
, token_start
);
324 debug ("Found instruction %s\n", opcode
->name
);
329 debug ("Didn't find insn\n");
330 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
333 *current_posn
= save_char
;
335 if (*current_posn
!= END_OF_INSN
)
336 { /* Find operands */
337 int paren_not_balanced
;
338 int expecting_operand
= 0;
342 /* skip optional white space before operand */
343 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
345 if (!is_space_char (*current_posn
))
347 as_bad ("Invalid character %s before %s operand",
348 output_invalid (*current_posn
),
349 ordinal_names
[insn
.operands
]);
354 token_start
= current_posn
; /* after white space */
355 paren_not_balanced
= 0;
356 while (paren_not_balanced
|| *current_posn
!= ',')
358 if (*current_posn
== END_OF_INSN
)
360 if (paren_not_balanced
)
362 as_bad ("Unbalanced parenthesis in %s operand.",
363 ordinal_names
[insn
.operands
]);
367 break; /* we are done */
369 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
371 as_bad ("Invalid character %s in %s operand",
372 output_invalid (*current_posn
),
373 ordinal_names
[insn
.operands
]);
376 if (*current_posn
== '(')
377 ++paren_not_balanced
;
378 if (*current_posn
== ')')
379 --paren_not_balanced
;
382 if (current_posn
!= token_start
)
383 { /* yes, we've read in another operand */
384 this_operand
= insn
.operands
++;
385 if (insn
.operands
> MAX_OPERANDS
)
387 as_bad ("Spurious operands; (%d operands/instruction max)",
391 /* now parse operand adding info to 'insn' as we go along */
392 save_char
= *current_posn
;
393 *current_posn
= '\0';
394 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
395 *current_posn
= save_char
;
396 if (insn
.operand_type
[this_operand
] == NULL
)
401 if (expecting_operand
)
403 as_bad ("Expecting operand after ','; got nothing");
406 if (*current_posn
== ',')
408 as_bad ("Expecting operand before ','; got nothing");
412 /* now *current_posn must be either ',' or END_OF_INSN */
413 if (*current_posn
== ',')
415 if (*++current_posn
== END_OF_INSN
)
416 { /* just skip it, if it's \n complain */
417 as_bad ("Expecting operand after ','; got nothing");
420 expecting_operand
= 1;
423 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
425 debug ("Number of operands found: %d\n", insn
.operands
);
426 /* Check that number of operands is correct */
427 if (insn
.operands
!= insn
.tm
->operands
)
430 int numops
= insn
.tm
->operands
;
431 /* If operands are not the same, then see if any of the operands are not
432 required. Then recheck with number of given operands. If they are still not
433 the same, then give an error, otherwise carry on. */
434 for (i
= 0; i
< insn
.tm
->operands
; i
++)
435 if (insn
.tm
->operand_types
[i
] & NotReq
)
437 if (insn
.operands
!= numops
)
439 as_bad ("Incorrect number of operands given");
443 insn
.addressing_mode
= AM_NotReq
;
444 for (count
= 0; count
< insn
.operands
; count
++)
446 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
448 debug ("Operand %d matches\n", count
+ 1);
449 /* If instruction has two operands and has an AddressMode modifier then set
450 addressing mode type for instruction */
451 if (insn
.tm
->opcode_modifier
== AddressMode
)
454 /* Store instruction uses the second operand for the address mode. */
455 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
)) == (Indirect
| Direct
))
457 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
458 insn
.addressing_mode
= AM_Register
;
459 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
460 insn
.addressing_mode
= AM_Direct
;
461 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
462 insn
.addressing_mode
= AM_Indirect
;
464 insn
.addressing_mode
= AM_Immediate
;
469 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
473 /* Now set the addressing mode for 3 operand instructions. */
474 if ((insn
.tm
->operand_types
[0] & op3T1
) && (insn
.tm
->operand_types
[1] & op3T2
))
476 /* Set the addressing mode to the values used for 2 operand instructions in the
477 G addressing field of the opcode. */
479 switch (insn
.operand_type
[0]->op_type
)
485 if (insn
.operand_type
[1]->op_type
& (AllReg
))
486 insn
.addressing_mode
= AM_Register
;
487 else if (insn
.operand_type
[1]->op_type
& Indirect
)
488 insn
.addressing_mode
= AM_Direct
;
491 /* Shouldn't make it to this stage */
492 as_bad ("Incompatible first and second operands in instruction");
497 if (insn
.operand_type
[1]->op_type
& (AllReg
))
498 insn
.addressing_mode
= AM_Indirect
;
499 else if (insn
.operand_type
[1]->op_type
& Indirect
)
500 insn
.addressing_mode
= AM_Immediate
;
503 /* Shouldn't make it to this stage */
504 as_bad ("Incompatible first and second operands in instruction");
509 /* Now make up the opcode for the 3 operand instructions. As in parallel
510 instructions, there will be no unresolved values, so they can be fully formed
511 and added to the frag table. */
512 insn
.opcode
= insn
.tm
->base_opcode
;
513 if (insn
.operand_type
[0]->op_type
& Indirect
)
515 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
516 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
519 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
520 if (insn
.operand_type
[1]->op_type
& Indirect
)
522 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
523 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
526 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
527 if (insn
.operands
== 3)
528 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
529 insn
.opcode
|= insn
.addressing_mode
;
530 p
= frag_more (INSN_SIZE
);
531 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
534 { /* Not a three operand instruction */
537 insn
.opcode
= insn
.tm
->base_opcode
;
538 /* Create frag for instruction - all instructions are 4 bytes long. */
539 p
= frag_more (INSN_SIZE
);
540 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
542 insn
.opcode
|= insn
.addressing_mode
;
543 if (insn
.addressing_mode
== AM_Indirect
)
545 /* Determine which operand gives the addressing mode */
546 if (insn
.operand_type
[0]->op_type
& Indirect
)
548 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Indirect
))
550 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
551 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
552 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
553 if (insn
.operands
> 1)
554 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
555 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
557 else if (insn
.addressing_mode
== AM_Register
)
559 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
560 if (insn
.operands
> 1)
561 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
562 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
564 else if (insn
.addressing_mode
== AM_Direct
)
566 if (insn
.operand_type
[0]->op_type
& Direct
)
568 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Direct
))
570 if (insn
.operands
> 1)
571 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
572 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
574 /* Resolved values can be placed straight into instruction word, and output */
575 insn
.opcode
|= (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
576 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
579 { /* Unresolved direct addressing mode instruction */
580 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
581 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[am_insn
]->direct
.direct_expr
, 0, 0);
584 else if (insn
.addressing_mode
== AM_Immediate
)
586 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
590 if (insn
.operands
> 1)
591 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
592 switch (insn
.tm
->imm_arg_type
)
595 debug ("Floating point first operand\n");
596 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
597 keeploc
= input_line_pointer
;
598 input_line_pointer
= insn
.operand_type
[0]->immediate
.label
;
599 if (md_atof ('f', p
+ 2, &size
) != 0)
601 as_bad ("invalid short form floating point immediate operand");
604 input_line_pointer
= keeploc
;
607 debug ("Unsigned int first operand\n");
608 if (insn
.operand_type
[0]->immediate
.decimal_found
)
609 as_warn ("rounding down first operand float to unsigned int");
610 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
611 as_warn ("only lower 16-bits of first operand are used");
612 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
613 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
616 debug ("Int first operand\n");
617 if (insn
.operand_type
[0]->immediate
.decimal_found
)
618 as_warn ("rounding down first operand float to signed int");
619 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
620 insn
.operand_type
[0]->immediate
.s_number
> 32767)
622 as_bad ("first operand is too large for 16-bit signed int");
625 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
626 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
631 { /* Unresolved immediate label */
632 if (insn
.operands
> 1)
633 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
634 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
635 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
639 else if (insn
.tm
->opcode_modifier
== PCRel
)
641 /* Conditional Branch and Call instructions */
642 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
)) == (AllReg
| Disp
))
644 if (insn
.operand_type
[0]->op_type
& (AllReg
))
646 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
647 insn
.opcode
|= PC_Register
;
648 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
652 insn
.opcode
|= PC_Relative
;
653 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
655 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
656 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
660 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
661 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 1, 0);
665 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
667 /* Decrement and Branch instructions */
668 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
669 if (insn
.operand_type
[1]->op_type
& (AllReg
))
671 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
672 insn
.opcode
|= PC_Register
;
673 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
675 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
677 if (insn
.operand_type
[0]->immediate
.decimal_found
)
679 as_bad ("first operand is floating point");
682 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
683 insn
.operand_type
[0]->immediate
.s_number
> 32767)
685 as_bad ("first operand is too large for 16-bit signed int");
688 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
689 insn
.opcode
|= PC_Relative
;
690 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
694 insn
.opcode
|= PC_Relative
;
695 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
696 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2, &insn
.operand_type
[1]->immediate
.imm_expr
, 1, 0);
700 else if (insn
.tm
->operand_types
[0] == IVector
)
702 /* Trap instructions */
703 if (insn
.operand_type
[0]->op_type
& IVector
)
704 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
706 { /* Shouldn't get here */
707 as_bad ("interrupt vector for trap instruction out of range");
710 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
712 else if (insn
.tm
->opcode_modifier
== StackOp
|| insn
.tm
->opcode_modifier
== Rotate
)
714 /* Push, Pop and Rotate instructions */
715 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
716 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
718 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
)) == (Abs24
| Direct
))
720 /* LDP Instruction needs to be tested for before the next section */
721 if (insn
.operand_type
[0]->op_type
& Direct
)
723 if (insn
.operand_type
[0]->direct
.resolved
== 1)
725 /* Direct addressing uses lower 8 bits of direct address */
726 insn
.opcode
|= (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
727 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
732 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
733 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
734 /* Ensure that the assembler doesn't complain about fitting a 24-bit
735 address into 8 bits. */
736 fix
->fx_no_overflow
= 1;
741 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
743 /* Immediate addressing uses upper 8 bits of address */
744 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
746 as_bad ("LDP instruction needs a 24-bit operand");
749 insn
.opcode
|= ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
750 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
755 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
756 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
757 fix
->fx_no_overflow
= 1;
761 else if (insn
.tm
->operand_types
[0] & (Imm24
))
763 /* Unconditional Branch and Call instructions */
764 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
766 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
767 as_warn ("first operand is too large for a 24-bit displacement");
768 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
769 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
773 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
774 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
777 else if (insn
.tm
->operand_types
[0] & NotReq
)
779 /* Check for NOP instruction without arguments. */
780 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
782 else if (insn
.tm
->operands
== 0)
784 /* Check for instructions without operands. */
785 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
788 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
791 for (i
= 0; i
< insn
.operands
; i
++)
793 if (insn
.operand_type
[i
]->immediate
.label
)
794 free (insn
.operand_type
[i
]->immediate
.label
);
795 free (insn
.operand_type
[i
]);
798 debug ("Final opcode: %08X\n", insn
.opcode
);
802 struct tic30_par_insn
{
803 partemplate
*tm
; /* Template of current parallel instruction */
804 int operands
[2]; /* Number of given operands for each insn */
805 /* Type of operand given in instruction */
806 operand
*operand_type
[2][MAX_OPERANDS
];
807 int swap_operands
; /* Whether to swap operands around. */
808 unsigned p_field
; /* Value of p field in multiply add/sub instructions */
809 unsigned opcode
; /* Final opcode */
812 struct tic30_par_insn p_insn
;
815 tic30_parallel_insn (char *token
)
817 static partemplate
*p_opcode
;
818 char *current_posn
= token
;
822 debug ("In tic30_parallel_insn with %s\n", token
);
823 memset (&p_insn
, '\0', sizeof (p_insn
));
824 while (is_opcode_char (*current_posn
))
826 { /* Find instruction */
827 save_char
= *current_posn
;
828 *current_posn
= '\0';
829 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
832 debug ("Found instruction %s\n", p_opcode
->name
);
833 p_insn
.tm
= p_opcode
;
837 char first_opcode
[6] =
839 char second_opcode
[6] =
842 int current_opcode
= -1;
845 for (i
= 0; i
< strlen (token
); i
++)
847 char ch
= *(token
+ i
);
848 if (ch
== '_' && current_opcode
== -1)
853 if (ch
== '_' && current_opcode
== 0)
859 switch (current_opcode
)
862 first_opcode
[char_ptr
++] = ch
;
865 second_opcode
[char_ptr
++] = ch
;
869 debug ("first_opcode = %s\n", first_opcode
);
870 debug ("second_opcode = %s\n", second_opcode
);
871 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
872 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
875 debug ("Found instruction %s\n", p_opcode
->name
);
876 p_insn
.tm
= p_opcode
;
877 p_insn
.swap_operands
= 1;
882 *current_posn
= save_char
;
884 { /* Find operands */
885 int paren_not_balanced
;
886 int expecting_operand
= 0;
887 int found_separator
= 0;
890 /* skip optional white space before operand */
891 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
893 if (!is_space_char (*current_posn
) && *current_posn
!= PARALLEL_SEPARATOR
)
895 as_bad ("Invalid character %s before %s operand",
896 output_invalid (*current_posn
),
897 ordinal_names
[insn
.operands
]);
900 if (*current_posn
== PARALLEL_SEPARATOR
)
904 token_start
= current_posn
; /* after white space */
905 paren_not_balanced
= 0;
906 while (paren_not_balanced
|| *current_posn
!= ',')
908 if (*current_posn
== END_OF_INSN
)
910 if (paren_not_balanced
)
912 as_bad ("Unbalanced parenthesis in %s operand.",
913 ordinal_names
[insn
.operands
]);
917 break; /* we are done */
919 else if (*current_posn
== PARALLEL_SEPARATOR
)
921 while (is_space_char (*(current_posn
- 1)))
925 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
927 as_bad ("Invalid character %s in %s operand",
928 output_invalid (*current_posn
),
929 ordinal_names
[insn
.operands
]);
932 if (*current_posn
== '(')
933 ++paren_not_balanced
;
934 if (*current_posn
== ')')
935 --paren_not_balanced
;
938 if (current_posn
!= token_start
)
939 { /* yes, we've read in another operand */
940 p_insn
.operands
[found_separator
]++;
941 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
943 as_bad ("Spurious operands; (%d operands/instruction max)",
947 /* now parse operand adding info to 'insn' as we go along */
948 save_char
= *current_posn
;
949 *current_posn
= '\0';
950 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
951 tic30_operand (token_start
);
952 *current_posn
= save_char
;
953 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
958 if (expecting_operand
)
960 as_bad ("Expecting operand after ','; got nothing");
963 if (*current_posn
== ',')
965 as_bad ("Expecting operand before ','; got nothing");
969 /* now *current_posn must be either ',' or END_OF_INSN */
970 if (*current_posn
== ',')
972 if (*++current_posn
== END_OF_INSN
)
973 { /* just skip it, if it's \n complain */
974 as_bad ("Expecting operand after ','; got nothing");
977 expecting_operand
= 1;
980 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
982 if (p_insn
.swap_operands
)
987 temp_num
= p_insn
.operands
[0];
988 p_insn
.operands
[0] = p_insn
.operands
[1];
989 p_insn
.operands
[1] = temp_num
;
990 for (i
= 0; i
< MAX_OPERANDS
; i
++)
992 temp_op
= p_insn
.operand_type
[0][i
];
993 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
994 p_insn
.operand_type
[1][i
] = temp_op
;
997 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
999 as_bad ("incorrect number of operands given in the first instruction");
1002 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
1004 as_bad ("incorrect number of operands given in the second instruction");
1007 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
1008 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
1009 { /* Now check if operands are correct */
1013 for (count
= 0; count
< 2; count
++)
1016 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
1018 if ((p_insn
.operand_type
[count
][i
]->op_type
&
1019 p_insn
.tm
->operand_types
[count
][i
]) == 0)
1021 as_bad ("%s instruction, operand %d doesn't match", ordinal_names
[count
], i
+ 1);
1024 /* Get number of R register and indirect reference contained within the first
1025 two operands of each instruction. This is required for the multiply
1026 parallel instructions which require two R registers and two indirect
1027 references, but not in any particular place. */
1028 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
1030 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
) && i
< 2)
1034 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
)) == (Indirect
| Rn
))
1036 /* Check for the multiply instructions */
1039 as_bad ("incorrect format for multiply parallel instruction");
1043 { /* Shouldn't get here */
1044 as_bad ("incorrect format for multiply parallel instruction");
1047 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00) &&
1048 (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
1050 as_bad ("destination for multiply can only be R0 or R1");
1053 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02) &&
1054 (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
1056 as_bad ("destination for add/subtract can only be R2 or R3");
1059 /* Now determine the P field for the instruction */
1060 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
1062 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
1063 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn */
1064 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1065 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn */
1067 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind */
1071 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
1072 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind */
1073 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1076 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn */
1077 /* Need to swap the two multiply operands around so that everything is in
1078 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1079 temp
= p_insn
.operand_type
[0][0];
1080 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1081 p_insn
.operand_type
[0][1] = temp
;
1086 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind */
1087 temp
= p_insn
.operand_type
[0][0];
1088 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1089 p_insn
.operand_type
[0][1] = temp
;
1094 debug ("P field: %08X\n", p_insn
.p_field
);
1095 /* Finalise opcode. This is easier for parallel instructions as they have to be
1096 fully resolved, there are no memory addresses allowed, except through indirect
1097 addressing, so there are no labels to resolve. */
1099 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
1100 switch (p_insn
.tm
->oporder
)
1103 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1104 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1105 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1106 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1107 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1108 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1111 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1112 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1113 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1114 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1115 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1116 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1117 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1118 as_warn ("loading the same register in parallel operation");
1121 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1122 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1123 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1124 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1125 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1126 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1129 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1130 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1131 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1132 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1133 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1134 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1135 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1138 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1139 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1140 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1141 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1142 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1143 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1144 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1147 p_insn
.opcode
|= p_insn
.p_field
;
1148 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1149 p_insn
.opcode
|= 0x00800000;
1150 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1151 p_insn
.opcode
|= 0x00400000;
1152 switch (p_insn
.p_field
)
1155 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1156 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1157 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1158 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1159 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1160 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1163 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1164 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1165 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1166 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1167 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1168 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1171 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1172 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1173 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1174 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1175 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1176 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1179 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1180 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1181 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1182 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1183 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1184 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1189 } /* Opcode is finalised at this point for all parallel instructions. */
1190 { /* Output opcode */
1192 p
= frag_more (INSN_SIZE
);
1193 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1197 for (i
= 0; i
< 2; i
++)
1198 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1199 free (p_insn
.operand_type
[i
][j
]);
1201 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1207 tic30_operand (token
)
1211 char ind_buffer
[strlen (token
)];
1212 operand
*current_op
;
1214 debug ("In tic30_operand with %s\n", token
);
1215 current_op
= (operand
*) malloc (sizeof (operand
));
1216 memset (current_op
, '\0', sizeof (operand
));
1217 if (*token
== DIRECT_REFERENCE
)
1219 char *token_posn
= token
+ 1;
1220 int direct_label
= 0;
1221 debug ("Found direct reference\n");
1224 if (!is_digit_char (*token_posn
))
1230 char *save_input_line_pointer
;
1232 debug ("Direct reference is a label\n");
1233 current_op
->direct
.label
= token
+ 1;
1234 save_input_line_pointer
= input_line_pointer
;
1235 input_line_pointer
= token
+ 1;
1236 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1237 retval
= expression (¤t_op
->direct
.direct_expr
);
1238 debug ("Expression type: %d\n", current_op
->direct
.direct_expr
.X_op
);
1239 debug ("Expression addnum: %d\n", current_op
->direct
.direct_expr
.X_add_number
);
1240 debug ("Segment: %d\n", retval
);
1241 input_line_pointer
= save_input_line_pointer
;
1242 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
1244 current_op
->direct
.address
= current_op
->direct
.direct_expr
.X_add_number
;
1245 current_op
->direct
.resolved
= 1;
1250 debug ("Direct reference is a number\n");
1251 current_op
->direct
.address
= atoi (token
+ 1);
1252 current_op
->direct
.resolved
= 1;
1254 current_op
->op_type
= Direct
;
1256 else if (*token
== INDIRECT_REFERENCE
)
1257 { /* Indirect reference operand */
1261 int disp_number
= 0;
1262 int buffer_posn
= 1;
1263 ind_addr_type
*ind_addr_op
;
1264 debug ("Found indirect reference\n");
1265 ind_buffer
[0] = *token
;
1266 for (count
= 1; count
< strlen (token
); count
++)
1267 { /* Strip operand */
1268 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
1269 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A') &&
1270 (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
1272 /* AR reference is found, so get its number and remove it from the buffer
1273 so it can pass through hash_find() */
1276 as_bad ("More than one AR register found in indirect reference");
1279 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
1281 as_bad ("Illegal AR register in indirect reference");
1284 ar_number
= *(token
+ count
+ 1) - '0';
1288 if (*(token
+ count
) == '(')
1290 /* Parenthesis found, so check if a displacement value is inside. If so, get
1291 the value and remove it from the buffer. */
1292 if (is_digit_char (*(token
+ count
+ 1)))
1299 as_bad ("More than one displacement found in indirect reference");
1303 while (*(token
+ count
) != ')')
1305 if (!is_digit_char (*(token
+ count
)))
1307 as_bad ("Invalid displacement in indirect reference");
1310 disp
[disp_posn
++] = *(token
+ (count
++));
1312 disp
[disp_posn
] = '\0';
1313 disp_number
= atoi (disp
);
1320 ind_buffer
[buffer_posn
] = '\0';
1323 as_bad ("AR register not found in indirect reference");
1326 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
1329 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
1330 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
1335 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
1337 /* Maybe an implied displacement of 1 again */
1338 as_bad ("required displacement wasn't given in indirect reference");
1344 as_bad ("illegal indirect reference");
1347 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
1349 as_bad ("displacement must be an unsigned 8-bit number");
1352 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
1353 current_op
->indirect
.disp
= disp_number
;
1354 current_op
->indirect
.ARnum
= ar_number
;
1355 current_op
->op_type
= Indirect
;
1359 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
1362 debug ("Found register operand: %s\n", regop
->name
);
1363 if (regop
->regtype
== REG_ARn
)
1364 current_op
->op_type
= ARn
;
1365 else if (regop
->regtype
== REG_Rn
)
1366 current_op
->op_type
= Rn
;
1367 else if (regop
->regtype
== REG_DP
)
1368 current_op
->op_type
= DPReg
;
1370 current_op
->op_type
= OtherReg
;
1371 current_op
->reg
.opcode
= regop
->opcode
;
1375 if (!is_digit_char (*token
) || *(token
+ 1) == 'x' || strchr (token
, 'h'))
1377 char *save_input_line_pointer
;
1379 debug ("Probably a label: %s\n", token
);
1380 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1381 strcpy (current_op
->immediate
.label
, token
);
1382 current_op
->immediate
.label
[strlen (token
)] = '\0';
1383 save_input_line_pointer
= input_line_pointer
;
1384 input_line_pointer
= token
;
1385 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1386 retval
= expression (¤t_op
->immediate
.imm_expr
);
1387 debug ("Expression type: %d\n", current_op
->immediate
.imm_expr
.X_op
);
1388 debug ("Expression addnum: %d\n", current_op
->immediate
.imm_expr
.X_add_number
);
1389 debug ("Segment: %d\n", retval
);
1390 input_line_pointer
= save_input_line_pointer
;
1391 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
1393 current_op
->immediate
.s_number
= current_op
->immediate
.imm_expr
.X_add_number
;
1394 current_op
->immediate
.u_number
= (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
1395 current_op
->immediate
.resolved
= 1;
1401 debug ("Found a number or displacement\n");
1402 for (count
= 0; count
< strlen (token
); count
++)
1403 if (*(token
+ count
) == '.')
1404 current_op
->immediate
.decimal_found
= 1;
1405 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1406 strcpy (current_op
->immediate
.label
, token
);
1407 current_op
->immediate
.label
[strlen (token
)] = '\0';
1408 current_op
->immediate
.f_number
= (float) atof (token
);
1409 current_op
->immediate
.s_number
= (int) atoi (token
);
1410 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
1411 current_op
->immediate
.resolved
= 1;
1413 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
1414 if (current_op
->immediate
.u_number
>= 0 && current_op
->immediate
.u_number
<= 31)
1415 current_op
->op_type
|= IVector
;
1421 /* next_line points to the next line after the current instruction (current_line).
1422 Search for the parallel bars, and if found, merge two lines into internal syntax
1423 for a parallel instruction:
1424 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1425 By this stage, all comments are scrubbed, and only the bare lines are given.
1429 #define START_OPCODE 1
1430 #define END_OPCODE 2
1431 #define START_OPERANDS 3
1432 #define END_OPERANDS 4
1435 tic30_find_parallel_insn (current_line
, next_line
)
1439 int found_parallel
= 0;
1440 char first_opcode
[256];
1441 char second_opcode
[256];
1442 char first_operands
[256];
1443 char second_operands
[256];
1444 char *parallel_insn
;
1446 debug ("In tic30_find_parallel_insn()\n");
1447 while (!is_end_of_line
[(unsigned char) *next_line
])
1449 if (*next_line
== PARALLEL_SEPARATOR
&& *(next_line
+ 1) == PARALLEL_SEPARATOR
)
1457 if (!found_parallel
)
1459 debug ("Found a parallel instruction\n");
1462 char *opcode
, *operands
, *line
;
1464 for (i
= 0; i
< 2; i
++)
1468 opcode
= &first_opcode
[0];
1469 operands
= &first_operands
[0];
1470 line
= current_line
;
1474 opcode
= &second_opcode
[0];
1475 operands
= &second_operands
[0];
1479 int search_status
= NONE
;
1483 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
1485 if (is_opcode_char (c
) && search_status
== NONE
)
1487 opcode
[char_ptr
++] = TOLOWER (c
);
1488 search_status
= START_OPCODE
;
1490 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
1492 opcode
[char_ptr
++] = TOLOWER (c
);
1494 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
1496 opcode
[char_ptr
] = '\0';
1498 search_status
= END_OPCODE
;
1500 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
1502 operands
[char_ptr
++] = c
;
1504 if (is_operand_char (c
) && search_status
== END_OPCODE
)
1506 operands
[char_ptr
++] = c
;
1507 search_status
= START_OPERANDS
;
1511 if (search_status
!= START_OPERANDS
)
1513 operands
[char_ptr
] = '\0';
1517 parallel_insn
= (char *) malloc (strlen (first_opcode
) + strlen (first_operands
) +
1518 strlen (second_opcode
) + strlen (second_operands
) + 8);
1519 sprintf (parallel_insn
, "q_%s_%s %s | %s", first_opcode
, second_opcode
, first_operands
, second_operands
);
1520 debug ("parallel insn = %s\n", parallel_insn
);
1521 return parallel_insn
;
1527 #undef START_OPERANDS
1530 /* In order to get gas to ignore any | chars at the start of a line,
1531 this function returns true if a | is found in a line. */
1534 tic30_unrecognized_line (c
)
1537 debug ("In tc_unrecognized_line\n");
1538 return (c
== PARALLEL_SEPARATOR
);
1542 md_estimate_size_before_relax (fragP
, segment
)
1546 debug ("In md_estimate_size_before_relax()\n");
1551 md_convert_frag (abfd
, sec
, fragP
)
1554 register fragS
*fragP
;
1556 debug ("In md_convert_frag()\n");
1560 md_apply_fix3 (fixP
, valP
, seg
)
1563 segT seg ATTRIBUTE_UNUSED
;
1565 valueT value
= *valP
;
1567 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1568 debug ("Values in fixP\n");
1569 debug ("fx_size = %d\n", fixP
->fx_size
);
1570 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1571 debug ("fx_where = %d\n", fixP
->fx_where
);
1572 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1574 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1577 if (fixP
->fx_size
== 1)
1578 /* Special fix for LDP instruction. */
1579 value
= (value
& 0x00FF0000) >> 16;
1581 debug ("new value = %ld\n", (long) value
);
1582 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1585 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1590 md_parse_option (c
, arg
)
1594 debug ("In md_parse_option()\n");
1599 md_show_usage (stream
)
1602 debug ("In md_show_usage()\n");
1606 md_undefined_symbol (name
)
1609 debug ("In md_undefined_symbol()\n");
1610 return (symbolS
*) 0;
1614 md_section_align (segment
, size
)
1618 debug ("In md_section_align() segment = %d and size = %d\n", segment
, size
);
1619 size
= (size
+ 3) / 4;
1621 debug ("New size value = %d\n", size
);
1626 md_pcrel_from (fixP
)
1631 debug ("In md_pcrel_from()\n");
1632 debug ("fx_where = %d\n", fixP
->fx_where
);
1633 debug ("fx_size = %d\n", fixP
->fx_size
);
1634 /* Find the opcode that represents the current instruction in the fr_literal
1635 storage area, and check bit 21. Bit 21 contains whether the current instruction
1636 is a delayed one or not, and then set the offset value appropriately. */
1637 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1641 debug ("offset = %d\n", offset
);
1642 /* PC Relative instructions have a format:
1643 displacement = Label - (PC + offset)
1644 This function returns PC + offset where:
1645 fx_where - fx_size = PC
1646 INSN_SIZE * offset = offset number of instructions
1648 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1652 md_atof (what_statement_type
, literalP
, sizeP
)
1653 int what_statement_type
;
1660 unsigned long value
;
1661 /* char *atof_ieee (); */
1663 debug ("In md_atof()\n");
1664 debug ("precision = %c\n", what_statement_type
);
1665 debug ("literal = %s\n", literalP
);
1667 token
= input_line_pointer
;
1668 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1669 && (*input_line_pointer
!= ','))
1671 debug ("%c", *input_line_pointer
);
1672 input_line_pointer
++;
1674 keepval
= *input_line_pointer
;
1675 *input_line_pointer
= '\0';
1677 float_value
= (float) atof (token
);
1678 *input_line_pointer
= keepval
;
1679 debug ("float_value = %f\n", float_value
);
1680 switch (what_statement_type
)
1698 return "Bad call to MD_ATOF()";
1700 if (float_value
== 0.0)
1702 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1706 unsigned long exp
, sign
, mant
, tmsfloat
;
1707 tmsfloat
= *((long *) &float_value
);
1708 sign
= tmsfloat
& 0x80000000;
1709 mant
= tmsfloat
& 0x007FFFFF;
1710 exp
= tmsfloat
& 0x7F800000;
1712 if (exp
== 0xFF000000)
1726 mant
= mant
& 0x007FFFFF;
1728 mant
= mant
& 0x00FFFFFF;
1732 exp
= (long) exp
- 0x01000000;
1735 tmsfloat
= exp
| mant
;
1742 if (tmsfloat
== 0x80000000)
1749 exp
= (tmsfloat
& 0xFF000000);
1751 mant
= tmsfloat
& 0x007FFFFF;
1752 if (tmsfloat
& 0x00800000)
1766 exp
+= (mant
>> 24);
1776 mant
= (exp
<< 12) | mant
;
1777 value
= mant
& 0xFFFF;
1782 md_number_to_chars (literalP
, value
, prec
);
1788 md_number_to_chars (buf
, val
, n
)
1793 debug ("In md_number_to_chars()\n");
1794 number_to_chars_bigendian (buf
, val
, n
);
1795 /* number_to_chars_littleendian(buf,val,n); */
1798 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1799 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1802 tc_gen_reloc (section
, fixP
)
1807 bfd_reloc_code_real_type code
= 0;
1809 debug ("In tc_gen_reloc()\n");
1810 debug ("fixP.size = %d\n", fixP
->fx_size
);
1811 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1812 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1813 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1815 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1816 MAP (2, 0, BFD_RELOC_16
);
1817 MAP (3, 0, BFD_RELOC_24
);
1818 MAP (2, 1, BFD_RELOC_16_PCREL
);
1819 MAP (4, 0, BFD_RELOC_32
);
1821 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1822 fixP
->fx_pcrel
? "pc-relative " : "");
1827 rel
= (arelent
*) xmalloc (sizeof (arelent
));
1829 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1830 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1831 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1833 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1837 name
= S_GET_NAME (fixP
->fx_addsy
);
1840 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name
, bfd_get_reloc_code_name (code
));
1846 tc_aout_pre_write_hook ()
1848 debug ("In tc_aout_pre_write_hook()\n");
1852 md_operand (expressionP
)
1853 expressionS
*expressionP
;
1855 debug ("In md_operand()\n");
1858 char output_invalid_buf
[8];
1865 sprintf (output_invalid_buf
, "'%c'", c
);
1867 sprintf (output_invalid_buf
, "(0x%x)", (unsigned) c
);
1868 return output_invalid_buf
;