1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 /* Texas Instruments TMS320C30 machine specific gas.
24 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25 Bugs & suggestions are completely welcome. This is free software.
26 Please help us make it better. */
29 #include "safe-ctype.h"
30 #include "opcode/tic30.h"
31 #ifdef ANSI_PROTOTYPES
37 /* Put here all non-digit non-letter characters that may occur in an
39 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
40 static char *ordinal_names
[] =
42 "first", "second", "third", "fourth", "fifth"
45 const int md_reloc_size
= 0;
47 const char comment_chars
[] = ";";
48 const char line_comment_chars
[] = "*";
49 const char line_separator_chars
[] = "";
51 const char *md_shortopts
= "";
52 struct option md_longopts
[] =
54 {NULL
, no_argument
, NULL
, 0}
57 size_t md_longopts_size
= sizeof (md_longopts
);
59 /* Chars that mean this number is a floating point constant.
62 const char FLT_CHARS
[] = "fFdDxX";
64 /* Chars that can be used to separate mant from exp in floating point
66 const char EXP_CHARS
[] = "eE";
68 /* Tables for lexical analysis. */
69 static char opcode_chars
[256];
70 static char register_chars
[256];
71 static char operand_chars
[256];
72 static char space_chars
[256];
73 static char identifier_chars
[256];
74 static char digit_chars
[256];
77 #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
78 #define is_operand_char(x) (operand_chars [(unsigned char) x])
79 #define is_register_char(x) (register_chars [(unsigned char) x])
80 #define is_space_char(x) (space_chars [(unsigned char) x])
81 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
82 #define is_digit_char(x) (digit_chars [(unsigned char) x])
84 const pseudo_typeS md_pseudo_table
[] =
90 debug (const char *string
, ...)
96 VA_OPEN (argptr
, string
);
97 VA_FIXEDARG (argptr
, const char *, string
);
98 vsprintf (str
, string
, argptr
);
102 fputs (str
, USE_STDOUT
? stdout
: stderr
);
109 /* Hash table for opcode lookup. */
110 static struct hash_control
*op_hash
;
111 /* Hash table for parallel opcode lookup. */
112 static struct hash_control
*parop_hash
;
113 /* Hash table for register lookup. */
114 static struct hash_control
*reg_hash
;
115 /* Hash table for indirect addressing lookup. */
116 static struct hash_control
*ind_hash
;
121 const char *hash_err
;
123 debug ("In md_begin()\n");
124 op_hash
= hash_new ();
127 const template *current_optab
= tic30_optab
;
129 for (; current_optab
< tic30_optab_end
; current_optab
++)
131 hash_err
= hash_insert (op_hash
, current_optab
->name
,
132 (char *) current_optab
);
134 as_fatal ("Internal Error: Can't Hash %s: %s",
135 current_optab
->name
, hash_err
);
139 parop_hash
= hash_new ();
142 const partemplate
*current_parop
= tic30_paroptab
;
144 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
146 hash_err
= hash_insert (parop_hash
, current_parop
->name
,
147 (char *) current_parop
);
149 as_fatal ("Internal Error: Can't Hash %s: %s",
150 current_parop
->name
, hash_err
);
154 reg_hash
= hash_new ();
157 const reg
*current_reg
= tic30_regtab
;
159 for (; current_reg
< tic30_regtab_end
; current_reg
++)
161 hash_err
= hash_insert (reg_hash
, current_reg
->name
,
162 (char *) current_reg
);
164 as_fatal ("Internal Error: Can't Hash %s: %s",
165 current_reg
->name
, hash_err
);
169 ind_hash
= hash_new ();
172 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
174 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
176 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
,
177 (char *) current_ind
);
179 as_fatal ("Internal Error: Can't Hash %s: %s",
180 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
== '(')
202 register_chars
[c
] = c
;
204 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
205 operand_chars
[c
] = c
;
207 if (ISDIGIT (c
) || c
== '-')
210 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
211 identifier_chars
[c
] = c
;
213 if (c
== ' ' || c
== '\t')
219 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
220 operand_chars
[(unsigned char) *p
] = *p
;
224 /* Address Mode OR values. */
225 #define AM_Register 0x00000000
226 #define AM_Direct 0x00200000
227 #define AM_Indirect 0x00400000
228 #define AM_Immediate 0x00600000
229 #define AM_NotReq 0xFFFFFFFF
231 /* PC Relative OR values. */
232 #define PC_Register 0x00000000
233 #define PC_Relative 0x02000000
243 expressionS direct_expr
;
261 unsigned int u_number
;
263 expressionS imm_expr
;
271 template *tm
; /* Template of current instruction. */
272 unsigned opcode
; /* Final opcode. */
273 unsigned int operands
; /* Number of given operands. */
274 /* Type of operand given in instruction. */
275 operand
*operand_type
[MAX_OPERANDS
];
276 unsigned addressing_mode
; /* Final addressing mode of instruction. */
279 struct tic30_insn insn
;
280 static int found_parallel_insn
;
282 static char output_invalid_buf
[8];
285 output_invalid (char c
)
288 sprintf (output_invalid_buf
, "'%c'", c
);
290 sprintf (output_invalid_buf
, "(0x%x)", (unsigned) c
);
291 return output_invalid_buf
;
294 /* next_line points to the next line after the current instruction
295 (current_line). Search for the parallel bars, and if found, merge two
296 lines into internal syntax for a parallel instruction:
297 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
298 By this stage, all comments are scrubbed, and only the bare lines are
302 #define START_OPCODE 1
304 #define START_OPERANDS 3
305 #define END_OPERANDS 4
308 tic30_find_parallel_insn (char *current_line
, char *next_line
)
310 int found_parallel
= 0;
311 char first_opcode
[256];
312 char second_opcode
[256];
313 char first_operands
[256];
314 char second_operands
[256];
317 debug ("In tic30_find_parallel_insn()\n");
318 while (!is_end_of_line
[(unsigned char) *next_line
])
320 if (*next_line
== PARALLEL_SEPARATOR
321 && *(next_line
+ 1) == PARALLEL_SEPARATOR
)
331 debug ("Found a parallel instruction\n");
335 char *opcode
, *operands
, *line
;
337 for (i
= 0; i
< 2; i
++)
341 opcode
= &first_opcode
[0];
342 operands
= &first_operands
[0];
347 opcode
= &second_opcode
[0];
348 operands
= &second_operands
[0];
353 int search_status
= NONE
;
357 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
359 if (is_opcode_char (c
) && search_status
== NONE
)
361 opcode
[char_ptr
++] = TOLOWER (c
);
362 search_status
= START_OPCODE
;
364 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
365 opcode
[char_ptr
++] = TOLOWER (c
);
366 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
368 opcode
[char_ptr
] = '\0';
370 search_status
= END_OPCODE
;
372 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
373 operands
[char_ptr
++] = c
;
375 if (is_operand_char (c
) && search_status
== END_OPCODE
)
377 operands
[char_ptr
++] = c
;
378 search_status
= START_OPERANDS
;
383 if (search_status
!= START_OPERANDS
)
385 operands
[char_ptr
] = '\0';
389 parallel_insn
= malloc (strlen (first_opcode
) + strlen (first_operands
)
390 + strlen (second_opcode
) + strlen (second_operands
) + 8);
391 sprintf (parallel_insn
, "q_%s_%s %s | %s",
392 first_opcode
, second_opcode
,
393 first_operands
, second_operands
);
394 debug ("parallel insn = %s\n", parallel_insn
);
395 return parallel_insn
;
401 #undef START_OPERANDS
405 tic30_operand (char *token
)
408 char ind_buffer
[strlen (token
)];
411 debug ("In tic30_operand with %s\n", token
);
412 current_op
= malloc (sizeof (* current_op
));
413 memset (current_op
, '\0', sizeof (operand
));
415 if (*token
== DIRECT_REFERENCE
)
417 char *token_posn
= token
+ 1;
418 int direct_label
= 0;
420 debug ("Found direct reference\n");
423 if (!is_digit_char (*token_posn
))
430 char *save_input_line_pointer
;
433 debug ("Direct reference is a label\n");
434 current_op
->direct
.label
= token
+ 1;
435 save_input_line_pointer
= input_line_pointer
;
436 input_line_pointer
= token
+ 1;
437 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
438 retval
= expression (¤t_op
->direct
.direct_expr
);
440 debug ("Expression type: %d\n",
441 current_op
->direct
.direct_expr
.X_op
);
442 debug ("Expression addnum: %d\n",
443 current_op
->direct
.direct_expr
.X_add_number
);
444 debug ("Segment: %d\n", retval
);
446 input_line_pointer
= save_input_line_pointer
;
448 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
450 current_op
->direct
.address
=
451 current_op
->direct
.direct_expr
.X_add_number
;
452 current_op
->direct
.resolved
= 1;
457 debug ("Direct reference is a number\n");
458 current_op
->direct
.address
= atoi (token
+ 1);
459 current_op
->direct
.resolved
= 1;
461 current_op
->op_type
= Direct
;
463 else if (*token
== INDIRECT_REFERENCE
)
465 /* Indirect reference operand. */
471 ind_addr_type
*ind_addr_op
;
473 debug ("Found indirect reference\n");
474 ind_buffer
[0] = *token
;
476 for (count
= 1; count
< strlen (token
); count
++)
479 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
481 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A')
482 && (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
484 /* AR reference is found, so get its number and remove
485 it from the buffer so it can pass through hash_find(). */
488 as_bad ("More than one AR register found in indirect reference");
491 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
493 as_bad ("Illegal AR register in indirect reference");
496 ar_number
= *(token
+ count
+ 1) - '0';
501 if (*(token
+ count
) == '(')
503 /* Parenthesis found, so check if a displacement value is
504 inside. If so, get the value and remove it from the
506 if (is_digit_char (*(token
+ count
+ 1)))
513 as_bad ("More than one displacement found in indirect reference");
517 while (*(token
+ count
) != ')')
519 if (!is_digit_char (*(token
+ count
)))
521 as_bad ("Invalid displacement in indirect reference");
524 disp
[disp_posn
++] = *(token
+ (count
++));
526 disp
[disp_posn
] = '\0';
527 disp_number
= atoi (disp
);
535 ind_buffer
[buffer_posn
] = '\0';
538 as_bad ("AR register not found in indirect reference");
542 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
545 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
546 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
551 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
553 /* Maybe an implied displacement of 1 again. */
554 as_bad ("required displacement wasn't given in indirect reference");
560 as_bad ("illegal indirect reference");
564 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
566 as_bad ("displacement must be an unsigned 8-bit number");
570 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
571 current_op
->indirect
.disp
= disp_number
;
572 current_op
->indirect
.ARnum
= ar_number
;
573 current_op
->op_type
= Indirect
;
577 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
581 debug ("Found register operand: %s\n", regop
->name
);
582 if (regop
->regtype
== REG_ARn
)
583 current_op
->op_type
= ARn
;
584 else if (regop
->regtype
== REG_Rn
)
585 current_op
->op_type
= Rn
;
586 else if (regop
->regtype
== REG_DP
)
587 current_op
->op_type
= DPReg
;
589 current_op
->op_type
= OtherReg
;
590 current_op
->reg
.opcode
= regop
->opcode
;
594 if (!is_digit_char (*token
)
595 || *(token
+ 1) == 'x'
596 || strchr (token
, 'h'))
598 char *save_input_line_pointer
;
601 debug ("Probably a label: %s\n", token
);
602 current_op
->immediate
.label
= malloc (strlen (token
) + 1);
603 strcpy (current_op
->immediate
.label
, token
);
604 current_op
->immediate
.label
[strlen (token
)] = '\0';
605 save_input_line_pointer
= input_line_pointer
;
606 input_line_pointer
= token
;
608 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
609 retval
= expression (¤t_op
->immediate
.imm_expr
);
610 debug ("Expression type: %d\n",
611 current_op
->immediate
.imm_expr
.X_op
);
612 debug ("Expression addnum: %d\n",
613 current_op
->immediate
.imm_expr
.X_add_number
);
614 debug ("Segment: %d\n", retval
);
615 input_line_pointer
= save_input_line_pointer
;
617 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
619 current_op
->immediate
.s_number
620 = current_op
->immediate
.imm_expr
.X_add_number
;
621 current_op
->immediate
.u_number
622 = (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
623 current_op
->immediate
.resolved
= 1;
630 debug ("Found a number or displacement\n");
631 for (count
= 0; count
< strlen (token
); count
++)
632 if (*(token
+ count
) == '.')
633 current_op
->immediate
.decimal_found
= 1;
634 current_op
->immediate
.label
= malloc (strlen (token
) + 1);
635 strcpy (current_op
->immediate
.label
, token
);
636 current_op
->immediate
.label
[strlen (token
)] = '\0';
637 current_op
->immediate
.f_number
= (float) atof (token
);
638 current_op
->immediate
.s_number
= (int) atoi (token
);
639 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
640 current_op
->immediate
.resolved
= 1;
642 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
643 if (current_op
->immediate
.u_number
<= 31)
644 current_op
->op_type
|= IVector
;
650 struct tic30_par_insn
652 partemplate
*tm
; /* Template of current parallel instruction. */
653 unsigned operands
[2]; /* Number of given operands for each insn. */
654 /* Type of operand given in instruction. */
655 operand
*operand_type
[2][MAX_OPERANDS
];
656 int swap_operands
; /* Whether to swap operands around. */
657 unsigned p_field
; /* Value of p field in multiply add/sub instructions. */
658 unsigned opcode
; /* Final opcode. */
661 struct tic30_par_insn p_insn
;
664 tic30_parallel_insn (char *token
)
666 static partemplate
*p_opcode
;
667 char *current_posn
= token
;
671 debug ("In tic30_parallel_insn with %s\n", token
);
672 memset (&p_insn
, '\0', sizeof (p_insn
));
674 while (is_opcode_char (*current_posn
))
677 /* Find instruction. */
678 save_char
= *current_posn
;
679 *current_posn
= '\0';
680 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
683 debug ("Found instruction %s\n", p_opcode
->name
);
684 p_insn
.tm
= p_opcode
;
688 char first_opcode
[6] = {0};
689 char second_opcode
[6] = {0};
691 int current_opcode
= -1;
694 for (i
= 0; i
< strlen (token
); i
++)
696 char ch
= *(token
+ i
);
698 if (ch
== '_' && current_opcode
== -1)
704 if (ch
== '_' && current_opcode
== 0)
711 switch (current_opcode
)
714 first_opcode
[char_ptr
++] = ch
;
717 second_opcode
[char_ptr
++] = ch
;
722 debug ("first_opcode = %s\n", first_opcode
);
723 debug ("second_opcode = %s\n", second_opcode
);
724 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
725 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
729 debug ("Found instruction %s\n", p_opcode
->name
);
730 p_insn
.tm
= p_opcode
;
731 p_insn
.swap_operands
= 1;
736 *current_posn
= save_char
;
741 int paren_not_balanced
;
742 int expecting_operand
= 0;
743 int found_separator
= 0;
747 /* Skip optional white space before operand. */
748 while (!is_operand_char (*current_posn
)
749 && *current_posn
!= END_OF_INSN
)
751 if (!is_space_char (*current_posn
)
752 && *current_posn
!= PARALLEL_SEPARATOR
)
754 as_bad ("Invalid character %s before %s operand",
755 output_invalid (*current_posn
),
756 ordinal_names
[insn
.operands
]);
759 if (*current_posn
== PARALLEL_SEPARATOR
)
764 token_start
= current_posn
;
765 paren_not_balanced
= 0;
767 while (paren_not_balanced
|| *current_posn
!= ',')
769 if (*current_posn
== END_OF_INSN
)
771 if (paren_not_balanced
)
773 as_bad ("Unbalanced parenthesis in %s operand.",
774 ordinal_names
[insn
.operands
]);
780 else if (*current_posn
== PARALLEL_SEPARATOR
)
782 while (is_space_char (*(current_posn
- 1)))
786 else if (!is_operand_char (*current_posn
)
787 && !is_space_char (*current_posn
))
789 as_bad ("Invalid character %s in %s operand",
790 output_invalid (*current_posn
),
791 ordinal_names
[insn
.operands
]);
795 if (*current_posn
== '(')
796 ++paren_not_balanced
;
797 if (*current_posn
== ')')
798 --paren_not_balanced
;
802 if (current_posn
!= token_start
)
804 /* Yes, we've read in another operand. */
805 p_insn
.operands
[found_separator
]++;
806 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
808 as_bad ("Spurious operands; (%d operands/instruction max)",
813 /* Now parse operand adding info to 'insn' as we go along. */
814 save_char
= *current_posn
;
815 *current_posn
= '\0';
816 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
817 tic30_operand (token_start
);
818 *current_posn
= save_char
;
819 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
824 if (expecting_operand
)
826 as_bad ("Expecting operand after ','; got nothing");
829 if (*current_posn
== ',')
831 as_bad ("Expecting operand before ','; got nothing");
836 /* Now *current_posn must be either ',' or END_OF_INSN. */
837 if (*current_posn
== ',')
839 if (*++current_posn
== END_OF_INSN
)
841 /* Just skip it, if it's \n complain. */
842 as_bad ("Expecting operand after ','; got nothing");
845 expecting_operand
= 1;
848 while (*current_posn
!= END_OF_INSN
);
851 if (p_insn
.swap_operands
)
856 temp_num
= p_insn
.operands
[0];
857 p_insn
.operands
[0] = p_insn
.operands
[1];
858 p_insn
.operands
[1] = temp_num
;
859 for (i
= 0; i
< MAX_OPERANDS
; i
++)
861 temp_op
= p_insn
.operand_type
[0][i
];
862 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
863 p_insn
.operand_type
[1][i
] = temp_op
;
867 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
869 as_bad ("incorrect number of operands given in the first instruction");
873 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
875 as_bad ("incorrect number of operands given in the second instruction");
879 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
880 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
883 /* Now check if operands are correct. */
888 for (count
= 0; count
< 2; count
++)
891 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
893 if ((p_insn
.operand_type
[count
][i
]->op_type
&
894 p_insn
.tm
->operand_types
[count
][i
]) == 0)
896 as_bad ("%s instruction, operand %d doesn't match",
897 ordinal_names
[count
], i
+ 1);
901 /* Get number of R register and indirect reference contained
902 within the first two operands of each instruction. This is
903 required for the multiply parallel instructions which require
904 two R registers and two indirect references, but not in any
906 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
908 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
)
914 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
))
917 /* Check for the multiply instructions. */
920 as_bad ("incorrect format for multiply parallel instruction");
926 /* Shouldn't get here. */
927 as_bad ("incorrect format for multiply parallel instruction");
931 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00)
932 && (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
934 as_bad ("destination for multiply can only be R0 or R1");
938 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02)
939 && (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
941 as_bad ("destination for add/subtract can only be R2 or R3");
945 /* Now determine the P field for the instruction. */
946 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
948 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
949 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn. */
950 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
951 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn. */
953 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind. */
957 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
958 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind. */
959 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
962 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn. */
963 /* Need to swap the two multiply operands around so that
964 everything is in its place for the opcode makeup.
965 ie so Ind * Rn, Ind +/- Rn. */
966 temp
= p_insn
.operand_type
[0][0];
967 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
968 p_insn
.operand_type
[0][1] = temp
;
973 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind. */
974 temp
= p_insn
.operand_type
[0][0];
975 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
976 p_insn
.operand_type
[0][1] = temp
;
982 debug ("P field: %08X\n", p_insn
.p_field
);
984 /* Finalise opcode. This is easier for parallel instructions as they have
985 to be fully resolved, there are no memory addresses allowed, except
986 through indirect addressing, so there are no labels to resolve. */
987 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
989 switch (p_insn
.tm
->oporder
)
992 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
993 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
994 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
995 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
996 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
997 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1001 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1002 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1003 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1004 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1005 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1006 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1007 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1008 as_warn ("loading the same register in parallel operation");
1012 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1013 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1014 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1015 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1016 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1017 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1021 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1022 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1023 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1024 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1025 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1026 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1027 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1031 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1032 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1033 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1034 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1035 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1036 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1037 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1041 p_insn
.opcode
|= p_insn
.p_field
;
1042 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1043 p_insn
.opcode
|= 0x00800000;
1044 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1045 p_insn
.opcode
|= 0x00400000;
1047 switch (p_insn
.p_field
)
1050 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1051 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1052 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1053 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1054 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1055 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1058 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1059 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1060 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1061 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1062 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1063 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1066 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1067 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1068 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1069 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1070 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1071 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1074 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1075 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1076 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1077 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1078 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1079 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1088 p
= frag_more (INSN_SIZE
);
1089 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1095 for (i
= 0; i
< 2; i
++)
1096 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1097 free (p_insn
.operand_type
[i
][j
]);
1100 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1106 /* In order to get gas to ignore any | chars at the start of a line,
1107 this function returns true if a | is found in a line. */
1110 tic30_unrecognized_line (int c
)
1112 debug ("In tc_unrecognized_line\n");
1113 return (c
== PARALLEL_SEPARATOR
);
1117 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
1118 segT segment ATTRIBUTE_UNUSED
)
1120 debug ("In md_estimate_size_before_relax()\n");
1125 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1126 segT sec ATTRIBUTE_UNUSED
,
1127 register fragS
*fragP ATTRIBUTE_UNUSED
)
1129 debug ("In md_convert_frag()\n");
1133 md_apply_fix3 (fixS
*fixP
,
1135 segT seg ATTRIBUTE_UNUSED
)
1137 valueT value
= *valP
;
1139 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1140 debug ("Values in fixP\n");
1141 debug ("fx_size = %d\n", fixP
->fx_size
);
1142 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1143 debug ("fx_where = %d\n", fixP
->fx_where
);
1144 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1146 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1149 if (fixP
->fx_size
== 1)
1150 /* Special fix for LDP instruction. */
1151 value
= (value
& 0x00FF0000) >> 16;
1153 debug ("new value = %ld\n", (long) value
);
1154 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1157 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1162 md_parse_option (int c ATTRIBUTE_UNUSED
,
1163 char *arg ATTRIBUTE_UNUSED
)
1165 debug ("In md_parse_option()\n");
1170 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
1172 debug ("In md_show_usage()\n");
1176 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1178 debug ("In md_undefined_symbol()\n");
1179 return (symbolS
*) 0;
1183 md_section_align (segT segment
, valueT size
)
1185 debug ("In md_section_align() segment = %d and size = %d\n",
1187 size
= (size
+ 3) / 4;
1189 debug ("New size value = %d\n", size
);
1194 md_pcrel_from (fixS
*fixP
)
1198 debug ("In md_pcrel_from()\n");
1199 debug ("fx_where = %d\n", fixP
->fx_where
);
1200 debug ("fx_size = %d\n", fixP
->fx_size
);
1201 /* Find the opcode that represents the current instruction in the
1202 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1203 current instruction is a delayed one or not, and then set the offset
1204 value appropriately. */
1205 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1209 debug ("offset = %d\n", offset
);
1210 /* PC Relative instructions have a format:
1211 displacement = Label - (PC + offset)
1212 This function returns PC + offset where:
1213 fx_where - fx_size = PC
1214 INSN_SIZE * offset = offset number of instructions. */
1215 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1219 md_atof (int what_statement_type
,
1226 unsigned long value
;
1229 debug ("In md_atof()\n");
1230 debug ("precision = %c\n", what_statement_type
);
1231 debug ("literal = %s\n", literalP
);
1233 token
= input_line_pointer
;
1234 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1235 && (*input_line_pointer
!= ','))
1237 debug ("%c", *input_line_pointer
);
1238 input_line_pointer
++;
1241 keepval
= *input_line_pointer
;
1242 *input_line_pointer
= '\0';
1244 float_value
= (float) atof (token
);
1245 *input_line_pointer
= keepval
;
1246 debug ("float_value = %f\n", float_value
);
1248 switch (what_statement_type
)
1266 return "Bad call to MD_ATOF()";
1269 if (float_value
== 0.0)
1270 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1273 unsigned long exp
, sign
, mant
, tmsfloat
;
1281 converter
.f
= float_value
;
1282 tmsfloat
= converter
.l
;
1283 sign
= tmsfloat
& 0x80000000;
1284 mant
= tmsfloat
& 0x007FFFFF;
1285 exp
= tmsfloat
& 0x7F800000;
1287 if (exp
== 0xFF000000)
1301 mant
= mant
& 0x007FFFFF;
1303 mant
= mant
& 0x00FFFFFF;
1307 exp
= (long) exp
- 0x01000000;
1310 tmsfloat
= exp
| mant
;
1317 if (tmsfloat
== 0x80000000)
1322 exp
= (tmsfloat
& 0xFF000000);
1324 mant
= tmsfloat
& 0x007FFFFF;
1325 if (tmsfloat
& 0x00800000)
1339 exp
+= (mant
>> 24);
1349 mant
= (exp
<< 12) | mant
;
1350 value
= mant
& 0xFFFF;
1355 md_number_to_chars (literalP
, value
, prec
);
1361 md_number_to_chars (char *buf
, valueT val
, int n
)
1363 debug ("In md_number_to_chars()\n");
1364 number_to_chars_bigendian (buf
, val
, n
);
1367 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1368 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1371 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
1374 bfd_reloc_code_real_type code
= 0;
1376 debug ("In tc_gen_reloc()\n");
1377 debug ("fixP.size = %d\n", fixP
->fx_size
);
1378 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1379 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1381 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1383 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1384 MAP (2, 0, BFD_RELOC_16
);
1385 MAP (3, 0, BFD_RELOC_24
);
1386 MAP (2, 1, BFD_RELOC_16_PCREL
);
1387 MAP (4, 0, BFD_RELOC_32
);
1389 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1390 fixP
->fx_pcrel
? "pc-relative " : "");
1395 rel
= xmalloc (sizeof (* rel
));
1397 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
1398 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1399 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1401 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1406 name
= S_GET_NAME (fixP
->fx_addsy
);
1409 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1410 name
, bfd_get_reloc_code_name (code
));
1416 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1418 debug ("In md_operand()\n");
1422 md_assemble (char *line
)
1430 debug ("In md_assemble() with argument %s\n", line
);
1431 memset (&insn
, '\0', sizeof (insn
));
1432 if (found_parallel_insn
)
1434 debug ("Line is second part of parallel instruction\n\n");
1435 found_parallel_insn
= 0;
1439 tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
1440 current_posn
= line
;
1442 found_parallel_insn
= 1;
1444 while (is_space_char (*current_posn
))
1447 token_start
= current_posn
;
1449 if (!is_opcode_char (*current_posn
))
1451 as_bad ("Invalid character %s in opcode",
1452 output_invalid (*current_posn
));
1455 /* Check if instruction is a parallel instruction
1456 by seeing if the first character is a q. */
1457 if (*token_start
== 'q')
1459 if (tic30_parallel_insn (token_start
))
1461 if (found_parallel_insn
)
1466 while (is_opcode_char (*current_posn
))
1469 /* Find instruction. */
1470 save_char
= *current_posn
;
1471 *current_posn
= '\0';
1472 opcode
= (template *) hash_find (op_hash
, token_start
);
1475 debug ("Found instruction %s\n", opcode
->name
);
1480 debug ("Didn't find insn\n");
1481 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
1484 *current_posn
= save_char
;
1487 if (*current_posn
!= END_OF_INSN
)
1489 /* Find operands. */
1490 int paren_not_balanced
;
1491 int expecting_operand
= 0;
1495 /* Skip optional white space before operand. */
1496 while (!is_operand_char (*current_posn
)
1497 && *current_posn
!= END_OF_INSN
)
1499 if (!is_space_char (*current_posn
))
1501 as_bad ("Invalid character %s before %s operand",
1502 output_invalid (*current_posn
),
1503 ordinal_names
[insn
.operands
]);
1508 token_start
= current_posn
;
1509 paren_not_balanced
= 0;
1510 while (paren_not_balanced
|| *current_posn
!= ',')
1512 if (*current_posn
== END_OF_INSN
)
1514 if (paren_not_balanced
)
1516 as_bad ("Unbalanced parenthesis in %s operand.",
1517 ordinal_names
[insn
.operands
]);
1523 else if (!is_operand_char (*current_posn
)
1524 && !is_space_char (*current_posn
))
1526 as_bad ("Invalid character %s in %s operand",
1527 output_invalid (*current_posn
),
1528 ordinal_names
[insn
.operands
]);
1531 if (*current_posn
== '(')
1532 ++paren_not_balanced
;
1533 if (*current_posn
== ')')
1534 --paren_not_balanced
;
1537 if (current_posn
!= token_start
)
1539 /* Yes, we've read in another operand. */
1540 this_operand
= insn
.operands
++;
1541 if (insn
.operands
> MAX_OPERANDS
)
1543 as_bad ("Spurious operands; (%d operands/instruction max)",
1548 /* Now parse operand adding info to 'insn' as we go along. */
1549 save_char
= *current_posn
;
1550 *current_posn
= '\0';
1551 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
1552 *current_posn
= save_char
;
1553 if (insn
.operand_type
[this_operand
] == NULL
)
1558 if (expecting_operand
)
1560 as_bad ("Expecting operand after ','; got nothing");
1563 if (*current_posn
== ',')
1565 as_bad ("Expecting operand before ','; got nothing");
1570 /* Now *current_posn must be either ',' or END_OF_INSN. */
1571 if (*current_posn
== ',')
1573 if (*++current_posn
== END_OF_INSN
)
1575 /* Just skip it, if it's \n complain. */
1576 as_bad ("Expecting operand after ','; got nothing");
1579 expecting_operand
= 1;
1582 while (*current_posn
!= END_OF_INSN
);
1585 debug ("Number of operands found: %d\n", insn
.operands
);
1587 /* Check that number of operands is correct. */
1588 if (insn
.operands
!= insn
.tm
->operands
)
1591 unsigned int numops
= insn
.tm
->operands
;
1593 /* If operands are not the same, then see if any of the operands are
1594 not required. Then recheck with number of given operands. If they
1595 are still not the same, then give an error, otherwise carry on. */
1596 for (i
= 0; i
< insn
.tm
->operands
; i
++)
1597 if (insn
.tm
->operand_types
[i
] & NotReq
)
1599 if (insn
.operands
!= numops
)
1601 as_bad ("Incorrect number of operands given");
1605 insn
.addressing_mode
= AM_NotReq
;
1606 for (count
= 0; count
< insn
.operands
; count
++)
1608 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
1610 debug ("Operand %d matches\n", count
+ 1);
1611 /* If instruction has two operands and has an AddressMode
1612 modifier then set addressing mode type for instruction. */
1613 if (insn
.tm
->opcode_modifier
== AddressMode
)
1616 /* Store instruction uses the second
1617 operand for the address mode. */
1618 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
))
1619 == (Indirect
| Direct
))
1622 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
1623 insn
.addressing_mode
= AM_Register
;
1624 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
1625 insn
.addressing_mode
= AM_Direct
;
1626 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
1627 insn
.addressing_mode
= AM_Indirect
;
1629 insn
.addressing_mode
= AM_Immediate
;
1634 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
1639 /* Now set the addressing mode for 3 operand instructions. */
1640 if ((insn
.tm
->operand_types
[0] & op3T1
)
1641 && (insn
.tm
->operand_types
[1] & op3T2
))
1643 /* Set the addressing mode to the values used for 2 operand
1644 instructions in the G addressing field of the opcode. */
1646 switch (insn
.operand_type
[0]->op_type
)
1652 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1653 insn
.addressing_mode
= AM_Register
;
1654 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1655 insn
.addressing_mode
= AM_Direct
;
1658 /* Shouldn't make it to this stage. */
1659 as_bad ("Incompatible first and second operands in instruction");
1664 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1665 insn
.addressing_mode
= AM_Indirect
;
1666 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1667 insn
.addressing_mode
= AM_Immediate
;
1670 /* Shouldn't make it to this stage. */
1671 as_bad ("Incompatible first and second operands in instruction");
1676 /* Now make up the opcode for the 3 operand instructions. As in
1677 parallel instructions, there will be no unresolved values, so they
1678 can be fully formed and added to the frag table. */
1679 insn
.opcode
= insn
.tm
->base_opcode
;
1680 if (insn
.operand_type
[0]->op_type
& Indirect
)
1682 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
1683 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
1686 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1688 if (insn
.operand_type
[1]->op_type
& Indirect
)
1690 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
1691 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
1694 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
1696 if (insn
.operands
== 3)
1697 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
1699 insn
.opcode
|= insn
.addressing_mode
;
1700 p
= frag_more (INSN_SIZE
);
1701 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1705 /* Not a three operand instruction. */
1708 insn
.opcode
= insn
.tm
->base_opcode
;
1709 /* Create frag for instruction - all instructions are 4 bytes long. */
1710 p
= frag_more (INSN_SIZE
);
1711 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
1713 insn
.opcode
|= insn
.addressing_mode
;
1714 if (insn
.addressing_mode
== AM_Indirect
)
1716 /* Determine which operand gives the addressing mode. */
1717 if (insn
.operand_type
[0]->op_type
& Indirect
)
1719 if ((insn
.operands
> 1)
1720 && (insn
.operand_type
[1]->op_type
& Indirect
))
1722 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
1723 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
1724 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
1725 if (insn
.operands
> 1)
1726 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
1727 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1729 else if (insn
.addressing_mode
== AM_Register
)
1731 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1732 if (insn
.operands
> 1)
1733 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1734 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1736 else if (insn
.addressing_mode
== AM_Direct
)
1738 if (insn
.operand_type
[0]->op_type
& Direct
)
1740 if ((insn
.operands
> 1)
1741 && (insn
.operand_type
[1]->op_type
& Direct
))
1743 if (insn
.operands
> 1)
1745 (insn
.operand_type
[! am_insn
]->reg
.opcode
<< 16);
1746 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
1748 /* Resolved values can be placed straight
1749 into instruction word, and output. */
1751 (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
1752 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1756 /* Unresolved direct addressing mode instruction. */
1757 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1758 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1759 & insn
.operand_type
[am_insn
]->direct
.direct_expr
,
1763 else if (insn
.addressing_mode
== AM_Immediate
)
1765 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1770 if (insn
.operands
> 1)
1771 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1773 switch (insn
.tm
->imm_arg_type
)
1776 debug ("Floating point first operand\n");
1777 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1779 keeploc
= input_line_pointer
;
1780 input_line_pointer
=
1781 insn
.operand_type
[0]->immediate
.label
;
1783 if (md_atof ('f', p
+ 2, & size
) != 0)
1785 as_bad ("invalid short form floating point immediate operand");
1789 input_line_pointer
= keeploc
;
1793 debug ("Unsigned int first operand\n");
1794 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1795 as_warn ("rounding down first operand float to unsigned int");
1796 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
1797 as_warn ("only lower 16-bits of first operand are used");
1799 (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
1800 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1804 debug ("Int first operand\n");
1806 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1807 as_warn ("rounding down first operand float to signed int");
1809 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1810 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1812 as_bad ("first operand is too large for 16-bit signed int");
1816 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
1817 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1823 /* Unresolved immediate label. */
1824 if (insn
.operands
> 1)
1825 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1826 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1827 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1828 & insn
.operand_type
[0]->immediate
.imm_expr
,
1833 else if (insn
.tm
->opcode_modifier
== PCRel
)
1835 /* Conditional Branch and Call instructions. */
1836 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
))
1839 if (insn
.operand_type
[0]->op_type
& (AllReg
))
1841 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1842 insn
.opcode
|= PC_Register
;
1843 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1847 insn
.opcode
|= PC_Relative
;
1848 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1851 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
1852 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1856 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1857 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
),
1858 2, & insn
.operand_type
[0]->immediate
.imm_expr
,
1863 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
1865 /* Decrement and Branch instructions. */
1866 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
1867 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1869 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
1870 insn
.opcode
|= PC_Register
;
1871 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1873 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
1875 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1877 as_bad ("first operand is floating point");
1880 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1881 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1883 as_bad ("first operand is too large for 16-bit signed int");
1886 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
1887 insn
.opcode
|= PC_Relative
;
1888 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1892 insn
.opcode
|= PC_Relative
;
1893 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1894 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2,
1895 & insn
.operand_type
[1]->immediate
.imm_expr
,
1900 else if (insn
.tm
->operand_types
[0] == IVector
)
1902 /* Trap instructions. */
1903 if (insn
.operand_type
[0]->op_type
& IVector
)
1904 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
1907 /* Shouldn't get here. */
1908 as_bad ("interrupt vector for trap instruction out of range");
1911 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1913 else if (insn
.tm
->opcode_modifier
== StackOp
1914 || insn
.tm
->opcode_modifier
== Rotate
)
1916 /* Push, Pop and Rotate instructions. */
1917 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
1918 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1920 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
))
1921 == (Abs24
| Direct
))
1923 /* LDP Instruction needs to be tested
1924 for before the next section. */
1925 if (insn
.operand_type
[0]->op_type
& Direct
)
1927 if (insn
.operand_type
[0]->direct
.resolved
== 1)
1929 /* Direct addressing uses lower 8 bits of direct address. */
1931 (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
1932 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1938 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1939 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1940 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
1941 /* Ensure that the assembler doesn't complain
1942 about fitting a 24-bit address into 8 bits. */
1943 fix
->fx_no_overflow
= 1;
1948 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1950 /* Immediate addressing uses upper 8 bits of address. */
1951 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1953 as_bad ("LDP instruction needs a 24-bit operand");
1957 ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
1958 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1963 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1964 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1965 1, &insn
.operand_type
[0]->immediate
.imm_expr
,
1967 fix
->fx_no_overflow
= 1;
1971 else if (insn
.tm
->operand_types
[0] & (Imm24
))
1973 /* Unconditional Branch and Call instructions. */
1974 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1976 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1977 as_warn ("first operand is too large for a 24-bit displacement");
1979 (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
1980 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1984 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1985 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3,
1986 & insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
1989 else if (insn
.tm
->operand_types
[0] & NotReq
)
1990 /* Check for NOP instruction without arguments. */
1991 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1993 else if (insn
.tm
->operands
== 0)
1994 /* Check for instructions without operands. */
1995 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1997 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
2001 for (i
= 0; i
< insn
.operands
; i
++)
2003 if (insn
.operand_type
[i
]->immediate
.label
)
2004 free (insn
.operand_type
[i
]->immediate
.label
);
2005 free (insn
.operand_type
[i
]);
2008 debug ("Final opcode: %08X\n", insn
.opcode
);