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