1 /* tc-d10v.c -- Assembler code for the Mitsubishi D10V
3 Copyright (C) 1996 Free Software Foundation.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "opcode/d10v.h"
29 const char comment_chars[] = "#;";
30 const char line_comment_chars[] = "#";
31 const char line_separator_chars[] = "";
32 const char *md_shortopts = "";
33 const char EXP_CHARS[] = "eE";
34 const char FLT_CHARS[] = "dD";
38 #define MAX_INSN_FIXUPS (5)
42 bfd_reloc_code_real_type reloc;
45 typedef struct _fixups
48 struct d10v_fixup fix[MAX_INSN_FIXUPS];
52 static Fixups FixUps[2];
53 static Fixups *fixups;
56 static int reg_name_search PARAMS ((char *name));
57 static int register_name PARAMS ((expressionS *expressionP));
58 static int check_range PARAMS ((unsigned long num, int bits, int flags));
59 static int postfix PARAMS ((char *p));
60 static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
61 static int get_operands PARAMS ((expressionS exp[]));
62 static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers, unsigned long insn));
63 static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
64 static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
65 static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
66 struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx));
67 static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
68 static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
69 offsetT value, int left));
72 struct option md_longopts[] = {
73 {NULL, no_argument, NULL, 0}
75 size_t md_longopts_size = sizeof(md_longopts);
77 /* The target specific pseudo-ops which we support. */
78 const pseudo_typeS md_pseudo_table[] =
83 /* Opcode hash table. */
84 static struct hash_control *d10v_hash;
86 /* reg_name_search does a binary search of the pre_defined_registers
87 array to see if "name" is a valid regiter name. Returns the register
88 number from the array on success, or -1 on failure. */
91 reg_name_search (name)
94 int middle, low, high;
98 high = reg_name_cnt() - 1;
102 middle = (low + high) / 2;
103 cmp = strcasecmp (name, pre_defined_registers[middle].name);
109 return pre_defined_registers[middle].value;
115 /* register_name() checks the string at input_line_pointer
116 to see if it is a valid register name */
119 register_name (expressionP)
120 expressionS *expressionP;
123 char c, *p = input_line_pointer;
125 while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
132 /* look to see if it's in the register table */
133 reg_number = reg_name_search (input_line_pointer);
136 expressionP->X_op = O_register;
137 /* temporarily store a pointer to the string here */
138 expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
139 expressionP->X_add_number = reg_number;
140 input_line_pointer = p;
150 check_range (num, bits, flags)
158 if (flags & OPERAND_SHIFT)
160 /* all special shift operands are unsigned */
161 /* and <= 16. We allow 0 for now. */
168 if (flags & OPERAND_SIGNED)
170 max = (1 << (bits - 1)) - 1;
171 min = - (1 << (bits - 1));
172 if (((long)num > max) || ((long)num < min))
177 max = (1 << bits) - 1;
179 if ((num > max) || (num < min))
188 md_show_usage (stream)
191 fprintf(stream, "D10V options:\n\
196 md_parse_option (c, arg)
204 md_undefined_symbol (name)
211 md_atof (type, litp, sizep)
220 md_convert_frag (abfd, sec, fragP)
225 printf ("call to md_convert_frag \n");
230 md_section_align (seg, addr)
234 int align = bfd_get_section_alignment (stdoutput, seg);
235 return ((addr + (1 << align) - 1) & (-1 << align));
242 char *prev_name = "";
243 struct d10v_opcode *opcode;
244 d10v_hash = hash_new();
246 /* Insert unique names into hash table. The D10v instruction set
247 has many identical opcode names that have different opcodes based
248 on the operands. This hash table then provides a quick index to
249 the first opcode with a particular name in the opcode table. */
251 for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++)
253 if (strcmp (prev_name, opcode->name))
255 prev_name = (char *)opcode->name;
256 hash_insert (d10v_hash, opcode->name, (char *) opcode);
261 FixUps[0].next = &FixUps[1];
262 FixUps[1].next = &FixUps[0];
266 /* this function removes the postincrement or postdecrement
267 operator ( '+' or '-' ) from an expression */
269 static int postfix (p)
272 while (*p != '-' && *p != '+')
274 if (*p==0 || *p=='\n' || *p=='\r')
294 static bfd_reloc_code_real_type
296 struct d10v_operand *op;
300 /* printf("get_reloc: bits=%d address=%d\n",bits,op->flags & OPERAND_ADDR); */
304 if (op->flags & OPERAND_ADDR)
307 return (BFD_RELOC_D10V_10_PCREL_R);
309 return (BFD_RELOC_D10V_18_PCREL);
312 return (BFD_RELOC_16);
315 /* get_operands parses a string of operands and returns
316 an array of expressions */
322 char *p = input_line_pointer;
328 while (*p == ' ' || *p == '\t' || *p == ',')
330 if (*p==0 || *p=='\n' || *p=='\r')
336 exp[numops].X_op = O_absent;
340 exp[numops].X_add_number = OPERAND_ATPAR;
345 exp[numops].X_add_number = OPERAND_ATMINUS;
349 exp[numops].X_add_number = OPERAND_ATSIGN;
358 /* just skip the trailing paren */
363 input_line_pointer = p;
366 /* check to see if it might be a register name */
367 if (!register_name (&exp[numops]))
369 /* parse as an expression */
370 expression (&exp[numops]);
373 if (exp[numops].X_op == O_illegal)
374 as_bad ("illegal operand");
375 else if (exp[numops].X_op == O_absent)
376 as_bad ("missing operand");
379 p = input_line_pointer;
384 case -1: /* postdecrement mode */
385 exp[numops].X_op = O_absent;
386 exp[numops++].X_add_number = OPERAND_MINUS;
388 case 1: /* postincrement mode */
389 exp[numops].X_op = O_absent;
390 exp[numops++].X_add_number = OPERAND_PLUS;
394 exp[numops].X_op = 0;
399 d10v_insert_operand (insn, op_type, value, left)
407 shift = d10v_operands[op_type].shift;
411 bits = d10v_operands[op_type].bits;
413 /* truncate to the proper number of bits */
414 if (check_range (value, bits, d10v_operands[op_type].flags))
415 as_bad("operand out of range: %d",value);
417 value &= 0x7FFFFFFF >> (31 - bits);
418 insn |= (value << shift);
424 /* build_insn takes a pointer to the opcode entry in the opcode table
425 and the array of operand expressions and returns the instruction */
428 build_insn (opcode, opers, insn)
429 struct d10v_opcode *opcode;
433 int i, bits, shift, flags, format;
436 /* the insn argument is only used for the DIVS kludge */
441 insn = opcode->opcode;
442 format = opcode->format;
445 for (i=0;opcode->operands[i];i++)
447 flags = d10v_operands[opcode->operands[i]].flags;
448 bits = d10v_operands[opcode->operands[i]].bits;
449 shift = d10v_operands[opcode->operands[i]].shift;
450 number = opers[i].X_add_number;
452 if (flags & OPERAND_REG)
454 number &= REGISTER_MASK;
455 if (format == LONG_L)
459 if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
461 /* now create a fixup */
464 printf("need a fixup: ");
465 print_expr_1(stdout,&opers[i]);
469 if (fixups->fc >= MAX_INSN_FIXUPS)
470 as_fatal ("too many fixups");
471 fixups->fix[fixups->fc].exp = opers[i];
473 /* put the operand number here for now. We can look up
474 the reloc type and/or fixup the instruction in md_apply_fix() */
475 fixups->fix[fixups->fc].reloc = opcode->operands[i];
479 /* truncate to the proper number of bits */
480 if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
481 as_bad("operand out of range: %d",number);
482 number &= 0x7FFFFFFF >> (31 - bits);
483 insn = insn | (number << shift);
486 /* kludge: for DIVS, we need to put the operands in twice */
487 /* on the second pass, format is changed to LONG_R to force */
488 /* the second set of operands to not be shifted over 15 */
489 if ((opcode->opcode == OPCODE_DIVS) && (format==LONG_L))
490 insn = build_insn (opcode, opers, insn);
495 /* write out a long form instruction */
497 write_long (opcode, insn, fx)
498 struct d10v_opcode *opcode;
503 char *f = frag_more(4);
506 /* printf("INSN: %08x\n",insn); */
507 number_to_chars_bigendian (f, insn, 4);
509 for (i=0; i < fx->fc; i++)
511 if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]))
514 printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
515 print_expr_1(stdout,&(fx->fix[i].exp));
519 fix_new_exp (frag_now,
520 f - frag_now->fr_literal,
531 /* write out a short form instruction by itself */
533 write_1_short (opcode, insn, fx)
534 struct d10v_opcode *opcode;
538 char *f = frag_more(4);
541 if (opcode->exec_type == PARONLY)
542 as_fatal ("Instruction must be executed in parallel with another instruction.");
544 /* the other container needs to be NOP */
545 /* according to 4.3.1: for FM=00, sub-instructions performed only
546 by IU cannot be encoded in L-container. */
547 if (opcode->unit == IU)
548 insn |= FM00 | (NOP << 15); /* right container */
550 insn = FM00 | (insn << 15) | NOP; /* left container */
552 /* printf("INSN: %08x\n",insn); */
553 number_to_chars_bigendian (f, insn, 4);
554 for (i=0; i < fx->fc; i++)
556 if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]))
559 printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
560 print_expr_1(stdout,&(fx->fix[i].exp));
564 fix_new_exp (frag_now,
565 f - frag_now->fr_literal,
575 /* write out a short form instruction if possible */
576 /* return number of instructions not written out */
578 write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
579 struct d10v_opcode *opcode1, *opcode2;
580 unsigned long insn1, insn2;
588 if ( (exec_type != 1) && ((opcode1->exec_type == PARONLY)
589 || (opcode2->exec_type == PARONLY)))
590 as_fatal("Instruction must be executed in parallel");
592 if ( (opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
593 as_fatal ("Long instructions may not be combined.");
595 if(opcode1->exec_type == BRANCH_LINK)
597 /* subroutines must be called from 32-bit boundaries */
598 /* so the return address will be correct */
599 write_1_short (opcode1, insn1, fx->next);
606 if (opcode1->unit == IU)
608 /* reverse sequential */
609 insn = FM10 | (insn2 << 15) | insn1;
613 insn = FM01 | (insn1 << 15) | insn2;
617 case 1: /* parallel */
618 if (opcode1->exec_type == SEQ || opcode2->exec_type == SEQ)
619 as_fatal ("One of these instructions may not be executed in parallel.");
621 if (opcode1->unit == IU)
623 if (opcode2->unit == IU)
624 as_fatal ("Two IU instructions may not be executed in parallel");
625 as_warn ("Swapping instruction order");
626 insn = FM00 | (insn2 << 15) | insn1;
628 else if (opcode2->unit == MU)
630 if (opcode1->unit == MU)
631 as_fatal ("Two MU instructions may not be executed in parallel");
632 as_warn ("Swapping instruction order");
633 insn = FM00 | (insn2 << 15) | insn1;
636 insn = FM00 | (insn1 << 15) | insn2;
639 case 2: /* sequential */
640 if (opcode1->unit == IU)
641 as_fatal ("IU instruction may not be in the left container");
642 insn = FM01 | (insn1 << 15) | insn2;
645 case 3: /* reverse sequential */
646 if (opcode2->unit == MU)
647 as_fatal ("MU instruction may not be in the right container");
648 insn = FM10 | (insn1 << 15) | insn2;
651 as_fatal("unknown execution type passed to write_2_short()");
654 /* printf("INSN: %08x\n",insn); */
656 number_to_chars_bigendian (f, insn, 4);
660 bfd_reloc_code_real_type reloc;
661 for (i=0; i < fx->fc; i++)
663 reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]);
666 if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0) )
667 fx->fix[i].reloc |= 1024;
670 printf("fix_new_exp: where:%x reloc:%d\n ",f - frag_now->fr_literal,fx->fix[i].reloc);
671 print_expr_1(stdout,&(fx->fix[i].exp));
674 fix_new_exp (frag_now,
675 f - frag_now->fr_literal,
690 /* This is the main entry point for the machine-dependent assembler. str points to a
691 machine-dependent instruction. This function is supposed to emit the frags/bytes
692 it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing
693 and leaves the difficult stuff to do_assemble().
696 static unsigned long prev_insn;
697 static struct d10v_opcode *prev_opcode = 0;
698 static subsegT prev_subseg;
699 static segT prev_seg;
705 struct d10v_opcode *opcode;
707 int extype=0; /* execution type; parallel, etc */
708 static int etype=0; /* saved extype. used for multiline instructions */
711 /* printf("md_assemble: str=%s\n",str); */
715 /* look for the special multiple instruction separators */
716 str2 = strstr (str, "||");
721 str2 = strstr (str, "->");
726 str2 = strstr (str, "<-");
731 /* str2 points to the separator, if one */
736 /* if two instructions are present and we already have one saved
737 then first write it out */
739 write_1_short (prev_opcode, prev_insn, fixups->next);
741 /* assemble first instruction and save it */
742 prev_insn = do_assemble (str, &prev_opcode);
744 as_fatal ("can't find opcode ");
745 fixups = fixups->next;
750 insn = do_assemble (str, &opcode);
758 as_fatal ("can't find opcode ");
767 /* if this is a long instruction, write it and any previous short instruction */
768 if (opcode->format & LONG_OPCODE)
771 as_fatal("Unable to mix instructions as specified");
774 write_1_short (prev_opcode, prev_insn, fixups->next);
777 write_long (opcode, insn, fixups);
782 if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
784 /* no instructions saved */
790 as_fatal("Unable to mix instructions as specified");
791 /* save off last instruction so it may be packed on next pass */
792 prev_opcode = opcode;
795 prev_subseg = now_subseg;
796 fixups = fixups->next;
801 /* do_assemble assembles a single instruction and returns an opcode */
802 /* it returns -1 (an invalid opcode) on error */
805 do_assemble (str, opcode)
807 struct d10v_opcode **opcode;
809 struct d10v_opcode *next_opcode;
810 unsigned char *op_start, *save;
811 unsigned char *op_end;
813 int nlen = 0, i, match, numops;
814 expressionS myops[6];
817 /* printf("do_assemble: str=%s\n",str); */
819 /* Drop leading whitespace */
823 /* find the opcode end */
824 for (op_start = op_end = (unsigned char *) (str);
827 && !is_end_of_line[*op_end] && *op_end != ' ';
830 name[nlen] = op_start[nlen];
838 /* find the first opcode with the proper name */
839 *opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
841 as_fatal ("unknown opcode: %s",name);
843 save = input_line_pointer;
844 input_line_pointer = op_end;
846 /* get all the operands and save them as expressions */
847 numops = get_operands (myops);
849 /* now see if the operand is a fake. If so, find the correct size */
850 /* instruction, if possible */
852 if ((*opcode)->format == OPCODE_FAKE)
854 int opnum = (*opcode)->operands[0];
855 if (myops[opnum].X_op == O_constant)
857 next_opcode=(*opcode)+1;
858 for (i=0; (*opcode)->operands[i+1]; i++)
860 int bits = d10v_operands[next_opcode->operands[opnum]].bits;
861 int flags = d10v_operands[next_opcode->operands[opnum]].flags;
862 if (!check_range (myops[opnum].X_add_number, bits, flags))
872 /* not a constant, so use a long instruction */
873 next_opcode = (*opcode)+2;
877 *opcode = next_opcode;
879 as_fatal ("value out of range");
883 /* now search the opcode table table for one with operands */
884 /* that matches what we've got */
888 for (i = 0; (*opcode)->operands[i]; i++)
890 int flags = d10v_operands[(*opcode)->operands[i]].flags;
891 int X_op = myops[i].X_op;
892 int num = myops[i].X_add_number;
900 if (flags & OPERAND_REG)
902 if ((X_op != O_register) ||
903 ((flags & OPERAND_ACC) != (num & OPERAND_ACC)) ||
904 ((flags & OPERAND_FLAG) != (num & OPERAND_FLAG)) ||
905 ((flags & OPERAND_CONTROL) != (num & OPERAND_CONTROL)))
912 if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
913 ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
914 ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
915 ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
916 ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || (num != OPERAND_ATSIGN))))
924 /* we're only done if the operands matched AND there
925 are no more to check */
926 if (match && myops[i].X_op==0)
929 next_opcode = (*opcode)+1;
930 if (next_opcode->opcode == 0)
932 if (strcmp(next_opcode->name, (*opcode)->name))
934 (*opcode) = next_opcode;
940 as_bad ("bad opcode or operands");
944 /* Check that all registers that are required to be even are. */
945 /* Also, if any operands were marked as registers, but were really symbols */
947 for (i=0; (*opcode)->operands[i]; i++)
949 if ((d10v_operands[(*opcode)->operands[i]].flags & OPERAND_EVEN) &&
950 (myops[i].X_add_number & 1))
951 as_fatal("Register number must be EVEN");
952 if (myops[i].X_op == O_register)
954 if (!(d10v_operands[(*opcode)->operands[i]].flags & OPERAND_REG))
956 myops[i].X_op = O_symbol;
957 myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
958 myops[i].X_add_number = 0;
959 myops[i].X_op_symbol = NULL;
964 input_line_pointer = save;
966 /* at this point, we have "opcode" pointing to the opcode entry in the
967 d10v opcode table, with myops filled out with the operands. */
968 insn = build_insn ((*opcode), myops, 0);
969 /* printf("sub-insn = %lx\n",insn); */
975 /* if while processing a fixup, a reloc really needs to be created */
976 /* then it is done here */
979 tc_gen_reloc (seg, fixp)
984 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
985 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
986 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
987 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
988 if (reloc->howto == (reloc_howto_type *) NULL)
990 as_bad_where (fixp->fx_file, fixp->fx_line,
991 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
994 reloc->addend = fixp->fx_addnumber;
995 /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
1000 md_estimate_size_before_relax (fragp, seg)
1009 md_pcrel_from_section (fixp, sec)
1014 /* return fixp->fx_frag->fr_address + fixp->fx_where; */
1018 md_apply_fix3 (fixp, valuep, seg)
1029 if (fixp->fx_addsy == (symbolS *) NULL)
1034 else if (fixp->fx_pcrel)
1038 value = fixp->fx_offset;
1039 if (fixp->fx_subsy != (symbolS *) NULL)
1041 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1042 value -= S_GET_VALUE (fixp->fx_subsy);
1045 /* We don't actually support subtracting a symbol. */
1046 as_bad_where (fixp->fx_file, fixp->fx_line,
1047 "expression too complex");
1052 /* printf("md_apply_fix: value=0x%x type=%d\n", value, fixp->fx_r_type); */
1054 op_type = fixp->fx_r_type;
1058 fixp->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
1062 fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
1064 /* Fetch the instruction, insert the fully resolved operand
1065 value, and stuff the instruction back again. */
1066 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1067 insn = bfd_getb32 ((unsigned char *) where);
1069 switch (fixp->fx_r_type)
1071 case BFD_RELOC_D10V_10_PCREL_L:
1072 case BFD_RELOC_D10V_10_PCREL_R:
1073 case BFD_RELOC_D10V_18_PCREL:
1074 /* instruction addresses are always right-shifted by 2
1076 if (!fixp->fx_pcrel)
1077 value -= fixp->fx_where;
1082 /* printf(" insn=%x value=%x where=%x pcrel=%x\n",insn,value,fixp->fx_where,fixp->fx_pcrel); */
1084 insn = d10v_insert_operand (insn, op_type, (offsetT)value, left);
1086 /* printf(" new insn=%x\n",insn); */
1088 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1093 fixp->fx_addnumber = value;
1098 /* d10v_cleanup() is called after the assembler has finished parsing the input
1099 file or after a label is defined. Because the D10V assembler sometimes saves short
1100 instructions to see if it can package them with the next instruction, there may
1101 be a short instruction that still needs written. */
1109 if ( prev_opcode && (done || (now_seg == prev_seg) && (now_subseg == prev_subseg)))
1112 subseg = now_subseg;
1113 subseg_set (prev_seg, prev_subseg);
1114 write_1_short (prev_opcode, prev_insn, fixups);
1115 subseg_set (seg, subseg);