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