1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007
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 3, 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"
32 /* Put here all non-digit non-letter characters that may occur in an
34 static char operand_special_chars
[] = "%$-+(,)*._~/<>&^!:[@]";
35 static char *ordinal_names
[] =
37 "first", "second", "third", "fourth", "fifth"
40 const char comment_chars
[] = ";";
41 const char line_comment_chars
[] = "*";
42 const char line_separator_chars
[] = "";
44 const char *md_shortopts
= "";
45 struct option md_longopts
[] =
47 {NULL
, no_argument
, NULL
, 0}
50 size_t md_longopts_size
= sizeof (md_longopts
);
52 /* Chars that mean this number is a floating point constant.
55 const char FLT_CHARS
[] = "fFdDxX";
57 /* Chars that can be used to separate mant from exp in floating point
59 const char EXP_CHARS
[] = "eE";
61 /* Tables for lexical analysis. */
62 static char opcode_chars
[256];
63 static char register_chars
[256];
64 static char operand_chars
[256];
65 static char space_chars
[256];
66 static char identifier_chars
[256];
67 static char digit_chars
[256];
70 #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
71 #define is_operand_char(x) (operand_chars [(unsigned char) x])
72 #define is_register_char(x) (register_chars [(unsigned char) x])
73 #define is_space_char(x) (space_chars [(unsigned char) x])
74 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
75 #define is_digit_char(x) (digit_chars [(unsigned char) x])
77 const pseudo_typeS md_pseudo_table
[] =
82 static int ATTRIBUTE_PRINTF_1
83 debug (const char *string
, ...)
89 VA_OPEN (argptr
, string
);
90 VA_FIXEDARG (argptr
, const char *, string
);
91 vsprintf (str
, string
, argptr
);
95 fputs (str
, USE_STDOUT
? stdout
: stderr
);
102 /* Hash table for opcode lookup. */
103 static struct hash_control
*op_hash
;
104 /* Hash table for parallel opcode lookup. */
105 static struct hash_control
*parop_hash
;
106 /* Hash table for register lookup. */
107 static struct hash_control
*reg_hash
;
108 /* Hash table for indirect addressing lookup. */
109 static struct hash_control
*ind_hash
;
114 const char *hash_err
;
116 debug ("In md_begin()\n");
117 op_hash
= hash_new ();
120 const template *current_optab
= tic30_optab
;
122 for (; current_optab
< tic30_optab_end
; current_optab
++)
124 hash_err
= hash_insert (op_hash
, current_optab
->name
,
125 (char *) current_optab
);
127 as_fatal ("Internal Error: Can't Hash %s: %s",
128 current_optab
->name
, hash_err
);
132 parop_hash
= hash_new ();
135 const partemplate
*current_parop
= tic30_paroptab
;
137 for (; current_parop
< tic30_paroptab_end
; current_parop
++)
139 hash_err
= hash_insert (parop_hash
, current_parop
->name
,
140 (char *) current_parop
);
142 as_fatal ("Internal Error: Can't Hash %s: %s",
143 current_parop
->name
, hash_err
);
147 reg_hash
= hash_new ();
150 const reg
*current_reg
= tic30_regtab
;
152 for (; current_reg
< tic30_regtab_end
; current_reg
++)
154 hash_err
= hash_insert (reg_hash
, current_reg
->name
,
155 (char *) current_reg
);
157 as_fatal ("Internal Error: Can't Hash %s: %s",
158 current_reg
->name
, hash_err
);
162 ind_hash
= hash_new ();
165 const ind_addr_type
*current_ind
= tic30_indaddr_tab
;
167 for (; current_ind
< tic30_indaddrtab_end
; current_ind
++)
169 hash_err
= hash_insert (ind_hash
, current_ind
->syntax
,
170 (char *) current_ind
);
172 as_fatal ("Internal Error: Can't Hash %s: %s",
173 current_ind
->syntax
, hash_err
);
177 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
182 for (c
= 0; c
< 256; c
++)
184 if (ISLOWER (c
) || ISDIGIT (c
))
187 register_chars
[c
] = c
;
189 else if (ISUPPER (c
))
191 opcode_chars
[c
] = TOLOWER (c
);
192 register_chars
[c
] = opcode_chars
[c
];
194 else if (c
== ')' || c
== '(')
195 register_chars
[c
] = c
;
197 if (ISUPPER (c
) || ISLOWER (c
) || ISDIGIT (c
))
198 operand_chars
[c
] = c
;
200 if (ISDIGIT (c
) || c
== '-')
203 if (ISALPHA (c
) || c
== '_' || c
== '.' || ISDIGIT (c
))
204 identifier_chars
[c
] = c
;
206 if (c
== ' ' || c
== '\t')
212 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
213 operand_chars
[(unsigned char) *p
] = *p
;
217 /* Address Mode OR values. */
218 #define AM_Register 0x00000000
219 #define AM_Direct 0x00200000
220 #define AM_Indirect 0x00400000
221 #define AM_Immediate 0x00600000
222 #define AM_NotReq 0xFFFFFFFF
224 /* PC Relative OR values. */
225 #define PC_Register 0x00000000
226 #define PC_Relative 0x02000000
236 expressionS direct_expr
;
254 unsigned int u_number
;
256 expressionS imm_expr
;
264 template *tm
; /* Template of current instruction. */
265 unsigned opcode
; /* Final opcode. */
266 unsigned int operands
; /* Number of given operands. */
267 /* Type of operand given in instruction. */
268 operand
*operand_type
[MAX_OPERANDS
];
269 unsigned addressing_mode
; /* Final addressing mode of instruction. */
272 struct tic30_insn insn
;
273 static int found_parallel_insn
;
275 static char output_invalid_buf
[sizeof (unsigned char) * 2 + 6];
278 output_invalid (char c
)
281 snprintf (output_invalid_buf
, sizeof (output_invalid_buf
),
284 snprintf (output_invalid_buf
, sizeof (output_invalid_buf
),
285 "(0x%x)", (unsigned char) c
);
286 return output_invalid_buf
;
289 /* next_line points to the next line after the current instruction
290 (current_line). Search for the parallel bars, and if found, merge two
291 lines into internal syntax for a parallel instruction:
292 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
293 By this stage, all comments are scrubbed, and only the bare lines are
297 #define START_OPCODE 1
299 #define START_OPERANDS 3
300 #define END_OPERANDS 4
303 tic30_find_parallel_insn (char *current_line
, char *next_line
)
305 int found_parallel
= 0;
306 char first_opcode
[256];
307 char second_opcode
[256];
308 char first_operands
[256];
309 char second_operands
[256];
312 debug ("In tic30_find_parallel_insn()\n");
313 while (!is_end_of_line
[(unsigned char) *next_line
])
315 if (*next_line
== PARALLEL_SEPARATOR
316 && *(next_line
+ 1) == PARALLEL_SEPARATOR
)
326 debug ("Found a parallel instruction\n");
330 char *opcode
, *operands
, *line
;
332 for (i
= 0; i
< 2; i
++)
336 opcode
= &first_opcode
[0];
337 operands
= &first_operands
[0];
342 opcode
= &second_opcode
[0];
343 operands
= &second_operands
[0];
348 int search_status
= NONE
;
352 while (!is_end_of_line
[(unsigned char) (c
= *line
)])
354 if (is_opcode_char (c
) && search_status
== NONE
)
356 opcode
[char_ptr
++] = TOLOWER (c
);
357 search_status
= START_OPCODE
;
359 else if (is_opcode_char (c
) && search_status
== START_OPCODE
)
360 opcode
[char_ptr
++] = TOLOWER (c
);
361 else if (!is_opcode_char (c
) && search_status
== START_OPCODE
)
363 opcode
[char_ptr
] = '\0';
365 search_status
= END_OPCODE
;
367 else if (is_operand_char (c
) && search_status
== START_OPERANDS
)
368 operands
[char_ptr
++] = c
;
370 if (is_operand_char (c
) && search_status
== END_OPCODE
)
372 operands
[char_ptr
++] = c
;
373 search_status
= START_OPERANDS
;
378 if (search_status
!= START_OPERANDS
)
380 operands
[char_ptr
] = '\0';
384 parallel_insn
= malloc (strlen (first_opcode
) + strlen (first_operands
)
385 + strlen (second_opcode
) + strlen (second_operands
) + 8);
386 sprintf (parallel_insn
, "q_%s_%s %s | %s",
387 first_opcode
, second_opcode
,
388 first_operands
, second_operands
);
389 debug ("parallel insn = %s\n", parallel_insn
);
390 return parallel_insn
;
396 #undef START_OPERANDS
400 tic30_operand (char *token
)
403 char ind_buffer
[strlen (token
)];
406 debug ("In tic30_operand with %s\n", token
);
407 current_op
= malloc (sizeof (* current_op
));
408 memset (current_op
, '\0', sizeof (operand
));
410 if (*token
== DIRECT_REFERENCE
)
412 char *token_posn
= token
+ 1;
413 int direct_label
= 0;
415 debug ("Found direct reference\n");
418 if (!is_digit_char (*token_posn
))
425 char *save_input_line_pointer
;
428 debug ("Direct reference is a label\n");
429 current_op
->direct
.label
= token
+ 1;
430 save_input_line_pointer
= input_line_pointer
;
431 input_line_pointer
= token
+ 1;
432 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
433 retval
= expression (¤t_op
->direct
.direct_expr
);
435 debug ("Expression type: %d\n",
436 current_op
->direct
.direct_expr
.X_op
);
437 debug ("Expression addnum: %ld\n",
438 (long) current_op
->direct
.direct_expr
.X_add_number
);
439 debug ("Segment: %p\n", retval
);
441 input_line_pointer
= save_input_line_pointer
;
443 if (current_op
->direct
.direct_expr
.X_op
== O_constant
)
445 current_op
->direct
.address
=
446 current_op
->direct
.direct_expr
.X_add_number
;
447 current_op
->direct
.resolved
= 1;
452 debug ("Direct reference is a number\n");
453 current_op
->direct
.address
= atoi (token
+ 1);
454 current_op
->direct
.resolved
= 1;
456 current_op
->op_type
= Direct
;
458 else if (*token
== INDIRECT_REFERENCE
)
460 /* Indirect reference operand. */
466 ind_addr_type
*ind_addr_op
;
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");
486 if (*(token
+ count
+ 1) < '0' || *(token
+ count
+ 1) > '7')
488 as_bad ("Illegal AR register in indirect reference");
491 ar_number
= *(token
+ count
+ 1) - '0';
496 if (*(token
+ count
) == '(')
498 /* Parenthesis found, so check if a displacement value is
499 inside. If so, get the value and remove it from the
501 if (is_digit_char (*(token
+ count
+ 1)))
508 as_bad ("More than one displacement found in indirect reference");
512 while (*(token
+ count
) != ')')
514 if (!is_digit_char (*(token
+ count
)))
516 as_bad ("Invalid displacement in indirect reference");
519 disp
[disp_posn
++] = *(token
+ (count
++));
521 disp
[disp_posn
] = '\0';
522 disp_number
= atoi (disp
);
530 ind_buffer
[buffer_posn
] = '\0';
533 as_bad ("AR register not found in indirect reference");
537 ind_addr_op
= (ind_addr_type
*) hash_find (ind_hash
, ind_buffer
);
540 debug ("Found indirect reference: %s\n", ind_addr_op
->syntax
);
541 if (ind_addr_op
->displacement
== IMPLIED_DISP
)
546 else if ((ind_addr_op
->displacement
== DISP_REQUIRED
) && !found_disp
)
548 /* Maybe an implied displacement of 1 again. */
549 as_bad ("required displacement wasn't given in indirect reference");
555 as_bad ("illegal indirect reference");
559 if (found_disp
&& (disp_number
< 0 || disp_number
> 255))
561 as_bad ("displacement must be an unsigned 8-bit number");
565 current_op
->indirect
.mod
= ind_addr_op
->modfield
;
566 current_op
->indirect
.disp
= disp_number
;
567 current_op
->indirect
.ARnum
= ar_number
;
568 current_op
->op_type
= Indirect
;
572 reg
*regop
= (reg
*) hash_find (reg_hash
, token
);
576 debug ("Found register operand: %s\n", regop
->name
);
577 if (regop
->regtype
== REG_ARn
)
578 current_op
->op_type
= ARn
;
579 else if (regop
->regtype
== REG_Rn
)
580 current_op
->op_type
= Rn
;
581 else if (regop
->regtype
== REG_DP
)
582 current_op
->op_type
= DPReg
;
584 current_op
->op_type
= OtherReg
;
585 current_op
->reg
.opcode
= regop
->opcode
;
589 if (!is_digit_char (*token
)
590 || *(token
+ 1) == 'x'
591 || strchr (token
, 'h'))
593 char *save_input_line_pointer
;
596 debug ("Probably a label: %s\n", token
);
597 current_op
->immediate
.label
= malloc (strlen (token
) + 1);
598 strcpy (current_op
->immediate
.label
, token
);
599 current_op
->immediate
.label
[strlen (token
)] = '\0';
600 save_input_line_pointer
= input_line_pointer
;
601 input_line_pointer
= token
;
603 debug ("Current input_line_pointer: %s\n", input_line_pointer
);
604 retval
= expression (¤t_op
->immediate
.imm_expr
);
605 debug ("Expression type: %d\n",
606 current_op
->immediate
.imm_expr
.X_op
);
607 debug ("Expression addnum: %ld\n",
608 (long) current_op
->immediate
.imm_expr
.X_add_number
);
609 debug ("Segment: %p\n", retval
);
610 input_line_pointer
= save_input_line_pointer
;
612 if (current_op
->immediate
.imm_expr
.X_op
== O_constant
)
614 current_op
->immediate
.s_number
615 = current_op
->immediate
.imm_expr
.X_add_number
;
616 current_op
->immediate
.u_number
617 = (unsigned int) current_op
->immediate
.imm_expr
.X_add_number
;
618 current_op
->immediate
.resolved
= 1;
625 debug ("Found a number or displacement\n");
626 for (count
= 0; count
< strlen (token
); count
++)
627 if (*(token
+ count
) == '.')
628 current_op
->immediate
.decimal_found
= 1;
629 current_op
->immediate
.label
= malloc (strlen (token
) + 1);
630 strcpy (current_op
->immediate
.label
, token
);
631 current_op
->immediate
.label
[strlen (token
)] = '\0';
632 current_op
->immediate
.f_number
= (float) atof (token
);
633 current_op
->immediate
.s_number
= (int) atoi (token
);
634 current_op
->immediate
.u_number
= (unsigned int) atoi (token
);
635 current_op
->immediate
.resolved
= 1;
637 current_op
->op_type
= Disp
| Abs24
| Imm16
| Imm24
;
638 if (current_op
->immediate
.u_number
<= 31)
639 current_op
->op_type
|= IVector
;
645 struct tic30_par_insn
647 partemplate
*tm
; /* Template of current parallel instruction. */
648 unsigned operands
[2]; /* Number of given operands for each insn. */
649 /* Type of operand given in instruction. */
650 operand
*operand_type
[2][MAX_OPERANDS
];
651 int swap_operands
; /* Whether to swap operands around. */
652 unsigned p_field
; /* Value of p field in multiply add/sub instructions. */
653 unsigned opcode
; /* Final opcode. */
656 struct tic30_par_insn p_insn
;
659 tic30_parallel_insn (char *token
)
661 static partemplate
*p_opcode
;
662 char *current_posn
= token
;
666 debug ("In tic30_parallel_insn with %s\n", token
);
667 memset (&p_insn
, '\0', sizeof (p_insn
));
669 while (is_opcode_char (*current_posn
))
672 /* Find instruction. */
673 save_char
= *current_posn
;
674 *current_posn
= '\0';
675 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
678 debug ("Found instruction %s\n", p_opcode
->name
);
679 p_insn
.tm
= p_opcode
;
683 char first_opcode
[6] = {0};
684 char second_opcode
[6] = {0};
686 int current_opcode
= -1;
689 for (i
= 0; i
< strlen (token
); i
++)
691 char ch
= *(token
+ i
);
693 if (ch
== '_' && current_opcode
== -1)
699 if (ch
== '_' && current_opcode
== 0)
706 switch (current_opcode
)
709 first_opcode
[char_ptr
++] = ch
;
712 second_opcode
[char_ptr
++] = ch
;
717 debug ("first_opcode = %s\n", first_opcode
);
718 debug ("second_opcode = %s\n", second_opcode
);
719 sprintf (token
, "q_%s_%s", second_opcode
, first_opcode
);
720 p_opcode
= (partemplate
*) hash_find (parop_hash
, token
);
724 debug ("Found instruction %s\n", p_opcode
->name
);
725 p_insn
.tm
= p_opcode
;
726 p_insn
.swap_operands
= 1;
731 *current_posn
= save_char
;
736 int paren_not_balanced
;
737 int expecting_operand
= 0;
738 int found_separator
= 0;
742 /* Skip optional white space before operand. */
743 while (!is_operand_char (*current_posn
)
744 && *current_posn
!= END_OF_INSN
)
746 if (!is_space_char (*current_posn
)
747 && *current_posn
!= PARALLEL_SEPARATOR
)
749 as_bad ("Invalid character %s before %s operand",
750 output_invalid (*current_posn
),
751 ordinal_names
[insn
.operands
]);
754 if (*current_posn
== PARALLEL_SEPARATOR
)
759 token_start
= current_posn
;
760 paren_not_balanced
= 0;
762 while (paren_not_balanced
|| *current_posn
!= ',')
764 if (*current_posn
== END_OF_INSN
)
766 if (paren_not_balanced
)
768 as_bad ("Unbalanced parenthesis in %s operand.",
769 ordinal_names
[insn
.operands
]);
775 else if (*current_posn
== PARALLEL_SEPARATOR
)
777 while (is_space_char (*(current_posn
- 1)))
781 else if (!is_operand_char (*current_posn
)
782 && !is_space_char (*current_posn
))
784 as_bad ("Invalid character %s in %s operand",
785 output_invalid (*current_posn
),
786 ordinal_names
[insn
.operands
]);
790 if (*current_posn
== '(')
791 ++paren_not_balanced
;
792 if (*current_posn
== ')')
793 --paren_not_balanced
;
797 if (current_posn
!= token_start
)
799 /* Yes, we've read in another operand. */
800 p_insn
.operands
[found_separator
]++;
801 if (p_insn
.operands
[found_separator
] > MAX_OPERANDS
)
803 as_bad ("Spurious operands; (%d operands/instruction max)",
808 /* Now parse operand adding info to 'insn' as we go along. */
809 save_char
= *current_posn
;
810 *current_posn
= '\0';
811 p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1] =
812 tic30_operand (token_start
);
813 *current_posn
= save_char
;
814 if (!p_insn
.operand_type
[found_separator
][p_insn
.operands
[found_separator
] - 1])
819 if (expecting_operand
)
821 as_bad ("Expecting operand after ','; got nothing");
824 if (*current_posn
== ',')
826 as_bad ("Expecting operand before ','; got nothing");
831 /* Now *current_posn must be either ',' or END_OF_INSN. */
832 if (*current_posn
== ',')
834 if (*++current_posn
== END_OF_INSN
)
836 /* Just skip it, if it's \n complain. */
837 as_bad ("Expecting operand after ','; got nothing");
840 expecting_operand
= 1;
843 while (*current_posn
!= END_OF_INSN
);
846 if (p_insn
.swap_operands
)
851 temp_num
= p_insn
.operands
[0];
852 p_insn
.operands
[0] = p_insn
.operands
[1];
853 p_insn
.operands
[1] = temp_num
;
854 for (i
= 0; i
< MAX_OPERANDS
; i
++)
856 temp_op
= p_insn
.operand_type
[0][i
];
857 p_insn
.operand_type
[0][i
] = p_insn
.operand_type
[1][i
];
858 p_insn
.operand_type
[1][i
] = temp_op
;
862 if (p_insn
.operands
[0] != p_insn
.tm
->operands_1
)
864 as_bad ("incorrect number of operands given in the first instruction");
868 if (p_insn
.operands
[1] != p_insn
.tm
->operands_2
)
870 as_bad ("incorrect number of operands given in the second instruction");
874 debug ("Number of operands in first insn: %d\n", p_insn
.operands
[0]);
875 debug ("Number of operands in second insn: %d\n", p_insn
.operands
[1]);
878 /* Now check if operands are correct. */
883 for (count
= 0; count
< 2; count
++)
886 for (i
= 0; i
< p_insn
.operands
[count
]; i
++)
888 if ((p_insn
.operand_type
[count
][i
]->op_type
&
889 p_insn
.tm
->operand_types
[count
][i
]) == 0)
891 as_bad ("%s instruction, operand %d doesn't match",
892 ordinal_names
[count
], i
+ 1);
896 /* Get number of R register and indirect reference contained
897 within the first two operands of each instruction. This is
898 required for the multiply parallel instructions which require
899 two R registers and two indirect references, but not in any
901 if ((p_insn
.operand_type
[count
][i
]->op_type
& Rn
) && i
< 2)
903 else if ((p_insn
.operand_type
[count
][i
]->op_type
& Indirect
)
909 if ((p_insn
.tm
->operand_types
[0][0] & (Indirect
| Rn
))
912 /* Check for the multiply instructions. */
915 as_bad ("incorrect format for multiply parallel instruction");
921 /* Shouldn't get here. */
922 as_bad ("incorrect format for multiply parallel instruction");
926 if ((p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x00)
927 && (p_insn
.operand_type
[0][2]->reg
.opcode
!= 0x01))
929 as_bad ("destination for multiply can only be R0 or R1");
933 if ((p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x02)
934 && (p_insn
.operand_type
[1][2]->reg
.opcode
!= 0x03))
936 as_bad ("destination for add/subtract can only be R2 or R3");
940 /* Now determine the P field for the instruction. */
941 if (p_insn
.operand_type
[0][0]->op_type
& Indirect
)
943 if (p_insn
.operand_type
[0][1]->op_type
& Indirect
)
944 p_insn
.p_field
= 0x00000000; /* Ind * Ind, Rn +/- Rn. */
945 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
946 p_insn
.p_field
= 0x01000000; /* Ind * Rn, Ind +/- Rn. */
948 p_insn
.p_field
= 0x03000000; /* Ind * Rn, Rn +/- Ind. */
952 if (p_insn
.operand_type
[0][1]->op_type
& Rn
)
953 p_insn
.p_field
= 0x02000000; /* Rn * Rn, Ind +/- Ind. */
954 else if (p_insn
.operand_type
[1][0]->op_type
& Indirect
)
957 p_insn
.p_field
= 0x01000000; /* Rn * Ind, Ind +/- Rn. */
958 /* Need to swap the two multiply operands around so that
959 everything is in its place for the opcode makeup.
960 ie so Ind * Rn, Ind +/- Rn. */
961 temp
= p_insn
.operand_type
[0][0];
962 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
963 p_insn
.operand_type
[0][1] = temp
;
968 p_insn
.p_field
= 0x03000000; /* Rn * Ind, Rn +/- Ind. */
969 temp
= p_insn
.operand_type
[0][0];
970 p_insn
.operand_type
[0][0] = p_insn
.operand_type
[0][1];
971 p_insn
.operand_type
[0][1] = temp
;
977 debug ("P field: %08X\n", p_insn
.p_field
);
979 /* Finalise opcode. This is easier for parallel instructions as they have
980 to be fully resolved, there are no memory addresses allowed, except
981 through indirect addressing, so there are no labels to resolve. */
982 p_insn
.opcode
= p_insn
.tm
->base_opcode
;
984 switch (p_insn
.tm
->oporder
)
987 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
988 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
989 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
990 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
991 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
992 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
996 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
997 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
998 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
999 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1000 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 19);
1001 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 22);
1002 if (p_insn
.operand_type
[1][1]->reg
.opcode
== p_insn
.operand_type
[0][1]->reg
.opcode
)
1003 as_warn ("loading the same register in parallel operation");
1007 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1008 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1009 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1010 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1011 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1012 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 22);
1016 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
);
1017 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 3);
1018 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1019 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1020 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1021 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1022 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1026 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1027 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1028 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
<< 8);
1029 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 11);
1030 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1031 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1032 p_insn
.opcode
|= (p_insn
.operand_type
[0][2]->reg
.opcode
<< 22);
1036 p_insn
.opcode
|= p_insn
.p_field
;
1037 if (p_insn
.operand_type
[0][2]->reg
.opcode
== 0x01)
1038 p_insn
.opcode
|= 0x00800000;
1039 if (p_insn
.operand_type
[1][2]->reg
.opcode
== 0x03)
1040 p_insn
.opcode
|= 0x00400000;
1042 switch (p_insn
.p_field
)
1045 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.ARnum
);
1046 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->indirect
.mod
<< 3);
1047 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1048 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1049 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1050 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 19);
1053 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
);
1054 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 3);
1055 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1056 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1057 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->reg
.opcode
<< 16);
1058 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1061 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1062 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1063 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.ARnum
<< 8);
1064 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->indirect
.mod
<< 11);
1065 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 16);
1066 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->reg
.opcode
<< 19);
1069 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.ARnum
);
1070 p_insn
.opcode
|= (p_insn
.operand_type
[1][1]->indirect
.mod
<< 3);
1071 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.ARnum
<< 8);
1072 p_insn
.opcode
|= (p_insn
.operand_type
[0][0]->indirect
.mod
<< 11);
1073 p_insn
.opcode
|= (p_insn
.operand_type
[1][0]->reg
.opcode
<< 16);
1074 p_insn
.opcode
|= (p_insn
.operand_type
[0][1]->reg
.opcode
<< 19);
1083 p
= frag_more (INSN_SIZE
);
1084 md_number_to_chars (p
, (valueT
) p_insn
.opcode
, INSN_SIZE
);
1090 for (i
= 0; i
< 2; i
++)
1091 for (j
= 0; j
< p_insn
.operands
[i
]; j
++)
1092 free (p_insn
.operand_type
[i
][j
]);
1095 debug ("Final opcode: %08X\n", p_insn
.opcode
);
1101 /* In order to get gas to ignore any | chars at the start of a line,
1102 this function returns true if a | is found in a line. */
1105 tic30_unrecognized_line (int c
)
1107 debug ("In tc_unrecognized_line\n");
1108 return (c
== PARALLEL_SEPARATOR
);
1112 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
1113 segT segment ATTRIBUTE_UNUSED
)
1115 debug ("In md_estimate_size_before_relax()\n");
1120 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1121 segT sec ATTRIBUTE_UNUSED
,
1122 register fragS
*fragP ATTRIBUTE_UNUSED
)
1124 debug ("In md_convert_frag()\n");
1128 md_apply_fix (fixS
*fixP
,
1130 segT seg ATTRIBUTE_UNUSED
)
1132 valueT value
= *valP
;
1134 debug ("In md_apply_fix() with value = %ld\n", (long) value
);
1135 debug ("Values in fixP\n");
1136 debug ("fx_size = %d\n", fixP
->fx_size
);
1137 debug ("fx_pcrel = %d\n", fixP
->fx_pcrel
);
1138 debug ("fx_where = %ld\n", fixP
->fx_where
);
1139 debug ("fx_offset = %d\n", (int) fixP
->fx_offset
);
1141 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1144 if (fixP
->fx_size
== 1)
1145 /* Special fix for LDP instruction. */
1146 value
= (value
& 0x00FF0000) >> 16;
1148 debug ("new value = %ld\n", (long) value
);
1149 md_number_to_chars (buf
, value
, fixP
->fx_size
);
1152 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1157 md_parse_option (int c ATTRIBUTE_UNUSED
,
1158 char *arg ATTRIBUTE_UNUSED
)
1160 debug ("In md_parse_option()\n");
1165 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
1167 debug ("In md_show_usage()\n");
1171 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1173 debug ("In md_undefined_symbol()\n");
1174 return (symbolS
*) 0;
1178 md_section_align (segT segment
, valueT size
)
1180 debug ("In md_section_align() segment = %p and size = %lu\n",
1181 segment
, (unsigned long) size
);
1182 size
= (size
+ 3) / 4;
1184 debug ("New size value = %lu\n", (unsigned long) size
);
1189 md_pcrel_from (fixS
*fixP
)
1193 debug ("In md_pcrel_from()\n");
1194 debug ("fx_where = %ld\n", fixP
->fx_where
);
1195 debug ("fx_size = %d\n", fixP
->fx_size
);
1196 /* Find the opcode that represents the current instruction in the
1197 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1198 current instruction is a delayed one or not, and then set the offset
1199 value appropriately. */
1200 if (fixP
->fx_frag
->fr_literal
[fixP
->fx_where
- fixP
->fx_size
+ 1] & 0x20)
1204 debug ("offset = %d\n", offset
);
1205 /* PC Relative instructions have a format:
1206 displacement = Label - (PC + offset)
1207 This function returns PC + offset where:
1208 fx_where - fx_size = PC
1209 INSN_SIZE * offset = offset number of instructions. */
1210 return fixP
->fx_where
- fixP
->fx_size
+ (INSN_SIZE
* offset
);
1214 md_atof (int what_statement_type
,
1221 unsigned long value
;
1224 debug ("In md_atof()\n");
1225 debug ("precision = %c\n", what_statement_type
);
1226 debug ("literal = %s\n", literalP
);
1228 token
= input_line_pointer
;
1229 while (!is_end_of_line
[(unsigned char) *input_line_pointer
]
1230 && (*input_line_pointer
!= ','))
1232 debug ("%c", *input_line_pointer
);
1233 input_line_pointer
++;
1236 keepval
= *input_line_pointer
;
1237 *input_line_pointer
= '\0';
1239 float_value
= (float) atof (token
);
1240 *input_line_pointer
= keepval
;
1241 debug ("float_value = %f\n", float_value
);
1243 switch (what_statement_type
)
1261 return _("Unrecognized or unsupported floating point constant");
1264 if (float_value
== 0.0)
1265 value
= (prec
== 2) ? 0x00008000L
: 0x80000000L
;
1268 unsigned long exp
, sign
, mant
, tmsfloat
;
1276 converter
.f
= float_value
;
1277 tmsfloat
= converter
.l
;
1278 sign
= tmsfloat
& 0x80000000;
1279 mant
= tmsfloat
& 0x007FFFFF;
1280 exp
= tmsfloat
& 0x7F800000;
1282 if (exp
== 0xFF000000)
1296 mant
= mant
& 0x007FFFFF;
1298 mant
= mant
& 0x00FFFFFF;
1302 exp
= (long) exp
- 0x01000000;
1305 tmsfloat
= exp
| mant
;
1312 if (tmsfloat
== 0x80000000)
1317 exp
= (tmsfloat
& 0xFF000000);
1319 mant
= tmsfloat
& 0x007FFFFF;
1320 if (tmsfloat
& 0x00800000)
1334 exp
+= (mant
>> 24);
1344 mant
= (exp
<< 12) | mant
;
1345 value
= mant
& 0xFFFF;
1350 md_number_to_chars (literalP
, value
, prec
);
1356 md_number_to_chars (char *buf
, valueT val
, int n
)
1358 debug ("In md_number_to_chars()\n");
1359 number_to_chars_bigendian (buf
, val
, n
);
1362 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1363 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1366 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
1369 bfd_reloc_code_real_type code
= 0;
1371 debug ("In tc_gen_reloc()\n");
1372 debug ("fixP.size = %d\n", fixP
->fx_size
);
1373 debug ("fixP.pcrel = %d\n", fixP
->fx_pcrel
);
1374 debug ("addsy.name = %s\n", S_GET_NAME (fixP
->fx_addsy
));
1376 switch (F (fixP
->fx_size
, fixP
->fx_pcrel
))
1378 MAP (1, 0, BFD_RELOC_TIC30_LDP
);
1379 MAP (2, 0, BFD_RELOC_16
);
1380 MAP (3, 0, BFD_RELOC_24
);
1381 MAP (2, 1, BFD_RELOC_16_PCREL
);
1382 MAP (4, 0, BFD_RELOC_32
);
1384 as_bad ("Can not do %d byte %srelocation", fixP
->fx_size
,
1385 fixP
->fx_pcrel
? "pc-relative " : "");
1390 rel
= xmalloc (sizeof (* rel
));
1391 gas_assert (rel
!= 0);
1392 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
1393 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1394 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1396 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1401 name
= S_GET_NAME (fixP
->fx_addsy
);
1404 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1405 name
, bfd_get_reloc_code_name (code
));
1411 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1413 debug ("In md_operand()\n");
1417 md_assemble (char *line
)
1425 debug ("In md_assemble() with argument %s\n", line
);
1426 memset (&insn
, '\0', sizeof (insn
));
1427 if (found_parallel_insn
)
1429 debug ("Line is second part of parallel instruction\n\n");
1430 found_parallel_insn
= 0;
1434 tic30_find_parallel_insn (line
, input_line_pointer
+ 1)) == NULL
)
1435 current_posn
= line
;
1437 found_parallel_insn
= 1;
1439 while (is_space_char (*current_posn
))
1442 token_start
= current_posn
;
1444 if (!is_opcode_char (*current_posn
))
1446 as_bad ("Invalid character %s in opcode",
1447 output_invalid (*current_posn
));
1450 /* Check if instruction is a parallel instruction
1451 by seeing if the first character is a q. */
1452 if (*token_start
== 'q')
1454 if (tic30_parallel_insn (token_start
))
1456 if (found_parallel_insn
)
1461 while (is_opcode_char (*current_posn
))
1464 /* Find instruction. */
1465 save_char
= *current_posn
;
1466 *current_posn
= '\0';
1467 opcode
= (template *) hash_find (op_hash
, token_start
);
1470 debug ("Found instruction %s\n", opcode
->name
);
1475 debug ("Didn't find insn\n");
1476 as_bad ("Unknown TMS320C30 instruction: %s", token_start
);
1479 *current_posn
= save_char
;
1482 if (*current_posn
!= END_OF_INSN
)
1484 /* Find operands. */
1485 int paren_not_balanced
;
1486 int expecting_operand
= 0;
1490 /* Skip optional white space before operand. */
1491 while (!is_operand_char (*current_posn
)
1492 && *current_posn
!= END_OF_INSN
)
1494 if (!is_space_char (*current_posn
))
1496 as_bad ("Invalid character %s before %s operand",
1497 output_invalid (*current_posn
),
1498 ordinal_names
[insn
.operands
]);
1503 token_start
= current_posn
;
1504 paren_not_balanced
= 0;
1505 while (paren_not_balanced
|| *current_posn
!= ',')
1507 if (*current_posn
== END_OF_INSN
)
1509 if (paren_not_balanced
)
1511 as_bad ("Unbalanced parenthesis in %s operand.",
1512 ordinal_names
[insn
.operands
]);
1518 else if (!is_operand_char (*current_posn
)
1519 && !is_space_char (*current_posn
))
1521 as_bad ("Invalid character %s in %s operand",
1522 output_invalid (*current_posn
),
1523 ordinal_names
[insn
.operands
]);
1526 if (*current_posn
== '(')
1527 ++paren_not_balanced
;
1528 if (*current_posn
== ')')
1529 --paren_not_balanced
;
1532 if (current_posn
!= token_start
)
1534 /* Yes, we've read in another operand. */
1535 this_operand
= insn
.operands
++;
1536 if (insn
.operands
> MAX_OPERANDS
)
1538 as_bad ("Spurious operands; (%d operands/instruction max)",
1543 /* Now parse operand adding info to 'insn' as we go along. */
1544 save_char
= *current_posn
;
1545 *current_posn
= '\0';
1546 insn
.operand_type
[this_operand
] = tic30_operand (token_start
);
1547 *current_posn
= save_char
;
1548 if (insn
.operand_type
[this_operand
] == NULL
)
1553 if (expecting_operand
)
1555 as_bad ("Expecting operand after ','; got nothing");
1558 if (*current_posn
== ',')
1560 as_bad ("Expecting operand before ','; got nothing");
1565 /* Now *current_posn must be either ',' or END_OF_INSN. */
1566 if (*current_posn
== ',')
1568 if (*++current_posn
== END_OF_INSN
)
1570 /* Just skip it, if it's \n complain. */
1571 as_bad ("Expecting operand after ','; got nothing");
1574 expecting_operand
= 1;
1577 while (*current_posn
!= END_OF_INSN
);
1580 debug ("Number of operands found: %d\n", insn
.operands
);
1582 /* Check that number of operands is correct. */
1583 if (insn
.operands
!= insn
.tm
->operands
)
1586 unsigned int numops
= insn
.tm
->operands
;
1588 /* If operands are not the same, then see if any of the operands are
1589 not required. Then recheck with number of given operands. If they
1590 are still not the same, then give an error, otherwise carry on. */
1591 for (i
= 0; i
< insn
.tm
->operands
; i
++)
1592 if (insn
.tm
->operand_types
[i
] & NotReq
)
1594 if (insn
.operands
!= numops
)
1596 as_bad ("Incorrect number of operands given");
1600 insn
.addressing_mode
= AM_NotReq
;
1601 for (count
= 0; count
< insn
.operands
; count
++)
1603 if (insn
.operand_type
[count
]->op_type
& insn
.tm
->operand_types
[count
])
1605 debug ("Operand %d matches\n", count
+ 1);
1606 /* If instruction has two operands and has an AddressMode
1607 modifier then set addressing mode type for instruction. */
1608 if (insn
.tm
->opcode_modifier
== AddressMode
)
1611 /* Store instruction uses the second
1612 operand for the address mode. */
1613 if ((insn
.tm
->operand_types
[1] & (Indirect
| Direct
))
1614 == (Indirect
| Direct
))
1617 if (insn
.operand_type
[addr_insn
]->op_type
& (AllReg
))
1618 insn
.addressing_mode
= AM_Register
;
1619 else if (insn
.operand_type
[addr_insn
]->op_type
& Direct
)
1620 insn
.addressing_mode
= AM_Direct
;
1621 else if (insn
.operand_type
[addr_insn
]->op_type
& Indirect
)
1622 insn
.addressing_mode
= AM_Indirect
;
1624 insn
.addressing_mode
= AM_Immediate
;
1629 as_bad ("The %s operand doesn't match", ordinal_names
[count
]);
1634 /* Now set the addressing mode for 3 operand instructions. */
1635 if ((insn
.tm
->operand_types
[0] & op3T1
)
1636 && (insn
.tm
->operand_types
[1] & op3T2
))
1638 /* Set the addressing mode to the values used for 2 operand
1639 instructions in the G addressing field of the opcode. */
1641 switch (insn
.operand_type
[0]->op_type
)
1647 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1648 insn
.addressing_mode
= AM_Register
;
1649 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1650 insn
.addressing_mode
= AM_Direct
;
1653 /* Shouldn't make it to this stage. */
1654 as_bad ("Incompatible first and second operands in instruction");
1659 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1660 insn
.addressing_mode
= AM_Indirect
;
1661 else if (insn
.operand_type
[1]->op_type
& Indirect
)
1662 insn
.addressing_mode
= AM_Immediate
;
1665 /* Shouldn't make it to this stage. */
1666 as_bad ("Incompatible first and second operands in instruction");
1671 /* Now make up the opcode for the 3 operand instructions. As in
1672 parallel instructions, there will be no unresolved values, so they
1673 can be fully formed and added to the frag table. */
1674 insn
.opcode
= insn
.tm
->base_opcode
;
1675 if (insn
.operand_type
[0]->op_type
& Indirect
)
1677 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.ARnum
);
1678 insn
.opcode
|= (insn
.operand_type
[0]->indirect
.mod
<< 3);
1681 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1683 if (insn
.operand_type
[1]->op_type
& Indirect
)
1685 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.ARnum
<< 8);
1686 insn
.opcode
|= (insn
.operand_type
[1]->indirect
.mod
<< 11);
1689 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 8);
1691 if (insn
.operands
== 3)
1692 insn
.opcode
|= (insn
.operand_type
[2]->reg
.opcode
<< 16);
1694 insn
.opcode
|= insn
.addressing_mode
;
1695 p
= frag_more (INSN_SIZE
);
1696 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1700 /* Not a three operand instruction. */
1703 insn
.opcode
= insn
.tm
->base_opcode
;
1704 /* Create frag for instruction - all instructions are 4 bytes long. */
1705 p
= frag_more (INSN_SIZE
);
1706 if ((insn
.operands
> 0) && (insn
.tm
->opcode_modifier
== AddressMode
))
1708 insn
.opcode
|= insn
.addressing_mode
;
1709 if (insn
.addressing_mode
== AM_Indirect
)
1711 /* Determine which operand gives the addressing mode. */
1712 if (insn
.operand_type
[0]->op_type
& Indirect
)
1714 if ((insn
.operands
> 1)
1715 && (insn
.operand_type
[1]->op_type
& Indirect
))
1717 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.disp
);
1718 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.ARnum
<< 8);
1719 insn
.opcode
|= (insn
.operand_type
[am_insn
]->indirect
.mod
<< 11);
1720 if (insn
.operands
> 1)
1721 insn
.opcode
|= (insn
.operand_type
[!am_insn
]->reg
.opcode
<< 16);
1722 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1724 else if (insn
.addressing_mode
== AM_Register
)
1726 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1727 if (insn
.operands
> 1)
1728 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1729 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1731 else if (insn
.addressing_mode
== AM_Direct
)
1733 if (insn
.operand_type
[0]->op_type
& Direct
)
1735 if ((insn
.operands
> 1)
1736 && (insn
.operand_type
[1]->op_type
& Direct
))
1738 if (insn
.operands
> 1)
1740 (insn
.operand_type
[! am_insn
]->reg
.opcode
<< 16);
1741 if (insn
.operand_type
[am_insn
]->direct
.resolved
== 1)
1743 /* Resolved values can be placed straight
1744 into instruction word, and output. */
1746 (insn
.operand_type
[am_insn
]->direct
.address
& 0x0000FFFF);
1747 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1751 /* Unresolved direct addressing mode instruction. */
1752 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1753 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1754 & insn
.operand_type
[am_insn
]->direct
.direct_expr
,
1758 else if (insn
.addressing_mode
== AM_Immediate
)
1760 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1765 if (insn
.operands
> 1)
1766 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1768 switch (insn
.tm
->imm_arg_type
)
1771 debug ("Floating point first operand\n");
1772 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1774 keeploc
= input_line_pointer
;
1775 input_line_pointer
=
1776 insn
.operand_type
[0]->immediate
.label
;
1778 if (md_atof ('f', p
+ 2, & size
) != 0)
1780 as_bad ("invalid short form floating point immediate operand");
1784 input_line_pointer
= keeploc
;
1788 debug ("Unsigned int first operand\n");
1789 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1790 as_warn ("rounding down first operand float to unsigned int");
1791 if (insn
.operand_type
[0]->immediate
.u_number
> 0xFFFF)
1792 as_warn ("only lower 16-bits of first operand are used");
1794 (insn
.operand_type
[0]->immediate
.u_number
& 0x0000FFFFL
);
1795 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1799 debug ("Int first operand\n");
1801 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1802 as_warn ("rounding down first operand float to signed int");
1804 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1805 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1807 as_bad ("first operand is too large for 16-bit signed int");
1811 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFFL
);
1812 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1818 /* Unresolved immediate label. */
1819 if (insn
.operands
> 1)
1820 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
<< 16);
1821 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1822 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
), 2,
1823 & insn
.operand_type
[0]->immediate
.imm_expr
,
1828 else if (insn
.tm
->opcode_modifier
== PCRel
)
1830 /* Conditional Branch and Call instructions. */
1831 if ((insn
.tm
->operand_types
[0] & (AllReg
| Disp
))
1834 if (insn
.operand_type
[0]->op_type
& (AllReg
))
1836 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
);
1837 insn
.opcode
|= PC_Register
;
1838 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1842 insn
.opcode
|= PC_Relative
;
1843 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1846 (insn
.operand_type
[0]->immediate
.s_number
& 0x0000FFFF);
1847 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1851 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1852 fix_new_exp (frag_now
, p
+ 2 - (frag_now
->fr_literal
),
1853 2, & insn
.operand_type
[0]->immediate
.imm_expr
,
1858 else if ((insn
.tm
->operand_types
[0] & ARn
) == ARn
)
1860 /* Decrement and Branch instructions. */
1861 insn
.opcode
|= ((insn
.operand_type
[0]->reg
.opcode
- 0x08) << 22);
1862 if (insn
.operand_type
[1]->op_type
& (AllReg
))
1864 insn
.opcode
|= (insn
.operand_type
[1]->reg
.opcode
);
1865 insn
.opcode
|= PC_Register
;
1866 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1868 else if (insn
.operand_type
[1]->immediate
.resolved
== 1)
1870 if (insn
.operand_type
[0]->immediate
.decimal_found
)
1872 as_bad ("first operand is floating point");
1875 if (insn
.operand_type
[0]->immediate
.s_number
< -32768 ||
1876 insn
.operand_type
[0]->immediate
.s_number
> 32767)
1878 as_bad ("first operand is too large for 16-bit signed int");
1881 insn
.opcode
|= (insn
.operand_type
[1]->immediate
.s_number
);
1882 insn
.opcode
|= PC_Relative
;
1883 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1887 insn
.opcode
|= PC_Relative
;
1888 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1889 fix_new_exp (frag_now
, p
+ 2 - frag_now
->fr_literal
, 2,
1890 & insn
.operand_type
[1]->immediate
.imm_expr
,
1895 else if (insn
.tm
->operand_types
[0] == IVector
)
1897 /* Trap instructions. */
1898 if (insn
.operand_type
[0]->op_type
& IVector
)
1899 insn
.opcode
|= (insn
.operand_type
[0]->immediate
.u_number
);
1902 /* Shouldn't get here. */
1903 as_bad ("interrupt vector for trap instruction out of range");
1906 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1908 else if (insn
.tm
->opcode_modifier
== StackOp
1909 || insn
.tm
->opcode_modifier
== Rotate
)
1911 /* Push, Pop and Rotate instructions. */
1912 insn
.opcode
|= (insn
.operand_type
[0]->reg
.opcode
<< 16);
1913 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1915 else if ((insn
.tm
->operand_types
[0] & (Abs24
| Direct
))
1916 == (Abs24
| Direct
))
1918 /* LDP Instruction needs to be tested
1919 for before the next section. */
1920 if (insn
.operand_type
[0]->op_type
& Direct
)
1922 if (insn
.operand_type
[0]->direct
.resolved
== 1)
1924 /* Direct addressing uses lower 8 bits of direct address. */
1926 (insn
.operand_type
[0]->direct
.address
& 0x00FF0000) >> 16;
1927 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1933 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1934 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1935 1, &insn
.operand_type
[0]->direct
.direct_expr
, 0, 0);
1936 /* Ensure that the assembler doesn't complain
1937 about fitting a 24-bit address into 8 bits. */
1938 fix
->fx_no_overflow
= 1;
1943 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1945 /* Immediate addressing uses upper 8 bits of address. */
1946 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1948 as_bad ("LDP instruction needs a 24-bit operand");
1952 ((insn
.operand_type
[0]->immediate
.u_number
& 0x00FF0000) >> 16);
1953 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1958 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1959 fix
= fix_new_exp (frag_now
, p
+ 3 - (frag_now
->fr_literal
),
1960 1, &insn
.operand_type
[0]->immediate
.imm_expr
,
1962 fix
->fx_no_overflow
= 1;
1966 else if (insn
.tm
->operand_types
[0] & (Imm24
))
1968 /* Unconditional Branch and Call instructions. */
1969 if (insn
.operand_type
[0]->immediate
.resolved
== 1)
1971 if (insn
.operand_type
[0]->immediate
.u_number
> 0x00FFFFFF)
1972 as_warn ("first operand is too large for a 24-bit displacement");
1974 (insn
.operand_type
[0]->immediate
.u_number
& 0x00FFFFFF);
1975 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1979 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1980 fix_new_exp (frag_now
, p
+ 1 - (frag_now
->fr_literal
), 3,
1981 & insn
.operand_type
[0]->immediate
.imm_expr
, 0, 0);
1984 else if (insn
.tm
->operand_types
[0] & NotReq
)
1985 /* Check for NOP instruction without arguments. */
1986 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1988 else if (insn
.tm
->operands
== 0)
1989 /* Check for instructions without operands. */
1990 md_number_to_chars (p
, (valueT
) insn
.opcode
, INSN_SIZE
);
1992 debug ("Addressing mode: %08X\n", insn
.addressing_mode
);
1996 for (i
= 0; i
< insn
.operands
; i
++)
1998 if (insn
.operand_type
[i
]->immediate
.label
)
1999 free (insn
.operand_type
[i
]->immediate
.label
);
2000 free (insn
.operand_type
[i
]);
2003 debug ("Final opcode: %08X\n", insn
.opcode
);