tc-tic30.c revision 1.1.1.6.2.1 1 1.1 skrll /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2 1.1.1.6.2.1 martin Copyright (C) 1998-2020 Free Software Foundation, Inc.
3 1.1 skrll Contributed by Steven Haworth (steve (at) pm.cse.rmit.edu.au)
4 1.1 skrll
5 1.1 skrll This file is part of GAS, the GNU Assembler.
6 1.1 skrll
7 1.1 skrll GAS is free software; you can redistribute it and/or modify
8 1.1 skrll it under the terms of the GNU General Public License as published by
9 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
10 1.1 skrll any later version.
11 1.1 skrll
12 1.1 skrll GAS is distributed in the hope that it will be useful,
13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 skrll GNU General Public License for more details.
16 1.1 skrll
17 1.1 skrll You should have received a copy of the GNU General Public License
18 1.1 skrll along with GAS; see the file COPYING. If not, write to the Free
19 1.1 skrll Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 1.1 skrll 02110-1301, USA. */
21 1.1 skrll
22 1.1 skrll /* Texas Instruments TMS320C30 machine specific gas.
23 1.1 skrll Written by Steven Haworth (steve (at) pm.cse.rmit.edu.au).
24 1.1 skrll Bugs & suggestions are completely welcome. This is free software.
25 1.1 skrll Please help us make it better. */
26 1.1 skrll
27 1.1 skrll #include "as.h"
28 1.1 skrll #include "safe-ctype.h"
29 1.1 skrll #include "opcode/tic30.h"
30 1.1 skrll
31 1.1 skrll /* Put here all non-digit non-letter characters that may occur in an
32 1.1 skrll operand. */
33 1.1 skrll static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
34 1.1.1.5 christos static const char *ordinal_names[] =
35 1.1 skrll {
36 1.1.1.3 christos N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
37 1.1 skrll };
38 1.1 skrll
39 1.1 skrll const char comment_chars[] = ";";
40 1.1 skrll const char line_comment_chars[] = "*";
41 1.1 skrll const char line_separator_chars[] = "";
42 1.1 skrll
43 1.1 skrll const char *md_shortopts = "";
44 1.1 skrll struct option md_longopts[] =
45 1.1 skrll {
46 1.1 skrll {NULL, no_argument, NULL, 0}
47 1.1 skrll };
48 1.1 skrll
49 1.1 skrll size_t md_longopts_size = sizeof (md_longopts);
50 1.1 skrll
51 1.1 skrll /* Chars that mean this number is a floating point constant.
52 1.1 skrll As in 0f12.456
53 1.1 skrll or 0d1.2345e12. */
54 1.1 skrll const char FLT_CHARS[] = "fFdDxX";
55 1.1 skrll
56 1.1 skrll /* Chars that can be used to separate mant from exp in floating point
57 1.1 skrll nums. */
58 1.1 skrll const char EXP_CHARS[] = "eE";
59 1.1 skrll
60 1.1 skrll /* Tables for lexical analysis. */
61 1.1 skrll static char opcode_chars[256];
62 1.1 skrll static char register_chars[256];
63 1.1 skrll static char operand_chars[256];
64 1.1 skrll static char space_chars[256];
65 1.1 skrll static char identifier_chars[256];
66 1.1 skrll static char digit_chars[256];
67 1.1 skrll
68 1.1 skrll /* Lexical macros. */
69 1.1 skrll #define is_opcode_char(x) (opcode_chars [(unsigned char) x])
70 1.1 skrll #define is_operand_char(x) (operand_chars [(unsigned char) x])
71 1.1 skrll #define is_register_char(x) (register_chars [(unsigned char) x])
72 1.1 skrll #define is_space_char(x) (space_chars [(unsigned char) x])
73 1.1 skrll #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
74 1.1 skrll #define is_digit_char(x) (digit_chars [(unsigned char) x])
75 1.1 skrll
76 1.1 skrll const pseudo_typeS md_pseudo_table[] =
77 1.1 skrll {
78 1.1 skrll {0, 0, 0}
79 1.1 skrll };
80 1.1 skrll
81 1.1 skrll static int ATTRIBUTE_PRINTF_1
82 1.1 skrll debug (const char *string, ...)
83 1.1 skrll {
84 1.1 skrll if (flag_debug)
85 1.1 skrll {
86 1.1 skrll char str[100];
87 1.1.1.4 christos va_list argptr;
88 1.1 skrll
89 1.1.1.4 christos va_start (argptr, string);
90 1.1 skrll vsprintf (str, string, argptr);
91 1.1.1.4 christos va_end (argptr);
92 1.1 skrll if (str[0] == '\0')
93 1.1 skrll return (0);
94 1.1 skrll fputs (str, USE_STDOUT ? stdout : stderr);
95 1.1 skrll return strlen (str);
96 1.1 skrll }
97 1.1 skrll else
98 1.1 skrll return 0;
99 1.1 skrll }
100 1.1 skrll
101 1.1 skrll /* Hash table for opcode lookup. */
102 1.1 skrll static struct hash_control *op_hash;
103 1.1 skrll /* Hash table for parallel opcode lookup. */
104 1.1 skrll static struct hash_control *parop_hash;
105 1.1 skrll /* Hash table for register lookup. */
106 1.1 skrll static struct hash_control *reg_hash;
107 1.1 skrll /* Hash table for indirect addressing lookup. */
108 1.1 skrll static struct hash_control *ind_hash;
109 1.1 skrll
110 1.1 skrll void
111 1.1 skrll md_begin (void)
112 1.1 skrll {
113 1.1 skrll const char *hash_err;
114 1.1 skrll
115 1.1 skrll debug ("In md_begin()\n");
116 1.1 skrll op_hash = hash_new ();
117 1.1 skrll
118 1.1 skrll {
119 1.1.1.2 christos const insn_template *current_optab = tic30_optab;
120 1.1 skrll
121 1.1 skrll for (; current_optab < tic30_optab_end; current_optab++)
122 1.1 skrll {
123 1.1 skrll hash_err = hash_insert (op_hash, current_optab->name,
124 1.1 skrll (char *) current_optab);
125 1.1 skrll if (hash_err)
126 1.1 skrll as_fatal ("Internal Error: Can't Hash %s: %s",
127 1.1 skrll current_optab->name, hash_err);
128 1.1 skrll }
129 1.1 skrll }
130 1.1 skrll
131 1.1 skrll parop_hash = hash_new ();
132 1.1 skrll
133 1.1 skrll {
134 1.1 skrll const partemplate *current_parop = tic30_paroptab;
135 1.1 skrll
136 1.1 skrll for (; current_parop < tic30_paroptab_end; current_parop++)
137 1.1 skrll {
138 1.1 skrll hash_err = hash_insert (parop_hash, current_parop->name,
139 1.1 skrll (char *) current_parop);
140 1.1 skrll if (hash_err)
141 1.1 skrll as_fatal ("Internal Error: Can't Hash %s: %s",
142 1.1 skrll current_parop->name, hash_err);
143 1.1 skrll }
144 1.1 skrll }
145 1.1 skrll
146 1.1 skrll reg_hash = hash_new ();
147 1.1 skrll
148 1.1 skrll {
149 1.1 skrll const reg *current_reg = tic30_regtab;
150 1.1 skrll
151 1.1 skrll for (; current_reg < tic30_regtab_end; current_reg++)
152 1.1 skrll {
153 1.1 skrll hash_err = hash_insert (reg_hash, current_reg->name,
154 1.1 skrll (char *) current_reg);
155 1.1 skrll if (hash_err)
156 1.1 skrll as_fatal ("Internal Error: Can't Hash %s: %s",
157 1.1 skrll current_reg->name, hash_err);
158 1.1 skrll }
159 1.1 skrll }
160 1.1 skrll
161 1.1 skrll ind_hash = hash_new ();
162 1.1 skrll
163 1.1 skrll {
164 1.1 skrll const ind_addr_type *current_ind = tic30_indaddr_tab;
165 1.1 skrll
166 1.1 skrll for (; current_ind < tic30_indaddrtab_end; current_ind++)
167 1.1 skrll {
168 1.1 skrll hash_err = hash_insert (ind_hash, current_ind->syntax,
169 1.1 skrll (char *) current_ind);
170 1.1 skrll if (hash_err)
171 1.1 skrll as_fatal ("Internal Error: Can't Hash %s: %s",
172 1.1 skrll current_ind->syntax, hash_err);
173 1.1 skrll }
174 1.1 skrll }
175 1.1 skrll
176 1.1 skrll /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
177 1.1 skrll {
178 1.1 skrll int c;
179 1.1 skrll char *p;
180 1.1 skrll
181 1.1 skrll for (c = 0; c < 256; c++)
182 1.1 skrll {
183 1.1 skrll if (ISLOWER (c) || ISDIGIT (c))
184 1.1 skrll {
185 1.1 skrll opcode_chars[c] = c;
186 1.1 skrll register_chars[c] = c;
187 1.1 skrll }
188 1.1 skrll else if (ISUPPER (c))
189 1.1 skrll {
190 1.1 skrll opcode_chars[c] = TOLOWER (c);
191 1.1 skrll register_chars[c] = opcode_chars[c];
192 1.1 skrll }
193 1.1 skrll else if (c == ')' || c == '(')
194 1.1 skrll register_chars[c] = c;
195 1.1 skrll
196 1.1 skrll if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
197 1.1 skrll operand_chars[c] = c;
198 1.1 skrll
199 1.1 skrll if (ISDIGIT (c) || c == '-')
200 1.1 skrll digit_chars[c] = c;
201 1.1 skrll
202 1.1 skrll if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
203 1.1 skrll identifier_chars[c] = c;
204 1.1 skrll
205 1.1 skrll if (c == ' ' || c == '\t')
206 1.1 skrll space_chars[c] = c;
207 1.1 skrll
208 1.1 skrll if (c == '_')
209 1.1 skrll opcode_chars[c] = c;
210 1.1 skrll }
211 1.1 skrll for (p = operand_special_chars; *p != '\0'; p++)
212 1.1 skrll operand_chars[(unsigned char) *p] = *p;
213 1.1 skrll }
214 1.1 skrll }
215 1.1 skrll
216 1.1 skrll /* Address Mode OR values. */
217 1.1 skrll #define AM_Register 0x00000000
218 1.1 skrll #define AM_Direct 0x00200000
219 1.1 skrll #define AM_Indirect 0x00400000
220 1.1 skrll #define AM_Immediate 0x00600000
221 1.1 skrll #define AM_NotReq 0xFFFFFFFF
222 1.1 skrll
223 1.1 skrll /* PC Relative OR values. */
224 1.1 skrll #define PC_Register 0x00000000
225 1.1 skrll #define PC_Relative 0x02000000
226 1.1 skrll
227 1.1 skrll typedef struct
228 1.1 skrll {
229 1.1 skrll unsigned op_type;
230 1.1 skrll struct
231 1.1 skrll {
232 1.1 skrll int resolved;
233 1.1 skrll unsigned address;
234 1.1 skrll char *label;
235 1.1 skrll expressionS direct_expr;
236 1.1 skrll } direct;
237 1.1 skrll struct
238 1.1 skrll {
239 1.1 skrll unsigned mod;
240 1.1 skrll int ARnum;
241 1.1 skrll unsigned char disp;
242 1.1 skrll } indirect;
243 1.1 skrll struct
244 1.1 skrll {
245 1.1 skrll unsigned opcode;
246 1.1 skrll } reg;
247 1.1 skrll struct
248 1.1 skrll {
249 1.1 skrll int resolved;
250 1.1 skrll int decimal_found;
251 1.1 skrll float f_number;
252 1.1 skrll int s_number;
253 1.1 skrll unsigned int u_number;
254 1.1 skrll char *label;
255 1.1 skrll expressionS imm_expr;
256 1.1 skrll } immediate;
257 1.1 skrll } operand;
258 1.1 skrll
259 1.1.1.2 christos insn_template *opcode;
260 1.1 skrll
261 1.1 skrll struct tic30_insn
262 1.1 skrll {
263 1.1.1.2 christos insn_template *tm; /* Template of current instruction. */
264 1.1 skrll unsigned opcode; /* Final opcode. */
265 1.1 skrll unsigned int operands; /* Number of given operands. */
266 1.1 skrll /* Type of operand given in instruction. */
267 1.1 skrll operand *operand_type[MAX_OPERANDS];
268 1.1 skrll unsigned addressing_mode; /* Final addressing mode of instruction. */
269 1.1 skrll };
270 1.1 skrll
271 1.1 skrll struct tic30_insn insn;
272 1.1 skrll static int found_parallel_insn;
273 1.1 skrll
274 1.1 skrll static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
275 1.1 skrll
276 1.1 skrll static char *
277 1.1 skrll output_invalid (char c)
278 1.1 skrll {
279 1.1 skrll if (ISPRINT (c))
280 1.1 skrll snprintf (output_invalid_buf, sizeof (output_invalid_buf),
281 1.1 skrll "'%c'", c);
282 1.1 skrll else
283 1.1.1.4 christos snprintf (output_invalid_buf, sizeof (output_invalid_buf),
284 1.1 skrll "(0x%x)", (unsigned char) c);
285 1.1 skrll return output_invalid_buf;
286 1.1 skrll }
287 1.1 skrll
288 1.1 skrll /* next_line points to the next line after the current instruction
289 1.1 skrll (current_line). Search for the parallel bars, and if found, merge two
290 1.1 skrll lines into internal syntax for a parallel instruction:
291 1.1 skrll q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
292 1.1 skrll By this stage, all comments are scrubbed, and only the bare lines are
293 1.1 skrll given. */
294 1.1 skrll
295 1.1 skrll #define NONE 0
296 1.1 skrll #define START_OPCODE 1
297 1.1 skrll #define END_OPCODE 2
298 1.1 skrll #define START_OPERANDS 3
299 1.1 skrll #define END_OPERANDS 4
300 1.1 skrll
301 1.1 skrll static char *
302 1.1 skrll tic30_find_parallel_insn (char *current_line, char *next_line)
303 1.1 skrll {
304 1.1 skrll int found_parallel = 0;
305 1.1 skrll char first_opcode[256];
306 1.1 skrll char second_opcode[256];
307 1.1 skrll char first_operands[256];
308 1.1 skrll char second_operands[256];
309 1.1 skrll char *parallel_insn;
310 1.1 skrll
311 1.1 skrll debug ("In tic30_find_parallel_insn()\n");
312 1.1 skrll while (!is_end_of_line[(unsigned char) *next_line])
313 1.1 skrll {
314 1.1 skrll if (*next_line == PARALLEL_SEPARATOR
315 1.1 skrll && *(next_line + 1) == PARALLEL_SEPARATOR)
316 1.1 skrll {
317 1.1 skrll found_parallel = 1;
318 1.1 skrll next_line++;
319 1.1 skrll break;
320 1.1 skrll }
321 1.1 skrll next_line++;
322 1.1 skrll }
323 1.1 skrll if (!found_parallel)
324 1.1 skrll return NULL;
325 1.1 skrll debug ("Found a parallel instruction\n");
326 1.1 skrll
327 1.1 skrll {
328 1.1 skrll int i;
329 1.1.1.2 christos char *op, *operands, *line;
330 1.1 skrll
331 1.1 skrll for (i = 0; i < 2; i++)
332 1.1 skrll {
333 1.1 skrll if (i == 0)
334 1.1 skrll {
335 1.1.1.2 christos op = &first_opcode[0];
336 1.1 skrll operands = &first_operands[0];
337 1.1 skrll line = current_line;
338 1.1 skrll }
339 1.1 skrll else
340 1.1 skrll {
341 1.1.1.2 christos op = &second_opcode[0];
342 1.1 skrll operands = &second_operands[0];
343 1.1 skrll line = next_line;
344 1.1 skrll }
345 1.1 skrll
346 1.1 skrll {
347 1.1 skrll int search_status = NONE;
348 1.1 skrll int char_ptr = 0;
349 1.1 skrll char c;
350 1.1 skrll
351 1.1 skrll while (!is_end_of_line[(unsigned char) (c = *line)])
352 1.1 skrll {
353 1.1 skrll if (is_opcode_char (c) && search_status == NONE)
354 1.1 skrll {
355 1.1.1.2 christos op[char_ptr++] = TOLOWER (c);
356 1.1 skrll search_status = START_OPCODE;
357 1.1 skrll }
358 1.1 skrll else if (is_opcode_char (c) && search_status == START_OPCODE)
359 1.1.1.2 christos op[char_ptr++] = TOLOWER (c);
360 1.1 skrll else if (!is_opcode_char (c) && search_status == START_OPCODE)
361 1.1 skrll {
362 1.1.1.2 christos op[char_ptr] = '\0';
363 1.1 skrll char_ptr = 0;
364 1.1 skrll search_status = END_OPCODE;
365 1.1 skrll }
366 1.1 skrll else if (is_operand_char (c) && search_status == START_OPERANDS)
367 1.1 skrll operands[char_ptr++] = c;
368 1.1 skrll
369 1.1 skrll if (is_operand_char (c) && search_status == END_OPCODE)
370 1.1 skrll {
371 1.1 skrll operands[char_ptr++] = c;
372 1.1 skrll search_status = START_OPERANDS;
373 1.1 skrll }
374 1.1 skrll
375 1.1 skrll line++;
376 1.1 skrll }
377 1.1 skrll if (search_status != START_OPERANDS)
378 1.1 skrll return NULL;
379 1.1 skrll operands[char_ptr] = '\0';
380 1.1 skrll }
381 1.1 skrll }
382 1.1 skrll }
383 1.1.1.5 christos
384 1.1.1.5 christos parallel_insn = concat ("q_", first_opcode, "_", second_opcode, " ",
385 1.1.1.5 christos first_operands, " | ", second_operands,
386 1.1.1.5 christos (char *) NULL);
387 1.1 skrll debug ("parallel insn = %s\n", parallel_insn);
388 1.1 skrll return parallel_insn;
389 1.1 skrll }
390 1.1 skrll
391 1.1 skrll #undef NONE
392 1.1 skrll #undef START_OPCODE
393 1.1 skrll #undef END_OPCODE
394 1.1 skrll #undef START_OPERANDS
395 1.1 skrll #undef END_OPERANDS
396 1.1 skrll
397 1.1 skrll static operand *
398 1.1 skrll tic30_operand (char *token)
399 1.1 skrll {
400 1.1 skrll unsigned int count;
401 1.1 skrll operand *current_op;
402 1.1 skrll
403 1.1 skrll debug ("In tic30_operand with %s\n", token);
404 1.1.1.5 christos current_op = XCNEW (operand);
405 1.1 skrll
406 1.1 skrll if (*token == DIRECT_REFERENCE)
407 1.1 skrll {
408 1.1 skrll char *token_posn = token + 1;
409 1.1 skrll int direct_label = 0;
410 1.1 skrll
411 1.1 skrll debug ("Found direct reference\n");
412 1.1 skrll while (*token_posn)
413 1.1 skrll {
414 1.1 skrll if (!is_digit_char (*token_posn))
415 1.1 skrll direct_label = 1;
416 1.1 skrll token_posn++;
417 1.1 skrll }
418 1.1 skrll
419 1.1 skrll if (direct_label)
420 1.1 skrll {
421 1.1 skrll char *save_input_line_pointer;
422 1.1 skrll segT retval;
423 1.1 skrll
424 1.1 skrll debug ("Direct reference is a label\n");
425 1.1 skrll current_op->direct.label = token + 1;
426 1.1 skrll save_input_line_pointer = input_line_pointer;
427 1.1 skrll input_line_pointer = token + 1;
428 1.1 skrll debug ("Current input_line_pointer: %s\n", input_line_pointer);
429 1.1 skrll retval = expression (¤t_op->direct.direct_expr);
430 1.1 skrll
431 1.1 skrll debug ("Expression type: %d\n",
432 1.1 skrll current_op->direct.direct_expr.X_op);
433 1.1 skrll debug ("Expression addnum: %ld\n",
434 1.1 skrll (long) current_op->direct.direct_expr.X_add_number);
435 1.1 skrll debug ("Segment: %p\n", retval);
436 1.1 skrll
437 1.1 skrll input_line_pointer = save_input_line_pointer;
438 1.1 skrll
439 1.1 skrll if (current_op->direct.direct_expr.X_op == O_constant)
440 1.1 skrll {
441 1.1 skrll current_op->direct.address =
442 1.1 skrll current_op->direct.direct_expr.X_add_number;
443 1.1 skrll current_op->direct.resolved = 1;
444 1.1 skrll }
445 1.1 skrll }
446 1.1 skrll else
447 1.1 skrll {
448 1.1 skrll debug ("Direct reference is a number\n");
449 1.1 skrll current_op->direct.address = atoi (token + 1);
450 1.1 skrll current_op->direct.resolved = 1;
451 1.1 skrll }
452 1.1 skrll current_op->op_type = Direct;
453 1.1 skrll }
454 1.1 skrll else if (*token == INDIRECT_REFERENCE)
455 1.1 skrll {
456 1.1 skrll /* Indirect reference operand. */
457 1.1 skrll int found_ar = 0;
458 1.1 skrll int found_disp = 0;
459 1.1 skrll int ar_number = -1;
460 1.1 skrll int disp_number = 0;
461 1.1 skrll int buffer_posn = 1;
462 1.1 skrll ind_addr_type *ind_addr_op;
463 1.1.1.5 christos char * ind_buffer;
464 1.1.1.5 christos
465 1.1.1.5 christos ind_buffer = XNEWVEC (char, strlen (token));
466 1.1 skrll
467 1.1 skrll debug ("Found indirect reference\n");
468 1.1 skrll ind_buffer[0] = *token;
469 1.1 skrll
470 1.1 skrll for (count = 1; count < strlen (token); count++)
471 1.1 skrll {
472 1.1 skrll /* Strip operand. */
473 1.1 skrll ind_buffer[buffer_posn] = TOLOWER (*(token + count));
474 1.1 skrll
475 1.1 skrll if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
476 1.1 skrll && (*(token + count) == 'r' || *(token + count) == 'R'))
477 1.1 skrll {
478 1.1 skrll /* AR reference is found, so get its number and remove
479 1.1 skrll it from the buffer so it can pass through hash_find(). */
480 1.1 skrll if (found_ar)
481 1.1 skrll {
482 1.1.1.2 christos as_bad (_("More than one AR register found in indirect reference"));
483 1.1.1.5 christos free (ind_buffer);
484 1.1 skrll return NULL;
485 1.1 skrll }
486 1.1 skrll if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
487 1.1 skrll {
488 1.1.1.2 christos as_bad (_("Illegal AR register in indirect reference"));
489 1.1.1.5 christos free (ind_buffer);
490 1.1 skrll return NULL;
491 1.1 skrll }
492 1.1 skrll ar_number = *(token + count + 1) - '0';
493 1.1 skrll found_ar = 1;
494 1.1 skrll count++;
495 1.1 skrll }
496 1.1 skrll
497 1.1 skrll if (*(token + count) == '(')
498 1.1 skrll {
499 1.1 skrll /* Parenthesis found, so check if a displacement value is
500 1.1 skrll inside. If so, get the value and remove it from the
501 1.1 skrll buffer. */
502 1.1 skrll if (is_digit_char (*(token + count + 1)))
503 1.1 skrll {
504 1.1 skrll char disp[10];
505 1.1 skrll int disp_posn = 0;
506 1.1 skrll
507 1.1 skrll if (found_disp)
508 1.1 skrll {
509 1.1.1.2 christos as_bad (_("More than one displacement found in indirect reference"));
510 1.1.1.5 christos free (ind_buffer);
511 1.1 skrll return NULL;
512 1.1 skrll }
513 1.1 skrll count++;
514 1.1 skrll while (*(token + count) != ')')
515 1.1 skrll {
516 1.1 skrll if (!is_digit_char (*(token + count)))
517 1.1 skrll {
518 1.1.1.2 christos as_bad (_("Invalid displacement in indirect reference"));
519 1.1.1.5 christos free (ind_buffer);
520 1.1 skrll return NULL;
521 1.1 skrll }
522 1.1 skrll disp[disp_posn++] = *(token + (count++));
523 1.1 skrll }
524 1.1 skrll disp[disp_posn] = '\0';
525 1.1 skrll disp_number = atoi (disp);
526 1.1 skrll count--;
527 1.1 skrll found_disp = 1;
528 1.1 skrll }
529 1.1 skrll }
530 1.1 skrll buffer_posn++;
531 1.1 skrll }
532 1.1 skrll
533 1.1 skrll ind_buffer[buffer_posn] = '\0';
534 1.1 skrll if (!found_ar)
535 1.1 skrll {
536 1.1.1.2 christos as_bad (_("AR register not found in indirect reference"));
537 1.1.1.5 christos free (ind_buffer);
538 1.1 skrll return NULL;
539 1.1 skrll }
540 1.1 skrll
541 1.1 skrll ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
542 1.1 skrll if (ind_addr_op)
543 1.1 skrll {
544 1.1 skrll debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
545 1.1 skrll if (ind_addr_op->displacement == IMPLIED_DISP)
546 1.1 skrll {
547 1.1 skrll found_disp = 1;
548 1.1 skrll disp_number = 1;
549 1.1 skrll }
550 1.1 skrll else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
551 1.1 skrll {
552 1.1 skrll /* Maybe an implied displacement of 1 again. */
553 1.1.1.2 christos as_bad (_("required displacement wasn't given in indirect reference"));
554 1.1.1.5 christos free (ind_buffer);
555 1.1.1.5 christos return NULL;
556 1.1 skrll }
557 1.1 skrll }
558 1.1 skrll else
559 1.1 skrll {
560 1.1.1.2 christos as_bad (_("illegal indirect reference"));
561 1.1.1.5 christos free (ind_buffer);
562 1.1 skrll return NULL;
563 1.1 skrll }
564 1.1 skrll
565 1.1 skrll if (found_disp && (disp_number < 0 || disp_number > 255))
566 1.1 skrll {
567 1.1.1.2 christos as_bad (_("displacement must be an unsigned 8-bit number"));
568 1.1.1.5 christos free (ind_buffer);
569 1.1 skrll return NULL;
570 1.1 skrll }
571 1.1 skrll
572 1.1 skrll current_op->indirect.mod = ind_addr_op->modfield;
573 1.1 skrll current_op->indirect.disp = disp_number;
574 1.1 skrll current_op->indirect.ARnum = ar_number;
575 1.1 skrll current_op->op_type = Indirect;
576 1.1.1.5 christos free (ind_buffer);
577 1.1 skrll }
578 1.1 skrll else
579 1.1 skrll {
580 1.1 skrll reg *regop = (reg *) hash_find (reg_hash, token);
581 1.1 skrll
582 1.1 skrll if (regop)
583 1.1 skrll {
584 1.1 skrll debug ("Found register operand: %s\n", regop->name);
585 1.1 skrll if (regop->regtype == REG_ARn)
586 1.1 skrll current_op->op_type = ARn;
587 1.1 skrll else if (regop->regtype == REG_Rn)
588 1.1 skrll current_op->op_type = Rn;
589 1.1 skrll else if (regop->regtype == REG_DP)
590 1.1 skrll current_op->op_type = DPReg;
591 1.1 skrll else
592 1.1 skrll current_op->op_type = OtherReg;
593 1.1 skrll current_op->reg.opcode = regop->opcode;
594 1.1 skrll }
595 1.1 skrll else
596 1.1 skrll {
597 1.1 skrll if (!is_digit_char (*token)
598 1.1 skrll || *(token + 1) == 'x'
599 1.1 skrll || strchr (token, 'h'))
600 1.1 skrll {
601 1.1 skrll char *save_input_line_pointer;
602 1.1 skrll segT retval;
603 1.1 skrll
604 1.1 skrll debug ("Probably a label: %s\n", token);
605 1.1.1.5 christos current_op->immediate.label = xstrdup (token);
606 1.1 skrll save_input_line_pointer = input_line_pointer;
607 1.1 skrll input_line_pointer = token;
608 1.1 skrll
609 1.1 skrll debug ("Current input_line_pointer: %s\n", input_line_pointer);
610 1.1 skrll retval = expression (¤t_op->immediate.imm_expr);
611 1.1 skrll debug ("Expression type: %d\n",
612 1.1 skrll current_op->immediate.imm_expr.X_op);
613 1.1 skrll debug ("Expression addnum: %ld\n",
614 1.1 skrll (long) current_op->immediate.imm_expr.X_add_number);
615 1.1 skrll debug ("Segment: %p\n", retval);
616 1.1 skrll input_line_pointer = save_input_line_pointer;
617 1.1 skrll
618 1.1 skrll if (current_op->immediate.imm_expr.X_op == O_constant)
619 1.1 skrll {
620 1.1 skrll current_op->immediate.s_number
621 1.1 skrll = current_op->immediate.imm_expr.X_add_number;
622 1.1 skrll current_op->immediate.u_number
623 1.1 skrll = (unsigned int) current_op->immediate.imm_expr.X_add_number;
624 1.1 skrll current_op->immediate.resolved = 1;
625 1.1 skrll }
626 1.1 skrll }
627 1.1 skrll else
628 1.1 skrll {
629 1.1 skrll debug ("Found a number or displacement\n");
630 1.1 skrll for (count = 0; count < strlen (token); count++)
631 1.1 skrll if (*(token + count) == '.')
632 1.1 skrll current_op->immediate.decimal_found = 1;
633 1.1.1.5 christos current_op->immediate.label = xstrdup (token);
634 1.1 skrll current_op->immediate.f_number = (float) atof (token);
635 1.1 skrll current_op->immediate.s_number = (int) atoi (token);
636 1.1 skrll current_op->immediate.u_number = (unsigned int) atoi (token);
637 1.1 skrll current_op->immediate.resolved = 1;
638 1.1 skrll }
639 1.1 skrll current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
640 1.1 skrll if (current_op->immediate.u_number <= 31)
641 1.1 skrll current_op->op_type |= IVector;
642 1.1 skrll }
643 1.1 skrll }
644 1.1 skrll return current_op;
645 1.1 skrll }
646 1.1 skrll
647 1.1 skrll struct tic30_par_insn
648 1.1 skrll {
649 1.1 skrll partemplate *tm; /* Template of current parallel instruction. */
650 1.1 skrll unsigned operands[2]; /* Number of given operands for each insn. */
651 1.1 skrll /* Type of operand given in instruction. */
652 1.1 skrll operand *operand_type[2][MAX_OPERANDS];
653 1.1 skrll int swap_operands; /* Whether to swap operands around. */
654 1.1 skrll unsigned p_field; /* Value of p field in multiply add/sub instructions. */
655 1.1 skrll unsigned opcode; /* Final opcode. */
656 1.1 skrll };
657 1.1 skrll
658 1.1 skrll struct tic30_par_insn p_insn;
659 1.1 skrll
660 1.1 skrll static int
661 1.1 skrll tic30_parallel_insn (char *token)
662 1.1 skrll {
663 1.1 skrll static partemplate *p_opcode;
664 1.1 skrll char *current_posn = token;
665 1.1 skrll char *token_start;
666 1.1 skrll char save_char;
667 1.1 skrll
668 1.1 skrll debug ("In tic30_parallel_insn with %s\n", token);
669 1.1 skrll memset (&p_insn, '\0', sizeof (p_insn));
670 1.1 skrll
671 1.1 skrll while (is_opcode_char (*current_posn))
672 1.1 skrll current_posn++;
673 1.1 skrll {
674 1.1 skrll /* Find instruction. */
675 1.1 skrll save_char = *current_posn;
676 1.1 skrll *current_posn = '\0';
677 1.1 skrll p_opcode = (partemplate *) hash_find (parop_hash, token);
678 1.1 skrll if (p_opcode)
679 1.1 skrll {
680 1.1 skrll debug ("Found instruction %s\n", p_opcode->name);
681 1.1 skrll p_insn.tm = p_opcode;
682 1.1 skrll }
683 1.1 skrll else
684 1.1 skrll {
685 1.1 skrll char first_opcode[6] = {0};
686 1.1 skrll char second_opcode[6] = {0};
687 1.1 skrll unsigned int i;
688 1.1 skrll int current_opcode = -1;
689 1.1 skrll int char_ptr = 0;
690 1.1 skrll
691 1.1 skrll for (i = 0; i < strlen (token); i++)
692 1.1 skrll {
693 1.1 skrll char ch = *(token + i);
694 1.1 skrll
695 1.1 skrll if (ch == '_' && current_opcode == -1)
696 1.1 skrll {
697 1.1 skrll current_opcode = 0;
698 1.1 skrll continue;
699 1.1 skrll }
700 1.1 skrll
701 1.1 skrll if (ch == '_' && current_opcode == 0)
702 1.1 skrll {
703 1.1 skrll current_opcode = 1;
704 1.1 skrll char_ptr = 0;
705 1.1 skrll continue;
706 1.1 skrll }
707 1.1 skrll
708 1.1 skrll switch (current_opcode)
709 1.1 skrll {
710 1.1 skrll case 0:
711 1.1 skrll first_opcode[char_ptr++] = ch;
712 1.1 skrll break;
713 1.1 skrll case 1:
714 1.1 skrll second_opcode[char_ptr++] = ch;
715 1.1 skrll break;
716 1.1 skrll }
717 1.1 skrll }
718 1.1 skrll
719 1.1 skrll debug ("first_opcode = %s\n", first_opcode);
720 1.1 skrll debug ("second_opcode = %s\n", second_opcode);
721 1.1 skrll sprintf (token, "q_%s_%s", second_opcode, first_opcode);
722 1.1 skrll p_opcode = (partemplate *) hash_find (parop_hash, token);
723 1.1 skrll
724 1.1 skrll if (p_opcode)
725 1.1 skrll {
726 1.1 skrll debug ("Found instruction %s\n", p_opcode->name);
727 1.1 skrll p_insn.tm = p_opcode;
728 1.1 skrll p_insn.swap_operands = 1;
729 1.1 skrll }
730 1.1 skrll else
731 1.1 skrll return 0;
732 1.1 skrll }
733 1.1 skrll *current_posn = save_char;
734 1.1 skrll }
735 1.1 skrll
736 1.1 skrll {
737 1.1 skrll /* Find operands. */
738 1.1 skrll int paren_not_balanced;
739 1.1 skrll int expecting_operand = 0;
740 1.1 skrll int found_separator = 0;
741 1.1 skrll
742 1.1 skrll do
743 1.1 skrll {
744 1.1 skrll /* Skip optional white space before operand. */
745 1.1 skrll while (!is_operand_char (*current_posn)
746 1.1 skrll && *current_posn != END_OF_INSN)
747 1.1 skrll {
748 1.1 skrll if (!is_space_char (*current_posn)
749 1.1 skrll && *current_posn != PARALLEL_SEPARATOR)
750 1.1 skrll {
751 1.1.1.2 christos as_bad (_("Invalid character %s before %s operand"),
752 1.1 skrll output_invalid (*current_posn),
753 1.1 skrll ordinal_names[insn.operands]);
754 1.1 skrll return 1;
755 1.1 skrll }
756 1.1 skrll if (*current_posn == PARALLEL_SEPARATOR)
757 1.1 skrll found_separator = 1;
758 1.1 skrll current_posn++;
759 1.1 skrll }
760 1.1 skrll
761 1.1 skrll token_start = current_posn;
762 1.1 skrll paren_not_balanced = 0;
763 1.1 skrll
764 1.1 skrll while (paren_not_balanced || *current_posn != ',')
765 1.1 skrll {
766 1.1 skrll if (*current_posn == END_OF_INSN)
767 1.1 skrll {
768 1.1 skrll if (paren_not_balanced)
769 1.1 skrll {
770 1.1.1.2 christos as_bad (_("Unbalanced parenthesis in %s operand."),
771 1.1 skrll ordinal_names[insn.operands]);
772 1.1 skrll return 1;
773 1.1 skrll }
774 1.1 skrll else
775 1.1 skrll break;
776 1.1 skrll }
777 1.1 skrll else if (*current_posn == PARALLEL_SEPARATOR)
778 1.1 skrll {
779 1.1 skrll while (is_space_char (*(current_posn - 1)))
780 1.1 skrll current_posn--;
781 1.1 skrll break;
782 1.1 skrll }
783 1.1 skrll else if (!is_operand_char (*current_posn)
784 1.1 skrll && !is_space_char (*current_posn))
785 1.1 skrll {
786 1.1.1.2 christos as_bad (_("Invalid character %s in %s operand"),
787 1.1 skrll output_invalid (*current_posn),
788 1.1 skrll ordinal_names[insn.operands]);
789 1.1 skrll return 1;
790 1.1 skrll }
791 1.1 skrll
792 1.1 skrll if (*current_posn == '(')
793 1.1 skrll ++paren_not_balanced;
794 1.1 skrll if (*current_posn == ')')
795 1.1 skrll --paren_not_balanced;
796 1.1 skrll current_posn++;
797 1.1 skrll }
798 1.1 skrll
799 1.1 skrll if (current_posn != token_start)
800 1.1 skrll {
801 1.1 skrll /* Yes, we've read in another operand. */
802 1.1 skrll p_insn.operands[found_separator]++;
803 1.1 skrll if (p_insn.operands[found_separator] > MAX_OPERANDS)
804 1.1 skrll {
805 1.1.1.2 christos as_bad (_("Spurious operands; (%d operands/instruction max)"),
806 1.1 skrll MAX_OPERANDS);
807 1.1 skrll return 1;
808 1.1 skrll }
809 1.1 skrll
810 1.1 skrll /* Now parse operand adding info to 'insn' as we go along. */
811 1.1 skrll save_char = *current_posn;
812 1.1 skrll *current_posn = '\0';
813 1.1 skrll p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
814 1.1 skrll tic30_operand (token_start);
815 1.1 skrll *current_posn = save_char;
816 1.1 skrll if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
817 1.1 skrll return 1;
818 1.1 skrll }
819 1.1 skrll else
820 1.1 skrll {
821 1.1 skrll if (expecting_operand)
822 1.1 skrll {
823 1.1.1.2 christos as_bad (_("Expecting operand after ','; got nothing"));
824 1.1 skrll return 1;
825 1.1 skrll }
826 1.1 skrll if (*current_posn == ',')
827 1.1 skrll {
828 1.1.1.2 christos as_bad (_("Expecting operand before ','; got nothing"));
829 1.1 skrll return 1;
830 1.1 skrll }
831 1.1 skrll }
832 1.1 skrll
833 1.1 skrll /* Now *current_posn must be either ',' or END_OF_INSN. */
834 1.1 skrll if (*current_posn == ',')
835 1.1 skrll {
836 1.1 skrll if (*++current_posn == END_OF_INSN)
837 1.1 skrll {
838 1.1 skrll /* Just skip it, if it's \n complain. */
839 1.1.1.2 christos as_bad (_("Expecting operand after ','; got nothing"));
840 1.1 skrll return 1;
841 1.1 skrll }
842 1.1 skrll expecting_operand = 1;
843 1.1 skrll }
844 1.1 skrll }
845 1.1 skrll while (*current_posn != END_OF_INSN);
846 1.1 skrll }
847 1.1 skrll
848 1.1 skrll if (p_insn.swap_operands)
849 1.1 skrll {
850 1.1 skrll int temp_num, i;
851 1.1 skrll operand *temp_op;
852 1.1 skrll
853 1.1 skrll temp_num = p_insn.operands[0];
854 1.1 skrll p_insn.operands[0] = p_insn.operands[1];
855 1.1 skrll p_insn.operands[1] = temp_num;
856 1.1 skrll for (i = 0; i < MAX_OPERANDS; i++)
857 1.1 skrll {
858 1.1 skrll temp_op = p_insn.operand_type[0][i];
859 1.1 skrll p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
860 1.1 skrll p_insn.operand_type[1][i] = temp_op;
861 1.1 skrll }
862 1.1 skrll }
863 1.1 skrll
864 1.1 skrll if (p_insn.operands[0] != p_insn.tm->operands_1)
865 1.1 skrll {
866 1.1.1.2 christos as_bad (_("incorrect number of operands given in the first instruction"));
867 1.1 skrll return 1;
868 1.1 skrll }
869 1.1 skrll
870 1.1 skrll if (p_insn.operands[1] != p_insn.tm->operands_2)
871 1.1 skrll {
872 1.1.1.2 christos as_bad (_("incorrect number of operands given in the second instruction"));
873 1.1 skrll return 1;
874 1.1 skrll }
875 1.1 skrll
876 1.1 skrll debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
877 1.1 skrll debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
878 1.1 skrll
879 1.1 skrll {
880 1.1 skrll /* Now check if operands are correct. */
881 1.1 skrll int count;
882 1.1 skrll int num_rn = 0;
883 1.1 skrll int num_ind = 0;
884 1.1 skrll
885 1.1 skrll for (count = 0; count < 2; count++)
886 1.1 skrll {
887 1.1 skrll unsigned int i;
888 1.1 skrll for (i = 0; i < p_insn.operands[count]; i++)
889 1.1 skrll {
890 1.1 skrll if ((p_insn.operand_type[count][i]->op_type &
891 1.1 skrll p_insn.tm->operand_types[count][i]) == 0)
892 1.1 skrll {
893 1.1.1.2 christos as_bad (_("%s instruction, operand %d doesn't match"),
894 1.1 skrll ordinal_names[count], i + 1);
895 1.1 skrll return 1;
896 1.1 skrll }
897 1.1 skrll
898 1.1 skrll /* Get number of R register and indirect reference contained
899 1.1 skrll within the first two operands of each instruction. This is
900 1.1 skrll required for the multiply parallel instructions which require
901 1.1 skrll two R registers and two indirect references, but not in any
902 1.1 skrll particular place. */
903 1.1 skrll if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
904 1.1 skrll num_rn++;
905 1.1 skrll else if ((p_insn.operand_type[count][i]->op_type & Indirect)
906 1.1 skrll && i < 2)
907 1.1 skrll num_ind++;
908 1.1 skrll }
909 1.1 skrll }
910 1.1 skrll
911 1.1 skrll if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
912 1.1 skrll == (Indirect | Rn))
913 1.1 skrll {
914 1.1 skrll /* Check for the multiply instructions. */
915 1.1 skrll if (num_rn != 2)
916 1.1 skrll {
917 1.1.1.2 christos as_bad (_("incorrect format for multiply parallel instruction"));
918 1.1 skrll return 1;
919 1.1 skrll }
920 1.1 skrll
921 1.1 skrll if (num_ind != 2)
922 1.1 skrll {
923 1.1 skrll /* Shouldn't get here. */
924 1.1.1.2 christos as_bad (_("incorrect format for multiply parallel instruction"));
925 1.1 skrll return 1;
926 1.1 skrll }
927 1.1 skrll
928 1.1 skrll if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
929 1.1 skrll && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
930 1.1 skrll {
931 1.1.1.2 christos as_bad (_("destination for multiply can only be R0 or R1"));
932 1.1 skrll return 1;
933 1.1 skrll }
934 1.1 skrll
935 1.1 skrll if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
936 1.1 skrll && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
937 1.1 skrll {
938 1.1.1.2 christos as_bad (_("destination for add/subtract can only be R2 or R3"));
939 1.1 skrll return 1;
940 1.1 skrll }
941 1.1 skrll
942 1.1 skrll /* Now determine the P field for the instruction. */
943 1.1 skrll if (p_insn.operand_type[0][0]->op_type & Indirect)
944 1.1 skrll {
945 1.1 skrll if (p_insn.operand_type[0][1]->op_type & Indirect)
946 1.1 skrll p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
947 1.1 skrll else if (p_insn.operand_type[1][0]->op_type & Indirect)
948 1.1 skrll p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
949 1.1 skrll else
950 1.1 skrll p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
951 1.1 skrll }
952 1.1 skrll else
953 1.1 skrll {
954 1.1 skrll if (p_insn.operand_type[0][1]->op_type & Rn)
955 1.1 skrll p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
956 1.1 skrll else if (p_insn.operand_type[1][0]->op_type & Indirect)
957 1.1 skrll {
958 1.1 skrll operand *temp;
959 1.1 skrll p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
960 1.1 skrll /* Need to swap the two multiply operands around so that
961 1.1 skrll everything is in its place for the opcode makeup.
962 1.1 skrll ie so Ind * Rn, Ind +/- Rn. */
963 1.1 skrll temp = p_insn.operand_type[0][0];
964 1.1 skrll p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
965 1.1 skrll p_insn.operand_type[0][1] = temp;
966 1.1 skrll }
967 1.1 skrll else
968 1.1 skrll {
969 1.1 skrll operand *temp;
970 1.1 skrll p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
971 1.1 skrll temp = p_insn.operand_type[0][0];
972 1.1 skrll p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
973 1.1 skrll p_insn.operand_type[0][1] = temp;
974 1.1 skrll }
975 1.1 skrll }
976 1.1 skrll }
977 1.1 skrll }
978 1.1 skrll
979 1.1 skrll debug ("P field: %08X\n", p_insn.p_field);
980 1.1 skrll
981 1.1 skrll /* Finalise opcode. This is easier for parallel instructions as they have
982 1.1 skrll to be fully resolved, there are no memory addresses allowed, except
983 1.1 skrll through indirect addressing, so there are no labels to resolve. */
984 1.1 skrll p_insn.opcode = p_insn.tm->base_opcode;
985 1.1 skrll
986 1.1 skrll switch (p_insn.tm->oporder)
987 1.1 skrll {
988 1.1 skrll case OO_4op1:
989 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
990 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
991 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
992 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
993 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
994 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
995 1.1 skrll break;
996 1.1 skrll
997 1.1 skrll case OO_4op2:
998 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
999 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1000 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1001 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1002 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1003 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1004 1.1 skrll if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1005 1.1.1.2 christos as_warn (_("loading the same register in parallel operation"));
1006 1.1 skrll break;
1007 1.1 skrll
1008 1.1 skrll case OO_4op3:
1009 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1010 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1011 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1012 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1013 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1014 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1015 1.1 skrll break;
1016 1.1 skrll
1017 1.1 skrll case OO_5op1:
1018 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1019 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1020 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1021 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1022 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1023 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1024 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1025 1.1 skrll break;
1026 1.1 skrll
1027 1.1 skrll case OO_5op2:
1028 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1029 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1030 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1031 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1032 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1033 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1034 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1035 1.1 skrll break;
1036 1.1 skrll
1037 1.1 skrll case OO_PField:
1038 1.1 skrll p_insn.opcode |= p_insn.p_field;
1039 1.1 skrll if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1040 1.1 skrll p_insn.opcode |= 0x00800000;
1041 1.1 skrll if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1042 1.1 skrll p_insn.opcode |= 0x00400000;
1043 1.1 skrll
1044 1.1 skrll switch (p_insn.p_field)
1045 1.1 skrll {
1046 1.1 skrll case 0x00000000:
1047 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1048 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1049 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1050 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1051 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1052 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1053 1.1 skrll break;
1054 1.1 skrll case 0x01000000:
1055 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1056 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1057 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1058 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1059 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1060 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1061 1.1 skrll break;
1062 1.1 skrll case 0x02000000:
1063 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1064 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1065 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1066 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1067 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1068 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1069 1.1 skrll break;
1070 1.1 skrll case 0x03000000:
1071 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1072 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1073 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1074 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1075 1.1 skrll p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1076 1.1 skrll p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1077 1.1 skrll break;
1078 1.1 skrll }
1079 1.1 skrll break;
1080 1.1 skrll }
1081 1.1 skrll
1082 1.1 skrll {
1083 1.1 skrll char *p;
1084 1.1 skrll
1085 1.1 skrll p = frag_more (INSN_SIZE);
1086 1.1 skrll md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1087 1.1 skrll }
1088 1.1 skrll
1089 1.1 skrll {
1090 1.1 skrll unsigned int i, j;
1091 1.1 skrll
1092 1.1 skrll for (i = 0; i < 2; i++)
1093 1.1 skrll for (j = 0; j < p_insn.operands[i]; j++)
1094 1.1 skrll free (p_insn.operand_type[i][j]);
1095 1.1 skrll }
1096 1.1 skrll
1097 1.1 skrll debug ("Final opcode: %08X\n", p_insn.opcode);
1098 1.1 skrll debug ("\n");
1099 1.1 skrll
1100 1.1 skrll return 1;
1101 1.1 skrll }
1102 1.1 skrll
1103 1.1 skrll /* In order to get gas to ignore any | chars at the start of a line,
1104 1.1 skrll this function returns true if a | is found in a line. */
1105 1.1 skrll
1106 1.1 skrll int
1107 1.1 skrll tic30_unrecognized_line (int c)
1108 1.1 skrll {
1109 1.1 skrll debug ("In tc_unrecognized_line\n");
1110 1.1 skrll return (c == PARALLEL_SEPARATOR);
1111 1.1 skrll }
1112 1.1 skrll
1113 1.1 skrll int
1114 1.1 skrll md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1115 1.1 skrll segT segment ATTRIBUTE_UNUSED)
1116 1.1 skrll {
1117 1.1 skrll debug ("In md_estimate_size_before_relax()\n");
1118 1.1 skrll return 0;
1119 1.1 skrll }
1120 1.1 skrll
1121 1.1 skrll void
1122 1.1 skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1123 1.1 skrll segT sec ATTRIBUTE_UNUSED,
1124 1.1.1.4 christos fragS *fragP ATTRIBUTE_UNUSED)
1125 1.1 skrll {
1126 1.1 skrll debug ("In md_convert_frag()\n");
1127 1.1 skrll }
1128 1.1 skrll
1129 1.1 skrll void
1130 1.1 skrll md_apply_fix (fixS *fixP,
1131 1.1 skrll valueT *valP,
1132 1.1 skrll segT seg ATTRIBUTE_UNUSED)
1133 1.1 skrll {
1134 1.1 skrll valueT value = *valP;
1135 1.1 skrll
1136 1.1 skrll debug ("In md_apply_fix() with value = %ld\n", (long) value);
1137 1.1 skrll debug ("Values in fixP\n");
1138 1.1 skrll debug ("fx_size = %d\n", fixP->fx_size);
1139 1.1 skrll debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1140 1.1 skrll debug ("fx_where = %ld\n", fixP->fx_where);
1141 1.1 skrll debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1142 1.1 skrll {
1143 1.1 skrll char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1144 1.1 skrll
1145 1.1 skrll value /= INSN_SIZE;
1146 1.1 skrll if (fixP->fx_size == 1)
1147 1.1 skrll /* Special fix for LDP instruction. */
1148 1.1 skrll value = (value & 0x00FF0000) >> 16;
1149 1.1 skrll
1150 1.1 skrll debug ("new value = %ld\n", (long) value);
1151 1.1 skrll md_number_to_chars (buf, value, fixP->fx_size);
1152 1.1 skrll }
1153 1.1 skrll
1154 1.1 skrll if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1155 1.1 skrll fixP->fx_done = 1;
1156 1.1 skrll }
1157 1.1 skrll
1158 1.1 skrll int
1159 1.1 skrll md_parse_option (int c ATTRIBUTE_UNUSED,
1160 1.1.1.5 christos const char *arg ATTRIBUTE_UNUSED)
1161 1.1 skrll {
1162 1.1 skrll debug ("In md_parse_option()\n");
1163 1.1 skrll return 0;
1164 1.1 skrll }
1165 1.1 skrll
1166 1.1 skrll void
1167 1.1 skrll md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1168 1.1 skrll {
1169 1.1 skrll debug ("In md_show_usage()\n");
1170 1.1 skrll }
1171 1.1 skrll
1172 1.1 skrll symbolS *
1173 1.1 skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1174 1.1 skrll {
1175 1.1 skrll debug ("In md_undefined_symbol()\n");
1176 1.1 skrll return (symbolS *) 0;
1177 1.1 skrll }
1178 1.1 skrll
1179 1.1 skrll valueT
1180 1.1 skrll md_section_align (segT segment, valueT size)
1181 1.1 skrll {
1182 1.1 skrll debug ("In md_section_align() segment = %p and size = %lu\n",
1183 1.1 skrll segment, (unsigned long) size);
1184 1.1 skrll size = (size + 3) / 4;
1185 1.1 skrll size *= 4;
1186 1.1 skrll debug ("New size value = %lu\n", (unsigned long) size);
1187 1.1 skrll return size;
1188 1.1 skrll }
1189 1.1 skrll
1190 1.1 skrll long
1191 1.1 skrll md_pcrel_from (fixS *fixP)
1192 1.1 skrll {
1193 1.1 skrll int offset;
1194 1.1 skrll
1195 1.1 skrll debug ("In md_pcrel_from()\n");
1196 1.1 skrll debug ("fx_where = %ld\n", fixP->fx_where);
1197 1.1 skrll debug ("fx_size = %d\n", fixP->fx_size);
1198 1.1 skrll /* Find the opcode that represents the current instruction in the
1199 1.1 skrll fr_literal storage area, and check bit 21. Bit 21 contains whether the
1200 1.1 skrll current instruction is a delayed one or not, and then set the offset
1201 1.1 skrll value appropriately. */
1202 1.1 skrll if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1203 1.1 skrll offset = 3;
1204 1.1 skrll else
1205 1.1 skrll offset = 1;
1206 1.1 skrll debug ("offset = %d\n", offset);
1207 1.1 skrll /* PC Relative instructions have a format:
1208 1.1 skrll displacement = Label - (PC + offset)
1209 1.1 skrll This function returns PC + offset where:
1210 1.1 skrll fx_where - fx_size = PC
1211 1.1 skrll INSN_SIZE * offset = offset number of instructions. */
1212 1.1 skrll return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1213 1.1 skrll }
1214 1.1 skrll
1215 1.1.1.5 christos const char *
1216 1.1 skrll md_atof (int what_statement_type,
1217 1.1 skrll char *literalP,
1218 1.1 skrll int *sizeP)
1219 1.1 skrll {
1220 1.1 skrll int prec;
1221 1.1 skrll char *token;
1222 1.1 skrll char keepval;
1223 1.1 skrll unsigned long value;
1224 1.1 skrll float float_value;
1225 1.1 skrll
1226 1.1 skrll debug ("In md_atof()\n");
1227 1.1 skrll debug ("precision = %c\n", what_statement_type);
1228 1.1 skrll debug ("literal = %s\n", literalP);
1229 1.1 skrll debug ("line = ");
1230 1.1 skrll token = input_line_pointer;
1231 1.1 skrll while (!is_end_of_line[(unsigned char) *input_line_pointer]
1232 1.1 skrll && (*input_line_pointer != ','))
1233 1.1 skrll {
1234 1.1 skrll debug ("%c", *input_line_pointer);
1235 1.1 skrll input_line_pointer++;
1236 1.1 skrll }
1237 1.1 skrll
1238 1.1 skrll keepval = *input_line_pointer;
1239 1.1 skrll *input_line_pointer = '\0';
1240 1.1 skrll debug ("\n");
1241 1.1 skrll float_value = (float) atof (token);
1242 1.1 skrll *input_line_pointer = keepval;
1243 1.1 skrll debug ("float_value = %f\n", float_value);
1244 1.1 skrll
1245 1.1 skrll switch (what_statement_type)
1246 1.1 skrll {
1247 1.1 skrll case 'f':
1248 1.1 skrll case 'F':
1249 1.1 skrll case 's':
1250 1.1 skrll case 'S':
1251 1.1 skrll prec = 2;
1252 1.1 skrll break;
1253 1.1 skrll
1254 1.1 skrll case 'd':
1255 1.1 skrll case 'D':
1256 1.1 skrll case 'r':
1257 1.1 skrll case 'R':
1258 1.1 skrll prec = 4;
1259 1.1 skrll break;
1260 1.1 skrll
1261 1.1 skrll default:
1262 1.1 skrll *sizeP = 0;
1263 1.1 skrll return _("Unrecognized or unsupported floating point constant");
1264 1.1 skrll }
1265 1.1 skrll
1266 1.1 skrll if (float_value == 0.0)
1267 1.1 skrll value = (prec == 2) ? 0x00008000L : 0x80000000L;
1268 1.1 skrll else
1269 1.1 skrll {
1270 1.1 skrll unsigned long exp, sign, mant, tmsfloat;
1271 1.1 skrll union
1272 1.1 skrll {
1273 1.1 skrll float f;
1274 1.1 skrll long l;
1275 1.1 skrll }
1276 1.1 skrll converter;
1277 1.1 skrll
1278 1.1 skrll converter.f = float_value;
1279 1.1 skrll tmsfloat = converter.l;
1280 1.1 skrll sign = tmsfloat & 0x80000000;
1281 1.1 skrll mant = tmsfloat & 0x007FFFFF;
1282 1.1 skrll exp = tmsfloat & 0x7F800000;
1283 1.1 skrll exp <<= 1;
1284 1.1 skrll if (exp == 0xFF000000)
1285 1.1 skrll {
1286 1.1 skrll if (mant == 0)
1287 1.1 skrll value = 0x7F7FFFFF;
1288 1.1 skrll else if (sign == 0)
1289 1.1 skrll value = 0x7F7FFFFF;
1290 1.1 skrll else
1291 1.1 skrll value = 0x7F800000;
1292 1.1 skrll }
1293 1.1 skrll else
1294 1.1 skrll {
1295 1.1 skrll exp -= 0x7F000000;
1296 1.1 skrll if (sign)
1297 1.1 skrll {
1298 1.1 skrll mant = mant & 0x007FFFFF;
1299 1.1 skrll mant = -mant;
1300 1.1 skrll mant = mant & 0x00FFFFFF;
1301 1.1 skrll if (mant == 0)
1302 1.1 skrll {
1303 1.1 skrll mant |= 0x00800000;
1304 1.1 skrll exp = (long) exp - 0x01000000;
1305 1.1 skrll }
1306 1.1 skrll }
1307 1.1 skrll tmsfloat = exp | mant;
1308 1.1 skrll value = tmsfloat;
1309 1.1 skrll }
1310 1.1 skrll if (prec == 2)
1311 1.1 skrll {
1312 1.1.1.2 christos long expon, mantis;
1313 1.1 skrll
1314 1.1 skrll if (tmsfloat == 0x80000000)
1315 1.1 skrll value = 0x8000;
1316 1.1 skrll else
1317 1.1 skrll {
1318 1.1 skrll value = 0;
1319 1.1.1.2 christos expon = (tmsfloat & 0xFF000000);
1320 1.1.1.2 christos expon >>= 24;
1321 1.1.1.2 christos mantis = tmsfloat & 0x007FFFFF;
1322 1.1 skrll if (tmsfloat & 0x00800000)
1323 1.1 skrll {
1324 1.1.1.2 christos mantis |= 0xFF000000;
1325 1.1.1.2 christos mantis += 0x00000800;
1326 1.1.1.2 christos mantis >>= 12;
1327 1.1.1.2 christos mantis |= 0x00000800;
1328 1.1.1.2 christos mantis &= 0x0FFF;
1329 1.1.1.2 christos if (expon > 7)
1330 1.1 skrll value = 0x7800;
1331 1.1 skrll }
1332 1.1 skrll else
1333 1.1 skrll {
1334 1.1.1.2 christos mantis |= 0x00800000;
1335 1.1.1.2 christos mantis += 0x00000800;
1336 1.1.1.2 christos expon += (mantis >> 24);
1337 1.1.1.2 christos mantis >>= 12;
1338 1.1.1.2 christos mantis &= 0x07FF;
1339 1.1.1.2 christos if (expon > 7)
1340 1.1 skrll value = 0x77FF;
1341 1.1 skrll }
1342 1.1.1.2 christos if (expon < -8)
1343 1.1 skrll value = 0x8000;
1344 1.1 skrll if (value == 0)
1345 1.1 skrll {
1346 1.1.1.2 christos mantis = (expon << 12) | mantis;
1347 1.1.1.2 christos value = mantis & 0xFFFF;
1348 1.1 skrll }
1349 1.1 skrll }
1350 1.1 skrll }
1351 1.1 skrll }
1352 1.1 skrll md_number_to_chars (literalP, value, prec);
1353 1.1 skrll *sizeP = prec;
1354 1.1 skrll return NULL;
1355 1.1 skrll }
1356 1.1 skrll
1357 1.1 skrll void
1358 1.1 skrll md_number_to_chars (char *buf, valueT val, int n)
1359 1.1 skrll {
1360 1.1 skrll debug ("In md_number_to_chars()\n");
1361 1.1 skrll number_to_chars_bigendian (buf, val, n);
1362 1.1 skrll }
1363 1.1 skrll
1364 1.1 skrll #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1365 1.1 skrll #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1366 1.1 skrll
1367 1.1 skrll arelent *
1368 1.1 skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1369 1.1 skrll {
1370 1.1 skrll arelent *rel;
1371 1.1 skrll bfd_reloc_code_real_type code = 0;
1372 1.1 skrll
1373 1.1 skrll debug ("In tc_gen_reloc()\n");
1374 1.1 skrll debug ("fixP.size = %d\n", fixP->fx_size);
1375 1.1 skrll debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1376 1.1 skrll debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1377 1.1 skrll
1378 1.1 skrll switch (F (fixP->fx_size, fixP->fx_pcrel))
1379 1.1 skrll {
1380 1.1 skrll MAP (1, 0, BFD_RELOC_TIC30_LDP);
1381 1.1 skrll MAP (2, 0, BFD_RELOC_16);
1382 1.1 skrll MAP (3, 0, BFD_RELOC_24);
1383 1.1 skrll MAP (2, 1, BFD_RELOC_16_PCREL);
1384 1.1 skrll MAP (4, 0, BFD_RELOC_32);
1385 1.1 skrll default:
1386 1.1.1.2 christos as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1387 1.1.1.2 christos fixP->fx_pcrel ? _("pc-relative ") : "");
1388 1.1 skrll }
1389 1.1 skrll #undef MAP
1390 1.1 skrll #undef F
1391 1.1 skrll
1392 1.1.1.5 christos rel = XNEW (arelent);
1393 1.1.1.2 christos gas_assert (rel != 0);
1394 1.1.1.5 christos rel->sym_ptr_ptr = XNEW (asymbol *);
1395 1.1 skrll *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1396 1.1 skrll rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1397 1.1 skrll rel->addend = 0;
1398 1.1 skrll rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1399 1.1 skrll if (!rel->howto)
1400 1.1 skrll {
1401 1.1 skrll const char *name;
1402 1.1 skrll
1403 1.1 skrll name = S_GET_NAME (fixP->fx_addsy);
1404 1.1 skrll if (name == NULL)
1405 1.1 skrll name = "<unknown>";
1406 1.1 skrll as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1407 1.1 skrll name, bfd_get_reloc_code_name (code));
1408 1.1 skrll }
1409 1.1 skrll return rel;
1410 1.1 skrll }
1411 1.1 skrll
1412 1.1 skrll void
1413 1.1 skrll md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1414 1.1 skrll {
1415 1.1 skrll debug ("In md_operand()\n");
1416 1.1 skrll }
1417 1.1 skrll
1418 1.1 skrll void
1419 1.1 skrll md_assemble (char *line)
1420 1.1 skrll {
1421 1.1.1.2 christos insn_template *op;
1422 1.1 skrll char *current_posn;
1423 1.1 skrll char *token_start;
1424 1.1 skrll char save_char;
1425 1.1 skrll unsigned int count;
1426 1.1 skrll
1427 1.1 skrll debug ("In md_assemble() with argument %s\n", line);
1428 1.1 skrll memset (&insn, '\0', sizeof (insn));
1429 1.1 skrll if (found_parallel_insn)
1430 1.1 skrll {
1431 1.1 skrll debug ("Line is second part of parallel instruction\n\n");
1432 1.1 skrll found_parallel_insn = 0;
1433 1.1 skrll return;
1434 1.1 skrll }
1435 1.1 skrll if ((current_posn =
1436 1.1 skrll tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1437 1.1 skrll current_posn = line;
1438 1.1 skrll else
1439 1.1 skrll found_parallel_insn = 1;
1440 1.1 skrll
1441 1.1 skrll while (is_space_char (*current_posn))
1442 1.1 skrll current_posn++;
1443 1.1 skrll
1444 1.1 skrll token_start = current_posn;
1445 1.1 skrll
1446 1.1 skrll if (!is_opcode_char (*current_posn))
1447 1.1 skrll {
1448 1.1.1.2 christos as_bad (_("Invalid character %s in opcode"),
1449 1.1 skrll output_invalid (*current_posn));
1450 1.1 skrll return;
1451 1.1 skrll }
1452 1.1 skrll /* Check if instruction is a parallel instruction
1453 1.1 skrll by seeing if the first character is a q. */
1454 1.1 skrll if (*token_start == 'q')
1455 1.1 skrll {
1456 1.1 skrll if (tic30_parallel_insn (token_start))
1457 1.1 skrll {
1458 1.1 skrll if (found_parallel_insn)
1459 1.1 skrll free (token_start);
1460 1.1 skrll return;
1461 1.1 skrll }
1462 1.1 skrll }
1463 1.1 skrll while (is_opcode_char (*current_posn))
1464 1.1 skrll current_posn++;
1465 1.1 skrll {
1466 1.1 skrll /* Find instruction. */
1467 1.1 skrll save_char = *current_posn;
1468 1.1 skrll *current_posn = '\0';
1469 1.1.1.2 christos op = (insn_template *) hash_find (op_hash, token_start);
1470 1.1.1.2 christos if (op)
1471 1.1 skrll {
1472 1.1.1.2 christos debug ("Found instruction %s\n", op->name);
1473 1.1.1.2 christos insn.tm = op;
1474 1.1 skrll }
1475 1.1 skrll else
1476 1.1 skrll {
1477 1.1 skrll debug ("Didn't find insn\n");
1478 1.1.1.2 christos as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1479 1.1 skrll return;
1480 1.1 skrll }
1481 1.1 skrll *current_posn = save_char;
1482 1.1 skrll }
1483 1.1 skrll
1484 1.1 skrll if (*current_posn != END_OF_INSN)
1485 1.1 skrll {
1486 1.1 skrll /* Find operands. */
1487 1.1 skrll int paren_not_balanced;
1488 1.1 skrll int expecting_operand = 0;
1489 1.1 skrll int this_operand;
1490 1.1 skrll do
1491 1.1 skrll {
1492 1.1 skrll /* Skip optional white space before operand. */
1493 1.1 skrll while (!is_operand_char (*current_posn)
1494 1.1 skrll && *current_posn != END_OF_INSN)
1495 1.1 skrll {
1496 1.1 skrll if (!is_space_char (*current_posn))
1497 1.1 skrll {
1498 1.1.1.2 christos as_bad (_("Invalid character %s before %s operand"),
1499 1.1 skrll output_invalid (*current_posn),
1500 1.1 skrll ordinal_names[insn.operands]);
1501 1.1 skrll return;
1502 1.1 skrll }
1503 1.1 skrll current_posn++;
1504 1.1 skrll }
1505 1.1 skrll token_start = current_posn;
1506 1.1 skrll paren_not_balanced = 0;
1507 1.1 skrll while (paren_not_balanced || *current_posn != ',')
1508 1.1 skrll {
1509 1.1 skrll if (*current_posn == END_OF_INSN)
1510 1.1 skrll {
1511 1.1 skrll if (paren_not_balanced)
1512 1.1 skrll {
1513 1.1.1.2 christos as_bad (_("Unbalanced parenthesis in %s operand."),
1514 1.1 skrll ordinal_names[insn.operands]);
1515 1.1 skrll return;
1516 1.1 skrll }
1517 1.1 skrll else
1518 1.1 skrll break;
1519 1.1 skrll }
1520 1.1 skrll else if (!is_operand_char (*current_posn)
1521 1.1 skrll && !is_space_char (*current_posn))
1522 1.1 skrll {
1523 1.1.1.2 christos as_bad (_("Invalid character %s in %s operand"),
1524 1.1 skrll output_invalid (*current_posn),
1525 1.1 skrll ordinal_names[insn.operands]);
1526 1.1 skrll return;
1527 1.1 skrll }
1528 1.1 skrll if (*current_posn == '(')
1529 1.1 skrll ++paren_not_balanced;
1530 1.1 skrll if (*current_posn == ')')
1531 1.1 skrll --paren_not_balanced;
1532 1.1 skrll current_posn++;
1533 1.1 skrll }
1534 1.1 skrll if (current_posn != token_start)
1535 1.1 skrll {
1536 1.1 skrll /* Yes, we've read in another operand. */
1537 1.1 skrll this_operand = insn.operands++;
1538 1.1 skrll if (insn.operands > MAX_OPERANDS)
1539 1.1 skrll {
1540 1.1.1.2 christos as_bad (_("Spurious operands; (%d operands/instruction max)"),
1541 1.1 skrll MAX_OPERANDS);
1542 1.1 skrll return;
1543 1.1 skrll }
1544 1.1 skrll
1545 1.1 skrll /* Now parse operand adding info to 'insn' as we go along. */
1546 1.1 skrll save_char = *current_posn;
1547 1.1 skrll *current_posn = '\0';
1548 1.1 skrll insn.operand_type[this_operand] = tic30_operand (token_start);
1549 1.1 skrll *current_posn = save_char;
1550 1.1 skrll if (insn.operand_type[this_operand] == NULL)
1551 1.1 skrll return;
1552 1.1 skrll }
1553 1.1 skrll else
1554 1.1 skrll {
1555 1.1 skrll if (expecting_operand)
1556 1.1 skrll {
1557 1.1.1.2 christos as_bad (_("Expecting operand after ','; got nothing"));
1558 1.1 skrll return;
1559 1.1 skrll }
1560 1.1 skrll if (*current_posn == ',')
1561 1.1 skrll {
1562 1.1.1.2 christos as_bad (_("Expecting operand before ','; got nothing"));
1563 1.1 skrll return;
1564 1.1 skrll }
1565 1.1 skrll }
1566 1.1 skrll
1567 1.1 skrll /* Now *current_posn must be either ',' or END_OF_INSN. */
1568 1.1 skrll if (*current_posn == ',')
1569 1.1 skrll {
1570 1.1 skrll if (*++current_posn == END_OF_INSN)
1571 1.1 skrll {
1572 1.1 skrll /* Just skip it, if it's \n complain. */
1573 1.1.1.2 christos as_bad (_("Expecting operand after ','; got nothing"));
1574 1.1 skrll return;
1575 1.1 skrll }
1576 1.1 skrll expecting_operand = 1;
1577 1.1 skrll }
1578 1.1 skrll }
1579 1.1 skrll while (*current_posn != END_OF_INSN);
1580 1.1 skrll }
1581 1.1 skrll
1582 1.1 skrll debug ("Number of operands found: %d\n", insn.operands);
1583 1.1 skrll
1584 1.1 skrll /* Check that number of operands is correct. */
1585 1.1 skrll if (insn.operands != insn.tm->operands)
1586 1.1 skrll {
1587 1.1 skrll unsigned int i;
1588 1.1 skrll unsigned int numops = insn.tm->operands;
1589 1.1 skrll
1590 1.1 skrll /* If operands are not the same, then see if any of the operands are
1591 1.1 skrll not required. Then recheck with number of given operands. If they
1592 1.1 skrll are still not the same, then give an error, otherwise carry on. */
1593 1.1 skrll for (i = 0; i < insn.tm->operands; i++)
1594 1.1 skrll if (insn.tm->operand_types[i] & NotReq)
1595 1.1 skrll numops--;
1596 1.1 skrll if (insn.operands != numops)
1597 1.1 skrll {
1598 1.1.1.2 christos as_bad (_("Incorrect number of operands given"));
1599 1.1 skrll return;
1600 1.1 skrll }
1601 1.1 skrll }
1602 1.1 skrll insn.addressing_mode = AM_NotReq;
1603 1.1 skrll for (count = 0; count < insn.operands; count++)
1604 1.1 skrll {
1605 1.1 skrll if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1606 1.1 skrll {
1607 1.1 skrll debug ("Operand %d matches\n", count + 1);
1608 1.1 skrll /* If instruction has two operands and has an AddressMode
1609 1.1 skrll modifier then set addressing mode type for instruction. */
1610 1.1 skrll if (insn.tm->opcode_modifier == AddressMode)
1611 1.1 skrll {
1612 1.1 skrll int addr_insn = 0;
1613 1.1 skrll /* Store instruction uses the second
1614 1.1 skrll operand for the address mode. */
1615 1.1 skrll if ((insn.tm->operand_types[1] & (Indirect | Direct))
1616 1.1 skrll == (Indirect | Direct))
1617 1.1 skrll addr_insn = 1;
1618 1.1 skrll
1619 1.1 skrll if (insn.operand_type[addr_insn]->op_type & (AllReg))
1620 1.1 skrll insn.addressing_mode = AM_Register;
1621 1.1 skrll else if (insn.operand_type[addr_insn]->op_type & Direct)
1622 1.1 skrll insn.addressing_mode = AM_Direct;
1623 1.1 skrll else if (insn.operand_type[addr_insn]->op_type & Indirect)
1624 1.1 skrll insn.addressing_mode = AM_Indirect;
1625 1.1 skrll else
1626 1.1 skrll insn.addressing_mode = AM_Immediate;
1627 1.1 skrll }
1628 1.1 skrll }
1629 1.1 skrll else
1630 1.1 skrll {
1631 1.1.1.2 christos as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1632 1.1 skrll return;
1633 1.1 skrll }
1634 1.1 skrll }
1635 1.1 skrll
1636 1.1 skrll /* Now set the addressing mode for 3 operand instructions. */
1637 1.1 skrll if ((insn.tm->operand_types[0] & op3T1)
1638 1.1 skrll && (insn.tm->operand_types[1] & op3T2))
1639 1.1 skrll {
1640 1.1 skrll /* Set the addressing mode to the values used for 2 operand
1641 1.1 skrll instructions in the G addressing field of the opcode. */
1642 1.1 skrll char *p;
1643 1.1 skrll switch (insn.operand_type[0]->op_type)
1644 1.1 skrll {
1645 1.1 skrll case Rn:
1646 1.1 skrll case ARn:
1647 1.1 skrll case DPReg:
1648 1.1 skrll case OtherReg:
1649 1.1 skrll if (insn.operand_type[1]->op_type & (AllReg))
1650 1.1 skrll insn.addressing_mode = AM_Register;
1651 1.1 skrll else if (insn.operand_type[1]->op_type & Indirect)
1652 1.1 skrll insn.addressing_mode = AM_Direct;
1653 1.1 skrll else
1654 1.1 skrll {
1655 1.1 skrll /* Shouldn't make it to this stage. */
1656 1.1.1.2 christos as_bad (_("Incompatible first and second operands in instruction"));
1657 1.1 skrll return;
1658 1.1 skrll }
1659 1.1 skrll break;
1660 1.1 skrll case Indirect:
1661 1.1 skrll if (insn.operand_type[1]->op_type & (AllReg))
1662 1.1 skrll insn.addressing_mode = AM_Indirect;
1663 1.1 skrll else if (insn.operand_type[1]->op_type & Indirect)
1664 1.1 skrll insn.addressing_mode = AM_Immediate;
1665 1.1 skrll else
1666 1.1 skrll {
1667 1.1 skrll /* Shouldn't make it to this stage. */
1668 1.1.1.2 christos as_bad (_("Incompatible first and second operands in instruction"));
1669 1.1 skrll return;
1670 1.1 skrll }
1671 1.1 skrll break;
1672 1.1 skrll }
1673 1.1 skrll /* Now make up the opcode for the 3 operand instructions. As in
1674 1.1 skrll parallel instructions, there will be no unresolved values, so they
1675 1.1 skrll can be fully formed and added to the frag table. */
1676 1.1 skrll insn.opcode = insn.tm->base_opcode;
1677 1.1 skrll if (insn.operand_type[0]->op_type & Indirect)
1678 1.1 skrll {
1679 1.1 skrll insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1680 1.1 skrll insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1681 1.1 skrll }
1682 1.1 skrll else
1683 1.1 skrll insn.opcode |= (insn.operand_type[0]->reg.opcode);
1684 1.1 skrll
1685 1.1 skrll if (insn.operand_type[1]->op_type & Indirect)
1686 1.1 skrll {
1687 1.1 skrll insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1688 1.1 skrll insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1689 1.1 skrll }
1690 1.1 skrll else
1691 1.1 skrll insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1692 1.1 skrll
1693 1.1 skrll if (insn.operands == 3)
1694 1.1 skrll insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1695 1.1 skrll
1696 1.1 skrll insn.opcode |= insn.addressing_mode;
1697 1.1 skrll p = frag_more (INSN_SIZE);
1698 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1699 1.1 skrll }
1700 1.1 skrll else
1701 1.1 skrll {
1702 1.1 skrll /* Not a three operand instruction. */
1703 1.1 skrll char *p;
1704 1.1 skrll int am_insn = -1;
1705 1.1 skrll insn.opcode = insn.tm->base_opcode;
1706 1.1 skrll /* Create frag for instruction - all instructions are 4 bytes long. */
1707 1.1 skrll p = frag_more (INSN_SIZE);
1708 1.1 skrll if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1709 1.1 skrll {
1710 1.1 skrll insn.opcode |= insn.addressing_mode;
1711 1.1 skrll if (insn.addressing_mode == AM_Indirect)
1712 1.1 skrll {
1713 1.1 skrll /* Determine which operand gives the addressing mode. */
1714 1.1 skrll if (insn.operand_type[0]->op_type & Indirect)
1715 1.1 skrll am_insn = 0;
1716 1.1 skrll if ((insn.operands > 1)
1717 1.1 skrll && (insn.operand_type[1]->op_type & Indirect))
1718 1.1 skrll am_insn = 1;
1719 1.1 skrll insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1720 1.1 skrll insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1721 1.1 skrll insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1722 1.1 skrll if (insn.operands > 1)
1723 1.1 skrll insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1724 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1725 1.1 skrll }
1726 1.1 skrll else if (insn.addressing_mode == AM_Register)
1727 1.1 skrll {
1728 1.1 skrll insn.opcode |= (insn.operand_type[0]->reg.opcode);
1729 1.1 skrll if (insn.operands > 1)
1730 1.1 skrll insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1731 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1732 1.1 skrll }
1733 1.1 skrll else if (insn.addressing_mode == AM_Direct)
1734 1.1 skrll {
1735 1.1 skrll if (insn.operand_type[0]->op_type & Direct)
1736 1.1 skrll am_insn = 0;
1737 1.1 skrll if ((insn.operands > 1)
1738 1.1 skrll && (insn.operand_type[1]->op_type & Direct))
1739 1.1 skrll am_insn = 1;
1740 1.1 skrll if (insn.operands > 1)
1741 1.1 skrll insn.opcode |=
1742 1.1 skrll (insn.operand_type[! am_insn]->reg.opcode << 16);
1743 1.1 skrll if (insn.operand_type[am_insn]->direct.resolved == 1)
1744 1.1 skrll {
1745 1.1 skrll /* Resolved values can be placed straight
1746 1.1 skrll into instruction word, and output. */
1747 1.1 skrll insn.opcode |=
1748 1.1 skrll (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1749 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1750 1.1 skrll }
1751 1.1 skrll else
1752 1.1 skrll {
1753 1.1 skrll /* Unresolved direct addressing mode instruction. */
1754 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1755 1.1 skrll fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1756 1.1 skrll & insn.operand_type[am_insn]->direct.direct_expr,
1757 1.1 skrll 0, 0);
1758 1.1 skrll }
1759 1.1 skrll }
1760 1.1 skrll else if (insn.addressing_mode == AM_Immediate)
1761 1.1 skrll {
1762 1.1 skrll if (insn.operand_type[0]->immediate.resolved == 1)
1763 1.1 skrll {
1764 1.1 skrll char *keeploc;
1765 1.1 skrll int size;
1766 1.1 skrll
1767 1.1 skrll if (insn.operands > 1)
1768 1.1 skrll insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1769 1.1 skrll
1770 1.1 skrll switch (insn.tm->imm_arg_type)
1771 1.1 skrll {
1772 1.1 skrll case Imm_Float:
1773 1.1 skrll debug ("Floating point first operand\n");
1774 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1775 1.1 skrll
1776 1.1 skrll keeploc = input_line_pointer;
1777 1.1 skrll input_line_pointer =
1778 1.1 skrll insn.operand_type[0]->immediate.label;
1779 1.1 skrll
1780 1.1 skrll if (md_atof ('f', p + 2, & size) != 0)
1781 1.1 skrll {
1782 1.1.1.2 christos as_bad (_("invalid short form floating point immediate operand"));
1783 1.1 skrll return;
1784 1.1 skrll }
1785 1.1 skrll
1786 1.1 skrll input_line_pointer = keeploc;
1787 1.1 skrll break;
1788 1.1 skrll
1789 1.1 skrll case Imm_UInt:
1790 1.1 skrll debug ("Unsigned int first operand\n");
1791 1.1 skrll if (insn.operand_type[0]->immediate.decimal_found)
1792 1.1.1.2 christos as_warn (_("rounding down first operand float to unsigned int"));
1793 1.1 skrll if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1794 1.1.1.2 christos as_warn (_("only lower 16-bits of first operand are used"));
1795 1.1 skrll insn.opcode |=
1796 1.1 skrll (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1797 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1798 1.1 skrll break;
1799 1.1 skrll
1800 1.1 skrll case Imm_SInt:
1801 1.1 skrll debug ("Int first operand\n");
1802 1.1 skrll
1803 1.1 skrll if (insn.operand_type[0]->immediate.decimal_found)
1804 1.1.1.2 christos as_warn (_("rounding down first operand float to signed int"));
1805 1.1 skrll
1806 1.1 skrll if (insn.operand_type[0]->immediate.s_number < -32768 ||
1807 1.1 skrll insn.operand_type[0]->immediate.s_number > 32767)
1808 1.1 skrll {
1809 1.1.1.2 christos as_bad (_("first operand is too large for 16-bit signed int"));
1810 1.1 skrll return;
1811 1.1 skrll }
1812 1.1 skrll insn.opcode |=
1813 1.1 skrll (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1814 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1815 1.1 skrll break;
1816 1.1 skrll }
1817 1.1 skrll }
1818 1.1 skrll else
1819 1.1 skrll {
1820 1.1 skrll /* Unresolved immediate label. */
1821 1.1 skrll if (insn.operands > 1)
1822 1.1 skrll insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1823 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1824 1.1 skrll fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1825 1.1 skrll & insn.operand_type[0]->immediate.imm_expr,
1826 1.1 skrll 0, 0);
1827 1.1 skrll }
1828 1.1 skrll }
1829 1.1 skrll }
1830 1.1 skrll else if (insn.tm->opcode_modifier == PCRel)
1831 1.1 skrll {
1832 1.1 skrll /* Conditional Branch and Call instructions. */
1833 1.1 skrll if ((insn.tm->operand_types[0] & (AllReg | Disp))
1834 1.1 skrll == (AllReg | Disp))
1835 1.1 skrll {
1836 1.1 skrll if (insn.operand_type[0]->op_type & (AllReg))
1837 1.1 skrll {
1838 1.1 skrll insn.opcode |= (insn.operand_type[0]->reg.opcode);
1839 1.1 skrll insn.opcode |= PC_Register;
1840 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1841 1.1 skrll }
1842 1.1 skrll else
1843 1.1 skrll {
1844 1.1 skrll insn.opcode |= PC_Relative;
1845 1.1 skrll if (insn.operand_type[0]->immediate.resolved == 1)
1846 1.1 skrll {
1847 1.1 skrll insn.opcode |=
1848 1.1 skrll (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1849 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1850 1.1 skrll }
1851 1.1 skrll else
1852 1.1 skrll {
1853 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1854 1.1 skrll fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1855 1.1 skrll 2, & insn.operand_type[0]->immediate.imm_expr,
1856 1.1 skrll 1, 0);
1857 1.1 skrll }
1858 1.1 skrll }
1859 1.1 skrll }
1860 1.1 skrll else if ((insn.tm->operand_types[0] & ARn) == ARn)
1861 1.1 skrll {
1862 1.1 skrll /* Decrement and Branch instructions. */
1863 1.1 skrll insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1864 1.1 skrll if (insn.operand_type[1]->op_type & (AllReg))
1865 1.1 skrll {
1866 1.1 skrll insn.opcode |= (insn.operand_type[1]->reg.opcode);
1867 1.1 skrll insn.opcode |= PC_Register;
1868 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1869 1.1 skrll }
1870 1.1 skrll else if (insn.operand_type[1]->immediate.resolved == 1)
1871 1.1 skrll {
1872 1.1 skrll if (insn.operand_type[0]->immediate.decimal_found)
1873 1.1 skrll {
1874 1.1.1.2 christos as_bad (_("first operand is floating point"));
1875 1.1 skrll return;
1876 1.1 skrll }
1877 1.1 skrll if (insn.operand_type[0]->immediate.s_number < -32768 ||
1878 1.1 skrll insn.operand_type[0]->immediate.s_number > 32767)
1879 1.1 skrll {
1880 1.1.1.2 christos as_bad (_("first operand is too large for 16-bit signed int"));
1881 1.1 skrll return;
1882 1.1 skrll }
1883 1.1 skrll insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1884 1.1 skrll insn.opcode |= PC_Relative;
1885 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1886 1.1 skrll }
1887 1.1 skrll else
1888 1.1 skrll {
1889 1.1 skrll insn.opcode |= PC_Relative;
1890 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1891 1.1 skrll fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1892 1.1 skrll & insn.operand_type[1]->immediate.imm_expr,
1893 1.1 skrll 1, 0);
1894 1.1 skrll }
1895 1.1 skrll }
1896 1.1 skrll }
1897 1.1 skrll else if (insn.tm->operand_types[0] == IVector)
1898 1.1 skrll {
1899 1.1 skrll /* Trap instructions. */
1900 1.1 skrll if (insn.operand_type[0]->op_type & IVector)
1901 1.1 skrll insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1902 1.1 skrll else
1903 1.1 skrll {
1904 1.1 skrll /* Shouldn't get here. */
1905 1.1.1.2 christos as_bad (_("interrupt vector for trap instruction out of range"));
1906 1.1 skrll return;
1907 1.1 skrll }
1908 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1909 1.1 skrll }
1910 1.1 skrll else if (insn.tm->opcode_modifier == StackOp
1911 1.1 skrll || insn.tm->opcode_modifier == Rotate)
1912 1.1 skrll {
1913 1.1 skrll /* Push, Pop and Rotate instructions. */
1914 1.1 skrll insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1915 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1916 1.1 skrll }
1917 1.1 skrll else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1918 1.1 skrll == (Abs24 | Direct))
1919 1.1 skrll {
1920 1.1 skrll /* LDP Instruction needs to be tested
1921 1.1 skrll for before the next section. */
1922 1.1 skrll if (insn.operand_type[0]->op_type & Direct)
1923 1.1 skrll {
1924 1.1 skrll if (insn.operand_type[0]->direct.resolved == 1)
1925 1.1 skrll {
1926 1.1 skrll /* Direct addressing uses lower 8 bits of direct address. */
1927 1.1 skrll insn.opcode |=
1928 1.1 skrll (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1929 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1930 1.1 skrll }
1931 1.1 skrll else
1932 1.1 skrll {
1933 1.1 skrll fixS *fix;
1934 1.1 skrll
1935 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1936 1.1 skrll fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1937 1.1 skrll 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1938 1.1 skrll /* Ensure that the assembler doesn't complain
1939 1.1 skrll about fitting a 24-bit address into 8 bits. */
1940 1.1 skrll fix->fx_no_overflow = 1;
1941 1.1 skrll }
1942 1.1 skrll }
1943 1.1 skrll else
1944 1.1 skrll {
1945 1.1 skrll if (insn.operand_type[0]->immediate.resolved == 1)
1946 1.1 skrll {
1947 1.1 skrll /* Immediate addressing uses upper 8 bits of address. */
1948 1.1 skrll if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1949 1.1 skrll {
1950 1.1.1.2 christos as_bad (_("LDP instruction needs a 24-bit operand"));
1951 1.1 skrll return;
1952 1.1 skrll }
1953 1.1 skrll insn.opcode |=
1954 1.1 skrll ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1955 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1956 1.1 skrll }
1957 1.1 skrll else
1958 1.1 skrll {
1959 1.1 skrll fixS *fix;
1960 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1961 1.1 skrll fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1962 1.1 skrll 1, &insn.operand_type[0]->immediate.imm_expr,
1963 1.1 skrll 0, 0);
1964 1.1 skrll fix->fx_no_overflow = 1;
1965 1.1 skrll }
1966 1.1 skrll }
1967 1.1 skrll }
1968 1.1 skrll else if (insn.tm->operand_types[0] & (Imm24))
1969 1.1 skrll {
1970 1.1 skrll /* Unconditional Branch and Call instructions. */
1971 1.1 skrll if (insn.operand_type[0]->immediate.resolved == 1)
1972 1.1 skrll {
1973 1.1 skrll if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1974 1.1.1.2 christos as_warn (_("first operand is too large for a 24-bit displacement"));
1975 1.1 skrll insn.opcode |=
1976 1.1 skrll (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1977 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1978 1.1 skrll }
1979 1.1 skrll else
1980 1.1 skrll {
1981 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1982 1.1 skrll fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1983 1.1 skrll & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1984 1.1 skrll }
1985 1.1 skrll }
1986 1.1 skrll else if (insn.tm->operand_types[0] & NotReq)
1987 1.1 skrll /* Check for NOP instruction without arguments. */
1988 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1989 1.1 skrll
1990 1.1 skrll else if (insn.tm->operands == 0)
1991 1.1 skrll /* Check for instructions without operands. */
1992 1.1 skrll md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1993 1.1 skrll }
1994 1.1 skrll debug ("Addressing mode: %08X\n", insn.addressing_mode);
1995 1.1 skrll {
1996 1.1 skrll unsigned int i;
1997 1.1 skrll
1998 1.1 skrll for (i = 0; i < insn.operands; i++)
1999 1.1 skrll {
2000 1.1 skrll if (insn.operand_type[i]->immediate.label)
2001 1.1 skrll free (insn.operand_type[i]->immediate.label);
2002 1.1 skrll free (insn.operand_type[i]);
2003 1.1 skrll }
2004 1.1 skrll }
2005 1.1 skrll debug ("Final opcode: %08X\n", insn.opcode);
2006 1.1 skrll debug ("\n");
2007 1.1 skrll }
2008