2003-06-09 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
CommitLineData
c2dcd04e 1/* tc-h8300.c -- Assemble code for the Renesas H8/300
cc8a6dd0 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
c2dcd04e 3 2001, 2002, 2003 Free Software Foundation, Inc.
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
bc0d738a 22/* Written By Steve Chamberlain <sac@cygnus.com>. */
252b5132
RH
23
24#include <stdio.h>
25#include "as.h"
26#include "subsegs.h"
27#include "bfd.h"
2c8714f2
NC
28
29#ifdef BFD_ASSEMBLER
30#include "dwarf2dbg.h"
31#endif
32
252b5132
RH
33#define DEFINE_TABLE
34#define h8_opcodes ops
35#include "opcode/h8300.h"
3882b010 36#include "safe-ctype.h"
252b5132 37
7e0de7bf
JL
38#ifdef OBJ_ELF
39#include "elf/h8.h"
7e0de7bf
JL
40#endif
41
63a0b638 42const char comment_chars[] = ";";
252b5132 43const char line_comment_chars[] = "#";
63a0b638 44const char line_separator_chars[] = "";
252b5132 45
3048287a
NC
46void cons PARAMS ((int));
47void sbranch PARAMS ((int));
48void h8300hmode PARAMS ((int));
49void h8300smode PARAMS ((int));
8d9cd6b1
NC
50void h8300hnmode PARAMS ((int));
51void h8300snmode PARAMS ((int));
7ee7b84d 52void h8300sxmode PARAMS ((int));
3048287a 53static void pint PARAMS ((int));
252b5132
RH
54
55int Hmode;
56int Smode;
8d9cd6b1 57int Nmode;
7ee7b84d 58int SXmode;
3048287a 59
252b5132 60#define PSIZE (Hmode ? L_32 : L_16)
252b5132 61#define DSYMMODE (Hmode ? L_24 : L_16)
3048287a 62
c2dcd04e 63int bsize = L_8; /* Default branch displacement. */
252b5132 64
a720f7bc
KD
65struct h8_instruction
66{
67 int length;
68 int noperands;
69 int idx;
70 int size;
71 const struct h8_opcode *opcode;
72};
73
74struct h8_instruction *h8_instructions;
75
252b5132 76void
3048287a
NC
77h8300hmode (arg)
78 int arg ATTRIBUTE_UNUSED;
252b5132
RH
79{
80 Hmode = 1;
81 Smode = 0;
83e20b45
JL
82#ifdef BFD_ASSEMBLER
83 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
84 as_warn (_("could not set architecture and machine"));
85#endif
252b5132
RH
86}
87
88void
3048287a
NC
89h8300smode (arg)
90 int arg ATTRIBUTE_UNUSED;
252b5132
RH
91{
92 Smode = 1;
93 Hmode = 1;
83e20b45
JL
94#ifdef BFD_ASSEMBLER
95 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
96 as_warn (_("could not set architecture and machine"));
97#endif
252b5132 98}
70d6ecf3 99
8d9cd6b1
NC
100void
101h8300hnmode (arg)
102 int arg ATTRIBUTE_UNUSED;
103{
104 Hmode = 1;
105 Smode = 0;
106 Nmode = 1;
107#ifdef BFD_ASSEMBLER
108 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300hn))
109 as_warn (_("could not set architecture and machine"));
110#endif
111}
112
113void
114h8300snmode (arg)
115 int arg ATTRIBUTE_UNUSED;
116{
117 Smode = 1;
118 Hmode = 1;
119 Nmode = 1;
120#ifdef BFD_ASSEMBLER
121 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sn))
122 as_warn (_("could not set architecture and machine"));
123#endif
124}
125
7ee7b84d
MS
126void
127h8300sxmode (arg)
128 int arg ATTRIBUTE_UNUSED;
129{
130 Smode = 1;
131 Hmode = 1;
132 SXmode = 1;
133#ifdef BFD_ASSEMBLER
134 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sx))
135 as_warn (_("could not set architecture and machine"));
136#endif
137}
138
252b5132
RH
139void
140sbranch (size)
141 int size;
142{
143 bsize = size;
144}
145
70d6ecf3 146static void
3048287a
NC
147pint (arg)
148 int arg ATTRIBUTE_UNUSED;
252b5132
RH
149{
150 cons (Hmode ? 4 : 2);
151}
152
3048287a
NC
153/* This table describes all the machine specific pseudo-ops the assembler
154 has to support. The fields are:
155 pseudo-op name without dot
156 function to call to execute this pseudo-op
157 Integer arg to pass to the function. */
158
252b5132
RH
159const pseudo_typeS md_pseudo_table[] =
160{
7ee7b84d 161 {"h8300h", h8300hmode, 0},
8d9cd6b1 162 {"h8300hn", h8300hnmode, 0},
7ee7b84d 163 {"h8300s", h8300smode, 0},
8d9cd6b1 164 {"h8300sn", h8300snmode, 0},
7ee7b84d 165 {"h8300sx", h8300sxmode, 0},
252b5132
RH
166 {"sbranch", sbranch, L_8},
167 {"lbranch", sbranch, L_16},
168
169 {"int", pint, 0},
170 {"data.b", cons, 1},
171 {"data.w", cons, 2},
172 {"data.l", cons, 4},
173 {"form", listing_psize, 0},
174 {"heading", listing_title, 0},
7ee7b84d
MS
175 {"import", s_ignore, 0},
176 {"page", listing_eject, 0},
252b5132
RH
177 {"program", s_ignore, 0},
178 {0, 0, 0}
179};
180
181const int md_reloc_size;
182
183const char EXP_CHARS[] = "eE";
184
3048287a
NC
185/* Chars that mean this number is a floating point constant
186 As in 0f12.456
187 or 0d1.2345e12. */
252b5132
RH
188const char FLT_CHARS[] = "rRsSfFdDxXpP";
189
3048287a 190static struct hash_control *opcode_hash_control; /* Opcode mnemonics. */
252b5132 191
70d6ecf3
AM
192/* This function is called once, at assembler startup time. This
193 should set up all the tables, etc. that the MD part of the assembler
194 needs. */
3048287a 195
252b5132
RH
196void
197md_begin ()
198{
a720f7bc 199 unsigned int nopcodes;
7ee7b84d 200 struct h8_opcode *p, *p1;
a720f7bc 201 struct h8_instruction *pi;
252b5132
RH
202 char prev_buffer[100];
203 int idx = 0;
204
83e20b45
JL
205#ifdef BFD_ASSEMBLER
206 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300))
207 as_warn (_("could not set architecture and machine"));
208#endif
209
252b5132
RH
210 opcode_hash_control = hash_new ();
211 prev_buffer[0] = 0;
212
a720f7bc
KD
213 nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
214
215 h8_instructions = (struct h8_instruction *)
216 xmalloc (nopcodes * sizeof (struct h8_instruction));
217
7ee7b84d
MS
218 pi = h8_instructions;
219 p1 = h8_opcodes;
220 /* We do a minimum amount of sorting on the opcode table; this is to
221 make it easy to describe the mova instructions without unnecessary
222 code duplication.
223 Sorting only takes place inside blocks of instructions of the form
224 X/Y, so for example mova/b, mova/w and mova/l can be intermixed. */
225 while (p1)
252b5132 226 {
7ee7b84d
MS
227 struct h8_opcode *first_skipped = 0;
228 int len, cmplen = 0;
229 char *src = p1->name;
230 char *dst, *buffer;
252b5132 231
7ee7b84d
MS
232 if (p1->name == 0)
233 break;
234 /* Strip off any . part when inserting the opcode and only enter
235 unique codes into the hash table. */
236 dst = buffer = malloc (strlen (src) + 1);
252b5132
RH
237 while (*src)
238 {
239 if (*src == '.')
240 {
241 src++;
252b5132
RH
242 break;
243 }
7ee7b84d
MS
244 if (*src == '/')
245 cmplen = src - p1->name + 1;
252b5132
RH
246 *dst++ = *src++;
247 }
7ee7b84d
MS
248 *dst = 0;
249 len = dst - buffer;
250 if (cmplen == 0)
251 cmplen = len;
252 hash_insert (opcode_hash_control, buffer, (char *) pi);
253 strcpy (prev_buffer, buffer);
254 idx++;
255
256 for (p = p1; p->name; p++)
252b5132 257 {
7ee7b84d
MS
258 /* A negative TIME is used to indicate that we've added this opcode
259 already. */
260 if (p->time == -1)
261 continue;
262 if (strncmp (p->name, buffer, cmplen) != 0
263 || (p->name[cmplen] != '\0' && p->name[cmplen] != '.'
264 && p->name[cmplen - 1] != '/'))
265 {
266 if (first_skipped == 0)
267 first_skipped = p;
268 break;
269 }
270 if (strncmp (p->name, buffer, len) != 0)
271 {
272 if (first_skipped == 0)
273 first_skipped = p;
274 continue;
275 }
276
277 p->time = -1;
278 pi->size = p->name[len] == '.' ? p->name[len + 1] : 0;
279 pi->idx = idx;
252b5132 280
7ee7b84d
MS
281 /* Find the number of operands. */
282 pi->noperands = 0;
283 while (pi->noperands < 3 && p->args.nib[pi->noperands] != (op_type) E)
284 pi->noperands++;
70d6ecf3 285
7ee7b84d
MS
286 /* Find the length of the opcode in bytes. */
287 pi->length = 0;
288 while (p->data.nib[pi->length * 2] != (op_type) E)
289 pi->length++;
a720f7bc 290
7ee7b84d
MS
291 pi->opcode = p;
292 pi++;
293 }
294 p1 = first_skipped;
252b5132
RH
295 }
296
a720f7bc
KD
297 /* Add entry for the NULL vector terminator. */
298 pi->length = 0;
299 pi->noperands = 0;
300 pi->idx = 0;
301 pi->size = 0;
7ee7b84d 302 pi->opcode = 0;
a720f7bc 303
252b5132
RH
304 linkrelax = 1;
305}
306
252b5132
RH
307struct h8_exp
308{
309 char *e_beg;
310 char *e_end;
311 expressionS e_exp;
312};
70d6ecf3 313
252b5132
RH
314struct h8_op
315{
316 op_type mode;
317 unsigned reg;
318 expressionS exp;
319};
320
a720f7bc 321static void clever_message PARAMS ((const struct h8_instruction *, struct h8_op *));
d4ea8842 322static void fix_operand_size PARAMS ((struct h8_op *, int));
a720f7bc 323static void build_bytes PARAMS ((const struct h8_instruction *, struct h8_op *));
7ee7b84d 324static void do_a_fix_imm PARAMS ((int, int, struct h8_op *, int));
3048287a 325static void check_operand PARAMS ((struct h8_op *, unsigned int, char *));
a720f7bc 326static const struct h8_instruction * get_specific PARAMS ((const struct h8_instruction *, struct h8_op *, int));
3048287a 327static char * get_operands PARAMS ((unsigned, char *, struct h8_op *));
7ee7b84d 328static void get_operand PARAMS ((char **, struct h8_op *, int));
3048287a
NC
329static char * skip_colonthing PARAMS ((char *, expressionS *, int *));
330static char * parse_exp PARAMS ((char *, expressionS *));
331static int parse_reg PARAMS ((char *, op_type *, unsigned *, int));
332char * colonmod24 PARAMS ((struct h8_op *, char *));
333
7ee7b84d
MS
334static int constant_fits_width_p PARAMS ((struct h8_op *, unsigned int));
335static int constant_fits_size_p PARAMS ((struct h8_op *, int, int));
336
252b5132
RH
337/*
338 parse operands
339 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
340 r0l,r0h,..r7l,r7h
341 @WREG
342 @WREG+
343 @-WREG
344 #const
345 ccr
346*/
347
bc0d738a
NC
348/* Try to parse a reg name. Return the number of chars consumed. */
349
40f09f82 350static int
252b5132
RH
351parse_reg (src, mode, reg, direction)
352 char *src;
353 op_type *mode;
354 unsigned int *reg;
355 int direction;
252b5132
RH
356{
357 char *end;
358 int len;
359
70d6ecf3 360 /* Cribbed from get_symbol_end. */
252b5132
RH
361 if (!is_name_beginner (*src) || *src == '\001')
362 return 0;
70d6ecf3 363 end = src + 1;
7ee7b84d 364 while ((is_part_of_name (*end) && *end != '.') || *end == '\001')
252b5132
RH
365 end++;
366 len = end - src;
367
7ee7b84d 368 if (len == 2 && TOLOWER (src[0]) == 's' && TOLOWER (src[1]) == 'p')
252b5132
RH
369 {
370 *mode = PSIZE | REG | direction;
371 *reg = 7;
372 return len;
373 }
7ee7b84d
MS
374 if (len == 3 &&
375 TOLOWER (src[0]) == 'c' &&
376 TOLOWER (src[1]) == 'c' &&
377 TOLOWER (src[2]) == 'r')
252b5132
RH
378 {
379 *mode = CCR;
380 *reg = 0;
381 return len;
382 }
7ee7b84d
MS
383 if (len == 3 &&
384 TOLOWER (src[0]) == 'e' &&
385 TOLOWER (src[1]) == 'x' &&
386 TOLOWER (src[2]) == 'r')
252b5132
RH
387 {
388 *mode = EXR;
7ee7b84d
MS
389 *reg = 1;
390 return len;
391 }
392 if (len == 3 &&
393 TOLOWER (src[0]) == 'v' &&
394 TOLOWER (src[1]) == 'b' &&
395 TOLOWER (src[2]) == 'r')
396 {
397 *mode = VBR;
398 *reg = 6;
399 return len;
400 }
401 if (len == 3 &&
402 TOLOWER (src[0]) == 's' &&
403 TOLOWER (src[1]) == 'b' &&
404 TOLOWER (src[2]) == 'r')
405 {
406 *mode = SBR;
407 *reg = 7;
252b5132
RH
408 return len;
409 }
7ee7b84d 410 if (len == 2 && TOLOWER (src[0]) == 'f' && TOLOWER (src[1]) == 'p')
252b5132
RH
411 {
412 *mode = PSIZE | REG | direction;
413 *reg = 6;
414 return len;
415 }
7ee7b84d
MS
416 if (len == 3 && TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' &&
417 src[2] >= '0' && src[2] <= '7')
252b5132
RH
418 {
419 *mode = L_32 | REG | direction;
420 *reg = src[2] - '0';
421 if (!Hmode)
422 as_warn (_("Reg not valid for H8/300"));
423 return len;
424 }
7ee7b84d 425 if (len == 2 && TOLOWER (src[0]) == 'e' && src[1] >= '0' && src[1] <= '7')
252b5132
RH
426 {
427 *mode = L_16 | REG | direction;
428 *reg = src[1] - '0' + 8;
429 if (!Hmode)
430 as_warn (_("Reg not valid for H8/300"));
431 return len;
432 }
433
7ee7b84d 434 if (TOLOWER (src[0]) == 'r')
252b5132
RH
435 {
436 if (src[1] >= '0' && src[1] <= '7')
437 {
7ee7b84d 438 if (len == 3 && TOLOWER (src[2]) == 'l')
252b5132
RH
439 {
440 *mode = L_8 | REG | direction;
441 *reg = (src[1] - '0') + 8;
442 return len;
443 }
7ee7b84d 444 if (len == 3 && TOLOWER (src[2]) == 'h')
252b5132
RH
445 {
446 *mode = L_8 | REG | direction;
447 *reg = (src[1] - '0');
448 return len;
449 }
450 if (len == 2)
451 {
452 *mode = L_16 | REG | direction;
453 *reg = (src[1] - '0');
454 return len;
455 }
456 }
457 }
458
459 return 0;
460}
461
40f09f82 462static char *
252b5132
RH
463parse_exp (s, op)
464 char *s;
70d6ecf3 465 expressionS *op;
252b5132
RH
466{
467 char *save = input_line_pointer;
468 char *new;
469
470 input_line_pointer = s;
471 expression (op);
472 if (op->X_op == O_absent)
473 as_bad (_("missing operand"));
474 new = input_line_pointer;
475 input_line_pointer = save;
476 return new;
477}
478
479static char *
480skip_colonthing (ptr, exp, mode)
481 char *ptr;
dbbc7809 482 expressionS *exp ATTRIBUTE_UNUSED;
252b5132
RH
483 int *mode;
484{
485 if (*ptr == ':')
486 {
487 ptr++;
488 *mode &= ~SIZE;
7ee7b84d
MS
489 if (ptr[0] == '8' && ! ISDIGIT (ptr[1]))
490 *mode |= L_8;
491 else if (ptr[0] == '2' && ! ISDIGIT (ptr[1]))
492 *mode |= L_2;
493 else if (ptr[0] == '3' && ! ISDIGIT (ptr[1]))
494 *mode |= L_3;
495 else if (ptr[0] == '4' && ! ISDIGIT (ptr[1]))
496 *mode |= L_4;
497 else if (ptr[0] == '5' && ! ISDIGIT (ptr[1]))
498 *mode |= L_5;
499 else if (ptr[0] == '2' && ptr[1] == '4')
500 *mode |= L_24;
501 else if (ptr[0] == '3' && ptr[1] == '2')
502 *mode |= L_32;
503 else if (ptr[0] == '1' && ptr[1] == '6')
504 *mode |= L_16;
252b5132 505 else
7ee7b84d
MS
506 as_bad (_("invalid operand size requested"));
507
508 while (ISDIGIT (*ptr))
509 ptr++;
252b5132
RH
510 }
511 return ptr;
512}
513
514/* The many forms of operand:
515
516 Rn Register direct
517 @Rn Register indirect
518 @(exp[:16], Rn) Register indirect with displacement
519 @Rn+
520 @-Rn
70d6ecf3
AM
521 @aa:8 absolute 8 bit
522 @aa:16 absolute 16 bit
252b5132
RH
523 @aa absolute 16 bit
524
525 #xx[:size] immediate data
70d6ecf3 526 @(exp:[8], pc) pc rel
3048287a 527 @@aa[:8] memory indirect. */
252b5132
RH
528
529char *
530colonmod24 (op, src)
531 struct h8_op *op;
532 char *src;
252b5132
RH
533{
534 int mode = 0;
535 src = skip_colonthing (src, &op->exp, &mode);
536
537 if (!mode)
538 {
d4ea8842
MS
539 /* If the operand is a 16-bit constant integer, leave fix_operand_size
540 to calculate its size. Otherwise choose a default here. */
252b5132
RH
541 if (op->exp.X_add_number < -32768
542 || op->exp.X_add_number > 32767)
543 {
544 if (Hmode)
545 mode = L_24;
546 else
547 mode = L_16;
548 }
549 else if (op->exp.X_add_symbol
550 || op->exp.X_op_symbol)
551 mode = DSYMMODE;
252b5132 552 }
3048287a 553
252b5132
RH
554 op->mode |= mode;
555 return src;
252b5132
RH
556}
557
7ee7b84d
MS
558static int
559constant_fits_width_p (operand, width)
560 struct h8_op *operand;
561 unsigned int width;
562{
563 return ((operand->exp.X_add_number & ~width) == 0
564 || (operand->exp.X_add_number | width) == (unsigned)(~0));
565}
566
567static int
568constant_fits_size_p (operand, size, no_symbols)
569 struct h8_op *operand;
570 int size, no_symbols;
571{
572 offsetT num = operand->exp.X_add_number;
573 if (no_symbols
574 && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
575 return 0;
576 switch (size)
577 {
578 case L_2:
579 return (num & ~3) == 0;
580 case L_3:
581 return (num & ~7) == 0;
582 case L_3NZ:
583 return num >= 1 && num < 8;
584 case L_4:
585 return (num & ~15) == 0;
586 case L_5:
587 return num >= 1 && num < 32;
588 case L_8:
589 return (num & ~0xFF) == 0 || ((unsigned)num | 0x7F) == ~0u;
590 case L_8U:
591 return (num & ~0xFF) == 0;
592 case L_16:
593 return (num & ~0xFFFF) == 0 || ((unsigned)num | 0x7FFF) == ~0u;
594 case L_16U:
595 return (num & ~0xFFFF) == 0;
596 case L_32:
597 return 1;
598 default:
599 abort ();
600 }
601}
602
252b5132 603static void
7ee7b84d 604get_operand (ptr, op, direction)
252b5132
RH
605 char **ptr;
606 struct h8_op *op;
252b5132
RH
607 int direction;
608{
609 char *src = *ptr;
610 op_type mode;
611 unsigned int num;
612 unsigned int len;
613
7ee7b84d 614 op->mode = 0;
252b5132 615
3048287a
NC
616 /* Check for '(' and ')' for instructions ldm and stm. */
617 if (src[0] == '(' && src[8] == ')')
618 ++ src;
619
252b5132
RH
620 /* Gross. Gross. ldm and stm have a format not easily handled
621 by get_operand. We deal with it explicitly here. */
7ee7b84d
MS
622 if (TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' &&
623 ISDIGIT (src[2]) && src[3] == '-' &&
624 TOLOWER (src[4]) == 'e' && TOLOWER (src[5]) == 'r' && ISDIGIT (src[6]))
252b5132
RH
625 {
626 int low, high;
627
628 low = src[2] - '0';
629 high = src[6] - '0';
630
7ee7b84d 631 if (high == low)
252b5132
RH
632 as_bad (_("Invalid register list for ldm/stm\n"));
633
7ee7b84d 634 if (high < low)
252b5132
RH
635 as_bad (_("Invalid register list for ldm/stm\n"));
636
637 if (high - low > 3)
7ee7b84d 638 as_bad (_("Invalid register list for ldm/stm)\n"));
252b5132
RH
639
640 /* Even sicker. We encode two registers into op->reg. One
641 for the low register to save, the other for the high
642 register to save; we also set the high bit in op->reg
643 so we know this is "very special". */
644 op->reg = 0x80000000 | (high << 8) | low;
645 op->mode = REG;
3048287a
NC
646 if (src[7] == ')')
647 *ptr = src + 8;
648 else
649 *ptr = src + 7;
252b5132
RH
650 return;
651 }
652
653 len = parse_reg (src, &op->mode, &op->reg, direction);
654 if (len)
655 {
7ee7b84d
MS
656 src += len;
657 if (*src == '.')
658 {
659 int size = op->mode & SIZE;
660 switch (src[1])
661 {
662 case 'l': case 'L':
663 if (size != L_32)
664 as_warn (_("mismatch between register and suffix"));
665 op->mode = (op->mode & ~MODE) | LOWREG;
666 break;
667 case 'w': case 'W':
668 if (size != L_32 && size != L_16)
669 as_warn (_("mismatch between register and suffix"));
670 op->mode = (op->mode & ~MODE) | LOWREG;
671 op->mode = (op->mode & ~SIZE) | L_16;
672 break;
673 case 'b': case 'B':
674 op->mode = (op->mode & ~MODE) | LOWREG;
675 if (size != L_32 && size != L_8)
676 as_warn (_("mismatch between register and suffix"));
677 op->mode = (op->mode & ~MODE) | LOWREG;
678 op->mode = (op->mode & ~SIZE) | L_8;
679 break;
680 default:
681 as_warn ("invalid suffix after register.");
682 break;
683 }
684 src += 2;
685 }
686 *ptr = src;
252b5132
RH
687 return;
688 }
689
690 if (*src == '@')
691 {
692 src++;
693 if (*src == '@')
694 {
695 src++;
696 src = parse_exp (src, &op->exp);
697
698 src = skip_colonthing (src, &op->exp, &op->mode);
699
700 *ptr = src;
701
7ee7b84d
MS
702 if (op->exp.X_add_number >= 0x100)
703 {
704 int divisor;
705
706 op->mode = VECIND;
707 /* FIXME : 2? or 4? */
708 if (op->exp.X_add_number >= 0x400)
709 as_bad (_("address too high for vector table jmp/jsr"));
710 else if (op->exp.X_add_number >= 0x200)
711 divisor = 4;
712 else
713 divisor = 2;
714
715 op->exp.X_add_number = op->exp.X_add_number / divisor - 0x80;
716 }
717 else
718 op->mode = MEMIND;
719
252b5132 720 return;
252b5132
RH
721 }
722
7ee7b84d 723 if (*src == '-' || *src == '+')
252b5132 724 {
7ee7b84d 725 char c = *src;
252b5132
RH
726 src++;
727 len = parse_reg (src, &mode, &num, direction);
728 if (len == 0)
729 {
70d6ecf3 730 /* Oops, not a reg after all, must be ordinary exp. */
252b5132 731 src--;
70d6ecf3 732 /* Must be a symbol. */
252b5132
RH
733 op->mode = ABS | PSIZE | direction;
734 *ptr = skip_colonthing (parse_exp (src, &op->exp),
735 &op->exp, &op->mode);
736
737 return;
252b5132
RH
738 }
739
252b5132
RH
740 if ((mode & SIZE) != PSIZE)
741 as_bad (_("Wrong size pointer register for architecture."));
7ee7b84d 742 op->mode = c == '-' ? RDPREDEC : RDPREINC;
252b5132
RH
743 op->reg = num;
744 *ptr = src + len;
745 return;
746 }
747 if (*src == '(')
748 {
252b5132
RH
749 src++;
750
7ee7b84d
MS
751 /* See if this is @(ERn.x, PC). */
752 len = parse_reg (src, &mode, &op->reg, direction);
753 if (len != 0 && (mode & MODE) == REG && src[len] == '.')
754 {
755 switch (TOLOWER (src[len + 1]))
756 {
757 case 'b':
758 mode = PCIDXB | direction;
759 break;
760 case 'w':
761 mode = PCIDXW | direction;
762 break;
763 case 'l':
764 mode = PCIDXL | direction;
765 break;
766 default:
767 mode = 0;
768 break;
769 }
770 if (mode
771 && src[len + 2] == ','
772 && TOLOWER (src[len + 3]) != 'p'
773 && TOLOWER (src[len + 4]) != 'c'
774 && src[len + 5] != ')')
775 {
776 *ptr = src + len + 6;
777 op->mode |= mode;
778 return;
779 }
780 /* Fall through into disp case - the grammar is somewhat
781 ambiguous, so we should try whether it's a DISP operand
782 after all ("ER3.L" might be a poorly named label...). */
783 }
784
785 /* Disp. */
786
70d6ecf3 787 /* Start off assuming a 16 bit offset. */
252b5132
RH
788
789 src = parse_exp (src, &op->exp);
790
791 src = colonmod24 (op, src);
792
793 if (*src == ')')
794 {
795 src++;
796 op->mode |= ABS | direction;
797 *ptr = src;
798 return;
799 }
800
801 if (*src != ',')
802 {
803 as_bad (_("expected @(exp, reg16)"));
804 return;
805
806 }
807 src++;
808
809 len = parse_reg (src, &mode, &op->reg, direction);
7ee7b84d 810 if (len == 0 || (mode & MODE) != REG)
252b5132
RH
811 {
812 as_bad (_("expected @(exp, reg16)"));
813 return;
814 }
252b5132 815 src += len;
7ee7b84d
MS
816 if (src[0] == '.')
817 {
818 switch (TOLOWER (src[1]))
819 {
820 case 'b':
821 op->mode |= INDEXB | direction;
822 break;
823 case 'w':
824 op->mode |= INDEXW | direction;
825 break;
826 case 'l':
827 op->mode |= INDEXL | direction;
828 break;
829 default:
830 as_bad (_("expected .L, .W or .B for register in indexed addressing mode"));
831 }
832 src += 2;
833 op->reg &= 7;
834 }
835 else
836 op->mode |= DISP | direction;
252b5132
RH
837 src = skip_colonthing (src, &op->exp, &op->mode);
838
839 if (*src != ')' && '(')
840 {
841 as_bad (_("expected @(exp, reg16)"));
842 return;
843 }
844 *ptr = src + 1;
845
846 return;
847 }
848 len = parse_reg (src, &mode, &num, direction);
849
850 if (len)
851 {
852 src += len;
7ee7b84d 853 if (*src == '+' || *src == '-')
252b5132 854 {
252b5132
RH
855 if ((mode & SIZE) != PSIZE)
856 as_bad (_("Wrong size pointer register for architecture."));
7ee7b84d 857 op->mode = *src == '+' ? RSPOSTINC : RSPOSTDEC;
252b5132 858 op->reg = num;
7ee7b84d 859 src++;
252b5132
RH
860 *ptr = src;
861 return;
862 }
863 if ((mode & SIZE) != PSIZE)
864 as_bad (_("Wrong size pointer register for architecture."));
865
866 op->mode = direction | IND | PSIZE;
867 op->reg = num;
868 *ptr = src;
869
870 return;
871 }
872 else
873 {
874 /* must be a symbol */
875
876 op->mode = ABS | direction;
877 src = parse_exp (src, &op->exp);
878
879 *ptr = colonmod24 (op, src);
880
881 return;
882 }
883 }
884
252b5132
RH
885 if (*src == '#')
886 {
887 src++;
888 op->mode = IMM;
889 src = parse_exp (src, &op->exp);
890 *ptr = skip_colonthing (src, &op->exp, &op->mode);
891
892 return;
893 }
7ee7b84d
MS
894 else if (strncmp (src, "mach", 4) == 0 ||
895 strncmp (src, "macl", 4) == 0 ||
896 strncmp (src, "MACH", 4) == 0 ||
897 strncmp (src, "MACL", 4) == 0)
252b5132 898 {
7ee7b84d 899 op->reg = TOLOWER (src[3]) == 'l';
252b5132
RH
900 op->mode = MACREG;
901 *ptr = src + 4;
902 return;
903 }
904 else
905 {
906 src = parse_exp (src, &op->exp);
907 /* Trailing ':' size ? */
908 if (*src == ':')
909 {
910 if (src[1] == '1' && src[2] == '6')
911 {
912 op->mode = PCREL | L_16;
913 src += 3;
914 }
915 else if (src[1] == '8')
916 {
917 op->mode = PCREL | L_8;
918 src += 2;
919 }
920 else
3048287a 921 as_bad (_("expect :8 or :16 here"));
252b5132
RH
922 }
923 else
7ee7b84d
MS
924 {
925 int val = op->exp.X_add_number;
926
927 op->mode = PCREL;
928 if (-128 < val && val < 127)
929 op->mode |= L_8;
930 else
931 op->mode |= L_16;
932 }
3048287a 933
252b5132
RH
934 *ptr = src;
935 }
936}
937
70d6ecf3 938static char *
252b5132
RH
939get_operands (noperands, op_end, operand)
940 unsigned int noperands;
941 char *op_end;
942 struct h8_op *operand;
943{
944 char *ptr = op_end;
945
946 switch (noperands)
947 {
948 case 0:
252b5132
RH
949 break;
950
951 case 1:
952 ptr++;
7ee7b84d 953 get_operand (&ptr, operand + 0, SRC);
252b5132
RH
954 if (*ptr == ',')
955 {
956 ptr++;
7ee7b84d 957 get_operand (&ptr, operand + 1, DST);
252b5132 958 }
252b5132 959 break;
70d6ecf3 960
252b5132
RH
961 case 2:
962 ptr++;
7ee7b84d 963 get_operand (&ptr, operand + 0, SRC);
252b5132
RH
964 if (*ptr == ',')
965 ptr++;
7ee7b84d
MS
966 get_operand (&ptr, operand + 1, DST);
967 break;
968
969 case 3:
970 ptr++;
971 get_operand (&ptr, operand + 0, SRC);
972 if (*ptr == ',')
973 ptr++;
974 get_operand (&ptr, operand + 1, DST);
975 if (*ptr == ',')
976 ptr++;
977 get_operand (&ptr, operand + 2, OP3);
252b5132
RH
978 break;
979
980 default:
981 abort ();
982 }
983
252b5132
RH
984 return ptr;
985}
986
7ee7b84d
MS
987/* MOVA has special requirements. Rather than adding twice the amount of
988 addressing modes, we simply special case it a bit. */
989static void
990get_mova_operands (char *op_end, struct h8_op *operand)
991{
992 char *ptr = op_end;
993
994 if (ptr[1] != '@' || ptr[2] != '(')
995 goto error;
996 ptr += 3;
997 operand[0].mode = 0;
998 ptr = parse_exp (ptr, &operand[0].exp);
999 ptr = colonmod24 (operand + 0, ptr);
1000
1001 if (*ptr !=',')
1002 goto error;
1003 ptr++;
1004 get_operand (&ptr, operand + 1, DST);
1005
1006 if (*ptr =='.')
1007 {
1008 ptr++;
1009 switch (*ptr++)
1010 {
1011 case 'b': case 'B':
1012 operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
1013 break;
1014 case 'w': case 'W':
1015 operand[0].mode = (operand[0].mode & ~MODE) | INDEXW;
1016 break;
1017 case 'l': case 'L':
1018 operand[0].mode = (operand[0].mode & ~MODE) | INDEXL;
1019 break;
1020 default:
1021 goto error;
1022 }
1023 }
1024 else if ((operand[1].mode & MODE) == LOWREG)
1025 {
1026 switch (operand[1].mode & SIZE)
1027 {
1028 case L_8:
1029 operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
1030 break;
1031 case L_16:
1032 operand[0].mode = (operand[0].mode & ~MODE) | INDEXW;
1033 break;
1034 case L_32:
1035 operand[0].mode = (operand[0].mode & ~MODE) | INDEXL;
1036 break;
1037 default:
1038 goto error;
1039 }
1040 }
1041 else
1042 goto error;
1043
1044 if (*ptr++ != ')' || *ptr++ != ',')
1045 goto error;
1046 get_operand (&ptr, operand + 2, OP3);
1047 /* See if we can use the short form of MOVA. */
1048 if (((operand[1].mode & MODE) == REG || (operand[1].mode & MODE) == LOWREG)
1049 && (operand[2].mode & MODE) == REG
1050 && (operand[1].reg & 7) == (operand[2].reg & 7))
1051 {
1052 operand[1].mode = operand[2].mode = 0;
1053 operand[0].reg = operand[2].reg & 7;
1054 }
1055 return;
1056
1057 error:
1058 as_bad (_("expected valid addressing mode for mova: \"@(disp, ea.sz),ERn\""));
1059 return;
1060}
1061
1062static void
1063get_rtsl_operands (char *ptr, struct h8_op *operand)
1064{
1065 int mode, num, num2, len, type = 0;
1066
1067 ptr++;
1068 if (*ptr == '(')
1069 {
1070 ptr++;
1071 type = 1;
1072 }
1073 len = parse_reg (ptr, &mode, &num, SRC);
1074 if (len == 0 || (mode & MODE) != REG)
1075 {
1076 as_bad (_("expected register"));
1077 return;
1078 }
1079 if (type == 1)
1080 {
1081 ptr += len;
1082 if (*ptr++ != '-')
1083 {
1084 as_bad (_("expected register list"));
1085 return;
1086 }
1087 len = parse_reg (ptr, &mode, &num2, SRC);
1088 if (len == 0 || (mode & MODE) != REG)
1089 {
1090 as_bad (_("expected register"));
1091 return;
1092 }
1093 ptr += len;
1094 if (*ptr++ != ')')
1095 {
1096 as_bad (_("expected closing paren"));
1097 return;
1098 }
1099 /* CONST_xxx are used as placeholders in the opcode table. */
1100 num = num2 - num;
1101 if (num < 1 || num > 3)
1102 {
1103 as_bad (_("invalid register list"));
1104 return;
1105 }
1106 }
1107 else
1108 num2 = num, num = 0;
1109 operand[0].mode = RS32;
1110 operand[1].mode = RD32;
1111 operand[0].reg = num;
1112 operand[1].reg = num2;
1113}
1114
252b5132
RH
1115/* Passed a pointer to a list of opcodes which use different
1116 addressing modes, return the opcode which matches the opcodes
70d6ecf3 1117 provided. */
3048287a 1118
a720f7bc
KD
1119static const struct h8_instruction *
1120get_specific (instruction, operands, size)
1121 const struct h8_instruction *instruction;
252b5132
RH
1122 struct h8_op *operands;
1123 int size;
1124{
a720f7bc 1125 const struct h8_instruction *this_try = instruction;
7ee7b84d 1126 const struct h8_instruction *found_other = 0, *found_mismatched = 0;
252b5132 1127 int found = 0;
a720f7bc 1128 int this_index = instruction->idx;
7ee7b84d 1129 int noperands = 0;
252b5132
RH
1130
1131 /* There's only one ldm/stm and it's easier to just
1132 get out quick for them. */
7ee7b84d
MS
1133 if (OP_KIND (instruction->opcode->how) == O_LDM
1134 || OP_KIND (instruction->opcode->how) == O_STM)
252b5132
RH
1135 return this_try;
1136
7ee7b84d
MS
1137 while (noperands < 3 && operands[noperands].mode != 0)
1138 noperands++;
1139
a720f7bc 1140 while (this_index == instruction->idx && !found)
252b5132 1141 {
7ee7b84d 1142 int this_size;
252b5132 1143
7ee7b84d 1144 found = 1;
a720f7bc 1145 this_try = instruction++;
7ee7b84d 1146 this_size = this_try->opcode->how & SN;
252b5132 1147
7ee7b84d
MS
1148 if (this_try->noperands != noperands)
1149 found = 0;
1150 else if (this_try->noperands > 0)
252b5132 1151 {
3048287a 1152 int i;
252b5132
RH
1153
1154 for (i = 0; i < this_try->noperands && found; i++)
1155 {
a720f7bc 1156 op_type op = this_try->opcode->args.nib[i];
7ee7b84d
MS
1157 int op_mode = op & MODE;
1158 int op_size = op & SIZE;
252b5132 1159 int x = operands[i].mode;
7ee7b84d
MS
1160 int x_mode = x & MODE;
1161 int x_size = x & SIZE;
252b5132 1162
7ee7b84d 1163 if (op_mode == LOWREG && (x_mode == REG || x_mode == LOWREG))
252b5132 1164 {
7ee7b84d
MS
1165 if ((x_size == L_8 && (operands[i].reg & 8) == 0)
1166 || (x_size == L_16 && (operands[i].reg & 8) == 8))
1167 as_warn (_("can't use high part of register in operand %d"), i);
1168
1169 if (x_size != op_size)
1170 found = 0;
252b5132 1171 }
7ee7b84d 1172 else if (op_mode == REG)
252b5132 1173 {
7ee7b84d
MS
1174 if (x_mode == LOWREG)
1175 x_mode = REG;
1176 if (x_mode != REG)
252b5132
RH
1177 found = 0;
1178
7ee7b84d
MS
1179 if (x_size == L_P)
1180 x_size = (Hmode ? L_32 : L_16);
1181 if (op_size == L_P)
1182 op_size = (Hmode ? L_32 : L_16);
252b5132 1183
70d6ecf3 1184 /* The size of the reg is v important. */
7ee7b84d 1185 if (op_size != x_size)
252b5132
RH
1186 found = 0;
1187 }
7ee7b84d 1188 else if (op_mode & CTRL) /* control register */
252b5132 1189 {
7ee7b84d
MS
1190 if (!(x_mode & CTRL))
1191 found = 0;
1192
1193 switch (x_mode)
1194 {
1195 case CCR:
1196 if (op_mode != CCR &&
1197 op_mode != CCR_EXR &&
1198 op_mode != CC_EX_VB_SB)
1199 found = 0;
1200 break;
1201 case EXR:
1202 if (op_mode != EXR &&
1203 op_mode != CCR_EXR &&
1204 op_mode != CC_EX_VB_SB)
1205 found = 0;
1206 break;
1207 case MACH:
1208 if (op_mode != MACH &&
1209 op_mode != MACREG)
1210 found = 0;
1211 break;
1212 case MACL:
1213 if (op_mode != MACL &&
1214 op_mode != MACREG)
1215 found = 0;
1216 break;
1217 case VBR:
1218 if (op_mode != VBR &&
1219 op_mode != VBR_SBR &&
1220 op_mode != CC_EX_VB_SB)
1221 found = 0;
1222 break;
1223 case SBR:
1224 if (op_mode != SBR &&
1225 op_mode != VBR_SBR &&
1226 op_mode != CC_EX_VB_SB)
1227 found = 0;
1228 break;
1229 }
1230 }
1231 else if ((op & ABSJMP) && (x_mode == ABS || x_mode == PCREL))
1232 {
1233 operands[i].mode &= ~MODE;
252b5132 1234 operands[i].mode |= ABSJMP;
70d6ecf3 1235 /* But it may not be 24 bits long. */
7ee7b84d 1236 if (x_mode == ABS && !Hmode)
252b5132
RH
1237 {
1238 operands[i].mode &= ~SIZE;
1239 operands[i].mode |= L_16;
1240 }
7ee7b84d
MS
1241 if ((operands[i].mode & SIZE) == L_32
1242 && (op_mode & SIZE) != L_32)
1243 found = 0;
252b5132 1244 }
7ee7b84d 1245 else if (x_mode == IMM && op_mode != IMM)
252b5132 1246 {
7ee7b84d
MS
1247 offsetT num = operands[i].exp.X_add_number;
1248 if (op_mode == KBIT || op_mode == DBIT)
1249 /* This is ok if the immediate value is sensible. */;
1250 else if (op_mode == CONST_2)
1251 found = num == 2;
1252 else if (op_mode == CONST_4)
1253 found = num == 4;
1254 else if (op_mode == CONST_8)
1255 found = num == 8;
1256 else if (op_mode == CONST_16)
1257 found = num == 16;
1258 else
1259 found = 0;
252b5132 1260 }
7ee7b84d 1261 else if (op_mode == PCREL && op_mode == x_mode)
252b5132 1262 {
7ee7b84d
MS
1263 /* movsd only comes in PCREL16 flavour:
1264 If x_size is L_8, promote it. */
1265 if (OP_KIND (this_try->opcode->how) == O_MOVSD)
1266 if (x_size == L_8)
1267 x_size = L_16;
1268
70d6ecf3 1269 /* The size of the displacement is important. */
7ee7b84d 1270 if (op_size != x_size)
252b5132
RH
1271 found = 0;
1272 }
7ee7b84d
MS
1273 else if ((op_mode == DISP || op_mode == IMM || op_mode == ABS
1274 || op_mode == INDEXB || op_mode == INDEXW
1275 || op_mode == INDEXL)
1276 && op_mode == x_mode)
252b5132
RH
1277 {
1278 /* Promote a L_24 to L_32 if it makes us match. */
7ee7b84d 1279 if (x_size == L_24 && op_size == L_32)
252b5132 1280 {
7ee7b84d
MS
1281 x &= ~SIZE;
1282 x |= x_size = L_32;
252b5132 1283 }
7ee7b84d
MS
1284
1285#if 0 /* ??? */
252b5132 1286 /* Promote an L8 to L_16 if it makes us match. */
7ee7b84d 1287 if ((op_mode == ABS || op_mode == DISP) && x_size == L_8)
252b5132 1288 {
7ee7b84d
MS
1289 if (op_size == L_16)
1290 x_size = L_16;
252b5132 1291 }
7ee7b84d
MS
1292#endif
1293
1294 if (((x_size == L_16 && op_size == L_16U)
1295 || (x_size == L_3 && op_size == L_3NZ))
1296 /* We're deliberately more permissive for ABS modes. */
1297 && (op_mode == ABS
1298 || constant_fits_size_p (operands + i, op_size,
1299 op & NO_SYMBOLS)))
1300 x_size = op_size;
1301
1302 if (x_size != 0 && op_size != x_size)
1303 found = 0;
1304 else if (x_size == 0
1305 && ! constant_fits_size_p (operands + i, op_size,
1306 op & NO_SYMBOLS))
252b5132
RH
1307 found = 0;
1308 }
7ee7b84d 1309 else if (op_mode != x_mode)
252b5132
RH
1310 {
1311 found = 0;
70d6ecf3 1312 }
252b5132
RH
1313 }
1314 }
7ee7b84d
MS
1315 if (found)
1316 {
1317 if ((this_try->opcode->available == AV_H8SX && ! SXmode)
d4ea8842 1318 || (this_try->opcode->available == AV_H8S && ! Smode)
7ee7b84d
MS
1319 || (this_try->opcode->available == AV_H8H && ! Hmode))
1320 found = 0, found_other = this_try;
1321 else if (this_size != size && (this_size != SN && size != SN))
1322 found_mismatched = this_try, found = 0;
1323
1324 }
252b5132
RH
1325 }
1326 if (found)
1327 return this_try;
7ee7b84d
MS
1328 if (found_other)
1329 {
1330 as_warn (_("Opcode `%s' with these operand types not available in %s mode"),
1331 found_other->opcode->name,
1332 (! Hmode && ! Smode ? "H8/300"
1333 : SXmode ? "H8sx"
1334 : Smode ? "H8/300S"
1335 : "H8/300H"));
1336 }
1337 else if (found_mismatched)
1338 {
1339 as_warn (_("mismatch between opcode size and operand size"));
1340 return found_mismatched;
1341 }
1342 return 0;
252b5132
RH
1343}
1344
1345static void
1346check_operand (operand, width, string)
1347 struct h8_op *operand;
1348 unsigned int width;
1349 char *string;
1350{
1351 if (operand->exp.X_add_symbol == 0
1352 && operand->exp.X_op_symbol == 0)
1353 {
70d6ecf3
AM
1354 /* No symbol involved, let's look at offset, it's dangerous if
1355 any of the high bits are not 0 or ff's, find out by oring or
1356 anding with the width and seeing if the answer is 0 or all
1357 fs. */
252b5132 1358
7ee7b84d 1359 if (! constant_fits_width_p (operand, width))
252b5132 1360 {
70d6ecf3 1361 if (width == 255
252b5132
RH
1362 && (operand->exp.X_add_number & 0xff00) == 0xff00)
1363 {
1364 /* Just ignore this one - which happens when trying to
1365 fit a 16 bit address truncated into an 8 bit address
1366 of something like bset. */
1367 }
166e23f9
KH
1368 else if (strcmp (string, "@") == 0
1369 && width == 0xffff
1370 && (operand->exp.X_add_number & 0xff8000) == 0xff8000)
1371 {
1372 /* Just ignore this one - which happens when trying to
1373 fit a 24 bit address truncated into a 16 bit address
1374 of something like mov.w. */
1375 }
70d6ecf3 1376 else
252b5132
RH
1377 {
1378 as_warn (_("operand %s0x%lx out of range."), string,
1379 (unsigned long) operand->exp.X_add_number);
1380 }
1381 }
1382 }
252b5132
RH
1383}
1384
1385/* RELAXMODE has one of 3 values:
1386
1387 0 Output a "normal" reloc, no relaxing possible for this insn/reloc
1388
1389 1 Output a relaxable 24bit absolute mov.w address relocation
1390 (may relax into a 16bit absolute address).
1391
1392 2 Output a relaxable 16/24 absolute mov.b address relocation
1393 (may relax into an 8bit absolute address). */
1394
1395static void
7ee7b84d
MS
1396do_a_fix_imm (offset, nibble, operand, relaxmode)
1397 int offset, nibble;
252b5132
RH
1398 struct h8_op *operand;
1399 int relaxmode;
1400{
1401 int idx;
1402 int size;
1403 int where;
7ee7b84d 1404 char *bytes = frag_now->fr_literal + offset;
252b5132 1405
7ee7b84d 1406 char *t = ((operand->mode & MODE) == IMM) ? "#" : "@";
252b5132
RH
1407
1408 if (operand->exp.X_add_symbol == 0)
1409 {
252b5132
RH
1410 switch (operand->mode & SIZE)
1411 {
1412 case L_2:
1413 check_operand (operand, 0x3, t);
7ee7b84d 1414 bytes[0] |= (operand->exp.X_add_number & 3) << (nibble ? 0 : 4);
252b5132
RH
1415 break;
1416 case L_3:
7ee7b84d 1417 case L_3NZ:
252b5132 1418 check_operand (operand, 0x7, t);
7ee7b84d
MS
1419 bytes[0] |= (operand->exp.X_add_number & 7) << (nibble ? 0 : 4);
1420 break;
1421 case L_4:
1422 check_operand (operand, 0xF, t);
1423 bytes[0] |= (operand->exp.X_add_number & 15) << (nibble ? 0 : 4);
1424 break;
1425 case L_5:
1426 check_operand (operand, 0x1F, t);
1427 bytes[0] |= operand->exp.X_add_number & 31;
252b5132
RH
1428 break;
1429 case L_8:
7ee7b84d 1430 case L_8U:
252b5132 1431 check_operand (operand, 0xff, t);
7ee7b84d 1432 bytes[0] |= operand->exp.X_add_number;
252b5132
RH
1433 break;
1434 case L_16:
7ee7b84d 1435 case L_16U:
252b5132 1436 check_operand (operand, 0xffff, t);
7ee7b84d
MS
1437 bytes[0] |= operand->exp.X_add_number >> 8;
1438 bytes[1] |= operand->exp.X_add_number >> 0;
252b5132
RH
1439 break;
1440 case L_24:
1441 check_operand (operand, 0xffffff, t);
7ee7b84d
MS
1442 bytes[0] |= operand->exp.X_add_number >> 16;
1443 bytes[1] |= operand->exp.X_add_number >> 8;
1444 bytes[2] |= operand->exp.X_add_number >> 0;
252b5132
RH
1445 break;
1446
1447 case L_32:
70d6ecf3 1448 /* This should be done with bfd. */
7ee7b84d
MS
1449 bytes[0] |= operand->exp.X_add_number >> 24;
1450 bytes[1] |= operand->exp.X_add_number >> 16;
1451 bytes[2] |= operand->exp.X_add_number >> 8;
1452 bytes[3] |= operand->exp.X_add_number >> 0;
4132022d
AM
1453 if (relaxmode != 0)
1454 {
1455 idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
1456 fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
1457 }
252b5132
RH
1458 break;
1459 }
252b5132
RH
1460 }
1461 else
1462 {
1463 switch (operand->mode & SIZE)
1464 {
252b5132
RH
1465 case L_24:
1466 case L_32:
1467 size = 4;
1468 where = (operand->mode & SIZE) == L_24 ? -1 : 0;
1469 if (relaxmode == 2)
1470 idx = R_MOV24B1;
1471 else if (relaxmode == 1)
1472 idx = R_MOVL1;
1473 else
1474 idx = R_RELLONG;
1475 break;
1476 default:
70d6ecf3 1477 as_bad (_("Can't work out size of operand.\n"));
252b5132 1478 case L_16:
7ee7b84d 1479 case L_16U:
252b5132
RH
1480 size = 2;
1481 where = 0;
1482 if (relaxmode == 2)
1483 idx = R_MOV16B1;
1484 else
1485 idx = R_RELWORD;
4132022d
AM
1486 operand->exp.X_add_number =
1487 ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
7ee7b84d 1488 operand->exp.X_add_number |= (bytes[0] << 8) | bytes[1];
252b5132
RH
1489 break;
1490 case L_8:
1491 size = 1;
1492 where = 0;
1493 idx = R_RELBYTE;
4132022d
AM
1494 operand->exp.X_add_number =
1495 ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
7ee7b84d 1496 operand->exp.X_add_number |= bytes[0];
252b5132
RH
1497 }
1498
1499 fix_new_exp (frag_now,
1500 offset + where,
1501 size,
1502 &operand->exp,
1503 0,
1504 idx);
1505 }
252b5132
RH
1506}
1507
70d6ecf3 1508/* Now we know what sort of opcodes it is, let's build the bytes. */
3048287a 1509
252b5132
RH
1510static void
1511build_bytes (this_try, operand)
a720f7bc 1512 const struct h8_instruction *this_try;
252b5132
RH
1513 struct h8_op *operand;
1514{
3048287a 1515 int i;
252b5132 1516 char *output = frag_more (this_try->length);
a720f7bc 1517 op_type *nibble_ptr = this_try->opcode->data.nib;
252b5132
RH
1518 op_type c;
1519 unsigned int nibble_count = 0;
7ee7b84d 1520 int op_at[3];
3048287a 1521 int nib = 0;
252b5132 1522 int movb = 0;
7ee7b84d 1523 char asnibbles[100];
252b5132 1524 char *p = asnibbles;
7ee7b84d 1525 int high, low;
252b5132 1526
d4ea8842 1527 if (!Hmode && this_try->opcode->available != AV_H8)
252b5132 1528 as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
a720f7bc 1529 this_try->opcode->name);
d4ea8842
MS
1530 else if (!Smode
1531 && this_try->opcode->available != AV_H8
1532 && this_try->opcode->available != AV_H8H)
1533 as_warn (_("Opcode `%s' with these operand types not available in H8/300H mode"),
1534 this_try->opcode->name);
1535 else if (!SXmode
1536 && this_try->opcode->available != AV_H8
1537 && this_try->opcode->available != AV_H8H
1538 && this_try->opcode->available != AV_H8S)
1539 as_warn (_("Opcode `%s' with these operand types not available in H8/300S mode"),
1540 this_try->opcode->name);
252b5132 1541
7ee7b84d 1542 while (*nibble_ptr != (op_type) E)
252b5132
RH
1543 {
1544 int d;
7ee7b84d
MS
1545
1546 nib = 0;
252b5132
RH
1547 c = *nibble_ptr++;
1548
7ee7b84d 1549 d = (c & OP3) == OP3 ? 2 : (c & DST) == DST ? 1 : 0;
252b5132
RH
1550
1551 if (c < 16)
3048287a 1552 nib = c;
252b5132
RH
1553 else
1554 {
7ee7b84d
MS
1555 int c2 = c & MODE;
1556
1557 if (c2 == REG || c2 == LOWREG
1558 || c2 == IND || c2 == PREINC || c2 == PREDEC
1559 || c2 == POSTINC || c2 == POSTDEC)
1560 {
1561 nib = operand[d].reg;
1562 if (c2 == LOWREG)
1563 nib &= 7;
1564 }
1565
1566 else if (c & CTRL) /* Control reg operand. */
3048287a
NC
1567 nib = operand[d].reg;
1568
252b5132 1569 else if ((c & DISPREG) == (DISPREG))
7ee7b84d
MS
1570 {
1571 nib = operand[d].reg;
1572 }
1573 else if (c2 == ABS)
252b5132
RH
1574 {
1575 operand[d].mode = c;
7ee7b84d 1576 op_at[d] = nibble_count;
252b5132
RH
1577 nib = 0;
1578 }
7ee7b84d
MS
1579 else if (c2 == IMM || c2 == PCREL || c2 == ABS
1580 || (c & ABSJMP) || c2 == DISP)
252b5132
RH
1581 {
1582 operand[d].mode = c;
7ee7b84d 1583 op_at[d] = nibble_count;
252b5132
RH
1584 nib = 0;
1585 }
7ee7b84d 1586 else if ((c & IGNORE) || (c & DATA))
3048287a
NC
1587 nib = 0;
1588
7ee7b84d 1589 else if (c2 == DBIT)
252b5132
RH
1590 {
1591 switch (operand[0].exp.X_add_number)
1592 {
1593 case 1:
1594 nib = c;
1595 break;
1596 case 2:
1597 nib = 0x8 | c;
1598 break;
1599 default:
1600 as_bad (_("Need #1 or #2 here"));
1601 }
1602 }
7ee7b84d 1603 else if (c2 == KBIT)
252b5132
RH
1604 {
1605 switch (operand[0].exp.X_add_number)
1606 {
1607 case 1:
1608 nib = 0;
1609 break;
1610 case 2:
1611 nib = 8;
1612 break;
1613 case 4:
1614 if (!Hmode)
1615 as_warn (_("#4 not valid on H8/300."));
1616 nib = 9;
1617 break;
1618
1619 default:
1620 as_bad (_("Need #1 or #2 here"));
1621 break;
1622 }
70d6ecf3 1623 /* Stop it making a fix. */
252b5132
RH
1624 operand[0].mode = 0;
1625 }
1626
1627 if (c & MEMRELAX)
3048287a 1628 operand[d].mode |= MEMRELAX;
252b5132
RH
1629
1630 if (c & B31)
3048287a 1631 nib |= 0x8;
252b5132 1632
7ee7b84d
MS
1633 if (c & B21)
1634 nib |= 0x4;
1635
1636 if (c & B11)
1637 nib |= 0x2;
1638
1639 if (c & B01)
1640 nib |= 0x1;
1641
1642 if (c2 == MACREG)
252b5132 1643 {
f0c56b90
NC
1644 if (operand[0].mode == MACREG)
1645 /* stmac has mac[hl] as the first operand. */
1646 nib = 2 + operand[0].reg;
1647 else
1648 /* ldmac has mac[hl] as the second operand. */
1649 nib = 2 + operand[1].reg;
252b5132
RH
1650 }
1651 }
1652 nibble_count++;
1653
1654 *p++ = nib;
1655 }
1656
1657 /* Disgusting. Why, oh why didn't someone ask us for advice
1658 on the assembler format. */
7ee7b84d 1659 if (OP_KIND (this_try->opcode->how) == O_LDM)
252b5132 1660 {
7ee7b84d
MS
1661 high = (operand[1].reg >> 8) & 0xf;
1662 low = (operand[1].reg) & 0xf;
252b5132 1663 asnibbles[2] = high - low;
7ee7b84d
MS
1664 asnibbles[7] = high;
1665 }
1666 else if (OP_KIND (this_try->opcode->how) == O_STM)
1667 {
1668 high = (operand[0].reg >> 8) & 0xf;
1669 low = (operand[0].reg) & 0xf;
1670 asnibbles[2] = high - low;
1671 asnibbles[7] = low;
252b5132
RH
1672 }
1673
1674 for (i = 0; i < this_try->length; i++)
3048287a 1675 output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
252b5132
RH
1676
1677 /* Note if this is a movb instruction -- there's a special relaxation
1678 which only applies to them. */
7ee7b84d 1679 if (this_try->opcode->how == O (O_MOV, SB))
252b5132
RH
1680 movb = 1;
1681
70d6ecf3 1682 /* Output any fixes. */
7ee7b84d 1683 for (i = 0; i < this_try->noperands; i++)
252b5132
RH
1684 {
1685 int x = operand[i].mode;
7ee7b84d 1686 int x_mode = x & MODE;
252b5132 1687
7ee7b84d
MS
1688 if (x_mode == IMM || x_mode == DISP)
1689 do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
1690 op_at[i] & 1, operand + i, (x & MEMRELAX) != 0);
3048287a 1691
7ee7b84d
MS
1692 else if (x_mode == ABS)
1693 do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
1694 op_at[i] & 1, operand + i,
1695 (x & MEMRELAX) ? movb + 1 : 0);
3048287a 1696
7ee7b84d 1697 else if (x_mode == PCREL)
252b5132 1698 {
7ee7b84d 1699 int size16 = (x & SIZE) == L_16;
252b5132
RH
1700 int size = size16 ? 2 : 1;
1701 int type = size16 ? R_PCRWORD : R_PCRBYTE;
36ed2fff 1702 fixS *fixP;
252b5132
RH
1703
1704 check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
1705
1706 if (operand[i].exp.X_add_number & 1)
3048287a
NC
1707 as_warn (_("branch operand has odd offset (%lx)\n"),
1708 (unsigned long) operand->exp.X_add_number);
36ed2fff
JL
1709#ifndef OBJ_ELF
1710 /* The COFF port has always been off by one, changing it
1711 now would be an incompatible change, so we leave it as-is.
1712
1713 We don't want to do this for ELF as we want to be
1714 compatible with the proposed ELF format from Hitachi. */
252b5132 1715 operand[i].exp.X_add_number -= 1;
36ed2fff 1716#endif
7ee7b84d
MS
1717 if (size16)
1718 {
1719 operand[i].exp.X_add_number =
1720 ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
1721 }
1722 else
1723 {
1724 operand[i].exp.X_add_number =
1725 ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
1726 }
1727
1728 /* For BRA/S. */
1729 if (! size16)
1730 operand[i].exp.X_add_number |= output[op_at[i] / 2];
252b5132 1731
36ed2fff 1732 fixP = fix_new_exp (frag_now,
7ee7b84d 1733 output - frag_now->fr_literal + op_at[i] / 2,
36ed2fff
JL
1734 size,
1735 &operand[i].exp,
1736 1,
1737 type);
1738 fixP->fx_signed = 1;
252b5132 1739 }
7ee7b84d 1740 else if (x_mode == MEMIND)
252b5132 1741 {
252b5132
RH
1742 check_operand (operand + i, 0xff, "@@");
1743 fix_new_exp (frag_now,
1744 output - frag_now->fr_literal + 1,
1745 1,
1746 &operand[i].exp,
1747 0,
1748 R_MEM_INDIRECT);
1749 }
7ee7b84d
MS
1750 else if (x_mode == VECIND)
1751 {
1752 check_operand (operand + i, 0x7f, "@@");
1753 /* FIXME: approximating the effect of "B31" here...
1754 This is very hackish, and ought to be done a better way. */
1755 operand[i].exp.X_add_number |= 0x80;
1756 fix_new_exp (frag_now,
1757 output - frag_now->fr_literal + 1,
1758 1,
1759 &operand[i].exp,
1760 0,
1761 R_MEM_INDIRECT);
1762 }
252b5132
RH
1763 else if (x & ABSJMP)
1764 {
3c1ba8a3 1765 int where = 0;
7ee7b84d 1766 bfd_reloc_code_real_type reloc_type = R_JMPL1;
3c1ba8a3
JL
1767
1768#ifdef OBJ_ELF
1769 /* To be compatible with the proposed H8 ELF format, we
1770 want the relocation's offset to point to the first byte
1771 that will be modified, not to the start of the instruction. */
7ee7b84d
MS
1772
1773 if ((operand->mode & SIZE) == L_32)
1774 {
1775 where = 2;
1776 reloc_type = R_RELLONG;
1777 }
1778 else
1779 where = 1;
3c1ba8a3 1780#endif
de342d07 1781
70d6ecf3 1782 /* This jmp may be a jump or a branch. */
252b5132 1783
7ee7b84d
MS
1784 check_operand (operand + i,
1785 SXmode ? 0xffffffff : Hmode ? 0xffffff : 0xffff,
1786 "@");
3048287a 1787
252b5132 1788 if (operand[i].exp.X_add_number & 1)
3048287a
NC
1789 as_warn (_("branch operand has odd offset (%lx)\n"),
1790 (unsigned long) operand->exp.X_add_number);
1791
252b5132 1792 if (!Hmode)
70d6ecf3 1793 operand[i].exp.X_add_number =
4132022d 1794 ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
252b5132 1795 fix_new_exp (frag_now,
3c1ba8a3 1796 output - frag_now->fr_literal + where,
252b5132
RH
1797 4,
1798 &operand[i].exp,
1799 0,
7ee7b84d 1800 reloc_type);
252b5132
RH
1801 }
1802 }
252b5132
RH
1803}
1804
70d6ecf3
AM
1805/* Try to give an intelligent error message for common and simple to
1806 detect errors. */
3048287a 1807
252b5132 1808static void
a720f7bc
KD
1809clever_message (instruction, operand)
1810 const struct h8_instruction *instruction;
252b5132
RH
1811 struct h8_op *operand;
1812{
70d6ecf3 1813 /* Find out if there was more than one possible opcode. */
252b5132 1814
a720f7bc 1815 if ((instruction + 1)->idx != instruction->idx)
252b5132 1816 {
3048287a 1817 int argn;
252b5132 1818
70d6ecf3
AM
1819 /* Only one opcode of this flavour, try to guess which operand
1820 didn't match. */
a720f7bc 1821 for (argn = 0; argn < instruction->noperands; argn++)
252b5132 1822 {
a720f7bc 1823 switch (instruction->opcode->args.nib[argn])
252b5132
RH
1824 {
1825 case RD16:
1826 if (operand[argn].mode != RD16)
1827 {
1828 as_bad (_("destination operand must be 16 bit register"));
1829 return;
1830
1831 }
1832 break;
1833
1834 case RS8:
252b5132
RH
1835 if (operand[argn].mode != RS8)
1836 {
1837 as_bad (_("source operand must be 8 bit register"));
1838 return;
1839 }
1840 break;
1841
1842 case ABS16DST:
1843 if (operand[argn].mode != ABS16DST)
1844 {
1845 as_bad (_("destination operand must be 16bit absolute address"));
1846 return;
1847 }
1848 break;
1849 case RD8:
1850 if (operand[argn].mode != RD8)
1851 {
1852 as_bad (_("destination operand must be 8 bit register"));
1853 return;
1854 }
1855 break;
1856
252b5132
RH
1857 case ABS16SRC:
1858 if (operand[argn].mode != ABS16SRC)
1859 {
1860 as_bad (_("source operand must be 16bit absolute address"));
1861 return;
1862 }
1863 break;
1864
1865 }
1866 }
1867 }
1868 as_bad (_("invalid operands"));
1869}
1870
d4ea8842
MS
1871
1872/* Adjust OPERAND's value and size given that it is accessing a field
1873 of SIZE bytes.
1874
1875 This function handles the choice between @(d:2,ERn) and @(d:16,ERn)
1876 when no size is explicitly given. It also scales down the assembly-level
1877 displacement in an @(d:2,ERn) operand. */
1878
1879static void
1880fix_operand_size (operand, size)
1881 struct h8_op *operand;
1882 int size;
1883{
1884 if ((operand->mode & MODE) == DISP)
1885 {
1886 /* If the user didn't specify an operand width, see if we
1887 can use @(d:2,ERn). */
1888 if (SXmode
1889 && (operand->mode & SIZE) == 0
1890 && (operand->exp.X_add_number == size
1891 || operand->exp.X_add_number == size * 2
1892 || operand->exp.X_add_number == size * 3))
1893 operand->mode |= L_2;
1894
1895 /* Scale down the displacement in an @(d:2,ERn) operand.
1896 X_add_number then contains the desired field value. */
1897 if ((operand->mode & SIZE) == L_2)
1898 {
1899 if (operand->exp.X_add_number % size != 0)
1900 as_warn (_("operand/size mis-match"));
1901 operand->exp.X_add_number /= size;
1902 }
1903 }
1904
1905 /* If the operand needs a size but doesn't have one yet, it must be
1906 a 16-bit integer (see colonmod24). */
1907 if ((operand->mode & SIZE) == 0)
1908 switch (operand->mode & MODE)
1909 {
1910 case DISP:
1911 case INDEXB:
1912 case INDEXW:
1913 case INDEXL:
1914 case ABS:
1915 operand->mode |= L_16;
1916 break;
1917 }
1918}
1919
1920
70d6ecf3
AM
1921/* This is the guts of the machine-dependent assembler. STR points to
1922 a machine dependent instruction. This function is supposed to emit
1923 the frags/bytes it assembles. */
3048287a 1924
252b5132
RH
1925void
1926md_assemble (str)
1927 char *str;
1928{
1929 char *op_start;
1930 char *op_end;
7ee7b84d 1931 struct h8_op operand[3];
a720f7bc
KD
1932 const struct h8_instruction *instruction;
1933 const struct h8_instruction *prev_instruction;
252b5132
RH
1934
1935 char *dot = 0;
1936 char c;
7ee7b84d 1937 int size, i;
252b5132 1938
70d6ecf3 1939 /* Drop leading whitespace. */
252b5132
RH
1940 while (*str == ' ')
1941 str++;
1942
70d6ecf3 1943 /* Find the op code end. */
252b5132
RH
1944 for (op_start = op_end = str;
1945 *op_end != 0 && *op_end != ' ';
1946 op_end++)
1947 {
1948 if (*op_end == '.')
1949 {
1950 dot = op_end + 1;
1951 *op_end = 0;
1952 op_end += 2;
1953 break;
1954 }
1955 }
1956
252b5132
RH
1957 if (op_end == op_start)
1958 {
1959 as_bad (_("can't find opcode "));
1960 }
1961 c = *op_end;
1962
1963 *op_end = 0;
1964
a720f7bc
KD
1965 instruction = (const struct h8_instruction *)
1966 hash_find (opcode_hash_control, op_start);
252b5132 1967
a720f7bc 1968 if (instruction == NULL)
252b5132
RH
1969 {
1970 as_bad (_("unknown opcode"));
1971 return;
1972 }
1973
70d6ecf3 1974 /* We used to set input_line_pointer to the result of get_operands,
252b5132
RH
1975 but that is wrong. Our caller assumes we don't change it. */
1976
7ee7b84d
MS
1977 operand[0].mode = 0;
1978 operand[1].mode = 0;
1979 operand[2].mode = 0;
1980
1981 if (OP_KIND (instruction->opcode->how) == O_MOVAB
1982 || OP_KIND (instruction->opcode->how) == O_MOVAW
1983 || OP_KIND (instruction->opcode->how) == O_MOVAL)
1984 get_mova_operands (op_end, operand);
1985 else if (OP_KIND (instruction->opcode->how) == O_RTEL
1986 || OP_KIND (instruction->opcode->how) == O_RTSL)
1987 get_rtsl_operands (op_end, operand);
1988 else
1989 get_operands (instruction->noperands, op_end, operand);
1990
252b5132 1991 *op_end = c;
a720f7bc 1992 prev_instruction = instruction;
252b5132
RH
1993
1994 size = SN;
1995 if (dot)
1996 {
1997 switch (*dot)
1998 {
1999 case 'b':
2000 size = SB;
2001 break;
2002
2003 case 'w':
2004 size = SW;
2005 break;
2006
2007 case 'l':
2008 size = SL;
2009 break;
2010 }
2011 }
7ee7b84d
MS
2012 if (OP_KIND (instruction->opcode->how) == O_MOVAB ||
2013 OP_KIND (instruction->opcode->how) == O_MOVAW ||
2014 OP_KIND (instruction->opcode->how) == O_MOVAL)
252b5132 2015 {
d4ea8842
MS
2016 switch (operand[0].mode & MODE)
2017 {
7ee7b84d
MS
2018 case INDEXB:
2019 default:
d4ea8842 2020 fix_operand_size (&operand[1], 1);
7ee7b84d
MS
2021 break;
2022 case INDEXW:
d4ea8842 2023 fix_operand_size (&operand[1], 2);
7ee7b84d
MS
2024 break;
2025 case INDEXL:
d4ea8842 2026 fix_operand_size (&operand[1], 4);
7ee7b84d 2027 break;
252b5132
RH
2028 }
2029 }
7ee7b84d
MS
2030 else
2031 {
d4ea8842
MS
2032 for (i = 0; i < 3 && operand[i].mode != 0; i++)
2033 switch (size)
2034 {
7ee7b84d
MS
2035 case SN:
2036 case SB:
2037 default:
d4ea8842 2038 fix_operand_size (&operand[i], 1);
7ee7b84d
MS
2039 break;
2040 case SW:
d4ea8842 2041 fix_operand_size (&operand[i], 2);
7ee7b84d
MS
2042 break;
2043 case SL:
d4ea8842 2044 fix_operand_size (&operand[i], 4);
7ee7b84d
MS
2045 break;
2046 }
2047 }
252b5132 2048
d4ea8842
MS
2049 instruction = get_specific (instruction, operand, size);
2050
2051 if (instruction == 0)
2052 {
2053 /* Couldn't find an opcode which matched the operands. */
2054 char *where = frag_more (2);
2055
2056 where[0] = 0x0;
2057 where[1] = 0x0;
2058 clever_message (prev_instruction, operand);
2059
2060 return;
2061 }
2062
a720f7bc 2063 build_bytes (instruction, operand);
2c8714f2
NC
2064
2065#ifdef BFD_ASSEMBLER
2066 dwarf2_emit_insn (instruction->length);
2067#endif
252b5132
RH
2068}
2069
5facebfc 2070#ifndef BFD_ASSEMBLER
252b5132
RH
2071void
2072tc_crawl_symbol_chain (headers)
70d6ecf3 2073 object_headers *headers ATTRIBUTE_UNUSED;
252b5132
RH
2074{
2075 printf (_("call to tc_crawl_symbol_chain \n"));
2076}
f333765f 2077#endif
252b5132
RH
2078
2079symbolS *
2080md_undefined_symbol (name)
dbbc7809 2081 char *name ATTRIBUTE_UNUSED;
252b5132
RH
2082{
2083 return 0;
2084}
2085
5facebfc 2086#ifndef BFD_ASSEMBLER
252b5132
RH
2087void
2088tc_headers_hook (headers)
70d6ecf3 2089 object_headers *headers ATTRIBUTE_UNUSED;
252b5132
RH
2090{
2091 printf (_("call to tc_headers_hook \n"));
2092}
f333765f 2093#endif
252b5132
RH
2094
2095/* Various routines to kill one day */
2096/* Equal to MAX_PRECISION in atof-ieee.c */
2097#define MAX_LITTLENUMS 6
2098
70d6ecf3
AM
2099/* Turn a string in input_line_pointer into a floating point constant
2100 of type TYPE, and store the appropriate bytes in *LITP. The number
bc0d738a 2101 of LITTLENUMS emitted is stored in *SIZEP. An error message is
70d6ecf3 2102 returned, or NULL on OK. */
bc0d738a 2103
252b5132
RH
2104char *
2105md_atof (type, litP, sizeP)
2106 char type;
2107 char *litP;
2108 int *sizeP;
2109{
2110 int prec;
2111 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2112 LITTLENUM_TYPE *wordP;
2113 char *t;
252b5132
RH
2114
2115 switch (type)
2116 {
2117 case 'f':
2118 case 'F':
2119 case 's':
2120 case 'S':
2121 prec = 2;
2122 break;
2123
2124 case 'd':
2125 case 'D':
2126 case 'r':
2127 case 'R':
2128 prec = 4;
2129 break;
2130
2131 case 'x':
2132 case 'X':
2133 prec = 6;
2134 break;
2135
2136 case 'p':
2137 case 'P':
2138 prec = 6;
2139 break;
2140
2141 default:
2142 *sizeP = 0;
2143 return _("Bad call to MD_ATOF()");
2144 }
2145 t = atof_ieee (input_line_pointer, type, words);
2146 if (t)
2147 input_line_pointer = t;
2148
2149 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2150 for (wordP = words; prec--;)
2151 {
2152 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
2153 litP += sizeof (LITTLENUM_TYPE);
2154 }
2155 return 0;
2156}
2157\f
5a38dc70 2158const char *md_shortopts = "";
252b5132
RH
2159struct option md_longopts[] = {
2160 {NULL, no_argument, NULL, 0}
2161};
70d6ecf3
AM
2162
2163size_t md_longopts_size = sizeof (md_longopts);
252b5132
RH
2164
2165int
2166md_parse_option (c, arg)
dbbc7809
JL
2167 int c ATTRIBUTE_UNUSED;
2168 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
2169{
2170 return 0;
2171}
2172
2173void
2174md_show_usage (stream)
dbbc7809 2175 FILE *stream ATTRIBUTE_UNUSED;
252b5132
RH
2176{
2177}
2178\f
3048287a
NC
2179void tc_aout_fix_to_chars PARAMS ((void));
2180
252b5132
RH
2181void
2182tc_aout_fix_to_chars ()
2183{
2184 printf (_("call to tc_aout_fix_to_chars \n"));
2185 abort ();
2186}
2187
2188void
2189md_convert_frag (headers, seg, fragP)
36ed2fff
JL
2190#ifdef BFD_ASSEMBLER
2191 bfd *headers ATTRIBUTE_UNUSED;
2192#else
dbbc7809 2193 object_headers *headers ATTRIBUTE_UNUSED;
36ed2fff 2194#endif
dbbc7809
JL
2195 segT seg ATTRIBUTE_UNUSED;
2196 fragS *fragP ATTRIBUTE_UNUSED;
252b5132
RH
2197{
2198 printf (_("call to md_convert_frag \n"));
2199 abort ();
2200}
2201
3c1ba8a3
JL
2202#ifdef BFD_ASSEMBLER
2203valueT
2204md_section_align (segment, size)
2205 segT segment;
2206 valueT size;
2207{
2208 int align = bfd_get_section_alignment (stdoutput, segment);
2209 return ((size + (1 << align) - 1) & (-1 << align));
2210}
2211#else
70d6ecf3 2212valueT
252b5132
RH
2213md_section_align (seg, size)
2214 segT seg;
2215 valueT size;
2216{
70d6ecf3 2217 return ((size + (1 << section_alignment[(int) seg]) - 1)
cc8a6dd0 2218 & (-1 << section_alignment[(int) seg]));
252b5132 2219}
3c1ba8a3
JL
2220#endif
2221
252b5132
RH
2222
2223void
94f592af 2224md_apply_fix3 (fixP, valP, seg)
252b5132 2225 fixS *fixP;
94f592af
NC
2226 valueT *valP;
2227 segT seg ATTRIBUTE_UNUSED;
252b5132
RH
2228{
2229 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
a161fe53 2230 long val = *valP;
252b5132
RH
2231
2232 switch (fixP->fx_size)
2233 {
2234 case 1:
2235 *buf++ = val;
2236 break;
2237 case 2:
2238 *buf++ = (val >> 8);
2239 *buf++ = val;
2240 break;
2241 case 4:
2242 *buf++ = (val >> 24);
2243 *buf++ = (val >> 16);
2244 *buf++ = (val >> 8);
2245 *buf++ = val;
2246 break;
2247 default:
2248 abort ();
2249 }
94f592af
NC
2250
2251 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
2252 fixP->fx_done = 1;
252b5132
RH
2253}
2254
2255int
2256md_estimate_size_before_relax (fragP, segment_type)
dbbc7809
JL
2257 register fragS *fragP ATTRIBUTE_UNUSED;
2258 register segT segment_type ATTRIBUTE_UNUSED;
252b5132
RH
2259{
2260 printf (_("call tomd_estimate_size_before_relax \n"));
2261 abort ();
2262}
2263
70d6ecf3 2264/* Put number into target byte order. */
252b5132
RH
2265void
2266md_number_to_chars (ptr, use, nbytes)
2267 char *ptr;
2268 valueT use;
2269 int nbytes;
2270{
2271 number_to_chars_bigendian (ptr, use, nbytes);
2272}
70d6ecf3 2273
252b5132
RH
2274long
2275md_pcrel_from (fixP)
dbbc7809 2276 fixS *fixP ATTRIBUTE_UNUSED;
252b5132
RH
2277{
2278 abort ();
2279}
2280
5facebfc 2281#ifndef BFD_ASSEMBLER
252b5132
RH
2282void
2283tc_reloc_mangle (fix_ptr, intr, base)
2284 fixS *fix_ptr;
2285 struct internal_reloc *intr;
2286 bfd_vma base;
2287
2288{
2289 symbolS *symbol_ptr;
2290
2291 symbol_ptr = fix_ptr->fx_addsy;
2292
2293 /* If this relocation is attached to a symbol then it's ok
70d6ecf3 2294 to output it. */
252b5132
RH
2295 if (fix_ptr->fx_r_type == TC_CONS_RELOC)
2296 {
2297 /* cons likes to create reloc32's whatever the size of the reloc..
2298 */
2299 switch (fix_ptr->fx_size)
2300 {
2301 case 4:
2302 intr->r_type = R_RELLONG;
2303 break;
2304 case 2:
2305 intr->r_type = R_RELWORD;
2306 break;
2307 case 1:
2308 intr->r_type = R_RELBYTE;
2309 break;
2310 default:
2311 abort ();
252b5132 2312 }
252b5132
RH
2313 }
2314 else
2315 {
2316 intr->r_type = fix_ptr->fx_r_type;
2317 }
2318
2319 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
2320 intr->r_offset = fix_ptr->fx_offset;
2321
2322 if (symbol_ptr)
2323 {
2324 if (symbol_ptr->sy_number != -1)
2325 intr->r_symndx = symbol_ptr->sy_number;
2326 else
2327 {
2328 symbolS *segsym;
2329
2330 /* This case arises when a reference is made to `.'. */
2331 segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;
2332 if (segsym == NULL)
2333 intr->r_symndx = -1;
2334 else
2335 {
2336 intr->r_symndx = segsym->sy_number;
2337 intr->r_offset += S_GET_VALUE (symbol_ptr);
2338 }
2339 }
2340 }
2341 else
2342 intr->r_symndx = -1;
252b5132 2343}
5facebfc 2344#else /* BFD_ASSEMBLER */
f333765f
JL
2345arelent *
2346tc_gen_reloc (section, fixp)
2347 asection *section ATTRIBUTE_UNUSED;
2348 fixS *fixp;
2349{
2350 arelent *rel;
2351 bfd_reloc_code_real_type r_type;
2352
de342d07
JL
2353 if (fixp->fx_addsy && fixp->fx_subsy)
2354 {
2355 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
2356 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
2357 {
2358 as_bad_where (fixp->fx_file, fixp->fx_line,
2359 "Difference of symbols in different sections is not supported");
2360 return NULL;
2361 }
2362 }
2363
f333765f
JL
2364 rel = (arelent *) xmalloc (sizeof (arelent));
2365 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2366 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2367 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2368 rel->addend = fixp->fx_offset;
2369
2370 r_type = fixp->fx_r_type;
2371
2372#define DEBUG 0
2373#if DEBUG
2374 fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
2375 fflush(stderr);
2376#endif
2377 rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
2378 if (rel->howto == NULL)
2379 {
2380 as_bad_where (fixp->fx_file, fixp->fx_line,
2381 _("Cannot represent relocation type %s"),
2382 bfd_get_reloc_code_name (r_type));
2383 return NULL;
2384 }
2385
2386 return rel;
2387}
2388#endif
This page took 0.303052 seconds and 4 git commands to generate.