Automatic date update in version.in
[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);
405 current_op = malloc (sizeof (* current_op));
406 memset (current_op, '\0', sizeof (operand));
407
408 if (*token == DIRECT_REFERENCE)
252b5132 409 {
4d5f9b2a
NC
410 char *token_posn = token + 1;
411 int direct_label = 0;
412
413 debug ("Found direct reference\n");
414 while (*token_posn)
252b5132 415 {
4d5f9b2a
NC
416 if (!is_digit_char (*token_posn))
417 direct_label = 1;
418 token_posn++;
252b5132 419 }
4d5f9b2a
NC
420
421 if (direct_label)
252b5132 422 {
4d5f9b2a
NC
423 char *save_input_line_pointer;
424 segT retval;
425
426 debug ("Direct reference is a label\n");
427 current_op->direct.label = token + 1;
428 save_input_line_pointer = input_line_pointer;
429 input_line_pointer = token + 1;
430 debug ("Current input_line_pointer: %s\n", input_line_pointer);
431 retval = expression (&current_op->direct.direct_expr);
432
433 debug ("Expression type: %d\n",
434 current_op->direct.direct_expr.X_op);
0fd3a477
JW
435 debug ("Expression addnum: %ld\n",
436 (long) current_op->direct.direct_expr.X_add_number);
437 debug ("Segment: %p\n", retval);
4d5f9b2a
NC
438
439 input_line_pointer = save_input_line_pointer;
440
441 if (current_op->direct.direct_expr.X_op == O_constant)
252b5132 442 {
4d5f9b2a
NC
443 current_op->direct.address =
444 current_op->direct.direct_expr.X_add_number;
445 current_op->direct.resolved = 1;
252b5132
RH
446 }
447 }
448 else
449 {
4d5f9b2a
NC
450 debug ("Direct reference is a number\n");
451 current_op->direct.address = atoi (token + 1);
452 current_op->direct.resolved = 1;
252b5132 453 }
4d5f9b2a 454 current_op->op_type = Direct;
252b5132 455 }
4d5f9b2a 456 else if (*token == INDIRECT_REFERENCE)
252b5132 457 {
4d5f9b2a
NC
458 /* Indirect reference operand. */
459 int found_ar = 0;
460 int found_disp = 0;
461 int ar_number = -1;
462 int disp_number = 0;
463 int buffer_posn = 1;
464 ind_addr_type *ind_addr_op;
e1fa0163
NC
465 char * ind_buffer;
466
467 ind_buffer = xmalloc (strlen (token));
4d5f9b2a
NC
468
469 debug ("Found indirect reference\n");
470 ind_buffer[0] = *token;
471
472 for (count = 1; count < strlen (token); count++)
252b5132 473 {
4d5f9b2a
NC
474 /* Strip operand. */
475 ind_buffer[buffer_posn] = TOLOWER (*(token + count));
476
477 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
478 && (*(token + count) == 'r' || *(token + count) == 'R'))
252b5132 479 {
4d5f9b2a
NC
480 /* AR reference is found, so get its number and remove
481 it from the buffer so it can pass through hash_find(). */
482 if (found_ar)
252b5132 483 {
20203fb9 484 as_bad (_("More than one AR register found in indirect reference"));
e1fa0163 485 free (ind_buffer);
4d5f9b2a 486 return NULL;
252b5132 487 }
4d5f9b2a
NC
488 if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
489 {
20203fb9 490 as_bad (_("Illegal AR register in indirect reference"));
e1fa0163 491 free (ind_buffer);
4d5f9b2a 492 return NULL;
252b5132 493 }
4d5f9b2a
NC
494 ar_number = *(token + count + 1) - '0';
495 found_ar = 1;
496 count++;
252b5132 497 }
4d5f9b2a
NC
498
499 if (*(token + count) == '(')
252b5132 500 {
4d5f9b2a
NC
501 /* Parenthesis found, so check if a displacement value is
502 inside. If so, get the value and remove it from the
503 buffer. */
504 if (is_digit_char (*(token + count + 1)))
252b5132 505 {
4d5f9b2a
NC
506 char disp[10];
507 int disp_posn = 0;
508
509 if (found_disp)
252b5132 510 {
20203fb9 511 as_bad (_("More than one displacement found in indirect reference"));
e1fa0163 512 free (ind_buffer);
4d5f9b2a
NC
513 return NULL;
514 }
515 count++;
516 while (*(token + count) != ')')
517 {
518 if (!is_digit_char (*(token + count)))
252b5132 519 {
20203fb9 520 as_bad (_("Invalid displacement in indirect reference"));
e1fa0163 521 free (ind_buffer);
4d5f9b2a 522 return NULL;
252b5132 523 }
4d5f9b2a 524 disp[disp_posn++] = *(token + (count++));
252b5132 525 }
4d5f9b2a
NC
526 disp[disp_posn] = '\0';
527 disp_number = atoi (disp);
528 count--;
529 found_disp = 1;
252b5132
RH
530 }
531 }
4d5f9b2a 532 buffer_posn++;
252b5132 533 }
4d5f9b2a
NC
534
535 ind_buffer[buffer_posn] = '\0';
536 if (!found_ar)
252b5132 537 {
20203fb9 538 as_bad (_("AR register not found in indirect reference"));
e1fa0163 539 free (ind_buffer);
4d5f9b2a
NC
540 return NULL;
541 }
542
543 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
544 if (ind_addr_op)
545 {
546 debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
547 if (ind_addr_op->displacement == IMPLIED_DISP)
252b5132 548 {
4d5f9b2a
NC
549 found_disp = 1;
550 disp_number = 1;
252b5132 551 }
4d5f9b2a 552 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
252b5132 553 {
4d5f9b2a 554 /* Maybe an implied displacement of 1 again. */
20203fb9 555 as_bad (_("required displacement wasn't given in indirect reference"));
e1fa0163
NC
556 free (ind_buffer);
557 return NULL;
252b5132
RH
558 }
559 }
4d5f9b2a 560 else
252b5132 561 {
20203fb9 562 as_bad (_("illegal indirect reference"));
e1fa0163 563 free (ind_buffer);
4d5f9b2a 564 return NULL;
252b5132 565 }
4d5f9b2a
NC
566
567 if (found_disp && (disp_number < 0 || disp_number > 255))
252b5132 568 {
20203fb9 569 as_bad (_("displacement must be an unsigned 8-bit number"));
e1fa0163 570 free (ind_buffer);
4d5f9b2a 571 return NULL;
252b5132 572 }
4d5f9b2a
NC
573
574 current_op->indirect.mod = ind_addr_op->modfield;
575 current_op->indirect.disp = disp_number;
576 current_op->indirect.ARnum = ar_number;
577 current_op->op_type = Indirect;
e1fa0163 578 free (ind_buffer);
4d5f9b2a
NC
579 }
580 else
581 {
582 reg *regop = (reg *) hash_find (reg_hash, token);
583
584 if (regop)
252b5132 585 {
4d5f9b2a
NC
586 debug ("Found register operand: %s\n", regop->name);
587 if (regop->regtype == REG_ARn)
588 current_op->op_type = ARn;
589 else if (regop->regtype == REG_Rn)
590 current_op->op_type = Rn;
591 else if (regop->regtype == REG_DP)
592 current_op->op_type = DPReg;
252b5132 593 else
4d5f9b2a
NC
594 current_op->op_type = OtherReg;
595 current_op->reg.opcode = regop->opcode;
252b5132 596 }
4d5f9b2a 597 else
252b5132 598 {
4d5f9b2a
NC
599 if (!is_digit_char (*token)
600 || *(token + 1) == 'x'
601 || strchr (token, 'h'))
252b5132 602 {
4d5f9b2a
NC
603 char *save_input_line_pointer;
604 segT retval;
605
606 debug ("Probably a label: %s\n", token);
a44e2901 607 current_op->immediate.label = xstrdup (token);
4d5f9b2a
NC
608 save_input_line_pointer = input_line_pointer;
609 input_line_pointer = token;
610
611 debug ("Current input_line_pointer: %s\n", input_line_pointer);
612 retval = expression (&current_op->immediate.imm_expr);
613 debug ("Expression type: %d\n",
614 current_op->immediate.imm_expr.X_op);
0fd3a477
JW
615 debug ("Expression addnum: %ld\n",
616 (long) current_op->immediate.imm_expr.X_add_number);
617 debug ("Segment: %p\n", retval);
4d5f9b2a
NC
618 input_line_pointer = save_input_line_pointer;
619
620 if (current_op->immediate.imm_expr.X_op == O_constant)
621 {
622 current_op->immediate.s_number
623 = current_op->immediate.imm_expr.X_add_number;
624 current_op->immediate.u_number
625 = (unsigned int) current_op->immediate.imm_expr.X_add_number;
626 current_op->immediate.resolved = 1;
627 }
252b5132
RH
628 }
629 else
630 {
4d5f9b2a
NC
631 debug ("Found a number or displacement\n");
632 for (count = 0; count < strlen (token); count++)
633 if (*(token + count) == '.')
634 current_op->immediate.decimal_found = 1;
a44e2901 635 current_op->immediate.label = xstrdup (token);
4d5f9b2a
NC
636 current_op->immediate.f_number = (float) atof (token);
637 current_op->immediate.s_number = (int) atoi (token);
638 current_op->immediate.u_number = (unsigned int) atoi (token);
639 current_op->immediate.resolved = 1;
252b5132 640 }
4d5f9b2a
NC
641 current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
642 if (current_op->immediate.u_number <= 31)
643 current_op->op_type |= IVector;
252b5132
RH
644 }
645 }
4d5f9b2a 646 return current_op;
252b5132
RH
647}
648
4d5f9b2a
NC
649struct tic30_par_insn
650{
651 partemplate *tm; /* Template of current parallel instruction. */
652 unsigned operands[2]; /* Number of given operands for each insn. */
653 /* Type of operand given in instruction. */
252b5132 654 operand *operand_type[2][MAX_OPERANDS];
1dab94dd 655 int swap_operands; /* Whether to swap operands around. */
4d5f9b2a
NC
656 unsigned p_field; /* Value of p field in multiply add/sub instructions. */
657 unsigned opcode; /* Final opcode. */
252b5132
RH
658};
659
660struct tic30_par_insn p_insn;
661
4d5f9b2a 662static int
252b5132
RH
663tic30_parallel_insn (char *token)
664{
665 static partemplate *p_opcode;
666 char *current_posn = token;
667 char *token_start;
668 char save_char;
669
670 debug ("In tic30_parallel_insn with %s\n", token);
671 memset (&p_insn, '\0', sizeof (p_insn));
4d5f9b2a 672
252b5132
RH
673 while (is_opcode_char (*current_posn))
674 current_posn++;
4d5f9b2a
NC
675 {
676 /* Find instruction. */
252b5132
RH
677 save_char = *current_posn;
678 *current_posn = '\0';
679 p_opcode = (partemplate *) hash_find (parop_hash, token);
680 if (p_opcode)
681 {
682 debug ("Found instruction %s\n", p_opcode->name);
683 p_insn.tm = p_opcode;
684 }
685 else
686 {
4d5f9b2a
NC
687 char first_opcode[6] = {0};
688 char second_opcode[6] = {0};
167795c4 689 unsigned int i;
252b5132
RH
690 int current_opcode = -1;
691 int char_ptr = 0;
692
693 for (i = 0; i < strlen (token); i++)
694 {
695 char ch = *(token + i);
4d5f9b2a 696
252b5132
RH
697 if (ch == '_' && current_opcode == -1)
698 {
699 current_opcode = 0;
700 continue;
701 }
4d5f9b2a 702
252b5132
RH
703 if (ch == '_' && current_opcode == 0)
704 {
705 current_opcode = 1;
706 char_ptr = 0;
707 continue;
708 }
4d5f9b2a 709
252b5132
RH
710 switch (current_opcode)
711 {
712 case 0:
713 first_opcode[char_ptr++] = ch;
714 break;
715 case 1:
716 second_opcode[char_ptr++] = ch;
717 break;
718 }
719 }
4d5f9b2a 720
252b5132
RH
721 debug ("first_opcode = %s\n", first_opcode);
722 debug ("second_opcode = %s\n", second_opcode);
723 sprintf (token, "q_%s_%s", second_opcode, first_opcode);
724 p_opcode = (partemplate *) hash_find (parop_hash, token);
4d5f9b2a 725
252b5132
RH
726 if (p_opcode)
727 {
728 debug ("Found instruction %s\n", p_opcode->name);
729 p_insn.tm = p_opcode;
730 p_insn.swap_operands = 1;
731 }
732 else
733 return 0;
734 }
735 *current_posn = save_char;
736 }
4d5f9b2a
NC
737
738 {
739 /* Find operands. */
252b5132
RH
740 int paren_not_balanced;
741 int expecting_operand = 0;
742 int found_separator = 0;
4d5f9b2a 743
252b5132
RH
744 do
745 {
4d5f9b2a
NC
746 /* Skip optional white space before operand. */
747 while (!is_operand_char (*current_posn)
748 && *current_posn != END_OF_INSN)
252b5132 749 {
4d5f9b2a
NC
750 if (!is_space_char (*current_posn)
751 && *current_posn != PARALLEL_SEPARATOR)
252b5132 752 {
20203fb9 753 as_bad (_("Invalid character %s before %s operand"),
252b5132
RH
754 output_invalid (*current_posn),
755 ordinal_names[insn.operands]);
756 return 1;
757 }
758 if (*current_posn == PARALLEL_SEPARATOR)
759 found_separator = 1;
760 current_posn++;
761 }
4d5f9b2a
NC
762
763 token_start = current_posn;
252b5132 764 paren_not_balanced = 0;
4d5f9b2a 765
252b5132
RH
766 while (paren_not_balanced || *current_posn != ',')
767 {
768 if (*current_posn == END_OF_INSN)
769 {
770 if (paren_not_balanced)
771 {
20203fb9 772 as_bad (_("Unbalanced parenthesis in %s operand."),
252b5132
RH
773 ordinal_names[insn.operands]);
774 return 1;
775 }
776 else
4d5f9b2a 777 break;
252b5132
RH
778 }
779 else if (*current_posn == PARALLEL_SEPARATOR)
780 {
781 while (is_space_char (*(current_posn - 1)))
782 current_posn--;
783 break;
784 }
4d5f9b2a
NC
785 else if (!is_operand_char (*current_posn)
786 && !is_space_char (*current_posn))
252b5132 787 {
20203fb9 788 as_bad (_("Invalid character %s in %s operand"),
252b5132
RH
789 output_invalid (*current_posn),
790 ordinal_names[insn.operands]);
791 return 1;
792 }
4d5f9b2a 793
252b5132
RH
794 if (*current_posn == '(')
795 ++paren_not_balanced;
796 if (*current_posn == ')')
797 --paren_not_balanced;
798 current_posn++;
799 }
4d5f9b2a 800
252b5132 801 if (current_posn != token_start)
4d5f9b2a
NC
802 {
803 /* Yes, we've read in another operand. */
252b5132
RH
804 p_insn.operands[found_separator]++;
805 if (p_insn.operands[found_separator] > MAX_OPERANDS)
806 {
20203fb9 807 as_bad (_("Spurious operands; (%d operands/instruction max)"),
252b5132
RH
808 MAX_OPERANDS);
809 return 1;
810 }
4d5f9b2a
NC
811
812 /* Now parse operand adding info to 'insn' as we go along. */
252b5132
RH
813 save_char = *current_posn;
814 *current_posn = '\0';
815 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
816 tic30_operand (token_start);
817 *current_posn = save_char;
818 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
819 return 1;
820 }
821 else
822 {
823 if (expecting_operand)
824 {
20203fb9 825 as_bad (_("Expecting operand after ','; got nothing"));
252b5132
RH
826 return 1;
827 }
828 if (*current_posn == ',')
829 {
20203fb9 830 as_bad (_("Expecting operand before ','; got nothing"));
252b5132
RH
831 return 1;
832 }
833 }
4d5f9b2a
NC
834
835 /* Now *current_posn must be either ',' or END_OF_INSN. */
252b5132
RH
836 if (*current_posn == ',')
837 {
838 if (*++current_posn == END_OF_INSN)
4d5f9b2a
NC
839 {
840 /* Just skip it, if it's \n complain. */
20203fb9 841 as_bad (_("Expecting operand after ','; got nothing"));
252b5132
RH
842 return 1;
843 }
844 expecting_operand = 1;
845 }
846 }
4d5f9b2a 847 while (*current_posn != END_OF_INSN);
252b5132 848 }
4d5f9b2a 849
252b5132
RH
850 if (p_insn.swap_operands)
851 {
852 int temp_num, i;
853 operand *temp_op;
854
855 temp_num = p_insn.operands[0];
856 p_insn.operands[0] = p_insn.operands[1];
857 p_insn.operands[1] = temp_num;
858 for (i = 0; i < MAX_OPERANDS; i++)
859 {
860 temp_op = p_insn.operand_type[0][i];
861 p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
862 p_insn.operand_type[1][i] = temp_op;
863 }
864 }
4d5f9b2a 865
252b5132
RH
866 if (p_insn.operands[0] != p_insn.tm->operands_1)
867 {
20203fb9 868 as_bad (_("incorrect number of operands given in the first instruction"));
252b5132
RH
869 return 1;
870 }
4d5f9b2a 871
252b5132
RH
872 if (p_insn.operands[1] != p_insn.tm->operands_2)
873 {
20203fb9 874 as_bad (_("incorrect number of operands given in the second instruction"));
252b5132
RH
875 return 1;
876 }
4d5f9b2a 877
252b5132
RH
878 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
879 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
4d5f9b2a
NC
880
881 {
882 /* Now check if operands are correct. */
252b5132
RH
883 int count;
884 int num_rn = 0;
885 int num_ind = 0;
4d5f9b2a 886
252b5132
RH
887 for (count = 0; count < 2; count++)
888 {
167795c4 889 unsigned int i;
252b5132
RH
890 for (i = 0; i < p_insn.operands[count]; i++)
891 {
892 if ((p_insn.operand_type[count][i]->op_type &
893 p_insn.tm->operand_types[count][i]) == 0)
894 {
20203fb9 895 as_bad (_("%s instruction, operand %d doesn't match"),
4d5f9b2a 896 ordinal_names[count], i + 1);
252b5132
RH
897 return 1;
898 }
4d5f9b2a
NC
899
900 /* Get number of R register and indirect reference contained
901 within the first two operands of each instruction. This is
902 required for the multiply parallel instructions which require
903 two R registers and two indirect references, but not in any
904 particular place. */
252b5132
RH
905 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
906 num_rn++;
4d5f9b2a
NC
907 else if ((p_insn.operand_type[count][i]->op_type & Indirect)
908 && i < 2)
252b5132
RH
909 num_ind++;
910 }
911 }
4d5f9b2a
NC
912
913 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
914 == (Indirect | Rn))
252b5132 915 {
4d5f9b2a 916 /* Check for the multiply instructions. */
252b5132
RH
917 if (num_rn != 2)
918 {
20203fb9 919 as_bad (_("incorrect format for multiply parallel instruction"));
252b5132
RH
920 return 1;
921 }
4d5f9b2a 922
252b5132 923 if (num_ind != 2)
4d5f9b2a
NC
924 {
925 /* Shouldn't get here. */
20203fb9 926 as_bad (_("incorrect format for multiply parallel instruction"));
252b5132
RH
927 return 1;
928 }
4d5f9b2a
NC
929
930 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
931 && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
252b5132 932 {
20203fb9 933 as_bad (_("destination for multiply can only be R0 or R1"));
252b5132
RH
934 return 1;
935 }
4d5f9b2a
NC
936
937 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
938 && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
252b5132 939 {
20203fb9 940 as_bad (_("destination for add/subtract can only be R2 or R3"));
252b5132
RH
941 return 1;
942 }
4d5f9b2a
NC
943
944 /* Now determine the P field for the instruction. */
252b5132
RH
945 if (p_insn.operand_type[0][0]->op_type & Indirect)
946 {
947 if (p_insn.operand_type[0][1]->op_type & Indirect)
4d5f9b2a 948 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
252b5132 949 else if (p_insn.operand_type[1][0]->op_type & Indirect)
4d5f9b2a 950 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
252b5132 951 else
4d5f9b2a 952 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
252b5132
RH
953 }
954 else
955 {
956 if (p_insn.operand_type[0][1]->op_type & Rn)
4d5f9b2a 957 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
252b5132
RH
958 else if (p_insn.operand_type[1][0]->op_type & Indirect)
959 {
960 operand *temp;
4d5f9b2a
NC
961 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
962 /* Need to swap the two multiply operands around so that
963 everything is in its place for the opcode makeup.
964 ie so Ind * Rn, Ind +/- Rn. */
252b5132
RH
965 temp = p_insn.operand_type[0][0];
966 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
967 p_insn.operand_type[0][1] = temp;
968 }
969 else
970 {
971 operand *temp;
4d5f9b2a 972 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
252b5132
RH
973 temp = p_insn.operand_type[0][0];
974 p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
975 p_insn.operand_type[0][1] = temp;
976 }
977 }
978 }
979 }
4d5f9b2a 980
252b5132 981 debug ("P field: %08X\n", p_insn.p_field);
4d5f9b2a
NC
982
983 /* Finalise opcode. This is easier for parallel instructions as they have
984 to be fully resolved, there are no memory addresses allowed, except
985 through indirect addressing, so there are no labels to resolve. */
986 p_insn.opcode = p_insn.tm->base_opcode;
987
988 switch (p_insn.tm->oporder)
989 {
990 case OO_4op1:
991 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
992 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
993 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
994 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
995 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
996 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
997 break;
998
999 case OO_4op2:
1000 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1001 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1002 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1003 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1004 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1005 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1006 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
20203fb9 1007 as_warn (_("loading the same register in parallel operation"));
4d5f9b2a
NC
1008 break;
1009
1010 case OO_4op3:
1011 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1012 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1013 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1014 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1015 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1016 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1017 break;
1018
1019 case OO_5op1:
1020 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1021 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1022 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1023 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1024 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1025 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1026 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1027 break;
1028
1029 case OO_5op2:
1030 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1031 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1032 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1033 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1034 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1035 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1036 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1037 break;
1038
1039 case OO_PField:
1040 p_insn.opcode |= p_insn.p_field;
1041 if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1042 p_insn.opcode |= 0x00800000;
1043 if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1044 p_insn.opcode |= 0x00400000;
1045
1046 switch (p_insn.p_field)
1047 {
1048 case 0x00000000:
1049 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1050 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1051 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1052 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1053 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1054 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1055 break;
1056 case 0x01000000:
1057 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1058 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1059 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1060 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1061 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1062 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1063 break;
1064 case 0x02000000:
1065 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1066 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1067 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1068 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1069 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1070 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1071 break;
1072 case 0x03000000:
1073 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1074 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1075 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1076 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1077 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1078 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1079 break;
1080 }
1081 break;
1082 }
1083
252b5132 1084 {
252b5132 1085 char *p;
4d5f9b2a 1086
252b5132
RH
1087 p = frag_more (INSN_SIZE);
1088 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1089 }
4d5f9b2a 1090
252b5132 1091 {
167795c4 1092 unsigned int i, j;
4d5f9b2a 1093
252b5132
RH
1094 for (i = 0; i < 2; i++)
1095 for (j = 0; j < p_insn.operands[i]; j++)
1096 free (p_insn.operand_type[i][j]);
1097 }
4d5f9b2a 1098
252b5132
RH
1099 debug ("Final opcode: %08X\n", p_insn.opcode);
1100 debug ("\n");
4d5f9b2a 1101
252b5132
RH
1102 return 1;
1103}
1104
4d5f9b2a
NC
1105/* In order to get gas to ignore any | chars at the start of a line,
1106 this function returns true if a | is found in a line. */
1107
1108int
1109tic30_unrecognized_line (int c)
252b5132 1110{
4d5f9b2a
NC
1111 debug ("In tc_unrecognized_line\n");
1112 return (c == PARALLEL_SEPARATOR);
1113}
252b5132 1114
4d5f9b2a
NC
1115int
1116md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1117 segT segment ATTRIBUTE_UNUSED)
1118{
1119 debug ("In md_estimate_size_before_relax()\n");
1120 return 0;
1121}
1122
1123void
1124md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1125 segT sec ATTRIBUTE_UNUSED,
ed9e98c2 1126 fragS *fragP ATTRIBUTE_UNUSED)
4d5f9b2a
NC
1127{
1128 debug ("In md_convert_frag()\n");
1129}
1130
1131void
55cf6793 1132md_apply_fix (fixS *fixP,
4d5f9b2a
NC
1133 valueT *valP,
1134 segT seg ATTRIBUTE_UNUSED)
1135{
1136 valueT value = *valP;
1137
1138 debug ("In md_apply_fix() with value = %ld\n", (long) value);
1139 debug ("Values in fixP\n");
1140 debug ("fx_size = %d\n", fixP->fx_size);
1141 debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
0fd3a477 1142 debug ("fx_where = %ld\n", fixP->fx_where);
4d5f9b2a
NC
1143 debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1144 {
1145 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1146
1147 value /= INSN_SIZE;
1148 if (fixP->fx_size == 1)
1149 /* Special fix for LDP instruction. */
1150 value = (value & 0x00FF0000) >> 16;
1151
1152 debug ("new value = %ld\n", (long) value);
1153 md_number_to_chars (buf, value, fixP->fx_size);
1154 }
1155
1156 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1157 fixP->fx_done = 1;
1158}
1159
1160int
1161md_parse_option (int c ATTRIBUTE_UNUSED,
17b9d67d 1162 const char *arg ATTRIBUTE_UNUSED)
4d5f9b2a
NC
1163{
1164 debug ("In md_parse_option()\n");
1165 return 0;
1166}
1167
1168void
1169md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1170{
1171 debug ("In md_show_usage()\n");
1172}
1173
1174symbolS *
1175md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1176{
1177 debug ("In md_undefined_symbol()\n");
1178 return (symbolS *) 0;
1179}
1180
1181valueT
1182md_section_align (segT segment, valueT size)
1183{
0fd3a477
JW
1184 debug ("In md_section_align() segment = %p and size = %lu\n",
1185 segment, (unsigned long) size);
4d5f9b2a
NC
1186 size = (size + 3) / 4;
1187 size *= 4;
0fd3a477 1188 debug ("New size value = %lu\n", (unsigned long) size);
4d5f9b2a
NC
1189 return size;
1190}
1191
1192long
1193md_pcrel_from (fixS *fixP)
1194{
1195 int offset;
1196
1197 debug ("In md_pcrel_from()\n");
0fd3a477 1198 debug ("fx_where = %ld\n", fixP->fx_where);
4d5f9b2a
NC
1199 debug ("fx_size = %d\n", fixP->fx_size);
1200 /* Find the opcode that represents the current instruction in the
1201 fr_literal storage area, and check bit 21. Bit 21 contains whether the
1202 current instruction is a delayed one or not, and then set the offset
1203 value appropriately. */
1204 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1205 offset = 3;
1206 else
1207 offset = 1;
1208 debug ("offset = %d\n", offset);
1209 /* PC Relative instructions have a format:
1210 displacement = Label - (PC + offset)
1211 This function returns PC + offset where:
1212 fx_where - fx_size = PC
1213 INSN_SIZE * offset = offset number of instructions. */
1214 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1215}
1216
6d4af3c2 1217const char *
4d5f9b2a
NC
1218md_atof (int what_statement_type,
1219 char *literalP,
1220 int *sizeP)
1221{
1222 int prec;
1223 char *token;
1224 char keepval;
1225 unsigned long value;
1226 float float_value;
1227
1228 debug ("In md_atof()\n");
1229 debug ("precision = %c\n", what_statement_type);
1230 debug ("literal = %s\n", literalP);
1231 debug ("line = ");
1232 token = input_line_pointer;
1233 while (!is_end_of_line[(unsigned char) *input_line_pointer]
1234 && (*input_line_pointer != ','))
1235 {
1236 debug ("%c", *input_line_pointer);
1237 input_line_pointer++;
1238 }
1239
1240 keepval = *input_line_pointer;
1241 *input_line_pointer = '\0';
1242 debug ("\n");
1243 float_value = (float) atof (token);
1244 *input_line_pointer = keepval;
1245 debug ("float_value = %f\n", float_value);
1246
1247 switch (what_statement_type)
1248 {
1249 case 'f':
1250 case 'F':
1251 case 's':
1252 case 'S':
1253 prec = 2;
1254 break;
1255
1256 case 'd':
1257 case 'D':
1258 case 'r':
1259 case 'R':
1260 prec = 4;
1261 break;
1262
1263 default:
1264 *sizeP = 0;
499ac353 1265 return _("Unrecognized or unsupported floating point constant");
4d5f9b2a
NC
1266 }
1267
1268 if (float_value == 0.0)
1269 value = (prec == 2) ? 0x00008000L : 0x80000000L;
1270 else
1271 {
1272 unsigned long exp, sign, mant, tmsfloat;
1273 union
1274 {
1275 float f;
1276 long l;
1277 }
1278 converter;
1279
1280 converter.f = float_value;
1281 tmsfloat = converter.l;
1282 sign = tmsfloat & 0x80000000;
1283 mant = tmsfloat & 0x007FFFFF;
1284 exp = tmsfloat & 0x7F800000;
1285 exp <<= 1;
1286 if (exp == 0xFF000000)
1287 {
1288 if (mant == 0)
1289 value = 0x7F7FFFFF;
1290 else if (sign == 0)
1291 value = 0x7F7FFFFF;
1292 else
1293 value = 0x7F800000;
1294 }
1295 else
1296 {
1297 exp -= 0x7F000000;
1298 if (sign)
252b5132 1299 {
4d5f9b2a
NC
1300 mant = mant & 0x007FFFFF;
1301 mant = -mant;
1302 mant = mant & 0x00FFFFFF;
1303 if (mant == 0)
1304 {
1305 mant |= 0x00800000;
1306 exp = (long) exp - 0x01000000;
1307 }
1308 }
1309 tmsfloat = exp | mant;
1310 value = tmsfloat;
1311 }
1312 if (prec == 2)
1313 {
91d6fa6a 1314 long expon, mantis;
4d5f9b2a
NC
1315
1316 if (tmsfloat == 0x80000000)
1317 value = 0x8000;
1318 else
1319 {
1320 value = 0;
91d6fa6a
NC
1321 expon = (tmsfloat & 0xFF000000);
1322 expon >>= 24;
1323 mantis = tmsfloat & 0x007FFFFF;
4d5f9b2a
NC
1324 if (tmsfloat & 0x00800000)
1325 {
91d6fa6a
NC
1326 mantis |= 0xFF000000;
1327 mantis += 0x00000800;
1328 mantis >>= 12;
1329 mantis |= 0x00000800;
1330 mantis &= 0x0FFF;
1331 if (expon > 7)
4d5f9b2a
NC
1332 value = 0x7800;
1333 }
1334 else
1335 {
91d6fa6a
NC
1336 mantis |= 0x00800000;
1337 mantis += 0x00000800;
1338 expon += (mantis >> 24);
1339 mantis >>= 12;
1340 mantis &= 0x07FF;
1341 if (expon > 7)
4d5f9b2a
NC
1342 value = 0x77FF;
1343 }
91d6fa6a 1344 if (expon < -8)
4d5f9b2a
NC
1345 value = 0x8000;
1346 if (value == 0)
1347 {
91d6fa6a
NC
1348 mantis = (expon << 12) | mantis;
1349 value = mantis & 0xFFFF;
4d5f9b2a
NC
1350 }
1351 }
1352 }
1353 }
1354 md_number_to_chars (literalP, value, prec);
1355 *sizeP = prec;
499ac353 1356 return NULL;
4d5f9b2a
NC
1357}
1358
1359void
1360md_number_to_chars (char *buf, valueT val, int n)
1361{
1362 debug ("In md_number_to_chars()\n");
1363 number_to_chars_bigendian (buf, val, n);
1364}
1365
1366#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1367#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1368
1369arelent *
1370tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1371{
1372 arelent *rel;
1373 bfd_reloc_code_real_type code = 0;
1374
1375 debug ("In tc_gen_reloc()\n");
1376 debug ("fixP.size = %d\n", fixP->fx_size);
1377 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1378 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1379
1380 switch (F (fixP->fx_size, fixP->fx_pcrel))
1381 {
1382 MAP (1, 0, BFD_RELOC_TIC30_LDP);
1383 MAP (2, 0, BFD_RELOC_16);
1384 MAP (3, 0, BFD_RELOC_24);
1385 MAP (2, 1, BFD_RELOC_16_PCREL);
1386 MAP (4, 0, BFD_RELOC_32);
1387 default:
20203fb9
NC
1388 as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1389 fixP->fx_pcrel ? _("pc-relative ") : "");
4d5f9b2a
NC
1390 }
1391#undef MAP
1392#undef F
1393
1394 rel = xmalloc (sizeof (* rel));
9c2799c2 1395 gas_assert (rel != 0);
4d5f9b2a
NC
1396 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1397 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1398 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1399 rel->addend = 0;
1400 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1401 if (!rel->howto)
1402 {
1403 const char *name;
1404
1405 name = S_GET_NAME (fixP->fx_addsy);
1406 if (name == NULL)
1407 name = "<unknown>";
1408 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1409 name, bfd_get_reloc_code_name (code));
1410 }
1411 return rel;
1412}
1413
1414void
1415md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1416{
1417 debug ("In md_operand()\n");
1418}
1419
1420void
1421md_assemble (char *line)
1422{
91d6fa6a 1423 insn_template *op;
4d5f9b2a
NC
1424 char *current_posn;
1425 char *token_start;
1426 char save_char;
1427 unsigned int count;
1428
1429 debug ("In md_assemble() with argument %s\n", line);
1430 memset (&insn, '\0', sizeof (insn));
1431 if (found_parallel_insn)
1432 {
1433 debug ("Line is second part of parallel instruction\n\n");
1434 found_parallel_insn = 0;
1435 return;
1436 }
1437 if ((current_posn =
1438 tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1439 current_posn = line;
1440 else
1441 found_parallel_insn = 1;
1442
1443 while (is_space_char (*current_posn))
1444 current_posn++;
1445
1446 token_start = current_posn;
1447
1448 if (!is_opcode_char (*current_posn))
1449 {
20203fb9 1450 as_bad (_("Invalid character %s in opcode"),
4d5f9b2a
NC
1451 output_invalid (*current_posn));
1452 return;
1453 }
1454 /* Check if instruction is a parallel instruction
1455 by seeing if the first character is a q. */
1456 if (*token_start == 'q')
1457 {
1458 if (tic30_parallel_insn (token_start))
1459 {
1460 if (found_parallel_insn)
1461 free (token_start);
1462 return;
1463 }
1464 }
1465 while (is_opcode_char (*current_posn))
1466 current_posn++;
1467 {
1468 /* Find instruction. */
1469 save_char = *current_posn;
1470 *current_posn = '\0';
91d6fa6a
NC
1471 op = (insn_template *) hash_find (op_hash, token_start);
1472 if (op)
4d5f9b2a 1473 {
91d6fa6a
NC
1474 debug ("Found instruction %s\n", op->name);
1475 insn.tm = op;
4d5f9b2a
NC
1476 }
1477 else
1478 {
1479 debug ("Didn't find insn\n");
20203fb9 1480 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
4d5f9b2a
NC
1481 return;
1482 }
1483 *current_posn = save_char;
1484 }
1485
1486 if (*current_posn != END_OF_INSN)
1487 {
1488 /* Find operands. */
1489 int paren_not_balanced;
1490 int expecting_operand = 0;
1491 int this_operand;
1492 do
1493 {
1494 /* Skip optional white space before operand. */
1495 while (!is_operand_char (*current_posn)
1496 && *current_posn != END_OF_INSN)
1497 {
1498 if (!is_space_char (*current_posn))
1499 {
20203fb9 1500 as_bad (_("Invalid character %s before %s operand"),
4d5f9b2a
NC
1501 output_invalid (*current_posn),
1502 ordinal_names[insn.operands]);
1503 return;
1504 }
1505 current_posn++;
1506 }
1507 token_start = current_posn;
1508 paren_not_balanced = 0;
1509 while (paren_not_balanced || *current_posn != ',')
1510 {
1511 if (*current_posn == END_OF_INSN)
1512 {
1513 if (paren_not_balanced)
1514 {
20203fb9 1515 as_bad (_("Unbalanced parenthesis in %s operand."),
4d5f9b2a
NC
1516 ordinal_names[insn.operands]);
1517 return;
1518 }
1519 else
1520 break;
1521 }
1522 else if (!is_operand_char (*current_posn)
1523 && !is_space_char (*current_posn))
1524 {
20203fb9 1525 as_bad (_("Invalid character %s in %s operand"),
4d5f9b2a
NC
1526 output_invalid (*current_posn),
1527 ordinal_names[insn.operands]);
1528 return;
1529 }
1530 if (*current_posn == '(')
1531 ++paren_not_balanced;
1532 if (*current_posn == ')')
1533 --paren_not_balanced;
1534 current_posn++;
1535 }
1536 if (current_posn != token_start)
1537 {
1538 /* Yes, we've read in another operand. */
1539 this_operand = insn.operands++;
1540 if (insn.operands > MAX_OPERANDS)
1541 {
20203fb9 1542 as_bad (_("Spurious operands; (%d operands/instruction max)"),
4d5f9b2a
NC
1543 MAX_OPERANDS);
1544 return;
1545 }
1546
1547 /* Now parse operand adding info to 'insn' as we go along. */
1548 save_char = *current_posn;
1549 *current_posn = '\0';
1550 insn.operand_type[this_operand] = tic30_operand (token_start);
1551 *current_posn = save_char;
1552 if (insn.operand_type[this_operand] == NULL)
1553 return;
252b5132 1554 }
4d5f9b2a 1555 else
252b5132 1556 {
4d5f9b2a 1557 if (expecting_operand)
252b5132 1558 {
20203fb9 1559 as_bad (_("Expecting operand after ','; got nothing"));
4d5f9b2a 1560 return;
252b5132 1561 }
4d5f9b2a 1562 if (*current_posn == ',')
252b5132 1563 {
20203fb9 1564 as_bad (_("Expecting operand before ','; got nothing"));
4d5f9b2a 1565 return;
252b5132 1566 }
252b5132 1567 }
4d5f9b2a
NC
1568
1569 /* Now *current_posn must be either ',' or END_OF_INSN. */
1570 if (*current_posn == ',')
252b5132 1571 {
4d5f9b2a 1572 if (*++current_posn == END_OF_INSN)
252b5132 1573 {
4d5f9b2a 1574 /* Just skip it, if it's \n complain. */
20203fb9 1575 as_bad (_("Expecting operand after ','; got nothing"));
4d5f9b2a 1576 return;
252b5132 1577 }
4d5f9b2a 1578 expecting_operand = 1;
252b5132 1579 }
252b5132 1580 }
4d5f9b2a
NC
1581 while (*current_posn != END_OF_INSN);
1582 }
1583
1584 debug ("Number of operands found: %d\n", insn.operands);
1585
1586 /* Check that number of operands is correct. */
1587 if (insn.operands != insn.tm->operands)
1588 {
1589 unsigned int i;
1590 unsigned int numops = insn.tm->operands;
1591
1592 /* If operands are not the same, then see if any of the operands are
1593 not required. Then recheck with number of given operands. If they
1594 are still not the same, then give an error, otherwise carry on. */
1595 for (i = 0; i < insn.tm->operands; i++)
1596 if (insn.tm->operand_types[i] & NotReq)
1597 numops--;
1598 if (insn.operands != numops)
252b5132 1599 {
20203fb9 1600 as_bad (_("Incorrect number of operands given"));
4d5f9b2a 1601 return;
252b5132 1602 }
4d5f9b2a
NC
1603 }
1604 insn.addressing_mode = AM_NotReq;
1605 for (count = 0; count < insn.operands; count++)
1606 {
1607 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
252b5132 1608 {
4d5f9b2a
NC
1609 debug ("Operand %d matches\n", count + 1);
1610 /* If instruction has two operands and has an AddressMode
1611 modifier then set addressing mode type for instruction. */
1612 if (insn.tm->opcode_modifier == AddressMode)
252b5132 1613 {
4d5f9b2a
NC
1614 int addr_insn = 0;
1615 /* Store instruction uses the second
1616 operand for the address mode. */
1617 if ((insn.tm->operand_types[1] & (Indirect | Direct))
1618 == (Indirect | Direct))
1619 addr_insn = 1;
1620
1621 if (insn.operand_type[addr_insn]->op_type & (AllReg))
1622 insn.addressing_mode = AM_Register;
1623 else if (insn.operand_type[addr_insn]->op_type & Direct)
1624 insn.addressing_mode = AM_Direct;
1625 else if (insn.operand_type[addr_insn]->op_type & Indirect)
1626 insn.addressing_mode = AM_Indirect;
1627 else
1628 insn.addressing_mode = AM_Immediate;
252b5132
RH
1629 }
1630 }
1631 else
1632 {
20203fb9 1633 as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
4d5f9b2a 1634 return;
252b5132 1635 }
252b5132 1636 }
4d5f9b2a
NC
1637
1638 /* Now set the addressing mode for 3 operand instructions. */
1639 if ((insn.tm->operand_types[0] & op3T1)
1640 && (insn.tm->operand_types[1] & op3T2))
252b5132 1641 {
4d5f9b2a
NC
1642 /* Set the addressing mode to the values used for 2 operand
1643 instructions in the G addressing field of the opcode. */
1644 char *p;
1645 switch (insn.operand_type[0]->op_type)
252b5132 1646 {
4d5f9b2a
NC
1647 case Rn:
1648 case ARn:
1649 case DPReg:
1650 case OtherReg:
1651 if (insn.operand_type[1]->op_type & (AllReg))
1652 insn.addressing_mode = AM_Register;
1653 else if (insn.operand_type[1]->op_type & Indirect)
1654 insn.addressing_mode = AM_Direct;
252b5132 1655 else
252b5132 1656 {
4d5f9b2a 1657 /* Shouldn't make it to this stage. */
20203fb9 1658 as_bad (_("Incompatible first and second operands in instruction"));
4d5f9b2a 1659 return;
252b5132 1660 }
4d5f9b2a
NC
1661 break;
1662 case Indirect:
1663 if (insn.operand_type[1]->op_type & (AllReg))
1664 insn.addressing_mode = AM_Indirect;
1665 else if (insn.operand_type[1]->op_type & Indirect)
1666 insn.addressing_mode = AM_Immediate;
252b5132
RH
1667 else
1668 {
4d5f9b2a 1669 /* Shouldn't make it to this stage. */
20203fb9 1670 as_bad (_("Incompatible first and second operands in instruction"));
4d5f9b2a
NC
1671 return;
1672 }
1673 break;
1674 }
1675 /* Now make up the opcode for the 3 operand instructions. As in
1676 parallel instructions, there will be no unresolved values, so they
1677 can be fully formed and added to the frag table. */
1678 insn.opcode = insn.tm->base_opcode;
1679 if (insn.operand_type[0]->op_type & Indirect)
252b5132 1680 {
4d5f9b2a
NC
1681 insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1682 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1683 }
1684 else
1685 insn.opcode |= (insn.operand_type[0]->reg.opcode);
252b5132 1686
4d5f9b2a
NC
1687 if (insn.operand_type[1]->op_type & Indirect)
1688 {
1689 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1690 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1691 }
1692 else
1693 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1694
1695 if (insn.operands == 3)
1696 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1697
1698 insn.opcode |= insn.addressing_mode;
1699 p = frag_more (INSN_SIZE);
1700 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1701 }
1702 else
1703 {
1704 /* Not a three operand instruction. */
1705 char *p;
1706 int am_insn = -1;
1707 insn.opcode = insn.tm->base_opcode;
1708 /* Create frag for instruction - all instructions are 4 bytes long. */
1709 p = frag_more (INSN_SIZE);
1710 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1711 {
1712 insn.opcode |= insn.addressing_mode;
1713 if (insn.addressing_mode == AM_Indirect)
252b5132 1714 {
4d5f9b2a
NC
1715 /* Determine which operand gives the addressing mode. */
1716 if (insn.operand_type[0]->op_type & Indirect)
1717 am_insn = 0;
1718 if ((insn.operands > 1)
1719 && (insn.operand_type[1]->op_type & Indirect))
1720 am_insn = 1;
1721 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1722 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1723 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1724 if (insn.operands > 1)
1725 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1726 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1727 }
1728 else if (insn.addressing_mode == AM_Register)
1729 {
1730 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1731 if (insn.operands > 1)
1732 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1733 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1734 }
1735 else if (insn.addressing_mode == AM_Direct)
1736 {
1737 if (insn.operand_type[0]->op_type & Direct)
1738 am_insn = 0;
1739 if ((insn.operands > 1)
1740 && (insn.operand_type[1]->op_type & Direct))
1741 am_insn = 1;
1742 if (insn.operands > 1)
1743 insn.opcode |=
1744 (insn.operand_type[! am_insn]->reg.opcode << 16);
1745 if (insn.operand_type[am_insn]->direct.resolved == 1)
252b5132 1746 {
4d5f9b2a
NC
1747 /* Resolved values can be placed straight
1748 into instruction word, and output. */
1749 insn.opcode |=
1750 (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1751 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
252b5132 1752 }
4d5f9b2a 1753 else
252b5132 1754 {
4d5f9b2a
NC
1755 /* Unresolved direct addressing mode instruction. */
1756 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1757 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1758 & insn.operand_type[am_insn]->direct.direct_expr,
1759 0, 0);
252b5132 1760 }
252b5132 1761 }
4d5f9b2a
NC
1762 else if (insn.addressing_mode == AM_Immediate)
1763 {
1764 if (insn.operand_type[0]->immediate.resolved == 1)
1765 {
1766 char *keeploc;
1767 int size;
252b5132 1768
4d5f9b2a
NC
1769 if (insn.operands > 1)
1770 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
252b5132 1771
4d5f9b2a
NC
1772 switch (insn.tm->imm_arg_type)
1773 {
1774 case Imm_Float:
1775 debug ("Floating point first operand\n");
1776 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
252b5132 1777
4d5f9b2a
NC
1778 keeploc = input_line_pointer;
1779 input_line_pointer =
1780 insn.operand_type[0]->immediate.label;
252b5132 1781
4d5f9b2a
NC
1782 if (md_atof ('f', p + 2, & size) != 0)
1783 {
20203fb9 1784 as_bad (_("invalid short form floating point immediate operand"));
4d5f9b2a
NC
1785 return;
1786 }
252b5132 1787
4d5f9b2a
NC
1788 input_line_pointer = keeploc;
1789 break;
252b5132 1790
4d5f9b2a
NC
1791 case Imm_UInt:
1792 debug ("Unsigned int first operand\n");
1793 if (insn.operand_type[0]->immediate.decimal_found)
20203fb9 1794 as_warn (_("rounding down first operand float to unsigned int"));
4d5f9b2a 1795 if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
20203fb9 1796 as_warn (_("only lower 16-bits of first operand are used"));
4d5f9b2a
NC
1797 insn.opcode |=
1798 (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1799 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1800 break;
252b5132 1801
4d5f9b2a
NC
1802 case Imm_SInt:
1803 debug ("Int first operand\n");
252b5132 1804
4d5f9b2a 1805 if (insn.operand_type[0]->immediate.decimal_found)
20203fb9 1806 as_warn (_("rounding down first operand float to signed int"));
4d5f9b2a
NC
1807
1808 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1809 insn.operand_type[0]->immediate.s_number > 32767)
1810 {
20203fb9 1811 as_bad (_("first operand is too large for 16-bit signed int"));
4d5f9b2a
NC
1812 return;
1813 }
1814 insn.opcode |=
1815 (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1816 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1817 break;
1818 }
1819 }
1820 else
1821 {
1822 /* Unresolved immediate label. */
1823 if (insn.operands > 1)
1824 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1825 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1826 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1827 & insn.operand_type[0]->immediate.imm_expr,
1828 0, 0);
1829 }
1830 }
252b5132 1831 }
4d5f9b2a 1832 else if (insn.tm->opcode_modifier == PCRel)
252b5132 1833 {
4d5f9b2a
NC
1834 /* Conditional Branch and Call instructions. */
1835 if ((insn.tm->operand_types[0] & (AllReg | Disp))
1836 == (AllReg | Disp))
252b5132 1837 {
4d5f9b2a 1838 if (insn.operand_type[0]->op_type & (AllReg))
252b5132 1839 {
4d5f9b2a
NC
1840 insn.opcode |= (insn.operand_type[0]->reg.opcode);
1841 insn.opcode |= PC_Register;
1842 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1843 }
1844 else
1845 {
1846 insn.opcode |= PC_Relative;
1847 if (insn.operand_type[0]->immediate.resolved == 1)
1848 {
1849 insn.opcode |=
1850 (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1851 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1852 }
1853 else
1854 {
1855 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1856 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1857 2, & insn.operand_type[0]->immediate.imm_expr,
1858 1, 0);
1859 }
1860 }
1861 }
1862 else if ((insn.tm->operand_types[0] & ARn) == ARn)
1863 {
1864 /* Decrement and Branch instructions. */
1865 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1866 if (insn.operand_type[1]->op_type & (AllReg))
1867 {
1868 insn.opcode |= (insn.operand_type[1]->reg.opcode);
1869 insn.opcode |= PC_Register;
1870 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1871 }
1872 else if (insn.operand_type[1]->immediate.resolved == 1)
1873 {
1874 if (insn.operand_type[0]->immediate.decimal_found)
1875 {
20203fb9 1876 as_bad (_("first operand is floating point"));
4d5f9b2a
NC
1877 return;
1878 }
1879 if (insn.operand_type[0]->immediate.s_number < -32768 ||
1880 insn.operand_type[0]->immediate.s_number > 32767)
1881 {
20203fb9 1882 as_bad (_("first operand is too large for 16-bit signed int"));
4d5f9b2a
NC
1883 return;
1884 }
1885 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1886 insn.opcode |= PC_Relative;
1887 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1888 }
1889 else
1890 {
1891 insn.opcode |= PC_Relative;
1892 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1893 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1894 & insn.operand_type[1]->immediate.imm_expr,
1895 1, 0);
252b5132
RH
1896 }
1897 }
252b5132 1898 }
4d5f9b2a 1899 else if (insn.tm->operand_types[0] == IVector)
252b5132 1900 {
4d5f9b2a
NC
1901 /* Trap instructions. */
1902 if (insn.operand_type[0]->op_type & IVector)
1903 insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1904 else
252b5132 1905 {
4d5f9b2a 1906 /* Shouldn't get here. */
20203fb9 1907 as_bad (_("interrupt vector for trap instruction out of range"));
4d5f9b2a 1908 return;
252b5132 1909 }
4d5f9b2a
NC
1910 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1911 }
1912 else if (insn.tm->opcode_modifier == StackOp
1913 || insn.tm->opcode_modifier == Rotate)
1914 {
1915 /* Push, Pop and Rotate instructions. */
1916 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1917 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1918 }
1919 else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1920 == (Abs24 | Direct))
1921 {
1922 /* LDP Instruction needs to be tested
1923 for before the next section. */
1924 if (insn.operand_type[0]->op_type & Direct)
252b5132 1925 {
4d5f9b2a 1926 if (insn.operand_type[0]->direct.resolved == 1)
252b5132 1927 {
4d5f9b2a
NC
1928 /* Direct addressing uses lower 8 bits of direct address. */
1929 insn.opcode |=
1930 (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1931 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
252b5132
RH
1932 }
1933 else
1934 {
4d5f9b2a
NC
1935 fixS *fix;
1936
1937 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1938 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1939 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1940 /* Ensure that the assembler doesn't complain
1941 about fitting a 24-bit address into 8 bits. */
1942 fix->fx_no_overflow = 1;
252b5132 1943 }
4d5f9b2a
NC
1944 }
1945 else
1946 {
1947 if (insn.operand_type[0]->immediate.resolved == 1)
252b5132 1948 {
4d5f9b2a
NC
1949 /* Immediate addressing uses upper 8 bits of address. */
1950 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1951 {
20203fb9 1952 as_bad (_("LDP instruction needs a 24-bit operand"));
4d5f9b2a
NC
1953 return;
1954 }
1955 insn.opcode |=
1956 ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1957 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1958 }
1959 else
1960 {
1961 fixS *fix;
1962 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1963 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1964 1, &insn.operand_type[0]->immediate.imm_expr,
1965 0, 0);
1966 fix->fx_no_overflow = 1;
252b5132
RH
1967 }
1968 }
1969 }
4d5f9b2a
NC
1970 else if (insn.tm->operand_types[0] & (Imm24))
1971 {
1972 /* Unconditional Branch and Call instructions. */
1973 if (insn.operand_type[0]->immediate.resolved == 1)
1974 {
1975 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
20203fb9 1976 as_warn (_("first operand is too large for a 24-bit displacement"));
4d5f9b2a
NC
1977 insn.opcode |=
1978 (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1979 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1980 }
1981 else
1982 {
1983 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1984 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1985 & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1986 }
1987 }
1988 else if (insn.tm->operand_types[0] & NotReq)
1989 /* Check for NOP instruction without arguments. */
1990 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
252b5132 1991
4d5f9b2a
NC
1992 else if (insn.tm->operands == 0)
1993 /* Check for instructions without operands. */
1994 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
252b5132 1995 }
4d5f9b2a
NC
1996 debug ("Addressing mode: %08X\n", insn.addressing_mode);
1997 {
1998 unsigned int i;
252b5132 1999
4d5f9b2a
NC
2000 for (i = 0; i < insn.operands; i++)
2001 {
2002 if (insn.operand_type[i]->immediate.label)
2003 free (insn.operand_type[i]->immediate.label);
2004 free (insn.operand_type[i]);
2005 }
2006 }
2007 debug ("Final opcode: %08X\n", insn.opcode);
2008 debug ("\n");
252b5132 2009}
This page took 0.812522 seconds and 4 git commands to generate.