Rearrange symbol_create parameters
[deliverable/binutils-gdb.git] / gas / config / tc-dlx.c
CommitLineData
df7b86aa 1/* tc-dlx.c -- Assemble for the DLX
b3adc24a 2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
d172d4ba
NC
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
ec2655a6 8 the Free Software Foundation; either version 3, or (at your option)
d172d4ba
NC
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
d172d4ba
NC
20
21/* Initially created by Kuang Hwa Lin, 3/20/2002. */
22
d172d4ba 23#include "as.h"
df7b86aa 24#include "safe-ctype.h"
d172d4ba
NC
25#include "tc-dlx.h"
26#include "opcode/dlx.h"
48afb194
TS
27#include "elf/dlx.h"
28#include "bfd/elf32-dlx.h"
d172d4ba
NC
29
30/* Make it easier to clone this machine desc into another one. */
31#define machine_opcode dlx_opcode
32#define machine_opcodes dlx_opcodes
33#define machine_ip dlx_ip
34#define machine_it dlx_it
35
36#define NO_RELOC BFD_RELOC_NONE
37#define RELOC_DLX_REL26 BFD_RELOC_DLX_JMP26
38#define RELOC_DLX_16 BFD_RELOC_16
39#define RELOC_DLX_REL16 BFD_RELOC_16_PCREL_S2
40#define RELOC_DLX_HI16 BFD_RELOC_HI16_S
41#define RELOC_DLX_LO16 BFD_RELOC_LO16
42#define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT
43#define RELOC_DLX_VTENTRY BFD_RELOC_VTABLE_ENTRY
44
45/* handle of the OPCODE hash table */
629310ab 46static htab_t op_hash = NULL;
d172d4ba
NC
47
48struct machine_it
49{
50 char *error;
51 unsigned long opcode;
52 struct nlist *nlistp;
53 expressionS exp;
54 int pcrel;
55 int size;
56 int reloc_offset; /* Offset of reloc within insn. */
4bfaa1ca 57 bfd_reloc_code_real_type reloc;
d172d4ba
NC
58 int HI;
59 int LO;
60}
61the_insn;
62
d172d4ba
NC
63/* This array holds the chars that always start a comment. If the
64 pre-processor is disabled, these aren't very useful. */
65const char comment_chars[] = ";";
66
67/* This array holds the chars that only start a comment at the beginning of
68 a line. If the line seems to have the form '# 123 filename'
69 .line and .file directives will appear in the pre-processed output. */
70/* Note that input_file.c hand checks for '#' at the beginning of the
71 first line of the input file. This is because the compiler outputs
72 #NO_APP at the beginning of its output. */
73/* Also note that comments like this one will always work. */
74const char line_comment_chars[] = "#";
75
76/* We needed an unused char for line separation to work around the
77 lack of macros, using sed and such. */
78const char line_separator_chars[] = "@";
79
80/* Chars that can be used to separate mant from exp in floating point nums. */
81const char EXP_CHARS[] = "eE";
82
83/* Chars that mean this number is a floating point constant.
84 As in 0f12.456
85 or 0d1.2345e12. */
86const char FLT_CHARS[] = "rRsSfFdDxXpP";
87
88static void
e0471c16 89insert_sreg (const char *regname, int regnum)
d172d4ba
NC
90{
91 /* Must be large enough to hold the names of the special registers. */
92 char buf[80];
93 int i;
94
e01e1cee
AM
95 symbol_table_insert (symbol_new (regname, reg_section,
96 &zero_address_frag, regnum));
d172d4ba
NC
97 for (i = 0; regname[i]; i++)
98 buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
99 buf[i] = '\0';
100
e01e1cee
AM
101 symbol_table_insert (symbol_new (buf, reg_section,
102 &zero_address_frag, regnum));
d172d4ba
NC
103}
104
105/* Install symbol definitions for assorted special registers.
106 See MIPS Assembly Language Programmer's Guide page 1-4 */
107
108static void
ea1562b3 109define_some_regs (void)
d172d4ba 110{
d172d4ba
NC
111 /* Software representation. */
112 insert_sreg ("zero", 0);
113 insert_sreg ("at", 1);
114 insert_sreg ("v0", 2);
115 insert_sreg ("v1", 3);
116 insert_sreg ("a0", 4);
117 insert_sreg ("a1", 5);
118 insert_sreg ("a2", 6);
119 insert_sreg ("a3", 7);
120 insert_sreg ("t0", 8);
121 insert_sreg ("t1", 9);
122 insert_sreg ("t2", 10);
123 insert_sreg ("t3", 11);
124 insert_sreg ("t4", 12);
125 insert_sreg ("t5", 13);
126 insert_sreg ("t6", 14);
127 insert_sreg ("t7", 15);
128 insert_sreg ("s0", 16);
129 insert_sreg ("s1", 17);
130 insert_sreg ("s2", 18);
131 insert_sreg ("s3", 19);
132 insert_sreg ("s4", 20);
133 insert_sreg ("s5", 21);
134 insert_sreg ("s6", 22);
135 insert_sreg ("s7", 23);
136 insert_sreg ("t8", 24);
137 insert_sreg ("t9", 25);
138 insert_sreg ("k0", 26);
139 insert_sreg ("k1", 27);
140 insert_sreg ("gp", 28);
141 insert_sreg ("sp", 29);
142 insert_sreg ("fp", 30);
143 insert_sreg ("ra", 31);
144 /* Special registers. */
145 insert_sreg ("pc", 0);
146 insert_sreg ("npc", 1);
147 insert_sreg ("iad", 2);
148}
149
ea1562b3 150/* Subroutine check the string to match an register. */
d172d4ba
NC
151
152static int
ea1562b3 153match_sft_register (char *name)
d172d4ba
NC
154{
155#define MAX_REG_NO 35
156/* Currently we have 35 software registers defined -
157 we borrowed from MIPS. */
e0471c16 158 static const char *soft_reg[] =
d172d4ba
NC
159 {
160 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
161 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9",
162 "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1",
163 "gp", "sp", "fp", "ra", "pc", "npc", "iad",
164 "EndofTab" /* End of the Table indicator */
165 };
166 char low_name[21], *ptr;
167 int idx;
168
169 for (ptr = name,idx = 0; *ptr != '\0'; ptr++)
170 low_name[idx++] = TOLOWER (*ptr);
171
172 low_name[idx] = '\0';
173 idx = 0;
174
175 while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0]))
176 idx += 1;
177
178 return idx < MAX_REG_NO;
179}
180
181/* Subroutine check the string to match an register. */
182
183static int
ea1562b3 184is_ldst_registers (char *name)
d172d4ba
NC
185{
186 char *ptr = name;
187
188 /* The first character of the register name got to be either %, $, r of R. */
189 if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R')
190 && ISDIGIT ((unsigned char) ptr[1]))
191 return 1;
192
193 /* Now check the software register representation. */
194 return match_sft_register (ptr);
195}
196
197/* Subroutine of s_proc so targets can choose a different default prefix.
198 If DEFAULT_PREFIX is NULL, use the target's "leading char". */
199
200static void
ea1562b3 201s_proc (int end_p)
d172d4ba
NC
202{
203 /* Record the current function so that we can issue an error message for
204 misplaced .func,.endfunc, and also so that .endfunc needs no
205 arguments. */
206 static char *current_name;
207 static char *current_label;
208
209 if (end_p)
210 {
211 if (current_name == NULL)
212 {
213 as_bad (_("missing .proc"));
214 ignore_rest_of_line ();
215 return;
216 }
217
218 current_name = current_label = NULL;
219 SKIP_WHITESPACE ();
220 while (!is_end_of_line[(unsigned char) *input_line_pointer])
221 input_line_pointer++;
222 }
223 else
224 {
225 char *name, *label;
226 char delim1, delim2;
227
228 if (current_name != NULL)
229 {
230 as_bad (_(".endfunc missing for previous .proc"));
231 ignore_rest_of_line ();
232 return;
233 }
234
d02603dc 235 delim1 = get_symbol_name (&name);
d172d4ba
NC
236 name = xstrdup (name);
237 *input_line_pointer = delim1;
d02603dc 238 SKIP_WHITESPACE_AFTER_NAME ();
d172d4ba
NC
239
240 if (*input_line_pointer != ',')
241 {
242 char leading_char = 0;
243
244 leading_char = bfd_get_symbol_leading_char (stdoutput);
245 /* Missing entry point, use function's name with the leading
246 char prepended. */
247 if (leading_char)
74cda0c4 248 {
f3719d90 249 unsigned len = strlen (name) + 1;
325801bd 250 label = XNEWVEC (char, len + 1);
f3719d90
AM
251 label[0] = leading_char;
252 memcpy (label + 1, name, len);
74cda0c4 253 }
d172d4ba
NC
254 else
255 label = name;
256 }
257 else
258 {
259 ++input_line_pointer;
260 SKIP_WHITESPACE ();
d02603dc 261 delim2 = get_symbol_name (&label);
d172d4ba 262 label = xstrdup (label);
d02603dc 263 (void) restore_line_pointer (delim2);
d172d4ba
NC
264 }
265
266 current_name = name;
267 current_label = label;
268 }
269 demand_empty_rest_of_line ();
270}
271
272/* This function is called once, at assembler startup time. It should
273 set up all the tables, etc., that the MD part of the assembler will
274 need. */
275
276void
ea1562b3 277md_begin (void)
d172d4ba 278{
d172d4ba
NC
279 unsigned int i;
280
281 /* Create a new hash table. */
629310ab 282 op_hash = str_htab_create ();
d172d4ba
NC
283
284 /* Hash up all the opcodes for fast use later. */
285 for (i = 0; i < num_dlx_opcodes; i++)
286 {
287 const char *name = machine_opcodes[i].name;
629310ab 288 str_hash_insert (op_hash, name, (void *) &machine_opcodes[i]);
d172d4ba
NC
289 }
290
d172d4ba 291 define_some_regs ();
d172d4ba
NC
292}
293
d172d4ba
NC
294/* This function will check the opcode and return 1 if the opcode is one
295 of the load/store instruction, and it will fix the operand string to
296 the standard form so we can use the standard parse_operand routine. */
297
298#define READ_OP 0x100
299#define WRITE_OP 0x200
300static char iBuf[81];
301
302static char *
ea1562b3 303dlx_parse_loadop (char * str)
d172d4ba
NC
304{
305 char *ptr = str;
306 int idx = 0;
307
308 /* The last pair of ()/[] is the register, all other are the
309 reloc displacement, and if there is a register then it ought
310 to have a pair of ()/[]
311 This is not necessarily true, what if the load instruction come
312 without the register and with %hi/%lo modifier? */
313 for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++)
314 ;
315
316 if (idx == 72)
317 {
318 badoperand_load:
319 as_bad (_("Bad operand for a load instruction: <%s>"), str);
320 return NULL;
321 }
322 else
323 {
324 int i, pb = 0;
325 int m2 = 0;
326 char rs1[7], rd[7], endm, match = '0';
327 char imm[72];
328
329 idx -= 1;
330 switch (str[idx])
331 {
332 case ')':
333 match = '(';
334 endm = ')';
335 break;
336 case ']':
337 match = '[';
338 endm = ']';
339 break;
340 default:
341 /* No register indicated, fill in zero. */
342 rs1[0] = 'r';
343 rs1[1] = '0';
344 rs1[2] = '\0';
345 match = 0;
346 endm = 0;
347 m2 = 1;
348 }
349
350 if (!m2)
351 {
352 /* Searching for (/[ which will match the ]/). */
353 for (pb = idx - 1; str[pb] != match; pb -= 1)
354 /* Match can only be either '[' or '(', if it is
c03099e6 355 '(' then this can be a normal expression, we'll treat
d172d4ba
NC
356 it as an operand. */
357 if (str[pb] == endm || pb < (idx - 5))
358 goto load_no_rs1;
359 pb += 1;
360
361 for (i = 0; (pb + i) < idx; i++)
362 rs1[i] = str[pb+i];
363
364 rs1[i] = '\0';
365
366 if (is_ldst_registers (& rs1[0]))
367 /* Point to the last character of the imm. */
368 pb -= 1;
369 else
370 {
371 load_no_rs1:
372 if (match == '[')
373 goto badoperand_load;
374 /* No register indicated, fill in zero and restore the imm. */
375 rs1[0] = 'r';
376 rs1[1] = '0';
377 rs1[2] = '\0';
378 m2 = 1;
379 }
380 }
381
382 /* Duplicate the first register. */
383 for (i = 0; i < 7 && str[i] != ','; i++)
384 rd[i] = ptr[i];
385
386 if (str[i] != ',')
387 goto badoperand_load;
388 else
389 rd[i] = '\0';
390
391 /* Copy the immd. */
392 if (m2)
393 /* Put the '\0' back in. */
394 pb = idx + 1;
395
396 for (i++, m2 = 0; i < pb; m2++,i++)
397 imm[m2] = ptr[i];
398
399 imm[m2] = '\0';
400
2d2255b5 401 /* Assemble the instruction to gas internal format. */
d172d4ba
NC
402 for (i = 0; rd[i] != '\0'; i++)
403 iBuf[i] = rd[i];
404
405 iBuf[i++] = ',';
406
407 for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
408 iBuf[i] = rs1[pb];
409
410 iBuf[i++] = ',';
411
412 for (pb = 0; imm[pb] != '\0'; i++, pb++)
413 iBuf[i] = imm[pb];
414
415 iBuf[i] = '\0';
416 return iBuf;
417 }
418}
419
420static char *
ea1562b3 421dlx_parse_storeop (char * str)
d172d4ba
NC
422{
423 char *ptr = str;
424 int idx = 0;
425
426 /* Search for the ','. */
427 for (idx = 0; idx < 72 && ptr[idx] != ','; idx++)
428 ;
429
430 if (idx == 72)
431 {
432 badoperand_store:
433 as_bad (_("Bad operand for a store instruction: <%s>"), str);
434 return NULL;
435 }
436 else
437 {
438 /* idx now points to the ','. */
439 int i, pb = 0;
440 int comma = idx;
441 int m2 = 0;
442 char rs1[7], rd[7], endm, match = '0';
443 char imm[72];
444
445 /* Now parse the '(' and ')', and make idx point to ')'. */
446 idx -= 1;
447 switch (str[idx])
448 {
449 case ')':
450 match = '(';
451 endm = ')';
452 break;
453 case ']':
454 match = '[';
455 endm = ']';
456 break;
457 default:
458 /* No register indicated, fill in zero. */
459 rs1[0] = 'r';
460 rs1[1] = '0';
461 rs1[2] = '\0';
462 match = 0;
463 endm = 0;
464 m2 = 1;
465 }
466
467 if (!m2)
468 {
469 /* Searching for (/[ which will match the ]/). */
470 for (pb = idx - 1; str[pb] != match; pb -= 1)
471 if (pb < (idx - 5) || str[pb] == endm)
472 goto store_no_rs1;
473 pb += 1;
474
475 for (i = 0; (pb + i) < idx; i++)
476 rs1[i] = str[pb + i];
477
478 rs1[i] = '\0';
479
480 if (is_ldst_registers (& rs1[0]))
481 /* Point to the last character of the imm. */
482 pb -= 1;
483 else
484 {
485 store_no_rs1:
486 if (match == '[')
487 goto badoperand_store;
488
489 /* No register indicated, fill in zero and restore the imm. */
490 rs1[0] = 'r';
491 rs1[1] = '0';
492 rs1[2] = '\0';
493 pb = comma;
494 }
495 }
496 else
497 /* No register was specified. */
498 pb = comma;
499
500 /* Duplicate the first register. */
501 for (i = comma + 1; (str[i] == ' ' || str[i] == '\t'); i++)
502 ;
503
504 for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++)
505 {
506 if (str[i] != ' ' && str[i] != '\t')
507 rd[m2] = str[i];
508 else
509 goto badoperand_store;
510 }
511
512 if (str[i] != '\0')
513 goto badoperand_store;
514 else
515 rd[m2] = '\0';
516
517 /* Copy the immd. */
518 for (i = 0; i < pb; i++)
519 imm[i] = ptr[i];
520
521 imm[i] = '\0';
522
2d2255b5 523 /* Assemble the instruction to gas internal format. */
d172d4ba
NC
524 for (i = 0; rd[i] != '\0'; i++)
525 iBuf[i] = rd[i];
526 iBuf[i++] = ',';
527 for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
528 iBuf[i] = rs1[pb];
529 iBuf[i++] = ',';
530 for (pb = 0; imm[pb] != '\0'; i++, pb++)
531 iBuf[i] = imm[pb];
532 iBuf[i] = '\0';
533 return iBuf;
534 }
535}
536
537static char *
ea1562b3 538fix_ld_st_operand (unsigned long opcode, char* str)
d172d4ba
NC
539{
540 /* Check the opcode. */
541 switch ((int) opcode)
542 {
543 case LBOP:
544 case LBUOP:
545 case LSBUOP:
546 case LHOP:
547 case LHUOP:
548 case LSHUOP:
549 case LWOP:
550 case LSWOP:
551 return dlx_parse_loadop (str);
552 case SBOP:
553 case SHOP:
554 case SWOP:
555 return dlx_parse_storeop (str);
556 default:
557 return str;
558 }
559}
560
ea1562b3
NC
561static int
562hilo_modifier_ok (char *s)
563{
564 char *ptr = s;
565 int idx, count = 1;
566
567 if (*ptr != '(')
568 return 1;
569
570 for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1)
571 {
572 if (count == 0)
573 return count;
574
575 if (ptr[idx] == '(')
576 count += 1;
577
578 if (ptr[idx] == ')')
579 count -= 1;
580 }
581
582 return (count == 0) ? 1:0;
583}
584
585static char *
586parse_operand (char *s, expressionS *operandp)
587{
588 char *save = input_line_pointer;
d3ce72d0 589 char *new_pos;
ea1562b3
NC
590
591 the_insn.HI = the_insn.LO = 0;
592
593 /* Search for %hi and %lo, make a mark and skip it. */
594 if (strncmp (s, "%hi", 3) == 0)
595 {
596 s += 3;
597 the_insn.HI = 1;
598 }
599 else
600 {
601 if (strncmp (s, "%lo", 3) == 0)
602 {
603 s += 3;
604 the_insn.LO = 1;
605 }
606 else
607 the_insn.LO = 0;
608 }
609
610 if (the_insn.HI || the_insn.LO)
611 {
612 if (!hilo_modifier_ok (s))
613 as_bad (_("Expression Error for operand modifier %%hi/%%lo\n"));
614 }
615
616 /* Check for the % and $ register representation */
617 if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R')
618 && ISDIGIT ((unsigned char) s[1]))
619 {
620 /* We have a numeric register expression. No biggy. */
621 s += 1;
622 input_line_pointer = s;
623 (void) expression (operandp);
624 if (operandp->X_op != O_constant
625 || operandp->X_add_number > 31)
626 as_bad (_("Invalid expression after %%%%\n"));
627 operandp->X_op = O_register;
628 }
629 else
630 {
631 /* Normal operand parsing. */
632 input_line_pointer = s;
633 (void) expression (operandp);
634 }
635
d3ce72d0 636 new_pos = input_line_pointer;
ea1562b3 637 input_line_pointer = save;
d3ce72d0 638 return new_pos;
ea1562b3
NC
639}
640
d172d4ba
NC
641/* Instruction parsing. Takes a string containing the opcode.
642 Operands are at input_line_pointer. Output is in the_insn.
643 Warnings or errors are generated. */
644
645static void
ea1562b3 646machine_ip (char *str)
d172d4ba
NC
647{
648 char *s;
649 const char *args;
650 struct machine_opcode *insn;
d172d4ba
NC
651 unsigned long opcode;
652 expressionS the_operand;
653 expressionS *operand = &the_operand;
654 unsigned int reg, reg_shift = 0;
655
97d24fbb
AM
656 memset (&the_insn, '\0', sizeof (the_insn));
657 the_insn.reloc = NO_RELOC;
658
d172d4ba
NC
659 /* Fixup the opcode string to all lower cases, and also
660 allow numerical digits. */
661 s = str;
662
663 if (ISALPHA (*s))
664 for (; ISALNUM (*s); ++s)
665 if (ISUPPER (*s))
666 *s = TOLOWER (*s);
667
668 switch (*s)
669 {
670 case '\0':
671 break;
672
673 /* FIXME-SOMEDAY more whitespace. */
674 case ' ':
675 *s++ = '\0';
676 break;
677
678 default:
679 as_bad (_("Unknown opcode: `%s'"), str);
680 return;
681 }
682
97d24fbb 683 /* Hash the opcode, insn will have the string from opcode table. */
629310ab 684 if ((insn = (struct machine_opcode *) str_hash_find (op_hash, str)) == NULL)
d172d4ba
NC
685 {
686 /* Handle the ret and return macro here. */
687 if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0))
97d24fbb 688 the_insn.opcode = JROP | 0x03e00000; /* 0x03e00000 = r31 << 21 */
d172d4ba
NC
689 else
690 as_bad (_("Unknown opcode `%s'."), str);
691
692 return;
693 }
694
d172d4ba 695 opcode = insn->opcode;
d172d4ba
NC
696
697 /* Set the sip reloc HI16 flag. */
698 if (!set_dlx_skip_hi16_flag (1))
699 as_bad (_("Can not set dlx_skip_hi16_flag"));
700
701 /* Fix the operand string if it is one of load store instructions. */
702 s = fix_ld_st_operand (opcode, s);
703
704 /* Build the opcode, checking as we go to make sure that the
705 operands match.
706 If an operand matches, we modify the_insn or opcode appropriately,
707 and do a "continue". If an operand fails to match, we "break". */
708 if (insn->args[0] != '\0' && insn->args[0] != 'N')
709 {
710 /* Prime the pump. */
711 if (*s == '\0')
712 {
713 as_bad (_("Missing arguments for opcode <%s>."), str);
714 return;
715 }
716 else
717 s = parse_operand (s, operand);
718 }
719 else if (insn->args[0] == 'N')
720 {
721 /* Clean up the insn and done! */
722 the_insn.opcode = opcode;
723 return;
724 }
725
726 /* Parse through the args (this is from opcode table), *s point to
727 the current character of the instruction stream. */
728 for (args = insn->args;; ++args)
729 {
730 switch (*args)
731 {
732 /* End of Line. */
733 case '\0':
734 /* End of args. */
735 if (*s == '\0')
736 {
737 /* We are truly done. */
738 the_insn.opcode = opcode;
739 /* Clean up the HI and LO mark. */
740 the_insn.HI = 0;
741 the_insn.LO = 0;
742 return;
743 }
744
745 the_insn.HI = 0;
746 the_insn.LO = 0;
747 as_bad (_("Too many operands: %s"), s);
748 break;
749
750 /* ',' Args separator */
751 case ',':
752 /* Must match a comma. */
753 if (*s++ == ',')
754 {
755 /* Parse next operand. */
756 s = parse_operand (s, operand);
757 continue;
758 }
759 break;
760
761 /* It can be a 'a' register or 'i' operand. */
762 case 'P':
763 /* Macro move operand/reg. */
764 if (operand->X_op == O_register)
765 {
33eaf5de 766 /* It's a register. */
d172d4ba
NC
767 reg_shift = 21;
768 goto general_reg;
769 }
1a0670f3 770 /* Fall through. */
d172d4ba
NC
771
772 /* The immediate 16 bits literal, bit 0-15. */
773 case 'i':
774 /* offset, unsigned. */
775 case 'I':
776 /* offset, signed. */
777 if (operand->X_op == O_constant)
778 {
779 if (the_insn.HI)
780 operand->X_add_number >>= 16;
781
782 opcode |= operand->X_add_number & 0xFFFF;
783
784 if (the_insn.HI && the_insn.LO)
785 as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s);
786 else
787 {
788 the_insn.HI = 0;
789 the_insn.LO = 0;
790 }
791 continue;
792 }
793
3739860c 794 the_insn.reloc = (the_insn.HI) ? RELOC_DLX_HI16
a7844384 795 : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16);
d172d4ba
NC
796 the_insn.reloc_offset = 2;
797 the_insn.size = 2;
798 the_insn.pcrel = 0;
799 the_insn.exp = * operand;
800 the_insn.HI = 0;
801 the_insn.LO = 0;
802 continue;
803
804 case 'd':
805 /* offset, signed. */
806 if (operand->X_op == O_constant)
807 {
808 opcode |= operand->X_add_number & 0xFFFF;
809 continue;
810 }
811 the_insn.reloc = RELOC_DLX_REL16;
812 the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */
813 the_insn.size = 4;
814 the_insn.pcrel = 1;
815 the_insn.exp = *operand;
816 continue;
817
818 /* The immediate 26 bits literal, bit 0-25. */
819 case 'D':
820 /* offset, signed. */
821 if (operand->X_op == O_constant)
822 {
823 opcode |= operand->X_add_number & 0x3FFFFFF;
824 continue;
825 }
826 the_insn.reloc = RELOC_DLX_REL26;
827 the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */
828 the_insn.size = 4;
829 the_insn.pcrel = 1;
830 the_insn.exp = *operand;
831 continue;
832
833 /* Type 'a' Register. */
834 case 'a':
835 /* A general register at bits 21-25, rs1. */
d172d4ba
NC
836 reg_shift = 21;
837 goto general_reg;
838
839 /* Type 'b' Register. */
840 case 'b':
841 /* A general register at bits 16-20, rs2/rd. */
d172d4ba
NC
842 reg_shift = 16;
843 goto general_reg;
844
845 /* Type 'c' Register. */
846 case 'c':
847 /* A general register at bits 11-15, rd. */
d172d4ba
NC
848 reg_shift = 11;
849
850 general_reg:
851 know (operand->X_add_symbol == 0);
852 know (operand->X_op_symbol == 0);
853 reg = operand->X_add_number;
854 if (reg & 0xffffffe0)
855 as_fatal (_("failed regnum sanity check."));
856 else
857 /* Got the register, now figure out where it goes in the opcode. */
858 opcode |= reg << reg_shift;
859
860 switch (*args)
861 {
862 case 'a':
863 case 'b':
864 case 'c':
865 case 'P':
866 continue;
867 }
868 as_fatal (_("failed general register sanity check."));
869 break;
870
871 default:
872 BAD_CASE (*args);
873 }
874
875 /* Types or values of args don't match. */
b1b17bc5 876 as_bad (_("Invalid operands"));
d172d4ba
NC
877 return;
878 }
879}
880
ea1562b3
NC
881/* Assemble a single instruction. Its label has already been handled
882 by the generic front end. We just parse opcode and operands, and
883 produce the bytes of data and relocation. */
884
885void
886md_assemble (char *str)
887{
888 char *toP;
889 fixS *fixP;
890 bit_fixS *bitP;
891
892 know (str);
893 machine_ip (str);
894 toP = frag_more (4);
d4f4f3fb
AM
895 dwarf2_emit_insn (4);
896
ea1562b3
NC
897 /* Put out the opcode. */
898 md_number_to_chars (toP, the_insn.opcode, 4);
899
900 /* Put out the symbol-dependent stuff. */
901 if (the_insn.reloc != NO_RELOC)
902 {
903 fixP = fix_new_exp (frag_now,
904 (toP - frag_now->fr_literal + the_insn.reloc_offset),
905 the_insn.size, & the_insn.exp, the_insn.pcrel,
906 the_insn.reloc);
907
908 /* Turn off complaints that the addend is
909 too large for things like foo+100000@ha. */
910 switch (the_insn.reloc)
911 {
912 case RELOC_DLX_HI16:
913 case RELOC_DLX_LO16:
914 fixP->fx_no_overflow = 1;
915 break;
916 default:
917 break;
918 }
919
920 switch (fixP->fx_r_type)
921 {
922 case RELOC_DLX_REL26:
325801bd 923 bitP = XNEW (bit_fixS);
ea1562b3
NC
924 bitP->fx_bit_size = 26;
925 bitP->fx_bit_offset = 25;
926 bitP->fx_bit_base = the_insn.opcode & 0xFC000000;
927 bitP->fx_bit_base_adj = 0;
928 bitP->fx_bit_max = 0;
929 bitP->fx_bit_min = 0;
930 bitP->fx_bit_add = 0x03FFFFFF;
931 fixP->fx_bit_fixP = bitP;
932 break;
933 case RELOC_DLX_LO16:
934 case RELOC_DLX_REL16:
325801bd 935 bitP = XNEW (bit_fixS);
ea1562b3
NC
936 bitP->fx_bit_size = 16;
937 bitP->fx_bit_offset = 15;
938 bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
939 bitP->fx_bit_base_adj = 0;
940 bitP->fx_bit_max = 0;
941 bitP->fx_bit_min = 0;
942 bitP->fx_bit_add = 0x0000FFFF;
943 fixP->fx_bit_fixP = bitP;
944 break;
945 case RELOC_DLX_HI16:
325801bd 946 bitP = XNEW (bit_fixS);
ea1562b3
NC
947 bitP->fx_bit_size = 16;
948 bitP->fx_bit_offset = 15;
949 bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
950 bitP->fx_bit_base_adj = 0;
951 bitP->fx_bit_max = 0;
952 bitP->fx_bit_min = 0;
953 bitP->fx_bit_add = 0x0000FFFF;
954 fixP->fx_bit_fixP = bitP;
955 break;
956 default:
957 fixP->fx_bit_fixP = NULL;
958 break;
959 }
960 }
961}
962
d172d4ba 963/* This is identical to the md_atof in m68k.c. I think this is right,
499ac353
NC
964 but I'm not sure. Dlx will not use it anyway, so I just leave it
965 here for now. */
d172d4ba 966
6d4af3c2 967const char *
ea1562b3 968md_atof (int type, char *litP, int *sizeP)
d172d4ba 969{
499ac353 970 return ieee_md_atof (type, litP, sizeP, TRUE);
d172d4ba
NC
971}
972
973/* Write out big-endian. */
974void
ea1562b3 975md_number_to_chars (char *buf, valueT val, int n)
d172d4ba
NC
976{
977 number_to_chars_bigendian (buf, val, n);
978}
979
b34976b6 980bfd_boolean
ea1562b3 981md_dlx_fix_adjustable (fixS *fixP)
d172d4ba
NC
982{
983 /* We need the symbol name for the VTABLE entries. */
a161fe53
AM
984 return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT
985 && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
d172d4ba
NC
986}
987
988void
55cf6793 989md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
d172d4ba
NC
990{
991 long val = *valP;
992 char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
993
d172d4ba
NC
994 switch (fixP->fx_r_type)
995 {
a7844384 996 case RELOC_DLX_LO16:
d172d4ba 997 case RELOC_DLX_REL16:
ea1562b3 998 if (fixP->fx_bit_fixP != NULL)
d172d4ba
NC
999 {
1000 val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base;
1001 free (fixP->fx_bit_fixP);
ea1562b3 1002 fixP->fx_bit_fixP = NULL;
d172d4ba 1003 }
d172d4ba
NC
1004 break;
1005
1006 case RELOC_DLX_HI16:
ea1562b3 1007 if (fixP->fx_bit_fixP != NULL)
d172d4ba
NC
1008 {
1009 val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base;
1010 free (fixP->fx_bit_fixP);
ea1562b3 1011 fixP->fx_bit_fixP = NULL;
d172d4ba 1012 }
d172d4ba
NC
1013 break;
1014
1015 case RELOC_DLX_REL26:
ea1562b3 1016 if (fixP->fx_bit_fixP != NULL)
d172d4ba
NC
1017 {
1018 val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base;
1019 free (fixP->fx_bit_fixP);
ea1562b3 1020 fixP->fx_bit_fixP = NULL;
d172d4ba 1021 }
d172d4ba
NC
1022 break;
1023
1024 case BFD_RELOC_VTABLE_INHERIT:
1025 /* This borrowed from tc-ppc.c on a whim. */
1026 fixP->fx_done = 0;
1027 if (fixP->fx_addsy
1028 && !S_IS_DEFINED (fixP->fx_addsy)
1029 && !S_IS_WEAK (fixP->fx_addsy))
1030 S_SET_WEAK (fixP->fx_addsy);
1031 return;
1032
1033 case BFD_RELOC_VTABLE_ENTRY:
1034 fixP->fx_done = 0;
1035 return;
1036
1037 default:
1038 break;
1039 }
1040
1041 number_to_chars_bigendian (place, val, fixP->fx_size);
a161fe53 1042 if (fixP->fx_addsy == NULL)
d172d4ba 1043 fixP->fx_done = 1;
5bc11336
AM
1044 if (fixP->fx_bit_fixP != NULL)
1045 fixP->fx_no_overflow = 1;
d172d4ba
NC
1046}
1047
5a38dc70 1048const char *md_shortopts = "";
d172d4ba
NC
1049
1050struct option md_longopts[] =
1051 {
1052 {NULL, no_argument, NULL, 0}
1053 };
1054
1055size_t md_longopts_size = sizeof (md_longopts);
1056
1057int
ea1562b3 1058md_parse_option (int c ATTRIBUTE_UNUSED,
17b9d67d 1059 const char *arg ATTRIBUTE_UNUSED)
d172d4ba
NC
1060{
1061 return 0;
1062}
1063
1064void
ea1562b3 1065md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
d172d4ba 1066{
d172d4ba
NC
1067}
1068
1069/* This is called when a line is unrecognized. */
1070
1071int
ea1562b3 1072dlx_unrecognized_line (int c)
d172d4ba
NC
1073{
1074 int lab;
1075 char *s;
1076
1077 if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
1078 return 0;
1079
1080 s = input_line_pointer;
1081
1082 lab = 0;
1083 while (ISDIGIT ((unsigned char) *s))
1084 {
1085 lab = lab * 10 + *s - '0';
1086 ++s;
1087 }
1088
1089 if (*s != ':')
ea1562b3
NC
1090 /* Not a label definition. */
1091 return 0;
d172d4ba
NC
1092
1093 if (dollar_label_defined (lab))
1094 {
1095 as_bad (_("label \"$%d\" redefined"), lab);
1096 return 0;
1097 }
1098
1099 define_dollar_label (lab);
1100 colon (dollar_label_name (lab, 0));
1101 input_line_pointer = s + 1;
1102
1103 return 1;
1104}
1105
1106/* Default the values of symbols known that should be "predefined". We
1107 don't bother to predefine them unless you actually use one, since there
1108 are a lot of them. */
1109
1110symbolS *
ea1562b3 1111md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
d172d4ba
NC
1112{
1113 return NULL;
1114}
1115
d172d4ba 1116/* Parse an operand that is machine-specific, the function was called
2d2255b5 1117 in expr.c by operand() function, when everything failed before it
d172d4ba
NC
1118 call a quit. */
1119
1120void
ea1562b3 1121md_operand (expressionS* expressionP)
d172d4ba
NC
1122{
1123 /* Check for the #number representation */
1124 if (input_line_pointer[0] == '#' &&
1125 ISDIGIT ((unsigned char) input_line_pointer[1]))
1126 {
1127 /* We have a numeric number expression. No biggy. */
1128 input_line_pointer += 1; /* Skip # */
1129
1130 (void) expression (expressionP);
1131
1132 if (expressionP->X_op != O_constant)
1133 as_bad (_("Invalid expression after # number\n"));
1134 }
1135
1136 return;
d172d4ba
NC
1137}
1138
1139/* Round up a section size to the appropriate boundary. */
1140
1141valueT
ea1562b3
NC
1142md_section_align (segT segment ATTRIBUTE_UNUSED,
1143 valueT size)
d172d4ba
NC
1144{
1145 /* Byte alignment is fine. */
1146 return size;
1147}
1148
1149/* Exactly what point is a PC-relative offset relative TO?
1150 On the 29000, they're relative to the address of the instruction,
1151 which we have set up as the address of the fixup too. */
1152
1153long
ea1562b3 1154md_pcrel_from (fixS* fixP)
d172d4ba
NC
1155{
1156 return 4 + fixP->fx_where + fixP->fx_frag->fr_address;
1157}
1158
d172d4ba
NC
1159/* Translate internal representation of relocation info to BFD target
1160 format.
1161 FIXME: To what extent can we get all relevant targets to use this?
1162 The above FIXME is from a29k, but I think it is also needed here. */
1163
1164arelent *
ea1562b3
NC
1165tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1166 fixS *fixP)
d172d4ba
NC
1167{
1168 arelent * reloc;
1169
325801bd 1170 reloc = XNEW (arelent);
d172d4ba
NC
1171 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1172
ea1562b3 1173 if (reloc->howto == NULL)
d172d4ba
NC
1174 {
1175 as_bad_where (fixP->fx_file, fixP->fx_line,
b1b17bc5 1176 _("internal error: can't export reloc type %d (`%s')"),
d172d4ba
NC
1177 fixP->fx_r_type,
1178 bfd_get_reloc_code_name (fixP->fx_r_type));
1179 return NULL;
1180 }
1181
9c2799c2 1182 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
d172d4ba 1183
325801bd 1184 reloc->sym_ptr_ptr = XNEW (asymbol *);
d172d4ba
NC
1185 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1186 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1187
a161fe53
AM
1188 if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1189 reloc->address = fixP->fx_offset;
1190 reloc->addend = 0;
1191
d172d4ba
NC
1192 return reloc;
1193}
1194
ea1562b3
NC
1195const pseudo_typeS
1196dlx_pseudo_table[] =
1197{
1198 /* Some additional ops that are used by gcc-dlx. */
38a57ae7 1199 {"asciiz", stringer, 8 + 1},
ea1562b3
NC
1200 {"half", cons, 2},
1201 {"dword", cons, 8},
1202 {"word", cons, 4},
1203 {"proc", s_proc, 0},
1204 {"endproc", s_proc, 1},
1205 {NULL, NULL, 0}
1206};
d172d4ba
NC
1207
1208void
ea1562b3 1209dlx_pop_insert (void)
d172d4ba
NC
1210{
1211 pop_insert (dlx_pseudo_table);
1212 return ;
1213}
This page took 0.930365 seconds and 4 git commands to generate.