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