1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998-2023 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
22 /* Texas Instruments TMS320C30 machine specific gas.
23 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
24 Bugs & suggestions are completely welcome. This is free software.
25 Please help us make it better. */
28 #include "safe-ctype.h"
29 #include "opcode/tic30.h"
31 /* Put here all non-digit non-letter characters that may occur in an
33 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
34 static const char *ordinal_names
[] =
36 N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
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
[] =
46 {NULL
, no_argument
, NULL
, 0}
49 size_t md_longopts_size
= sizeof (md_longopts
);
51 /* Chars that mean this number is a floating point constant.
54 const char FLT_CHARS
[] = "fFdDxX";
56 /* Chars that can be used to separate mant from exp in floating point
58 const char EXP_CHARS
[] = "eE";
60 /* Tables for lexical analysis. */
61 static char opcode_chars
[256];
62 static char register_chars
[256];
63 static char operand_chars
[256];
64 static char space_chars
[256];
65 static char identifier_chars
[256];
66 static char digit_chars
[256];
69 #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
70 #define is_operand_char(x) (operand_chars [(unsigned char) x])
71 #define is_register_char(x) (register_chars [(unsigned char) x])
72 #define is_space_char(x) (space_chars [(unsigned char) x])
73 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
74 #define is_digit_char(x) (digit_chars [(unsigned char) x])
76 const pseudo_typeS md_pseudo_table
[] =
81 static int ATTRIBUTE_PRINTF_1
82 debug (const char *string
, ...)
89 va_start (argptr
, string
);
90 vsprintf (str
, string
, argptr
);
94 fputs (str
, USE_STDOUT
? stdout
: stderr
);
101 /* Hash table for opcode lookup. */
102 static htab_t op_hash
;
103 /* Hash table for parallel opcode lookup. */
104 static htab_t parop_hash
;
105 /* Hash table for register lookup. */
106 static htab_t reg_hash
;
107 /* Hash table for indirect addressing lookup. */
108 static htab_t ind_hash
;
113 debug ("In md_begin()\n");
114 op_hash
= str_htab_create ();
117 const insn_template
*current_optab
= tic30_optab
;
119 for (; current_optab
< tic30_optab_end
; current_optab
++)
120 if (str_hash_insert (op_hash
, current_optab
->name
, current_optab
, 0))
121 as_fatal (_("duplicate %s"), current_optab
->name
);
124 parop_hash
= str_htab_create ();
127 const partemplate
*current_parop
= tic30_paroptab
;
129 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
130 if (str_hash_insert (parop_hash
, current_parop
->name
, current_parop
, 0))
131 as_fatal (_("duplicate %s"), current_parop
->name
);
134 reg_hash
= str_htab_create ();
137 const reg
*current_reg
= tic30_regtab
;
139 for (; current_reg
< tic30_regtab_end
; current_reg
++)
140 if (str_hash_insert (reg_hash
, current_reg
->name
, current_reg
, 0))
141 as_fatal (_("duplicate %s"), current_reg
->name
);
144 ind_hash
= str_htab_create ();
147 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
149 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
150 if (str_hash_insert (ind_hash
, current_ind
->syntax
, current_ind
, 0))
151 as_fatal (_("duplicate %s"), current_ind
->syntax
);
154 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
159 for (c
= 0; c
< 256; c
++)
161 if (ISLOWER (c
) || ISDIGIT (c
))
164 register_chars
[c
] = c
;
166 else if (ISUPPER (c
))
168 opcode_chars
[c
] = TOLOWER (c
);
169 register_chars
[c
] = opcode_chars
[c
];
171 else if (c
== ')' || c
== '(')
172 register_chars
[c
] = c
;
174 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
175 operand_chars
[c
] = c
;
177 if (ISDIGIT (c
) || c
== '-')
180 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
181 identifier_chars
[c
] = c
;
183 if (c
== ' ' || c
== '\t')
189 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
190 operand_chars
[(unsigned char) *p
] = *p
;
194 /* Address Mode OR values. */
195 #define AM_Register 0x00000000
196 #define AM_Direct 0x00200000
197 #define AM_Indirect 0x00400000
198 #define AM_Immediate 0x00600000
199 #define AM_NotReq 0xFFFFFFFF
201 /* PC Relative OR values. */
202 #define PC_Register 0x00000000
203 #define PC_Relative 0x02000000
213 expressionS direct_expr
;
231 unsigned int u_number
;
233 expressionS imm_expr
;
237 insn_template
*opcode
;
241 insn_template
*tm
; /* Template of current instruction. */
242 unsigned opcode
; /* Final opcode. */
243 unsigned int operands
; /* Number of given operands. */
244 /* Type of operand given in instruction. */
245 operand
*operand_type
[MAX_OPERANDS
];
246 unsigned addressing_mode
; /* Final addressing mode of instruction. */
249 struct tic30_insn insn
;
250 static int found_parallel_insn
;
252 static char output_invalid_buf
[sizeof (unsigned char) * 2 + 6];
255 output_invalid (char c
)
258 snprintf (output_invalid_buf
, sizeof (output_invalid_buf
),
261 snprintf (output_invalid_buf
, sizeof (output_invalid_buf
),
262 "(0x%x)", (unsigned char) c
);
263 return output_invalid_buf
;
266 /* next_line points to the next line after the current instruction
267 (current_line). Search for the parallel bars, and if found, merge two
268 lines into internal syntax for a parallel instruction:
269 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
270 By this stage, all comments are scrubbed, and only the bare lines are
274 #define START_OPCODE 1
276 #define START_OPERANDS 3
277 #define END_OPERANDS 4
280 tic30_find_parallel_insn (char *current_line
, char *next_line
)
282 int found_parallel
= 0;
283 char first_opcode
[256];
284 char second_opcode
[256];
285 char first_operands
[256];
286 char second_operands
[256];
289 debug ("In tic30_find_parallel_insn()\n");
290 while (!is_end_of_line
[(unsigned char) *next_line
])
292 if (*next_line
== PARALLEL_SEPARATOR
293 && *(next_line
+ 1) == PARALLEL_SEPARATOR
)
303 debug ("Found a parallel instruction\n");
307 char *op
, *operands
, *line
;
309 for (i
= 0; i
< 2; i
++)
313 op
= &first_opcode
[0];
314 operands
= &first_operands
[0];
319 op
= &second_opcode
[0];
320 operands
= &second_operands
[0];
325 int search_status
= NONE
;
329 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
331 if (is_opcode_char (c
) && search_status
== NONE
)
333 op
[char_ptr
++] = TOLOWER (c
);
334 search_status
= START_OPCODE
;
336 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
337 op
[char_ptr
++] = TOLOWER (c
);
338 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
342 search_status
= END_OPCODE
;
344 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
345 operands
[char_ptr
++] = c
;
347 if (is_operand_char (c
) && search_status
== END_OPCODE
)
349 operands
[char_ptr
++] = c
;
350 search_status
= START_OPERANDS
;
355 if (search_status
!= START_OPERANDS
)
357 operands
[char_ptr
] = '\0';
362 parallel_insn
= concat ("q_", first_opcode
, "_", second_opcode
, " ",
363 first_operands
, " | ", second_operands
,
365 debug ("parallel insn = %s\n", parallel_insn
);
366 return parallel_insn
;
372 #undef START_OPERANDS
376 tic30_operand (char *token
)
381 debug ("In tic30_operand with %s\n", token
);
382 current_op
= XCNEW (operand
);
384 if (*token
== DIRECT_REFERENCE
)
386 char *token_posn
= token
+ 1;
387 int direct_label
= 0;
389 debug ("Found direct reference\n");
392 if (!is_digit_char (*token_posn
))
399 char *save_input_line_pointer
;
402 debug ("Direct reference is a label\n");
403 current_op
->direct
.label
= token
+ 1;
404 save_input_line_pointer
= input_line_pointer
;
405 input_line_pointer
= token
+ 1;
406 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
407 retval
= expression (¤t_op
->direct
.direct_expr
);
409 debug ("Expression type: %d\n",
410 current_op
->direct
.direct_expr
.X_op
);
411 debug ("Expression addnum: %ld\n",
412 (long) current_op
->direct
.direct_expr
.X_add_number
);
413 debug ("Segment: %p\n", retval
);
415 input_line_pointer
= save_input_line_pointer
;
417 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
419 current_op
->direct
.address
=
420 current_op
->direct
.direct_expr
.X_add_number
;
421 current_op
->direct
.resolved
= 1;
426 debug ("Direct reference is a number\n");
427 current_op
->direct
.address
= atoi (token
+ 1);
428 current_op
->direct
.resolved
= 1;
430 current_op
->op_type
= Direct
;
432 else if (*token
== INDIRECT_REFERENCE
)
434 /* Indirect reference operand. */
440 ind_addr_type
*ind_addr_op
;
443 ind_buffer
= XNEWVEC (char, strlen (token
));
445 debug ("Found indirect reference\n");
446 ind_buffer
[0] = *token
;
448 for (count
= 1; count
< strlen (token
); count
++)
451 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
453 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A')
454 && (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
456 /* AR reference is found, so get its number and remove
457 it from the buffer so it can pass through str_hash_find(). */
460 as_bad (_("More than one AR register found in indirect reference"));
464 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
466 as_bad (_("Illegal AR register in indirect reference"));
470 ar_number
= *(token
+ count
+ 1) - '0';
475 if (*(token
+ count
) == '(')
477 /* Parenthesis found, so check if a displacement value is
478 inside. If so, get the value and remove it from the
480 if (is_digit_char (*(token
+ count
+ 1)))
487 as_bad (_("More than one displacement found in indirect reference"));
492 while (*(token
+ count
) != ')')
494 if (!is_digit_char (*(token
+ count
)))
496 as_bad (_("Invalid displacement in indirect reference"));
500 disp
[disp_posn
++] = *(token
+ (count
++));
502 disp
[disp_posn
] = '\0';
503 disp_number
= atoi (disp
);
511 ind_buffer
[buffer_posn
] = '\0';
514 as_bad (_("AR register not found in indirect reference"));
519 ind_addr_op
= (ind_addr_type
*) str_hash_find (ind_hash
, ind_buffer
);
522 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
523 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
528 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
530 /* Maybe an implied displacement of 1 again. */
531 as_bad (_("required displacement wasn't given in indirect reference"));
538 as_bad (_("illegal indirect reference"));
543 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
545 as_bad (_("displacement must be an unsigned 8-bit number"));
550 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
551 current_op
->indirect
.disp
= disp_number
;
552 current_op
->indirect
.ARnum
= ar_number
;
553 current_op
->op_type
= Indirect
;
558 reg
*regop
= (reg
*) str_hash_find (reg_hash
, token
);
562 debug ("Found register operand: %s\n", regop
->name
);
563 if (regop
->regtype
== REG_ARn
)
564 current_op
->op_type
= ARn
;
565 else if (regop
->regtype
== REG_Rn
)
566 current_op
->op_type
= Rn
;
567 else if (regop
->regtype
== REG_DP
)
568 current_op
->op_type
= DPReg
;
570 current_op
->op_type
= OtherReg
;
571 current_op
->reg
.opcode
= regop
->opcode
;
575 if (!is_digit_char (*token
)
576 || *(token
+ 1) == 'x'
577 || strchr (token
, 'h'))
579 char *save_input_line_pointer
;
582 debug ("Probably a label: %s\n", token
);
583 current_op
->immediate
.label
= xstrdup (token
);
584 save_input_line_pointer
= input_line_pointer
;
585 input_line_pointer
= token
;
587 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
588 retval
= expression (¤t_op
->immediate
.imm_expr
);
589 debug ("Expression type: %d\n",
590 current_op
->immediate
.imm_expr
.X_op
);
591 debug ("Expression addnum: %ld\n",
592 (long) current_op
->immediate
.imm_expr
.X_add_number
);
593 debug ("Segment: %p\n", retval
);
594 input_line_pointer
= save_input_line_pointer
;
596 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
598 current_op
->immediate
.s_number
599 = current_op
->immediate
.imm_expr
.X_add_number
;
600 current_op
->immediate
.u_number
601 = (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
602 current_op
->immediate
.resolved
= 1;
607 debug ("Found a number or displacement\n");
608 for (count
= 0; count
< strlen (token
); count
++)
609 if (*(token
+ count
) == '.')
610 current_op
->immediate
.decimal_found
= 1;
611 current_op
->immediate
.label
= xstrdup (token
);
612 current_op
->immediate
.f_number
= (float) atof (token
);
613 current_op
->immediate
.s_number
= (int) atoi (token
);
614 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
615 current_op
->immediate
.resolved
= 1;
617 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
618 if (current_op
->immediate
.u_number
<= 31)
619 current_op
->op_type
|= IVector
;
625 struct tic30_par_insn
627 partemplate
*tm
; /* Template of current parallel instruction. */
628 unsigned operands
[2]; /* Number of given operands for each insn. */
629 /* Type of operand given in instruction. */
630 operand
*operand_type
[2][MAX_OPERANDS
];
631 int swap_operands
; /* Whether to swap operands around. */
632 unsigned p_field
; /* Value of p field in multiply add/sub instructions. */
633 unsigned opcode
; /* Final opcode. */
636 struct tic30_par_insn p_insn
;
639 tic30_parallel_insn (char *token
)
641 static partemplate
*p_opcode
;
642 char *current_posn
= token
;
646 debug ("In tic30_parallel_insn with %s\n", token
);
647 memset (&p_insn
, '\0', sizeof (p_insn
));
649 while (is_opcode_char (*current_posn
))
652 /* Find instruction. */
653 save_char
= *current_posn
;
654 *current_posn
= '\0';
655 p_opcode
= (partemplate
*) str_hash_find (parop_hash
, token
);
658 debug ("Found instruction %s\n", p_opcode
->name
);
659 p_insn
.tm
= p_opcode
;
663 char first_opcode
[6] = {0};
664 char second_opcode
[6] = {0};
666 int current_opcode
= -1;
669 for (i
= 0; i
< strlen (token
); i
++)
671 char ch
= *(token
+ i
);
673 if (ch
== '_' && current_opcode
== -1)
679 if (ch
== '_' && current_opcode
== 0)
686 switch (current_opcode
)
689 first_opcode
[char_ptr
++] = ch
;
692 second_opcode
[char_ptr
++] = ch
;
697 debug ("first_opcode = %s\n", first_opcode
);
698 debug ("second_opcode = %s\n", second_opcode
);
699 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
700 p_opcode
= (partemplate
*) str_hash_find (parop_hash
, token
);
704 debug ("Found instruction %s\n", p_opcode
->name
);
705 p_insn
.tm
= p_opcode
;
706 p_insn
.swap_operands
= 1;
711 *current_posn
= save_char
;
716 int paren_not_balanced
;
717 int expecting_operand
= 0;
718 int found_separator
= 0;
722 /* Skip optional white space before operand. */
723 while (!is_operand_char (*current_posn
)
724 && *current_posn
!= END_OF_INSN
)
726 if (!is_space_char (*current_posn
)
727 && *current_posn
!= PARALLEL_SEPARATOR
)
729 as_bad (_("Invalid character %s before %s operand"),
730 output_invalid (*current_posn
),
731 ordinal_names
[insn
.operands
]);
734 if (*current_posn
== PARALLEL_SEPARATOR
)
739 token_start
= current_posn
;
740 paren_not_balanced
= 0;
742 while (paren_not_balanced
|| *current_posn
!= ',')
744 if (*current_posn
== END_OF_INSN
)
746 if (paren_not_balanced
)
748 as_bad (_("Unbalanced parenthesis in %s operand."),
749 ordinal_names
[insn
.operands
]);
755 else if (*current_posn
== PARALLEL_SEPARATOR
)
757 while (is_space_char (*(current_posn
- 1)))
761 else if (!is_operand_char (*current_posn
)
762 && !is_space_char (*current_posn
))
764 as_bad (_("Invalid character %s in %s operand"),
765 output_invalid (*current_posn
),
766 ordinal_names
[insn
.operands
]);
770 if (*current_posn
== '(')
771 ++paren_not_balanced
;
772 if (*current_posn
== ')')
773 --paren_not_balanced
;
777 if (current_posn
!= token_start
)
779 /* Yes, we've read in another operand. */
780 p_insn
.operands
[found_separator
]++;
781 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
783 as_bad (_("Spurious operands; (%d operands/instruction max)"),
788 /* Now parse operand adding info to 'insn' as we go along. */
789 save_char
= *current_posn
;
790 *current_posn
= '\0';
791 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
792 tic30_operand (token_start
);
793 *current_posn
= save_char
;
794 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
799 if (expecting_operand
)
801 as_bad (_("Expecting operand after ','; got nothing"));
804 if (*current_posn
== ',')
806 as_bad (_("Expecting operand before ','; got nothing"));
811 /* Now *current_posn must be either ',' or END_OF_INSN. */
812 if (*current_posn
== ',')
814 if (*++current_posn
== END_OF_INSN
)
816 /* Just skip it, if it's \n complain. */
817 as_bad (_("Expecting operand after ','; got nothing"));
820 expecting_operand
= 1;
823 while (*current_posn
!= END_OF_INSN
);
826 if (p_insn
.swap_operands
)
831 temp_num
= p_insn
.operands
[0];
832 p_insn
.operands
[0] = p_insn
.operands
[1];
833 p_insn
.operands
[1] = temp_num
;
834 for (i
= 0; i
< MAX_OPERANDS
; i
++)
836 temp_op
= p_insn
.operand_type
[0][i
];
837 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
838 p_insn
.operand_type
[1][i
] = temp_op
;
842 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
844 as_bad (_("incorrect number of operands given in the first instruction"));
848 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
850 as_bad (_("incorrect number of operands given in the second instruction"));
854 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
855 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
858 /* Now check if operands are correct. */
863 for (count
= 0; count
< 2; count
++)
866 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
868 if ((p_insn
.operand_type
[count
][i
]->op_type
&
869 p_insn
.tm
->operand_types
[count
][i
]) == 0)
871 as_bad (_("%s instruction, operand %d doesn't match"),
872 ordinal_names
[count
], i
+ 1);
876 /* Get number of R register and indirect reference contained
877 within the first two operands of each instruction. This is
878 required for the multiply parallel instructions which require
879 two R registers and two indirect references, but not in any
881 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
883 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
)
889 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
))
892 /* Check for the multiply instructions. */
895 as_bad (_("incorrect format for multiply parallel instruction"));
901 /* Shouldn't get here. */
902 as_bad (_("incorrect format for multiply parallel instruction"));
906 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00)
907 && (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
909 as_bad (_("destination for multiply can only be R0 or R1"));
913 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02)
914 && (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
916 as_bad (_("destination for add/subtract can only be R2 or R3"));
920 /* Now determine the P field for the instruction. */
921 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
923 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
924 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn. */
925 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
926 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn. */
928 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind. */
932 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
933 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind. */
934 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
937 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn. */
938 /* Need to swap the two multiply operands around so that
939 everything is in its place for the opcode makeup.
940 ie so Ind * Rn, Ind +/- Rn. */
941 temp
= p_insn
.operand_type
[0][0];
942 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
943 p_insn
.operand_type
[0][1] = temp
;
948 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind. */
949 temp
= p_insn
.operand_type
[0][0];
950 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
951 p_insn
.operand_type
[0][1] = temp
;
957 debug ("P field: %08X\n", p_insn
.p_field
);
959 /* Finalise opcode. This is easier for parallel instructions as they have
960 to be fully resolved, there are no memory addresses allowed, except
961 through indirect addressing, so there are no labels to resolve. */
962 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
964 switch (p_insn
.tm
->oporder
)
967 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
968 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
969 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
970 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
971 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
972 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
976 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
977 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
978 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
979 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
980 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
981 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
982 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
983 as_warn (_("loading the same register in parallel operation"));
987 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
988 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
989 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
990 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
991 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
992 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
996 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
997 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
998 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
999 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1000 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1001 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1002 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1006 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1007 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1008 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1009 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1010 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1011 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1012 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1016 p_insn
.opcode
|= p_insn
.p_field
;
1017 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1018 p_insn
.opcode
|= 0x00800000;
1019 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1020 p_insn
.opcode
|= 0x00400000;
1022 switch (p_insn
.p_field
)
1025 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1026 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1027 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1028 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1029 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1030 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1033 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1034 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1035 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1036 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1037 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1038 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1041 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1042 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1043 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1044 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1045 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1046 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1049 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1050 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1051 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1052 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1053 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1054 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1063 p
= frag_more (INSN_SIZE
);
1064 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1070 for (i
= 0; i
< 2; i
++)
1071 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1072 free (p_insn
.operand_type
[i
][j
]);
1075 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1081 /* In order to get gas to ignore any | chars at the start of a line,
1082 this function returns true if a | is found in a line. */
1085 tic30_unrecognized_line (int c
)
1087 debug ("In tc_unrecognized_line\n");
1088 return (c
== PARALLEL_SEPARATOR
);
1092 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
1093 segT segment ATTRIBUTE_UNUSED
)
1095 debug ("In md_estimate_size_before_relax()\n");
1100 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1101 segT sec ATTRIBUTE_UNUSED
,
1102 fragS
*fragP ATTRIBUTE_UNUSED
)
1104 debug ("In md_convert_frag()\n");
1108 md_apply_fix (fixS
*fixP
,
1110 segT seg ATTRIBUTE_UNUSED
)
1112 valueT value
= *valP
;
1114 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1115 debug ("Values in fixP\n");
1116 debug ("fx_size = %d\n", fixP
->fx_size
);
1117 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1118 debug ("fx_where = %ld\n", fixP
->fx_where
);
1119 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1121 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1124 if (fixP
->fx_size
== 1)
1125 /* Special fix for LDP instruction. */
1126 value
= (value
& 0x00FF0000) >> 16;
1128 debug ("new value = %ld\n", (long) value
);
1129 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1132 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1137 md_parse_option (int c ATTRIBUTE_UNUSED
,
1138 const char *arg ATTRIBUTE_UNUSED
)
1140 debug ("In md_parse_option()\n");
1145 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
1147 debug ("In md_show_usage()\n");
1151 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1153 debug ("In md_undefined_symbol()\n");
1154 return (symbolS
*) 0;
1158 md_section_align (segT segment
, valueT size
)
1160 debug ("In md_section_align() segment = %p and size = %lu\n",
1161 segment
, (unsigned long) size
);
1162 size
= (size
+ 3) / 4;
1164 debug ("New size value = %lu\n", (unsigned long) size
);
1169 md_pcrel_from (fixS
*fixP
)
1173 debug ("In md_pcrel_from()\n");
1174 debug ("fx_where = %ld\n", fixP
->fx_where
);
1175 debug ("fx_size = %d\n", fixP
->fx_size
);
1176 /* Find the opcode that represents the current instruction in the
1177 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1178 current instruction is a delayed one or not, and then set the offset
1179 value appropriately. */
1180 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1184 debug ("offset = %d\n", offset
);
1185 /* PC Relative instructions have a format:
1186 displacement = Label - (PC + offset)
1187 This function returns PC + offset where:
1188 fx_where - fx_size = PC
1189 INSN_SIZE * offset = offset number of instructions. */
1190 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1194 md_atof (int what_statement_type
,
1201 unsigned long value
;
1204 debug ("In md_atof()\n");
1205 debug ("precision = %c\n", what_statement_type
);
1206 debug ("literal = %s\n", literalP
);
1208 token
= input_line_pointer
;
1209 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1210 && (*input_line_pointer
!= ','))
1212 debug ("%c", *input_line_pointer
);
1213 input_line_pointer
++;
1216 keepval
= *input_line_pointer
;
1217 *input_line_pointer
= '\0';
1219 float_value
= (float) atof (token
);
1220 *input_line_pointer
= keepval
;
1221 debug ("float_value = %f\n", float_value
);
1223 switch (what_statement_type
)
1241 return _("Unrecognized or unsupported floating point constant");
1244 if (float_value
== 0.0)
1245 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1248 unsigned long exp
, sign
, mant
, tmsfloat
;
1256 converter
.f
= float_value
;
1257 tmsfloat
= converter
.l
;
1258 sign
= tmsfloat
& 0x80000000;
1259 mant
= tmsfloat
& 0x007FFFFF;
1260 exp
= tmsfloat
& 0x7F800000;
1262 if (exp
== 0xFF000000)
1276 mant
= mant
& 0x007FFFFF;
1278 mant
= mant
& 0x00FFFFFF;
1282 exp
= (long) exp
- 0x01000000;
1285 tmsfloat
= exp
| mant
;
1292 if (tmsfloat
== 0x80000000)
1297 expon
= (tmsfloat
& 0xFF000000);
1299 mantis
= tmsfloat
& 0x007FFFFF;
1300 if (tmsfloat
& 0x00800000)
1302 mantis
|= 0xFF000000;
1303 mantis
+= 0x00000800;
1305 mantis
|= 0x00000800;
1312 mantis
|= 0x00800000;
1313 mantis
+= 0x00000800;
1314 expon
+= (mantis
>> 24);
1324 mantis
= (expon
<< 12) | mantis
;
1325 value
= mantis
& 0xFFFF;
1330 md_number_to_chars (literalP
, value
, prec
);
1336 md_number_to_chars (char *buf
, valueT val
, int n
)
1338 debug ("In md_number_to_chars()\n");
1339 number_to_chars_bigendian (buf
, val
, n
);
1342 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1343 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1346 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
1349 bfd_reloc_code_real_type code
= 0;
1351 debug ("In tc_gen_reloc()\n");
1352 debug ("fixP.size = %d\n", fixP
->fx_size
);
1353 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1354 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1356 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1358 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1359 MAP (2, 0, BFD_RELOC_16
);
1360 MAP (3, 0, BFD_RELOC_24
);
1361 MAP (2, 1, BFD_RELOC_16_PCREL
);
1362 MAP (4, 0, BFD_RELOC_32
);
1364 as_bad (_("Can not do %d byte %srelocation"), fixP
->fx_size
,
1365 fixP
->fx_pcrel
? _("pc-relative ") : "");
1370 rel
= XNEW (arelent
);
1371 gas_assert (rel
!= 0);
1372 rel
->sym_ptr_ptr
= XNEW (asymbol
*);
1373 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1374 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1376 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1381 name
= S_GET_NAME (fixP
->fx_addsy
);
1384 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1385 name
, bfd_get_reloc_code_name (code
));
1391 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1393 debug ("In md_operand()\n");
1397 md_assemble (char *line
)
1405 debug ("In md_assemble() with argument %s\n", line
);
1406 memset (&insn
, '\0', sizeof (insn
));
1407 if (found_parallel_insn
)
1409 debug ("Line is second part of parallel instruction\n\n");
1410 found_parallel_insn
= 0;
1414 tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
1415 current_posn
= line
;
1417 found_parallel_insn
= 1;
1419 while (is_space_char (*current_posn
))
1422 token_start
= current_posn
;
1424 if (!is_opcode_char (*current_posn
))
1426 as_bad (_("Invalid character %s in opcode"),
1427 output_invalid (*current_posn
));
1430 /* Check if instruction is a parallel instruction
1431 by seeing if the first character is a q. */
1432 if (*token_start
== 'q')
1434 if (tic30_parallel_insn (token_start
))
1436 if (found_parallel_insn
)
1441 while (is_opcode_char (*current_posn
))
1444 /* Find instruction. */
1445 save_char
= *current_posn
;
1446 *current_posn
= '\0';
1447 op
= (insn_template
*) str_hash_find (op_hash
, token_start
);
1450 debug ("Found instruction %s\n", op
->name
);
1455 debug ("Didn't find insn\n");
1456 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start
);
1459 *current_posn
= save_char
;
1462 if (*current_posn
!= END_OF_INSN
)
1464 /* Find operands. */
1465 int paren_not_balanced
;
1466 int expecting_operand
= 0;
1470 /* Skip optional white space before operand. */
1471 while (!is_operand_char (*current_posn
)
1472 && *current_posn
!= END_OF_INSN
)
1474 if (!is_space_char (*current_posn
))
1476 as_bad (_("Invalid character %s before %s operand"),
1477 output_invalid (*current_posn
),
1478 ordinal_names
[insn
.operands
]);
1483 token_start
= current_posn
;
1484 paren_not_balanced
= 0;
1485 while (paren_not_balanced
|| *current_posn
!= ',')
1487 if (*current_posn
== END_OF_INSN
)
1489 if (paren_not_balanced
)
1491 as_bad (_("Unbalanced parenthesis in %s operand."),
1492 ordinal_names
[insn
.operands
]);
1498 else if (!is_operand_char (*current_posn
)
1499 && !is_space_char (*current_posn
))
1501 as_bad (_("Invalid character %s in %s operand"),
1502 output_invalid (*current_posn
),
1503 ordinal_names
[insn
.operands
]);
1506 if (*current_posn
== '(')
1507 ++paren_not_balanced
;
1508 if (*current_posn
== ')')
1509 --paren_not_balanced
;
1512 if (current_posn
!= token_start
)
1514 /* Yes, we've read in another operand. */
1515 this_operand
= insn
.operands
++;
1516 if (insn
.operands
> MAX_OPERANDS
)
1518 as_bad (_("Spurious operands; (%d operands/instruction max)"),
1523 /* Now parse operand adding info to 'insn' as we go along. */
1524 save_char
= *current_posn
;
1525 *current_posn
= '\0';
1526 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
1527 *current_posn
= save_char
;
1528 if (insn
.operand_type
[this_operand
] == NULL
)
1533 if (expecting_operand
)
1535 as_bad (_("Expecting operand after ','; got nothing"));
1538 if (*current_posn
== ',')
1540 as_bad (_("Expecting operand before ','; got nothing"));
1545 /* Now *current_posn must be either ',' or END_OF_INSN. */
1546 if (*current_posn
== ',')
1548 if (*++current_posn
== END_OF_INSN
)
1550 /* Just skip it, if it's \n complain. */
1551 as_bad (_("Expecting operand after ','; got nothing"));
1554 expecting_operand
= 1;
1557 while (*current_posn
!= END_OF_INSN
);
1560 debug ("Number of operands found: %d\n", insn
.operands
);
1562 /* Check that number of operands is correct. */
1563 if (insn
.operands
!= insn
.tm
->operands
)
1566 unsigned int numops
= insn
.tm
->operands
;
1568 /* If operands are not the same, then see if any of the operands are
1569 not required. Then recheck with number of given operands. If they
1570 are still not the same, then give an error, otherwise carry on. */
1571 for (i
= 0; i
< insn
.tm
->operands
; i
++)
1572 if (insn
.tm
->operand_types
[i
] & NotReq
)
1574 if (insn
.operands
!= numops
)
1576 as_bad (_("Incorrect number of operands given"));
1580 insn
.addressing_mode
= AM_NotReq
;
1581 for (count
= 0; count
< insn
.operands
; count
++)
1583 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
1585 debug ("Operand %d matches\n", count
+ 1);
1586 /* If instruction has two operands and has an AddressMode
1587 modifier then set addressing mode type for instruction. */
1588 if (insn
.tm
->opcode_modifier
== AddressMode
)
1591 /* Store instruction uses the second
1592 operand for the address mode. */
1593 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
))
1594 == (Indirect
| Direct
))
1597 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
1598 insn
.addressing_mode
= AM_Register
;
1599 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
1600 insn
.addressing_mode
= AM_Direct
;
1601 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
1602 insn
.addressing_mode
= AM_Indirect
;
1604 insn
.addressing_mode
= AM_Immediate
;
1609 as_bad (_("The %s operand doesn't match"), ordinal_names
[count
]);
1614 /* Now set the addressing mode for 3 operand instructions. */
1615 if ((insn
.tm
->operand_types
[0] & op3T1
)
1616 && (insn
.tm
->operand_types
[1] & op3T2
))
1618 /* Set the addressing mode to the values used for 2 operand
1619 instructions in the G addressing field of the opcode. */
1621 switch (insn
.operand_type
[0]->op_type
)
1627 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1628 insn
.addressing_mode
= AM_Register
;
1629 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1630 insn
.addressing_mode
= AM_Direct
;
1633 /* Shouldn't make it to this stage. */
1634 as_bad (_("Incompatible first and second operands in instruction"));
1639 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1640 insn
.addressing_mode
= AM_Indirect
;
1641 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1642 insn
.addressing_mode
= AM_Immediate
;
1645 /* Shouldn't make it to this stage. */
1646 as_bad (_("Incompatible first and second operands in instruction"));
1651 /* Now make up the opcode for the 3 operand instructions. As in
1652 parallel instructions, there will be no unresolved values, so they
1653 can be fully formed and added to the frag table. */
1654 insn
.opcode
= insn
.tm
->base_opcode
;
1655 if (insn
.operand_type
[0]->op_type
& Indirect
)
1657 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
1658 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
1661 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1663 if (insn
.operand_type
[1]->op_type
& Indirect
)
1665 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
1666 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
1669 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
1671 if (insn
.operands
== 3)
1672 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
1674 insn
.opcode
|= insn
.addressing_mode
;
1675 p
= frag_more (INSN_SIZE
);
1676 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1680 /* Not a three operand instruction. */
1683 insn
.opcode
= insn
.tm
->base_opcode
;
1684 /* Create frag for instruction - all instructions are 4 bytes long. */
1685 p
= frag_more (INSN_SIZE
);
1686 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
1688 insn
.opcode
|= insn
.addressing_mode
;
1689 if (insn
.addressing_mode
== AM_Indirect
)
1691 /* Determine which operand gives the addressing mode. */
1692 if (insn
.operand_type
[0]->op_type
& Indirect
)
1694 if ((insn
.operands
> 1)
1695 && (insn
.operand_type
[1]->op_type
& Indirect
))
1697 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
1698 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
1699 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
1700 if (insn
.operands
> 1)
1701 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
1702 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1704 else if (insn
.addressing_mode
== AM_Register
)
1706 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1707 if (insn
.operands
> 1)
1708 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1709 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1711 else if (insn
.addressing_mode
== AM_Direct
)
1713 if (insn
.operand_type
[0]->op_type
& Direct
)
1715 if ((insn
.operands
> 1)
1716 && (insn
.operand_type
[1]->op_type
& Direct
))
1718 if (insn
.operands
> 1)
1720 (insn
.operand_type
[! am_insn
]->reg
.opcode
<< 16);
1721 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
1723 /* Resolved values can be placed straight
1724 into instruction word, and output. */
1726 (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
1727 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1731 /* Unresolved direct addressing mode instruction. */
1732 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1733 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1734 & insn
.operand_type
[am_insn
]->direct
.direct_expr
,
1738 else if (insn
.addressing_mode
== AM_Immediate
)
1740 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1745 if (insn
.operands
> 1)
1746 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1748 switch (insn
.tm
->imm_arg_type
)
1751 debug ("Floating point first operand\n");
1752 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1754 keeploc
= input_line_pointer
;
1755 input_line_pointer
=
1756 insn
.operand_type
[0]->immediate
.label
;
1758 if (md_atof ('f', p
+ 2, & size
) != 0)
1760 as_bad (_("invalid short form floating point immediate operand"));
1764 input_line_pointer
= keeploc
;
1768 debug ("Unsigned int first operand\n");
1769 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1770 as_warn (_("rounding down first operand float to unsigned int"));
1771 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
1772 as_warn (_("only lower 16-bits of first operand are used"));
1774 (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
1775 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1779 debug ("Int first operand\n");
1781 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1782 as_warn (_("rounding down first operand float to signed int"));
1784 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1785 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1787 as_bad (_("first operand is too large for 16-bit signed int"));
1791 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
1792 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1798 /* Unresolved immediate label. */
1799 if (insn
.operands
> 1)
1800 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1801 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1802 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1803 & insn
.operand_type
[0]->immediate
.imm_expr
,
1808 else if (insn
.tm
->opcode_modifier
== PCRel
)
1810 /* Conditional Branch and Call instructions. */
1811 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
))
1814 if (insn
.operand_type
[0]->op_type
& (AllReg
))
1816 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1817 insn
.opcode
|= PC_Register
;
1818 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1822 insn
.opcode
|= PC_Relative
;
1823 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1826 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
1827 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1831 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1832 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
),
1833 2, & insn
.operand_type
[0]->immediate
.imm_expr
,
1838 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
1840 /* Decrement and Branch instructions. */
1841 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
1842 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1844 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
1845 insn
.opcode
|= PC_Register
;
1846 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1848 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
1850 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1852 as_bad (_("first operand is floating point"));
1855 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1856 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1858 as_bad (_("first operand is too large for 16-bit signed int"));
1861 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
1862 insn
.opcode
|= PC_Relative
;
1863 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1867 insn
.opcode
|= PC_Relative
;
1868 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1869 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2,
1870 & insn
.operand_type
[1]->immediate
.imm_expr
,
1875 else if (insn
.tm
->operand_types
[0] == IVector
)
1877 /* Trap instructions. */
1878 if (insn
.operand_type
[0]->op_type
& IVector
)
1879 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
1882 /* Shouldn't get here. */
1883 as_bad (_("interrupt vector for trap instruction out of range"));
1886 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1888 else if (insn
.tm
->opcode_modifier
== StackOp
1889 || insn
.tm
->opcode_modifier
== Rotate
)
1891 /* Push, Pop and Rotate instructions. */
1892 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
1893 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1895 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
))
1896 == (Abs24
| Direct
))
1898 /* LDP Instruction needs to be tested
1899 for before the next section. */
1900 if (insn
.operand_type
[0]->op_type
& Direct
)
1902 if (insn
.operand_type
[0]->direct
.resolved
== 1)
1904 /* Direct addressing uses lower 8 bits of direct address. */
1906 (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
1907 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1913 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1914 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1915 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
1916 /* Ensure that the assembler doesn't complain
1917 about fitting a 24-bit address into 8 bits. */
1918 fix
->fx_no_overflow
= 1;
1923 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1925 /* Immediate addressing uses upper 8 bits of address. */
1926 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1928 as_bad (_("LDP instruction needs a 24-bit operand"));
1932 ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
1933 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]->immediate
.imm_expr
,
1942 fix
->fx_no_overflow
= 1;
1946 else if (insn
.tm
->operand_types
[0] & (Imm24
))
1948 /* Unconditional Branch and Call instructions. */
1949 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1951 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1952 as_warn (_("first operand is too large for a 24-bit displacement"));
1954 (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
1955 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1959 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1960 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3,
1961 & insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
1964 else if (insn
.tm
->operand_types
[0] & NotReq
)
1965 /* Check for NOP instruction without arguments. */
1966 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1968 else if (insn
.tm
->operands
== 0)
1969 /* Check for instructions without operands. */
1970 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1972 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
1976 for (i
= 0; i
< insn
.operands
; i
++)
1978 free (insn
.operand_type
[i
]->immediate
.label
);
1979 free (insn
.operand_type
[i
]);
1982 debug ("Final opcode: %08X\n", insn
.opcode
);