1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 /* Texas Instruments TMS320C30 machine specific gas.
24 Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25 Bugs & suggestions are completely welcome. This is free software.
26 Please help us make it better. */
29 #include "safe-ctype.h"
30 #include "opcode/tic30.h"
33 /* Put here all non-digit non-letter characters that may occur in an
35 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
36 static char *ordinal_names
[] =
38 "first", "second", "third", "fourth", "fifth"
41 const char comment_chars
[] = ";";
42 const char line_comment_chars
[] = "*";
43 const char line_separator_chars
[] = "";
45 const char *md_shortopts
= "";
46 struct option md_longopts
[] =
48 {NULL
, no_argument
, NULL
, 0}
51 size_t md_longopts_size
= sizeof (md_longopts
);
53 /* Chars that mean this number is a floating point constant.
56 const char FLT_CHARS
[] = "fFdDxX";
58 /* Chars that can be used to separate mant from exp in floating point
60 const char EXP_CHARS
[] = "eE";
62 /* Tables for lexical analysis. */
63 static char opcode_chars
[256];
64 static char register_chars
[256];
65 static char operand_chars
[256];
66 static char space_chars
[256];
67 static char identifier_chars
[256];
68 static char digit_chars
[256];
71 #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
72 #define is_operand_char(x) (operand_chars [(unsigned char) x])
73 #define is_register_char(x) (register_chars [(unsigned char) x])
74 #define is_space_char(x) (space_chars [(unsigned char) x])
75 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
76 #define is_digit_char(x) (digit_chars [(unsigned char) x])
78 const pseudo_typeS md_pseudo_table
[] =
83 static int ATTRIBUTE_PRINTF_1
84 debug (const char *string
, ...)
90 VA_OPEN (argptr
, string
);
91 VA_FIXEDARG (argptr
, const char *, string
);
92 vsprintf (str
, string
, argptr
);
96 fputs (str
, USE_STDOUT
? stdout
: stderr
);
103 /* Hash table for opcode lookup. */
104 static struct hash_control
*op_hash
;
105 /* Hash table for parallel opcode lookup. */
106 static struct hash_control
*parop_hash
;
107 /* Hash table for register lookup. */
108 static struct hash_control
*reg_hash
;
109 /* Hash table for indirect addressing lookup. */
110 static struct hash_control
*ind_hash
;
115 const char *hash_err
;
117 debug ("In md_begin()\n");
118 op_hash
= hash_new ();
121 const template *current_optab
= tic30_optab
;
123 for (; current_optab
< tic30_optab_end
; current_optab
++)
125 hash_err
= hash_insert (op_hash
, current_optab
->name
,
126 (char *) current_optab
);
128 as_fatal ("Internal Error: Can't Hash %s: %s",
129 current_optab
->name
, hash_err
);
133 parop_hash
= hash_new ();
136 const partemplate
*current_parop
= tic30_paroptab
;
138 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
140 hash_err
= hash_insert (parop_hash
, current_parop
->name
,
141 (char *) current_parop
);
143 as_fatal ("Internal Error: Can't Hash %s: %s",
144 current_parop
->name
, hash_err
);
148 reg_hash
= hash_new ();
151 const reg
*current_reg
= tic30_regtab
;
153 for (; current_reg
< tic30_regtab_end
; current_reg
++)
155 hash_err
= hash_insert (reg_hash
, current_reg
->name
,
156 (char *) current_reg
);
158 as_fatal ("Internal Error: Can't Hash %s: %s",
159 current_reg
->name
, hash_err
);
163 ind_hash
= hash_new ();
166 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
168 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
170 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
,
171 (char *) current_ind
);
173 as_fatal ("Internal Error: Can't Hash %s: %s",
174 current_ind
->syntax
, hash_err
);
178 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
183 for (c
= 0; c
< 256; c
++)
185 if (ISLOWER (c
) || ISDIGIT (c
))
188 register_chars
[c
] = c
;
190 else if (ISUPPER (c
))
192 opcode_chars
[c
] = TOLOWER (c
);
193 register_chars
[c
] = opcode_chars
[c
];
195 else if (c
== ')' || c
== '(')
196 register_chars
[c
] = c
;
198 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
199 operand_chars
[c
] = c
;
201 if (ISDIGIT (c
) || c
== '-')
204 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
205 identifier_chars
[c
] = c
;
207 if (c
== ' ' || c
== '\t')
213 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
214 operand_chars
[(unsigned char) *p
] = *p
;
218 /* Address Mode OR values. */
219 #define AM_Register 0x00000000
220 #define AM_Direct 0x00200000
221 #define AM_Indirect 0x00400000
222 #define AM_Immediate 0x00600000
223 #define AM_NotReq 0xFFFFFFFF
225 /* PC Relative OR values. */
226 #define PC_Register 0x00000000
227 #define PC_Relative 0x02000000
237 expressionS direct_expr
;
255 unsigned int u_number
;
257 expressionS imm_expr
;
265 template *tm
; /* Template of current instruction. */
266 unsigned opcode
; /* Final opcode. */
267 unsigned int operands
; /* Number of given operands. */
268 /* Type of operand given in instruction. */
269 operand
*operand_type
[MAX_OPERANDS
];
270 unsigned addressing_mode
; /* Final addressing mode of instruction. */
273 struct tic30_insn insn
;
274 static int found_parallel_insn
;
276 static char output_invalid_buf
[8];
279 output_invalid (char c
)
282 sprintf (output_invalid_buf
, "'%c'", c
);
284 sprintf (output_invalid_buf
, "(0x%x)", (unsigned) 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 *opcode
, *operands
, *line
;
331 for (i
= 0; i
< 2; i
++)
335 opcode
= &first_opcode
[0];
336 operands
= &first_operands
[0];
341 opcode
= &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 opcode
[char_ptr
++] = TOLOWER (c
);
356 search_status
= START_OPCODE
;
358 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
359 opcode
[char_ptr
++] = TOLOWER (c
);
360 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
362 opcode
[char_ptr
] = '\0';
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
)
402 char ind_buffer
[strlen (token
)];
405 debug ("In tic30_operand with %s\n", token
);
406 current_op
= malloc (sizeof (* current_op
));
407 memset (current_op
, '\0', sizeof (operand
));
409 if (*token
== DIRECT_REFERENCE
)
411 char *token_posn
= token
+ 1;
412 int direct_label
= 0;
414 debug ("Found direct reference\n");
417 if (!is_digit_char (*token_posn
))
424 char *save_input_line_pointer
;
427 debug ("Direct reference is a label\n");
428 current_op
->direct
.label
= token
+ 1;
429 save_input_line_pointer
= input_line_pointer
;
430 input_line_pointer
= token
+ 1;
431 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
432 retval
= expression (¤t_op
->direct
.direct_expr
);
434 debug ("Expression type: %d\n",
435 current_op
->direct
.direct_expr
.X_op
);
436 debug ("Expression addnum: %ld\n",
437 (long) current_op
->direct
.direct_expr
.X_add_number
);
438 debug ("Segment: %p\n", retval
);
440 input_line_pointer
= save_input_line_pointer
;
442 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
444 current_op
->direct
.address
=
445 current_op
->direct
.direct_expr
.X_add_number
;
446 current_op
->direct
.resolved
= 1;
451 debug ("Direct reference is a number\n");
452 current_op
->direct
.address
= atoi (token
+ 1);
453 current_op
->direct
.resolved
= 1;
455 current_op
->op_type
= Direct
;
457 else if (*token
== INDIRECT_REFERENCE
)
459 /* Indirect reference operand. */
465 ind_addr_type
*ind_addr_op
;
467 debug ("Found indirect reference\n");
468 ind_buffer
[0] = *token
;
470 for (count
= 1; count
< strlen (token
); count
++)
473 ind_buffer
[buffer_posn
] = TOLOWER (*(token
+ count
));
475 if ((*(token
+ count
- 1) == 'a' || *(token
+ count
- 1) == 'A')
476 && (*(token
+ count
) == 'r' || *(token
+ count
) == 'R'))
478 /* AR reference is found, so get its number and remove
479 it from the buffer so it can pass through hash_find(). */
482 as_bad ("More than one AR register found in indirect reference");
485 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
487 as_bad ("Illegal AR register in indirect reference");
490 ar_number
= *(token
+ count
+ 1) - '0';
495 if (*(token
+ count
) == '(')
497 /* Parenthesis found, so check if a displacement value is
498 inside. If so, get the value and remove it from the
500 if (is_digit_char (*(token
+ count
+ 1)))
507 as_bad ("More than one displacement found in indirect reference");
511 while (*(token
+ count
) != ')')
513 if (!is_digit_char (*(token
+ count
)))
515 as_bad ("Invalid displacement in indirect reference");
518 disp
[disp_posn
++] = *(token
+ (count
++));
520 disp
[disp_posn
] = '\0';
521 disp_number
= atoi (disp
);
529 ind_buffer
[buffer_posn
] = '\0';
532 as_bad ("AR register not found in indirect reference");
536 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
539 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
540 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
545 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
547 /* Maybe an implied displacement of 1 again. */
548 as_bad ("required displacement wasn't given in indirect reference");
554 as_bad ("illegal indirect reference");
558 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
560 as_bad ("displacement must be an unsigned 8-bit number");
564 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
565 current_op
->indirect
.disp
= disp_number
;
566 current_op
->indirect
.ARnum
= ar_number
;
567 current_op
->op_type
= Indirect
;
571 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
575 debug ("Found register operand: %s\n", regop
->name
);
576 if (regop
->regtype
== REG_ARn
)
577 current_op
->op_type
= ARn
;
578 else if (regop
->regtype
== REG_Rn
)
579 current_op
->op_type
= Rn
;
580 else if (regop
->regtype
== REG_DP
)
581 current_op
->op_type
= DPReg
;
583 current_op
->op_type
= OtherReg
;
584 current_op
->reg
.opcode
= regop
->opcode
;
588 if (!is_digit_char (*token
)
589 || *(token
+ 1) == 'x'
590 || strchr (token
, 'h'))
592 char *save_input_line_pointer
;
595 debug ("Probably a label: %s\n", token
);
596 current_op
->immediate
.label
= malloc (strlen (token
) + 1);
597 strcpy (current_op
->immediate
.label
, token
);
598 current_op
->immediate
.label
[strlen (token
)] = '\0';
599 save_input_line_pointer
= input_line_pointer
;
600 input_line_pointer
= token
;
602 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
603 retval
= expression (¤t_op
->immediate
.imm_expr
);
604 debug ("Expression type: %d\n",
605 current_op
->immediate
.imm_expr
.X_op
);
606 debug ("Expression addnum: %ld\n",
607 (long) current_op
->immediate
.imm_expr
.X_add_number
);
608 debug ("Segment: %p\n", retval
);
609 input_line_pointer
= save_input_line_pointer
;
611 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
613 current_op
->immediate
.s_number
614 = current_op
->immediate
.imm_expr
.X_add_number
;
615 current_op
->immediate
.u_number
616 = (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
617 current_op
->immediate
.resolved
= 1;
624 debug ("Found a number or displacement\n");
625 for (count
= 0; count
< strlen (token
); count
++)
626 if (*(token
+ count
) == '.')
627 current_op
->immediate
.decimal_found
= 1;
628 current_op
->immediate
.label
= malloc (strlen (token
) + 1);
629 strcpy (current_op
->immediate
.label
, token
);
630 current_op
->immediate
.label
[strlen (token
)] = '\0';
631 current_op
->immediate
.f_number
= (float) atof (token
);
632 current_op
->immediate
.s_number
= (int) atoi (token
);
633 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
634 current_op
->immediate
.resolved
= 1;
636 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
637 if (current_op
->immediate
.u_number
<= 31)
638 current_op
->op_type
|= IVector
;
644 struct tic30_par_insn
646 partemplate
*tm
; /* Template of current parallel instruction. */
647 unsigned operands
[2]; /* Number of given operands for each insn. */
648 /* Type of operand given in instruction. */
649 operand
*operand_type
[2][MAX_OPERANDS
];
650 int swap_operands
; /* Whether to swap operands around. */
651 unsigned p_field
; /* Value of p field in multiply add/sub instructions. */
652 unsigned opcode
; /* Final opcode. */
655 struct tic30_par_insn p_insn
;
658 tic30_parallel_insn (char *token
)
660 static partemplate
*p_opcode
;
661 char *current_posn
= token
;
665 debug ("In tic30_parallel_insn with %s\n", token
);
666 memset (&p_insn
, '\0', sizeof (p_insn
));
668 while (is_opcode_char (*current_posn
))
671 /* Find instruction. */
672 save_char
= *current_posn
;
673 *current_posn
= '\0';
674 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
677 debug ("Found instruction %s\n", p_opcode
->name
);
678 p_insn
.tm
= p_opcode
;
682 char first_opcode
[6] = {0};
683 char second_opcode
[6] = {0};
685 int current_opcode
= -1;
688 for (i
= 0; i
< strlen (token
); i
++)
690 char ch
= *(token
+ i
);
692 if (ch
== '_' && current_opcode
== -1)
698 if (ch
== '_' && current_opcode
== 0)
705 switch (current_opcode
)
708 first_opcode
[char_ptr
++] = ch
;
711 second_opcode
[char_ptr
++] = ch
;
716 debug ("first_opcode = %s\n", first_opcode
);
717 debug ("second_opcode = %s\n", second_opcode
);
718 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
719 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
723 debug ("Found instruction %s\n", p_opcode
->name
);
724 p_insn
.tm
= p_opcode
;
725 p_insn
.swap_operands
= 1;
730 *current_posn
= save_char
;
735 int paren_not_balanced
;
736 int expecting_operand
= 0;
737 int found_separator
= 0;
741 /* Skip optional white space before operand. */
742 while (!is_operand_char (*current_posn
)
743 && *current_posn
!= END_OF_INSN
)
745 if (!is_space_char (*current_posn
)
746 && *current_posn
!= PARALLEL_SEPARATOR
)
748 as_bad ("Invalid character %s before %s operand",
749 output_invalid (*current_posn
),
750 ordinal_names
[insn
.operands
]);
753 if (*current_posn
== PARALLEL_SEPARATOR
)
758 token_start
= current_posn
;
759 paren_not_balanced
= 0;
761 while (paren_not_balanced
|| *current_posn
!= ',')
763 if (*current_posn
== END_OF_INSN
)
765 if (paren_not_balanced
)
767 as_bad ("Unbalanced parenthesis in %s operand.",
768 ordinal_names
[insn
.operands
]);
774 else if (*current_posn
== PARALLEL_SEPARATOR
)
776 while (is_space_char (*(current_posn
- 1)))
780 else if (!is_operand_char (*current_posn
)
781 && !is_space_char (*current_posn
))
783 as_bad ("Invalid character %s in %s operand",
784 output_invalid (*current_posn
),
785 ordinal_names
[insn
.operands
]);
789 if (*current_posn
== '(')
790 ++paren_not_balanced
;
791 if (*current_posn
== ')')
792 --paren_not_balanced
;
796 if (current_posn
!= token_start
)
798 /* Yes, we've read in another operand. */
799 p_insn
.operands
[found_separator
]++;
800 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
802 as_bad ("Spurious operands; (%d operands/instruction max)",
807 /* Now parse operand adding info to 'insn' as we go along. */
808 save_char
= *current_posn
;
809 *current_posn
= '\0';
810 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
811 tic30_operand (token_start
);
812 *current_posn
= save_char
;
813 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
818 if (expecting_operand
)
820 as_bad ("Expecting operand after ','; got nothing");
823 if (*current_posn
== ',')
825 as_bad ("Expecting operand before ','; got nothing");
830 /* Now *current_posn must be either ',' or END_OF_INSN. */
831 if (*current_posn
== ',')
833 if (*++current_posn
== END_OF_INSN
)
835 /* Just skip it, if it's \n complain. */
836 as_bad ("Expecting operand after ','; got nothing");
839 expecting_operand
= 1;
842 while (*current_posn
!= END_OF_INSN
);
845 if (p_insn
.swap_operands
)
850 temp_num
= p_insn
.operands
[0];
851 p_insn
.operands
[0] = p_insn
.operands
[1];
852 p_insn
.operands
[1] = temp_num
;
853 for (i
= 0; i
< MAX_OPERANDS
; i
++)
855 temp_op
= p_insn
.operand_type
[0][i
];
856 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
857 p_insn
.operand_type
[1][i
] = temp_op
;
861 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
863 as_bad ("incorrect number of operands given in the first instruction");
867 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
869 as_bad ("incorrect number of operands given in the second instruction");
873 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
874 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
877 /* Now check if operands are correct. */
882 for (count
= 0; count
< 2; count
++)
885 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
887 if ((p_insn
.operand_type
[count
][i
]->op_type
&
888 p_insn
.tm
->operand_types
[count
][i
]) == 0)
890 as_bad ("%s instruction, operand %d doesn't match",
891 ordinal_names
[count
], i
+ 1);
895 /* Get number of R register and indirect reference contained
896 within the first two operands of each instruction. This is
897 required for the multiply parallel instructions which require
898 two R registers and two indirect references, but not in any
900 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
902 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
)
908 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
))
911 /* Check for the multiply instructions. */
914 as_bad ("incorrect format for multiply parallel instruction");
920 /* Shouldn't get here. */
921 as_bad ("incorrect format for multiply parallel instruction");
925 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00)
926 && (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
928 as_bad ("destination for multiply can only be R0 or R1");
932 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02)
933 && (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
935 as_bad ("destination for add/subtract can only be R2 or R3");
939 /* Now determine the P field for the instruction. */
940 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
942 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
943 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn. */
944 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
945 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn. */
947 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind. */
951 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
952 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind. */
953 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
956 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn. */
957 /* Need to swap the two multiply operands around so that
958 everything is in its place for the opcode makeup.
959 ie so Ind * Rn, Ind +/- Rn. */
960 temp
= p_insn
.operand_type
[0][0];
961 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
962 p_insn
.operand_type
[0][1] = temp
;
967 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind. */
968 temp
= p_insn
.operand_type
[0][0];
969 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
970 p_insn
.operand_type
[0][1] = temp
;
976 debug ("P field: %08X\n", p_insn
.p_field
);
978 /* Finalise opcode. This is easier for parallel instructions as they have
979 to be fully resolved, there are no memory addresses allowed, except
980 through indirect addressing, so there are no labels to resolve. */
981 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
983 switch (p_insn
.tm
->oporder
)
986 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
987 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
988 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
989 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
990 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
991 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
995 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
996 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
997 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
998 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
999 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1000 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1001 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1002 as_warn ("loading the same register in parallel operation");
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
<< 22);
1015 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1016 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1017 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1018 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1019 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1020 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1021 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
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
[1][1]->indirect
.ARnum
<< 8);
1028 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1029 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1030 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1031 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1035 p_insn
.opcode
|= p_insn
.p_field
;
1036 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1037 p_insn
.opcode
|= 0x00800000;
1038 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1039 p_insn
.opcode
|= 0x00400000;
1041 switch (p_insn
.p_field
)
1044 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1045 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1046 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1047 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1048 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1049 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1052 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1053 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1054 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1055 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1056 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1057 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1060 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1061 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1062 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1063 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1064 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1065 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1068 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1069 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1070 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1071 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1072 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1073 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1082 p
= frag_more (INSN_SIZE
);
1083 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1089 for (i
= 0; i
< 2; i
++)
1090 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1091 free (p_insn
.operand_type
[i
][j
]);
1094 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1100 /* In order to get gas to ignore any | chars at the start of a line,
1101 this function returns true if a | is found in a line. */
1104 tic30_unrecognized_line (int c
)
1106 debug ("In tc_unrecognized_line\n");
1107 return (c
== PARALLEL_SEPARATOR
);
1111 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
1112 segT segment ATTRIBUTE_UNUSED
)
1114 debug ("In md_estimate_size_before_relax()\n");
1119 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1120 segT sec ATTRIBUTE_UNUSED
,
1121 register fragS
*fragP ATTRIBUTE_UNUSED
)
1123 debug ("In md_convert_frag()\n");
1127 md_apply_fix (fixS
*fixP
,
1129 segT seg ATTRIBUTE_UNUSED
)
1131 valueT value
= *valP
;
1133 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1134 debug ("Values in fixP\n");
1135 debug ("fx_size = %d\n", fixP
->fx_size
);
1136 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1137 debug ("fx_where = %ld\n", fixP
->fx_where
);
1138 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1140 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1143 if (fixP
->fx_size
== 1)
1144 /* Special fix for LDP instruction. */
1145 value
= (value
& 0x00FF0000) >> 16;
1147 debug ("new value = %ld\n", (long) value
);
1148 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1151 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1156 md_parse_option (int c ATTRIBUTE_UNUSED
,
1157 char *arg ATTRIBUTE_UNUSED
)
1159 debug ("In md_parse_option()\n");
1164 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
1166 debug ("In md_show_usage()\n");
1170 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1172 debug ("In md_undefined_symbol()\n");
1173 return (symbolS
*) 0;
1177 md_section_align (segT segment
, valueT size
)
1179 debug ("In md_section_align() segment = %p and size = %lu\n",
1180 segment
, (unsigned long) size
);
1181 size
= (size
+ 3) / 4;
1183 debug ("New size value = %lu\n", (unsigned long) size
);
1188 md_pcrel_from (fixS
*fixP
)
1192 debug ("In md_pcrel_from()\n");
1193 debug ("fx_where = %ld\n", fixP
->fx_where
);
1194 debug ("fx_size = %d\n", fixP
->fx_size
);
1195 /* Find the opcode that represents the current instruction in the
1196 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1197 current instruction is a delayed one or not, and then set the offset
1198 value appropriately. */
1199 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1203 debug ("offset = %d\n", offset
);
1204 /* PC Relative instructions have a format:
1205 displacement = Label - (PC + offset)
1206 This function returns PC + offset where:
1207 fx_where - fx_size = PC
1208 INSN_SIZE * offset = offset number of instructions. */
1209 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1213 md_atof (int what_statement_type
,
1220 unsigned long value
;
1223 debug ("In md_atof()\n");
1224 debug ("precision = %c\n", what_statement_type
);
1225 debug ("literal = %s\n", literalP
);
1227 token
= input_line_pointer
;
1228 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1229 && (*input_line_pointer
!= ','))
1231 debug ("%c", *input_line_pointer
);
1232 input_line_pointer
++;
1235 keepval
= *input_line_pointer
;
1236 *input_line_pointer
= '\0';
1238 float_value
= (float) atof (token
);
1239 *input_line_pointer
= keepval
;
1240 debug ("float_value = %f\n", float_value
);
1242 switch (what_statement_type
)
1260 return "Bad call to MD_ATOF()";
1263 if (float_value
== 0.0)
1264 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1267 unsigned long exp
, sign
, mant
, tmsfloat
;
1275 converter
.f
= float_value
;
1276 tmsfloat
= converter
.l
;
1277 sign
= tmsfloat
& 0x80000000;
1278 mant
= tmsfloat
& 0x007FFFFF;
1279 exp
= tmsfloat
& 0x7F800000;
1281 if (exp
== 0xFF000000)
1295 mant
= mant
& 0x007FFFFF;
1297 mant
= mant
& 0x00FFFFFF;
1301 exp
= (long) exp
- 0x01000000;
1304 tmsfloat
= exp
| mant
;
1311 if (tmsfloat
== 0x80000000)
1316 exp
= (tmsfloat
& 0xFF000000);
1318 mant
= tmsfloat
& 0x007FFFFF;
1319 if (tmsfloat
& 0x00800000)
1333 exp
+= (mant
>> 24);
1343 mant
= (exp
<< 12) | mant
;
1344 value
= mant
& 0xFFFF;
1349 md_number_to_chars (literalP
, value
, prec
);
1355 md_number_to_chars (char *buf
, valueT val
, int n
)
1357 debug ("In md_number_to_chars()\n");
1358 number_to_chars_bigendian (buf
, val
, n
);
1361 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1362 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1365 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
1368 bfd_reloc_code_real_type code
= 0;
1370 debug ("In tc_gen_reloc()\n");
1371 debug ("fixP.size = %d\n", fixP
->fx_size
);
1372 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1373 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1375 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1377 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1378 MAP (2, 0, BFD_RELOC_16
);
1379 MAP (3, 0, BFD_RELOC_24
);
1380 MAP (2, 1, BFD_RELOC_16_PCREL
);
1381 MAP (4, 0, BFD_RELOC_32
);
1383 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1384 fixP
->fx_pcrel
? "pc-relative " : "");
1389 rel
= xmalloc (sizeof (* rel
));
1391 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
1392 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1393 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1395 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1400 name
= S_GET_NAME (fixP
->fx_addsy
);
1403 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1404 name
, bfd_get_reloc_code_name (code
));
1410 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1412 debug ("In md_operand()\n");
1416 md_assemble (char *line
)
1424 debug ("In md_assemble() with argument %s\n", line
);
1425 memset (&insn
, '\0', sizeof (insn
));
1426 if (found_parallel_insn
)
1428 debug ("Line is second part of parallel instruction\n\n");
1429 found_parallel_insn
= 0;
1433 tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
1434 current_posn
= line
;
1436 found_parallel_insn
= 1;
1438 while (is_space_char (*current_posn
))
1441 token_start
= current_posn
;
1443 if (!is_opcode_char (*current_posn
))
1445 as_bad ("Invalid character %s in opcode",
1446 output_invalid (*current_posn
));
1449 /* Check if instruction is a parallel instruction
1450 by seeing if the first character is a q. */
1451 if (*token_start
== 'q')
1453 if (tic30_parallel_insn (token_start
))
1455 if (found_parallel_insn
)
1460 while (is_opcode_char (*current_posn
))
1463 /* Find instruction. */
1464 save_char
= *current_posn
;
1465 *current_posn
= '\0';
1466 opcode
= (template *) hash_find (op_hash
, token_start
);
1469 debug ("Found instruction %s\n", opcode
->name
);
1474 debug ("Didn't find insn\n");
1475 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
1478 *current_posn
= save_char
;
1481 if (*current_posn
!= END_OF_INSN
)
1483 /* Find operands. */
1484 int paren_not_balanced
;
1485 int expecting_operand
= 0;
1489 /* Skip optional white space before operand. */
1490 while (!is_operand_char (*current_posn
)
1491 && *current_posn
!= END_OF_INSN
)
1493 if (!is_space_char (*current_posn
))
1495 as_bad ("Invalid character %s before %s operand",
1496 output_invalid (*current_posn
),
1497 ordinal_names
[insn
.operands
]);
1502 token_start
= current_posn
;
1503 paren_not_balanced
= 0;
1504 while (paren_not_balanced
|| *current_posn
!= ',')
1506 if (*current_posn
== END_OF_INSN
)
1508 if (paren_not_balanced
)
1510 as_bad ("Unbalanced parenthesis in %s operand.",
1511 ordinal_names
[insn
.operands
]);
1517 else if (!is_operand_char (*current_posn
)
1518 && !is_space_char (*current_posn
))
1520 as_bad ("Invalid character %s in %s operand",
1521 output_invalid (*current_posn
),
1522 ordinal_names
[insn
.operands
]);
1525 if (*current_posn
== '(')
1526 ++paren_not_balanced
;
1527 if (*current_posn
== ')')
1528 --paren_not_balanced
;
1531 if (current_posn
!= token_start
)
1533 /* Yes, we've read in another operand. */
1534 this_operand
= insn
.operands
++;
1535 if (insn
.operands
> MAX_OPERANDS
)
1537 as_bad ("Spurious operands; (%d operands/instruction max)",
1542 /* Now parse operand adding info to 'insn' as we go along. */
1543 save_char
= *current_posn
;
1544 *current_posn
= '\0';
1545 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
1546 *current_posn
= save_char
;
1547 if (insn
.operand_type
[this_operand
] == NULL
)
1552 if (expecting_operand
)
1554 as_bad ("Expecting operand after ','; got nothing");
1557 if (*current_posn
== ',')
1559 as_bad ("Expecting operand before ','; got nothing");
1564 /* Now *current_posn must be either ',' or END_OF_INSN. */
1565 if (*current_posn
== ',')
1567 if (*++current_posn
== END_OF_INSN
)
1569 /* Just skip it, if it's \n complain. */
1570 as_bad ("Expecting operand after ','; got nothing");
1573 expecting_operand
= 1;
1576 while (*current_posn
!= END_OF_INSN
);
1579 debug ("Number of operands found: %d\n", insn
.operands
);
1581 /* Check that number of operands is correct. */
1582 if (insn
.operands
!= insn
.tm
->operands
)
1585 unsigned int numops
= insn
.tm
->operands
;
1587 /* If operands are not the same, then see if any of the operands are
1588 not required. Then recheck with number of given operands. If they
1589 are still not the same, then give an error, otherwise carry on. */
1590 for (i
= 0; i
< insn
.tm
->operands
; i
++)
1591 if (insn
.tm
->operand_types
[i
] & NotReq
)
1593 if (insn
.operands
!= numops
)
1595 as_bad ("Incorrect number of operands given");
1599 insn
.addressing_mode
= AM_NotReq
;
1600 for (count
= 0; count
< insn
.operands
; count
++)
1602 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
1604 debug ("Operand %d matches\n", count
+ 1);
1605 /* If instruction has two operands and has an AddressMode
1606 modifier then set addressing mode type for instruction. */
1607 if (insn
.tm
->opcode_modifier
== AddressMode
)
1610 /* Store instruction uses the second
1611 operand for the address mode. */
1612 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
))
1613 == (Indirect
| Direct
))
1616 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
1617 insn
.addressing_mode
= AM_Register
;
1618 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
1619 insn
.addressing_mode
= AM_Direct
;
1620 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
1621 insn
.addressing_mode
= AM_Indirect
;
1623 insn
.addressing_mode
= AM_Immediate
;
1628 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
1633 /* Now set the addressing mode for 3 operand instructions. */
1634 if ((insn
.tm
->operand_types
[0] & op3T1
)
1635 && (insn
.tm
->operand_types
[1] & op3T2
))
1637 /* Set the addressing mode to the values used for 2 operand
1638 instructions in the G addressing field of the opcode. */
1640 switch (insn
.operand_type
[0]->op_type
)
1646 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1647 insn
.addressing_mode
= AM_Register
;
1648 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1649 insn
.addressing_mode
= AM_Direct
;
1652 /* Shouldn't make it to this stage. */
1653 as_bad ("Incompatible first and second operands in instruction");
1658 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1659 insn
.addressing_mode
= AM_Indirect
;
1660 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1661 insn
.addressing_mode
= AM_Immediate
;
1664 /* Shouldn't make it to this stage. */
1665 as_bad ("Incompatible first and second operands in instruction");
1670 /* Now make up the opcode for the 3 operand instructions. As in
1671 parallel instructions, there will be no unresolved values, so they
1672 can be fully formed and added to the frag table. */
1673 insn
.opcode
= insn
.tm
->base_opcode
;
1674 if (insn
.operand_type
[0]->op_type
& Indirect
)
1676 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
1677 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
1680 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1682 if (insn
.operand_type
[1]->op_type
& Indirect
)
1684 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
1685 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
1688 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
1690 if (insn
.operands
== 3)
1691 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
1693 insn
.opcode
|= insn
.addressing_mode
;
1694 p
= frag_more (INSN_SIZE
);
1695 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1699 /* Not a three operand instruction. */
1702 insn
.opcode
= insn
.tm
->base_opcode
;
1703 /* Create frag for instruction - all instructions are 4 bytes long. */
1704 p
= frag_more (INSN_SIZE
);
1705 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
1707 insn
.opcode
|= insn
.addressing_mode
;
1708 if (insn
.addressing_mode
== AM_Indirect
)
1710 /* Determine which operand gives the addressing mode. */
1711 if (insn
.operand_type
[0]->op_type
& Indirect
)
1713 if ((insn
.operands
> 1)
1714 && (insn
.operand_type
[1]->op_type
& Indirect
))
1716 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
1717 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
1718 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
1719 if (insn
.operands
> 1)
1720 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
1721 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1723 else if (insn
.addressing_mode
== AM_Register
)
1725 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1726 if (insn
.operands
> 1)
1727 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1728 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1730 else if (insn
.addressing_mode
== AM_Direct
)
1732 if (insn
.operand_type
[0]->op_type
& Direct
)
1734 if ((insn
.operands
> 1)
1735 && (insn
.operand_type
[1]->op_type
& Direct
))
1737 if (insn
.operands
> 1)
1739 (insn
.operand_type
[! am_insn
]->reg
.opcode
<< 16);
1740 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
1742 /* Resolved values can be placed straight
1743 into instruction word, and output. */
1745 (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
1746 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1750 /* Unresolved direct addressing mode instruction. */
1751 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1752 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1753 & insn
.operand_type
[am_insn
]->direct
.direct_expr
,
1757 else if (insn
.addressing_mode
== AM_Immediate
)
1759 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1764 if (insn
.operands
> 1)
1765 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1767 switch (insn
.tm
->imm_arg_type
)
1770 debug ("Floating point first operand\n");
1771 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1773 keeploc
= input_line_pointer
;
1774 input_line_pointer
=
1775 insn
.operand_type
[0]->immediate
.label
;
1777 if (md_atof ('f', p
+ 2, & size
) != 0)
1779 as_bad ("invalid short form floating point immediate operand");
1783 input_line_pointer
= keeploc
;
1787 debug ("Unsigned int first operand\n");
1788 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1789 as_warn ("rounding down first operand float to unsigned int");
1790 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
1791 as_warn ("only lower 16-bits of first operand are used");
1793 (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
1794 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1798 debug ("Int first operand\n");
1800 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1801 as_warn ("rounding down first operand float to signed int");
1803 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1804 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1806 as_bad ("first operand is too large for 16-bit signed int");
1810 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
1811 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1817 /* Unresolved immediate label. */
1818 if (insn
.operands
> 1)
1819 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1820 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1821 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1822 & insn
.operand_type
[0]->immediate
.imm_expr
,
1827 else if (insn
.tm
->opcode_modifier
== PCRel
)
1829 /* Conditional Branch and Call instructions. */
1830 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
))
1833 if (insn
.operand_type
[0]->op_type
& (AllReg
))
1835 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1836 insn
.opcode
|= PC_Register
;
1837 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1841 insn
.opcode
|= PC_Relative
;
1842 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1845 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
1846 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1850 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1851 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
),
1852 2, & insn
.operand_type
[0]->immediate
.imm_expr
,
1857 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
1859 /* Decrement and Branch instructions. */
1860 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
1861 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1863 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
1864 insn
.opcode
|= PC_Register
;
1865 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1867 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
1869 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1871 as_bad ("first operand is floating point");
1874 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1875 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1877 as_bad ("first operand is too large for 16-bit signed int");
1880 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
1881 insn
.opcode
|= PC_Relative
;
1882 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1886 insn
.opcode
|= PC_Relative
;
1887 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1888 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2,
1889 & insn
.operand_type
[1]->immediate
.imm_expr
,
1894 else if (insn
.tm
->operand_types
[0] == IVector
)
1896 /* Trap instructions. */
1897 if (insn
.operand_type
[0]->op_type
& IVector
)
1898 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
1901 /* Shouldn't get here. */
1902 as_bad ("interrupt vector for trap instruction out of range");
1905 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1907 else if (insn
.tm
->opcode_modifier
== StackOp
1908 || insn
.tm
->opcode_modifier
== Rotate
)
1910 /* Push, Pop and Rotate instructions. */
1911 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
1912 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1914 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
))
1915 == (Abs24
| Direct
))
1917 /* LDP Instruction needs to be tested
1918 for before the next section. */
1919 if (insn
.operand_type
[0]->op_type
& Direct
)
1921 if (insn
.operand_type
[0]->direct
.resolved
== 1)
1923 /* Direct addressing uses lower 8 bits of direct address. */
1925 (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
1926 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1932 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1933 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1934 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
1935 /* Ensure that the assembler doesn't complain
1936 about fitting a 24-bit address into 8 bits. */
1937 fix
->fx_no_overflow
= 1;
1942 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1944 /* Immediate addressing uses upper 8 bits of address. */
1945 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1947 as_bad ("LDP instruction needs a 24-bit operand");
1951 ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
1952 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1957 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1958 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1959 1, &insn
.operand_type
[0]->immediate
.imm_expr
,
1961 fix
->fx_no_overflow
= 1;
1965 else if (insn
.tm
->operand_types
[0] & (Imm24
))
1967 /* Unconditional Branch and Call instructions. */
1968 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1970 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1971 as_warn ("first operand is too large for a 24-bit displacement");
1973 (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
1974 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1978 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1979 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3,
1980 & insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
1983 else if (insn
.tm
->operand_types
[0] & NotReq
)
1984 /* Check for NOP instruction without arguments. */
1985 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1987 else if (insn
.tm
->operands
== 0)
1988 /* Check for instructions without operands. */
1989 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1991 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
1995 for (i
= 0; i
< insn
.operands
; i
++)
1997 if (insn
.operand_type
[i
]->immediate
.label
)
1998 free (insn
.operand_type
[i
]->immediate
.label
);
1999 free (insn
.operand_type
[i
]);
2002 debug ("Final opcode: %08X\n", insn
.opcode
);