Better optimize parallel instructions
[deliverable/binutils-gdb.git] / gas / config / tc-d30v.c
1 /* tc-d30v.c -- Assembler code for the Mitsubishi D30V
2
3 Copyright (C) 1997 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/d30v.h"
27
28 const char comment_chars[] = ";";
29 const char line_comment_chars[] = "#";
30 const char line_separator_chars[] = "";
31 const char *md_shortopts = "O";
32 const char EXP_CHARS[] = "eE";
33 const char FLT_CHARS[] = "dD";
34
35 int Optimizing = 0;
36
37 #define FORCE_SHORT 1
38 #define FORCE_LONG 2
39
40 /* fixups */
41 #define MAX_INSN_FIXUPS (5)
42 struct d30v_fixup
43 {
44 expressionS exp;
45 int operand;
46 int pcrel;
47 int size;
48 bfd_reloc_code_real_type reloc;
49 };
50
51 typedef struct _fixups
52 {
53 int fc;
54 struct d30v_fixup fix[MAX_INSN_FIXUPS];
55 struct _fixups *next;
56 } Fixups;
57
58 static Fixups FixUps[2];
59 static Fixups *fixups;
60
61 /* local functions */
62 static int reg_name_search PARAMS ((char *name));
63 static int register_name PARAMS ((expressionS *expressionP));
64 static int check_range PARAMS ((unsigned long num, int bits, int flags));
65 static int postfix PARAMS ((char *p));
66 static bfd_reloc_code_real_type get_reloc PARAMS ((struct d30v_operand *op, int rel_flag));
67 static int get_operands PARAMS ((expressionS exp[], int cmp_hack));
68 static struct d30v_format *find_format PARAMS ((struct d30v_opcode *opcode,
69 expressionS ops[],int fsize, int cmp_hack));
70 static long long build_insn PARAMS ((struct d30v_insn *opcode, expressionS *opers));
71 static void write_long PARAMS ((struct d30v_insn *opcode, long long insn, Fixups *fx));
72 static void write_1_short PARAMS ((struct d30v_insn *opcode, long long insn, Fixups *fx));
73 static int write_2_short PARAMS ((struct d30v_insn *opcode1, long long insn1,
74 struct d30v_insn *opcode2, long long insn2, int exec_type, Fixups *fx));
75 static long long do_assemble PARAMS ((char *str, struct d30v_insn *opcode));
76 static unsigned long d30v_insert_operand PARAMS (( unsigned long insn, int op_type,
77 offsetT value, int left, fixS *fix));
78 static int parallel_ok PARAMS ((struct d30v_insn *opcode1, unsigned long insn1,
79 struct d30v_insn *opcode2, unsigned long insn2,
80 int exec_type));
81 static void d30v_number_to_chars PARAMS ((char *buf, long long value, int nbytes));
82 static void check_size PARAMS ((long value, int bits, char *file, int line));
83
84 struct option md_longopts[] = {
85 {NULL, no_argument, NULL, 0}
86 };
87 size_t md_longopts_size = sizeof(md_longopts);
88
89
90 /* The target specific pseudo-ops which we support. */
91 const pseudo_typeS md_pseudo_table[] =
92 {
93 { "word", cons, 4 },
94 { "hword", cons, 2 },
95 { NULL, NULL, 0 }
96 };
97
98 /* Opcode hash table. */
99 static struct hash_control *d30v_hash;
100
101 /* reg_name_search does a binary search of the pre_defined_registers
102 array to see if "name" is a valid regiter name. Returns the register
103 number from the array on success, or -1 on failure. */
104
105 static int
106 reg_name_search (name)
107 char *name;
108 {
109 int middle, low, high;
110 int cmp;
111
112 low = 0;
113 high = reg_name_cnt() - 1;
114
115 do
116 {
117 middle = (low + high) / 2;
118 cmp = strcasecmp (name, pre_defined_registers[middle].name);
119 if (cmp < 0)
120 high = middle - 1;
121 else if (cmp > 0)
122 low = middle + 1;
123 else
124 return pre_defined_registers[middle].value;
125 }
126 while (low <= high);
127 return -1;
128 }
129
130 /* register_name() checks the string at input_line_pointer
131 to see if it is a valid register name */
132
133 static int
134 register_name (expressionP)
135 expressionS *expressionP;
136 {
137 int reg_number;
138 char c, *p = input_line_pointer;
139
140 while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
141 p++;
142
143 c = *p;
144 if (c)
145 *p++ = 0;
146
147 /* look to see if it's in the register table */
148 reg_number = reg_name_search (input_line_pointer);
149 if (reg_number >= 0)
150 {
151 expressionP->X_op = O_register;
152 /* temporarily store a pointer to the string here */
153 expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
154 expressionP->X_add_number = reg_number;
155 input_line_pointer = p;
156 return 1;
157 }
158 if (c)
159 *(p-1) = c;
160 return 0;
161 }
162
163
164 static int
165 check_range (num, bits, flags)
166 unsigned long num;
167 int bits;
168 int flags;
169 {
170 long min, max, bit1;
171 int retval=0;
172
173 /* don't bother checking 32-bit values */
174 if (bits == 32)
175 return 0;
176
177 if (flags & OPERAND_SIGNED)
178 {
179 max = (1 << (bits - 1))-1;
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 }
191 return retval;
192 }
193
194
195 void
196 md_show_usage (stream)
197 FILE *stream;
198 {
199 fprintf(stream, "D30V options:\n\
200 -O optimize. Will do some operations in parallel.\n");
201 }
202
203 int
204 md_parse_option (c, arg)
205 int c;
206 char *arg;
207 {
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;
218 }
219
220 symbolS *
221 md_undefined_symbol (name)
222 char *name;
223 {
224 return 0;
225 }
226
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 */
231 char *
232 md_atof (type, litP, sizeP)
233 int type;
234 char *litP;
235 int *sizeP;
236 {
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;
267 }
268
269 void
270 md_convert_frag (abfd, sec, fragP)
271 bfd *abfd;
272 asection *sec;
273 fragS *fragP;
274 {
275 abort ();
276 }
277
278 valueT
279 md_section_align (seg, addr)
280 asection *seg;
281 valueT addr;
282 {
283 int align = bfd_get_section_alignment (stdoutput, seg);
284 return ((addr + (1 << align) - 1) & (-1 << align));
285 }
286
287
288 void
289 md_begin ()
290 {
291 struct d30v_opcode *opcode;
292 d30v_hash = hash_new();
293
294 /* Insert opcode names into a hash table. */
295 for (opcode = (struct d30v_opcode *)d30v_opcode_table; opcode->name; opcode++)
296 hash_insert (d30v_hash, opcode->name, (char *) opcode);
297
298 fixups = &FixUps[0];
299 FixUps[0].next = &FixUps[1];
300 FixUps[1].next = &FixUps[0];
301 }
302
303
304 /* this function removes the postincrement or postdecrement
305 operator ( '+' or '-' ) from an expression */
306
307 static int postfix (p)
308 char *p;
309 {
310 while (*p != '-' && *p != '+')
311 {
312 if (*p==0 || *p=='\n' || *p=='\r' || *p==' ' || *p==',')
313 break;
314 p++;
315 }
316
317 if (*p == '-')
318 {
319 *p = ' ';
320 return (-1);
321 }
322 if (*p == '+')
323 {
324 *p = ' ';
325 return (1);
326 }
327
328 return (0);
329 }
330
331
332 static bfd_reloc_code_real_type
333 get_reloc (op, rel_flag)
334 struct d30v_operand *op;
335 int rel_flag;
336 {
337 switch (op->bits)
338 {
339 case 6:
340 if (op->flags & OPERAND_SHIFT)
341 return BFD_RELOC_D30V_9_PCREL;
342 else
343 return BFD_RELOC_D30V_6;
344 break;
345 case 12:
346 if (!(op->flags & OPERAND_SHIFT))
347 as_warn("unexpected 12-bit reloc type");
348 if (rel_flag == RELOC_PCREL)
349 return BFD_RELOC_D30V_15_PCREL;
350 else
351 return BFD_RELOC_D30V_15;
352 case 18:
353 if (!(op->flags & OPERAND_SHIFT))
354 as_warn("unexpected 18-bit reloc type");
355 if (rel_flag == RELOC_PCREL)
356 return BFD_RELOC_D30V_21_PCREL;
357 else
358 return BFD_RELOC_D30V_21;
359 case 32:
360 if (rel_flag == RELOC_PCREL)
361 return BFD_RELOC_D30V_32_PCREL;
362 else
363 return BFD_RELOC_D30V_32;
364 default:
365 return 0;
366 }
367 }
368
369 /* get_operands parses a string of operands and returns
370 an array of expressions */
371
372 static int
373 get_operands (exp, cmp_hack)
374 expressionS exp[];
375 int cmp_hack;
376 {
377 char *p = input_line_pointer;
378 int numops = 0;
379 int post = 0;
380
381 if (cmp_hack)
382 {
383 exp[numops].X_op = O_absent;
384 exp[numops++].X_add_number = cmp_hack - 1;
385 }
386
387 while (*p)
388 {
389 while (*p == ' ' || *p == '\t' || *p == ',')
390 p++;
391 if (*p==0 || *p=='\n' || *p=='\r')
392 break;
393
394 if (*p == '@')
395 {
396 p++;
397 exp[numops].X_op = O_absent;
398 if (*p == '(')
399 {
400 p++;
401 exp[numops].X_add_number = OPERAND_ATPAR;
402 post = postfix (p);
403 }
404 else if (*p == '-')
405 {
406 p++;
407 exp[numops].X_add_number = OPERAND_ATMINUS;
408 }
409 else
410 {
411 exp[numops].X_add_number = OPERAND_ATSIGN;
412 post = postfix (p);
413 }
414 numops++;
415 continue;
416 }
417
418 if (*p == ')')
419 {
420 /* just skip the trailing paren */
421 p++;
422 continue;
423 }
424
425 input_line_pointer = p;
426
427 /* check to see if it might be a register name */
428 if (!register_name (&exp[numops]))
429 {
430 /* parse as an expression */
431 expression (&exp[numops]);
432 }
433
434 if (exp[numops].X_op == O_illegal)
435 as_bad ("illegal operand");
436 else if (exp[numops].X_op == O_absent)
437 as_bad ("missing operand");
438
439 numops++;
440 p = input_line_pointer;
441
442 switch (post)
443 {
444 case -1: /* postdecrement mode */
445 exp[numops].X_op = O_absent;
446 exp[numops++].X_add_number = OPERAND_MINUS;
447 break;
448 case 1: /* postincrement mode */
449 exp[numops].X_op = O_absent;
450 exp[numops++].X_add_number = OPERAND_PLUS;
451 break;
452 }
453 post = 0;
454 }
455
456 exp[numops].X_op = 0;
457 return (numops);
458 }
459
460 /* build_insn generates the instruction. It does everything */
461 /* but write the FM bits. */
462
463 static long long
464 build_insn (opcode, opers)
465 struct d30v_insn *opcode;
466 expressionS *opers;
467 {
468 int i, length, bits, shift, flags, format;
469 unsigned int number, id=0;
470 long long insn;
471 struct d30v_opcode *op = opcode->op;
472 struct d30v_format *form = opcode->form;
473
474 insn = opcode->ecc << 28 | op->op1 << 25 | op->op2 << 20 | form->modifier << 18;
475
476 for (i=0; form->operands[i]; i++)
477 {
478 flags = d30v_operand_table[form->operands[i]].flags;
479
480 /* must be a register or number */
481 if (!(flags & OPERAND_REG) && !(flags & OPERAND_NUM) &&
482 !(flags & OPERAND_NAME) && !(flags & OPERAND_SPECIAL))
483 continue;
484
485 bits = d30v_operand_table[form->operands[i]].bits;
486 if (flags & OPERAND_SHIFT)
487 bits += 3;
488
489 length = d30v_operand_table[form->operands[i]].length;
490 shift = 12 - d30v_operand_table[form->operands[i]].position;
491 if (opers[i].X_op != O_symbol)
492 number = opers[i].X_add_number;
493 else
494 number = 0;
495 if (flags & OPERAND_REG)
496 {
497 /* check for mvfsys or mvtsys control registers */
498 if (flags & OPERAND_CONTROL && (number & 0x7f) > MAX_CONTROL_REG)
499 {
500 /* PSWL or PSWH */
501 id = (number & 0x7f) - MAX_CONTROL_REG;
502 number = 0;
503 }
504 else if (number & OPERAND_FLAG)
505 {
506 id = 3; /* number is a flag register */
507 }
508 number &= 0x7F;
509 }
510 else if (flags & OPERAND_SPECIAL)
511 {
512 number = id;
513 }
514
515 if (opers[i].X_op != O_register && opers[i].X_op != O_constant && !(flags & OPERAND_NAME))
516 {
517 /* now create a fixup */
518
519 if (fixups->fc >= MAX_INSN_FIXUPS)
520 as_fatal ("too many fixups");
521
522 fixups->fix[fixups->fc].reloc =
523 get_reloc((struct d30v_operand *)&d30v_operand_table[form->operands[i]], op->reloc_flag);
524 fixups->fix[fixups->fc].size = 4;
525 fixups->fix[fixups->fc].exp = opers[i];
526 fixups->fix[fixups->fc].operand = form->operands[i];
527 if (fixups->fix[fixups->fc].reloc == BFD_RELOC_D30V_9_PCREL)
528 fixups->fix[fixups->fc].pcrel = RELOC_PCREL;
529 else
530 fixups->fix[fixups->fc].pcrel = op->reloc_flag;
531 (fixups->fc)++;
532 }
533
534 /* truncate to the proper number of bits */
535 if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
536 as_bad("operand out of range: %d",number);
537 if (bits < 31)
538 number &= 0x7FFFFFFF >> (31 - bits);
539 if (flags & OPERAND_SHIFT)
540 number >>= 3;
541 if (bits == 32)
542 {
543 /* it's a LONG instruction */
544 insn |= (number >> 26); /* top 6 bits */
545 insn <<= 32; /* shift the first word over */
546 insn |= ((number & 0x03FC0000) << 2); /* next 8 bits */
547 insn |= number & 0x0003FFFF; /* bottom 18 bits */
548 }
549 else
550 insn |= number << shift;
551 }
552 return insn;
553 }
554
555
556 /* write out a long form instruction */
557 static void
558 write_long (opcode, insn, fx)
559 struct d30v_insn *opcode;
560 long long insn;
561 Fixups *fx;
562 {
563 int i, where;
564 char *f = frag_more(8);
565
566 insn |= FM11;
567 d30v_number_to_chars (f, insn, 8);
568
569 for (i=0; i < fx->fc; i++)
570 {
571 if (fx->fix[i].reloc)
572 {
573 where = f - frag_now->fr_literal;
574 fix_new_exp (frag_now,
575 where,
576 fx->fix[i].size,
577 &(fx->fix[i].exp),
578 fx->fix[i].pcrel,
579 fx->fix[i].reloc);
580 }
581 }
582 fx->fc = 0;
583 }
584
585
586 /* write out a short form instruction by itself */
587 static void
588 write_1_short (opcode, insn, fx)
589 struct d30v_insn *opcode;
590 long long insn;
591 Fixups *fx;
592 {
593 char *f = frag_more(8);
594 int i, where;
595
596 /* the other container needs to be NOP */
597 /* according to 4.3.1: for FM=00, sub-instructions performed only
598 by IU cannot be encoded in L-container. */
599 if (opcode->op->unit == IU)
600 insn |= FM00 | ((long long)NOP << 32); /* right container */
601 else
602 insn = FM00 | (insn << 32) | (long long)NOP; /* left container */
603
604 d30v_number_to_chars (f, insn, 8);
605
606 for (i=0; i < fx->fc; i++)
607 {
608 if (fx->fix[i].reloc)
609 {
610 where = f - frag_now->fr_literal;
611 fix_new_exp (frag_now,
612 where,
613 fx->fix[i].size,
614 &(fx->fix[i].exp),
615 fx->fix[i].pcrel,
616 fx->fix[i].reloc);
617 }
618 }
619 fx->fc = 0;
620 }
621
622 /* write out a short form instruction if possible */
623 /* return number of instructions not written out */
624 static int
625 write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
626 struct d30v_insn *opcode1, *opcode2;
627 long long insn1, insn2;
628 int exec_type;
629 Fixups *fx;
630 {
631 long long insn;
632 char *f;
633 int i,j, where;
634
635 if(exec_type != 1 && (opcode1->op->flags_used == FLAG_JSR))
636 {
637 /* subroutines must be called from 32-bit boundaries */
638 /* so the return address will be correct */
639 write_1_short (opcode1, insn1, fx->next);
640 return (1);
641 }
642
643 switch (exec_type)
644 {
645 case 0: /* order not specified */
646 if ( Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
647 {
648 /* parallel */
649 if (opcode1->op->unit == IU)
650 insn = FM00 | (insn2 << 32) | insn1;
651 else if (opcode2->op->unit == MU)
652 insn = FM00 | (insn2 << 32) | insn1;
653 else
654 {
655 insn = FM00 | (insn1 << 32) | insn2;
656 fx = fx->next;
657 }
658 }
659 else if (opcode1->op->unit == IU)
660 {
661 /* reverse sequential */
662 insn = FM10 | (insn2 << 32) | insn1;
663 }
664 else
665 {
666 /* sequential */
667 insn = FM01 | (insn1 << 32) | insn2;
668 fx = fx->next;
669 }
670 break;
671 case 1: /* parallel */
672 if (opcode1->op->unit == IU)
673 {
674 if (opcode2->op->unit == IU)
675 as_fatal ("Two IU instructions may not be executed in parallel");
676 as_warn ("Swapping instruction order");
677 insn = FM00 | (insn2 << 32) | insn1;
678 }
679 else if (opcode2->op->unit == MU)
680 {
681 if (opcode1->op->unit == MU)
682 as_fatal ("Two MU instructions may not be executed in parallel");
683 as_warn ("Swapping instruction order");
684 insn = FM00 | (insn2 << 32) | insn1;
685 }
686 else
687 {
688 insn = FM00 | (insn1 << 32) | insn2;
689 fx = fx->next;
690 }
691 break;
692 case 2: /* sequential */
693 if (opcode1->op->unit == IU)
694 as_fatal ("IU instruction may not be in the left container");
695 insn = FM01 | (insn1 << 32) | insn2;
696 fx = fx->next;
697 break;
698 case 3: /* reverse sequential */
699 if (opcode2->op->unit == MU)
700 as_fatal ("MU instruction may not be in the right container");
701 insn = FM10 | (insn1 << 32) | insn2;
702 fx = fx->next;
703 break;
704 default:
705 as_fatal("unknown execution type passed to write_2_short()");
706 }
707
708 /* printf("writing out %llx\n",insn); */
709 f = frag_more(8);
710 d30v_number_to_chars (f, insn, 8);
711
712 for (j=0; j<2; j++)
713 {
714 for (i=0; i < fx->fc; i++)
715 {
716 if (fx->fix[i].reloc)
717 {
718 where = (f - frag_now->fr_literal) + 4*j;
719
720 fix_new_exp (frag_now,
721 where,
722 fx->fix[i].size,
723 &(fx->fix[i].exp),
724 fx->fix[i].pcrel,
725 fx->fix[i].reloc);
726 }
727 }
728 fx->fc = 0;
729 fx = fx->next;
730 }
731 return (0);
732 }
733
734
735 /* Check 2 instructions and determine if they can be safely */
736 /* executed in parallel. Returns 1 if they can be. */
737 static int
738 parallel_ok (op1, insn1, op2, insn2, exec_type)
739 struct d30v_insn *op1, *op2;
740 unsigned long insn1, insn2;
741 int exec_type;
742 {
743 int i, j, shift, regno, bits, ecc;
744 unsigned long flags, mask, flags_set1, flags_set2, flags_used1, flags_used2;
745 unsigned long ins, mod_reg[2][3], used_reg[2][3];
746 struct d30v_format *f;
747 struct d30v_opcode *op;
748 int reverse_p;
749
750 /* section 4.3: both instructions must not be IU or MU only */
751 if ((op1->op->unit == IU && op2->op->unit == IU)
752 || (op1->op->unit == MU && op2->op->unit == MU))
753 return 0;
754
755 /* first instruction must not be a jump to safely optimize */
756 if (op1->op->flags_used & (FLAG_JMP | FLAG_JSR))
757 return 0;
758
759 /* If one instruction is /TX or /XT and the other is /FX or /XF respectively,
760 then it is safe to allow the two to be done as parallel ops, since only
761 one will ever be executed at a time. */
762 if ((op1->ecc == ECC_TX && op2->ecc == ECC_FX)
763 || (op1->ecc == ECC_FX && op2->ecc == ECC_TX)
764 || (op1->ecc == ECC_XT && op2->ecc == ECC_XF)
765 || (op1->ecc == ECC_XF && op2->ecc == ECC_XT))
766 return 1;
767
768 /* [0] r0-r31
769 [1] r32-r63
770 [2] a0, a1, flag registers */
771
772 for (j = 0; j < 2; j++)
773 {
774 if (j == 0)
775 {
776 f = op1->form;
777 op = op1->op;
778 ecc = op1->ecc;
779 ins = insn1;
780 }
781 else
782 {
783 f = op2->form;
784 op = op2->op;
785 ecc = op2->ecc;
786 ins = insn2;
787 }
788 mod_reg[j][0] = mod_reg[j][1] = 0;
789 mod_reg[j][2] = (op->flags_set & FLAG_ALL);
790 used_reg[j][0] = used_reg[j][1] = 0;
791 used_reg[j][2] = (op->flags_used & FLAG_ALL);
792
793 /* BSR/JSR always sets R62 */
794 if (op->flags_used & FLAG_JSR)
795 mod_reg[j][1] = (1L << (62-32));
796
797 /* conditional execution affects the flags_used */
798 switch (ecc)
799 {
800 case ECC_TX:
801 case ECC_FX:
802 used_reg[j][2] |= FLAG_0;
803 break;
804
805 case ECC_XT:
806 case ECC_XF:
807 used_reg[j][2] |= FLAG_1;
808 break;
809
810 case ECC_TT:
811 case ECC_TF:
812 used_reg[j][2] |= (FLAG_0 | FLAG_1);
813 break;
814 }
815
816 for (i = 0; f->operands[i]; i++)
817 {
818 flags = d30v_operand_table[f->operands[i]].flags;
819 shift = 12 - d30v_operand_table[f->operands[i]].position;
820 bits = d30v_operand_table[f->operands[i]].bits;
821 if (bits == 32)
822 mask = 0xffffffff;
823 else
824 mask = 0x7FFFFFFF >> (31 - bits);
825
826 if ((flags & OPERAND_PLUS) || (flags & OPERAND_MINUS))
827 {
828 /* this is a post-increment or post-decrement */
829 /* the previous register needs to be marked as modified */
830
831 shift = 12 - d30v_operand_table[f->operands[i-1]].position;
832 regno = (ins >> shift) & 0x3f;
833 if (regno >= 32)
834 mod_reg[j][1] |= 1L << (regno - 32);
835 else
836 mod_reg[j][0] |= 1L << regno;
837 }
838 else if (flags & OPERAND_REG)
839 {
840 regno = (ins >> shift) & mask;
841 /* the memory write functions don't have a destination register */
842 if ((flags & OPERAND_DEST) && !(op->flags_set & FLAG_MEM))
843 {
844 /* MODIFIED registers and flags */
845 if (flags & OPERAND_ACC)
846 {
847 if (regno == 0)
848 mod_reg[j][2] |= FLAG_A0;
849 else if (regno == 1)
850 mod_reg[j][2] |= FLAG_A1;
851 else
852 abort ();
853 }
854 else if (flags & OPERAND_FLAG)
855 mod_reg[j][2] |= 1L << regno;
856 else if (!(flags & OPERAND_CONTROL))
857 {
858 int r, z;
859
860 /* need to check if there are two destination */
861 /* registers, for example ld2w */
862 if (flags & OPERAND_2REG)
863 z = 1;
864 else
865 z = 0;
866
867 for (r = regno; r <= regno + z; r++)
868 {
869 if (r >= 32)
870 mod_reg[j][1] |= 1L << (r - 32);
871 else
872 mod_reg[j][0] |= 1L << r;
873 }
874 }
875 }
876 else
877 {
878 /* USED, but not modified registers and flags */
879 if (flags & OPERAND_ACC)
880 {
881 if (regno == 0)
882 used_reg[j][2] |= FLAG_A0;
883 else if (regno == 1)
884 used_reg[j][2] |= FLAG_A1;
885 else
886 abort ();
887 }
888 else if (flags & OPERAND_FLAG)
889 used_reg[j][2] |= 1L << regno;
890 else if (!(flags & OPERAND_CONTROL))
891 {
892 int r, z;
893
894 /* need to check if there are two source */
895 /* registers, for example st2w */
896 if (flags & OPERAND_2REG)
897 z = 1;
898 else
899 z = 0;
900
901 for (r = regno; r <= regno + z; r++)
902 {
903 if (r >= 32)
904 used_reg[j][1] |= 1L << (r - 32);
905 else
906 used_reg[j][0] |= 1L << r;
907 }
908 }
909 }
910 }
911 }
912 }
913
914 flags_set1 = op1->op->flags_set;
915 flags_set2 = op2->op->flags_set;
916 flags_used1 = op1->op->flags_used;
917 flags_used2 = op2->op->flags_used;
918
919 /* ST2W/ST4HB combined with ADDppp/SUBppp is illegal. */
920 if (((flags_set1 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD)
921 && (flags_used2 & FLAG_ADDSUBppp) != 0)
922 || ((flags_set2 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD)
923 && (flags_used1 & FLAG_ADDSUBppp) != 0))
924 return 0;
925
926 /* Load instruction combined with half-word multiply is illegal. */
927 if (((flags_used1 & FLAG_MEM) != 0 && (flags_used2 & FLAG_MUL16))
928 || ((flags_used2 & FLAG_MEM) != 0 && (flags_used1 & FLAG_MUL16)))
929 return 0;
930
931 /* Specifically allow add || add by removing carry, overflow bits dependency.
932 This is safe, even if an addc follows since the IU takes the argument in
933 the right container, and it writes its results last.
934 However, don't paralellize add followed by addc or sub followed by
935 subb. */
936
937 if (mod_reg[0][2] == FLAG_CVVA && mod_reg[1][2] == FLAG_CVVA
938 && used_reg[0][2] == 0 && used_reg[1][2] == 0
939 && op1->op->unit == EITHER && op2->op->unit == EITHER)
940 {
941 mod_reg[0][2] = mod_reg[1][2] = 0;
942 }
943
944 for(j = 0; j < 3; j++)
945 {
946 /* If the second instruction depends on the first, we obviously
947 cannot parallelize. Note, the mod flag implies use, so
948 check that as well. */
949 if ((mod_reg[0][j] & (mod_reg[1][j] | used_reg[1][j])) != 0)
950 return 0;
951 }
952
953 return 1;
954 }
955
956
957
958 /* This is the main entry point for the machine-dependent assembler. str points to a
959 machine-dependent instruction. This function is supposed to emit the frags/bytes
960 it assembles to. For the D30V, it mostly handles the special VLIW parsing and packing
961 and leaves the difficult stuff to do_assemble().
962 */
963
964 static long long prev_insn = -1;
965 static struct d30v_insn prev_opcode;
966 static subsegT prev_subseg;
967 static segT prev_seg = 0;
968
969 void
970 md_assemble (str)
971 char *str;
972 {
973 struct d30v_insn opcode;
974 long long insn;
975 int extype=0; /* execution type; parallel, etc */
976 static int etype=0; /* saved extype. used for multiline instructions */
977 char *str2;
978
979 if ( (prev_insn != -1) && prev_seg && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
980 d30v_cleanup();
981
982 if (etype == 0)
983 {
984 /* look for the special multiple instruction separators */
985 str2 = strstr (str, "||");
986 if (str2)
987 extype = 1;
988 else
989 {
990 str2 = strstr (str, "->");
991 if (str2)
992 extype = 2;
993 else
994 {
995 str2 = strstr (str, "<-");
996 if (str2)
997 extype = 3;
998 }
999 }
1000 /* str2 points to the separator, if one */
1001 if (str2)
1002 {
1003 *str2 = 0;
1004
1005 /* if two instructions are present and we already have one saved
1006 then first write it out */
1007 d30v_cleanup();
1008
1009 /* assemble first instruction and save it */
1010 prev_insn = do_assemble (str, &prev_opcode);
1011 if (prev_insn == -1)
1012 as_fatal ("cannot assemble instruction ");
1013 if (prev_opcode.form->form >= LONG)
1014 as_fatal ("First opcode is long. Unable to mix instructions as specified.");
1015 fixups = fixups->next;
1016 str = str2 + 2;
1017 }
1018 }
1019
1020 insn = do_assemble (str, &opcode);
1021 if (insn == -1)
1022 {
1023 if (extype)
1024 {
1025 etype = extype;
1026 return;
1027 }
1028 as_fatal ("cannot assemble instruction ");
1029 }
1030
1031 if (etype)
1032 {
1033 extype = etype;
1034 etype = 0;
1035 }
1036
1037 /* if this is a long instruction, write it and any previous short instruction */
1038 if (opcode.form->form >= LONG)
1039 {
1040 if (extype)
1041 as_fatal("Unable to mix instructions as specified");
1042 d30v_cleanup();
1043 write_long (&opcode, insn, fixups);
1044 prev_insn = -1;
1045 return;
1046 }
1047
1048 if ( (prev_insn != -1) &&
1049 (write_2_short (&prev_opcode, (long)prev_insn, &opcode, (long)insn, extype, fixups) == 0))
1050 {
1051 /* no instructions saved */
1052 prev_insn = -1;
1053 }
1054 else
1055 {
1056 if (extype)
1057 as_fatal("Unable to mix instructions as specified");
1058 /* save off last instruction so it may be packed on next pass */
1059 memcpy( &prev_opcode, &opcode, sizeof(prev_opcode));
1060 prev_insn = insn;
1061 prev_seg = now_seg;
1062 prev_subseg = now_subseg;
1063 fixups = fixups->next;
1064 }
1065 }
1066
1067
1068 /* do_assemble assembles a single instruction and returns an opcode */
1069 /* it returns -1 (an invalid opcode) on error */
1070
1071 static long long
1072 do_assemble (str, opcode)
1073 char *str;
1074 struct d30v_insn *opcode;
1075 {
1076 unsigned char *op_start, *save;
1077 unsigned char *op_end;
1078 char name[20];
1079 int cmp_hack, nlen = 0, fsize = 0;
1080 expressionS myops[6];
1081 long long insn;
1082
1083 /* Drop leading whitespace */
1084 while (*str == ' ')
1085 str++;
1086
1087 /* find the opcode end */
1088 for (op_start = op_end = (unsigned char *) (str);
1089 *op_end
1090 && nlen < 20
1091 && *op_end != '/'
1092 && !is_end_of_line[*op_end] && *op_end != ' ';
1093 op_end++)
1094 {
1095 name[nlen] = tolower(op_start[nlen]);
1096 nlen++;
1097 }
1098
1099 if (nlen == 0)
1100 return (-1);
1101
1102 name[nlen] = 0;
1103
1104 /* if there is an execution condition code, handle it */
1105 if (*op_end == '/')
1106 {
1107 int i = 0;
1108 while ( (i < ECC_MAX) && strncasecmp(d30v_ecc_names[i],op_end+1,2))
1109 i++;
1110
1111 if (i == ECC_MAX)
1112 {
1113 char tmp[4];
1114 strncpy(tmp,op_end+1,2);
1115 tmp[2] = 0;
1116 as_fatal ("unknown condition code: %s",tmp);
1117 return -1;
1118 }
1119 /* printf("condition code=%d\n",i); */
1120 opcode->ecc = i;
1121 op_end += 3;
1122 }
1123 else
1124 opcode->ecc = ECC_AL;
1125
1126
1127 /* CMP and CMPU change their name based on condition codes */
1128 if (!strncmp(name,"cmp",3))
1129 {
1130 int p,i;
1131 char **str = (char **)d30v_cc_names;
1132 if (name[3] == 'u')
1133 p = 4;
1134 else
1135 p = 3;
1136
1137 for(i=1; *str && strncmp(*str,&name[p],2); i++, *str++)
1138 ;
1139
1140 /* cmpu only supports some condition codes */
1141 if (p == 4)
1142 {
1143 if (i < 3 || i > 6)
1144 {
1145 name[p+2]=0;
1146 as_fatal ("cmpu doesn't support condition code %s",&name[p]);
1147 }
1148 }
1149
1150 if (!*str)
1151 {
1152 name[p+2]=0;
1153 as_fatal ("unknown condition code: %s",&name[p]);
1154 }
1155
1156 cmp_hack = i;
1157 name[p] = 0;
1158 }
1159 else
1160 cmp_hack = 0;
1161
1162 /* printf("cmp_hack=%d\n",cmp_hack); */
1163
1164 /* need to look for .s or .l */
1165 if (name[nlen-2] == '.')
1166 {
1167 switch (name[nlen-1])
1168 {
1169 case 's':
1170 fsize = FORCE_SHORT;
1171 break;
1172 case 'l':
1173 fsize = FORCE_LONG;
1174 default:
1175 }
1176 name[nlen-2] = 0;
1177 }
1178
1179 /* find the first opcode with the proper name */
1180 opcode->op = (struct d30v_opcode *)hash_find (d30v_hash, name);
1181 if (opcode->op == NULL)
1182 as_fatal ("unknown opcode: %s",name);
1183
1184 save = input_line_pointer;
1185 input_line_pointer = op_end;
1186 while (!(opcode->form = find_format (opcode->op, myops, fsize, cmp_hack)))
1187 {
1188 opcode->op++;
1189 if (strcmp(opcode->op->name,name))
1190 return -1;
1191 }
1192 input_line_pointer = save;
1193
1194 insn = build_insn (opcode, myops);
1195 return (insn);
1196 }
1197
1198
1199 /* find_format() gets a pointer to an entry in the format table. */
1200 /* It must look at all formats for an opcode and use the operands */
1201 /* to choose the correct one. Returns NULL on error. */
1202
1203 static struct d30v_format *
1204 find_format (opcode, myops, fsize, cmp_hack)
1205 struct d30v_opcode *opcode;
1206 expressionS myops[];
1207 int fsize;
1208 int cmp_hack;
1209 {
1210 int numops, match, index, i=0, j, k;
1211 struct d30v_format *fm;
1212 struct d30v_operand *op;
1213
1214 /* get all the operands and save them as expressions */
1215 numops = get_operands (myops, cmp_hack);
1216
1217 while (index = opcode->format[i++])
1218 {
1219 if ((fsize == FORCE_SHORT) && (index >= LONG))
1220 continue;
1221
1222 if ((fsize == FORCE_LONG) && (index < LONG))
1223 continue;
1224
1225 fm = (struct d30v_format *)&d30v_format_table[index];
1226 k = index;
1227 while (fm->form == index)
1228 {
1229 match = 1;
1230 /* now check the operands for compatibility */
1231 for (j = 0; match && fm->operands[j]; j++)
1232 {
1233 int flags = d30v_operand_table[fm->operands[j]].flags;
1234 int X_op = myops[j].X_op;
1235 int num = myops[j].X_add_number;
1236
1237 if ( flags & OPERAND_SPECIAL )
1238 break;
1239 else if (X_op == 0)
1240 match = 0;
1241 else if (flags & OPERAND_REG)
1242 {
1243 if ((X_op != O_register) ||
1244 ((flags & OPERAND_ACC) && !(num & OPERAND_ACC)) ||
1245 ((flags & OPERAND_FLAG) && !(num & OPERAND_FLAG)) ||
1246 (flags & OPERAND_CONTROL && !(num & OPERAND_CONTROL | num & OPERAND_FLAG)))
1247 {
1248 match = 0;
1249 }
1250 }
1251 else
1252 if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
1253 ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
1254 ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
1255 ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
1256 ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || (num != OPERAND_ATSIGN))))
1257 {
1258 match=0;
1259 }
1260 else if (flags & OPERAND_NUM)
1261 {
1262 /* a number can be a constant or symbol expression */
1263 if (fm->form >= LONG)
1264 {
1265 /* If we're testing for a LONG format, either fits */
1266 if (X_op != O_constant && X_op != O_symbol)
1267 match = 0;
1268 }
1269 else if ((fm->form < LONG) && (((fsize == FORCE_SHORT) && (X_op == O_symbol)) ||
1270 (fm->form == SHORT_D2 && j == 0)))
1271 match = 1;
1272 /* This is the tricky part. Will the constant or symbol */
1273 /* fit into the space in the current format? */
1274 else if (X_op == O_constant)
1275 {
1276 if (check_range (num, d30v_operand_table[fm->operands[j]].bits, flags))
1277 match = 0;
1278 }
1279 else if (X_op == O_symbol && S_IS_DEFINED(myops[j].X_add_symbol) &&
1280 (S_GET_SEGMENT(myops[j].X_add_symbol) == now_seg) &&
1281 opcode->reloc_flag == RELOC_PCREL)
1282 {
1283 /* if the symbol is defined, see if the value will fit */
1284 /* into the form we're considering */
1285 fragS *f;
1286 long value;
1287 /* calculate the current address by running through the previous frags */
1288 /* and adding our current offset */
1289 for (value = 0, f = frchain_now->frch_root; f; f = f->fr_next)
1290 value += f->fr_fix + f->fr_offset;
1291 value = S_GET_VALUE(myops[j].X_add_symbol) - value -
1292 (obstack_next_free(&frchain_now->frch_obstack) - frag_now->fr_literal);
1293 if (check_range (value, d30v_operand_table[fm->operands[j]].bits, flags))
1294 match = 0;
1295 }
1296 else
1297 match = 0;
1298 }
1299 }
1300 /* printf("through the loop: match=%d\n",match); */
1301 /* we're only done if the operands matched so far AND there
1302 are no more to check */
1303 if (match && myops[j].X_op==0)
1304 return fm;
1305 match = 0;
1306 fm = (struct d30v_format *)&d30v_format_table[++k];
1307 }
1308 /* printf("trying another format: i=%d\n",i); */
1309 }
1310 return NULL;
1311 }
1312
1313 /* if while processing a fixup, a reloc really needs to be created */
1314 /* then it is done here */
1315
1316 arelent *
1317 tc_gen_reloc (seg, fixp)
1318 asection *seg;
1319 fixS *fixp;
1320 {
1321 arelent *reloc;
1322 reloc = (arelent *) xmalloc (sizeof (arelent));
1323 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1324 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1325 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1326 if (reloc->howto == (reloc_howto_type *) NULL)
1327 {
1328 as_bad_where (fixp->fx_file, fixp->fx_line,
1329 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
1330 return NULL;
1331 }
1332 reloc->addend = fixp->fx_addnumber;
1333 return reloc;
1334 }
1335
1336 int
1337 md_estimate_size_before_relax (fragp, seg)
1338 fragS *fragp;
1339 asection *seg;
1340 {
1341 abort ();
1342 return 0;
1343 }
1344
1345 long
1346 md_pcrel_from_section (fixp, sec)
1347 fixS *fixp;
1348 segT sec;
1349 {
1350 if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) ||
1351 (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1352 return 0;
1353 return fixp->fx_frag->fr_address + fixp->fx_where;
1354 }
1355
1356 int
1357 md_apply_fix3 (fixp, valuep, seg)
1358 fixS *fixp;
1359 valueT *valuep;
1360 segT seg;
1361 {
1362 char *where;
1363 unsigned long insn, insn2;
1364 long value;
1365 int op_type;
1366 int left=0;
1367
1368 if (fixp->fx_addsy == (symbolS *) NULL)
1369 {
1370 value = *valuep;
1371 fixp->fx_done = 1;
1372 }
1373 else if (fixp->fx_pcrel)
1374 {
1375 value = *valuep;
1376 }
1377 else
1378 {
1379 value = fixp->fx_offset;
1380 if (fixp->fx_subsy != (symbolS *) NULL)
1381 {
1382 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1383 value -= S_GET_VALUE (fixp->fx_subsy);
1384 else
1385 {
1386 /* We don't actually support subtracting a symbol. */
1387 as_bad_where (fixp->fx_file, fixp->fx_line,
1388 "expression too complex");
1389 }
1390 }
1391 }
1392
1393 /* Fetch the instruction, insert the fully resolved operand
1394 value, and stuff the instruction back again. */
1395 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1396 insn = bfd_getb32 ((unsigned char *) where);
1397
1398 switch (fixp->fx_r_type)
1399 {
1400 case BFD_RELOC_D30V_6:
1401 check_size (value, 6, fixp->fx_file, fixp->fx_line);
1402 insn |= value & 0x3F;
1403 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1404 break;
1405 case BFD_RELOC_D30V_9_PCREL:
1406 if (fixp->fx_where & 0x7)
1407 {
1408 if (fixp->fx_done)
1409 value += 4;
1410 else
1411 fixp->fx_r_type = BFD_RELOC_D30V_9_PCREL_R;
1412 }
1413 check_size (value, 9, fixp->fx_file, fixp->fx_line);
1414 insn |= ((value >> 3) & 0x3F) << 12;
1415 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1416 break;
1417 case BFD_RELOC_D30V_15:
1418 check_size (value, 15, fixp->fx_file, fixp->fx_line);
1419 insn |= (value >> 3) & 0xFFF;
1420 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1421 break;
1422 case BFD_RELOC_D30V_15_PCREL:
1423 if (fixp->fx_where & 0x7)
1424 {
1425 if (fixp->fx_done)
1426 value += 4;
1427 else
1428 fixp->fx_r_type = BFD_RELOC_D30V_15_PCREL_R;
1429 }
1430 check_size (value, 15, fixp->fx_file, fixp->fx_line);
1431 insn |= (value >> 3) & 0xFFF;
1432 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1433 break;
1434 case BFD_RELOC_D30V_21:
1435 check_size (value, 21, fixp->fx_file, fixp->fx_line);
1436 insn |= (value >> 3) & 0x3FFFF;
1437 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1438 break;
1439 case BFD_RELOC_D30V_21_PCREL:
1440 if (fixp->fx_where & 0x7)
1441 {
1442 if (fixp->fx_done)
1443 value += 4;
1444 else
1445 fixp->fx_r_type = BFD_RELOC_D30V_21_PCREL_R;
1446 }
1447 check_size (value, 21, fixp->fx_file, fixp->fx_line);
1448 insn |= (value >> 3) & 0x3FFFF;
1449 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1450 break;
1451 case BFD_RELOC_D30V_32:
1452 insn2 = bfd_getb32 ((unsigned char *) where + 4);
1453 insn |= (value >> 26) & 0x3F; /* top 6 bits */
1454 insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */
1455 insn2 |= value & 0x0003FFFF; /* bottom 18 bits */
1456 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1457 bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
1458 break;
1459 case BFD_RELOC_D30V_32_PCREL:
1460 insn2 = bfd_getb32 ((unsigned char *) where + 4);
1461 insn |= (value >> 26) & 0x3F; /* top 6 bits */
1462 insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */
1463 insn2 |= value & 0x0003FFFF; /* bottom 18 bits */
1464 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1465 bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
1466 break;
1467 case BFD_RELOC_32:
1468 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
1469 break;
1470 default:
1471 as_fatal ("line %d: unknown relocation type: 0x%x",fixp->fx_line,fixp->fx_r_type);
1472 }
1473 return 0;
1474 }
1475
1476
1477 /* d30v_cleanup() is called after the assembler has finished parsing the input
1478 file or after a label is defined. Because the D30V assembler sometimes saves short
1479 instructions to see if it can package them with the next instruction, there may
1480 be a short instruction that still needs written. */
1481 int
1482 d30v_cleanup ()
1483 {
1484 segT seg;
1485 subsegT subseg;
1486
1487 if (prev_insn != -1)
1488 {
1489 seg = now_seg;
1490 subseg = now_subseg;
1491 subseg_set (prev_seg, prev_subseg);
1492 write_1_short (&prev_opcode, (long)prev_insn, fixups->next);
1493 subseg_set (seg, subseg);
1494 prev_insn = -1;
1495 }
1496 return 1;
1497 }
1498
1499
1500 static void
1501 d30v_number_to_chars (buf, value, n)
1502 char *buf; /* Return 'nbytes' of chars here. */
1503 long long value; /* The value of the bits. */
1504 int n; /* Number of bytes in the output. */
1505 {
1506 while (n--)
1507 {
1508 buf[n] = value & 0xff;
1509 value >>= 8;
1510 }
1511 }
1512
1513
1514 /* This function is called at the start of every line. */
1515 /* it checks to see if the first character is a '.' */
1516 /* which indicates the start of a pseudo-op. If it is, */
1517 /* then write out any unwritten instructions */
1518
1519 void
1520 d30v_start_line()
1521 {
1522 char *c = input_line_pointer;
1523
1524 while(isspace(*c))
1525 c++;
1526
1527 if (*c == '.')
1528 d30v_cleanup();
1529 }
1530
1531 static void
1532 check_size (value, bits, file, line)
1533 long value;
1534 int bits;
1535 char *file;
1536 int line;
1537 {
1538 int tmp, max;
1539
1540 if (value < 0)
1541 tmp = ~value;
1542 else
1543 tmp = value;
1544
1545 max = (1 << (bits - 1)) - 1;
1546
1547 if (tmp > max)
1548 as_bad_where (file, line,"value too large to fit in %d bits",bits);
1549
1550 return;
1551 }
This page took 0.088485 seconds and 5 git commands to generate.