* configure.in: Make all i386-elf targets use bfd_gas.
[deliverable/binutils-gdb.git] / gas / config / tc-d30v.c
CommitLineData
9b1168d6
MH
1/* tc-d30v.c -- Assembler code for the Mitsubishi D30V
2
ccc12f73 3 Copyright (C) 1997, 1998 Free Software Foundation.
9b1168d6
MH
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/d30v.h"
27
28const char comment_chars[] = ";";
29const char line_comment_chars[] = "#";
30const char line_separator_chars[] = "";
343b2ab8 31const char *md_shortopts = "OnN";
9b1168d6
MH
32const char EXP_CHARS[] = "eE";
33const char FLT_CHARS[] = "dD";
34
343b2ab8
MM
35#define NOP_MULTIPLY 1
36#define NOP_ALL 2
37static int warn_nops = 0;
38static int Optimizing = 0;
9b1168d6 39
e0882f34
MM
40#define FORCE_SHORT 1
41#define FORCE_LONG 2
42
343b2ab8
MM
43/* EXEC types. */
44typedef enum _exec_type
45{
46 EXEC_UNKNOWN, /* no order specified */
ccc12f73
FF
47 EXEC_PARALLEL, /* done in parallel (FM=00) */
48 EXEC_SEQ, /* sequential (FM=01) */
49 EXEC_REVSEQ /* reverse sequential (FM=10) */
343b2ab8
MM
50} exec_type_enum;
51
9b1168d6
MH
52/* fixups */
53#define MAX_INSN_FIXUPS (5)
54struct d30v_fixup
55{
56 expressionS exp;
57 int operand;
58 int pcrel;
59 int size;
60 bfd_reloc_code_real_type reloc;
61};
62
63typedef struct _fixups
64{
65 int fc;
66 struct d30v_fixup fix[MAX_INSN_FIXUPS];
67 struct _fixups *next;
68} Fixups;
69
70static Fixups FixUps[2];
71static Fixups *fixups;
72
343b2ab8 73/* Whether current and previous instruction is a word multiply. */
7d515759
RH
74static int cur_mul32_p = 0;
75static int prev_mul32_p = 0;
343b2ab8 76
ccc12f73
FF
77/* The flag_explicitly_parallel is true iff the instruction being assembled
78 has been explicitly written as a parallel short-instruction pair by the
79 human programmer. It is used in parallel_ok() to distinguish between
80 those dangerous parallelizations attempted by the human, which are to be
81 allowed, and those attempted by the assembler, which are not. It is set
82 from md_assemble(). */
83static int flag_explicitly_parallel = 0;
84static int flag_xp_state = 0;
85
e21cafde
FCE
86/* Whether current and previous left sub-instruction disables
87 execution of right sub-instruction. */
88static int cur_left_kills_right_p = 0;
89static int prev_left_kills_right_p = 0;
90
7d515759
RH
91/* The known current alignment of the current section. */
92static int d30v_current_align;
93static segT d30v_current_align_seg;
94
95/* The last seen label in the current section. This is used to auto-align
96 labels preceeding instructions. */
97static symbolS *d30v_last_label;
98
343b2ab8
MM
99/* Two nops */
100#define NOP_LEFT ((long long)NOP << 32)
101#define NOP_RIGHT ((long long)NOP)
102#define NOP2 (FM00 | NOP_LEFT | NOP_RIGHT)
103
9b1168d6
MH
104/* local functions */
105static int reg_name_search PARAMS ((char *name));
106static int register_name PARAMS ((expressionS *expressionP));
107static int check_range PARAMS ((unsigned long num, int bits, int flags));
108static int postfix PARAMS ((char *p));
109static bfd_reloc_code_real_type get_reloc PARAMS ((struct d30v_operand *op, int rel_flag));
110static int get_operands PARAMS ((expressionS exp[], int cmp_hack));
e0882f34
MM
111static struct d30v_format *find_format PARAMS ((struct d30v_opcode *opcode,
112 expressionS ops[],int fsize, int cmp_hack));
9b1168d6
MH
113static long long build_insn PARAMS ((struct d30v_insn *opcode, expressionS *opers));
114static void write_long PARAMS ((struct d30v_insn *opcode, long long insn, Fixups *fx));
115static void write_1_short PARAMS ((struct d30v_insn *opcode, long long insn, Fixups *fx));
116static int write_2_short PARAMS ((struct d30v_insn *opcode1, long long insn1,
343b2ab8 117 struct d30v_insn *opcode2, long long insn2, exec_type_enum exec_type, Fixups *fx));
daaef8f8 118static long long do_assemble PARAMS ((char *str, struct d30v_insn *opcode,
7a0f469b 119 int shortp, int is_parallel));
9b1168d6
MH
120static int parallel_ok PARAMS ((struct d30v_insn *opcode1, unsigned long insn1,
121 struct d30v_insn *opcode2, unsigned long insn2,
343b2ab8 122 exec_type_enum exec_type));
9b1168d6 123static void d30v_number_to_chars PARAMS ((char *buf, long long value, int nbytes));
e0882f34 124static void check_size PARAMS ((long value, int bits, char *file, int line));
7d515759
RH
125static void d30v_align PARAMS ((int, char *, symbolS *));
126static void s_d30v_align PARAMS ((int));
127static void s_d30v_text PARAMS ((int));
128static void s_d30v_data PARAMS ((int));
129static void s_d30v_section PARAMS ((int));
9b1168d6
MH
130
131struct option md_longopts[] = {
132 {NULL, no_argument, NULL, 0}
133};
134size_t md_longopts_size = sizeof(md_longopts);
135
136
137/* The target specific pseudo-ops which we support. */
138const pseudo_typeS md_pseudo_table[] =
139{
e0882f34
MM
140 { "word", cons, 4 },
141 { "hword", cons, 2 },
7d515759
RH
142 { "align", s_d30v_align, 0 },
143 { "text", s_d30v_text, 0 },
144 { "data", s_d30v_data, 0 },
145 { "section", s_d30v_section, 0 },
146 { "section.s", s_d30v_section, 0 },
147 { "sect", s_d30v_section, 0 },
148 { "sect.s", s_d30v_section, 0 },
e0882f34 149 { NULL, NULL, 0 }
9b1168d6
MH
150};
151
152/* Opcode hash table. */
153static struct hash_control *d30v_hash;
154
155/* reg_name_search does a binary search of the pre_defined_registers
156 array to see if "name" is a valid regiter name. Returns the register
157 number from the array on success, or -1 on failure. */
158
159static int
160reg_name_search (name)
161 char *name;
162{
163 int middle, low, high;
164 int cmp;
165
166 low = 0;
7a0f469b 167 high = reg_name_cnt () - 1;
9b1168d6
MH
168
169 do
170 {
171 middle = (low + high) / 2;
172 cmp = strcasecmp (name, pre_defined_registers[middle].name);
173 if (cmp < 0)
174 high = middle - 1;
175 else if (cmp > 0)
176 low = middle + 1;
177 else
178 return pre_defined_registers[middle].value;
179 }
180 while (low <= high);
181 return -1;
182}
183
184/* register_name() checks the string at input_line_pointer
185 to see if it is a valid register name */
186
187static int
188register_name (expressionP)
189 expressionS *expressionP;
190{
191 int reg_number;
192 char c, *p = input_line_pointer;
193
194 while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
195 p++;
196
197 c = *p;
198 if (c)
199 *p++ = 0;
200
201 /* look to see if it's in the register table */
202 reg_number = reg_name_search (input_line_pointer);
203 if (reg_number >= 0)
204 {
205 expressionP->X_op = O_register;
206 /* temporarily store a pointer to the string here */
207 expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
208 expressionP->X_add_number = reg_number;
209 input_line_pointer = p;
210 return 1;
211 }
212 if (c)
213 *(p-1) = c;
214 return 0;
215}
216
217
218static int
219check_range (num, bits, flags)
220 unsigned long num;
221 int bits;
222 int flags;
223{
343b2ab8 224 long min, max;
9b1168d6
MH
225 int retval=0;
226
227 /* don't bother checking 32-bit values */
228 if (bits == 32)
229 return 0;
230
e21cafde
FCE
231 if (flags & OPERAND_SHIFT)
232 {
233 /* We know that all shifts are right by three bits.... */
234
235 if (flags & OPERAND_SIGNED)
236 num = (unsigned long) (((/*signed*/ long) num) >> 3);
237 else
238 num >>= 3;
239 }
240
9b1168d6
MH
241 if (flags & OPERAND_SIGNED)
242 {
243 max = (1 << (bits - 1))-1;
e0882f34 244 min = - (1 << (bits - 1));
9b1168d6
MH
245 if (((long)num > max) || ((long)num < min))
246 retval = 1;
247 }
248 else
249 {
250 max = (1 << bits) - 1;
251 min = 0;
252 if ((num > max) || (num < min))
253 retval = 1;
254 }
255 return retval;
256}
257
258
259void
260md_show_usage (stream)
261 FILE *stream;
262{
7a0f469b 263 fprintf (stream, _("\nD30V options:\n\
343b2ab8
MM
264-O Make adjacent short instructions parallel if possible.\n\
265-n Warn about all NOPs inserted by the assembler.\n\
7d515759 266-N Warn about NOPs inserted after word multiplies.\n"));
9b1168d6
MH
267}
268
269int
270md_parse_option (c, arg)
271 int c;
272 char *arg;
273{
274 switch (c)
275 {
9b1168d6 276 /* Optimize. Will attempt to parallelize operations */
343b2ab8 277 case 'O':
9b1168d6
MH
278 Optimizing = 1;
279 break;
343b2ab8
MM
280
281 /* Warn about all NOPS that the assembler inserts. */
282 case 'n':
283 warn_nops = NOP_ALL;
284 break;
285
286 /* Warn about the NOPS that the assembler inserts because of the
287 multiply hazard. */
288 case 'N':
289 warn_nops = NOP_MULTIPLY;
290 break;
291
9b1168d6
MH
292 default:
293 return 0;
294 }
295 return 1;
296}
297
298symbolS *
299md_undefined_symbol (name)
300 char *name;
301{
302 return 0;
303}
304
305/* Turn a string in input_line_pointer into a floating point constant of type
306 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
307 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
308 */
309char *
310md_atof (type, litP, sizeP)
311 int type;
312 char *litP;
313 int *sizeP;
314{
315 int prec;
316 LITTLENUM_TYPE words[4];
317 char *t;
318 int i;
319
320 switch (type)
321 {
322 case 'f':
323 prec = 2;
324 break;
325 case 'd':
326 prec = 4;
327 break;
328 default:
329 *sizeP = 0;
48401fcf 330 return _("bad call to md_atof");
9b1168d6
MH
331 }
332
333 t = atof_ieee (input_line_pointer, type, words);
334 if (t)
335 input_line_pointer = t;
336
337 *sizeP = prec * 2;
338
339 for (i = 0; i < prec; i++)
340 {
341 md_number_to_chars (litP, (valueT) words[i], 2);
342 litP += 2;
343 }
344 return NULL;
345}
346
347void
348md_convert_frag (abfd, sec, fragP)
349 bfd *abfd;
350 asection *sec;
351 fragS *fragP;
352{
353 abort ();
354}
355
356valueT
357md_section_align (seg, addr)
358 asection *seg;
359 valueT addr;
360{
361 int align = bfd_get_section_alignment (stdoutput, seg);
362 return ((addr + (1 << align) - 1) & (-1 << align));
363}
364
365
366void
367md_begin ()
368{
369 struct d30v_opcode *opcode;
7a0f469b 370 d30v_hash = hash_new ();
9b1168d6
MH
371
372 /* Insert opcode names into a hash table. */
373 for (opcode = (struct d30v_opcode *)d30v_opcode_table; opcode->name; opcode++)
374 hash_insert (d30v_hash, opcode->name, (char *) opcode);
375
376 fixups = &FixUps[0];
377 FixUps[0].next = &FixUps[1];
378 FixUps[1].next = &FixUps[0];
7d515759
RH
379
380 d30v_current_align_seg = now_seg;
9b1168d6
MH
381}
382
383
384/* this function removes the postincrement or postdecrement
385 operator ( '+' or '-' ) from an expression */
386
387static int postfix (p)
388 char *p;
389{
390 while (*p != '-' && *p != '+')
391 {
2c268a85 392 if (*p==0 || *p=='\n' || *p=='\r' || *p==' ' || *p==',')
9b1168d6
MH
393 break;
394 p++;
395 }
396
397 if (*p == '-')
398 {
399 *p = ' ';
400 return (-1);
401 }
402 if (*p == '+')
403 {
404 *p = ' ';
405 return (1);
406 }
407
408 return (0);
409}
410
411
412static bfd_reloc_code_real_type
413get_reloc (op, rel_flag)
414 struct d30v_operand *op;
415 int rel_flag;
416{
417 switch (op->bits)
418 {
419 case 6:
e0882f34
MM
420 if (op->flags & OPERAND_SHIFT)
421 return BFD_RELOC_D30V_9_PCREL;
422 else
423 return BFD_RELOC_D30V_6;
424 break;
9b1168d6
MH
425 case 12:
426 if (!(op->flags & OPERAND_SHIFT))
7a0f469b 427 as_warn (_("unexpected 12-bit reloc type"));
9b1168d6
MH
428 if (rel_flag == RELOC_PCREL)
429 return BFD_RELOC_D30V_15_PCREL;
430 else
431 return BFD_RELOC_D30V_15;
432 case 18:
433 if (!(op->flags & OPERAND_SHIFT))
7a0f469b 434 as_warn (_("unexpected 18-bit reloc type"));
9b1168d6
MH
435 if (rel_flag == RELOC_PCREL)
436 return BFD_RELOC_D30V_21_PCREL;
437 else
438 return BFD_RELOC_D30V_21;
439 case 32:
440 if (rel_flag == RELOC_PCREL)
441 return BFD_RELOC_D30V_32_PCREL;
442 else
443 return BFD_RELOC_D30V_32;
444 default:
445 return 0;
446 }
447}
448
449/* get_operands parses a string of operands and returns
450 an array of expressions */
451
452static int
453get_operands (exp, cmp_hack)
454 expressionS exp[];
455 int cmp_hack;
456{
457 char *p = input_line_pointer;
458 int numops = 0;
459 int post = 0;
460
461 if (cmp_hack)
462 {
463 exp[numops].X_op = O_absent;
464 exp[numops++].X_add_number = cmp_hack - 1;
465 }
466
467 while (*p)
468 {
469 while (*p == ' ' || *p == '\t' || *p == ',')
470 p++;
471 if (*p==0 || *p=='\n' || *p=='\r')
472 break;
473
474 if (*p == '@')
475 {
476 p++;
477 exp[numops].X_op = O_absent;
478 if (*p == '(')
479 {
480 p++;
481 exp[numops].X_add_number = OPERAND_ATPAR;
482 post = postfix (p);
483 }
484 else if (*p == '-')
485 {
486 p++;
487 exp[numops].X_add_number = OPERAND_ATMINUS;
488 }
489 else
490 {
491 exp[numops].X_add_number = OPERAND_ATSIGN;
492 post = postfix (p);
493 }
494 numops++;
495 continue;
496 }
497
498 if (*p == ')')
499 {
500 /* just skip the trailing paren */
501 p++;
502 continue;
503 }
504
505 input_line_pointer = p;
506
507 /* check to see if it might be a register name */
508 if (!register_name (&exp[numops]))
509 {
510 /* parse as an expression */
511 expression (&exp[numops]);
512 }
513
514 if (exp[numops].X_op == O_illegal)
48401fcf 515 as_bad (_("illegal operand"));
9b1168d6 516 else if (exp[numops].X_op == O_absent)
48401fcf 517 as_bad (_("missing operand"));
9b1168d6
MH
518
519 numops++;
520 p = input_line_pointer;
521
522 switch (post)
523 {
524 case -1: /* postdecrement mode */
525 exp[numops].X_op = O_absent;
526 exp[numops++].X_add_number = OPERAND_MINUS;
527 break;
528 case 1: /* postincrement mode */
529 exp[numops].X_op = O_absent;
530 exp[numops++].X_add_number = OPERAND_PLUS;
531 break;
532 }
533 post = 0;
534 }
535
536 exp[numops].X_op = 0;
537 return (numops);
538}
539
9b1168d6
MH
540/* build_insn generates the instruction. It does everything */
541/* but write the FM bits. */
542
543static long long
544build_insn (opcode, opers)
545 struct d30v_insn *opcode;
546 expressionS *opers;
547{
343b2ab8 548 int i, length, bits, shift, flags;
9b1168d6
MH
549 unsigned int number, id=0;
550 long long insn;
551 struct d30v_opcode *op = opcode->op;
552 struct d30v_format *form = opcode->form;
553
9b1168d6 554 insn = opcode->ecc << 28 | op->op1 << 25 | op->op2 << 20 | form->modifier << 18;
e0882f34 555
9b1168d6
MH
556 for (i=0; form->operands[i]; i++)
557 {
558 flags = d30v_operand_table[form->operands[i]].flags;
559
9b1168d6
MH
560 /* must be a register or number */
561 if (!(flags & OPERAND_REG) && !(flags & OPERAND_NUM) &&
562 !(flags & OPERAND_NAME) && !(flags & OPERAND_SPECIAL))
563 continue;
564
565 bits = d30v_operand_table[form->operands[i]].bits;
e0882f34
MM
566 if (flags & OPERAND_SHIFT)
567 bits += 3;
568
9b1168d6
MH
569 length = d30v_operand_table[form->operands[i]].length;
570 shift = 12 - d30v_operand_table[form->operands[i]].position;
e0882f34
MM
571 if (opers[i].X_op != O_symbol)
572 number = opers[i].X_add_number;
573 else
574 number = 0;
9b1168d6
MH
575 if (flags & OPERAND_REG)
576 {
e0882f34
MM
577 /* check for mvfsys or mvtsys control registers */
578 if (flags & OPERAND_CONTROL && (number & 0x7f) > MAX_CONTROL_REG)
9b1168d6
MH
579 {
580 /* PSWL or PSWH */
e0882f34
MM
581 id = (number & 0x7f) - MAX_CONTROL_REG;
582 number = 0;
9b1168d6
MH
583 }
584 else if (number & OPERAND_FLAG)
585 {
586 id = 3; /* number is a flag register */
587 }
e0882f34 588 number &= 0x7F;
9b1168d6
MH
589 }
590 else if (flags & OPERAND_SPECIAL)
591 {
592 number = id;
593 }
9b1168d6
MH
594
595 if (opers[i].X_op != O_register && opers[i].X_op != O_constant && !(flags & OPERAND_NAME))
596 {
597 /* now create a fixup */
598
599 if (fixups->fc >= MAX_INSN_FIXUPS)
48401fcf 600 as_fatal (_("too many fixups"));
9b1168d6
MH
601
602 fixups->fix[fixups->fc].reloc =
7a0f469b 603 get_reloc ((struct d30v_operand *)&d30v_operand_table[form->operands[i]], op->reloc_flag);
9b1168d6
MH
604 fixups->fix[fixups->fc].size = 4;
605 fixups->fix[fixups->fc].exp = opers[i];
606 fixups->fix[fixups->fc].operand = form->operands[i];
e0882f34
MM
607 if (fixups->fix[fixups->fc].reloc == BFD_RELOC_D30V_9_PCREL)
608 fixups->fix[fixups->fc].pcrel = RELOC_PCREL;
609 else
610 fixups->fix[fixups->fc].pcrel = op->reloc_flag;
9b1168d6
MH
611 (fixups->fc)++;
612 }
613
614 /* truncate to the proper number of bits */
2c268a85 615 if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
7a0f469b 616 as_bad (_("operand out of range: %d"),number);
2c268a85 617 if (bits < 31)
9b1168d6 618 number &= 0x7FFFFFFF >> (31 - bits);
e0882f34
MM
619 if (flags & OPERAND_SHIFT)
620 number >>= 3;
9b1168d6
MH
621 if (bits == 32)
622 {
623 /* it's a LONG instruction */
624 insn |= (number >> 26); /* top 6 bits */
625 insn <<= 32; /* shift the first word over */
626 insn |= ((number & 0x03FC0000) << 2); /* next 8 bits */
627 insn |= number & 0x0003FFFF; /* bottom 18 bits */
628 }
629 else
630 insn |= number << shift;
631 }
632 return insn;
633}
634
635
636/* write out a long form instruction */
637static void
638write_long (opcode, insn, fx)
639 struct d30v_insn *opcode;
640 long long insn;
641 Fixups *fx;
642{
643 int i, where;
7a0f469b 644 char *f = frag_more (8);
9b1168d6
MH
645
646 insn |= FM11;
647 d30v_number_to_chars (f, insn, 8);
648
649 for (i=0; i < fx->fc; i++)
650 {
651 if (fx->fix[i].reloc)
652 {
653 where = f - frag_now->fr_literal;
9b1168d6
MH
654 fix_new_exp (frag_now,
655 where,
656 fx->fix[i].size,
657 &(fx->fix[i].exp),
658 fx->fix[i].pcrel,
659 fx->fix[i].reloc);
660 }
661 }
662 fx->fc = 0;
663}
664
665
666/* write out a short form instruction by itself */
667static void
668write_1_short (opcode, insn, fx)
669 struct d30v_insn *opcode;
670 long long insn;
671 Fixups *fx;
672{
7a0f469b 673 char *f = frag_more (8);
9b1168d6
MH
674 int i, where;
675
343b2ab8 676 if (warn_nops == NOP_ALL)
48401fcf 677 as_warn (_("NOP inserted"));
343b2ab8 678
9b1168d6
MH
679 /* the other container needs to be NOP */
680 /* according to 4.3.1: for FM=00, sub-instructions performed only
681 by IU cannot be encoded in L-container. */
682 if (opcode->op->unit == IU)
343b2ab8 683 insn |= FM00 | NOP_LEFT; /* right container */
9b1168d6 684 else
343b2ab8 685 insn = FM00 | (insn << 32) | NOP_RIGHT; /* left container */
9b1168d6
MH
686
687 d30v_number_to_chars (f, insn, 8);
688
689 for (i=0; i < fx->fc; i++)
690 {
691 if (fx->fix[i].reloc)
692 {
693 where = f - frag_now->fr_literal;
9b1168d6
MH
694 fix_new_exp (frag_now,
695 where,
696 fx->fix[i].size,
697 &(fx->fix[i].exp),
698 fx->fix[i].pcrel,
699 fx->fix[i].reloc);
700 }
701 }
702 fx->fc = 0;
703}
704
705/* write out a short form instruction if possible */
706/* return number of instructions not written out */
707static int
708write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
709 struct d30v_insn *opcode1, *opcode2;
710 long long insn1, insn2;
343b2ab8 711 exec_type_enum exec_type;
9b1168d6
MH
712 Fixups *fx;
713{
343b2ab8 714 long long insn = NOP2;
9b1168d6
MH
715 char *f;
716 int i,j, where;
717
7a0f469b 718 if (exec_type != EXEC_PARALLEL &&
48401fcf 719 ((opcode1->op->flags_used & (FLAG_JSR | FLAG_DELAY)) == FLAG_JSR))
9b1168d6
MH
720 {
721 /* subroutines must be called from 32-bit boundaries */
722 /* so the return address will be correct */
723 write_1_short (opcode1, insn1, fx->next);
724 return (1);
725 }
726
727 switch (exec_type)
728 {
343b2ab8
MM
729 case EXEC_UNKNOWN: /* order not specified */
730 if (Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
9b1168d6
MH
731 {
732 /* parallel */
343b2ab8 733 exec_type = EXEC_PARALLEL;
9b1168d6
MH
734 if (opcode1->op->unit == IU)
735 insn = FM00 | (insn2 << 32) | insn1;
736 else if (opcode2->op->unit == MU)
737 insn = FM00 | (insn2 << 32) | insn1;
738 else
739 {
740 insn = FM00 | (insn1 << 32) | insn2;
741 fx = fx->next;
742 }
743 }
343b2ab8 744 else if (opcode1->op->unit == IU)
9b1168d6
MH
745 {
746 /* reverse sequential */
747 insn = FM10 | (insn2 << 32) | insn1;
343b2ab8 748 exec_type = EXEC_REVSEQ;
9b1168d6
MH
749 }
750 else
751 {
752 /* sequential */
753 insn = FM01 | (insn1 << 32) | insn2;
343b2ab8
MM
754 fx = fx->next;
755 exec_type = EXEC_SEQ;
9b1168d6
MH
756 }
757 break;
343b2ab8
MM
758
759 case EXEC_PARALLEL: /* parallel */
ccc12f73 760 flag_explicitly_parallel = flag_xp_state;
343b2ab8 761 if (! parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
48401fcf 762 as_fatal (_("Instructions may not be executed in parallel"));
343b2ab8 763 else if (opcode1->op->unit == IU)
9b1168d6
MH
764 {
765 if (opcode2->op->unit == IU)
48401fcf
TT
766 as_fatal (_("Two IU instructions may not be executed in parallel"));
767 as_warn (_("Swapping instruction order"));
9b1168d6
MH
768 insn = FM00 | (insn2 << 32) | insn1;
769 }
770 else if (opcode2->op->unit == MU)
771 {
772 if (opcode1->op->unit == MU)
48401fcf
TT
773 as_fatal (_("Two MU instructions may not be executed in parallel"));
774 as_warn (_("Swapping instruction order"));
9b1168d6
MH
775 insn = FM00 | (insn2 << 32) | insn1;
776 }
777 else
778 {
779 insn = FM00 | (insn1 << 32) | insn2;
780 fx = fx->next;
781 }
ccc12f73 782 flag_explicitly_parallel = 0;
9b1168d6 783 break;
343b2ab8
MM
784
785 case EXEC_SEQ: /* sequential */
9b1168d6 786 if (opcode1->op->unit == IU)
48401fcf 787 as_fatal (_("IU instruction may not be in the left container"));
e21cafde
FCE
788 if (prev_left_kills_right_p)
789 as_warn (_("special left instruction `%s' kills instruction "
790 "`%s' in right container"),
791 opcode1->op->name, opcode2->op->name);
9b1168d6
MH
792 insn = FM01 | (insn1 << 32) | insn2;
793 fx = fx->next;
794 break;
343b2ab8
MM
795
796 case EXEC_REVSEQ: /* reverse sequential */
9b1168d6 797 if (opcode2->op->unit == MU)
48401fcf 798 as_fatal (_("MU instruction may not be in the right container"));
9b1168d6
MH
799 insn = FM10 | (insn1 << 32) | insn2;
800 fx = fx->next;
801 break;
343b2ab8 802
9b1168d6 803 default:
7a0f469b 804 as_fatal (_("unknown execution type passed to write_2_short()"));
9b1168d6
MH
805 }
806
807 /* printf("writing out %llx\n",insn); */
7a0f469b 808 f = frag_more (8);
9b1168d6
MH
809 d30v_number_to_chars (f, insn, 8);
810
343b2ab8
MM
811 /* If the previous instruction was a 32-bit multiply but it is put into a
812 parallel container, mark the current instruction as being a 32-bit
813 multiply. */
814 if (prev_mul32_p && exec_type == EXEC_PARALLEL)
815 cur_mul32_p = 1;
816
9b1168d6
MH
817 for (j=0; j<2; j++)
818 {
819 for (i=0; i < fx->fc; i++)
820 {
821 if (fx->fix[i].reloc)
822 {
823 where = (f - frag_now->fr_literal) + 4*j;
824
9b1168d6
MH
825 fix_new_exp (frag_now,
826 where,
827 fx->fix[i].size,
828 &(fx->fix[i].exp),
829 fx->fix[i].pcrel,
830 fx->fix[i].reloc);
831 }
832 }
833 fx->fc = 0;
834 fx = fx->next;
835 }
836 return (0);
837}
838
839
840/* Check 2 instructions and determine if they can be safely */
841/* executed in parallel. Returns 1 if they can be. */
842static int
843parallel_ok (op1, insn1, op2, insn2, exec_type)
844 struct d30v_insn *op1, *op2;
845 unsigned long insn1, insn2;
343b2ab8 846 exec_type_enum exec_type;
9b1168d6 847{
e0882f34
MM
848 int i, j, shift, regno, bits, ecc;
849 unsigned long flags, mask, flags_set1, flags_set2, flags_used1, flags_used2;
343b2ab8 850 unsigned long ins, mod_reg[2][3], used_reg[2][3], flag_reg[2];
1b524697
MH
851 struct d30v_format *f;
852 struct d30v_opcode *op;
853
854 /* section 4.3: both instructions must not be IU or MU only */
855 if ((op1->op->unit == IU && op2->op->unit == IU)
856 || (op1->op->unit == MU && op2->op->unit == MU))
9b1168d6
MH
857 return 0;
858
343b2ab8
MM
859 /* first instruction must not be a jump to safely optimize, unless this
860 is an explicit parallel operation. */
861 if (exec_type != EXEC_PARALLEL
862 && (op1->op->flags_used & (FLAG_JMP | FLAG_JSR)))
e0882f34
MM
863 return 0;
864
865 /* If one instruction is /TX or /XT and the other is /FX or /XF respectively,
866 then it is safe to allow the two to be done as parallel ops, since only
867 one will ever be executed at a time. */
868 if ((op1->ecc == ECC_TX && op2->ecc == ECC_FX)
869 || (op1->ecc == ECC_FX && op2->ecc == ECC_TX)
870 || (op1->ecc == ECC_XT && op2->ecc == ECC_XF)
871 || (op1->ecc == ECC_XF && op2->ecc == ECC_XT))
872 return 1;
873
874 /* [0] r0-r31
875 [1] r32-r63
876 [2] a0, a1, flag registers */
9b1168d6 877
1b524697 878 for (j = 0; j < 2; j++)
9b1168d6
MH
879 {
880 if (j == 0)
881 {
1b524697
MH
882 f = op1->form;
883 op = op1->op;
e0882f34 884 ecc = op1->ecc;
9b1168d6
MH
885 ins = insn1;
886 }
887 else
888 {
1b524697
MH
889 f = op2->form;
890 op = op2->op;
e0882f34 891 ecc = op2->ecc;
9b1168d6
MH
892 ins = insn2;
893 }
343b2ab8 894 flag_reg[j] = 0;
1b524697 895 mod_reg[j][0] = mod_reg[j][1] = 0;
e0882f34 896 mod_reg[j][2] = (op->flags_set & FLAG_ALL);
1b524697 897 used_reg[j][0] = used_reg[j][1] = 0;
e0882f34
MM
898 used_reg[j][2] = (op->flags_used & FLAG_ALL);
899
900 /* BSR/JSR always sets R62 */
901 if (op->flags_used & FLAG_JSR)
902 mod_reg[j][1] = (1L << (62-32));
903
904 /* conditional execution affects the flags_used */
905 switch (ecc)
906 {
907 case ECC_TX:
908 case ECC_FX:
343b2ab8 909 used_reg[j][2] |= flag_reg[j] = FLAG_0;
e0882f34
MM
910 break;
911
912 case ECC_XT:
913 case ECC_XF:
343b2ab8 914 used_reg[j][2] |= flag_reg[j] = FLAG_1;
e0882f34
MM
915 break;
916
917 case ECC_TT:
918 case ECC_TF:
343b2ab8 919 used_reg[j][2] |= flag_reg[j] = (FLAG_0 | FLAG_1);
e0882f34
MM
920 break;
921 }
922
1b524697 923 for (i = 0; f->operands[i]; i++)
9b1168d6 924 {
1b524697
MH
925 flags = d30v_operand_table[f->operands[i]].flags;
926 shift = 12 - d30v_operand_table[f->operands[i]].position;
927 bits = d30v_operand_table[f->operands[i]].bits;
928 if (bits == 32)
929 mask = 0xffffffff;
930 else
931 mask = 0x7FFFFFFF >> (31 - bits);
e0882f34
MM
932
933 if ((flags & OPERAND_PLUS) || (flags & OPERAND_MINUS))
934 {
935 /* this is a post-increment or post-decrement */
936 /* the previous register needs to be marked as modified */
937
938 shift = 12 - d30v_operand_table[f->operands[i-1]].position;
939 regno = (ins >> shift) & 0x3f;
940 if (regno >= 32)
941 mod_reg[j][1] |= 1L << (regno - 32);
942 else
943 mod_reg[j][0] |= 1L << regno;
944 }
945 else if (flags & OPERAND_REG)
9b1168d6
MH
946 {
947 regno = (ins >> shift) & mask;
e0882f34
MM
948 /* the memory write functions don't have a destination register */
949 if ((flags & OPERAND_DEST) && !(op->flags_set & FLAG_MEM))
9b1168d6 950 {
e0882f34 951 /* MODIFIED registers and flags */
1b524697 952 if (flags & OPERAND_ACC)
e0882f34
MM
953 {
954 if (regno == 0)
955 mod_reg[j][2] |= FLAG_A0;
956 else if (regno == 1)
957 mod_reg[j][2] |= FLAG_A1;
958 else
959 abort ();
960 }
1b524697 961 else if (flags & OPERAND_FLAG)
e0882f34 962 mod_reg[j][2] |= 1L << regno;
1b524697
MH
963 else if (!(flags & OPERAND_CONTROL))
964 {
e0882f34
MM
965 int r, z;
966
967 /* need to check if there are two destination */
968 /* registers, for example ld2w */
969 if (flags & OPERAND_2REG)
970 z = 1;
1b524697 971 else
e0882f34
MM
972 z = 0;
973
974 for (r = regno; r <= regno + z; r++)
975 {
976 if (r >= 32)
977 mod_reg[j][1] |= 1L << (r - 32);
978 else
979 mod_reg[j][0] |= 1L << r;
980 }
1b524697 981 }
9b1168d6
MH
982 }
983 else
984 {
e0882f34 985 /* USED, but not modified registers and flags */
1b524697 986 if (flags & OPERAND_ACC)
e0882f34
MM
987 {
988 if (regno == 0)
989 used_reg[j][2] |= FLAG_A0;
990 else if (regno == 1)
991 used_reg[j][2] |= FLAG_A1;
992 else
993 abort ();
994 }
1b524697 995 else if (flags & OPERAND_FLAG)
e0882f34 996 used_reg[j][2] |= 1L << regno;
1b524697
MH
997 else if (!(flags & OPERAND_CONTROL))
998 {
e0882f34
MM
999 int r, z;
1000
1001 /* need to check if there are two source */
1002 /* registers, for example st2w */
1003 if (flags & OPERAND_2REG)
1004 z = 1;
1b524697 1005 else
e0882f34
MM
1006 z = 0;
1007
1008 for (r = regno; r <= regno + z; r++)
1009 {
1010 if (r >= 32)
1011 used_reg[j][1] |= 1L << (r - 32);
1012 else
1013 used_reg[j][0] |= 1L << r;
1014 }
1b524697 1015 }
9b1168d6
MH
1016 }
1017 }
1018 }
9b1168d6 1019 }
1b524697 1020
e0882f34
MM
1021 flags_set1 = op1->op->flags_set;
1022 flags_set2 = op2->op->flags_set;
1023 flags_used1 = op1->op->flags_used;
1024 flags_used2 = op2->op->flags_used;
1025
1026 /* ST2W/ST4HB combined with ADDppp/SUBppp is illegal. */
1027 if (((flags_set1 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD)
1028 && (flags_used2 & FLAG_ADDSUBppp) != 0)
1029 || ((flags_set2 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD)
1030 && (flags_used1 & FLAG_ADDSUBppp) != 0))
1031 return 0;
1032
1033 /* Load instruction combined with half-word multiply is illegal. */
1034 if (((flags_used1 & FLAG_MEM) != 0 && (flags_used2 & FLAG_MUL16))
1035 || ((flags_used2 & FLAG_MEM) != 0 && (flags_used1 & FLAG_MUL16)))
1036 return 0;
1037
1038 /* Specifically allow add || add by removing carry, overflow bits dependency.
1039 This is safe, even if an addc follows since the IU takes the argument in
1040 the right container, and it writes its results last.
1041 However, don't paralellize add followed by addc or sub followed by
1042 subb. */
1043
1044 if (mod_reg[0][2] == FLAG_CVVA && mod_reg[1][2] == FLAG_CVVA
343b2ab8
MM
1045 && (used_reg[0][2] & ~flag_reg[0]) == 0
1046 && (used_reg[1][2] & ~flag_reg[1]) == 0
e0882f34
MM
1047 && op1->op->unit == EITHER && op2->op->unit == EITHER)
1048 {
1049 mod_reg[0][2] = mod_reg[1][2] = 0;
1050 }
1051
7a0f469b 1052 for (j = 0; j < 3; j++)
e0882f34
MM
1053 {
1054 /* If the second instruction depends on the first, we obviously
1055 cannot parallelize. Note, the mod flag implies use, so
1056 check that as well. */
ccc12f73
FF
1057 /* If flag_explicitly_parallel is set, then the case of the
1058 second instruction using a register the first instruction
1059 modifies is assumed to be okay; we trust the human. We
1060 don't trust the human if both instructions modify the same
1061 register but we do trust the human if they modify the same
1062 flags. */
1063 if (flag_explicitly_parallel)
1064 {
1065 if ((j < 2) && (mod_reg[0][j] & mod_reg[1][j]) != 0)
1066 return 0;
1067 }
1068 else
1069 if ((mod_reg[0][j] & (mod_reg[1][j] | used_reg[1][j])) != 0)
1070 return 0;
e0882f34
MM
1071 }
1072
1b524697 1073 return 1;
9b1168d6
MH
1074}
1075
1076
1077
1078/* This is the main entry point for the machine-dependent assembler. str points to a
1079 machine-dependent instruction. This function is supposed to emit the frags/bytes
1080 it assembles to. For the D30V, it mostly handles the special VLIW parsing and packing
343b2ab8 1081 and leaves the difficult stuff to do_assemble(). */
9b1168d6
MH
1082
1083static long long prev_insn = -1;
1084static struct d30v_insn prev_opcode;
1085static subsegT prev_subseg;
1086static segT prev_seg = 0;
1087
1088void
1089md_assemble (str)
1090 char *str;
1091{
1092 struct d30v_insn opcode;
1093 long long insn;
343b2ab8
MM
1094 exec_type_enum extype = EXEC_UNKNOWN; /* execution type; parallel, etc */
1095 static exec_type_enum etype = EXEC_UNKNOWN; /* saved extype. used for multiline instructions */
9b1168d6
MH
1096 char *str2;
1097
7d515759
RH
1098 if ((prev_insn != -1) && prev_seg
1099 && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
7a0f469b 1100 d30v_cleanup ();
e0882f34 1101
7d515759
RH
1102 if (d30v_current_align < 3)
1103 d30v_align (3, NULL, d30v_last_label);
1104 else if (d30v_current_align > 3)
1105 d30v_current_align = 3;
1106 d30v_last_label = NULL;
1107
ccc12f73
FF
1108 flag_explicitly_parallel = 0;
1109 flag_xp_state = 0;
343b2ab8 1110 if (etype == EXEC_UNKNOWN)
9b1168d6
MH
1111 {
1112 /* look for the special multiple instruction separators */
1113 str2 = strstr (str, "||");
1114 if (str2)
ccc12f73
FF
1115 {
1116 extype = EXEC_PARALLEL;
1117 flag_xp_state = 1;
1118 }
9b1168d6
MH
1119 else
1120 {
1121 str2 = strstr (str, "->");
1122 if (str2)
343b2ab8 1123 extype = EXEC_SEQ;
9b1168d6
MH
1124 else
1125 {
1126 str2 = strstr (str, "<-");
1127 if (str2)
343b2ab8 1128 extype = EXEC_REVSEQ;
9b1168d6
MH
1129 }
1130 }
1131 /* str2 points to the separator, if one */
1132 if (str2)
1133 {
1134 *str2 = 0;
1135
1136 /* if two instructions are present and we already have one saved
1137 then first write it out */
7a0f469b 1138 d30v_cleanup ();
9b1168d6
MH
1139
1140 /* assemble first instruction and save it */
7a0f469b 1141 prev_insn = do_assemble (str, &prev_opcode, 1, 0);
9b1168d6 1142 if (prev_insn == -1)
7d515759 1143 as_fatal (_("Cannot assemble instruction"));
e0882f34 1144 if (prev_opcode.form->form >= LONG)
48401fcf 1145 as_fatal (_("First opcode is long. Unable to mix instructions as specified."));
9b1168d6
MH
1146 fixups = fixups->next;
1147 str = str2 + 2;
bc67c823
NC
1148 prev_seg = now_seg;
1149 prev_subseg = now_subseg;
9b1168d6
MH
1150 }
1151 }
1152
daaef8f8 1153 insn = do_assemble (str, &opcode,
7a0f469b
NC
1154 (extype != EXEC_UNKNOWN || etype != EXEC_UNKNOWN),
1155 extype == EXEC_PARALLEL);
9b1168d6
MH
1156 if (insn == -1)
1157 {
daaef8f8 1158 if (extype != EXEC_UNKNOWN)
9b1168d6
MH
1159 {
1160 etype = extype;
1161 return;
1162 }
7d515759 1163 as_fatal (_("Cannot assemble instruction"));
9b1168d6
MH
1164 }
1165
daaef8f8 1166 if (etype != EXEC_UNKNOWN)
9b1168d6
MH
1167 {
1168 extype = etype;
daaef8f8 1169 etype = EXEC_UNKNOWN;
9b1168d6
MH
1170 }
1171
343b2ab8
MM
1172 /* Word multiply instructions must not be followed by either a load or a
1173 16-bit multiply instruction in the next cycle. */
7a0f469b
NC
1174 if ( (extype != EXEC_REVSEQ)
1175 && prev_mul32_p
1176 && (opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16)))
343b2ab8
MM
1177 {
1178 /* However, load and multiply should able to be combined in a parallel
1179 operation, so check for that first. */
343b2ab8
MM
1180 if (prev_insn != -1
1181 && (opcode.op->flags_used & FLAG_MEM)
1182 && opcode.form->form < LONG
1183 && (extype == EXEC_PARALLEL || (Optimizing && extype == EXEC_UNKNOWN))
1184 && parallel_ok (&prev_opcode, (long)prev_insn,
1185 &opcode, (long)insn, extype)
1186 && write_2_short (&prev_opcode, (long)prev_insn,
1187 &opcode, (long)insn, extype, fixups) == 0)
1188 {
1189 /* no instructions saved */
1190 prev_insn = -1;
1191 return;
1192 }
343b2ab8
MM
1193 else
1194 {
7a0f469b
NC
1195 /* Can't parallelize, flush previous instruction and emit a word of NOPS,
1196 unless the previous instruction is a NOP, in whcih case just flush it,
1197 as this will generate a word of NOPs for us. */
343b2ab8 1198
7a0f469b
NC
1199 if (prev_insn != -1 && (strcmp (prev_opcode.op->name, "nop") == 0))
1200 {
1201 d30v_cleanup ();
1202 }
1203 else
1204 {
1205 char * f;
1206
1207 d30v_cleanup ();
1208
1209 f = frag_more (8);
1210 d30v_number_to_chars (f, NOP2, 8);
1211 if (warn_nops == NOP_ALL || warn_nops == NOP_MULTIPLY)
1212 {
1213 if (opcode.op->flags_used & FLAG_MEM)
1214 as_warn (_("word of NOPs added between word multiply and load"));
1215 else
1216 as_warn (_("word of NOPs added between word multiply and 16-bit multiply"));
1217 }
1218 }
1219 extype = EXEC_UNKNOWN;
1220 }
1221 }
1222 else if ( (extype == EXEC_REVSEQ)
1223 && cur_mul32_p
1224 && (prev_opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16)))
1225 {
1226 /* Can't parallelize, flush current instruction and emit a word of NOPS */
1227 write_1_short (& opcode, (long) insn, fixups->next->next);
1228
1229 if (strcmp (opcode.op->name, "nop") != 0)
1230 {
1231 char * f;
1232
1233 f = frag_more (8);
343b2ab8
MM
1234 d30v_number_to_chars (f, NOP2, 8);
1235 if (warn_nops == NOP_ALL || warn_nops == NOP_MULTIPLY)
48401fcf 1236 {
7d515759 1237 if (opcode.op->flags_used & FLAG_MEM)
48401fcf
TT
1238 as_warn (_("word of NOPs added between word multiply and load"));
1239 else
1240 as_warn (_("word of NOPs added between word multiply and 16-bit multiply"));
1241 }
343b2ab8 1242 }
7a0f469b
NC
1243
1244 /* Make the previous instruction the current one. */
1245 extype = EXEC_UNKNOWN;
1246 insn = prev_insn;
1247 now_seg = prev_seg;
1248 now_subseg = prev_subseg;
1249 prev_insn = -1;
1250 cur_mul32_p = prev_mul32_p;
1251 prev_mul32_p = 0;
343b2ab8
MM
1252 }
1253
7a0f469b 1254 /* If this is a long instruction, write it and any previous short instruction. */
9b1168d6
MH
1255 if (opcode.form->form >= LONG)
1256 {
7a0f469b
NC
1257 if (extype != EXEC_UNKNOWN)
1258 as_fatal (_("Unable to mix instructions as specified"));
1259 d30v_cleanup ();
9b1168d6
MH
1260 write_long (&opcode, insn, fixups);
1261 prev_insn = -1;
9b1168d6 1262 }
7a0f469b 1263 else if ((prev_insn != -1) &&
343b2ab8 1264 (write_2_short (&prev_opcode, (long)prev_insn, &opcode, (long)insn, extype, fixups) == 0))
9b1168d6 1265 {
7a0f469b 1266 /* No instructions saved. */
9b1168d6
MH
1267 prev_insn = -1;
1268 }
1269 else
1270 {
7a0f469b
NC
1271 if (extype != EXEC_UNKNOWN)
1272 as_fatal (_("Unable to mix instructions as specified"));
1273
1274 /* Save off last instruction so it may be packed on next pass. */
1275 memcpy (&prev_opcode, &opcode, sizeof (prev_opcode));
9b1168d6
MH
1276 prev_insn = insn;
1277 prev_seg = now_seg;
1278 prev_subseg = now_subseg;
1279 fixups = fixups->next;
1280 }
1281}
1282
1283
1284/* do_assemble assembles a single instruction and returns an opcode */
1285/* it returns -1 (an invalid opcode) on error */
1286
1287static long long
7a0f469b 1288do_assemble (str, opcode, shortp, is_parallel)
9b1168d6
MH
1289 char *str;
1290 struct d30v_insn *opcode;
daaef8f8 1291 int shortp;
7a0f469b 1292 int is_parallel;
9b1168d6
MH
1293{
1294 unsigned char *op_start, *save;
1295 unsigned char *op_end;
1296 char name[20];
daaef8f8 1297 int cmp_hack, nlen = 0, fsize = (shortp ? FORCE_SHORT : 0);
9b1168d6
MH
1298 expressionS myops[6];
1299 long long insn;
1300
9b1168d6
MH
1301 /* Drop leading whitespace */
1302 while (*str == ' ')
1303 str++;
1304
1305 /* find the opcode end */
1306 for (op_start = op_end = (unsigned char *) (str);
1307 *op_end
1308 && nlen < 20
1309 && *op_end != '/'
1310 && !is_end_of_line[*op_end] && *op_end != ' ';
1311 op_end++)
1312 {
7a0f469b 1313 name[nlen] = tolower (op_start[nlen]);
9b1168d6
MH
1314 nlen++;
1315 }
1316
1317 if (nlen == 0)
1318 return (-1);
1319
1320 name[nlen] = 0;
1321
1322 /* if there is an execution condition code, handle it */
1323 if (*op_end == '/')
1324 {
1325 int i = 0;
7a0f469b 1326 while ( (i < ECC_MAX) && strncasecmp (d30v_ecc_names[i],op_end+1,2))
9b1168d6
MH
1327 i++;
1328
1329 if (i == ECC_MAX)
1330 {
1331 char tmp[4];
7a0f469b 1332 strncpy (tmp,op_end+1,2);
9b1168d6 1333 tmp[2] = 0;
48401fcf 1334 as_fatal (_("unknown condition code: %s"),tmp);
9b1168d6
MH
1335 return -1;
1336 }
1337 /* printf("condition code=%d\n",i); */
1338 opcode->ecc = i;
1339 op_end += 3;
1340 }
1341 else
1342 opcode->ecc = ECC_AL;
1343
1344
1345 /* CMP and CMPU change their name based on condition codes */
7a0f469b 1346 if (!strncmp (name,"cmp",3))
9b1168d6
MH
1347 {
1348 int p,i;
1349 char **str = (char **)d30v_cc_names;
1350 if (name[3] == 'u')
1351 p = 4;
1352 else
1353 p = 3;
1354
7a0f469b 1355 for (i=1; *str && strncmp (*str,&name[p],2); i++, str++)
9b1168d6
MH
1356 ;
1357
e0882f34
MM
1358 /* cmpu only supports some condition codes */
1359 if (p == 4)
1360 {
1361 if (i < 3 || i > 6)
1362 {
1363 name[p+2]=0;
7d515759 1364 as_fatal (_("cmpu doesn't support condition code %s"),&name[p]);
e0882f34
MM
1365 }
1366 }
1367
9b1168d6
MH
1368 if (!*str)
1369 {
1370 name[p+2]=0;
48401fcf 1371 as_fatal (_("unknown condition code: %s"),&name[p]);
9b1168d6
MH
1372 }
1373
1374 cmp_hack = i;
1375 name[p] = 0;
1376 }
1377 else
1378 cmp_hack = 0;
1379
1380 /* printf("cmp_hack=%d\n",cmp_hack); */
1381
e0882f34
MM
1382 /* need to look for .s or .l */
1383 if (name[nlen-2] == '.')
1384 {
1385 switch (name[nlen-1])
1386 {
1387 case 's':
1388 fsize = FORCE_SHORT;
1389 break;
1390 case 'l':
1391 fsize = FORCE_LONG;
ccc12f73 1392 break;
e0882f34
MM
1393 }
1394 name[nlen-2] = 0;
1395 }
1396
9b1168d6
MH
1397 /* find the first opcode with the proper name */
1398 opcode->op = (struct d30v_opcode *)hash_find (d30v_hash, name);
1399 if (opcode->op == NULL)
7a0f469b 1400 as_fatal (_("unknown opcode: %s"),name);
9b1168d6
MH
1401
1402 save = input_line_pointer;
1403 input_line_pointer = op_end;
e0882f34 1404 while (!(opcode->form = find_format (opcode->op, myops, fsize, cmp_hack)))
9b1168d6
MH
1405 {
1406 opcode->op++;
7a0f469b 1407 if (strcmp (opcode->op->name,name))
7d515759 1408 as_fatal (_("operands for opcode `%s' do not match any valid format"), name);
9b1168d6
MH
1409 }
1410 input_line_pointer = save;
1411
1412 insn = build_insn (opcode, myops);
343b2ab8
MM
1413
1414 /* Propigate multiply status */
1415 if (insn != -1)
1416 {
7a0f469b
NC
1417 if (is_parallel && prev_mul32_p)
1418 cur_mul32_p = 1;
1419 else
1420 {
1421 prev_mul32_p = cur_mul32_p;
1422 cur_mul32_p = (opcode->op->flags_used & FLAG_MUL32) != 0;
1423 }
343b2ab8
MM
1424 }
1425
e21cafde
FCE
1426 /* Propagate left_kills_right status */
1427 if (insn != -1)
1428 {
1429 prev_left_kills_right_p = cur_left_kills_right_p;
1430
1431 if (opcode->op->flags_set & FLAG_LKR)
1432 {
1433 cur_left_kills_right_p = 1;
1434
1435 if (strcmp (opcode->op->name, "mvtsys") == 0)
1436 {
1437 /* Left kills right for only mvtsys only for PSW/PSWH/PSWL/flags target. */
1438 if ((myops[0].X_op == O_register) &&
1439 ((myops[0].X_add_number == OPERAND_CONTROL) || /* psw */
1440 (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+2) || /* pswh */
1441 (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+1) || /* pswl */
1442 (myops[0].X_add_number == OPERAND_FLAG+0) || /* f0 */
1443 (myops[0].X_add_number == OPERAND_FLAG+1) || /* f1 */
1444 (myops[0].X_add_number == OPERAND_FLAG+2) || /* f2 */
1445 (myops[0].X_add_number == OPERAND_FLAG+3) || /* f3 */
1446 (myops[0].X_add_number == OPERAND_FLAG+4) || /* f4 */
1447 (myops[0].X_add_number == OPERAND_FLAG+5) || /* f5 */
1448 (myops[0].X_add_number == OPERAND_FLAG+6) || /* f6 */
1449 (myops[0].X_add_number == OPERAND_FLAG+7))) /* f7 */
1450 {
1451 cur_left_kills_right_p = 1;
1452 }
1453 else
1454 {
1455 /* Other mvtsys target registers don't kill right instruction. */
1456 cur_left_kills_right_p = 0;
1457 }
1458 } /* mvtsys */
1459 }
1460 else
1461 cur_left_kills_right_p = 0;
1462 }
1463
1464
9b1168d6
MH
1465 return (insn);
1466}
1467
1468
7d515759
RH
1469/* find_format() gets a pointer to an entry in the format table.
1470 It must look at all formats for an opcode and use the operands
1471 to choose the correct one. Returns NULL on error. */
9b1168d6
MH
1472
1473static struct d30v_format *
e0882f34 1474find_format (opcode, myops, fsize, cmp_hack)
9b1168d6
MH
1475 struct d30v_opcode *opcode;
1476 expressionS myops[];
e0882f34 1477 int fsize;
9b1168d6
MH
1478 int cmp_hack;
1479{
1480 int numops, match, index, i=0, j, k;
1481 struct d30v_format *fm;
9b1168d6 1482
7d515759 1483 /* Get all the operands and save them as expressions. */
9b1168d6
MH
1484 numops = get_operands (myops, cmp_hack);
1485
343b2ab8 1486 while ((index = opcode->format[i++]) != 0)
9b1168d6 1487 {
7d515759 1488 if (fsize == FORCE_SHORT && index >= LONG)
e0882f34
MM
1489 continue;
1490
7d515759 1491 if (fsize == FORCE_LONG && index < LONG)
e0882f34
MM
1492 continue;
1493
9b1168d6
MH
1494 fm = (struct d30v_format *)&d30v_format_table[index];
1495 k = index;
1496 while (fm->form == index)
1497 {
1498 match = 1;
7d515759 1499 /* Now check the operands for compatibility. */
9b1168d6
MH
1500 for (j = 0; match && fm->operands[j]; j++)
1501 {
1502 int flags = d30v_operand_table[fm->operands[j]].flags;
7d515759 1503 int bits = d30v_operand_table[fm->operands[j]].bits;
9b1168d6
MH
1504 int X_op = myops[j].X_op;
1505 int num = myops[j].X_add_number;
1506
7d515759 1507 if (flags & OPERAND_SPECIAL)
9b1168d6 1508 break;
7d515759 1509 else if (X_op == O_illegal)
9b1168d6
MH
1510 match = 0;
1511 else if (flags & OPERAND_REG)
1512 {
7d515759 1513 if (X_op != O_register
343b2ab8
MM
1514 || ((flags & OPERAND_ACC) && !(num & OPERAND_ACC))
1515 || ((flags & OPERAND_FLAG) && !(num & OPERAND_FLAG))
1516 || ((flags & OPERAND_CONTROL)
1517 && !(num & (OPERAND_CONTROL | OPERAND_FLAG))))
9b1168d6
MH
1518 {
1519 match = 0;
9b1168d6
MH
1520 }
1521 }
7d515759
RH
1522 else if (((flags & OPERAND_MINUS)
1523 && (X_op != O_absent || num != OPERAND_MINUS))
1524 || ((flags & OPERAND_PLUS)
1525 && (X_op != O_absent || num != OPERAND_PLUS))
1526 || ((flags & OPERAND_ATMINUS)
1527 && (X_op != O_absent || num != OPERAND_ATMINUS))
1528 || ((flags & OPERAND_ATPAR)
1529 && (X_op != O_absent || num != OPERAND_ATPAR))
1530 || ((flags & OPERAND_ATSIGN)
1531 && (X_op != O_absent || num != OPERAND_ATSIGN)))
1532 {
1533 match=0;
1534 }
1535 else if (flags & OPERAND_NUM)
1536 {
1537 /* A number can be a constant or symbol expression. */
1538
1539 /* Turn an expression into a symbol for later resolution. */
1540 if (X_op != O_absent && X_op != O_constant
1541 && X_op != O_symbol && X_op != O_register
1542 && X_op != O_big)
1543 {
1544 symbolS *sym = make_expr_symbol (&myops[j]);
1545 myops[j].X_op = X_op = O_symbol;
1546 myops[j].X_add_symbol = sym;
1547 myops[j].X_add_number = num = 0;
1548 }
1549
1550 if (fm->form >= LONG)
1551 {
1552 /* If we're testing for a LONG format, either fits. */
1553 if (X_op != O_constant && X_op != O_symbol)
1554 match = 0;
1555 }
1556 else if (fm->form < LONG
1557 && ((fsize == FORCE_SHORT && X_op == O_symbol)
1558 || (fm->form == SHORT_D2 && j == 0)))
1559 match = 1;
1560 /* This is the tricky part. Will the constant or symbol
1561 fit into the space in the current format? */
1562 else if (X_op == O_constant)
1563 {
1564 if (check_range (num, bits, flags))
1565 match = 0;
1566 }
1567 else if (X_op == O_symbol
7a0f469b
NC
1568 && S_IS_DEFINED (myops[j].X_add_symbol)
1569 && S_GET_SEGMENT (myops[j].X_add_symbol) == now_seg
7d515759
RH
1570 && opcode->reloc_flag == RELOC_PCREL)
1571 {
1572 /* If the symbol is defined, see if the value will fit
1573 into the form we're considering. */
1574 fragS *f;
1575 long value;
1576
1577 /* Calculate the current address by running through the
1578 previous frags and adding our current offset. */
1579 value = 0;
1580 for (f = frchain_now->frch_root; f; f = f->fr_next)
1581 value += f->fr_fix + f->fr_offset;
7a0f469b
NC
1582 value = (S_GET_VALUE (myops[j].X_add_symbol) - value
1583 - (obstack_next_free (&frchain_now->frch_obstack)
7d515759
RH
1584 - frag_now->fr_literal));
1585 if (check_range (value, bits, flags))
1586 match = 0;
1587 }
1588 else
1589 match = 0;
1590 }
9b1168d6
MH
1591 }
1592 /* printf("through the loop: match=%d\n",match); */
7d515759
RH
1593 /* We're only done if the operands matched so far AND there
1594 are no more to check. */
1595 if (match && myops[j].X_op == 0)
9b1168d6 1596 return fm;
9b1168d6
MH
1597 fm = (struct d30v_format *)&d30v_format_table[++k];
1598 }
1599 /* printf("trying another format: i=%d\n",i); */
1600 }
1601 return NULL;
1602}
1603
1604/* if while processing a fixup, a reloc really needs to be created */
1605/* then it is done here */
1606
1607arelent *
1608tc_gen_reloc (seg, fixp)
1609 asection *seg;
1610 fixS *fixp;
1611{
1612 arelent *reloc;
2c268a85 1613 reloc = (arelent *) xmalloc (sizeof (arelent));
9b1168d6
MH
1614 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1615 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1616 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
9b1168d6
MH
1617 if (reloc->howto == (reloc_howto_type *) NULL)
1618 {
1619 as_bad_where (fixp->fx_file, fixp->fx_line,
48401fcf 1620 _("reloc %d not supported by object file format"), (int)fixp->fx_r_type);
9b1168d6
MH
1621 return NULL;
1622 }
1623 reloc->addend = fixp->fx_addnumber;
1624 return reloc;
1625}
1626
1627int
1628md_estimate_size_before_relax (fragp, seg)
1629 fragS *fragp;
1630 asection *seg;
1631{
1632 abort ();
1633 return 0;
1634}
1635
1636long
1637md_pcrel_from_section (fixp, sec)
1638 fixS *fixp;
1639 segT sec;
1640{
e0882f34
MM
1641 if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) ||
1642 (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
9b1168d6
MH
1643 return 0;
1644 return fixp->fx_frag->fr_address + fixp->fx_where;
1645}
1646
1647int
1648md_apply_fix3 (fixp, valuep, seg)
1649 fixS *fixp;
1650 valueT *valuep;
1651 segT seg;
1652{
1653 char *where;
1654 unsigned long insn, insn2;
1655 long value;
9b1168d6
MH
1656
1657 if (fixp->fx_addsy == (symbolS *) NULL)
1658 {
1659 value = *valuep;
1660 fixp->fx_done = 1;
1661 }
9b1168d6
MH
1662 else if (fixp->fx_pcrel)
1663 {
1664 value = *valuep;
e0882f34 1665 }
1b524697 1666 else
9b1168d6
MH
1667 {
1668 value = fixp->fx_offset;
9b1168d6
MH
1669 if (fixp->fx_subsy != (symbolS *) NULL)
1670 {
e0882f34 1671 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
9b1168d6
MH
1672 value -= S_GET_VALUE (fixp->fx_subsy);
1673 else
1674 {
1675 /* We don't actually support subtracting a symbol. */
1b524697 1676 as_bad_where (fixp->fx_file, fixp->fx_line,
48401fcf 1677 _("expression too complex"));
9b1168d6
MH
1678 }
1679 }
1680 }
1681
1682 /* Fetch the instruction, insert the fully resolved operand
1683 value, and stuff the instruction back again. */
1684 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1685 insn = bfd_getb32 ((unsigned char *) where);
1b524697 1686
9b1168d6
MH
1687 switch (fixp->fx_r_type)
1688 {
d32f7037
NC
1689 case BFD_RELOC_8:
1690 /* Caused by a bad .byte directive. */
1691 as_fatal (_("line %d: unable to place address of symbol '%s' into a byte"),
1692 fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
1693 break;
1694
1695 case BFD_RELOC_16:
1696 /* Caused by a bad .short directive. */
1697 as_fatal (_("line %d: unable to place address of symbol '%s' into a short"),
1698 fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
1699 break;
1700
1701 case BFD_RELOC_64:
1702 /* Caused by a bad .quad directive. */
1703 as_fatal (_("line %d: unable to place address of symbol '%s' into a .quad"),
1704 fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
1705 break;
1706
9b1168d6 1707 case BFD_RELOC_D30V_6:
e0882f34 1708 check_size (value, 6, fixp->fx_file, fixp->fx_line);
9b1168d6
MH
1709 insn |= value & 0x3F;
1710 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1711 break;
343b2ab8 1712
e0882f34
MM
1713 case BFD_RELOC_D30V_9_PCREL:
1714 if (fixp->fx_where & 0x7)
1715 {
1716 if (fixp->fx_done)
1717 value += 4;
1718 else
1719 fixp->fx_r_type = BFD_RELOC_D30V_9_PCREL_R;
1720 }
1721 check_size (value, 9, fixp->fx_file, fixp->fx_line);
1722 insn |= ((value >> 3) & 0x3F) << 12;
1723 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1724 break;
343b2ab8 1725
9b1168d6 1726 case BFD_RELOC_D30V_15:
e0882f34 1727 check_size (value, 15, fixp->fx_file, fixp->fx_line);
9b1168d6
MH
1728 insn |= (value >> 3) & 0xFFF;
1729 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1730 break;
343b2ab8 1731
9b1168d6 1732 case BFD_RELOC_D30V_15_PCREL:
e0882f34
MM
1733 if (fixp->fx_where & 0x7)
1734 {
1735 if (fixp->fx_done)
1736 value += 4;
1737 else
1738 fixp->fx_r_type = BFD_RELOC_D30V_15_PCREL_R;
1739 }
1740 check_size (value, 15, fixp->fx_file, fixp->fx_line);
9b1168d6
MH
1741 insn |= (value >> 3) & 0xFFF;
1742 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1743 break;
343b2ab8 1744
9b1168d6 1745 case BFD_RELOC_D30V_21:
e0882f34 1746 check_size (value, 21, fixp->fx_file, fixp->fx_line);
9b1168d6
MH
1747 insn |= (value >> 3) & 0x3FFFF;
1748 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1749 break;
343b2ab8 1750
9b1168d6 1751 case BFD_RELOC_D30V_21_PCREL:
e0882f34
MM
1752 if (fixp->fx_where & 0x7)
1753 {
1754 if (fixp->fx_done)
1755 value += 4;
1756 else
1757 fixp->fx_r_type = BFD_RELOC_D30V_21_PCREL_R;
1758 }
1759 check_size (value, 21, fixp->fx_file, fixp->fx_line);
9b1168d6
MH
1760 insn |= (value >> 3) & 0x3FFFF;
1761 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1762 break;
343b2ab8 1763
9b1168d6
MH
1764 case BFD_RELOC_D30V_32:
1765 insn2 = bfd_getb32 ((unsigned char *) where + 4);
343b2ab8
MM
1766 insn |= (value >> 26) & 0x3F; /* top 6 bits */
1767 insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */
9b1168d6
MH
1768 insn2 |= value & 0x0003FFFF; /* bottom 18 bits */
1769 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1770 bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
1771 break;
343b2ab8 1772
9b1168d6 1773 case BFD_RELOC_D30V_32_PCREL:
9b1168d6 1774 insn2 = bfd_getb32 ((unsigned char *) where + 4);
343b2ab8
MM
1775 insn |= (value >> 26) & 0x3F; /* top 6 bits */
1776 insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */
9b1168d6
MH
1777 insn2 |= value & 0x0003FFFF; /* bottom 18 bits */
1778 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1779 bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
1780 break;
343b2ab8 1781
9b1168d6 1782 case BFD_RELOC_32:
9b1168d6
MH
1783 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
1784 break;
343b2ab8 1785
9b1168d6 1786 default:
48401fcf 1787 as_fatal (_("line %d: unknown relocation type: 0x%x"),fixp->fx_line,fixp->fx_r_type);
9b1168d6 1788 }
9b1168d6
MH
1789 return 0;
1790}
1791
1792
1793/* d30v_cleanup() is called after the assembler has finished parsing the input
1794 file or after a label is defined. Because the D30V assembler sometimes saves short
1795 instructions to see if it can package them with the next instruction, there may
1796 be a short instruction that still needs written. */
1797int
1798d30v_cleanup ()
1799{
1800 segT seg;
1801 subsegT subseg;
1802
1803 if (prev_insn != -1)
1804 {
1805 seg = now_seg;
1806 subseg = now_subseg;
1807 subseg_set (prev_seg, prev_subseg);
1808 write_1_short (&prev_opcode, (long)prev_insn, fixups->next);
1809 subseg_set (seg, subseg);
1810 prev_insn = -1;
1811 }
1812 return 1;
1813}
1814
9b1168d6
MH
1815static void
1816d30v_number_to_chars (buf, value, n)
1817 char *buf; /* Return 'nbytes' of chars here. */
1818 long long value; /* The value of the bits. */
1819 int n; /* Number of bytes in the output. */
1820{
1821 while (n--)
1822 {
1823 buf[n] = value & 0xff;
1824 value >>= 8;
1825 }
1826}
e0882f34
MM
1827
1828
1829/* This function is called at the start of every line. */
1830/* it checks to see if the first character is a '.' */
1831/* which indicates the start of a pseudo-op. If it is, */
1832/* then write out any unwritten instructions */
1833
1834void
7a0f469b 1835d30v_start_line ()
e0882f34
MM
1836{
1837 char *c = input_line_pointer;
1838
7a0f469b 1839 while (isspace (*c))
e0882f34
MM
1840 c++;
1841
7a0f469b
NC
1842 if (*c == '.')
1843 d30v_cleanup ();
e0882f34
MM
1844}
1845
1846static void
1847check_size (value, bits, file, line)
1848 long value;
1849 int bits;
1850 char *file;
1851 int line;
1852{
1853 int tmp, max;
1854
1855 if (value < 0)
1856 tmp = ~value;
1857 else
1858 tmp = value;
1859
1860 max = (1 << (bits - 1)) - 1;
1861
1862 if (tmp > max)
7d515759 1863 as_bad_where (file, line, _("value too large to fit in %d bits"), bits);
e0882f34
MM
1864
1865 return;
1866}
7d515759
RH
1867
1868/* d30v_frob_label() is called when after a label is recognized. */
1869
1870void
1871d30v_frob_label (lab)
1872 symbolS *lab;
1873{
1874 /* Emit any pending instructions. */
7a0f469b 1875 d30v_cleanup ();
7d515759
RH
1876
1877 /* Update the label's address with the current output pointer. */
1878 lab->sy_frag = frag_now;
1879 S_SET_VALUE (lab, (valueT) frag_now_fix ());
1880
1881 /* Record this label for future adjustment after we find out what
1882 kind of data it references, and the required alignment therewith. */
1883 d30v_last_label = lab;
1884}
1885
1886/* Hook into cons for capturing alignment changes. */
1887
1888void
1889d30v_cons_align (size)
1890 int size;
1891{
1892 int log_size;
1893
1894 log_size = 0;
1895 while ((size >>= 1) != 0)
1896 ++log_size;
1897
1898 if (d30v_current_align < log_size)
1899 d30v_align (log_size, (char *) NULL, NULL);
1900 else if (d30v_current_align > log_size)
1901 d30v_current_align = log_size;
1902 d30v_last_label = NULL;
1903}
1904
1905/* Called internally to handle all alignment needs. This takes care
1906 of eliding calls to frag_align if'n the cached current alignment
1907 says we've already got it, as well as taking care of the auto-aligning
1908 labels wrt code. */
1909
1910static void
1911d30v_align (n, pfill, label)
1912 int n;
1913 char *pfill;
1914 symbolS *label;
1915{
1916 /* The front end is prone to changing segments out from under us
1917 temporarily when -g is in effect. */
1918 int switched_seg_p = (d30v_current_align_seg != now_seg);
1919
e21cafde
FCE
1920 /* Do not assume that if 'd30v_current_align >= n' and
1921 '! switched_seg_p' that it is safe to avoid performing
1922 this alignement request. The alignment of the current frag
1923 can be changed under our feet, for example by a .ascii
1924 directive in the source code. cf testsuite/gas/d30v/reloc.s */
7d515759 1925
7a0f469b 1926 d30v_cleanup ();
7d515759
RH
1927
1928 if (pfill == NULL)
1929 {
1930 if (n > 2
1931 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
1932 {
1933 static char const nop[4] = { 0x00, 0xf0, 0x00, 0x00 };
1934
1935 /* First, make sure we're on a four-byte boundary, in case
1936 someone has been putting .byte values the text section. */
1937 if (d30v_current_align < 2 || switched_seg_p)
1938 frag_align (2, 0, 0);
1939 frag_align_pattern (n, nop, sizeof nop, 0);
1940 }
1941 else
1942 frag_align (n, 0, 0);
1943 }
1944 else
1945 frag_align (n, *pfill, 0);
1946
1947 if (!switched_seg_p)
1948 d30v_current_align = n;
1949
1950 if (label != NULL)
1951 {
bc67c823
NC
1952 symbolS * sym;
1953 int label_seen = false;
1954 struct frag * old_frag;
1955 valueT old_value;
1956 valueT new_value;
1957
7d515759 1958 assert (S_GET_SEGMENT (label) == now_seg);
bc67c823
NC
1959
1960 old_frag = label->sy_frag;
1961 old_value = S_GET_VALUE (label);
7a0f469b 1962 new_value = (valueT) frag_now_fix ();
bc67c823
NC
1963
1964 /* It is possible to have more than one label at a particular
1965 address, especially if debugging is enabled, so we must
1966 take care to adjust all the labels at this address in this
1967 fragment. To save time we search from the end of the symbol
1968 list, backwards, since the symbols we are interested in are
1969 almost certainly the ones that were most recently added.
1970 Also to save time we stop searching once we have seen at least
1971 one matching label, and we encounter a label that is no longer
1972 in the target fragment. Note, this search is guaranteed to
1973 find at least one match when sym == label, so no special case
1974 code is necessary. */
1975 for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous)
1976 {
1977 if (sym->sy_frag == old_frag && S_GET_VALUE (sym) == old_value)
1978 {
1979 label_seen = true;
1980 sym->sy_frag = frag_now;
1981 S_SET_VALUE (sym, new_value);
1982 }
1983 else if (label_seen && sym->sy_frag != old_frag)
1984 break;
1985 }
7d515759
RH
1986 }
1987
7a0f469b 1988 record_alignment (now_seg, n);
7d515759
RH
1989}
1990
1991/* Handle the .align pseudo-op. This aligns to a power of two. We
1992 hook here to latch the current alignment. */
1993
1994static void
1995s_d30v_align (ignore)
1996 int ignore;
1997{
1998 int align;
1999 char fill, *pfill = NULL;
2000 long max_alignment = 15;
2001
2002 align = get_absolute_expression ();
2003 if (align > max_alignment)
2004 {
2005 align = max_alignment;
2006 as_warn (_("Alignment too large: %d assumed"), align);
2007 }
2008 else if (align < 0)
2009 {
2010 as_warn (_("Alignment negative: 0 assumed"));
2011 align = 0;
2012 }
2013
2014 if (*input_line_pointer == ',')
2015 {
2016 input_line_pointer++;
2017 fill = get_absolute_expression ();
2018 pfill = &fill;
2019 }
2020
2021 d30v_last_label = NULL;
2022 d30v_align (align, pfill, NULL);
2023
2024 demand_empty_rest_of_line ();
2025}
2026
2027/* Handle the .text pseudo-op. This is like the usual one, but it
2028 clears the saved last label and resets known alignment. */
2029
2030static void
2031s_d30v_text (i)
2032 int i;
2033
2034{
2035 s_text (i);
2036 d30v_last_label = NULL;
2037 d30v_current_align = 0;
2038 d30v_current_align_seg = now_seg;
2039}
2040
2041/* Handle the .data pseudo-op. This is like the usual one, but it
2042 clears the saved last label and resets known alignment. */
2043
2044static void
2045s_d30v_data (i)
2046 int i;
2047{
2048 s_data (i);
2049 d30v_last_label = NULL;
2050 d30v_current_align = 0;
2051 d30v_current_align_seg = now_seg;
2052}
2053
2054/* Handle the .section pseudo-op. This is like the usual one, but it
2055 clears the saved last label and resets known alignment. */
2056
2057static void
2058s_d30v_section (ignore)
2059 int ignore;
2060{
2061 obj_elf_section (ignore);
2062 d30v_last_label = NULL;
2063 d30v_current_align = 0;
2064 d30v_current_align_seg = now_seg;
2065}
This page took 0.157287 seconds and 4 git commands to generate.