* config/tc-v850.c (reg_name_search): Align calling convention to
[deliverable/binutils-gdb.git] / gas / config / tc-d10v.c
CommitLineData
7be9a312
MH
1/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
2
3 Copyright (C) 1996 Free Software Foundation.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include <ctype.h>
24#include "as.h"
25#include "subsegs.h"
26#include "opcode/d10v.h"
27#include "elf/ppc.h"
28
29const char comment_chars[] = "#;";
30const char line_comment_chars[] = "#";
31const char line_separator_chars[] = "";
bb5638c6 32const char *md_shortopts = "O";
7be9a312
MH
33const char EXP_CHARS[] = "eE";
34const char FLT_CHARS[] = "dD";
35
bb5638c6 36int Optimizing = 0;
0ef32559
MH
37
38/* fixups */
39#define MAX_INSN_FIXUPS (5)
40struct d10v_fixup
41{
42 expressionS exp;
bb5638c6
MH
43 int operand;
44 int pcrel;
0ef32559
MH
45};
46
47typedef struct _fixups
48{
49 int fc;
50 struct d10v_fixup fix[MAX_INSN_FIXUPS];
51 struct _fixups *next;
52} Fixups;
53
54static Fixups FixUps[2];
55static Fixups *fixups;
56
7be9a312
MH
57/* local functions */
58static int reg_name_search PARAMS ((char *name));
0ef32559 59static int register_name PARAMS ((expressionS *expressionP));
a40d3589 60static int check_range PARAMS ((unsigned long num, int bits, int flags));
7be9a312
MH
61static int postfix PARAMS ((char *p));
62static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
63static int get_operands PARAMS ((expressionS exp[]));
bb5638c6 64static struct d10v_opcode *find_opcode PARAMS ((struct d10v_opcode *opcode, expressionS ops[]));
ab48956f 65static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers, unsigned long insn));
0ef32559
MH
66static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
67static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
7be9a312 68static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
0ef32559 69 struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx));
7be9a312 70static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
0ef32559 71static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
67f0d0ea 72 offsetT value, int left, fixS *fix));
bb5638c6
MH
73static int parallel_ok PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
74 struct d10v_opcode *opcode2, unsigned long insn2));
7be9a312 75
7be9a312
MH
76
77struct option md_longopts[] = {
78 {NULL, no_argument, NULL, 0}
79};
80size_t md_longopts_size = sizeof(md_longopts);
81
82/* The target specific pseudo-ops which we support. */
83const pseudo_typeS md_pseudo_table[] =
84{
7be9a312
MH
85 { NULL, NULL, 0 }
86};
87
88/* Opcode hash table. */
89static struct hash_control *d10v_hash;
90
7be9a312
MH
91/* reg_name_search does a binary search of the pre_defined_registers
92 array to see if "name" is a valid regiter name. Returns the register
93 number from the array on success, or -1 on failure. */
94
95static int
96reg_name_search (name)
97 char *name;
98{
99 int middle, low, high;
100 int cmp;
101
102 low = 0;
0ef32559 103 high = reg_name_cnt() - 1;
7be9a312
MH
104
105 do
106 {
107 middle = (low + high) / 2;
108 cmp = strcasecmp (name, pre_defined_registers[middle].name);
109 if (cmp < 0)
110 high = middle - 1;
111 else if (cmp > 0)
112 low = middle + 1;
113 else
114 return pre_defined_registers[middle].value;
115 }
116 while (low <= high);
117 return -1;
118}
119
0ef32559
MH
120/* register_name() checks the string at input_line_pointer
121 to see if it is a valid register name */
7be9a312 122
0ef32559 123static int
7be9a312
MH
124register_name (expressionP)
125 expressionS *expressionP;
126{
127 int reg_number;
0ef32559
MH
128 char c, *p = input_line_pointer;
129
130 while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
131 p++;
7be9a312 132
0ef32559
MH
133 c = *p;
134 if (c)
135 *p++ = 0;
7be9a312 136
0ef32559
MH
137 /* look to see if it's in the register table */
138 reg_number = reg_name_search (input_line_pointer);
139 if (reg_number >= 0)
140 {
141 expressionP->X_op = O_register;
142 /* temporarily store a pointer to the string here */
143 expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
144 expressionP->X_add_number = reg_number;
145 input_line_pointer = p;
146 return 1;
7be9a312 147 }
0ef32559
MH
148 if (c)
149 *(p-1) = c;
150 return 0;
7be9a312
MH
151}
152
ab48956f
MH
153
154static int
a40d3589 155check_range (num, bits, flags)
ab48956f
MH
156 unsigned long num;
157 int bits;
a40d3589 158 int flags;
ab48956f 159{
f8508db7 160 long min, max, bit1;
ab48956f
MH
161 int retval=0;
162
9971ae59
MH
163 /* don't bother checking 16-bit values */
164 if (bits == 16)
165 return 0;
166
a40d3589
MH
167 if (flags & OPERAND_SHIFT)
168 {
169 /* all special shift operands are unsigned */
170 /* and <= 16. We allow 0 for now. */
171 if (num>16)
172 return 1;
173 else
174 return 0;
175 }
176
177 if (flags & OPERAND_SIGNED)
ab48956f 178 {
9971ae59 179 max = (1 << (bits - 1))-1;
ab48956f
MH
180 min = - (1 << (bits - 1));
181 if (((long)num > max) || ((long)num < min))
182 retval = 1;
183 }
184 else
185 {
186 max = (1 << bits) - 1;
187 min = 0;
188 if ((num > max) || (num < min))
189 retval = 1;
190 }
ab48956f
MH
191 return retval;
192}
193
194
7be9a312
MH
195void
196md_show_usage (stream)
197 FILE *stream;
198{
199 fprintf(stream, "D10V options:\n\
bb5638c6 200-O optimize. Will do some operations in parallel.\n");
7be9a312
MH
201}
202
203int
204md_parse_option (c, arg)
205 int c;
206 char *arg;
207{
bb5638c6
MH
208 switch (c)
209 {
210 case 'O':
211 /* Optimize. Will attempt to parallelize operations */
212 Optimizing = 1;
213 break;
214 default:
215 return 0;
216 }
217 return 1;
7be9a312
MH
218}
219
220symbolS *
221md_undefined_symbol (name)
222 char *name;
223{
224 return 0;
225}
226
bb5638c6
MH
227/* Turn a string in input_line_pointer into a floating point constant of type
228 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
229 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
230 */
7be9a312 231char *
bb5638c6
MH
232md_atof (type, litP, sizeP)
233 int type;
234 char *litP;
235 int *sizeP;
7be9a312 236{
bb5638c6
MH
237 int prec;
238 LITTLENUM_TYPE words[4];
239 char *t;
240 int i;
241
242 switch (type)
243 {
244 case 'f':
245 prec = 2;
246 break;
247 case 'd':
248 prec = 4;
249 break;
250 default:
251 *sizeP = 0;
252 return "bad call to md_atof";
253 }
254
255 t = atof_ieee (input_line_pointer, type, words);
256 if (t)
257 input_line_pointer = t;
258
259 *sizeP = prec * 2;
260
261 for (i = 0; i < prec; i++)
262 {
263 md_number_to_chars (litP, (valueT) words[i], 2);
264 litP += 2;
265 }
266 return NULL;
7be9a312
MH
267}
268
269void
270md_convert_frag (abfd, sec, fragP)
271 bfd *abfd;
272 asection *sec;
273 fragS *fragP;
274{
0ef32559 275 printf ("call to md_convert_frag \n");
7be9a312
MH
276 abort ();
277}
278
279valueT
280md_section_align (seg, addr)
281 asection *seg;
282 valueT addr;
283{
284 int align = bfd_get_section_alignment (stdoutput, seg);
285 return ((addr + (1 << align) - 1) & (-1 << align));
286}
287
0ef32559 288
7be9a312
MH
289void
290md_begin ()
291{
292 char *prev_name = "";
293 struct d10v_opcode *opcode;
294 d10v_hash = hash_new();
295
296 /* Insert unique names into hash table. The D10v instruction set
297 has many identical opcode names that have different opcodes based
298 on the operands. This hash table then provides a quick index to
299 the first opcode with a particular name in the opcode table. */
300
301 for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++)
302 {
303 if (strcmp (prev_name, opcode->name))
304 {
305 prev_name = (char *)opcode->name;
306 hash_insert (d10v_hash, opcode->name, (char *) opcode);
307 }
308 }
0ef32559
MH
309
310 fixups = &FixUps[0];
311 FixUps[0].next = &FixUps[1];
312 FixUps[1].next = &FixUps[0];
7be9a312
MH
313}
314
315
316/* this function removes the postincrement or postdecrement
317 operator ( '+' or '-' ) from an expression */
318
319static int postfix (p)
320 char *p;
321{
322 while (*p != '-' && *p != '+')
323 {
324 if (*p==0 || *p=='\n' || *p=='\r')
325 break;
326 p++;
327 }
328
329 if (*p == '-')
330 {
331 *p = ' ';
332 return (-1);
333 }
334 if (*p == '+')
335 {
336 *p = ' ';
337 return (1);
338 }
339
340 return (0);
341}
342
343
344static bfd_reloc_code_real_type
345get_reloc (op)
346 struct d10v_operand *op;
347{
348 int bits = op->bits;
349
350 /* printf("get_reloc: bits=%d address=%d\n",bits,op->flags & OPERAND_ADDR); */
351 if (bits <= 4)
352 return (0);
353
354 if (op->flags & OPERAND_ADDR)
355 {
0ef32559
MH
356 if (bits == 8)
357 return (BFD_RELOC_D10V_10_PCREL_R);
7be9a312 358 else
e805bff7 359 return (BFD_RELOC_D10V_18_PCREL);
7be9a312
MH
360 }
361
362 return (BFD_RELOC_16);
363}
364
365/* get_operands parses a string of operands and returns
366 an array of expressions */
367
368static int
369get_operands (exp)
370 expressionS exp[];
371{
372 char *p = input_line_pointer;
373 int numops = 0;
374 int post = 0;
375
376 while (*p)
377 {
378 while (*p == ' ' || *p == '\t' || *p == ',')
379 p++;
380 if (*p==0 || *p=='\n' || *p=='\r')
381 break;
382
383 if (*p == '@')
384 {
385 p++;
386 exp[numops].X_op = O_absent;
387 if (*p == '(')
388 {
389 p++;
390 exp[numops].X_add_number = OPERAND_ATPAR;
391 }
392 else if (*p == '-')
393 {
394 p++;
395 exp[numops].X_add_number = OPERAND_ATMINUS;
396 }
397 else
398 {
399 exp[numops].X_add_number = OPERAND_ATSIGN;
400 post = postfix (p);
401 }
402 numops++;
403 continue;
404 }
405
406 if (*p == ')')
407 {
408 /* just skip the trailing paren */
409 p++;
410 continue;
411 }
412
413 input_line_pointer = p;
0ef32559
MH
414
415
7be9a312 416 /* check to see if it might be a register name */
0ef32559
MH
417 if (!register_name (&exp[numops]))
418 {
419 /* parse as an expression */
420 expression (&exp[numops]);
421 }
7be9a312
MH
422
423 if (exp[numops].X_op == O_illegal)
424 as_bad ("illegal operand");
425 else if (exp[numops].X_op == O_absent)
426 as_bad ("missing operand");
427
428 numops++;
429 p = input_line_pointer;
430 }
431
432 switch (post)
433 {
434 case -1: /* postdecrement mode */
435 exp[numops].X_op = O_absent;
436 exp[numops++].X_add_number = OPERAND_MINUS;
437 break;
438 case 1: /* postincrement mode */
439 exp[numops].X_op = O_absent;
440 exp[numops++].X_add_number = OPERAND_PLUS;
441 break;
442 }
443
444 exp[numops].X_op = 0;
445 return (numops);
446}
447
448static unsigned long
67f0d0ea 449d10v_insert_operand (insn, op_type, value, left, fix)
7be9a312
MH
450 unsigned long insn;
451 int op_type;
452 offsetT value;
0ef32559 453 int left;
67f0d0ea 454 fixS *fix;
7be9a312
MH
455{
456 int shift, bits;
457
458 shift = d10v_operands[op_type].shift;
0ef32559
MH
459 if (left)
460 shift += 15;
461
7be9a312 462 bits = d10v_operands[op_type].bits;
93050391 463
7be9a312 464 /* truncate to the proper number of bits */
a40d3589 465 if (check_range (value, bits, d10v_operands[op_type].flags))
67f0d0ea 466 as_bad_where (fix->fx_file, fix->fx_line, "operand out of range: %d", value);
ab48956f 467
7be9a312
MH
468 value &= 0x7FFFFFFF >> (31 - bits);
469 insn |= (value << shift);
470
471 return insn;
472}
473
474
475/* build_insn takes a pointer to the opcode entry in the opcode table
476 and the array of operand expressions and returns the instruction */
477
478static unsigned long
ab48956f 479build_insn (opcode, opers, insn)
7be9a312
MH
480 struct d10v_opcode *opcode;
481 expressionS *opers;
ab48956f 482 unsigned long insn;
7be9a312 483{
ab48956f 484 int i, bits, shift, flags, format;
7be9a312 485 unsigned int number;
ab48956f
MH
486
487 /* the insn argument is only used for the DIVS kludge */
488 if (insn)
489 format = LONG_R;
490 else
491 {
492 insn = opcode->opcode;
493 format = opcode->format;
494 }
495
7be9a312
MH
496 for (i=0;opcode->operands[i];i++)
497 {
498 flags = d10v_operands[opcode->operands[i]].flags;
499 bits = d10v_operands[opcode->operands[i]].bits;
500 shift = d10v_operands[opcode->operands[i]].shift;
501 number = opers[i].X_add_number;
502
503 if (flags & OPERAND_REG)
504 {
505 number &= REGISTER_MASK;
ab48956f 506 if (format == LONG_L)
7be9a312
MH
507 shift += 15;
508 }
509
510 if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
511 {
512 /* now create a fixup */
513
514 /*
515 printf("need a fixup: ");
516 print_expr_1(stdout,&opers[i]);
bb5638c6 517 printf("\n");
7be9a312
MH
518 */
519
0ef32559 520 if (fixups->fc >= MAX_INSN_FIXUPS)
7be9a312 521 as_fatal ("too many fixups");
0ef32559 522 fixups->fix[fixups->fc].exp = opers[i];
bb5638c6
MH
523 fixups->fix[fixups->fc].operand = opcode->operands[i];
524 fixups->fix[fixups->fc].pcrel = (flags & OPERAND_ADDR) ? true : false;
0ef32559 525 (fixups->fc)++;
7be9a312
MH
526 }
527
528 /* truncate to the proper number of bits */
a40d3589 529 if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
ab48956f 530 as_bad("operand out of range: %d",number);
7be9a312
MH
531 number &= 0x7FFFFFFF >> (31 - bits);
532 insn = insn | (number << shift);
533 }
ab48956f
MH
534
535 /* kludge: for DIVS, we need to put the operands in twice */
536 /* on the second pass, format is changed to LONG_R to force */
537 /* the second set of operands to not be shifted over 15 */
538 if ((opcode->opcode == OPCODE_DIVS) && (format==LONG_L))
539 insn = build_insn (opcode, opers, insn);
540
7be9a312
MH
541 return insn;
542}
543
544/* write out a long form instruction */
545static void
0ef32559 546write_long (opcode, insn, fx)
7be9a312
MH
547 struct d10v_opcode *opcode;
548 unsigned long insn;
0ef32559 549 Fixups *fx;
7be9a312
MH
550{
551 int i;
552 char *f = frag_more(4);
553
554 insn |= FM11;
0ef32559 555 /* printf("INSN: %08x\n",insn); */
7be9a312
MH
556 number_to_chars_bigendian (f, insn, 4);
557
0ef32559 558 for (i=0; i < fx->fc; i++)
7be9a312 559 {
bb5638c6 560 if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].operand]))
7be9a312
MH
561 {
562 /*
563 printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
0ef32559 564 print_expr_1(stdout,&(fx->fix[i].exp));
7be9a312
MH
565 printf("\n");
566 */
0ef32559 567
7be9a312
MH
568 fix_new_exp (frag_now,
569 f - frag_now->fr_literal,
570 4,
0ef32559 571 &(fx->fix[i].exp),
bb5638c6
MH
572 fx->fix[i].pcrel,
573 fx->fix[i].operand|2048);
7be9a312
MH
574 }
575 }
0ef32559 576 fx->fc = 0;
7be9a312
MH
577}
578
0ef32559 579
7be9a312
MH
580/* write out a short form instruction by itself */
581static void
0ef32559 582write_1_short (opcode, insn, fx)
7be9a312
MH
583 struct d10v_opcode *opcode;
584 unsigned long insn;
0ef32559 585 Fixups *fx;
7be9a312
MH
586{
587 char *f = frag_more(4);
588 int i;
589
bb5638c6 590 if (opcode->exec_type & PARONLY)
a40d3589
MH
591 as_fatal ("Instruction must be executed in parallel with another instruction.");
592
ab48956f
MH
593 /* the other container needs to be NOP */
594 /* according to 4.3.1: for FM=00, sub-instructions performed only
595 by IU cannot be encoded in L-container. */
596 if (opcode->unit == IU)
597 insn |= FM00 | (NOP << 15); /* right container */
598 else
599 insn = FM00 | (insn << 15) | NOP; /* left container */
600
0ef32559 601 /* printf("INSN: %08x\n",insn); */
7be9a312 602 number_to_chars_bigendian (f, insn, 4);
0ef32559 603 for (i=0; i < fx->fc; i++)
7be9a312 604 {
f8508db7 605 bfd_reloc_code_real_type reloc;
bb5638c6 606 reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].operand]);
f8508db7 607 if (reloc)
7be9a312
MH
608 {
609 /*
610 printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
0ef32559 611 print_expr_1(stdout,&(fx->fix[i].exp));
7be9a312
MH
612 printf("\n");
613 */
614
f8508db7
MH
615 /* if it's an R reloc, we may have to switch it to L */
616 if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) )
bb5638c6 617 fx->fix[i].operand |= 1024;
f8508db7 618
7be9a312
MH
619 fix_new_exp (frag_now,
620 f - frag_now->fr_literal,
621 4,
0ef32559 622 &(fx->fix[i].exp),
bb5638c6
MH
623 fx->fix[i].pcrel,
624 fx->fix[i].operand|2048);
7be9a312
MH
625 }
626 }
0ef32559 627 fx->fc = 0;
7be9a312
MH
628}
629
630/* write out a short form instruction if possible */
631/* return number of instructions not written out */
632static int
0ef32559 633write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
7be9a312
MH
634 struct d10v_opcode *opcode1, *opcode2;
635 unsigned long insn1, insn2;
636 int exec_type;
0ef32559 637 Fixups *fx;
7be9a312
MH
638{
639 unsigned long insn;
0ef32559
MH
640 char *f;
641 int i,j;
7be9a312 642
bb5638c6
MH
643 if ( (exec_type != 1) && ((opcode1->exec_type & PARONLY)
644 || (opcode2->exec_type & PARONLY)))
a40d3589
MH
645 as_fatal("Instruction must be executed in parallel");
646
647 if ( (opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
648 as_fatal ("Long instructions may not be combined.");
649
bb5638c6 650 if(opcode1->exec_type & BRANCH_LINK)
7be9a312
MH
651 {
652 /* subroutines must be called from 32-bit boundaries */
653 /* so the return address will be correct */
0ef32559 654 write_1_short (opcode1, insn1, fx->next);
7be9a312
MH
655 return (1);
656 }
657
658 switch (exec_type)
659 {
bb5638c6
MH
660 case 0: /* order not specified */
661 if ( Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2))
662 {
663 /* parallel */
664 if (opcode1->unit == IU)
665 insn = FM00 | (insn2 << 15) | insn1;
666 else if (opcode2->unit == MU)
667 insn = FM00 | (insn2 << 15) | insn1;
668 else
669 {
670 insn = FM00 | (insn1 << 15) | insn2;
671 fx = fx->next;
672 }
673 }
674 else if (opcode1->unit == IU)
7be9a312 675 {
0ef32559 676 /* reverse sequential */
7be9a312
MH
677 insn = FM10 | (insn2 << 15) | insn1;
678 }
679 else
680 {
bb5638c6 681 /* sequential */
0ef32559
MH
682 insn = FM01 | (insn1 << 15) | insn2;
683 fx = fx->next;
7be9a312
MH
684 }
685 break;
686 case 1: /* parallel */
bb5638c6 687 if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
a40d3589
MH
688 as_fatal ("One of these instructions may not be executed in parallel.");
689
690 if (opcode1->unit == IU)
691 {
692 if (opcode2->unit == IU)
693 as_fatal ("Two IU instructions may not be executed in parallel");
694 as_warn ("Swapping instruction order");
695 insn = FM00 | (insn2 << 15) | insn1;
696 }
697 else if (opcode2->unit == MU)
698 {
699 if (opcode1->unit == MU)
700 as_fatal ("Two MU instructions may not be executed in parallel");
701 as_warn ("Swapping instruction order");
702 insn = FM00 | (insn2 << 15) | insn1;
703 }
704 else
bb5638c6
MH
705 {
706 insn = FM00 | (insn1 << 15) | insn2;
707 fx = fx->next;
708 }
7be9a312
MH
709 break;
710 case 2: /* sequential */
a40d3589
MH
711 if (opcode1->unit == IU)
712 as_fatal ("IU instruction may not be in the left container");
713 insn = FM01 | (insn1 << 15) | insn2;
714 fx = fx->next;
7be9a312
MH
715 break;
716 case 3: /* reverse sequential */
a40d3589
MH
717 if (opcode2->unit == MU)
718 as_fatal ("MU instruction may not be in the right container");
719 insn = FM10 | (insn1 << 15) | insn2;
bb5638c6 720 fx = fx->next;
7be9a312
MH
721 break;
722 default:
723 as_fatal("unknown execution type passed to write_2_short()");
724 }
725
726 /* printf("INSN: %08x\n",insn); */
0ef32559
MH
727 f = frag_more(4);
728 number_to_chars_bigendian (f, insn, 4);
729
bb5638c6
MH
730 for (j=0; j<2; j++)
731 {
732 bfd_reloc_code_real_type reloc;
733 for (i=0; i < fx->fc; i++)
734 {
735 reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].operand]);
736 if (reloc)
737 {
738 if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0) )
739 fx->fix[i].operand |= 1024;
740
741 /*
742 printf("fix_new_exp: where:%x reloc:%d\n ",f - frag_now->fr_literal,fx->fix[i].operand);
743 print_expr_1(stdout,&(fx->fix[i].exp));
744 printf("\n");
745 */
746 fix_new_exp (frag_now,
747 f - frag_now->fr_literal,
748 4,
749 &(fx->fix[i].exp),
750 fx->fix[i].pcrel,
751 fx->fix[i].operand|2048);
752 }
753 }
754 fx->fc = 0;
755 fx = fx->next;
756 }
7be9a312
MH
757 return (0);
758}
759
760
bb5638c6
MH
761/* Check 2 instructions and determine if they can be safely */
762/* executed in parallel. Returns 1 if they can be. */
763static int
764parallel_ok (op1, insn1, op2, insn2)
765 struct d10v_opcode *op1, *op2;
766 unsigned long insn1, insn2;
767{
768 int i, j, flags, mask, shift, regno;
769 unsigned long ins, mod[2], used[2];
770 struct d10v_opcode *op;
771
772 if (op1->exec_type & SEQ || op2->exec_type & SEQ)
773 return 0;
774
775 /* The idea here is to create two sets of bitmasks (mod and used) */
776 /* which indicate which registers are modified or used by each instruction. */
777 /* The operation can only be done in parallel if instruction 1 and instruction 2 */
778 /* modify different registers, and neither instruction modifies any registers */
779 /* the other is using. Accesses to control registers, PSW, and memory are treated */
780 /* as accesses to a single register. So if both instructions write memory or one */
781 /* instruction writes memory and the other reads, then they cannot be done in parallel. */
782 /* Likewise, if one instruction mucks with the psw and the other reads the PSW */
783 /* (which includes C, F0, and F1), then they cannot operate safely in parallel. */
784
785 /* the bitmasks (mod and used) look like this (bit 31 = MSB) */
786 /* r0-r15 0-15 */
787 /* a0-a1 16-17 */
788 /* cr (not psw) 18 */
789 /* psw 19 */
790 /* mem 20 */
791
792 for (j=0;j<2;j++)
793 {
794 if (j == 0)
795 {
796 op = op1;
797 ins = insn1;
798 }
799 else
800 {
801 op = op2;
802 ins = insn2;
803 }
804 mod[j] = used[j] = 0;
443dbf14 805 for (i = 0; op->operands[i]; i++)
bb5638c6
MH
806 {
807 flags = d10v_operands[op->operands[i]].flags;
808 shift = d10v_operands[op->operands[i]].shift;
809 mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
810 if (flags & OPERAND_REG)
811 {
812 regno = (ins >> shift) & mask;
813 if (flags & OPERAND_ACC)
814 regno += 16;
815 else if (flags & OPERAND_CONTROL) /* mvtc or mvfc */
816 {
817 if (regno == 0)
818 regno = 19;
819 else
820 regno = 18;
821 }
822 else if (flags & OPERAND_FLAG)
823 regno = 19;
824
825 if ( flags & OPERAND_DEST )
826 {
827 mod[j] |= 1 << regno;
828 if (flags & OPERAND_EVEN)
829 mod[j] |= 1 << (regno + 1);
830 }
831 else
832 {
833 used[j] |= 1 << regno ;
834 if (flags & OPERAND_EVEN)
835 used[j] |= 1 << (regno + 1);
836 }
837 }
443dbf14
MH
838 }
839 if (op->exec_type & RMEM)
840 used[j] |= 1 << 20;
841 else if (op->exec_type & WMEM)
842 mod[j] |= 1 << 20;
843 else if (op->exec_type & RF0)
844 used[j] |= 1 << 19;
845 else if (op->exec_type & WF0)
846 mod[j] |= 1 << 19;
847 else if (op->exec_type & WCAR)
848 mod[j] |= 1 << 19;
bb5638c6
MH
849 }
850 if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0 && (mod[1] & used[0]) == 0)
851 return 1;
852 return 0;
853}
854
855
7be9a312
MH
856/* This is the main entry point for the machine-dependent assembler. str points to a
857 machine-dependent instruction. This function is supposed to emit the frags/bytes
858 it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing
859 and leaves the difficult stuff to do_assemble().
860 */
861
862static unsigned long prev_insn;
863static struct d10v_opcode *prev_opcode = 0;
0ef32559
MH
864static subsegT prev_subseg;
865static segT prev_seg;
7be9a312
MH
866
867void
868md_assemble (str)
869 char *str;
870{
871 struct d10v_opcode *opcode;
872 unsigned long insn;
ef5a4085
MH
873 int extype=0; /* execution type; parallel, etc */
874 static int etype=0; /* saved extype. used for multiline instructions */
7be9a312
MH
875 char *str2;
876
877 /* printf("md_assemble: str=%s\n",str); */
0ef32559 878
ef5a4085 879 if (etype == 0)
7be9a312 880 {
ef5a4085
MH
881 /* look for the special multiple instruction separators */
882 str2 = strstr (str, "||");
7be9a312 883 if (str2)
ef5a4085 884 extype = 1;
7be9a312
MH
885 else
886 {
ef5a4085 887 str2 = strstr (str, "->");
7be9a312 888 if (str2)
ef5a4085
MH
889 extype = 2;
890 else
891 {
892 str2 = strstr (str, "<-");
893 if (str2)
894 extype = 3;
895 }
896 }
897 /* str2 points to the separator, if one */
898 if (str2)
899 {
900 *str2 = 0;
901
902 /* if two instructions are present and we already have one saved
903 then first write it out */
904 if (prev_opcode)
905 write_1_short (prev_opcode, prev_insn, fixups->next);
906
907 /* assemble first instruction and save it */
908 prev_insn = do_assemble (str, &prev_opcode);
909 if (prev_insn == -1)
910 as_fatal ("can't find opcode ");
911 fixups = fixups->next;
912 str = str2 + 2;
7be9a312
MH
913 }
914 }
915
ef5a4085
MH
916 insn = do_assemble (str, &opcode);
917 if (insn == -1)
7be9a312 918 {
ef5a4085
MH
919 if (extype)
920 {
921 etype = extype;
922 return;
923 }
924 as_fatal ("can't find opcode ");
7be9a312
MH
925 }
926
ef5a4085
MH
927 if (etype)
928 {
929 extype = etype;
930 etype = 0;
931 }
7be9a312
MH
932
933 /* if this is a long instruction, write it and any previous short instruction */
934 if (opcode->format & LONG_OPCODE)
935 {
ef5a4085 936 if (extype)
7be9a312
MH
937 as_fatal("Unable to mix instructions as specified");
938 if (prev_opcode)
939 {
0ef32559 940 write_1_short (prev_opcode, prev_insn, fixups->next);
7be9a312
MH
941 prev_opcode = NULL;
942 }
0ef32559 943 write_long (opcode, insn, fixups);
7be9a312
MH
944 prev_opcode = NULL;
945 return;
946 }
947
ef5a4085 948 if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
7be9a312
MH
949 {
950 /* no instructions saved */
951 prev_opcode = NULL;
952 }
953 else
954 {
ef5a4085 955 if (extype)
7be9a312
MH
956 as_fatal("Unable to mix instructions as specified");
957 /* save off last instruction so it may be packed on next pass */
958 prev_opcode = opcode;
959 prev_insn = insn;
0ef32559
MH
960 prev_seg = now_seg;
961 prev_subseg = now_subseg;
962 fixups = fixups->next;
7be9a312
MH
963 }
964}
965
966
ef5a4085
MH
967/* do_assemble assembles a single instruction and returns an opcode */
968/* it returns -1 (an invalid opcode) on error */
969
7be9a312
MH
970static unsigned long
971do_assemble (str, opcode)
972 char *str;
973 struct d10v_opcode **opcode;
974{
7be9a312
MH
975 unsigned char *op_start, *save;
976 unsigned char *op_end;
977 char name[20];
bb5638c6 978 int nlen = 0;
7be9a312
MH
979 expressionS myops[6];
980 unsigned long insn;
981
0ef32559 982 /* printf("do_assemble: str=%s\n",str); */
7be9a312
MH
983
984 /* Drop leading whitespace */
985 while (*str == ' ')
986 str++;
987
988 /* find the opcode end */
989 for (op_start = op_end = (unsigned char *) (str);
990 *op_end
991 && nlen < 20
992 && !is_end_of_line[*op_end] && *op_end != ' ';
993 op_end++)
994 {
995 name[nlen] = op_start[nlen];
996 nlen++;
997 }
998 name[nlen] = 0;
999
1000 if (nlen == 0)
ef5a4085 1001 return (-1);
7be9a312
MH
1002
1003 /* find the first opcode with the proper name */
1004 *opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
1005 if (*opcode == NULL)
ab48956f 1006 as_fatal ("unknown opcode: %s",name);
7be9a312
MH
1007
1008 save = input_line_pointer;
1009 input_line_pointer = op_end;
bb5638c6
MH
1010 *opcode = find_opcode (*opcode, myops);
1011 if (*opcode == 0)
1012 return -1;
1013 input_line_pointer = save;
1014
1015 insn = build_insn ((*opcode), myops, 0);
1016 /* printf("sub-insn = %lx\n",insn); */
1017 return (insn);
1018}
1019
1020/* find_opcode() gets a pointer to an entry in the opcode table. */
1021/* It must look at all opcodes with the same name and use the operands */
1022/* to choose the correct opcode. */
1023
1024static struct d10v_opcode *
1025find_opcode (opcode, myops)
1026 struct d10v_opcode *opcode;
1027 expressionS myops[];
1028{
1029 int i, match, done, numops;
1030 struct d10v_opcode *next_opcode;
7be9a312
MH
1031
1032 /* get all the operands and save them as expressions */
1033 numops = get_operands (myops);
1034
ab48956f
MH
1035 /* now see if the operand is a fake. If so, find the correct size */
1036 /* instruction, if possible */
bb5638c6 1037 if (opcode->format == OPCODE_FAKE)
7be9a312 1038 {
bb5638c6
MH
1039 int opnum = opcode->operands[0];
1040
1041 if (myops[opnum].X_op == O_register)
7be9a312 1042 {
bb5638c6
MH
1043 myops[opnum].X_op = O_symbol;
1044 myops[opnum].X_add_symbol = symbol_find_or_make ((char *)myops[opnum].X_op_symbol);
1045 myops[opnum].X_add_number = 0;
1046 myops[opnum].X_op_symbol = NULL;
1047 }
1048
443dbf14
MH
1049 if (myops[opnum].X_op == O_constant || (myops[opnum].X_op == O_symbol &&
1050 S_IS_DEFINED(myops[opnum].X_add_symbol) &&
1051 (S_GET_SEGMENT(myops[opnum].X_add_symbol) == now_seg)))
bb5638c6
MH
1052 {
1053 next_opcode=opcode+1;
1054 for (i=0; opcode->operands[i+1]; i++)
7be9a312 1055 {
ab48956f
MH
1056 int bits = d10v_operands[next_opcode->operands[opnum]].bits;
1057 int flags = d10v_operands[next_opcode->operands[opnum]].flags;
67f0d0ea
MH
1058 if (flags & OPERAND_ADDR)
1059 bits += 2;
1060 if (myops[opnum].X_op == O_constant)
1061 {
1062 if (!check_range (myops[opnum].X_add_number, bits, flags))
1063 return next_opcode;
1064 }
1065 else
1066 {
1067 int value = obstack_next_free(&frchain_now->frch_obstack) - frag_now->fr_literal -
1068 S_GET_VALUE(myops[opnum].X_add_symbol);
1069 if (!check_range (value, bits, flags))
1070 return next_opcode;
1071 }
ab48956f 1072 next_opcode++;
7be9a312 1073 }
bb5638c6 1074 as_fatal ("value out of range");
ab48956f
MH
1075 }
1076 else
1077 {
bb5638c6
MH
1078 /* not a constant, so use a long instruction */
1079 return opcode+2;
ab48956f 1080 }
ab48956f
MH
1081 }
1082 else
1083 {
bb5638c6 1084 match = 0;
ab48956f 1085 /* now search the opcode table table for one with operands */
ef5a4085 1086 /* that matches what we've got */
ab48956f
MH
1087 while (!match)
1088 {
1089 match = 1;
bb5638c6 1090 for (i = 0; opcode->operands[i]; i++)
7be9a312 1091 {
bb5638c6 1092 int flags = d10v_operands[opcode->operands[i]].flags;
ab48956f
MH
1093 int X_op = myops[i].X_op;
1094 int num = myops[i].X_add_number;
1095
1096 if (X_op==0)
7be9a312
MH
1097 {
1098 match=0;
1099 break;
ab48956f
MH
1100 }
1101
1102 if (flags & OPERAND_REG)
1103 {
1104 if ((X_op != O_register) ||
1105 ((flags & OPERAND_ACC) != (num & OPERAND_ACC)) ||
1106 ((flags & OPERAND_FLAG) != (num & OPERAND_FLAG)) ||
1107 ((flags & OPERAND_CONTROL) != (num & OPERAND_CONTROL)))
1108 {
1109 match=0;
1110 break;
1111 }
1112 }
1113
1114 if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
1115 ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
1116 ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
1117 ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
1118 ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || (num != OPERAND_ATSIGN))))
1119 {
1120 match=0;
1121 break;
bb5638c6 1122 }
7be9a312 1123 }
ab48956f 1124
bb5638c6 1125 /* we're only done if the operands matched so far AND there
ab48956f
MH
1126 are no more to check */
1127 if (match && myops[i].X_op==0)
1128 break;
1129
bb5638c6 1130 next_opcode = opcode+1;
ab48956f
MH
1131 if (next_opcode->opcode == 0)
1132 break;
bb5638c6 1133 if (strcmp(next_opcode->name, opcode->name))
ab48956f 1134 break;
bb5638c6 1135 opcode = next_opcode;
7be9a312 1136 }
ab48956f 1137 }
7be9a312
MH
1138
1139 if (!match)
1140 {
1141 as_bad ("bad opcode or operands");
1142 return (0);
1143 }
1144
1145 /* Check that all registers that are required to be even are. */
1146 /* Also, if any operands were marked as registers, but were really symbols */
1147 /* fix that here. */
bb5638c6 1148 for (i=0; opcode->operands[i]; i++)
7be9a312 1149 {
bb5638c6 1150 if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
7be9a312
MH
1151 (myops[i].X_add_number & 1))
1152 as_fatal("Register number must be EVEN");
1153 if (myops[i].X_op == O_register)
1154 {
bb5638c6 1155 if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
7be9a312
MH
1156 {
1157 myops[i].X_op = O_symbol;
0ef32559 1158 myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
7be9a312 1159 myops[i].X_add_number = 0;
0ef32559 1160 myops[i].X_op_symbol = NULL;
7be9a312
MH
1161 }
1162 }
1163 }
bb5638c6 1164 return opcode;
7be9a312
MH
1165}
1166
7be9a312
MH
1167/* if while processing a fixup, a reloc really needs to be created */
1168/* then it is done here */
1169
1170arelent *
1171tc_gen_reloc (seg, fixp)
1172 asection *seg;
1173 fixS *fixp;
1174{
1175 arelent *reloc;
1176 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
1177 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1178 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1179 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1180 if (reloc->howto == (reloc_howto_type *) NULL)
1181 {
1182 as_bad_where (fixp->fx_file, fixp->fx_line,
1183 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
1184 return NULL;
1185 }
1186 reloc->addend = fixp->fx_addnumber;
e805bff7 1187 /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
7be9a312
MH
1188 return reloc;
1189}
1190
1191int
1192md_estimate_size_before_relax (fragp, seg)
1193 fragS *fragp;
1194 asection *seg;
1195{
1196 abort ();
1197 return 0;
1198}
1199
1200long
1201md_pcrel_from_section (fixp, sec)
1202 fixS *fixp;
1203 segT sec;
1204{
bb5638c6 1205 if (fixp->fx_addsy != (symbolS *)NULL && !S_IS_DEFINED (fixp->fx_addsy))
7be9a312 1206 return 0;
bb5638c6
MH
1207 /* printf("pcrel_from_section: %x\n", fixp->fx_frag->fr_address + fixp->fx_where); */
1208 return fixp->fx_frag->fr_address + fixp->fx_where;
7be9a312
MH
1209}
1210
1211int
1212md_apply_fix3 (fixp, valuep, seg)
1213 fixS *fixp;
1214 valueT *valuep;
1215 segT seg;
1216{
7be9a312
MH
1217 char *where;
1218 unsigned long insn;
93050391 1219 long value;
7be9a312 1220 int op_type;
0ef32559 1221 int left=0;
7be9a312
MH
1222
1223 if (fixp->fx_addsy == (symbolS *) NULL)
1224 {
1225 value = *valuep;
1226 fixp->fx_done = 1;
1227 }
1228 else if (fixp->fx_pcrel)
1229 value = *valuep;
1230 else
1231 {
1232 value = fixp->fx_offset;
1233 if (fixp->fx_subsy != (symbolS *) NULL)
1234 {
1235 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1236 value -= S_GET_VALUE (fixp->fx_subsy);
1237 else
1238 {
1239 /* We don't actually support subtracting a symbol. */
1240 as_bad_where (fixp->fx_file, fixp->fx_line,
1241 "expression too complex");
1242 }
1243 }
1244 }
1245
67f0d0ea 1246 /* printf("md_apply_fix: value=0x%x type=0x%x where=0x%x size=%d line=%d\n", value, fixp->fx_r_type,fixp->fx_where,fixp->fx_size, fixp->fx_line); */
7be9a312
MH
1247
1248 op_type = fixp->fx_r_type;
e805bff7 1249 if (op_type & 2048)
0ef32559 1250 {
e805bff7
MH
1251 op_type -= 2048;
1252 if (op_type & 1024)
1253 {
1254 op_type -= 1024;
1255 fixp->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
1256 left = 1;
1257 }
1258 else
1259 fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
0ef32559 1260 }
7be9a312
MH
1261
1262 /* Fetch the instruction, insert the fully resolved operand
1263 value, and stuff the instruction back again. */
1264 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1265 insn = bfd_getb32 ((unsigned char *) where);
7be9a312 1266
93050391
MH
1267 switch (fixp->fx_r_type)
1268 {
1269 case BFD_RELOC_D10V_10_PCREL_L:
1270 case BFD_RELOC_D10V_10_PCREL_R:
1271 case BFD_RELOC_D10V_18_PCREL:
bb5638c6 1272 /* instruction addresses are always right-shifted by 2 */
93050391 1273 value >>= 2;
e805bff7
MH
1274 break;
1275 case BFD_RELOC_32:
1276 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
1277 return 1;
67f0d0ea
MH
1278 case BFD_RELOC_16:
1279 if (fixp->fx_size == 2)
1280 {
1281 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
1282 return 1;
1283 }
93050391
MH
1284 default:
1285 break;
1286 }
e805bff7
MH
1287
1288 /* printf(" insn=%x value=%x where=%x pcrel=%x\n",insn,value,fixp->fx_where,fixp->fx_pcrel); */
67f0d0ea 1289 insn = d10v_insert_operand (insn, op_type, (offsetT)value, left, fixp);
7be9a312
MH
1290 /* printf(" new insn=%x\n",insn); */
1291
1292 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1293
1294 if (fixp->fx_done)
1295 return 1;
1296
1297 fixp->fx_addnumber = value;
1298 return 1;
1299}
1300
7be9a312 1301
0ef32559
MH
1302/* d10v_cleanup() is called after the assembler has finished parsing the input
1303 file or after a label is defined. Because the D10V assembler sometimes saves short
1304 instructions to see if it can package them with the next instruction, there may
1305 be a short instruction that still needs written. */
7be9a312 1306int
ab48956f
MH
1307d10v_cleanup (done)
1308 int done;
7be9a312 1309{
0ef32559
MH
1310 segT seg;
1311 subsegT subseg;
1312
ab48956f 1313 if ( prev_opcode && (done || (now_seg == prev_seg) && (now_subseg == prev_subseg)))
7be9a312 1314 {
0ef32559
MH
1315 seg = now_seg;
1316 subseg = now_subseg;
1317 subseg_set (prev_seg, prev_subseg);
443dbf14 1318 write_1_short (prev_opcode, prev_insn, fixups->next);
0ef32559 1319 subseg_set (seg, subseg);
7be9a312
MH
1320 prev_opcode = NULL;
1321 }
1322 return 1;
1323}
This page took 0.085196 seconds and 4 git commands to generate.