1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright (C) 1998-2016 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 struct hash_control
*op_hash
;
103 /* Hash table for parallel opcode lookup. */
104 static struct hash_control
*parop_hash
;
105 /* Hash table for register lookup. */
106 static struct hash_control
*reg_hash
;
107 /* Hash table for indirect addressing lookup. */
108 static struct hash_control
*ind_hash
;
113 const char *hash_err
;
115 debug ("In md_begin()\n");
116 op_hash
= hash_new ();
119 const insn_template
*current_optab
= tic30_optab
;
121 for (; current_optab
< tic30_optab_end
; current_optab
++)
123 hash_err
= hash_insert (op_hash
, current_optab
->name
,
124 (char *) current_optab
);
126 as_fatal ("Internal Error: Can't Hash %s: %s",
127 current_optab
->name
, hash_err
);
131 parop_hash
= hash_new ();
134 const partemplate
*current_parop
= tic30_paroptab
;
136 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
138 hash_err
= hash_insert (parop_hash
, current_parop
->name
,
139 (char *) current_parop
);
141 as_fatal ("Internal Error: Can't Hash %s: %s",
142 current_parop
->name
, hash_err
);
146 reg_hash
= hash_new ();
149 const reg
*current_reg
= tic30_regtab
;
151 for (; current_reg
< tic30_regtab_end
; current_reg
++)
153 hash_err
= hash_insert (reg_hash
, current_reg
->name
,
154 (char *) current_reg
);
156 as_fatal ("Internal Error: Can't Hash %s: %s",
157 current_reg
->name
, hash_err
);
161 ind_hash
= hash_new ();
164 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
166 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
168 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
,
169 (char *) current_ind
);
171 as_fatal ("Internal Error: Can't Hash %s: %s",
172 current_ind
->syntax
, hash_err
);
176 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
181 for (c
= 0; c
< 256; c
++)
183 if (ISLOWER (c
) || ISDIGIT (c
))
186 register_chars
[c
] = c
;
188 else if (ISUPPER (c
))
190 opcode_chars
[c
] = TOLOWER (c
);
191 register_chars
[c
] = opcode_chars
[c
];
193 else if (c
== ')' || c
== '(')
194 register_chars
[c
] = c
;
196 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
197 operand_chars
[c
] = c
;
199 if (ISDIGIT (c
) || c
== '-')
202 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
203 identifier_chars
[c
] = c
;
205 if (c
== ' ' || c
== '\t')
211 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
212 operand_chars
[(unsigned char) *p
] = *p
;
216 /* Address Mode OR values. */
217 #define AM_Register 0x00000000
218 #define AM_Direct 0x00200000
219 #define AM_Indirect 0x00400000
220 #define AM_Immediate 0x00600000
221 #define AM_NotReq 0xFFFFFFFF
223 /* PC Relative OR values. */
224 #define PC_Register 0x00000000
225 #define PC_Relative 0x02000000
235 expressionS direct_expr
;
253 unsigned int u_number
;
255 expressionS imm_expr
;
259 insn_template
*opcode
;
263 insn_template
*tm
; /* Template of current instruction. */
264 unsigned opcode
; /* Final opcode. */
265 unsigned int operands
; /* Number of given operands. */
266 /* Type of operand given in instruction. */
267 operand
*operand_type
[MAX_OPERANDS
];
268 unsigned addressing_mode
; /* Final addressing mode of instruction. */
271 struct tic30_insn insn
;
272 static int found_parallel_insn
;
274 static char output_invalid_buf
[sizeof (unsigned char) * 2 + 6];
277 output_invalid (char c
)
280 snprintf (output_invalid_buf
, sizeof (output_invalid_buf
),
283 snprintf (output_invalid_buf
, sizeof (output_invalid_buf
),
284 "(0x%x)", (unsigned char) c
);
285 return output_invalid_buf
;
288 /* next_line points to the next line after the current instruction
289 (current_line). Search for the parallel bars, and if found, merge two
290 lines into internal syntax for a parallel instruction:
291 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
292 By this stage, all comments are scrubbed, and only the bare lines are
296 #define START_OPCODE 1
298 #define START_OPERANDS 3
299 #define END_OPERANDS 4
302 tic30_find_parallel_insn (char *current_line
, char *next_line
)
304 int found_parallel
= 0;
305 char first_opcode
[256];
306 char second_opcode
[256];
307 char first_operands
[256];
308 char second_operands
[256];
311 debug ("In tic30_find_parallel_insn()\n");
312 while (!is_end_of_line
[(unsigned char) *next_line
])
314 if (*next_line
== PARALLEL_SEPARATOR
315 && *(next_line
+ 1) == PARALLEL_SEPARATOR
)
325 debug ("Found a parallel instruction\n");
329 char *op
, *operands
, *line
;
331 for (i
= 0; i
< 2; i
++)
335 op
= &first_opcode
[0];
336 operands
= &first_operands
[0];
341 op
= &second_opcode
[0];
342 operands
= &second_operands
[0];
347 int search_status
= NONE
;
351 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
353 if (is_opcode_char (c
) && search_status
== NONE
)
355 op
[char_ptr
++] = TOLOWER (c
);
356 search_status
= START_OPCODE
;
358 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
359 op
[char_ptr
++] = TOLOWER (c
);
360 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
364 search_status
= END_OPCODE
;
366 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
367 operands
[char_ptr
++] = c
;
369 if (is_operand_char (c
) && search_status
== END_OPCODE
)
371 operands
[char_ptr
++] = c
;
372 search_status
= START_OPERANDS
;
377 if (search_status
!= START_OPERANDS
)
379 operands
[char_ptr
] = '\0';
383 parallel_insn
= malloc (strlen (first_opcode
) + strlen (first_operands
)
384 + strlen (second_opcode
) + strlen (second_operands
) + 8);
385 sprintf (parallel_insn
, "q_%s_%s %s | %s",
386 first_opcode
, second_opcode
,
387 first_operands
, second_operands
);
388 debug ("parallel insn = %s\n", parallel_insn
);
389 return parallel_insn
;
395 #undef START_OPERANDS
399 tic30_operand (char *token
)
404 debug ("In tic30_operand with %s\n", token
);
405 current_op
= XCNEW (operand
);
407 if (*token
== DIRECT_REFERENCE
)
409 char *token_posn
= token
+ 1;
410 int direct_label
= 0;
412 debug ("Found direct reference\n");
415 if (!is_digit_char (*token_posn
))
422 char *save_input_line_pointer
;
425 debug ("Direct reference is a label\n");
426 current_op
->direct
.label
= token
+ 1;
427 save_input_line_pointer
= input_line_pointer
;
428 input_line_pointer
= token
+ 1;
429 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
430 retval
= expression (¤t_op
->direct
.direct_expr
);
432 debug ("Expression type: %d\n",
433 current_op
->direct
.direct_expr
.X_op
);
434 debug ("Expression addnum: %ld\n",
435 (long) current_op
->direct
.direct_expr
.X_add_number
);
436 debug ("Segment: %p\n", retval
);
438 input_line_pointer
= save_input_line_pointer
;
440 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
442 current_op
->direct
.address
=
443 current_op
->direct
.direct_expr
.X_add_number
;
444 current_op
->direct
.resolved
= 1;
449 debug ("Direct reference is a number\n");
450 current_op
->direct
.address
= atoi (token
+ 1);
451 current_op
->direct
.resolved
= 1;
453 current_op
->op_type
= Direct
;
455 else if (*token
== INDIRECT_REFERENCE
)
457 /* Indirect reference operand. */
463 ind_addr_type
*ind_addr_op
;
466 ind_buffer
= XNEWVEC (char, strlen (token
));
468 debug ("Found indirect reference\n");
469 ind_buffer
[0] = *token
;
471 for (count
= 1; count
< strlen (token
); count
++)
474 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
476 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A')
477 && (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
479 /* AR reference is found, so get its number and remove
480 it from the buffer so it can pass through hash_find(). */
483 as_bad (_("More than one AR register found in indirect reference"));
487 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
489 as_bad (_("Illegal AR register in indirect reference"));
493 ar_number
= *(token
+ count
+ 1) - '0';
498 if (*(token
+ count
) == '(')
500 /* Parenthesis found, so check if a displacement value is
501 inside. If so, get the value and remove it from the
503 if (is_digit_char (*(token
+ count
+ 1)))
510 as_bad (_("More than one displacement found in indirect reference"));
515 while (*(token
+ count
) != ')')
517 if (!is_digit_char (*(token
+ count
)))
519 as_bad (_("Invalid displacement in indirect reference"));
523 disp
[disp_posn
++] = *(token
+ (count
++));
525 disp
[disp_posn
] = '\0';
526 disp_number
= atoi (disp
);
534 ind_buffer
[buffer_posn
] = '\0';
537 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"));
561 as_bad (_("illegal indirect reference"));
566 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
568 as_bad (_("displacement must be an unsigned 8-bit number"));
573 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
574 current_op
->indirect
.disp
= disp_number
;
575 current_op
->indirect
.ARnum
= ar_number
;
576 current_op
->op_type
= Indirect
;
581 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
585 debug ("Found register operand: %s\n", regop
->name
);
586 if (regop
->regtype
== REG_ARn
)
587 current_op
->op_type
= ARn
;
588 else if (regop
->regtype
== REG_Rn
)
589 current_op
->op_type
= Rn
;
590 else if (regop
->regtype
== REG_DP
)
591 current_op
->op_type
= DPReg
;
593 current_op
->op_type
= OtherReg
;
594 current_op
->reg
.opcode
= regop
->opcode
;
598 if (!is_digit_char (*token
)
599 || *(token
+ 1) == 'x'
600 || strchr (token
, 'h'))
602 char *save_input_line_pointer
;
605 debug ("Probably a label: %s\n", token
);
606 current_op
->immediate
.label
= xstrdup (token
);
607 save_input_line_pointer
= input_line_pointer
;
608 input_line_pointer
= token
;
610 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
611 retval
= expression (¤t_op
->immediate
.imm_expr
);
612 debug ("Expression type: %d\n",
613 current_op
->immediate
.imm_expr
.X_op
);
614 debug ("Expression addnum: %ld\n",
615 (long) current_op
->immediate
.imm_expr
.X_add_number
);
616 debug ("Segment: %p\n", retval
);
617 input_line_pointer
= save_input_line_pointer
;
619 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
621 current_op
->immediate
.s_number
622 = current_op
->immediate
.imm_expr
.X_add_number
;
623 current_op
->immediate
.u_number
624 = (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
625 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
= xstrdup (token
);
635 current_op
->immediate
.f_number
= (float) atof (token
);
636 current_op
->immediate
.s_number
= (int) atoi (token
);
637 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
638 current_op
->immediate
.resolved
= 1;
640 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
641 if (current_op
->immediate
.u_number
<= 31)
642 current_op
->op_type
|= IVector
;
648 struct tic30_par_insn
650 partemplate
*tm
; /* Template of current parallel instruction. */
651 unsigned operands
[2]; /* Number of given operands for each insn. */
652 /* Type of operand given in instruction. */
653 operand
*operand_type
[2][MAX_OPERANDS
];
654 int swap_operands
; /* Whether to swap operands around. */
655 unsigned p_field
; /* Value of p field in multiply add/sub instructions. */
656 unsigned opcode
; /* Final opcode. */
659 struct tic30_par_insn p_insn
;
662 tic30_parallel_insn (char *token
)
664 static partemplate
*p_opcode
;
665 char *current_posn
= token
;
669 debug ("In tic30_parallel_insn with %s\n", token
);
670 memset (&p_insn
, '\0', sizeof (p_insn
));
672 while (is_opcode_char (*current_posn
))
675 /* Find instruction. */
676 save_char
= *current_posn
;
677 *current_posn
= '\0';
678 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
681 debug ("Found instruction %s\n", p_opcode
->name
);
682 p_insn
.tm
= p_opcode
;
686 char first_opcode
[6] = {0};
687 char second_opcode
[6] = {0};
689 int current_opcode
= -1;
692 for (i
= 0; i
< strlen (token
); i
++)
694 char ch
= *(token
+ i
);
696 if (ch
== '_' && current_opcode
== -1)
702 if (ch
== '_' && current_opcode
== 0)
709 switch (current_opcode
)
712 first_opcode
[char_ptr
++] = ch
;
715 second_opcode
[char_ptr
++] = ch
;
720 debug ("first_opcode = %s\n", first_opcode
);
721 debug ("second_opcode = %s\n", second_opcode
);
722 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
723 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
727 debug ("Found instruction %s\n", p_opcode
->name
);
728 p_insn
.tm
= p_opcode
;
729 p_insn
.swap_operands
= 1;
734 *current_posn
= save_char
;
739 int paren_not_balanced
;
740 int expecting_operand
= 0;
741 int found_separator
= 0;
745 /* Skip optional white space before operand. */
746 while (!is_operand_char (*current_posn
)
747 && *current_posn
!= END_OF_INSN
)
749 if (!is_space_char (*current_posn
)
750 && *current_posn
!= PARALLEL_SEPARATOR
)
752 as_bad (_("Invalid character %s before %s operand"),
753 output_invalid (*current_posn
),
754 ordinal_names
[insn
.operands
]);
757 if (*current_posn
== PARALLEL_SEPARATOR
)
762 token_start
= current_posn
;
763 paren_not_balanced
= 0;
765 while (paren_not_balanced
|| *current_posn
!= ',')
767 if (*current_posn
== END_OF_INSN
)
769 if (paren_not_balanced
)
771 as_bad (_("Unbalanced parenthesis in %s operand."),
772 ordinal_names
[insn
.operands
]);
778 else if (*current_posn
== PARALLEL_SEPARATOR
)
780 while (is_space_char (*(current_posn
- 1)))
784 else if (!is_operand_char (*current_posn
)
785 && !is_space_char (*current_posn
))
787 as_bad (_("Invalid character %s in %s operand"),
788 output_invalid (*current_posn
),
789 ordinal_names
[insn
.operands
]);
793 if (*current_posn
== '(')
794 ++paren_not_balanced
;
795 if (*current_posn
== ')')
796 --paren_not_balanced
;
800 if (current_posn
!= token_start
)
802 /* Yes, we've read in another operand. */
803 p_insn
.operands
[found_separator
]++;
804 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
806 as_bad (_("Spurious operands; (%d operands/instruction max)"),
811 /* Now parse operand adding info to 'insn' as we go along. */
812 save_char
= *current_posn
;
813 *current_posn
= '\0';
814 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
815 tic30_operand (token_start
);
816 *current_posn
= save_char
;
817 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
822 if (expecting_operand
)
824 as_bad (_("Expecting operand after ','; got nothing"));
827 if (*current_posn
== ',')
829 as_bad (_("Expecting operand before ','; got nothing"));
834 /* Now *current_posn must be either ',' or END_OF_INSN. */
835 if (*current_posn
== ',')
837 if (*++current_posn
== END_OF_INSN
)
839 /* Just skip it, if it's \n complain. */
840 as_bad (_("Expecting operand after ','; got nothing"));
843 expecting_operand
= 1;
846 while (*current_posn
!= END_OF_INSN
);
849 if (p_insn
.swap_operands
)
854 temp_num
= p_insn
.operands
[0];
855 p_insn
.operands
[0] = p_insn
.operands
[1];
856 p_insn
.operands
[1] = temp_num
;
857 for (i
= 0; i
< MAX_OPERANDS
; i
++)
859 temp_op
= p_insn
.operand_type
[0][i
];
860 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
861 p_insn
.operand_type
[1][i
] = temp_op
;
865 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
867 as_bad (_("incorrect number of operands given in the first instruction"));
871 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
873 as_bad (_("incorrect number of operands given in the second instruction"));
877 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
878 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
881 /* Now check if operands are correct. */
886 for (count
= 0; count
< 2; count
++)
889 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
891 if ((p_insn
.operand_type
[count
][i
]->op_type
&
892 p_insn
.tm
->operand_types
[count
][i
]) == 0)
894 as_bad (_("%s instruction, operand %d doesn't match"),
895 ordinal_names
[count
], i
+ 1);
899 /* Get number of R register and indirect reference contained
900 within the first two operands of each instruction. This is
901 required for the multiply parallel instructions which require
902 two R registers and two indirect references, but not in any
904 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
906 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
)
912 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
))
915 /* Check for the multiply instructions. */
918 as_bad (_("incorrect format for multiply parallel instruction"));
924 /* Shouldn't get here. */
925 as_bad (_("incorrect format for multiply parallel instruction"));
929 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00)
930 && (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
932 as_bad (_("destination for multiply can only be R0 or R1"));
936 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02)
937 && (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
939 as_bad (_("destination for add/subtract can only be R2 or R3"));
943 /* Now determine the P field for the instruction. */
944 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
946 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
947 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn. */
948 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
949 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn. */
951 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind. */
955 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
956 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind. */
957 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
960 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn. */
961 /* Need to swap the two multiply operands around so that
962 everything is in its place for the opcode makeup.
963 ie so Ind * Rn, Ind +/- Rn. */
964 temp
= p_insn
.operand_type
[0][0];
965 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
966 p_insn
.operand_type
[0][1] = temp
;
971 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind. */
972 temp
= p_insn
.operand_type
[0][0];
973 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
974 p_insn
.operand_type
[0][1] = temp
;
980 debug ("P field: %08X\n", p_insn
.p_field
);
982 /* Finalise opcode. This is easier for parallel instructions as they have
983 to be fully resolved, there are no memory addresses allowed, except
984 through indirect addressing, so there are no labels to resolve. */
985 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
987 switch (p_insn
.tm
->oporder
)
990 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
991 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
992 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
993 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
994 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
995 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
999 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1000 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1001 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1002 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1003 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1004 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1005 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1006 as_warn (_("loading the same register in parallel operation"));
1010 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1011 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1012 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1013 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1014 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1015 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1019 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1020 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1021 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1022 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1023 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1024 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1025 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1029 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1030 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1031 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1032 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1033 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1034 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1035 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1039 p_insn
.opcode
|= p_insn
.p_field
;
1040 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1041 p_insn
.opcode
|= 0x00800000;
1042 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1043 p_insn
.opcode
|= 0x00400000;
1045 switch (p_insn
.p_field
)
1048 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1049 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1050 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1051 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1052 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1053 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1056 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1057 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1058 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1059 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1060 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1061 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1064 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1065 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1066 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1067 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1068 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1069 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1072 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1073 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1074 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1075 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1076 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1077 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1086 p
= frag_more (INSN_SIZE
);
1087 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1093 for (i
= 0; i
< 2; i
++)
1094 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1095 free (p_insn
.operand_type
[i
][j
]);
1098 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1104 /* In order to get gas to ignore any | chars at the start of a line,
1105 this function returns true if a | is found in a line. */
1108 tic30_unrecognized_line (int c
)
1110 debug ("In tc_unrecognized_line\n");
1111 return (c
== PARALLEL_SEPARATOR
);
1115 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
1116 segT segment ATTRIBUTE_UNUSED
)
1118 debug ("In md_estimate_size_before_relax()\n");
1123 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1124 segT sec ATTRIBUTE_UNUSED
,
1125 fragS
*fragP ATTRIBUTE_UNUSED
)
1127 debug ("In md_convert_frag()\n");
1131 md_apply_fix (fixS
*fixP
,
1133 segT seg ATTRIBUTE_UNUSED
)
1135 valueT value
= *valP
;
1137 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1138 debug ("Values in fixP\n");
1139 debug ("fx_size = %d\n", fixP
->fx_size
);
1140 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1141 debug ("fx_where = %ld\n", fixP
->fx_where
);
1142 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1144 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1147 if (fixP
->fx_size
== 1)
1148 /* Special fix for LDP instruction. */
1149 value
= (value
& 0x00FF0000) >> 16;
1151 debug ("new value = %ld\n", (long) value
);
1152 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1155 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1160 md_parse_option (int c ATTRIBUTE_UNUSED
,
1161 const char *arg ATTRIBUTE_UNUSED
)
1163 debug ("In md_parse_option()\n");
1168 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
1170 debug ("In md_show_usage()\n");
1174 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1176 debug ("In md_undefined_symbol()\n");
1177 return (symbolS
*) 0;
1181 md_section_align (segT segment
, valueT size
)
1183 debug ("In md_section_align() segment = %p and size = %lu\n",
1184 segment
, (unsigned long) size
);
1185 size
= (size
+ 3) / 4;
1187 debug ("New size value = %lu\n", (unsigned long) size
);
1192 md_pcrel_from (fixS
*fixP
)
1196 debug ("In md_pcrel_from()\n");
1197 debug ("fx_where = %ld\n", fixP
->fx_where
);
1198 debug ("fx_size = %d\n", fixP
->fx_size
);
1199 /* Find the opcode that represents the current instruction in the
1200 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1201 current instruction is a delayed one or not, and then set the offset
1202 value appropriately. */
1203 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1207 debug ("offset = %d\n", offset
);
1208 /* PC Relative instructions have a format:
1209 displacement = Label - (PC + offset)
1210 This function returns PC + offset where:
1211 fx_where - fx_size = PC
1212 INSN_SIZE * offset = offset number of instructions. */
1213 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1217 md_atof (int what_statement_type
,
1224 unsigned long value
;
1227 debug ("In md_atof()\n");
1228 debug ("precision = %c\n", what_statement_type
);
1229 debug ("literal = %s\n", literalP
);
1231 token
= input_line_pointer
;
1232 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1233 && (*input_line_pointer
!= ','))
1235 debug ("%c", *input_line_pointer
);
1236 input_line_pointer
++;
1239 keepval
= *input_line_pointer
;
1240 *input_line_pointer
= '\0';
1242 float_value
= (float) atof (token
);
1243 *input_line_pointer
= keepval
;
1244 debug ("float_value = %f\n", float_value
);
1246 switch (what_statement_type
)
1264 return _("Unrecognized or unsupported floating point constant");
1267 if (float_value
== 0.0)
1268 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1271 unsigned long exp
, sign
, mant
, tmsfloat
;
1279 converter
.f
= float_value
;
1280 tmsfloat
= converter
.l
;
1281 sign
= tmsfloat
& 0x80000000;
1282 mant
= tmsfloat
& 0x007FFFFF;
1283 exp
= tmsfloat
& 0x7F800000;
1285 if (exp
== 0xFF000000)
1299 mant
= mant
& 0x007FFFFF;
1301 mant
= mant
& 0x00FFFFFF;
1305 exp
= (long) exp
- 0x01000000;
1308 tmsfloat
= exp
| mant
;
1315 if (tmsfloat
== 0x80000000)
1320 expon
= (tmsfloat
& 0xFF000000);
1322 mantis
= tmsfloat
& 0x007FFFFF;
1323 if (tmsfloat
& 0x00800000)
1325 mantis
|= 0xFF000000;
1326 mantis
+= 0x00000800;
1328 mantis
|= 0x00000800;
1335 mantis
|= 0x00800000;
1336 mantis
+= 0x00000800;
1337 expon
+= (mantis
>> 24);
1347 mantis
= (expon
<< 12) | mantis
;
1348 value
= mantis
& 0xFFFF;
1353 md_number_to_chars (literalP
, value
, prec
);
1359 md_number_to_chars (char *buf
, valueT val
, int n
)
1361 debug ("In md_number_to_chars()\n");
1362 number_to_chars_bigendian (buf
, val
, n
);
1365 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1366 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1369 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
1372 bfd_reloc_code_real_type code
= 0;
1374 debug ("In tc_gen_reloc()\n");
1375 debug ("fixP.size = %d\n", fixP
->fx_size
);
1376 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1377 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1379 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1381 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1382 MAP (2, 0, BFD_RELOC_16
);
1383 MAP (3, 0, BFD_RELOC_24
);
1384 MAP (2, 1, BFD_RELOC_16_PCREL
);
1385 MAP (4, 0, BFD_RELOC_32
);
1387 as_bad (_("Can not do %d byte %srelocation"), fixP
->fx_size
,
1388 fixP
->fx_pcrel
? _("pc-relative ") : "");
1393 rel
= XNEW (arelent
);
1394 gas_assert (rel
!= 0);
1395 rel
->sym_ptr_ptr
= XNEW (asymbol
*);
1396 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1397 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1399 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1404 name
= S_GET_NAME (fixP
->fx_addsy
);
1407 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1408 name
, bfd_get_reloc_code_name (code
));
1414 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1416 debug ("In md_operand()\n");
1420 md_assemble (char *line
)
1428 debug ("In md_assemble() with argument %s\n", line
);
1429 memset (&insn
, '\0', sizeof (insn
));
1430 if (found_parallel_insn
)
1432 debug ("Line is second part of parallel instruction\n\n");
1433 found_parallel_insn
= 0;
1437 tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
1438 current_posn
= line
;
1440 found_parallel_insn
= 1;
1442 while (is_space_char (*current_posn
))
1445 token_start
= current_posn
;
1447 if (!is_opcode_char (*current_posn
))
1449 as_bad (_("Invalid character %s in opcode"),
1450 output_invalid (*current_posn
));
1453 /* Check if instruction is a parallel instruction
1454 by seeing if the first character is a q. */
1455 if (*token_start
== 'q')
1457 if (tic30_parallel_insn (token_start
))
1459 if (found_parallel_insn
)
1464 while (is_opcode_char (*current_posn
))
1467 /* Find instruction. */
1468 save_char
= *current_posn
;
1469 *current_posn
= '\0';
1470 op
= (insn_template
*) hash_find (op_hash
, token_start
);
1473 debug ("Found instruction %s\n", op
->name
);
1478 debug ("Didn't find insn\n");
1479 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start
);
1482 *current_posn
= save_char
;
1485 if (*current_posn
!= END_OF_INSN
)
1487 /* Find operands. */
1488 int paren_not_balanced
;
1489 int expecting_operand
= 0;
1493 /* Skip optional white space before operand. */
1494 while (!is_operand_char (*current_posn
)
1495 && *current_posn
!= END_OF_INSN
)
1497 if (!is_space_char (*current_posn
))
1499 as_bad (_("Invalid character %s before %s operand"),
1500 output_invalid (*current_posn
),
1501 ordinal_names
[insn
.operands
]);
1506 token_start
= current_posn
;
1507 paren_not_balanced
= 0;
1508 while (paren_not_balanced
|| *current_posn
!= ',')
1510 if (*current_posn
== END_OF_INSN
)
1512 if (paren_not_balanced
)
1514 as_bad (_("Unbalanced parenthesis in %s operand."),
1515 ordinal_names
[insn
.operands
]);
1521 else if (!is_operand_char (*current_posn
)
1522 && !is_space_char (*current_posn
))
1524 as_bad (_("Invalid character %s in %s operand"),
1525 output_invalid (*current_posn
),
1526 ordinal_names
[insn
.operands
]);
1529 if (*current_posn
== '(')
1530 ++paren_not_balanced
;
1531 if (*current_posn
== ')')
1532 --paren_not_balanced
;
1535 if (current_posn
!= token_start
)
1537 /* Yes, we've read in another operand. */
1538 this_operand
= insn
.operands
++;
1539 if (insn
.operands
> MAX_OPERANDS
)
1541 as_bad (_("Spurious operands; (%d operands/instruction max)"),
1546 /* Now parse operand adding info to 'insn' as we go along. */
1547 save_char
= *current_posn
;
1548 *current_posn
= '\0';
1549 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
1550 *current_posn
= save_char
;
1551 if (insn
.operand_type
[this_operand
] == NULL
)
1556 if (expecting_operand
)
1558 as_bad (_("Expecting operand after ','; got nothing"));
1561 if (*current_posn
== ',')
1563 as_bad (_("Expecting operand before ','; got nothing"));
1568 /* Now *current_posn must be either ',' or END_OF_INSN. */
1569 if (*current_posn
== ',')
1571 if (*++current_posn
== END_OF_INSN
)
1573 /* Just skip it, if it's \n complain. */
1574 as_bad (_("Expecting operand after ','; got nothing"));
1577 expecting_operand
= 1;
1580 while (*current_posn
!= END_OF_INSN
);
1583 debug ("Number of operands found: %d\n", insn
.operands
);
1585 /* Check that number of operands is correct. */
1586 if (insn
.operands
!= insn
.tm
->operands
)
1589 unsigned int numops
= insn
.tm
->operands
;
1591 /* If operands are not the same, then see if any of the operands are
1592 not required. Then recheck with number of given operands. If they
1593 are still not the same, then give an error, otherwise carry on. */
1594 for (i
= 0; i
< insn
.tm
->operands
; i
++)
1595 if (insn
.tm
->operand_types
[i
] & NotReq
)
1597 if (insn
.operands
!= numops
)
1599 as_bad (_("Incorrect number of operands given"));
1603 insn
.addressing_mode
= AM_NotReq
;
1604 for (count
= 0; count
< insn
.operands
; count
++)
1606 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
1608 debug ("Operand %d matches\n", count
+ 1);
1609 /* If instruction has two operands and has an AddressMode
1610 modifier then set addressing mode type for instruction. */
1611 if (insn
.tm
->opcode_modifier
== AddressMode
)
1614 /* Store instruction uses the second
1615 operand for the address mode. */
1616 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
))
1617 == (Indirect
| Direct
))
1620 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
1621 insn
.addressing_mode
= AM_Register
;
1622 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
1623 insn
.addressing_mode
= AM_Direct
;
1624 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
1625 insn
.addressing_mode
= AM_Indirect
;
1627 insn
.addressing_mode
= AM_Immediate
;
1632 as_bad (_("The %s operand doesn't match"), ordinal_names
[count
]);
1637 /* Now set the addressing mode for 3 operand instructions. */
1638 if ((insn
.tm
->operand_types
[0] & op3T1
)
1639 && (insn
.tm
->operand_types
[1] & op3T2
))
1641 /* Set the addressing mode to the values used for 2 operand
1642 instructions in the G addressing field of the opcode. */
1644 switch (insn
.operand_type
[0]->op_type
)
1650 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1651 insn
.addressing_mode
= AM_Register
;
1652 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1653 insn
.addressing_mode
= AM_Direct
;
1656 /* Shouldn't make it to this stage. */
1657 as_bad (_("Incompatible first and second operands in instruction"));
1662 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1663 insn
.addressing_mode
= AM_Indirect
;
1664 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1665 insn
.addressing_mode
= AM_Immediate
;
1668 /* Shouldn't make it to this stage. */
1669 as_bad (_("Incompatible first and second operands in instruction"));
1674 /* Now make up the opcode for the 3 operand instructions. As in
1675 parallel instructions, there will be no unresolved values, so they
1676 can be fully formed and added to the frag table. */
1677 insn
.opcode
= insn
.tm
->base_opcode
;
1678 if (insn
.operand_type
[0]->op_type
& Indirect
)
1680 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
1681 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
1684 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1686 if (insn
.operand_type
[1]->op_type
& Indirect
)
1688 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
1689 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
1692 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
1694 if (insn
.operands
== 3)
1695 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
1697 insn
.opcode
|= insn
.addressing_mode
;
1698 p
= frag_more (INSN_SIZE
);
1699 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1703 /* Not a three operand instruction. */
1706 insn
.opcode
= insn
.tm
->base_opcode
;
1707 /* Create frag for instruction - all instructions are 4 bytes long. */
1708 p
= frag_more (INSN_SIZE
);
1709 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
1711 insn
.opcode
|= insn
.addressing_mode
;
1712 if (insn
.addressing_mode
== AM_Indirect
)
1714 /* Determine which operand gives the addressing mode. */
1715 if (insn
.operand_type
[0]->op_type
& Indirect
)
1717 if ((insn
.operands
> 1)
1718 && (insn
.operand_type
[1]->op_type
& Indirect
))
1720 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
1721 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
1722 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
1723 if (insn
.operands
> 1)
1724 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
1725 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1727 else if (insn
.addressing_mode
== AM_Register
)
1729 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1730 if (insn
.operands
> 1)
1731 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1732 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1734 else if (insn
.addressing_mode
== AM_Direct
)
1736 if (insn
.operand_type
[0]->op_type
& Direct
)
1738 if ((insn
.operands
> 1)
1739 && (insn
.operand_type
[1]->op_type
& Direct
))
1741 if (insn
.operands
> 1)
1743 (insn
.operand_type
[! am_insn
]->reg
.opcode
<< 16);
1744 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
1746 /* Resolved values can be placed straight
1747 into instruction word, and output. */
1749 (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
1750 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1754 /* Unresolved direct addressing mode instruction. */
1755 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1756 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1757 & insn
.operand_type
[am_insn
]->direct
.direct_expr
,
1761 else if (insn
.addressing_mode
== AM_Immediate
)
1763 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1768 if (insn
.operands
> 1)
1769 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1771 switch (insn
.tm
->imm_arg_type
)
1774 debug ("Floating point first operand\n");
1775 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1777 keeploc
= input_line_pointer
;
1778 input_line_pointer
=
1779 insn
.operand_type
[0]->immediate
.label
;
1781 if (md_atof ('f', p
+ 2, & size
) != 0)
1783 as_bad (_("invalid short form floating point immediate operand"));
1787 input_line_pointer
= keeploc
;
1791 debug ("Unsigned int first operand\n");
1792 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1793 as_warn (_("rounding down first operand float to unsigned int"));
1794 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
1795 as_warn (_("only lower 16-bits of first operand are used"));
1797 (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
1798 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1802 debug ("Int first operand\n");
1804 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1805 as_warn (_("rounding down first operand float to signed int"));
1807 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1808 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1810 as_bad (_("first operand is too large for 16-bit signed int"));
1814 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
1815 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1821 /* Unresolved immediate label. */
1822 if (insn
.operands
> 1)
1823 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1824 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1825 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1826 & insn
.operand_type
[0]->immediate
.imm_expr
,
1831 else if (insn
.tm
->opcode_modifier
== PCRel
)
1833 /* Conditional Branch and Call instructions. */
1834 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
))
1837 if (insn
.operand_type
[0]->op_type
& (AllReg
))
1839 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1840 insn
.opcode
|= PC_Register
;
1841 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1845 insn
.opcode
|= PC_Relative
;
1846 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1849 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
1850 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1854 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1855 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
),
1856 2, & insn
.operand_type
[0]->immediate
.imm_expr
,
1861 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
1863 /* Decrement and Branch instructions. */
1864 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
1865 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1867 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
1868 insn
.opcode
|= PC_Register
;
1869 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1871 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
1873 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1875 as_bad (_("first operand is floating point"));
1878 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1879 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1881 as_bad (_("first operand is too large for 16-bit signed int"));
1884 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
1885 insn
.opcode
|= PC_Relative
;
1886 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1890 insn
.opcode
|= PC_Relative
;
1891 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1892 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2,
1893 & insn
.operand_type
[1]->immediate
.imm_expr
,
1898 else if (insn
.tm
->operand_types
[0] == IVector
)
1900 /* Trap instructions. */
1901 if (insn
.operand_type
[0]->op_type
& IVector
)
1902 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
1905 /* Shouldn't get here. */
1906 as_bad (_("interrupt vector for trap instruction out of range"));
1909 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1911 else if (insn
.tm
->opcode_modifier
== StackOp
1912 || insn
.tm
->opcode_modifier
== Rotate
)
1914 /* Push, Pop and Rotate instructions. */
1915 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
1916 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1918 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
))
1919 == (Abs24
| Direct
))
1921 /* LDP Instruction needs to be tested
1922 for before the next section. */
1923 if (insn
.operand_type
[0]->op_type
& Direct
)
1925 if (insn
.operand_type
[0]->direct
.resolved
== 1)
1927 /* Direct addressing uses lower 8 bits of direct address. */
1929 (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
1930 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1936 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1937 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1938 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
1939 /* Ensure that the assembler doesn't complain
1940 about fitting a 24-bit address into 8 bits. */
1941 fix
->fx_no_overflow
= 1;
1946 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1948 /* Immediate addressing uses upper 8 bits of address. */
1949 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1951 as_bad (_("LDP instruction needs a 24-bit operand"));
1955 ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
1956 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1961 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1962 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1963 1, &insn
.operand_type
[0]->immediate
.imm_expr
,
1965 fix
->fx_no_overflow
= 1;
1969 else if (insn
.tm
->operand_types
[0] & (Imm24
))
1971 /* Unconditional Branch and Call instructions. */
1972 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1974 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1975 as_warn (_("first operand is too large for a 24-bit displacement"));
1977 (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
1978 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1982 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1983 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3,
1984 & insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
1987 else if (insn
.tm
->operand_types
[0] & NotReq
)
1988 /* Check for NOP instruction without arguments. */
1989 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1991 else if (insn
.tm
->operands
== 0)
1992 /* Check for instructions without operands. */
1993 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1995 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
1999 for (i
= 0; i
< insn
.operands
; i
++)
2001 if (insn
.operand_type
[i
]->immediate
.label
)
2002 free (insn
.operand_type
[i
]->immediate
.label
);
2003 free (insn
.operand_type
[i
]);
2006 debug ("Final opcode: %08X\n", insn
.opcode
);