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