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