1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000 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 "opcode/tic30.h"
30 /* Put here all non-digit non-letter charcters that may occur in an
32 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
33 static char *ordinal_names
[] = {
34 "first", "second", "third", "fourth", "fifth"
37 const int md_reloc_size
= 0;
39 const char comment_chars
[] = ";";
40 const char line_comment_chars
[] = "*";
41 const char line_separator_chars
[] = "";
43 const char *md_shortopts
= "";
44 struct option md_longopts
[] = {
45 {NULL
, no_argument
, NULL
, 0}
48 size_t md_longopts_size
= sizeof (md_longopts
);
50 /* Chars that mean this number is a floating point constant. */
53 const char FLT_CHARS
[] = "fFdDxX";
55 /* Chars that can be used to separate mant from exp in floating point
57 const char EXP_CHARS
[] = "eE";
59 /* tables for lexical analysis */
60 static char opcode_chars
[256];
61 static char register_chars
[256];
62 static char operand_chars
[256];
63 static char space_chars
[256];
64 static char identifier_chars
[256];
65 static char digit_chars
[256];
68 #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
69 #define is_operand_char(x) (operand_chars[(unsigned char) x])
70 #define is_register_char(x) (register_chars[(unsigned char) x])
71 #define is_space_char(x) (space_chars[(unsigned char) x])
72 #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
73 #define is_digit_char(x) (digit_chars[(unsigned char) x])
75 const pseudo_typeS md_pseudo_table
[] = {
87 debug (const char *string
, ...)
94 va_start (argptr
, string
);
95 vsprintf (str
, string
, argptr
);
99 fputs (str
, USE_STDOUT
? stdout
: stderr
);
107 debug (string
, va_alist
)
117 va_start (argptr
, string
);
118 cnt
= vsprintf (str
, string
, argptr
);
122 fputs (str
, USE_STDOUT
? stdout
: stderr
);
130 /* hash table for opcode lookup */
131 static struct hash_control
*op_hash
;
132 /* hash table for parallel opcode lookup */
133 static struct hash_control
*parop_hash
;
134 /* hash table for register lookup */
135 static struct hash_control
*reg_hash
;
136 /* hash table for indirect addressing lookup */
137 static struct hash_control
*ind_hash
;
142 const char *hash_err
;
143 debug ("In md_begin()\n");
144 op_hash
= hash_new ();
146 const template *current_optab
= tic30_optab
;
147 for (; current_optab
< tic30_optab_end
; current_optab
++)
149 hash_err
= hash_insert (op_hash
, current_optab
->name
, (char *) current_optab
);
151 as_fatal ("Internal Error: Can't Hash %s: %s", current_optab
->name
, hash_err
);
154 parop_hash
= hash_new ();
156 const partemplate
*current_parop
= tic30_paroptab
;
157 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
159 hash_err
= hash_insert (parop_hash
, current_parop
->name
, (char *) current_parop
);
161 as_fatal ("Internal Error: Can't Hash %s: %s", current_parop
->name
, hash_err
);
164 reg_hash
= hash_new ();
166 const reg
*current_reg
= tic30_regtab
;
167 for (; current_reg
< tic30_regtab_end
; current_reg
++)
169 hash_err
= hash_insert (reg_hash
, current_reg
->name
, (char *) current_reg
);
171 as_fatal ("Internal Error: Can't Hash %s: %s", current_reg
->name
, hash_err
);
174 ind_hash
= hash_new ();
176 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
177 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
179 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
, (char *) current_ind
);
181 as_fatal ("Internal Error: Can't Hash %s: %s", current_ind
->syntax
, hash_err
);
184 /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
189 for (c
= 0; c
< 256; c
++)
191 if (islower (c
) || isdigit (c
))
194 register_chars
[c
] = c
;
196 else if (isupper (c
))
198 opcode_chars
[c
] = tolower (c
);
199 register_chars
[c
] = opcode_chars
[c
];
201 else if (c
== ')' || c
== '(')
203 register_chars
[c
] = c
;
205 if (isupper (c
) || islower (c
) || isdigit (c
))
206 operand_chars
[c
] = c
;
207 if (isdigit (c
) || c
== '-')
209 if (isalpha (c
) || c
== '_' || c
== '.' || isdigit (c
))
210 identifier_chars
[c
] = c
;
211 if (c
== ' ' || c
== '\t')
216 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
217 operand_chars
[(unsigned char) *p
] = *p
;
221 /* Address Mode OR values */
222 #define AM_Register 0x00000000
223 #define AM_Direct 0x00200000
224 #define AM_Indirect 0x00400000
225 #define AM_Immediate 0x00600000
226 #define AM_NotReq 0xFFFFFFFF
228 /* PC Relative OR values */
229 #define PC_Register 0x00000000
230 #define PC_Relative 0x02000000
238 expressionS direct_expr
;
253 unsigned int u_number
;
255 expressionS imm_expr
;
259 int tic30_parallel_insn
PARAMS ((char *));
260 operand
*tic30_operand
PARAMS ((char *));
261 char *tic30_find_parallel_insn
PARAMS ((char *, char *));
266 template *tm
; /* Template of current instruction */
267 unsigned opcode
; /* Final opcode */
268 int operands
; /* Number of given operands */
269 /* Type of operand given in instruction */
270 operand
*operand_type
[MAX_OPERANDS
];
271 unsigned addressing_mode
; /* Final addressing mode of instruction */
274 struct tic30_insn insn
;
275 static int found_parallel_insn
;
287 debug ("In md_assemble() with argument %s\n", line
);
288 memset (&insn
, '\0', sizeof (insn
));
289 if (found_parallel_insn
)
291 debug ("Line is second part of parallel instruction\n\n");
292 found_parallel_insn
= 0;
295 if ((current_posn
= tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
298 found_parallel_insn
= 1;
299 while (is_space_char (*current_posn
))
301 token_start
= current_posn
;
302 if (!is_opcode_char (*current_posn
))
304 as_bad ("Invalid character %s in opcode", output_invalid (*current_posn
));
307 /* Check if instruction is a parallel instruction by seeing if the first
309 if (*token_start
== 'q')
311 if (tic30_parallel_insn (token_start
))
313 if (found_parallel_insn
)
318 while (is_opcode_char (*current_posn
))
320 { /* Find instruction */
321 save_char
= *current_posn
;
322 *current_posn
= '\0';
323 opcode
= (template *) hash_find (op_hash
, token_start
);
326 debug ("Found instruction %s\n", opcode
->name
);
331 debug ("Didn't find insn\n");
332 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
335 *current_posn
= save_char
;
337 if (*current_posn
!= END_OF_INSN
)
338 { /* Find operands */
339 int paren_not_balanced
;
340 int expecting_operand
= 0;
344 /* skip optional white space before operand */
345 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
347 if (!is_space_char (*current_posn
))
349 as_bad ("Invalid character %s before %s operand",
350 output_invalid (*current_posn
),
351 ordinal_names
[insn
.operands
]);
356 token_start
= current_posn
; /* after white space */
357 paren_not_balanced
= 0;
358 while (paren_not_balanced
|| *current_posn
!= ',')
360 if (*current_posn
== END_OF_INSN
)
362 if (paren_not_balanced
)
364 as_bad ("Unbalanced parenthesis in %s operand.",
365 ordinal_names
[insn
.operands
]);
369 break; /* we are done */
371 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
373 as_bad ("Invalid character %s in %s operand",
374 output_invalid (*current_posn
),
375 ordinal_names
[insn
.operands
]);
378 if (*current_posn
== '(')
379 ++paren_not_balanced
;
380 if (*current_posn
== ')')
381 --paren_not_balanced
;
384 if (current_posn
!= token_start
)
385 { /* yes, we've read in another operand */
386 this_operand
= insn
.operands
++;
387 if (insn
.operands
> MAX_OPERANDS
)
389 as_bad ("Spurious operands; (%d operands/instruction max)",
393 /* now parse operand adding info to 'insn' as we go along */
394 save_char
= *current_posn
;
395 *current_posn
= '\0';
396 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
397 *current_posn
= save_char
;
398 if (insn
.operand_type
[this_operand
] == NULL
)
403 if (expecting_operand
)
405 as_bad ("Expecting operand after ','; got nothing");
408 if (*current_posn
== ',')
410 as_bad ("Expecting operand before ','; got nothing");
414 /* now *current_posn must be either ',' or END_OF_INSN */
415 if (*current_posn
== ',')
417 if (*++current_posn
== END_OF_INSN
)
418 { /* just skip it, if it's \n complain */
419 as_bad ("Expecting operand after ','; got nothing");
422 expecting_operand
= 1;
425 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
427 debug ("Number of operands found: %d\n", insn
.operands
);
428 /* Check that number of operands is correct */
429 if (insn
.operands
!= insn
.tm
->operands
)
432 int numops
= insn
.tm
->operands
;
433 /* If operands are not the same, then see if any of the operands are not
434 required. Then recheck with number of given operands. If they are still not
435 the same, then give an error, otherwise carry on. */
436 for (i
= 0; i
< insn
.tm
->operands
; i
++)
437 if (insn
.tm
->operand_types
[i
] & NotReq
)
439 if (insn
.operands
!= numops
)
441 as_bad ("Incorrect number of operands given");
445 insn
.addressing_mode
= AM_NotReq
;
446 for (count
= 0; count
< insn
.operands
; count
++)
448 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
450 debug ("Operand %d matches\n", count
+ 1);
451 /* If instruction has two operands and has an AddressMode modifier then set
452 addressing mode type for instruction */
453 if (insn
.tm
->opcode_modifier
== AddressMode
)
456 /* Store instruction uses the second operand for the address mode. */
457 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
)) == (Indirect
| Direct
))
459 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
460 insn
.addressing_mode
= AM_Register
;
461 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
462 insn
.addressing_mode
= AM_Direct
;
463 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
464 insn
.addressing_mode
= AM_Indirect
;
466 insn
.addressing_mode
= AM_Immediate
;
471 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
475 /* Now set the addressing mode for 3 operand instructions. */
476 if ((insn
.tm
->operand_types
[0] & op3T1
) && (insn
.tm
->operand_types
[1] & op3T2
))
478 /* Set the addressing mode to the values used for 2 operand instructions in the
479 G addressing field of the opcode. */
481 switch (insn
.operand_type
[0]->op_type
)
487 if (insn
.operand_type
[1]->op_type
& (AllReg
))
488 insn
.addressing_mode
= AM_Register
;
489 else if (insn
.operand_type
[1]->op_type
& Indirect
)
490 insn
.addressing_mode
= AM_Direct
;
493 /* Shouldn't make it to this stage */
494 as_bad ("Incompatible first and second operands in instruction");
499 if (insn
.operand_type
[1]->op_type
& (AllReg
))
500 insn
.addressing_mode
= AM_Indirect
;
501 else if (insn
.operand_type
[1]->op_type
& Indirect
)
502 insn
.addressing_mode
= AM_Immediate
;
505 /* Shouldn't make it to this stage */
506 as_bad ("Incompatible first and second operands in instruction");
511 /* Now make up the opcode for the 3 operand instructions. As in parallel
512 instructions, there will be no unresolved values, so they can be fully formed
513 and added to the frag table. */
514 insn
.opcode
= insn
.tm
->base_opcode
;
515 if (insn
.operand_type
[0]->op_type
& Indirect
)
517 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
518 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
521 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
522 if (insn
.operand_type
[1]->op_type
& Indirect
)
524 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
525 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
528 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
529 if (insn
.operands
== 3)
530 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
531 insn
.opcode
|= insn
.addressing_mode
;
532 p
= frag_more (INSN_SIZE
);
533 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
536 { /* Not a three operand instruction */
539 insn
.opcode
= insn
.tm
->base_opcode
;
540 /* Create frag for instruction - all instructions are 4 bytes long. */
541 p
= frag_more (INSN_SIZE
);
542 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
544 insn
.opcode
|= insn
.addressing_mode
;
545 if (insn
.addressing_mode
== AM_Indirect
)
547 /* Determine which operand gives the addressing mode */
548 if (insn
.operand_type
[0]->op_type
& Indirect
)
550 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Indirect
))
552 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
553 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
554 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
555 if (insn
.operands
> 1)
556 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
557 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
559 else if (insn
.addressing_mode
== AM_Register
)
561 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
562 if (insn
.operands
> 1)
563 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
564 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
566 else if (insn
.addressing_mode
== AM_Direct
)
568 if (insn
.operand_type
[0]->op_type
& Direct
)
570 if ((insn
.operands
> 1) && (insn
.operand_type
[1]->op_type
& Direct
))
572 if (insn
.operands
> 1)
573 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
574 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
576 /* Resolved values can be placed straight into instruction word, and output */
577 insn
.opcode
|= (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
578 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
581 { /* Unresolved direct addressing mode instruction */
582 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
583 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[am_insn
]->direct
.direct_expr
, 0, 0);
586 else if (insn
.addressing_mode
== AM_Immediate
)
588 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
592 if (insn
.operands
> 1)
593 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
594 switch (insn
.tm
->imm_arg_type
)
597 debug ("Floating point first operand\n");
598 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
599 keeploc
= input_line_pointer
;
600 input_line_pointer
= insn
.operand_type
[0]->immediate
.label
;
601 if (md_atof ('f', p
+ 2, &size
) != 0)
603 as_bad ("invalid short form floating point immediate operand");
606 input_line_pointer
= keeploc
;
609 debug ("Unsigned int first operand\n");
610 if (insn
.operand_type
[0]->immediate
.decimal_found
)
611 as_warn ("rounding down first operand float to unsigned int");
612 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
613 as_warn ("only lower 16-bits of first operand are used");
614 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
615 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
618 debug ("Int first operand\n");
619 if (insn
.operand_type
[0]->immediate
.decimal_found
)
620 as_warn ("rounding down first operand float to signed int");
621 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
622 insn
.operand_type
[0]->immediate
.s_number
> 32767)
624 as_bad ("first operand is too large for 16-bit signed int");
627 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
628 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
633 { /* Unresolved immediate label */
634 if (insn
.operands
> 1)
635 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
636 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
637 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
641 else if (insn
.tm
->opcode_modifier
== PCRel
)
643 /* Conditional Branch and Call instructions */
644 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
)) == (AllReg
| Disp
))
646 if (insn
.operand_type
[0]->op_type
& (AllReg
))
648 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
649 insn
.opcode
|= PC_Register
;
650 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
654 insn
.opcode
|= PC_Relative
;
655 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
657 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
658 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
662 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
663 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2, &insn
.operand_type
[0]->immediate
.imm_expr
, 1, 0);
667 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
669 /* Decrement and Branch instructions */
670 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
671 if (insn
.operand_type
[1]->op_type
& (AllReg
))
673 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
674 insn
.opcode
|= PC_Register
;
675 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
677 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
679 if (insn
.operand_type
[0]->immediate
.decimal_found
)
681 as_bad ("first operand is floating point");
684 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
685 insn
.operand_type
[0]->immediate
.s_number
> 32767)
687 as_bad ("first operand is too large for 16-bit signed int");
690 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
691 insn
.opcode
|= PC_Relative
;
692 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
696 insn
.opcode
|= PC_Relative
;
697 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
698 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2, &insn
.operand_type
[1]->immediate
.imm_expr
, 1, 0);
702 else if (insn
.tm
->operand_types
[0] == IVector
)
704 /* Trap instructions */
705 if (insn
.operand_type
[0]->op_type
& IVector
)
706 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
708 { /* Shouldn't get here */
709 as_bad ("interrupt vector for trap instruction out of range");
712 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
714 else if (insn
.tm
->opcode_modifier
== StackOp
|| insn
.tm
->opcode_modifier
== Rotate
)
716 /* Push, Pop and Rotate instructions */
717 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
718 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
720 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
)) == (Abs24
| Direct
))
722 /* LDP Instruction needs to be tested for before the next section */
723 if (insn
.operand_type
[0]->op_type
& Direct
)
725 if (insn
.operand_type
[0]->direct
.resolved
== 1)
727 /* Direct addressing uses lower 8 bits of direct address */
728 insn
.opcode
|= (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
729 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
734 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
735 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
736 /* Ensure that the assembler doesn't complain about fitting a 24-bit
737 address into 8 bits. */
738 fix
->fx_no_overflow
= 1;
743 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
745 /* Immediate addressing uses upper 8 bits of address */
746 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
748 as_bad ("LDP instruction needs a 24-bit operand");
751 insn
.opcode
|= ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
752 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
757 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
758 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
), 1, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
759 fix
->fx_no_overflow
= 1;
763 else if (insn
.tm
->operand_types
[0] & (Imm24
))
765 /* Unconditional Branch and Call instructions */
766 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
768 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
769 as_warn ("first operand is too large for a 24-bit displacement");
770 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
771 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
775 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
776 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3, &insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
779 else if (insn
.tm
->operand_types
[0] & NotReq
)
781 /* Check for NOP instruction without arguments. */
782 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
784 else if (insn
.tm
->operands
== 0)
786 /* Check for instructions without operands. */
787 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
790 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
793 for (i
= 0; i
< insn
.operands
; i
++)
795 if (insn
.operand_type
[i
]->immediate
.label
)
796 free (insn
.operand_type
[i
]->immediate
.label
);
797 free (insn
.operand_type
[i
]);
800 debug ("Final opcode: %08X\n", insn
.opcode
);
804 struct tic30_par_insn
{
805 partemplate
*tm
; /* Template of current parallel instruction */
806 int operands
[2]; /* Number of given operands for each insn */
807 /* Type of operand given in instruction */
808 operand
*operand_type
[2][MAX_OPERANDS
];
809 int swap_operands
; /* Whether to swap operands around. */
810 unsigned p_field
; /* Value of p field in multiply add/sub instructions */
811 unsigned opcode
; /* Final opcode */
814 struct tic30_par_insn p_insn
;
817 tic30_parallel_insn (char *token
)
819 static partemplate
*p_opcode
;
820 char *current_posn
= token
;
824 debug ("In tic30_parallel_insn with %s\n", token
);
825 memset (&p_insn
, '\0', sizeof (p_insn
));
826 while (is_opcode_char (*current_posn
))
828 { /* Find instruction */
829 save_char
= *current_posn
;
830 *current_posn
= '\0';
831 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
834 debug ("Found instruction %s\n", p_opcode
->name
);
835 p_insn
.tm
= p_opcode
;
839 char first_opcode
[6] =
841 char second_opcode
[6] =
844 int current_opcode
= -1;
847 for (i
= 0; i
< strlen (token
); i
++)
849 char ch
= *(token
+ i
);
850 if (ch
== '_' && current_opcode
== -1)
855 if (ch
== '_' && current_opcode
== 0)
861 switch (current_opcode
)
864 first_opcode
[char_ptr
++] = ch
;
867 second_opcode
[char_ptr
++] = ch
;
871 debug ("first_opcode = %s\n", first_opcode
);
872 debug ("second_opcode = %s\n", second_opcode
);
873 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
874 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
877 debug ("Found instruction %s\n", p_opcode
->name
);
878 p_insn
.tm
= p_opcode
;
879 p_insn
.swap_operands
= 1;
884 *current_posn
= save_char
;
886 { /* Find operands */
887 int paren_not_balanced
;
888 int expecting_operand
= 0;
889 int found_separator
= 0;
892 /* skip optional white space before operand */
893 while (!is_operand_char (*current_posn
) && *current_posn
!= END_OF_INSN
)
895 if (!is_space_char (*current_posn
) && *current_posn
!= PARALLEL_SEPARATOR
)
897 as_bad ("Invalid character %s before %s operand",
898 output_invalid (*current_posn
),
899 ordinal_names
[insn
.operands
]);
902 if (*current_posn
== PARALLEL_SEPARATOR
)
906 token_start
= current_posn
; /* after white space */
907 paren_not_balanced
= 0;
908 while (paren_not_balanced
|| *current_posn
!= ',')
910 if (*current_posn
== END_OF_INSN
)
912 if (paren_not_balanced
)
914 as_bad ("Unbalanced parenthesis in %s operand.",
915 ordinal_names
[insn
.operands
]);
919 break; /* we are done */
921 else if (*current_posn
== PARALLEL_SEPARATOR
)
923 while (is_space_char (*(current_posn
- 1)))
927 else if (!is_operand_char (*current_posn
) && !is_space_char (*current_posn
))
929 as_bad ("Invalid character %s in %s operand",
930 output_invalid (*current_posn
),
931 ordinal_names
[insn
.operands
]);
934 if (*current_posn
== '(')
935 ++paren_not_balanced
;
936 if (*current_posn
== ')')
937 --paren_not_balanced
;
940 if (current_posn
!= token_start
)
941 { /* yes, we've read in another operand */
942 p_insn
.operands
[found_separator
]++;
943 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
945 as_bad ("Spurious operands; (%d operands/instruction max)",
949 /* now parse operand adding info to 'insn' as we go along */
950 save_char
= *current_posn
;
951 *current_posn
= '\0';
952 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
953 tic30_operand (token_start
);
954 *current_posn
= save_char
;
955 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
960 if (expecting_operand
)
962 as_bad ("Expecting operand after ','; got nothing");
965 if (*current_posn
== ',')
967 as_bad ("Expecting operand before ','; got nothing");
971 /* now *current_posn must be either ',' or END_OF_INSN */
972 if (*current_posn
== ',')
974 if (*++current_posn
== END_OF_INSN
)
975 { /* just skip it, if it's \n complain */
976 as_bad ("Expecting operand after ','; got nothing");
979 expecting_operand
= 1;
982 while (*current_posn
!= END_OF_INSN
); /* until we get end of insn */
984 if (p_insn
.swap_operands
)
989 temp_num
= p_insn
.operands
[0];
990 p_insn
.operands
[0] = p_insn
.operands
[1];
991 p_insn
.operands
[1] = temp_num
;
992 for (i
= 0; i
< MAX_OPERANDS
; i
++)
994 temp_op
= p_insn
.operand_type
[0][i
];
995 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
996 p_insn
.operand_type
[1][i
] = temp_op
;
999 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
1001 as_bad ("incorrect number of operands given in the first instruction");
1004 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
1006 as_bad ("incorrect number of operands given in the second instruction");
1009 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
1010 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
1011 { /* Now check if operands are correct */
1015 for (count
= 0; count
< 2; count
++)
1018 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
1020 if ((p_insn
.operand_type
[count
][i
]->op_type
&
1021 p_insn
.tm
->operand_types
[count
][i
]) == 0)
1023 as_bad ("%s instruction, operand %d doesn't match", ordinal_names
[count
], i
+ 1);
1026 /* Get number of R register and indirect reference contained within the first
1027 two operands of each instruction. This is required for the multiply
1028 parallel instructions which require two R registers and two indirect
1029 references, but not in any particular place. */
1030 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
1032 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
) && i
< 2)
1036 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
)) == (Indirect
| Rn
))
1038 /* Check for the multiply instructions */
1041 as_bad ("incorrect format for multiply parallel instruction");
1045 { /* Shouldn't get here */
1046 as_bad ("incorrect format for multiply parallel instruction");
1049 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00) &&
1050 (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
1052 as_bad ("destination for multiply can only be R0 or R1");
1055 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02) &&
1056 (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
1058 as_bad ("destination for add/subtract can only be R2 or R3");
1061 /* Now determine the P field for the instruction */
1062 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
1064 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
1065 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn */
1066 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1067 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn */
1069 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind */
1073 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
1074 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind */
1075 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
1078 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn */
1079 /* Need to swap the two multiply operands around so that everything is in
1080 its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
1081 temp
= p_insn
.operand_type
[0][0];
1082 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1083 p_insn
.operand_type
[0][1] = temp
;
1088 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind */
1089 temp
= p_insn
.operand_type
[0][0];
1090 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
1091 p_insn
.operand_type
[0][1] = temp
;
1096 debug ("P field: %08X\n", p_insn
.p_field
);
1097 /* Finalise opcode. This is easier for parallel instructions as they have to be
1098 fully resolved, there are no memory addresses allowed, except through indirect
1099 addressing, so there are no labels to resolve. */
1101 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
1102 switch (p_insn
.tm
->oporder
)
1105 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1106 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1107 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1108 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1109 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1110 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1113 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1114 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1115 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1116 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1117 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1118 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1119 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1120 as_warn ("loading the same register in parallel operation");
1123 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1124 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1125 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1126 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1127 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1128 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1131 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1132 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1133 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1134 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1135 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1136 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1137 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1140 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1141 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1142 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1143 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1144 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1145 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1146 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1149 p_insn
.opcode
|= p_insn
.p_field
;
1150 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1151 p_insn
.opcode
|= 0x00800000;
1152 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1153 p_insn
.opcode
|= 0x00400000;
1154 switch (p_insn
.p_field
)
1157 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1158 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1159 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1160 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1161 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1162 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1165 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1166 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1167 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1168 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1169 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1170 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1173 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1174 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1175 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1176 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1177 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1178 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1181 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1182 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1183 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1184 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1185 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1186 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1191 } /* Opcode is finalised at this point for all parallel instructions. */
1192 { /* Output opcode */
1194 p
= frag_more (INSN_SIZE
);
1195 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1199 for (i
= 0; i
< 2; i
++)
1200 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1201 free (p_insn
.operand_type
[i
][j
]);
1203 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1209 tic30_operand (token
)
1213 char ind_buffer
[strlen (token
)];
1214 operand
*current_op
;
1216 debug ("In tic30_operand with %s\n", token
);
1217 current_op
= (operand
*) malloc (sizeof (operand
));
1218 memset (current_op
, '\0', sizeof (operand
));
1219 if (*token
== DIRECT_REFERENCE
)
1221 char *token_posn
= token
+ 1;
1222 int direct_label
= 0;
1223 debug ("Found direct reference\n");
1226 if (!is_digit_char (*token_posn
))
1232 char *save_input_line_pointer
;
1234 debug ("Direct reference is a label\n");
1235 current_op
->direct
.label
= token
+ 1;
1236 save_input_line_pointer
= input_line_pointer
;
1237 input_line_pointer
= token
+ 1;
1238 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1239 retval
= expression (¤t_op
->direct
.direct_expr
);
1240 debug ("Expression type: %d\n", current_op
->direct
.direct_expr
.X_op
);
1241 debug ("Expression addnum: %d\n", current_op
->direct
.direct_expr
.X_add_number
);
1242 debug ("Segment: %d\n", retval
);
1243 input_line_pointer
= save_input_line_pointer
;
1244 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
1246 current_op
->direct
.address
= current_op
->direct
.direct_expr
.X_add_number
;
1247 current_op
->direct
.resolved
= 1;
1252 debug ("Direct reference is a number\n");
1253 current_op
->direct
.address
= atoi (token
+ 1);
1254 current_op
->direct
.resolved
= 1;
1256 current_op
->op_type
= Direct
;
1258 else if (*token
== INDIRECT_REFERENCE
)
1259 { /* Indirect reference operand */
1263 int disp_number
= 0;
1264 int buffer_posn
= 1;
1265 ind_addr_type
*ind_addr_op
;
1266 debug ("Found indirect reference\n");
1267 ind_buffer
[0] = *token
;
1268 for (count
= 1; count
< strlen (token
); count
++)
1269 { /* Strip operand */
1270 ind_buffer
[buffer_posn
] = tolower (*(token
+ count
));
1271 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A') &&
1272 (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
1274 /* AR reference is found, so get its number and remove it from the buffer
1275 so it can pass through hash_find() */
1278 as_bad ("More than one AR register found in indirect reference");
1281 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
1283 as_bad ("Illegal AR register in indirect reference");
1286 ar_number
= *(token
+ count
+ 1) - '0';
1290 if (*(token
+ count
) == '(')
1292 /* Parenthesis found, so check if a displacement value is inside. If so, get
1293 the value and remove it from the buffer. */
1294 if (is_digit_char (*(token
+ count
+ 1)))
1301 as_bad ("More than one displacement found in indirect reference");
1305 while (*(token
+ count
) != ')')
1307 if (!is_digit_char (*(token
+ count
)))
1309 as_bad ("Invalid displacement in indirect reference");
1312 disp
[disp_posn
++] = *(token
+ (count
++));
1314 disp
[disp_posn
] = '\0';
1315 disp_number
= atoi (disp
);
1322 ind_buffer
[buffer_posn
] = '\0';
1325 as_bad ("AR register not found in indirect reference");
1328 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
1331 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
1332 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
1337 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
1339 /* Maybe an implied displacement of 1 again */
1340 as_bad ("required displacement wasn't given in indirect reference");
1346 as_bad ("illegal indirect reference");
1349 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
1351 as_bad ("displacement must be an unsigned 8-bit number");
1354 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
1355 current_op
->indirect
.disp
= disp_number
;
1356 current_op
->indirect
.ARnum
= ar_number
;
1357 current_op
->op_type
= Indirect
;
1361 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
1364 debug ("Found register operand: %s\n", regop
->name
);
1365 if (regop
->regtype
== REG_ARn
)
1366 current_op
->op_type
= ARn
;
1367 else if (regop
->regtype
== REG_Rn
)
1368 current_op
->op_type
= Rn
;
1369 else if (regop
->regtype
== REG_DP
)
1370 current_op
->op_type
= DPReg
;
1372 current_op
->op_type
= OtherReg
;
1373 current_op
->reg
.opcode
= regop
->opcode
;
1377 if (!is_digit_char (*token
) || *(token
+ 1) == 'x' || strchr (token
, 'h'))
1379 char *save_input_line_pointer
;
1381 debug ("Probably a label: %s\n", token
);
1382 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1383 strcpy (current_op
->immediate
.label
, token
);
1384 current_op
->immediate
.label
[strlen (token
)] = '\0';
1385 save_input_line_pointer
= input_line_pointer
;
1386 input_line_pointer
= token
;
1387 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
1388 retval
= expression (¤t_op
->immediate
.imm_expr
);
1389 debug ("Expression type: %d\n", current_op
->immediate
.imm_expr
.X_op
);
1390 debug ("Expression addnum: %d\n", current_op
->immediate
.imm_expr
.X_add_number
);
1391 debug ("Segment: %d\n", retval
);
1392 input_line_pointer
= save_input_line_pointer
;
1393 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
1395 current_op
->immediate
.s_number
= current_op
->immediate
.imm_expr
.X_add_number
;
1396 current_op
->immediate
.u_number
= (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
1397 current_op
->immediate
.resolved
= 1;
1403 debug ("Found a number or displacement\n");
1404 for (count
= 0; count
< strlen (token
); count
++)
1405 if (*(token
+ count
) == '.')
1406 current_op
->immediate
.decimal_found
= 1;
1407 current_op
->immediate
.label
= (char *) malloc (strlen (token
) + 1);
1408 strcpy (current_op
->immediate
.label
, token
);
1409 current_op
->immediate
.label
[strlen (token
)] = '\0';
1410 current_op
->immediate
.f_number
= (float) atof (token
);
1411 current_op
->immediate
.s_number
= (int) atoi (token
);
1412 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
1413 current_op
->immediate
.resolved
= 1;
1415 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
1416 if (current_op
->immediate
.u_number
>= 0 && current_op
->immediate
.u_number
<= 31)
1417 current_op
->op_type
|= IVector
;
1423 /* next_line points to the next line after the current instruction (current_line).
1424 Search for the parallel bars, and if found, merge two lines into internal syntax
1425 for a parallel instruction:
1426 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
1427 By this stage, all comments are scrubbed, and only the bare lines are given.
1431 #define START_OPCODE 1
1432 #define END_OPCODE 2
1433 #define START_OPERANDS 3
1434 #define END_OPERANDS 4
1437 tic30_find_parallel_insn (current_line
, next_line
)
1441 int found_parallel
= 0;
1442 char first_opcode
[256];
1443 char second_opcode
[256];
1444 char first_operands
[256];
1445 char second_operands
[256];
1446 char *parallel_insn
;
1448 debug ("In tic30_find_parallel_insn()\n");
1449 while (!is_end_of_line
[(unsigned char) *next_line
])
1451 if (*next_line
== PARALLEL_SEPARATOR
&& *(next_line
+ 1) == PARALLEL_SEPARATOR
)
1459 if (!found_parallel
)
1461 debug ("Found a parallel instruction\n");
1464 char *opcode
, *operands
, *line
;
1466 for (i
= 0; i
< 2; i
++)
1470 opcode
= &first_opcode
[0];
1471 operands
= &first_operands
[0];
1472 line
= current_line
;
1476 opcode
= &second_opcode
[0];
1477 operands
= &second_operands
[0];
1481 int search_status
= NONE
;
1485 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
1487 if (is_opcode_char (c
) && search_status
== NONE
)
1489 opcode
[char_ptr
++] = tolower (c
);
1490 search_status
= START_OPCODE
;
1492 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
1494 opcode
[char_ptr
++] = tolower (c
);
1496 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
1498 opcode
[char_ptr
] = '\0';
1500 search_status
= END_OPCODE
;
1502 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
1504 operands
[char_ptr
++] = c
;
1506 if (is_operand_char (c
) && search_status
== END_OPCODE
)
1508 operands
[char_ptr
++] = c
;
1509 search_status
= START_OPERANDS
;
1513 if (search_status
!= START_OPERANDS
)
1515 operands
[char_ptr
] = '\0';
1519 parallel_insn
= (char *) malloc (strlen (first_opcode
) + strlen (first_operands
) +
1520 strlen (second_opcode
) + strlen (second_operands
) + 8);
1521 sprintf (parallel_insn
, "q_%s_%s %s | %s", first_opcode
, second_opcode
, first_operands
, second_operands
);
1522 debug ("parallel insn = %s\n", parallel_insn
);
1523 return parallel_insn
;
1529 #undef START_OPERANDS
1532 /* In order to get gas to ignore any | chars at the start of a line,
1533 this function returns true if a | is found in a line. */
1536 tic30_unrecognized_line (c
)
1539 debug ("In tc_unrecognized_line\n");
1540 return (c
== PARALLEL_SEPARATOR
);
1544 md_estimate_size_before_relax (fragP
, segment
)
1548 debug ("In md_estimate_size_before_relax()\n");
1553 md_convert_frag (abfd
, sec
, fragP
)
1556 register fragS
*fragP
;
1558 debug ("In md_convert_frag()\n");
1562 md_apply_fix (fixP
, valP
)
1566 valueT value
= *valP
;
1568 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1569 debug ("Values in fixP\n");
1570 debug ("fx_size = %d\n", fixP
->fx_size
);
1571 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1572 debug ("fx_where = %d\n", fixP
->fx_where
);
1573 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1575 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
);
1588 md_parse_option (c
, arg
)
1594 debug ("In md_parse_option()\n");
1595 for (i
= 0; i
< c
; i
++)
1597 printf ("%c\n", arg
[c
]);
1603 md_show_usage (stream
)
1606 debug ("In md_show_usage()\n");
1610 md_undefined_symbol (name
)
1613 debug ("In md_undefined_symbol()\n");
1614 return (symbolS
*) 0;
1618 md_section_align (segment
, size
)
1622 debug ("In md_section_align() segment = %d and size = %d\n", segment
, size
);
1623 size
= (size
+ 3) / 4;
1625 debug ("New size value = %d\n", size
);
1630 md_pcrel_from (fixP
)
1635 debug ("In md_pcrel_from()\n");
1636 debug ("fx_where = %d\n", fixP
->fx_where
);
1637 debug ("fx_size = %d\n", fixP
->fx_size
);
1638 /* Find the opcode that represents the current instruction in the fr_literal
1639 storage area, and check bit 21. Bit 21 contains whether the current instruction
1640 is a delayed one or not, and then set the offset value appropriately. */
1641 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1645 debug ("offset = %d\n", offset
);
1646 /* PC Relative instructions have a format:
1647 displacement = Label - (PC + offset)
1648 This function returns PC + offset where:
1649 fx_where - fx_size = PC
1650 INSN_SIZE * offset = offset number of instructions
1652 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1656 md_atof (what_statement_type
, literalP
, sizeP
)
1657 int what_statement_type
;
1664 unsigned long value
;
1665 /* char *atof_ieee (); */
1667 debug ("In md_atof()\n");
1668 debug ("precision = %c\n", what_statement_type
);
1669 debug ("literal = %s\n", literalP
);
1671 token
= input_line_pointer
;
1672 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1673 && (*input_line_pointer
!= ','))
1675 debug ("%c", *input_line_pointer
);
1676 input_line_pointer
++;
1678 keepval
= *input_line_pointer
;
1679 *input_line_pointer
= '\0';
1681 float_value
= (float) atof (token
);
1682 *input_line_pointer
= keepval
;
1683 debug ("float_value = %f\n", float_value
);
1684 switch (what_statement_type
)
1702 return "Bad call to MD_ATOF()";
1704 if (float_value
== 0.0)
1706 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1710 unsigned long exp
, sign
, mant
, tmsfloat
;
1711 tmsfloat
= *((long *) &float_value
);
1712 sign
= tmsfloat
& 0x80000000;
1713 mant
= tmsfloat
& 0x007FFFFF;
1714 exp
= tmsfloat
& 0x7F800000;
1716 if (exp
== 0xFF000000)
1730 mant
= mant
& 0x007FFFFF;
1732 mant
= mant
& 0x00FFFFFF;
1736 exp
= (long) exp
- 0x01000000;
1739 tmsfloat
= exp
| mant
;
1746 if (tmsfloat
== 0x80000000)
1753 exp
= (tmsfloat
& 0xFF000000);
1755 mant
= tmsfloat
& 0x007FFFFF;
1756 if (tmsfloat
& 0x00800000)
1770 exp
+= (mant
>> 24);
1780 mant
= (exp
<< 12) | mant
;
1781 value
= mant
& 0xFFFF;
1786 md_number_to_chars (literalP
, value
, prec
);
1792 md_number_to_chars (buf
, val
, n
)
1797 debug ("In md_number_to_chars()\n");
1798 number_to_chars_bigendian (buf
, val
, n
);
1799 /* number_to_chars_littleendian(buf,val,n); */
1802 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1803 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1806 tc_gen_reloc (section
, fixP
)
1811 bfd_reloc_code_real_type code
= 0;
1813 debug ("In tc_gen_reloc()\n");
1814 debug ("fixP.size = %d\n", fixP
->fx_size
);
1815 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1816 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1817 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1819 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1820 MAP (2, 0, BFD_RELOC_16
);
1821 MAP (3, 0, BFD_RELOC_24
);
1822 MAP (2, 1, BFD_RELOC_16_PCREL
);
1823 MAP (4, 0, BFD_RELOC_32
);
1825 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1826 fixP
->fx_pcrel
? "pc-relative " : "");
1831 rel
= (arelent
*) xmalloc (sizeof (arelent
));
1833 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1834 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1835 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1837 rel
->addend
= fixP
->fx_addnumber
;
1840 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1844 name
= S_GET_NAME (fixP
->fx_addsy
);
1847 as_fatal ("Cannot generate relocation type for symbol %s, code %s", name
, bfd_get_reloc_code_name (code
));
1853 tc_aout_pre_write_hook ()
1855 debug ("In tc_aout_pre_write_hook()\n");
1859 md_operand (expressionP
)
1860 expressionS
*expressionP
;
1862 debug ("In md_operand()\n");
1865 char output_invalid_buf
[8];
1872 sprintf (output_invalid_buf
, "'%c'", c
);
1874 sprintf (output_invalid_buf
, "(0x%x)", (unsigned) c
);
1875 return output_invalid_buf
;