* config/tc-mn10300.c (mn10300_insert_operand): Shift low part
[deliverable/binutils-gdb.git] / gas / config / tc-mn10300.c
1 /* tc-mn10300.c -- Assembler code for the Matsushita 10300
2
3 Copyright (C) 1996 Free Software Foundation.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include <stdio.h>
23 #include <ctype.h>
24 #include "as.h"
25 #include "subsegs.h"
26 #include "opcode/mn10300.h"
27 \f
28 /* Structure to hold information about predefined registers. */
29 struct reg_name
30 {
31 const char *name;
32 int value;
33 };
34
35 /* Generic assembler global variables which must be defined by all targets. */
36
37 /* Characters which always start a comment. */
38 const char comment_chars[] = "#";
39
40 /* Characters which start a comment at the beginning of a line. */
41 const char line_comment_chars[] = ";#";
42
43 /* Characters which may be used to separate multiple commands on a
44 single line. */
45 const char line_separator_chars[] = ";";
46
47 /* Characters which are used to indicate an exponent in a floating
48 point number. */
49 const char EXP_CHARS[] = "eE";
50
51 /* Characters which mean that a number is a floating point constant,
52 as in 0d1.0. */
53 const char FLT_CHARS[] = "dD";
54 \f
55
56 /* local functions */
57 static unsigned long mn10300
58 PARAMS ((unsigned long insn, const struct mn10300_operand *operand,
59 offsetT val, char *file, unsigned int line));
60 static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
61 static boolean register_name PARAMS ((expressionS *expressionP));
62 static boolean system_register_name PARAMS ((expressionS *expressionP));
63 static boolean cc_name PARAMS ((expressionS *expressionP));
64
65
66 /* fixups */
67 #define MAX_INSN_FIXUPS (5)
68 struct mn10300_fixup
69 {
70 expressionS exp;
71 int opindex;
72 bfd_reloc_code_real_type reloc;
73 };
74 struct mn10300_fixup fixups[MAX_INSN_FIXUPS];
75 static int fc;
76 \f
77 const char *md_shortopts = "";
78 struct option md_longopts[] = {
79 {NULL, no_argument, NULL, 0}
80 };
81 size_t md_longopts_size = sizeof(md_longopts);
82
83 /* The target specific pseudo-ops which we support. */
84 const pseudo_typeS md_pseudo_table[] =
85 {
86 { NULL, NULL, 0 }
87 };
88
89 /* Opcode hash table. */
90 static struct hash_control *mn10300_hash;
91
92 /* This table is sorted. Suitable for searching by a binary search. */
93 static const struct reg_name data_registers[] =
94 {
95 { "d0", 0 },
96 { "d1", 1 },
97 { "d2", 2 },
98 { "d3", 3 },
99 };
100 #define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
101
102 static const struct reg_name address_registers[] =
103 {
104 { "a0", 0 },
105 { "a1", 1 },
106 { "a2", 2 },
107 { "a3", 3 },
108 };
109 #define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
110
111 static const struct reg_name other_registers[] =
112 {
113 { "mdr", 0 },
114 { "psw", 0 },
115 { "sp", 0 },
116 };
117 #define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
118
119 /* reg_name_search does a binary search of the given register table
120 to see if "name" is a valid regiter name. Returns the register
121 number from the array on success, or -1 on failure. */
122
123 static int
124 reg_name_search (regs, regcount, name)
125 const struct reg_name *regs;
126 int regcount;
127 const char *name;
128 {
129 int middle, low, high;
130 int cmp;
131
132 low = 0;
133 high = regcount - 1;
134
135 do
136 {
137 middle = (low + high) / 2;
138 cmp = strcasecmp (name, regs[middle].name);
139 if (cmp < 0)
140 high = middle - 1;
141 else if (cmp > 0)
142 low = middle + 1;
143 else
144 return regs[middle].value;
145 }
146 while (low <= high);
147 return -1;
148 }
149
150
151 /* Summary of register_name().
152 *
153 * in: Input_line_pointer points to 1st char of operand.
154 *
155 * out: A expressionS.
156 * The operand may have been a register: in this case, X_op == O_register,
157 * X_add_number is set to the register number, and truth is returned.
158 * Input_line_pointer->(next non-blank) char after operand, or is in
159 * its original state.
160 */
161 static boolean
162 data_register_name (expressionP)
163 expressionS *expressionP;
164 {
165 int reg_number;
166 char *name;
167 char *start;
168 char c;
169
170 /* Find the spelling of the operand */
171 start = name = input_line_pointer;
172
173 c = get_symbol_end ();
174 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
175
176 /* look to see if it's in the register table */
177 if (reg_number >= 0)
178 {
179 expressionP->X_op = O_register;
180 expressionP->X_add_number = reg_number;
181
182 /* make the rest nice */
183 expressionP->X_add_symbol = NULL;
184 expressionP->X_op_symbol = NULL;
185 *input_line_pointer = c; /* put back the delimiting char */
186 return true;
187 }
188 else
189 {
190 /* reset the line as if we had not done anything */
191 *input_line_pointer = c; /* put back the delimiting char */
192 input_line_pointer = start; /* reset input_line pointer */
193 return false;
194 }
195 }
196
197 /* Summary of register_name().
198 *
199 * in: Input_line_pointer points to 1st char of operand.
200 *
201 * out: A expressionS.
202 * The operand may have been a register: in this case, X_op == O_register,
203 * X_add_number is set to the register number, and truth is returned.
204 * Input_line_pointer->(next non-blank) char after operand, or is in
205 * its original state.
206 */
207 static boolean
208 address_register_name (expressionP)
209 expressionS *expressionP;
210 {
211 int reg_number;
212 char *name;
213 char *start;
214 char c;
215
216 /* Find the spelling of the operand */
217 start = name = input_line_pointer;
218
219 c = get_symbol_end ();
220 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
221
222 /* look to see if it's in the register table */
223 if (reg_number >= 0)
224 {
225 expressionP->X_op = O_register;
226 expressionP->X_add_number = reg_number;
227
228 /* make the rest nice */
229 expressionP->X_add_symbol = NULL;
230 expressionP->X_op_symbol = NULL;
231 *input_line_pointer = c; /* put back the delimiting char */
232 return true;
233 }
234 else
235 {
236 /* reset the line as if we had not done anything */
237 *input_line_pointer = c; /* put back the delimiting char */
238 input_line_pointer = start; /* reset input_line pointer */
239 return false;
240 }
241 }
242
243 /* Summary of register_name().
244 *
245 * in: Input_line_pointer points to 1st char of operand.
246 *
247 * out: A expressionS.
248 * The operand may have been a register: in this case, X_op == O_register,
249 * X_add_number is set to the register number, and truth is returned.
250 * Input_line_pointer->(next non-blank) char after operand, or is in
251 * its original state.
252 */
253 static boolean
254 other_register_name (expressionP)
255 expressionS *expressionP;
256 {
257 int reg_number;
258 char *name;
259 char *start;
260 char c;
261
262 /* Find the spelling of the operand */
263 start = name = input_line_pointer;
264
265 c = get_symbol_end ();
266 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
267
268 /* look to see if it's in the register table */
269 if (reg_number >= 0)
270 {
271 expressionP->X_op = O_register;
272 expressionP->X_add_number = reg_number;
273
274 /* make the rest nice */
275 expressionP->X_add_symbol = NULL;
276 expressionP->X_op_symbol = NULL;
277 *input_line_pointer = c; /* put back the delimiting char */
278 return true;
279 }
280 else
281 {
282 /* reset the line as if we had not done anything */
283 *input_line_pointer = c; /* put back the delimiting char */
284 input_line_pointer = start; /* reset input_line pointer */
285 return false;
286 }
287 }
288
289 void
290 md_show_usage (stream)
291 FILE *stream;
292 {
293 fprintf(stream, "MN10300 options:\n\
294 none yet\n");
295 }
296
297 int
298 md_parse_option (c, arg)
299 int c;
300 char *arg;
301 {
302 return 0;
303 }
304
305 symbolS *
306 md_undefined_symbol (name)
307 char *name;
308 {
309 return 0;
310 }
311
312 char *
313 md_atof (type, litp, sizep)
314 int type;
315 char *litp;
316 int *sizep;
317 {
318 int prec;
319 LITTLENUM_TYPE words[4];
320 char *t;
321 int i;
322
323 switch (type)
324 {
325 case 'f':
326 prec = 2;
327 break;
328
329 case 'd':
330 prec = 4;
331 break;
332
333 default:
334 *sizep = 0;
335 return "bad call to md_atof";
336 }
337
338 t = atof_ieee (input_line_pointer, type, words);
339 if (t)
340 input_line_pointer = t;
341
342 *sizep = prec * 2;
343
344 for (i = prec - 1; i >= 0; i--)
345 {
346 md_number_to_chars (litp, (valueT) words[i], 2);
347 litp += 2;
348 }
349
350 return NULL;
351 }
352
353
354 void
355 md_convert_frag (abfd, sec, fragP)
356 bfd *abfd;
357 asection *sec;
358 fragS *fragP;
359 {
360 /* printf ("call to md_convert_frag \n"); */
361 abort ();
362 }
363
364 valueT
365 md_section_align (seg, addr)
366 asection *seg;
367 valueT addr;
368 {
369 int align = bfd_get_section_alignment (stdoutput, seg);
370 return ((addr + (1 << align) - 1) & (-1 << align));
371 }
372
373 void
374 md_begin ()
375 {
376 char *prev_name = "";
377 register const struct mn10300_opcode *op;
378
379 mn10300_hash = hash_new();
380
381 /* Insert unique names into hash table. The MN10300 instruction set
382 has many identical opcode names that have different opcodes based
383 on the operands. This hash table then provides a quick index to
384 the first opcode with a particular name in the opcode table. */
385
386 op = mn10300_opcodes;
387 while (op->name)
388 {
389 if (strcmp (prev_name, op->name))
390 {
391 prev_name = (char *) op->name;
392 hash_insert (mn10300_hash, op->name, (char *) op);
393 }
394 op++;
395 }
396 }
397
398 void
399 md_assemble (str)
400 char *str;
401 {
402 char *s;
403 struct mn10300_opcode *opcode;
404 struct mn10300_opcode *next_opcode;
405 const unsigned char *opindex_ptr;
406 int next_opindex;
407 unsigned long insn, extension, size;
408 char *f;
409 int i;
410 int match;
411 bfd_reloc_code_real_type reloc;
412
413 /* Get the opcode. */
414 for (s = str; *s != '\0' && ! isspace (*s); s++)
415 ;
416 if (*s != '\0')
417 *s++ = '\0';
418
419 /* find the first opcode with the proper name */
420 opcode = (struct mn10300_opcode *)hash_find (mn10300_hash, str);
421 if (opcode == NULL)
422 {
423 as_bad ("Unrecognized opcode: `%s'", str);
424 return;
425 }
426
427 str = s;
428 while (isspace (*str))
429 ++str;
430
431 input_line_pointer = str;
432
433 for(;;)
434 {
435 const char *errmsg = NULL;
436 int op_idx;
437 char *hold;
438 int extra_shift = 0;
439
440 fc = 0;
441 match = 0;
442 next_opindex = 0;
443 insn = opcode->opcode;
444 extension = 0;
445 for (op_idx = 1, opindex_ptr = opcode->operands;
446 *opindex_ptr != 0;
447 opindex_ptr++, op_idx++)
448 {
449 const struct mn10300_operand *operand;
450 expressionS ex;
451
452 if (next_opindex == 0)
453 {
454 operand = &mn10300_operands[*opindex_ptr];
455 }
456 else
457 {
458 operand = &mn10300_operands[next_opindex];
459 next_opindex = 0;
460 }
461
462 errmsg = NULL;
463
464 while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
465 ++str;
466
467 /* Gather the operand. */
468 hold = input_line_pointer;
469 input_line_pointer = str;
470
471 if (operand->flags & MN10300_OPERAND_PAREN)
472 {
473 if (*input_line_pointer != ')' && *input_line_pointer != '(')
474 {
475 input_line_pointer = hold;
476 str = hold;
477 goto error;
478 }
479 input_line_pointer++;
480 goto keep_going;
481 }
482 /* See if we can match the operands. */
483 else if (operand->flags & MN10300_OPERAND_DREG)
484 {
485 if (!data_register_name (&ex))
486 {
487 input_line_pointer = hold;
488 str = hold;
489 goto error;
490 }
491 }
492 else if (operand->flags & MN10300_OPERAND_AREG)
493 {
494 if (!address_register_name (&ex))
495 {
496 input_line_pointer = hold;
497 str = hold;
498 goto error;
499 }
500 }
501 else if (operand->flags & MN10300_OPERAND_SP)
502 {
503 char *start = input_line_pointer;
504 char c = get_symbol_end ();
505
506 if (strcmp (start, "sp") != 0)
507 {
508 *input_line_pointer = c;
509 input_line_pointer = hold;
510 str = hold;
511 goto error;
512 }
513 *input_line_pointer = c;
514 goto keep_going;
515 }
516 else if (operand->flags & MN10300_OPERAND_PSW)
517 {
518 char *start = input_line_pointer;
519 char c = get_symbol_end ();
520
521 if (strcmp (start, "psw") != 0)
522 {
523 *input_line_pointer = c;
524 input_line_pointer = hold;
525 str = hold;
526 goto error;
527 }
528 *input_line_pointer = c;
529 goto keep_going;
530 }
531 else if (operand->flags & MN10300_OPERAND_MDR)
532 {
533 char *start = input_line_pointer;
534 char c = get_symbol_end ();
535
536 if (strcmp (start, "mdr") != 0)
537 {
538 *input_line_pointer = c;
539 input_line_pointer = hold;
540 str = hold;
541 goto error;
542 }
543 *input_line_pointer = c;
544 goto keep_going;
545 }
546 else if (data_register_name (&ex))
547 {
548 input_line_pointer = hold;
549 str = hold;
550 goto error;
551 }
552 else if (address_register_name (&ex))
553 {
554 input_line_pointer = hold;
555 str = hold;
556 goto error;
557 }
558 else if (other_register_name (&ex))
559 {
560 input_line_pointer = hold;
561 str = hold;
562 goto error;
563 }
564 else if (*str == ')' || *str == '(')
565 {
566 input_line_pointer = hold;
567 str = hold;
568 goto error;
569 }
570 else
571 {
572 expression (&ex);
573 }
574
575 switch (ex.X_op)
576 {
577 case O_illegal:
578 errmsg = "illegal operand";
579 goto error;
580 case O_absent:
581 errmsg = "missing operand";
582 goto error;
583 case O_register:
584 if (operand->flags & (MN10300_OPERAND_DREG
585 | MN10300_OPERAND_AREG) == 0)
586 {
587 input_line_pointer = hold;
588 str = hold;
589 goto error;
590 }
591
592 if (opcode->format == FMT_D1 || opcode->format == FMT_S1)
593 extra_shift = 8;
594 else if (opcode->format == FMT_D2 || opcode->format == FMT_D4
595 || opcode->format == FMT_S2 || opcode->format == FMT_S4
596 || opcode->format == FMT_S6 || opcode->format == FMT_D5)
597 extra_shift = 16;
598 else
599 extra_shift = 0;
600
601 mn10300_insert_operand (&insn, &extension, operand,
602 ex.X_add_number, (char *) NULL,
603 0, extra_shift);
604
605 break;
606
607 case O_constant:
608 /* If this operand can be promoted, and it doesn't
609 fit into the allocated bitfield for this insn,
610 then promote it (ie this opcode does not match). */
611 if (operand->flags & MN10300_OPERAND_PROMOTE
612 && ! check_operand (insn, operand, ex.X_add_number))
613 {
614 input_line_pointer = hold;
615 str = hold;
616 goto error;
617 }
618
619 mn10300_insert_operand (&insn, &extension, operand,
620 ex.X_add_number, (char *) NULL,
621 0, 0);
622 break;
623
624 default:
625 /* If this operand can be promoted, then this opcode didn't
626 match since we can't know if it needed promotion! */
627 if (operand->flags & MN10300_OPERAND_PROMOTE)
628 {
629 input_line_pointer = hold;
630 str = hold;
631 goto error;
632 }
633
634 /* We need to generate a fixup for this expression. */
635 if (fc >= MAX_INSN_FIXUPS)
636 as_fatal ("too many fixups");
637 fixups[fc].exp = ex;
638 fixups[fc].opindex = *opindex_ptr;
639 fixups[fc].reloc = BFD_RELOC_UNUSED;
640 ++fc;
641 break;
642 }
643
644 keep_going:
645 str = input_line_pointer;
646 input_line_pointer = hold;
647
648 while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
649 ++str;
650
651 }
652
653 /* Make sure we used all the operands! */
654 if (*str != ',')
655 match = 1;
656
657 error:
658 if (match == 0)
659 {
660 next_opcode = opcode + 1;
661 if (next_opcode->opcode != 0 && !strcmp(next_opcode->name, opcode->name))
662 {
663 opcode = next_opcode;
664 continue;
665 }
666
667 as_bad ("%s", errmsg);
668 return;
669 }
670 break;
671 }
672
673 while (isspace (*str))
674 ++str;
675
676 if (*str != '\0')
677 as_bad ("junk at end of line: `%s'", str);
678
679 input_line_pointer = str;
680
681 /* Determine the size of the instruction. */
682 if (opcode->format == FMT_S0)
683 size = 1;
684
685 if (opcode->format == FMT_S1 || opcode->format == FMT_D0)
686 size = 2;
687
688 if (opcode->format == FMT_S2 || opcode->format == FMT_D1)
689 size = 3;
690
691 if (opcode->format == FMT_S4)
692 size = 5;
693
694 if (opcode->format == FMT_S6 || opcode->format == FMT_D5)
695 size = 7;
696
697 if (opcode->format == FMT_D2)
698 size = 4;
699
700 if (opcode->format == FMT_D4)
701 size = 6;
702
703 /* Write out the instruction. */
704
705 f = frag_more (size);
706 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
707 if (size > 4)
708 number_to_chars_bigendian (f + 4, extension, size - 4);
709 }
710
711
712 /* if while processing a fixup, a reloc really needs to be created */
713 /* then it is done here */
714
715 arelent *
716 tc_gen_reloc (seg, fixp)
717 asection *seg;
718 fixS *fixp;
719 {
720 arelent *reloc;
721 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
722 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
723 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
724 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
725 if (reloc->howto == (reloc_howto_type *) NULL)
726 {
727 as_bad_where (fixp->fx_file, fixp->fx_line,
728 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
729 return NULL;
730 }
731 reloc->addend = fixp->fx_addnumber;
732 /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
733 return reloc;
734 }
735
736 int
737 md_estimate_size_before_relax (fragp, seg)
738 fragS *fragp;
739 asection *seg;
740 {
741 return 0;
742 }
743
744 long
745 md_pcrel_from (fixp)
746 fixS *fixp;
747 {
748 if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
749 {
750 /* The symbol is undefined. Let the linker figure it out. */
751 return 0;
752 }
753 return fixp->fx_frag->fr_address + fixp->fx_where;
754 }
755
756 int
757 md_apply_fix3 (fixp, valuep, seg)
758 fixS *fixp;
759 valueT *valuep;
760 segT seg;
761 {
762 valueT value;
763 char *where;
764
765 fixp->fx_done = 1;
766 return 0;
767
768 if (fixp->fx_addsy == (symbolS *) NULL)
769 {
770 value = *valuep;
771 fixp->fx_done = 1;
772 }
773 else if (fixp->fx_pcrel)
774 value = *valuep;
775 else
776 {
777 value = fixp->fx_offset;
778 if (fixp->fx_subsy != (symbolS *) NULL)
779 {
780 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
781 value -= S_GET_VALUE (fixp->fx_subsy);
782 else
783 {
784 /* We don't actually support subtracting a symbol. */
785 as_bad_where (fixp->fx_file, fixp->fx_line,
786 "expression too complex");
787 }
788 }
789 }
790
791 /* printf("md_apply_fix: value=0x%x type=%d\n", value, fixp->fx_r_type); */
792
793 if ((int) fixp->fx_r_type >= (int) BFD_RELOC_UNUSED)
794 {
795 int opindex;
796 const struct mn10300_operand *operand;
797 char *where;
798 unsigned long insn, extension;
799
800 opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
801 operand = &mn10300_operands[opindex];
802
803 /* Fetch the instruction, insert the fully resolved operand
804 value, and stuff the instruction back again.
805
806 Note the instruction has been stored in little endian
807 format! */
808 where = fixp->fx_frag->fr_literal + fixp->fx_where;
809
810 insn = bfd_getl32((unsigned char *) where);
811 extension = 0;
812 mn10300_insert_operand (&insn, &extension, operand,
813 (offsetT) value, fixp->fx_file,
814 fixp->fx_line, 0);
815 bfd_putl32((bfd_vma) insn, (unsigned char *) where);
816
817 if (fixp->fx_done)
818 {
819 /* Nothing else to do here. */
820 return 1;
821 }
822
823 /* Determine a BFD reloc value based on the operand information.
824 We are only prepared to turn a few of the operands into relocs. */
825
826 {
827 as_bad_where(fixp->fx_file, fixp->fx_line,
828 "unresolved expression that must be resolved");
829 fixp->fx_done = 1;
830 return 1;
831 }
832 }
833 else if (fixp->fx_done)
834 {
835 /* We still have to insert the value into memory! */
836 where = fixp->fx_frag->fr_literal + fixp->fx_where;
837 if (fixp->fx_size == 1)
838 *where = value & 0xff;
839 if (fixp->fx_size == 2)
840 bfd_putl16(value & 0xffff, (unsigned char *) where);
841 if (fixp->fx_size == 4)
842 bfd_putl32(value, (unsigned char *) where);
843 }
844
845 fixp->fx_addnumber = value;
846 return 1;
847 }
848
849 /* Insert an operand value into an instruction. */
850
851 static void
852 mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift)
853 unsigned long *insnp;
854 unsigned long *extensionp;
855 const struct mn10300_operand *operand;
856 offsetT val;
857 char *file;
858 unsigned int line;
859 unsigned int shift;
860 {
861 if (operand->bits != 32)
862 {
863 long min, max;
864 offsetT test;
865
866 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
867 {
868 max = (1 << (operand->bits - 1)) - 1;
869 min = - (1 << (operand->bits - 1));
870 }
871 else
872 {
873 max = (1 << operand->bits) - 1;
874 min = 0;
875 }
876
877 test = val;
878
879
880 if (test < (offsetT) min || test > (offsetT) max)
881 {
882 const char *err =
883 "operand out of range (%s not between %ld and %ld)";
884 char buf[100];
885
886 sprint_value (buf, test);
887 if (file == (char *) NULL)
888 as_warn (err, buf, min, max);
889 else
890 as_warn_where (file, line, err, buf, min, max);
891 }
892 }
893
894 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
895 {
896 *insnp |= (val >> 16) & 0xffff;
897 *extensionp |= (val & 0xffff) << operand->shift;
898 }
899 else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0)
900 {
901 *insnp |= (((long) val & ((1 << operand->bits) - 1))
902 << (operand->shift + shift));
903
904 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
905 *insnp |= (((long) val & ((1 << operand->bits) - 1))
906 << (operand->shift + shift + 2));
907 }
908 else
909 {
910 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
911 << (operand->shift + shift));
912
913 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
914 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
915 << (operand->shift + shift + 2));
916 }
917 }
918
919 static unsigned long
920 check_operand (insn, operand, val)
921 unsigned long insn;
922 const struct mn10300_operand *operand;
923 offsetT val;
924 {
925 if (operand->bits != 32)
926 {
927 long min, max;
928 offsetT test;
929
930 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
931 {
932 max = (1 << (operand->bits - 1)) - 1;
933 min = - (1 << (operand->bits - 1));
934 }
935 else
936 {
937 max = (1 << operand->bits) - 1;
938 min = 0;
939 }
940
941 test = val;
942
943
944 if (test < (offsetT) min || test > (offsetT) max)
945 return 0;
946 else
947 return 1;
948 }
949 return 1;
950 }
This page took 0.049208 seconds and 5 git commands to generate.