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