1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001 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
[] = {
88 debug (const char *string
, ...)
95 va_start (argptr
, string
);
96 vsprintf (str
, string
, argptr
);
100 fputs (str
, USE_STDOUT
? stdout
: stderr
);
108 debug (string
, va_alist
)
118 va_start (argptr
, string
);
119 cnt
= vsprintf (str
, string
, argptr
);
123 fputs (str
, USE_STDOUT
? stdout
: stderr
);
131 /* hash table for opcode lookup */
132 static struct hash_control
*op_hash
;
133 /* hash table for parallel opcode lookup */
134 static struct hash_control
*parop_hash
;
135 /* hash table for register lookup */
136 static struct hash_control
*reg_hash
;
137 /* hash table for indirect addressing lookup */
138 static struct hash_control
*ind_hash
;
143 const char *hash_err
;
144 debug ("In md_begin()\n");
145 op_hash
= hash_new ();
147 const template *current_optab
= tic30_optab
;
148 for (; current_optab
< tic30_optab_end
; current_optab
++)
150 hash_err
= hash_insert (op_hash
, current_optab
->name
, (char *) current_optab
);
152 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab
->name
, hash_err
);
155 parop_hash
= hash_new ();
157 const partemplate
*current_parop
= tic30_paroptab
;
158 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
160 hash_err
= hash_insert (parop_hash
, current_parop
->name
, (char *) current_parop
);
162 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop
->name
, hash_err
);
165 reg_hash
= hash_new ();
167 const reg
*current_reg
= tic30_regtab
;
168 for (; current_reg
< tic30_regtab_end
; current_reg
++)
170 hash_err
= hash_insert (reg_hash
, current_reg
->name
, (char *) current_reg
);
172 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg
->name
, hash_err
);
175 ind_hash
= hash_new ();
177 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
178 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
180 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
, (char *) current_ind
);
182 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind
->syntax
, hash_err
);
185 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
190 for (c
= 0; c
< 256; c
++)
192 if (ISLOWER (c
) || ISDIGIT (c
))
195 register_chars
[c
] = c
;
197 else if (ISUPPER (c
))
199 opcode_chars
[c
] = TOLOWER (c
);
200 register_chars
[c
] = opcode_chars
[c
];
202 else if (c
== ')' || c
== '(')
204 register_chars
[c
] = c
;
206 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
207 operand_chars
[c
] = c
;
208 if (ISDIGIT (c
) || c
== '-')
210 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
211 identifier_chars
[c
] = c
;
212 if (c
== ' ' || c
== '\t')
217 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
218 operand_chars
[(unsigned char) *p
] = *p
;
222 /* Address Mode OR values */
223 #define AM_Register 0x00000000
224 #define AM_Direct 0x00200000
225 #define AM_Indirect 0x00400000
226 #define AM_Immediate 0x00600000
227 #define AM_NotReq 0xFFFFFFFF
229 /* PC Relative OR values */
230 #define PC_Register 0x00000000
231 #define PC_Relative 0x02000000
239 expressionS direct_expr
;
254 unsigned int u_number
;
256 expressionS imm_expr
;
260 int tic30_parallel_insn
PARAMS ((char *));
261 operand
*tic30_operand
PARAMS ((char *));
262 char *tic30_find_parallel_insn
PARAMS ((char *, char *));
267 template *tm
; /* Template of current instruction */
268 unsigned opcode
; /* Final opcode */
269 int operands
; /* Number of given operands */
270 /* Type of operand given in instruction */
271 operand
*operand_type
[MAX_OPERANDS
];
272 unsigned addressing_mode
; /* Final addressing mode of instruction */
275 struct tic30_insn insn
;
276 static int found_parallel_insn
;
288 debug ("In md_assemble() with argument %s\n", line
);
289 memset (&insn
, '\0', sizeof (insn
));
290 if (found_parallel_insn
)
292 debug ("Line is second part of parallel instruction\n\n");
293 found_parallel_insn
= 0;
296 if ((current_posn
= tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
299 found_parallel_insn
= 1;
300 while (is_space_char (*current_posn
))
302 token_start
= current_posn
;
303 if (!is_opcode_char (*current_posn
))
305 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn
));
308 /* Check if instruction is a parallel instruction by seeing if the first
310 if (*token_start
== 'q')
312 if (tic30_parallel_insn (token_start
))
314 if (found_parallel_insn
)
319 while (is_opcode_char (*current_posn
))
321 { /* Find instruction */
322 save_char
= *current_posn
;
323 *current_posn
= '\0';
324 opcode
= (template *) hash_find (op_hash
, token_start
);
327 debug ("Found instruction %s\n", opcode
->name
);
332 debug ("Didn't find insn\n");
333 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
336 *current_posn
= save_char
;
338 if (*current_posn
!= END_OF_INSN
)
339 { /* Find operands */
340 int paren_not_balanced
;
341 int expecting_operand
= 0;
345 /* skip optional white space before operand */
346 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
348 if (!is_space_char (*current_posn
))
350 as_bad ("Invalid character %s before %s operand",
351 output_invalid (*current_posn
),
352 ordinal_names
[insn
.operands
]);
357 token_start
= current_posn
; /* after white space */
358 paren_not_balanced
= 0;
359 while (paren_not_balanced
|| *current_posn
!= ',')
361 if (*current_posn
== END_OF_INSN
)
363 if (paren_not_balanced
)
365 as_bad ("Unbalanced parenthesis in %s operand.",
366 ordinal_names
[insn
.operands
]);
370 break; /* we are done */
372 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
374 as_bad ("Invalid character %s in %s operand",
375 output_invalid (*current_posn
),
376 ordinal_names
[insn
.operands
]);
379 if (*current_posn
== '(')
380 ++paren_not_balanced
;
381 if (*current_posn
== ')')
382 --paren_not_balanced
;
385 if (current_posn
!= token_start
)
386 { /* yes, we've read in another operand */
387 this_operand
= insn
.operands
++;
388 if (insn
.operands
> MAX_OPERANDS
)
390 as_bad ("Spurious operands; (%d operands/instruction max)",
394 /* now parse operand adding info to 'insn' as we go along */
395 save_char
= *current_posn
;
396 *current_posn
= '\0';
397 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
398 *current_posn
= save_char
;
399 if (insn
.operand_type
[this_operand
] == NULL
)
404 if (expecting_operand
)
406 as_bad ("Expecting operand after ','; got nothing");
409 if (*current_posn
== ',')
411 as_bad ("Expecting operand before ','; got nothing");
415 /* now *current_posn must be either ',' or END_OF_INSN */
416 if (*current_posn
== ',')
418 if (*++current_posn
== END_OF_INSN
)
419 { /* just skip it, if it's \n complain */
420 as_bad ("Expecting operand after ','; got nothing");
423 expecting_operand
= 1;
426 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
428 debug ("Number of operands found: %d\n", insn
.operands
);
429 /* Check that number of operands is correct */
430 if (insn
.operands
!= insn
.tm
->operands
)
433 int numops
= insn
.tm
->operands
;
434 /* If operands are not the same, then see if any of the operands are not
435 required. Then recheck with number of given operands. If they are still not
436 the same, then give an error, otherwise carry on. */
437 for (i
= 0; i
< insn
.tm
->operands
; i
++)
438 if (insn
.tm
->operand_types
[i
] & NotReq
)
440 if (insn
.operands
!= numops
)
442 as_bad ("Incorrect number of operands given");
446 insn
.addressing_mode
= AM_NotReq
;
447 for (count
= 0; count
< insn
.operands
; count
++)
449 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
451 debug ("Operand %d matches\n", count
+ 1);
452 /* If instruction has two operands and has an AddressMode modifier then set
453 addressing mode type for instruction */
454 if (insn
.tm
->opcode_modifier
== AddressMode
)
457 /* Store instruction uses the second operand for the address mode. */
458 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
)) == (Indirect
| Direct
))
460 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
461 insn
.addressing_mode
= AM_Register
;
462 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
463 insn
.addressing_mode
= AM_Direct
;
464 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
465 insn
.addressing_mode
= AM_Indirect
;
467 insn
.addressing_mode
= AM_Immediate
;
472 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
476 /* Now set the addressing mode for 3 operand instructions. */
477 if ((insn
.tm
->operand_types
[0] & op3T1
) && (insn
.tm
->operand_types
[1] & op3T2
))
479 /* Set the addressing mode to the values used for 2 operand instructions in the
480 G addressing field of the opcode. */
482 switch (insn
.operand_type
[0]->op_type
)
488 if (insn
.operand_type
[1]->op_type
& (AllReg
))
489 insn
.addressing_mode
= AM_Register
;
490 else if (insn
.operand_type
[1]->op_type
& Indirect
)
491 insn
.addressing_mode
= AM_Direct
;
494 /* Shouldn't make it to this stage */
495 as_bad ("Incompatible first and second operands in instruction");
500 if (insn
.operand_type
[1]->op_type
& (AllReg
))
501 insn
.addressing_mode
= AM_Indirect
;
502 else if (insn
.operand_type
[1]->op_type
& Indirect
)
503 insn
.addressing_mode
= AM_Immediate
;
506 /* Shouldn't make it to this stage */
507 as_bad ("Incompatible first and second operands in instruction");
512 /* Now make up the opcode for the 3 operand instructions. As in parallel
513 instructions, there will be no unresolved values, so they can be fully formed
514 and added to the frag table. */
515 insn
.opcode
= insn
.tm
->base_opcode
;
516 if (insn
.operand_type
[0]->op_type
& Indirect
)
518 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
519 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
522 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
523 if (insn
.operand_type
[1]->op_type
& Indirect
)
525 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
526 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
529 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
530 if (insn
.operands
== 3)
531 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
532 insn
.opcode
|= insn
.addressing_mode
;
533 p
= frag_more (INSN_SIZE
);
534 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
537 { /* Not a three operand instruction */
540 insn
.opcode
= insn
.tm
->base_opcode
;
541 /* Create frag for instruction - all instructions are 4 bytes long. */
542 p
= frag_more (INSN_SIZE
);
543 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
545 insn
.opcode
|= insn
.addressing_mode
;
546 if (insn
.addressing_mode
== AM_Indirect
)
548 /* Determine which operand gives the addressing mode */
549 if (insn
.operand_type
[0]->op_type
& Indirect
)
551 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Indirect
))
553 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
554 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
555 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
556 if (insn
.operands
> 1)
557 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
558 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
560 else if (insn
.addressing_mode
== AM_Register
)
562 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
563 if (insn
.operands
> 1)
564 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
565 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
567 else if (insn
.addressing_mode
== AM_Direct
)
569 if (insn
.operand_type
[0]->op_type
& Direct
)
571 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Direct
))
573 if (insn
.operands
> 1)
574 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
575 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
577 /* Resolved values can be placed straight into instruction word, and output */
578 insn
.opcode
|= (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
579 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
582 { /* Unresolved direct addressing mode instruction */
583 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
584 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[am_insn
]->direct
.direct_expr
, 0, 0);
587 else if (insn
.addressing_mode
== AM_Immediate
)
589 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
593 if (insn
.operands
> 1)
594 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
595 switch (insn
.tm
->imm_arg_type
)
598 debug ("Floating point first operand\n");
599 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
600 keeploc
= input_line_pointer
;
601 input_line_pointer
= insn
.operand_type
[0]->immediate
.label
;
602 if (md_atof ('f', p
+ 2, &size
) != 0)
604 as_bad ("invalid short form floating point immediate operand");
607 input_line_pointer
= keeploc
;
610 debug ("Unsigned int first operand\n");
611 if (insn
.operand_type
[0]->immediate
.decimal_found
)
612 as_warn ("rounding down first operand float to unsigned int");
613 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
614 as_warn ("only lower 16-bits of first operand are used");
615 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
616 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
619 debug ("Int first operand\n");
620 if (insn
.operand_type
[0]->immediate
.decimal_found
)
621 as_warn ("rounding down first operand float to signed int");
622 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
623 insn
.operand_type
[0]->immediate
.s_number
> 32767)
625 as_bad ("first operand is too large for 16-bit signed int");
628 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
629 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
634 { /* Unresolved immediate label */
635 if (insn
.operands
> 1)
636 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
637 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
638 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
642 else if (insn
.tm
->opcode_modifier
== PCRel
)
644 /* Conditional Branch and Call instructions */
645 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
)) == (AllReg
| Disp
))
647 if (insn
.operand_type
[0]->op_type
& (AllReg
))
649 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
650 insn
.opcode
|= PC_Register
;
651 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
655 insn
.opcode
|= PC_Relative
;
656 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
658 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
659 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
663 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
664 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 1, 0);
668 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
670 /* Decrement and Branch instructions */
671 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
672 if (insn
.operand_type
[1]->op_type
& (AllReg
))
674 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
675 insn
.opcode
|= PC_Register
;
676 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
678 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
680 if (insn
.operand_type
[0]->immediate
.decimal_found
)
682 as_bad ("first operand is floating point");
685 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
686 insn
.operand_type
[0]->immediate
.s_number
> 32767)
688 as_bad ("first operand is too large for 16-bit signed int");
691 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
692 insn
.opcode
|= PC_Relative
;
693 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
697 insn
.opcode
|= PC_Relative
;
698 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
699 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2, &insn
.operand_type
[1]->immediate
.imm_expr
, 1, 0);
703 else if (insn
.tm
->operand_types
[0] == IVector
)
705 /* Trap instructions */
706 if (insn
.operand_type
[0]->op_type
& IVector
)
707 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
709 { /* Shouldn't get here */
710 as_bad ("interrupt vector for trap instruction out of range");
713 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
715 else if (insn
.tm
->opcode_modifier
== StackOp
|| insn
.tm
->opcode_modifier
== Rotate
)
717 /* Push, Pop and Rotate instructions */
718 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
719 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
721 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
)) == (Abs24
| Direct
))
723 /* LDP Instruction needs to be tested for before the next section */
724 if (insn
.operand_type
[0]->op_type
& Direct
)
726 if (insn
.operand_type
[0]->direct
.resolved
== 1)
728 /* Direct addressing uses lower 8 bits of direct address */
729 insn
.opcode
|= (insn
.operand_type
[0]->direct
.address
& 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]->direct
.direct_expr
, 0, 0);
737 /* Ensure that the assembler doesn't complain about fitting a 24-bit
738 address into 8 bits. */
739 fix
->fx_no_overflow
= 1;
744 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
746 /* Immediate addressing uses upper 8 bits of address */
747 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
749 as_bad ("LDP instruction needs a 24-bit operand");
752 insn
.opcode
|= ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
753 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
758 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
759 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
760 fix
->fx_no_overflow
= 1;
764 else if (insn
.tm
->operand_types
[0] & (Imm24
))
766 /* Unconditional Branch and Call instructions */
767 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
769 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
770 as_warn ("first operand is too large for a 24-bit displacement");
771 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
772 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
776 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
777 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
780 else if (insn
.tm
->operand_types
[0] & NotReq
)
782 /* Check for NOP instruction without arguments. */
783 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
785 else if (insn
.tm
->operands
== 0)
787 /* Check for instructions without operands. */
788 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
791 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
794 for (i
= 0; i
< insn
.operands
; i
++)
796 if (insn
.operand_type
[i
]->immediate
.label
)
797 free (insn
.operand_type
[i
]->immediate
.label
);
798 free (insn
.operand_type
[i
]);
801 debug ("Final opcode: %08X\n", insn
.opcode
);
805 struct tic30_par_insn
{
806 partemplate
*tm
; /* Template of current parallel instruction */
807 int operands
[2]; /* Number of given operands for each insn */
808 /* Type of operand given in instruction */
809 operand
*operand_type
[2][MAX_OPERANDS
];
810 int swap_operands
; /* Whether to swap operands around. */
811 unsigned p_field
; /* Value of p field in multiply add/sub instructions */
812 unsigned opcode
; /* Final opcode */
815 struct tic30_par_insn p_insn
;
818 tic30_parallel_insn (char *token
)
820 static partemplate
*p_opcode
;
821 char *current_posn
= token
;
825 debug ("In tic30_parallel_insn with %s\n", token
);
826 memset (&p_insn
, '\0', sizeof (p_insn
));
827 while (is_opcode_char (*current_posn
))
829 { /* Find instruction */
830 save_char
= *current_posn
;
831 *current_posn
= '\0';
832 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
835 debug ("Found instruction %s\n", p_opcode
->name
);
836 p_insn
.tm
= p_opcode
;
840 char first_opcode
[6] =
842 char second_opcode
[6] =
845 int current_opcode
= -1;
848 for (i
= 0; i
< strlen (token
); i
++)
850 char ch
= *(token
+ i
);
851 if (ch
== '_' && current_opcode
== -1)
856 if (ch
== '_' && current_opcode
== 0)
862 switch (current_opcode
)
865 first_opcode
[char_ptr
++] = ch
;
868 second_opcode
[char_ptr
++] = ch
;
872 debug ("first_opcode = %s\n", first_opcode
);
873 debug ("second_opcode = %s\n", second_opcode
);
874 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
875 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
878 debug ("Found instruction %s\n", p_opcode
->name
);
879 p_insn
.tm
= p_opcode
;
880 p_insn
.swap_operands
= 1;
885 *current_posn
= save_char
;
887 { /* Find operands */
888 int paren_not_balanced
;
889 int expecting_operand
= 0;
890 int found_separator
= 0;
893 /* skip optional white space before operand */
894 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
896 if (!is_space_char (*current_posn
) && *current_posn
!= PARALLEL_SEPARATOR
)
898 as_bad ("Invalid character %s before %s operand",
899 output_invalid (*current_posn
),
900 ordinal_names
[insn
.operands
]);
903 if (*current_posn
== PARALLEL_SEPARATOR
)
907 token_start
= current_posn
; /* after white space */
908 paren_not_balanced
= 0;
909 while (paren_not_balanced
|| *current_posn
!= ',')
911 if (*current_posn
== END_OF_INSN
)
913 if (paren_not_balanced
)
915 as_bad ("Unbalanced parenthesis in %s operand.",
916 ordinal_names
[insn
.operands
]);
920 break; /* we are done */
922 else if (*current_posn
== PARALLEL_SEPARATOR
)
924 while (is_space_char (*(current_posn
- 1)))
928 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
930 as_bad ("Invalid character %s in %s operand",
931 output_invalid (*current_posn
),
932 ordinal_names
[insn
.operands
]);
935 if (*current_posn
== '(')
936 ++paren_not_balanced
;
937 if (*current_posn
== ')')
938 --paren_not_balanced
;
941 if (current_posn
!= token_start
)
942 { /* yes, we've read in another operand */
943 p_insn
.operands
[found_separator
]++;
944 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
946 as_bad ("Spurious operands; (%d operands/instruction max)",
950 /* now parse operand adding info to 'insn' as we go along */
951 save_char
= *current_posn
;
952 *current_posn
= '\0';
953 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
954 tic30_operand (token_start
);
955 *current_posn
= save_char
;
956 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
961 if (expecting_operand
)
963 as_bad ("Expecting operand after ','; got nothing");
966 if (*current_posn
== ',')
968 as_bad ("Expecting operand before ','; got nothing");
972 /* now *current_posn must be either ',' or END_OF_INSN */
973 if (*current_posn
== ',')
975 if (*++current_posn
== END_OF_INSN
)
976 { /* just skip it, if it's \n complain */
977 as_bad ("Expecting operand after ','; got nothing");
980 expecting_operand
= 1;
983 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
985 if (p_insn
.swap_operands
)
990 temp_num
= p_insn
.operands
[0];
991 p_insn
.operands
[0] = p_insn
.operands
[1];
992 p_insn
.operands
[1] = temp_num
;
993 for (i
= 0; i
< MAX_OPERANDS
; i
++)
995 temp_op
= p_insn
.operand_type
[0][i
];
996 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
997 p_insn
.operand_type
[1][i
] = temp_op
;
1000 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
1002 as_bad ("incorrect number of operands given in the first instruction");
1005 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
1007 as_bad ("incorrect number of operands given in the second instruction");
1010 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
1011 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
1012 { /* Now check if operands are correct */
1016 for (count
= 0; count
< 2; count
++)
1019 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
1021 if ((p_insn
.operand_type
[count
][i
]->op_type
&
1022 p_insn
.tm
->operand_types
[count
][i
]) == 0)
1024 as_bad ("%s instruction, operand %d doesn't match", ordinal_names
[count
], i
+ 1);
1027 /* Get number of R register and indirect reference contained within the first
1028 two operands of each instruction. This is required for the multiply
1029 parallel instructions which require two R registers and two indirect
1030 references, but not in any particular place. */
1031 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
1033 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
) && i
< 2)
1037 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
)) == (Indirect
| Rn
))
1039 /* Check for the multiply instructions */
1042 as_bad ("incorrect format for multiply parallel instruction");
1046 { /* Shouldn't get here */
1047 as_bad ("incorrect format for multiply parallel instruction");
1050 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00) &&
1051 (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
1053 as_bad ("destination for multiply can only be R0 or R1");
1056 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02) &&
1057 (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
1059 as_bad ("destination for add/subtract can only be R2 or R3");
1062 /* Now determine the P field for the instruction */
1063 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
1065 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
1066 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn */
1067 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1068 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn */
1070 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind */
1074 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
1075 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind */
1076 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1079 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn */
1080 /* Need to swap the two multiply operands around so that everything is in
1081 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1082 temp
= p_insn
.operand_type
[0][0];
1083 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1084 p_insn
.operand_type
[0][1] = temp
;
1089 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind */
1090 temp
= p_insn
.operand_type
[0][0];
1091 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1092 p_insn
.operand_type
[0][1] = temp
;
1097 debug ("P field: %08X\n", p_insn
.p_field
);
1098 /* Finalise opcode. This is easier for parallel instructions as they have to be
1099 fully resolved, there are no memory addresses allowed, except through indirect
1100 addressing, so there are no labels to resolve. */
1102 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
1103 switch (p_insn
.tm
->oporder
)
1106 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1107 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1108 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1109 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1110 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1111 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1114 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1115 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1116 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1117 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1118 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1119 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1120 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1121 as_warn ("loading the same register in parallel operation");
1124 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1125 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1126 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1127 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1128 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1129 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1132 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1133 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1134 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1135 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1136 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1137 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1138 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1141 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1142 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1143 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1144 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1145 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1146 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1147 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1150 p_insn
.opcode
|= p_insn
.p_field
;
1151 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1152 p_insn
.opcode
|= 0x00800000;
1153 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1154 p_insn
.opcode
|= 0x00400000;
1155 switch (p_insn
.p_field
)
1158 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1159 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1160 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1161 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1162 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1163 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1166 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1167 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1168 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1169 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1170 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1171 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1174 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1175 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1176 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1177 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1178 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1179 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1182 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1183 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1184 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1185 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1186 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1187 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1192 } /* Opcode is finalised at this point for all parallel instructions. */
1193 { /* Output opcode */
1195 p
= frag_more (INSN_SIZE
);
1196 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1200 for (i
= 0; i
< 2; i
++)
1201 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1202 free (p_insn
.operand_type
[i
][j
]);
1204 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1210 tic30_operand (token
)
1214 char ind_buffer
[strlen (token
)];
1215 operand
*current_op
;
1217 debug ("In tic30_operand with %s\n", token
);
1218 current_op
= (operand
*) malloc (sizeof (operand
));
1219 memset (current_op
, '\0', sizeof (operand
));
1220 if (*token
== DIRECT_REFERENCE
)
1222 char *token_posn
= token
+ 1;
1223 int direct_label
= 0;
1224 debug ("Found direct reference\n");
1227 if (!is_digit_char (*token_posn
))
1233 char *save_input_line_pointer
;
1235 debug ("Direct reference is a label\n");
1236 current_op
->direct
.label
= token
+ 1;
1237 save_input_line_pointer
= input_line_pointer
;
1238 input_line_pointer
= token
+ 1;
1239 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1240 retval
= expression (¤t_op
->direct
.direct_expr
);
1241 debug ("Expression type: %d\n", current_op
->direct
.direct_expr
.X_op
);
1242 debug ("Expression addnum: %d\n", current_op
->direct
.direct_expr
.X_add_number
);
1243 debug ("Segment: %d\n", retval
);
1244 input_line_pointer
= save_input_line_pointer
;
1245 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
1247 current_op
->direct
.address
= current_op
->direct
.direct_expr
.X_add_number
;
1248 current_op
->direct
.resolved
= 1;
1253 debug ("Direct reference is a number\n");
1254 current_op
->direct
.address
= atoi (token
+ 1);
1255 current_op
->direct
.resolved
= 1;
1257 current_op
->op_type
= Direct
;
1259 else if (*token
== INDIRECT_REFERENCE
)
1260 { /* Indirect reference operand */
1264 int disp_number
= 0;
1265 int buffer_posn
= 1;
1266 ind_addr_type
*ind_addr_op
;
1267 debug ("Found indirect reference\n");
1268 ind_buffer
[0] = *token
;
1269 for (count
= 1; count
< strlen (token
); count
++)
1270 { /* Strip operand */
1271 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
1272 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A') &&
1273 (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
1275 /* AR reference is found, so get its number and remove it from the buffer
1276 so it can pass through hash_find() */
1279 as_bad ("More than one AR register found in indirect reference");
1282 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
1284 as_bad ("Illegal AR register in indirect reference");
1287 ar_number
= *(token
+ count
+ 1) - '0';
1291 if (*(token
+ count
) == '(')
1293 /* Parenthesis found, so check if a displacement value is inside. If so, get
1294 the value and remove it from the buffer. */
1295 if (is_digit_char (*(token
+ count
+ 1)))
1302 as_bad ("More than one displacement found in indirect reference");
1306 while (*(token
+ count
) != ')')
1308 if (!is_digit_char (*(token
+ count
)))
1310 as_bad ("Invalid displacement in indirect reference");
1313 disp
[disp_posn
++] = *(token
+ (count
++));
1315 disp
[disp_posn
] = '\0';
1316 disp_number
= atoi (disp
);
1323 ind_buffer
[buffer_posn
] = '\0';
1326 as_bad ("AR register not found in indirect reference");
1329 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
1332 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
1333 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
1338 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
1340 /* Maybe an implied displacement of 1 again */
1341 as_bad ("required displacement wasn't given in indirect reference");
1347 as_bad ("illegal indirect reference");
1350 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
1352 as_bad ("displacement must be an unsigned 8-bit number");
1355 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
1356 current_op
->indirect
.disp
= disp_number
;
1357 current_op
->indirect
.ARnum
= ar_number
;
1358 current_op
->op_type
= Indirect
;
1362 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
1365 debug ("Found register operand: %s\n", regop
->name
);
1366 if (regop
->regtype
== REG_ARn
)
1367 current_op
->op_type
= ARn
;
1368 else if (regop
->regtype
== REG_Rn
)
1369 current_op
->op_type
= Rn
;
1370 else if (regop
->regtype
== REG_DP
)
1371 current_op
->op_type
= DPReg
;
1373 current_op
->op_type
= OtherReg
;
1374 current_op
->reg
.opcode
= regop
->opcode
;
1378 if (!is_digit_char (*token
) || *(token
+ 1) == 'x' || strchr (token
, 'h'))
1380 char *save_input_line_pointer
;
1382 debug ("Probably a label: %s\n", token
);
1383 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1384 strcpy (current_op
->immediate
.label
, token
);
1385 current_op
->immediate
.label
[strlen (token
)] = '\0';
1386 save_input_line_pointer
= input_line_pointer
;
1387 input_line_pointer
= token
;
1388 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1389 retval
= expression (¤t_op
->immediate
.imm_expr
);
1390 debug ("Expression type: %d\n", current_op
->immediate
.imm_expr
.X_op
);
1391 debug ("Expression addnum: %d\n", current_op
->immediate
.imm_expr
.X_add_number
);
1392 debug ("Segment: %d\n", retval
);
1393 input_line_pointer
= save_input_line_pointer
;
1394 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
1396 current_op
->immediate
.s_number
= current_op
->immediate
.imm_expr
.X_add_number
;
1397 current_op
->immediate
.u_number
= (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
1398 current_op
->immediate
.resolved
= 1;
1404 debug ("Found a number or displacement\n");
1405 for (count
= 0; count
< strlen (token
); count
++)
1406 if (*(token
+ count
) == '.')
1407 current_op
->immediate
.decimal_found
= 1;
1408 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1409 strcpy (current_op
->immediate
.label
, token
);
1410 current_op
->immediate
.label
[strlen (token
)] = '\0';
1411 current_op
->immediate
.f_number
= (float) atof (token
);
1412 current_op
->immediate
.s_number
= (int) atoi (token
);
1413 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
1414 current_op
->immediate
.resolved
= 1;
1416 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
1417 if (current_op
->immediate
.u_number
>= 0 && current_op
->immediate
.u_number
<= 31)
1418 current_op
->op_type
|= IVector
;
1424 /* next_line points to the next line after the current instruction (current_line).
1425 Search for the parallel bars, and if found, merge two lines into internal syntax
1426 for a parallel instruction:
1427 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1428 By this stage, all comments are scrubbed, and only the bare lines are given.
1432 #define START_OPCODE 1
1433 #define END_OPCODE 2
1434 #define START_OPERANDS 3
1435 #define END_OPERANDS 4
1438 tic30_find_parallel_insn (current_line
, next_line
)
1442 int found_parallel
= 0;
1443 char first_opcode
[256];
1444 char second_opcode
[256];
1445 char first_operands
[256];
1446 char second_operands
[256];
1447 char *parallel_insn
;
1449 debug ("In tic30_find_parallel_insn()\n");
1450 while (!is_end_of_line
[(unsigned char) *next_line
])
1452 if (*next_line
== PARALLEL_SEPARATOR
&& *(next_line
+ 1) == PARALLEL_SEPARATOR
)
1460 if (!found_parallel
)
1462 debug ("Found a parallel instruction\n");
1465 char *opcode
, *operands
, *line
;
1467 for (i
= 0; i
< 2; i
++)
1471 opcode
= &first_opcode
[0];
1472 operands
= &first_operands
[0];
1473 line
= current_line
;
1477 opcode
= &second_opcode
[0];
1478 operands
= &second_operands
[0];
1482 int search_status
= NONE
;
1486 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
1488 if (is_opcode_char (c
) && search_status
== NONE
)
1490 opcode
[char_ptr
++] = TOLOWER (c
);
1491 search_status
= START_OPCODE
;
1493 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
1495 opcode
[char_ptr
++] = TOLOWER (c
);
1497 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
1499 opcode
[char_ptr
] = '\0';
1501 search_status
= END_OPCODE
;
1503 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
1505 operands
[char_ptr
++] = c
;
1507 if (is_operand_char (c
) && search_status
== END_OPCODE
)
1509 operands
[char_ptr
++] = c
;
1510 search_status
= START_OPERANDS
;
1514 if (search_status
!= START_OPERANDS
)
1516 operands
[char_ptr
] = '\0';
1520 parallel_insn
= (char *) malloc (strlen (first_opcode
) + strlen (first_operands
) +
1521 strlen (second_opcode
) + strlen (second_operands
) + 8);
1522 sprintf (parallel_insn
, "q_%s_%s %s | %s", first_opcode
, second_opcode
, first_operands
, second_operands
);
1523 debug ("parallel insn = %s\n", parallel_insn
);
1524 return parallel_insn
;
1530 #undef START_OPERANDS
1533 /* In order to get gas to ignore any | chars at the start of a line,
1534 this function returns true if a | is found in a line. */
1537 tic30_unrecognized_line (c
)
1540 debug ("In tc_unrecognized_line\n");
1541 return (c
== PARALLEL_SEPARATOR
);
1545 md_estimate_size_before_relax (fragP
, segment
)
1549 debug ("In md_estimate_size_before_relax()\n");
1554 md_convert_frag (abfd
, sec
, fragP
)
1557 register fragS
*fragP
;
1559 debug ("In md_convert_frag()\n");
1563 md_apply_fix3 (fixP
, valP
, seg
)
1566 segT seg ATTRIBUTE_UNUSED
;
1568 valueT value
= *valP
;
1570 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1571 debug ("Values in fixP\n");
1572 debug ("fx_size = %d\n", fixP
->fx_size
);
1573 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1574 debug ("fx_where = %d\n", fixP
->fx_where
);
1575 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1577 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1580 if (fixP
->fx_size
== 1)
1581 /* Special fix for LDP instruction. */
1582 value
= (value
& 0x00FF0000) >> 16;
1584 debug ("new value = %ld\n", (long) value
);
1585 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1588 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1593 md_parse_option (c
, arg
)
1599 debug ("In md_parse_option()\n");
1600 for (i
= 0; i
< c
; i
++)
1602 printf ("%c\n", arg
[c
]);
1608 md_show_usage (stream
)
1611 debug ("In md_show_usage()\n");
1615 md_undefined_symbol (name
)
1618 debug ("In md_undefined_symbol()\n");
1619 return (symbolS
*) 0;
1623 md_section_align (segment
, size
)
1627 debug ("In md_section_align() segment = %d and size = %d\n", segment
, size
);
1628 size
= (size
+ 3) / 4;
1630 debug ("New size value = %d\n", size
);
1635 md_pcrel_from (fixP
)
1640 debug ("In md_pcrel_from()\n");
1641 debug ("fx_where = %d\n", fixP
->fx_where
);
1642 debug ("fx_size = %d\n", fixP
->fx_size
);
1643 /* Find the opcode that represents the current instruction in the fr_literal
1644 storage area, and check bit 21. Bit 21 contains whether the current instruction
1645 is a delayed one or not, and then set the offset value appropriately. */
1646 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1650 debug ("offset = %d\n", offset
);
1651 /* PC Relative instructions have a format:
1652 displacement = Label - (PC + offset)
1653 This function returns PC + offset where:
1654 fx_where - fx_size = PC
1655 INSN_SIZE * offset = offset number of instructions
1657 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1661 md_atof (what_statement_type
, literalP
, sizeP
)
1662 int what_statement_type
;
1669 unsigned long value
;
1670 /* char *atof_ieee (); */
1672 debug ("In md_atof()\n");
1673 debug ("precision = %c\n", what_statement_type
);
1674 debug ("literal = %s\n", literalP
);
1676 token
= input_line_pointer
;
1677 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1678 && (*input_line_pointer
!= ','))
1680 debug ("%c", *input_line_pointer
);
1681 input_line_pointer
++;
1683 keepval
= *input_line_pointer
;
1684 *input_line_pointer
= '\0';
1686 float_value
= (float) atof (token
);
1687 *input_line_pointer
= keepval
;
1688 debug ("float_value = %f\n", float_value
);
1689 switch (what_statement_type
)
1707 return "Bad call to MD_ATOF()";
1709 if (float_value
== 0.0)
1711 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1715 unsigned long exp
, sign
, mant
, tmsfloat
;
1716 tmsfloat
= *((long *) &float_value
);
1717 sign
= tmsfloat
& 0x80000000;
1718 mant
= tmsfloat
& 0x007FFFFF;
1719 exp
= tmsfloat
& 0x7F800000;
1721 if (exp
== 0xFF000000)
1735 mant
= mant
& 0x007FFFFF;
1737 mant
= mant
& 0x00FFFFFF;
1741 exp
= (long) exp
- 0x01000000;
1744 tmsfloat
= exp
| mant
;
1751 if (tmsfloat
== 0x80000000)
1758 exp
= (tmsfloat
& 0xFF000000);
1760 mant
= tmsfloat
& 0x007FFFFF;
1761 if (tmsfloat
& 0x00800000)
1775 exp
+= (mant
>> 24);
1785 mant
= (exp
<< 12) | mant
;
1786 value
= mant
& 0xFFFF;
1791 md_number_to_chars (literalP
, value
, prec
);
1797 md_number_to_chars (buf
, val
, n
)
1802 debug ("In md_number_to_chars()\n");
1803 number_to_chars_bigendian (buf
, val
, n
);
1804 /* number_to_chars_littleendian(buf,val,n); */
1807 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1808 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1811 tc_gen_reloc (section
, fixP
)
1816 bfd_reloc_code_real_type code
= 0;
1818 debug ("In tc_gen_reloc()\n");
1819 debug ("fixP.size = %d\n", fixP
->fx_size
);
1820 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1821 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1822 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1824 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1825 MAP (2, 0, BFD_RELOC_16
);
1826 MAP (3, 0, BFD_RELOC_24
);
1827 MAP (2, 1, BFD_RELOC_16_PCREL
);
1828 MAP (4, 0, BFD_RELOC_32
);
1830 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1831 fixP
->fx_pcrel
? "pc-relative " : "");
1836 rel
= (arelent
*) xmalloc (sizeof (arelent
));
1838 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1839 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1840 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1842 rel
->addend
= fixP
->fx_addnumber
;
1845 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1849 name
= S_GET_NAME (fixP
->fx_addsy
);
1852 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name
, bfd_get_reloc_code_name (code
));
1858 tc_aout_pre_write_hook ()
1860 debug ("In tc_aout_pre_write_hook()\n");
1864 md_operand (expressionP
)
1865 expressionS
*expressionP
;
1867 debug ("In md_operand()\n");
1870 char output_invalid_buf
[8];
1877 sprintf (output_invalid_buf
, "'%c'", c
);
1879 sprintf (output_invalid_buf
, "(0x%x)", (unsigned) c
);
1880 return output_invalid_buf
;