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