Assign correct reloc value to size 1 constant valued fixes.
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
CommitLineData
252b5132 1/* tc-h8300.c -- Assemble code for the Hitachi H8/300
4132022d
AM
2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 2000
3 Free Software Foundation.
252b5132
RH
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 the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22
23/*
24 Written By Steve Chamberlain
25 sac@cygnus.com
26 */
27
28#include <stdio.h>
29#include "as.h"
30#include "subsegs.h"
31#include "bfd.h"
32#define DEFINE_TABLE
33#define h8_opcodes ops
34#include "opcode/h8300.h"
35#include <ctype.h>
36
37const char comment_chars[] =
38{';', 0};
39const char line_separator_chars[] =
40{0};
41const char line_comment_chars[] = "#";
42
43/* This table describes all the machine specific pseudo-ops the assembler
44 has to support. The fields are:
45 pseudo-op name without dot
46 function to call to execute this pseudo-op
47 Integer arg to pass to the function
48 */
49
50void cons ();
51
52int Hmode;
53int Smode;
54#define PSIZE (Hmode ? L_32 : L_16)
55#define DMODE (L_16)
56#define DSYMMODE (Hmode ? L_24 : L_16)
57int bsize = L_8; /* default branch displacement */
58
59
60void
61h8300hmode ()
62{
63 Hmode = 1;
64 Smode = 0;
65}
66
67void
68h8300smode ()
69{
70 Smode = 1;
71 Hmode = 1;
72}
73void
74sbranch (size)
75 int size;
76{
77 bsize = size;
78}
79
80static void pint ()
81{
82 cons (Hmode ? 4 : 2);
83}
84
85const pseudo_typeS md_pseudo_table[] =
86{
87
88 {"h8300h", h8300hmode, 0},
89 {"h8300s", h8300smode, 0},
90 {"sbranch", sbranch, L_8},
91 {"lbranch", sbranch, L_16},
92
93 {"int", pint, 0},
94 {"data.b", cons, 1},
95 {"data.w", cons, 2},
96 {"data.l", cons, 4},
97 {"form", listing_psize, 0},
98 {"heading", listing_title, 0},
99 {"import", s_ignore, 0},
100 {"page", listing_eject, 0},
101 {"program", s_ignore, 0},
102 {0, 0, 0}
103};
104
105const int md_reloc_size;
106
107const char EXP_CHARS[] = "eE";
108
109/* Chars that mean this number is a floating point constant */
110/* As in 0f12.456 */
111/* or 0d1.2345e12 */
112const char FLT_CHARS[] = "rRsSfFdDxXpP";
113
114static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
115
116/*
117 This function is called once, at assembler startup time. This should
118 set up all the tables, etc that the MD part of the assembler needs
119 */
120
121
122void
123md_begin ()
124{
125 struct h8_opcode *opcode;
126 char prev_buffer[100];
127 int idx = 0;
128
129 opcode_hash_control = hash_new ();
130 prev_buffer[0] = 0;
131
132 for (opcode = h8_opcodes; opcode->name; opcode++)
133 {
134 /* Strip off any . part when inserting the opcode and only enter
135 unique codes into the hash table
136 */
137 char *src = opcode->name;
138 unsigned int len = strlen (src);
139 char *dst = malloc (len + 1);
140 char *buffer = dst;
141
142 opcode->size = 0;
143 while (*src)
144 {
145 if (*src == '.')
146 {
147 src++;
148 opcode->size = *src;
149 break;
150 }
151 *dst++ = *src++;
152 }
153 *dst++ = 0;
154 if (strcmp (buffer, prev_buffer))
155 {
156 hash_insert (opcode_hash_control, buffer, (char *) opcode);
157 strcpy (prev_buffer, buffer);
158 idx++;
159 }
160 opcode->idx = idx;
161
162
163 /* Find the number of operands */
164 opcode->noperands = 0;
165 while (opcode->args.nib[opcode->noperands] != E)
166 opcode->noperands++;
167 /* Find the length of the opcode in bytes */
168 opcode->length = 0;
169 while (opcode->data.nib[opcode->length * 2] != E)
170 opcode->length++;
171 }
172
173 linkrelax = 1;
174}
175
176
177struct h8_exp
178{
179 char *e_beg;
180 char *e_end;
181 expressionS e_exp;
182};
183int dispreg;
184int opsize; /* Set when a register size is seen */
185
186
187struct h8_op
188{
189 op_type mode;
190 unsigned reg;
191 expressionS exp;
192};
193
194/*
195 parse operands
196 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
197 r0l,r0h,..r7l,r7h
198 @WREG
199 @WREG+
200 @-WREG
201 #const
202 ccr
203*/
204
205/* try and parse a reg name, returns number of chars consumed */
206int
207parse_reg (src, mode, reg, direction)
208 char *src;
209 op_type *mode;
210 unsigned int *reg;
211 int direction;
212
213{
214 char *end;
215 int len;
216
217 /* Cribbed from get_symbol_end(). */
218 if (!is_name_beginner (*src) || *src == '\001')
219 return 0;
220 end = src+1;
221 while (is_part_of_name (*end) || *end == '\001')
222 end++;
223 len = end - src;
224
225 if (len == 2 && src[0] == 's' && src[1] == 'p')
226 {
227 *mode = PSIZE | REG | direction;
228 *reg = 7;
229 return len;
230 }
231 if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
232 {
233 *mode = CCR;
234 *reg = 0;
235 return len;
236 }
237 if (len == 3 && src[0] == 'e' && src[1] == 'x' && src[2] == 'r')
238 {
239 *mode = EXR;
240 *reg = 0;
241 return len;
242 }
243 if (len == 2 && src[0] == 'f' && src[1] == 'p')
244 {
245 *mode = PSIZE | REG | direction;
246 *reg = 6;
247 return len;
248 }
249 if (len == 3 && src[0] == 'e' && src[1] == 'r'
250 && src[2] >= '0' && src[2] <= '7')
251 {
252 *mode = L_32 | REG | direction;
253 *reg = src[2] - '0';
254 if (!Hmode)
255 as_warn (_("Reg not valid for H8/300"));
256 return len;
257 }
258 if (len == 2 && src[0] == 'e' && src[1] >= '0' && src[1] <= '7')
259 {
260 *mode = L_16 | REG | direction;
261 *reg = src[1] - '0' + 8;
262 if (!Hmode)
263 as_warn (_("Reg not valid for H8/300"));
264 return len;
265 }
266
267 if (src[0] == 'r')
268 {
269 if (src[1] >= '0' && src[1] <= '7')
270 {
271 if (len == 3 && src[2] == 'l')
272 {
273 *mode = L_8 | REG | direction;
274 *reg = (src[1] - '0') + 8;
275 return len;
276 }
277 if (len == 3 && src[2] == 'h')
278 {
279 *mode = L_8 | REG | direction;
280 *reg = (src[1] - '0');
281 return len;
282 }
283 if (len == 2)
284 {
285 *mode = L_16 | REG | direction;
286 *reg = (src[1] - '0');
287 return len;
288 }
289 }
290 }
291
292 return 0;
293}
294
295char *
296parse_exp (s, op)
297 char *s;
298 expressionS * op;
299{
300 char *save = input_line_pointer;
301 char *new;
302
303 input_line_pointer = s;
304 expression (op);
305 if (op->X_op == O_absent)
306 as_bad (_("missing operand"));
307 new = input_line_pointer;
308 input_line_pointer = save;
309 return new;
310}
311
312static char *
313skip_colonthing (ptr, exp, mode)
314 char *ptr;
dbbc7809 315 expressionS *exp ATTRIBUTE_UNUSED;
252b5132
RH
316 int *mode;
317{
318 if (*ptr == ':')
319 {
320 ptr++;
321 *mode &= ~SIZE;
322 if (*ptr == '8')
323 {
324 ptr++;
325 /* ff fill any 8 bit quantity */
326 /* exp->X_add_number -= 0x100;*/
327 *mode |= L_8;
328 }
329 else
330 {
331 if (*ptr == '2')
332 {
333 *mode |= L_24;
334 }
335 else if (*ptr == '3')
336 {
337 *mode |= L_32;
338 }
339 else if (*ptr == '1')
340 {
341 *mode |= L_16;
342 }
343 while (isdigit (*ptr))
344 ptr++;
345 }
346 }
347 return ptr;
348}
349
350/* The many forms of operand:
351
352 Rn Register direct
353 @Rn Register indirect
354 @(exp[:16], Rn) Register indirect with displacement
355 @Rn+
356 @-Rn
357 @aa:8 absolute 8 bit
358 @aa:16 absolute 16 bit
359 @aa absolute 16 bit
360
361 #xx[:size] immediate data
362 @(exp:[8], pc) pc rel
363 @@aa[:8] memory indirect
364
365 */
366
367char *
368colonmod24 (op, src)
369 struct h8_op *op;
370 char *src;
371
372{
373 int mode = 0;
374 src = skip_colonthing (src, &op->exp, &mode);
375
376 if (!mode)
377 {
378 /* Choose a default mode */
379 if (op->exp.X_add_number < -32768
380 || op->exp.X_add_number > 32767)
381 {
382 if (Hmode)
383 mode = L_24;
384 else
385 mode = L_16;
386 }
387 else if (op->exp.X_add_symbol
388 || op->exp.X_op_symbol)
389 mode = DSYMMODE;
390 else
391 mode = DMODE;
392 }
393 op->mode |= mode;
394 return src;
395
396}
397
398
399static void
400get_operand (ptr, op, dst, direction)
401 char **ptr;
402 struct h8_op *op;
dbbc7809 403 unsigned int dst ATTRIBUTE_UNUSED;
252b5132
RH
404 int direction;
405{
406 char *src = *ptr;
407 op_type mode;
408 unsigned int num;
409 unsigned int len;
410
411 op->mode = E;
412
413 /* Gross. Gross. ldm and stm have a format not easily handled
414 by get_operand. We deal with it explicitly here. */
415 if (src[0] == 'e' && src[1] == 'r' && isdigit(src[2])
416 && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit(src[6]))
417 {
418 int low, high;
419
420 low = src[2] - '0';
421 high = src[6] - '0';
422
423 if (high < low)
424 as_bad (_("Invalid register list for ldm/stm\n"));
425
426 if (low % 2)
427 as_bad (_("Invalid register list for ldm/stm\n"));
428
429 if (high - low > 3)
430 as_bad (_("Invalid register list for ldm/stm\n"));
431
432 if (high - low != 1
433 && low % 4)
434 as_bad (_("Invalid register list for ldm/stm\n"));
435
436 /* Even sicker. We encode two registers into op->reg. One
437 for the low register to save, the other for the high
438 register to save; we also set the high bit in op->reg
439 so we know this is "very special". */
440 op->reg = 0x80000000 | (high << 8) | low;
441 op->mode = REG;
442 *ptr = src + 7;
443 return;
444 }
445
446 len = parse_reg (src, &op->mode, &op->reg, direction);
447 if (len)
448 {
449 *ptr = src + len;
450 return;
451 }
452
453 if (*src == '@')
454 {
455 src++;
456 if (*src == '@')
457 {
458 src++;
459 src = parse_exp (src, &op->exp);
460
461 src = skip_colonthing (src, &op->exp, &op->mode);
462
463 *ptr = src;
464
465 op->mode = MEMIND;
466 return;
467
468 }
469
470
471 if (*src == '-')
472 {
473 src++;
474 len = parse_reg (src, &mode, &num, direction);
475 if (len == 0)
476 {
477 /* Oops, not a reg after all, must be ordinary exp */
478 src--;
479 /* must be a symbol */
480 op->mode = ABS | PSIZE | direction;
481 *ptr = skip_colonthing (parse_exp (src, &op->exp),
482 &op->exp, &op->mode);
483
484 return;
485
486
487 }
488
489
490 if ((mode & SIZE) != PSIZE)
491 as_bad (_("Wrong size pointer register for architecture."));
492 op->mode = RDDEC;
493 op->reg = num;
494 *ptr = src + len;
495 return;
496 }
497 if (*src == '(')
498 {
499 /* Disp */
500 src++;
501
502 /* Start off assuming a 16 bit offset */
503
504
505 src = parse_exp (src, &op->exp);
506
507 src = colonmod24 (op, src);
508
509 if (*src == ')')
510 {
511 src++;
512 op->mode |= ABS | direction;
513 *ptr = src;
514 return;
515 }
516
517 if (*src != ',')
518 {
519 as_bad (_("expected @(exp, reg16)"));
520 return;
521
522 }
523 src++;
524
525 len = parse_reg (src, &mode, &op->reg, direction);
526 if (len == 0 || !(mode & REG))
527 {
528 as_bad (_("expected @(exp, reg16)"));
529 return;
530 }
531 op->mode |= DISP | direction;
532 dispreg = op->reg;
533 src += len;
534 src = skip_colonthing (src, &op->exp, &op->mode);
535
536 if (*src != ')' && '(')
537 {
538 as_bad (_("expected @(exp, reg16)"));
539 return;
540 }
541 *ptr = src + 1;
542
543 return;
544 }
545 len = parse_reg (src, &mode, &num, direction);
546
547 if (len)
548 {
549 src += len;
550 if (*src == '+')
551 {
552 src++;
553 if ((mode & SIZE) != PSIZE)
554 as_bad (_("Wrong size pointer register for architecture."));
555 op->mode = RSINC;
556 op->reg = num;
557 *ptr = src;
558 return;
559 }
560 if ((mode & SIZE) != PSIZE)
561 as_bad (_("Wrong size pointer register for architecture."));
562
563 op->mode = direction | IND | PSIZE;
564 op->reg = num;
565 *ptr = src;
566
567 return;
568 }
569 else
570 {
571 /* must be a symbol */
572
573 op->mode = ABS | direction;
574 src = parse_exp (src, &op->exp);
575
576 *ptr = colonmod24 (op, src);
577
578 return;
579 }
580 }
581
582
583 if (*src == '#')
584 {
585 src++;
586 op->mode = IMM;
587 src = parse_exp (src, &op->exp);
588 *ptr = skip_colonthing (src, &op->exp, &op->mode);
589
590 return;
591 }
592 else if (strncmp (src, "mach", 4) == 0
593 || strncmp (src, "macl", 4) == 0)
594 {
595 op->reg = src[3] == 'l';
596 op->mode = MACREG;
597 *ptr = src + 4;
598 return;
599 }
600 else
601 {
602 src = parse_exp (src, &op->exp);
603 /* Trailing ':' size ? */
604 if (*src == ':')
605 {
606 if (src[1] == '1' && src[2] == '6')
607 {
608 op->mode = PCREL | L_16;
609 src += 3;
610 }
611 else if (src[1] == '8')
612 {
613 op->mode = PCREL | L_8;
614 src += 2;
615 }
616 else
617 {
618 as_bad (_("expect :8 or :16 here"));
619 }
620 }
621 else
622 {
623 op->mode = PCREL | bsize;
624 }
625 *ptr = src;
626 }
627}
628
629
630static
631char *
632get_operands (noperands, op_end, operand)
633 unsigned int noperands;
634 char *op_end;
635 struct h8_op *operand;
636{
637 char *ptr = op_end;
638
639 switch (noperands)
640 {
641 case 0:
642 operand[0].mode = 0;
643 operand[1].mode = 0;
644 break;
645
646 case 1:
647 ptr++;
648 get_operand (&ptr, operand + 0, 0, SRC);
649 if (*ptr == ',')
650 {
651 ptr++;
652 get_operand (&ptr, operand + 1, 1, DST);
653 }
654 else
655 {
656 operand[1].mode = 0;
657 }
658
659 break;
660 case 2:
661 ptr++;
662 get_operand (&ptr, operand + 0, 0, SRC);
663 if (*ptr == ',')
664 ptr++;
665 get_operand (&ptr, operand + 1, 1, DST);
666 break;
667
668 default:
669 abort ();
670 }
671
672
673 return ptr;
674}
675
676/* Passed a pointer to a list of opcodes which use different
677 addressing modes, return the opcode which matches the opcodes
678 provided
679 */
680static
681struct h8_opcode *
682get_specific (opcode, operands, size)
683 struct h8_opcode *opcode;
684 struct h8_op *operands;
685 int size;
686{
687 struct h8_opcode *this_try = opcode;
688 int found = 0;
689
690 unsigned int this_index = opcode->idx;
691
692 /* There's only one ldm/stm and it's easier to just
693 get out quick for them. */
694 if (strcmp (opcode->name, "stm.l") == 0
695 || strcmp (opcode->name, "ldm.l") == 0)
696 return this_try;
697
698 while (this_index == opcode->idx && !found)
699 {
700 found = 1;
701
702 this_try = opcode++;
703 if (this_try->noperands == 0)
704 {
705 int this_size;
706
707 this_size = this_try->how & SN;
708 if (this_size != size && (this_size != SB || size != SN))
709 found = 0;
710 }
711 else
712 {
713 unsigned int i;
714
715 for (i = 0; i < this_try->noperands && found; i++)
716 {
717 op_type op = this_try->args.nib[i];
718 int x = operands[i].mode;
719
720 if ((op & (DISP | REG)) == (DISP | REG)
721 && ((x & (DISP | REG)) == (DISP | REG)))
722 {
723 dispreg = operands[i].reg;
724 }
725 else if (op & REG)
726 {
727 if (!(x & REG))
728 found = 0;
729
730 if (x & L_P)
731 x = (x & ~L_P) | (Hmode ? L_32 : L_16);
732 if (op & L_P)
733 op = (op & ~L_P) | (Hmode ? L_32 : L_16);
734
735 opsize = op & SIZE;
736
737 /* The size of the reg is v important */
738 if ((op & SIZE) != (x & SIZE))
739 found = 0;
740 }
741 else if ((op & ABSJMP) && (x & ABS))
742 {
743 operands[i].mode &= ~ABS;
744 operands[i].mode |= ABSJMP;
745 /* But it may not be 24 bits long */
746 if (!Hmode)
747 {
748 operands[i].mode &= ~SIZE;
749 operands[i].mode |= L_16;
750 }
751 }
752 else if ((op & (KBIT | DBIT)) && (x & IMM))
753 {
754 /* This is ok if the immediate value is sensible */
755 }
756 else if (op & PCREL)
757 {
758 /* The size of the displacement is important */
759 if ((op & SIZE) != (x & SIZE))
760 found = 0;
761 }
762 else if ((op & (DISP | IMM | ABS))
763 && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS)))
764 {
765 /* Promote a L_24 to L_32 if it makes us match. */
766 if ((x & L_24) && (op & L_32))
767 {
768 x &= ~L_24;
769 x |= L_32;
770 }
771 /* Promote an L8 to L_16 if it makes us match. */
772 if (op & ABS && op & L_8 && op & DISP)
773 {
774 if (x & L_16)
775 found= 1;
776 }
777 else if ((x & SIZE) != 0
778 && ((op & SIZE) != (x & SIZE)))
779 found = 0;
780 }
781 else if ((op & MACREG) != (x & MACREG))
782 {
783 found = 0;
784 }
785 else if ((op & MODE) != (x & MODE))
786 {
787 found = 0;
788 }
789 }
790 }
791 }
792 if (found)
793 return this_try;
794 else
795 return 0;
796}
797
798static void
799check_operand (operand, width, string)
800 struct h8_op *operand;
801 unsigned int width;
802 char *string;
803{
804 if (operand->exp.X_add_symbol == 0
805 && operand->exp.X_op_symbol == 0)
806 {
807
808 /* No symbol involved, let's look at offset, it's dangerous if any of
809 the high bits are not 0 or ff's, find out by oring or anding with
810 the width and seeing if the answer is 0 or all fs*/
811
812 if ((operand->exp.X_add_number & ~width) != 0 &&
813 (operand->exp.X_add_number | width) != (~0))
814 {
815 if (width == 255
816 && (operand->exp.X_add_number & 0xff00) == 0xff00)
817 {
818 /* Just ignore this one - which happens when trying to
819 fit a 16 bit address truncated into an 8 bit address
820 of something like bset. */
821 }
822 else
823 {
824 as_warn (_("operand %s0x%lx out of range."), string,
825 (unsigned long) operand->exp.X_add_number);
826 }
827 }
828 }
829
830}
831
832/* RELAXMODE has one of 3 values:
833
834 0 Output a "normal" reloc, no relaxing possible for this insn/reloc
835
836 1 Output a relaxable 24bit absolute mov.w address relocation
837 (may relax into a 16bit absolute address).
838
839 2 Output a relaxable 16/24 absolute mov.b address relocation
840 (may relax into an 8bit absolute address). */
841
842static void
843do_a_fix_imm (offset, operand, relaxmode)
844 int offset;
845 struct h8_op *operand;
846 int relaxmode;
847{
848 int idx;
849 int size;
850 int where;
851
852
853 char *t = operand->mode & IMM ? "#" : "@";
854
855 if (operand->exp.X_add_symbol == 0)
856 {
857 char *bytes = frag_now->fr_literal + offset;
858 switch (operand->mode & SIZE)
859 {
860 case L_2:
861 check_operand (operand, 0x3, t);
862 bytes[0] |= (operand->exp.X_add_number) << 4;
863 break;
864 case L_3:
865 check_operand (operand, 0x7, t);
866 bytes[0] |= (operand->exp.X_add_number) << 4;
867 break;
868 case L_8:
869 check_operand (operand, 0xff, t);
870 bytes[0] = operand->exp.X_add_number;
871 break;
872 case L_16:
873 check_operand (operand, 0xffff, t);
874 bytes[0] = operand->exp.X_add_number >> 8;
875 bytes[1] = operand->exp.X_add_number >> 0;
876 break;
877 case L_24:
878 check_operand (operand, 0xffffff, t);
879 bytes[0] = operand->exp.X_add_number >> 16;
880 bytes[1] = operand->exp.X_add_number >> 8;
881 bytes[2] = operand->exp.X_add_number >> 0;
882 break;
883
884 case L_32:
885 /* This should be done with bfd */
886 bytes[0] = operand->exp.X_add_number >> 24;
887 bytes[1] = operand->exp.X_add_number >> 16;
888 bytes[2] = operand->exp.X_add_number >> 8;
889 bytes[3] = operand->exp.X_add_number >> 0;
4132022d
AM
890 if (relaxmode != 0)
891 {
892 idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
893 fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
894 }
252b5132
RH
895 break;
896 }
897
898 }
899 else
900 {
901 switch (operand->mode & SIZE)
902 {
903
904 case L_24:
905 case L_32:
906 size = 4;
907 where = (operand->mode & SIZE) == L_24 ? -1 : 0;
908 if (relaxmode == 2)
909 idx = R_MOV24B1;
910 else if (relaxmode == 1)
911 idx = R_MOVL1;
912 else
913 idx = R_RELLONG;
914 break;
915 default:
916 as_bad(_("Can't work out size of operand.\n"));
917 case L_16:
918 size = 2;
919 where = 0;
920 if (relaxmode == 2)
921 idx = R_MOV16B1;
922 else
923 idx = R_RELWORD;
4132022d
AM
924 operand->exp.X_add_number =
925 ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
252b5132
RH
926 break;
927 case L_8:
928 size = 1;
929 where = 0;
930 idx = R_RELBYTE;
4132022d
AM
931 operand->exp.X_add_number =
932 ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
252b5132
RH
933 }
934
935 fix_new_exp (frag_now,
936 offset + where,
937 size,
938 &operand->exp,
939 0,
940 idx);
941 }
942
943}
944
945/* Now we know what sort of opcodes it is, lets build the bytes -
946 */
947static void
948build_bytes (this_try, operand)
949 struct h8_opcode *this_try;
950 struct h8_op *operand;
951{
952 unsigned int i;
953
954 char *output = frag_more (this_try->length);
955 op_type *nibble_ptr = this_try->data.nib;
956 op_type c;
957 unsigned int nibble_count = 0;
958 int absat;
959 int immat;
960 int nib;
961 int movb = 0;
962 char asnibbles[30];
963 char *p = asnibbles;
964
965 if (!(this_try->inbase || Hmode))
966 as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
967 this_try->name);
968
969 while (*nibble_ptr != E)
970 {
971 int d;
972 c = *nibble_ptr++;
973
974 d = (c & (DST | SRC_IN_DST)) != 0;
975
976 if (c < 16)
977 {
978 nib = c;
979 }
980 else
981 {
982
983 if (c & (REG | IND | INC | DEC))
984 {
985 nib = operand[d].reg;
986 }
987 else if ((c & DISPREG) == (DISPREG))
988 {
989 nib = dispreg;
990 }
991 else if (c & ABS )
992 {
993 operand[d].mode = c;
994 absat = nibble_count / 2;
995 nib = 0;
996 }
997 else if (c & (IMM | PCREL | ABS | ABSJMP | DISP))
998 {
999 operand[d].mode = c;
1000 immat = nibble_count / 2;
1001 nib = 0;
1002 }
1003 else if (c & IGNORE)
1004 {
1005 nib = 0;
1006 }
1007 else if (c & DBIT)
1008 {
1009 switch (operand[0].exp.X_add_number)
1010 {
1011 case 1:
1012 nib = c;
1013 break;
1014 case 2:
1015 nib = 0x8 | c;
1016 break;
1017 default:
1018 as_bad (_("Need #1 or #2 here"));
1019 }
1020 }
1021 else if (c & KBIT)
1022 {
1023 switch (operand[0].exp.X_add_number)
1024 {
1025 case 1:
1026 nib = 0;
1027 break;
1028 case 2:
1029 nib = 8;
1030 break;
1031 case 4:
1032 if (!Hmode)
1033 as_warn (_("#4 not valid on H8/300."));
1034 nib = 9;
1035 break;
1036
1037 default:
1038 as_bad (_("Need #1 or #2 here"));
1039 break;
1040 }
1041 /* stop it making a fix */
1042 operand[0].mode = 0;
1043 }
1044
1045 if (c & MEMRELAX)
1046 {
1047 operand[d].mode |= MEMRELAX;
1048 }
1049
1050 if (c & B31)
1051 {
1052 nib |= 0x8;
1053 }
1054
1055 if (c & MACREG)
1056 {
1057 nib = 2 + operand[d].reg;
1058 }
1059 }
1060 nibble_count++;
1061
1062 *p++ = nib;
1063 }
1064
1065 /* Disgusting. Why, oh why didn't someone ask us for advice
1066 on the assembler format. */
1067 if (strcmp (this_try->name, "stm.l") == 0
1068 || strcmp (this_try->name, "ldm.l") == 0)
1069 {
1070 int high, low;
1071 high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf;
1072 low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf;
1073
1074 asnibbles[2] = high - low;
1075 asnibbles[7] = (this_try->name[0] == 'l') ? high : low;
1076 }
1077
1078 for (i = 0; i < this_try->length; i++)
1079 {
1080 output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
1081 }
1082
1083 /* Note if this is a movb instruction -- there's a special relaxation
1084 which only applies to them. */
1085 if (strcmp (this_try->name, "mov.b") == 0)
1086 movb = 1;
1087
1088 /* output any fixes */
1089 for (i = 0; i < 2; i++)
1090 {
1091 int x = operand[i].mode;
1092
1093 if (x & (IMM | DISP))
1094 {
1095 do_a_fix_imm (output - frag_now->fr_literal + immat,
1096 operand + i, x & MEMRELAX != 0);
1097 }
1098 else if (x & ABS)
1099 {
1100 do_a_fix_imm (output - frag_now->fr_literal + absat,
1101 operand + i, x & MEMRELAX ? movb + 1 : 0);
1102 }
1103 else if (x & PCREL)
1104 {
1105 int size16 = x & L_16;
1106 int where = size16 ? 2 : 1;
1107 int size = size16 ? 2 : 1;
1108 int type = size16 ? R_PCRWORD : R_PCRBYTE;
1109
1110 check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
1111
1112 if (operand[i].exp.X_add_number & 1)
1113 {
1114 as_warn (_("branch operand has odd offset (%lx)\n"),
1115 (unsigned long) operand->exp.X_add_number);
1116 }
1117
1118 operand[i].exp.X_add_number -= 1;
4132022d
AM
1119 operand[i].exp.X_add_number =
1120 ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
252b5132
RH
1121
1122 fix_new_exp (frag_now,
1123 output - frag_now->fr_literal + where,
1124 size,
1125 &operand[i].exp,
1126 1,
1127 type);
1128 }
1129 else if (x & MEMIND)
1130 {
1131
1132 check_operand (operand + i, 0xff, "@@");
1133 fix_new_exp (frag_now,
1134 output - frag_now->fr_literal + 1,
1135 1,
1136 &operand[i].exp,
1137 0,
1138 R_MEM_INDIRECT);
1139 }
1140 else if (x & ABSJMP)
1141 {
1142 /* This jmp may be a jump or a branch */
1143
1144 check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");
1145 if (operand[i].exp.X_add_number & 1)
1146 {
1147 as_warn (_("branch operand has odd offset (%lx)\n"),
1148 (unsigned long) operand->exp.X_add_number);
1149 }
1150 if (!Hmode)
4132022d
AM
1151 operand[i].exp.X_add_number =
1152 ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
252b5132
RH
1153 fix_new_exp (frag_now,
1154 output - frag_now->fr_literal,
1155 4,
1156 &operand[i].exp,
1157 0,
1158 R_JMPL1);
1159 }
1160 }
1161
1162}
1163
1164/*
1165 try and give an intelligent error message for common and simple to
1166 detect errors
1167 */
1168
1169static void
1170clever_message (opcode, operand)
1171 struct h8_opcode *opcode;
1172 struct h8_op *operand;
1173{
1174 /* Find out if there was more than one possible opccode */
1175
1176 if ((opcode + 1)->idx != opcode->idx)
1177 {
1178 unsigned int argn;
1179
1180 /* Only one opcode of this flavour, try and guess which operand
1181 didn't match */
1182 for (argn = 0; argn < opcode->noperands; argn++)
1183 {
1184 switch (opcode->args.nib[argn])
1185 {
1186 case RD16:
1187 if (operand[argn].mode != RD16)
1188 {
1189 as_bad (_("destination operand must be 16 bit register"));
1190 return;
1191
1192 }
1193 break;
1194
1195 case RS8:
1196
1197 if (operand[argn].mode != RS8)
1198 {
1199 as_bad (_("source operand must be 8 bit register"));
1200 return;
1201 }
1202 break;
1203
1204 case ABS16DST:
1205 if (operand[argn].mode != ABS16DST)
1206 {
1207 as_bad (_("destination operand must be 16bit absolute address"));
1208 return;
1209 }
1210 break;
1211 case RD8:
1212 if (operand[argn].mode != RD8)
1213 {
1214 as_bad (_("destination operand must be 8 bit register"));
1215 return;
1216 }
1217 break;
1218
1219
1220 case ABS16SRC:
1221 if (operand[argn].mode != ABS16SRC)
1222 {
1223 as_bad (_("source operand must be 16bit absolute address"));
1224 return;
1225 }
1226 break;
1227
1228 }
1229 }
1230 }
1231 as_bad (_("invalid operands"));
1232}
1233
1234/* This is the guts of the machine-dependent assembler. STR points to a
1235 machine dependent instruction. This funciton is supposed to emit
1236 the frags/bytes it assembles to.
1237 */
1238
1239
1240
1241void
1242md_assemble (str)
1243 char *str;
1244{
1245 char *op_start;
1246 char *op_end;
1247 struct h8_op operand[2];
1248 struct h8_opcode *opcode;
1249 struct h8_opcode *prev_opcode;
1250
1251 char *dot = 0;
1252 char c;
1253 int size;
1254
1255 /* Drop leading whitespace */
1256 while (*str == ' ')
1257 str++;
1258
1259 /* find the op code end */
1260 for (op_start = op_end = str;
1261 *op_end != 0 && *op_end != ' ';
1262 op_end++)
1263 {
1264 if (*op_end == '.')
1265 {
1266 dot = op_end + 1;
1267 *op_end = 0;
1268 op_end += 2;
1269 break;
1270 }
1271 }
1272
1273 ;
1274
1275 if (op_end == op_start)
1276 {
1277 as_bad (_("can't find opcode "));
1278 }
1279 c = *op_end;
1280
1281 *op_end = 0;
1282
1283 opcode = (struct h8_opcode *) hash_find (opcode_hash_control,
1284 op_start);
1285
1286 if (opcode == NULL)
1287 {
1288 as_bad (_("unknown opcode"));
1289 return;
1290 }
1291
1292 /* We use to set input_line_pointer to the result of get_operands,
1293 but that is wrong. Our caller assumes we don't change it. */
1294
1295 (void) get_operands (opcode->noperands, op_end, operand);
1296 *op_end = c;
1297 prev_opcode = opcode;
1298
1299 size = SN;
1300 if (dot)
1301 {
1302 switch (*dot)
1303 {
1304 case 'b':
1305 size = SB;
1306 break;
1307
1308 case 'w':
1309 size = SW;
1310 break;
1311
1312 case 'l':
1313 size = SL;
1314 break;
1315 }
1316 }
1317 opcode = get_specific (opcode, operand, size);
1318
1319 if (opcode == 0)
1320 {
1321 /* Couldn't find an opcode which matched the operands */
1322 char *where = frag_more (2);
1323
1324 where[0] = 0x0;
1325 where[1] = 0x0;
1326 clever_message (prev_opcode, operand);
1327
1328 return;
1329 }
1330 if (opcode->size && dot)
1331 {
1332 if (opcode->size != *dot)
1333 {
1334 as_warn (_("mismatch between opcode size and operand size"));
1335 }
1336 }
1337
1338 build_bytes (opcode, operand);
1339
1340}
1341
1342void
1343tc_crawl_symbol_chain (headers)
dbbc7809 1344 object_headers * headers ATTRIBUTE_UNUSED;
252b5132
RH
1345{
1346 printf (_("call to tc_crawl_symbol_chain \n"));
1347}
1348
1349symbolS *
1350md_undefined_symbol (name)
dbbc7809 1351 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1352{
1353 return 0;
1354}
1355
1356void
1357tc_headers_hook (headers)
dbbc7809 1358 object_headers * headers ATTRIBUTE_UNUSED;
252b5132
RH
1359{
1360 printf (_("call to tc_headers_hook \n"));
1361}
1362
1363/* Various routines to kill one day */
1364/* Equal to MAX_PRECISION in atof-ieee.c */
1365#define MAX_LITTLENUMS 6
1366
1367/* Turn a string in input_line_pointer into a floating point constant of type
1368 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1369 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1370 */
1371char *
1372md_atof (type, litP, sizeP)
1373 char type;
1374 char *litP;
1375 int *sizeP;
1376{
1377 int prec;
1378 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1379 LITTLENUM_TYPE *wordP;
1380 char *t;
1381 char *atof_ieee ();
1382
1383 switch (type)
1384 {
1385 case 'f':
1386 case 'F':
1387 case 's':
1388 case 'S':
1389 prec = 2;
1390 break;
1391
1392 case 'd':
1393 case 'D':
1394 case 'r':
1395 case 'R':
1396 prec = 4;
1397 break;
1398
1399 case 'x':
1400 case 'X':
1401 prec = 6;
1402 break;
1403
1404 case 'p':
1405 case 'P':
1406 prec = 6;
1407 break;
1408
1409 default:
1410 *sizeP = 0;
1411 return _("Bad call to MD_ATOF()");
1412 }
1413 t = atof_ieee (input_line_pointer, type, words);
1414 if (t)
1415 input_line_pointer = t;
1416
1417 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1418 for (wordP = words; prec--;)
1419 {
1420 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1421 litP += sizeof (LITTLENUM_TYPE);
1422 }
1423 return 0;
1424}
1425\f
1426CONST char *md_shortopts = "";
1427struct option md_longopts[] = {
1428 {NULL, no_argument, NULL, 0}
1429};
1430size_t md_longopts_size = sizeof(md_longopts);
1431
1432int
1433md_parse_option (c, arg)
dbbc7809
JL
1434 int c ATTRIBUTE_UNUSED;
1435 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
1436{
1437 return 0;
1438}
1439
1440void
1441md_show_usage (stream)
dbbc7809 1442 FILE *stream ATTRIBUTE_UNUSED;
252b5132
RH
1443{
1444}
1445\f
1446void
1447tc_aout_fix_to_chars ()
1448{
1449 printf (_("call to tc_aout_fix_to_chars \n"));
1450 abort ();
1451}
1452
1453void
1454md_convert_frag (headers, seg, fragP)
dbbc7809
JL
1455 object_headers *headers ATTRIBUTE_UNUSED;
1456 segT seg ATTRIBUTE_UNUSED;
1457 fragS *fragP ATTRIBUTE_UNUSED;
252b5132
RH
1458{
1459 printf (_("call to md_convert_frag \n"));
1460 abort ();
1461}
1462
1463valueT
1464md_section_align (seg, size)
1465 segT seg;
1466 valueT size;
1467{
1468 return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
1469
1470}
1471
1472void
1473md_apply_fix (fixP, val)
1474 fixS *fixP;
1475 long val;
1476{
1477 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1478
1479 switch (fixP->fx_size)
1480 {
1481 case 1:
1482 *buf++ = val;
1483 break;
1484 case 2:
1485 *buf++ = (val >> 8);
1486 *buf++ = val;
1487 break;
1488 case 4:
1489 *buf++ = (val >> 24);
1490 *buf++ = (val >> 16);
1491 *buf++ = (val >> 8);
1492 *buf++ = val;
1493 break;
1494 default:
1495 abort ();
1496 }
1497}
1498
1499int
1500md_estimate_size_before_relax (fragP, segment_type)
dbbc7809
JL
1501 register fragS *fragP ATTRIBUTE_UNUSED;
1502 register segT segment_type ATTRIBUTE_UNUSED;
252b5132
RH
1503{
1504 printf (_("call tomd_estimate_size_before_relax \n"));
1505 abort ();
1506}
1507
1508/* Put number into target byte order */
1509
1510void
1511md_number_to_chars (ptr, use, nbytes)
1512 char *ptr;
1513 valueT use;
1514 int nbytes;
1515{
1516 number_to_chars_bigendian (ptr, use, nbytes);
1517}
1518long
1519md_pcrel_from (fixP)
dbbc7809 1520 fixS *fixP ATTRIBUTE_UNUSED;
252b5132
RH
1521{
1522 abort ();
1523}
1524
1525
1526void
1527tc_reloc_mangle (fix_ptr, intr, base)
1528 fixS *fix_ptr;
1529 struct internal_reloc *intr;
1530 bfd_vma base;
1531
1532{
1533 symbolS *symbol_ptr;
1534
1535 symbol_ptr = fix_ptr->fx_addsy;
1536
1537 /* If this relocation is attached to a symbol then it's ok
1538 to output it */
1539 if (fix_ptr->fx_r_type == TC_CONS_RELOC)
1540 {
1541 /* cons likes to create reloc32's whatever the size of the reloc..
1542 */
1543 switch (fix_ptr->fx_size)
1544 {
1545 case 4:
1546 intr->r_type = R_RELLONG;
1547 break;
1548 case 2:
1549 intr->r_type = R_RELWORD;
1550 break;
1551 case 1:
1552 intr->r_type = R_RELBYTE;
1553 break;
1554 default:
1555 abort ();
1556
1557 }
1558
1559 }
1560 else
1561 {
1562 intr->r_type = fix_ptr->fx_r_type;
1563 }
1564
1565 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1566 intr->r_offset = fix_ptr->fx_offset;
1567
1568 if (symbol_ptr)
1569 {
1570 if (symbol_ptr->sy_number != -1)
1571 intr->r_symndx = symbol_ptr->sy_number;
1572 else
1573 {
1574 symbolS *segsym;
1575
1576 /* This case arises when a reference is made to `.'. */
1577 segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;
1578 if (segsym == NULL)
1579 intr->r_symndx = -1;
1580 else
1581 {
1582 intr->r_symndx = segsym->sy_number;
1583 intr->r_offset += S_GET_VALUE (symbol_ptr);
1584 }
1585 }
1586 }
1587 else
1588 intr->r_symndx = -1;
1589
1590
1591}
1592
1593/* end of tc-h8300.c */
This page took 0.132587 seconds and 4 git commands to generate.