merge from gcc
[binutils.git] / gas / config / tc-z80.c
blob76d46f55492104e4dbc66b50dc47cb8623445a3b
1 /* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800
2 Copyright 2005 Free Software Foundation, Inc.
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
5 This file is part of GAS, the GNU Assembler.
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.
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.
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, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "as.h"
23 #include "listing.h"
24 #include "bfd.h"
25 #include "safe-ctype.h"
26 #include "subsegs.h"
27 #include "symbols.h"
28 #include "libiberty.h"
30 /* Exported constants. */
31 const char comment_chars[] = ";\0";
32 const char line_comment_chars[] = "#;\0";
33 const char line_separator_chars[] = "\0";
34 const char EXP_CHARS[] = "eE\0";
35 const char FLT_CHARS[] = "RrFf\0";
37 /* For machine specific options. */
38 const char * md_shortopts = ""; /* None yet. */
40 enum options
42 OPTION_MACH_Z80 = OPTION_MD_BASE,
43 OPTION_MACH_R800,
44 OPTION_MACH_IUD,
45 OPTION_MACH_WUD,
46 OPTION_MACH_FUD,
47 OPTION_MACH_IUP,
48 OPTION_MACH_WUP,
49 OPTION_MACH_FUP
52 #define INS_Z80 1
53 #define INS_UNDOC 2
54 #define INS_UNPORT 4
55 #define INS_R800 8
57 struct option md_longopts[] =
59 { "z80", no_argument, NULL, OPTION_MACH_Z80},
60 { "r800", no_argument, NULL, OPTION_MACH_R800},
61 { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD },
62 { "Wnud", no_argument, NULL, OPTION_MACH_IUD },
63 { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD },
64 { "Wud", no_argument, NULL, OPTION_MACH_WUD },
65 { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD },
66 { "Fud", no_argument, NULL, OPTION_MACH_FUD },
67 { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP },
68 { "Wnup", no_argument, NULL, OPTION_MACH_IUP },
69 { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP },
70 { "Wup", no_argument, NULL, OPTION_MACH_WUP },
71 { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP },
72 { "Fup", no_argument, NULL, OPTION_MACH_FUP },
74 { NULL, no_argument, NULL, 0 }
75 } ;
77 size_t md_longopts_size = sizeof (md_longopts);
79 extern int coff_flags;
80 /* Instruction classes that silently assembled. */
81 static int ins_ok = INS_Z80 | INS_UNDOC;
82 /* Instruction classes that generate errors. */
83 static int ins_err = INS_R800;
84 /* Instruction classes actually used, determines machine type. */
85 static int ins_used = INS_Z80;
87 int
88 md_parse_option (int c, char* arg ATTRIBUTE_UNUSED)
90 switch (c)
92 default:
93 return 0;
94 case OPTION_MACH_Z80:
95 ins_ok &= ~INS_R800;
96 ins_err |= INS_R800;
97 break;
98 case OPTION_MACH_R800:
99 ins_ok = INS_Z80 | INS_UNDOC | INS_R800;
100 ins_err = INS_UNPORT;
101 break;
102 case OPTION_MACH_IUD:
103 ins_ok |= INS_UNDOC;
104 ins_err &= ~INS_UNDOC;
105 break;
106 case OPTION_MACH_IUP:
107 ins_ok |= INS_UNDOC | INS_UNPORT;
108 ins_err &= ~(INS_UNDOC | INS_UNPORT);
109 break;
110 case OPTION_MACH_WUD:
111 if ((ins_ok & INS_R800) == 0)
113 ins_ok &= ~(INS_UNDOC|INS_UNPORT);
114 ins_err &= ~INS_UNDOC;
116 break;
117 case OPTION_MACH_WUP:
118 ins_ok &= ~INS_UNPORT;
119 ins_err &= ~(INS_UNDOC|INS_UNPORT);
120 break;
121 case OPTION_MACH_FUD:
122 if ((ins_ok & INS_R800) == 0)
124 ins_ok &= (INS_UNDOC | INS_UNPORT);
125 ins_err |= INS_UNDOC | INS_UNPORT;
127 break;
128 case OPTION_MACH_FUP:
129 ins_ok &= ~INS_UNPORT;
130 ins_err |= INS_UNPORT;
131 break;
134 return 1;
137 void
138 md_show_usage (FILE * f)
140 fprintf (f, "\n\
141 CPU model/instruction set options:\n\
143 -z80\t\t assemble for Z80\n\
144 -ignore-undocumented-instructions\n\
145 -Wnud\n\
146 \tsilently assemble undocumented Z80-instructions that work on R800\n\
147 -ignore-unportable-instructions\n\
148 -Wnup\n\
149 \tsilently assemble all undocumented Z80-instructions\n\
150 -warn-undocumented-instructions\n\
151 -Wud\n\
152 \tissue warnings for undocumented Z80-instructions that work on R800\n\
153 -warn-unportable-instructions\n\
154 -Wup\n\
155 \tissue warnings for other undocumented Z80-instructions\n\
156 -forbid-undocumented-instructions\n\
157 -Fud\n\
158 \ttreat all undocumented z80-instructions as errors\n\
159 -forbid-unportable-instructions\n\
160 -Fup\n\
161 \ttreat undocumented z80-instructions that do not work on R800 as errors\n\
162 -r800\t assemble for R800\n\n\
163 Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n");
166 static symbolS * zero;
168 void
169 md_begin (void)
171 expressionS nul;
172 char * p;
174 p = input_line_pointer;
175 input_line_pointer = "0";
176 nul.X_md=0;
177 expression (& nul);
178 input_line_pointer = p;
179 zero = make_expr_symbol (& nul);
180 /* We do not use relaxation (yet). */
181 linkrelax = 0;
184 void
185 z80_md_end (void)
187 int mach_type;
189 if (ins_used & (INS_UNPORT | INS_R800))
190 ins_used |= INS_UNDOC;
192 switch (ins_used)
194 case INS_Z80:
195 mach_type = bfd_mach_z80strict;
196 break;
197 case INS_Z80|INS_UNDOC:
198 mach_type = bfd_mach_z80;
199 break;
200 case INS_Z80|INS_UNDOC|INS_UNPORT:
201 mach_type = bfd_mach_z80full;
202 break;
203 case INS_Z80|INS_UNDOC|INS_R800:
204 mach_type = bfd_mach_r800;
205 break;
206 default:
207 mach_type = 0;
210 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
213 static const char *
214 skip_space (const char *s)
216 while (*s == ' ' || *s == '\t')
217 ++s;
218 return s;
221 /* A non-zero return-value causes a continue in the
222 function read_a_source_file () in ../read.c. */
224 z80_start_line_hook (void)
226 char *p, quote;
227 char buf[4];
229 /* Convert one character constants. */
230 for (p = input_line_pointer; *p && *p != '\n'; ++p)
232 switch (*p)
234 case '\'':
235 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
237 snprintf (buf, 4, "%3d", (unsigned char)p[1]);
238 *p++ = buf[0];
239 *p++ = buf[1];
240 *p++ = buf[2];
241 break;
243 case '"':
244 for (quote = *p++; quote != *p && '\n' != *p; ++p)
245 /* No escapes. */ ;
246 if (quote != *p)
248 as_bad (_("-- unterminated string"));
249 ignore_rest_of_line ();
250 return 1;
252 break;
255 /* Check for <label>[:] [.](EQU|DEFL) <value>. */
256 if (is_name_beginner (*input_line_pointer))
258 char c, *rest, *line_start;
259 int len;
260 symbolS * symbolP;
262 line_start = input_line_pointer;
263 LISTING_NEWLINE ();
264 if (ignore_input ())
265 return 0;
267 c = get_symbol_end ();
268 rest = input_line_pointer + 1;
270 if (*rest == ':')
271 ++rest;
272 if (*rest == ' ' || *rest == '\t')
273 ++rest;
274 if (*rest == '.')
275 ++rest;
276 if (strncasecmp (rest, "EQU", 3) == 0)
277 len = 3;
278 else if (strncasecmp (rest, "DEFL", 4) == 0)
279 len = 4;
280 else
281 len = 0;
282 if (len && (rest[len] == ' ' || rest[len] == '\t'))
284 /* Handle assignment here. */
285 input_line_pointer = rest + len;
286 if (line_start[-1] == '\n')
287 bump_line_counters ();
288 /* Most Z80 assemblers require the first definition of a
289 label to use "EQU" and redefinitions to have "DEFL". */
290 if (len == 3 && (symbolP = symbol_find (line_start)) != NULL)
292 if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
293 as_bad (_("symbol `%s' is already defined"), line_start);
295 equals (line_start, 1);
296 return 1;
298 else
300 /* Restore line and pointer. */
301 *input_line_pointer = c;
302 input_line_pointer = line_start;
305 return 0;
308 symbolS *
309 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
311 return NULL;
314 char *
315 md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED,
316 int *sizeP ATTRIBUTE_UNUSED)
318 return _("floating point numbers are not implemented");
321 valueT
322 md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
324 return size;
327 long
328 md_pcrel_from (fixS * fixp)
330 return fixp->fx_where +
331 fixp->fx_frag->fr_address + 1;
334 typedef const char * (asfunc)(char, char, const char*);
336 typedef struct _table_t
338 char* name;
339 char prefix;
340 char opcode;
341 asfunc * fp;
342 } table_t;
344 /* Compares the key for structs that start with a char * to the key. */
345 static int
346 key_cmp (const void * a, const void * b)
348 const char *str_a, *str_b;
350 str_a = *((const char**)a);
351 str_b = *((const char**)b);
352 return strcmp (str_a, str_b);
355 #define BUFLEN 8 /* Large enough for any keyword. */
357 char buf[BUFLEN];
358 const char *key = buf;
360 #define R_STACKABLE (0x80)
361 #define R_ARITH (0x40)
362 #define R_IX (0x20)
363 #define R_IY (0x10)
364 #define R_INDEX (R_IX | R_IY)
366 #define REG_A (7)
367 #define REG_B (0)
368 #define REG_C (1)
369 #define REG_D (2)
370 #define REG_E (3)
371 #define REG_H (4)
372 #define REG_L (5)
373 #define REG_F (6 | 8)
374 #define REG_I (9)
375 #define REG_R (10)
377 #define REG_AF (3 | R_STACKABLE)
378 #define REG_BC (0 | R_STACKABLE | R_ARITH)
379 #define REG_DE (1 | R_STACKABLE | R_ARITH)
380 #define REG_HL (2 | R_STACKABLE | R_ARITH)
381 #define REG_SP (3 | R_ARITH)
383 static const struct reg_entry
385 char* name;
386 int number;
387 } regtable[] =
389 {"a", REG_A },
390 {"af", REG_AF },
391 {"b", REG_B },
392 {"bc", REG_BC },
393 {"c", REG_C },
394 {"d", REG_D },
395 {"de", REG_DE },
396 {"e", REG_E },
397 {"f", REG_F },
398 {"h", REG_H },
399 {"hl", REG_HL },
400 {"i", REG_I },
401 {"ix", REG_HL | R_IX },
402 {"ixh",REG_H | R_IX },
403 {"ixl",REG_L | R_IX },
404 {"iy", REG_HL | R_IY },
405 {"iyh",REG_H | R_IY },
406 {"iyl",REG_L | R_IY },
407 {"l", REG_L },
408 {"r", REG_R },
409 {"sp", REG_SP },
412 /* Prevent an error on a line from also generating
413 a "junk at end of line" error message. */
414 static char err_flag;
416 static void
417 error (const char * message)
419 as_bad (message);
420 err_flag = 1;
423 static void
424 ill_op (void)
426 error (_("illegal operand"));
429 static void
430 wrong_mach (int ins_type)
432 const char *p;
434 switch (ins_type)
436 case INS_UNDOC:
437 p = "undocumented instruction";
438 break;
439 case INS_UNPORT:
440 p = "instruction does not work on R800";
441 break;
442 case INS_R800:
443 p = "instruction only works R800";
444 break;
445 default:
446 p = 0; /* Not reachable. */
449 if (ins_type & ins_err)
450 error (_(p));
451 else
452 as_warn (_(p));
455 static void
456 check_mach (int ins_type)
458 if ((ins_type & ins_ok) == 0)
459 wrong_mach (ins_type);
460 ins_used |= ins_type;
463 /* This function tries to subtract two symbols, the generic code does
464 that too, but this function tries harder.
465 The behaviour of this function is not altered by extra
466 fragmentations caused by the code to produce listings. */
468 z80_optimize_expr (expressionS *resultP, operatorT left_op,
469 expressionS *right)
471 int res, swap, som;
472 fragS *lfrag, *rfrag, *cur;
474 res = 0;
475 if (left_op == O_subtract
476 && right->X_op == O_symbol
477 && resultP->X_op == O_symbol)
479 lfrag = symbol_get_frag (resultP->X_add_symbol);
480 rfrag = symbol_get_frag (right->X_add_symbol);
482 if (S_GET_SEGMENT (right->X_add_symbol) != undefined_section
483 && (S_GET_SEGMENT (right->X_add_symbol)
484 == S_GET_SEGMENT (resultP->X_add_symbol)))
486 for (swap = 0; (res == 0) && (swap < 2); ++swap)
488 if (swap)
490 cur = lfrag;
491 lfrag = rfrag;
492 rfrag = cur;
494 else
495 cur = rfrag;
497 /* Now som == cur->fr_address - rfrag->address, except
498 the latter may not have been computed yet. */
499 for (som = 0; cur && cur != lfrag; cur = cur->fr_next)
501 if (cur->fr_type == rs_fill) /* Is the size fized? */
502 som += cur->fr_fix+cur->fr_offset*cur->fr_var;
503 else
504 break;
507 if (cur == lfrag)
509 resultP->X_add_number -= right->X_add_number;
510 resultP->X_add_number
511 += (S_GET_VALUE (resultP->X_add_symbol)
512 - S_GET_VALUE (right->X_add_symbol));
513 som -= lfrag->fr_address - rfrag->fr_address;
514 /* Correct the result if the fr_address
515 fields are not computed yet. */
516 resultP->X_add_number += (swap ? -som : som);
517 resultP->X_op = O_constant;
518 resultP->X_add_symbol = 0;
519 res = 1;
524 return res;
527 /* Check whether an expression is indirect. */
528 static int
529 is_indir (const char *s)
531 char quote;
532 const char *p;
533 int indir, depth;
535 /* Indirection is indicated with parentheses. */
536 indir = (*s == '(');
538 for (p = s, depth = 0; *p && *p != ','; ++p)
540 switch (*p)
542 case '"':
543 case '\'':
544 for (quote = *p++; quote != *p && *p != '\n'; ++p)
545 if (*p == '\\' && p[1])
546 ++p;
547 break;
548 case '(':
549 ++ depth;
550 break;
551 case ')':
552 -- depth;
553 if (depth == 0)
555 p = skip_space (p + 1);
556 if (*p && *p != ',')
557 indir = 0;
558 --p;
560 if (depth < 0)
561 error (_("mismatched parentheses"));
562 break;
566 if (depth != 0)
567 error (_("mismatched parentheses"));
569 return indir;
572 /* Parse general expression. */
573 static const char *
574 parse_exp2 (const char *s, expressionS *op, segT *pseg)
576 const char *p;
577 int indir;
578 int i;
579 const struct reg_entry * regp;
580 expressionS offset;
582 p = skip_space (s);
583 op->X_md = indir = is_indir (p);
584 if (indir)
585 p = skip_space (p + 1);
587 for (i = 0; i < BUFLEN; ++i)
589 if (!ISALPHA (p[i])) /* Register names consist of letters only. */
590 break;
591 buf[i] = TOLOWER (p[i]);
594 if ((i < BUFLEN) && ((p[i] == 0) || (strchr (")+-, \t", p[i]))))
596 buf[i] = 0;
597 regp = bsearch (& key, regtable, ARRAY_SIZE (regtable),
598 sizeof (regtable[0]), key_cmp);
599 if (regp)
601 *pseg = reg_section;
602 op->X_add_symbol = op->X_op_symbol = 0;
603 op->X_add_number = regp->number;
604 op->X_op = O_register;
605 p += strlen (regp->name);
606 p = skip_space (p);
607 if (indir)
609 if (*p == ')')
610 ++p;
611 if ((regp->number & R_INDEX) && (regp->number & R_ARITH))
613 op->X_op = O_md1;
615 if ((*p == '+') || (*p == '-'))
617 input_line_pointer = (char*) p;
618 expression (& offset);
619 p = skip_space (input_line_pointer);
620 if (*p != ')')
621 error (_("bad offset expression syntax"));
622 else
623 ++ p;
624 op->X_add_symbol = make_expr_symbol (& offset);
625 return p;
628 /* We treat (i[xy]) as (i[xy]+0), which is how it will
629 end up anyway, unless we're processing jp (i[xy]). */
630 op->X_add_symbol = zero;
633 p = skip_space (p);
635 if ((*p == 0) || (*p == ','))
636 return p;
639 /* Not an argument involving a register; use the generic parser. */
640 input_line_pointer = (char*) s ;
641 *pseg = expression (op);
642 if (op->X_op == O_absent)
643 error (_("missing operand"));
644 if (op->X_op == O_illegal)
645 error (_("bad expression syntax"));
646 return input_line_pointer;
649 static const char *
650 parse_exp (const char *s, expressionS *op)
652 segT dummy;
653 return parse_exp2 (s, op, & dummy);
656 /* Condition codes, including some synonyms provided by HiTech zas. */
657 static const struct reg_entry cc_tab[] =
659 { "age", 6 << 3 },
660 { "alt", 7 << 3 },
661 { "c", 3 << 3 },
662 { "di", 4 << 3 },
663 { "ei", 5 << 3 },
664 { "lge", 2 << 3 },
665 { "llt", 3 << 3 },
666 { "m", 7 << 3 },
667 { "nc", 2 << 3 },
668 { "nz", 0 << 3 },
669 { "p", 6 << 3 },
670 { "pe", 5 << 3 },
671 { "po", 4 << 3 },
672 { "z", 1 << 3 },
675 /* Parse condition code. */
676 static const char *
677 parse_cc (const char *s, char * op)
679 const char *p;
680 int i;
681 struct reg_entry * cc_p;
683 for (i = 0; i < BUFLEN; ++i)
685 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
686 break;
687 buf[i] = TOLOWER (s[i]);
690 if ((i < BUFLEN)
691 && ((s[i] == 0) || (s[i] == ',')))
693 buf[i] = 0;
694 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
695 sizeof (cc_tab[0]), key_cmp);
697 else
698 cc_p = NULL;
700 if (cc_p)
702 *op = cc_p->number;
703 p = s + i;
705 else
706 p = NULL;
708 return p;
711 static const char *
712 emit_insn (char prefix, char opcode, const char * args)
714 char *p;
716 if (prefix)
718 p = frag_more (2);
719 *p++ = prefix;
721 else
722 p = frag_more (1);
723 *p = opcode;
724 return args;
727 void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
729 bfd_reloc_code_real_type r[4] =
731 BFD_RELOC_8,
732 BFD_RELOC_16,
733 BFD_RELOC_24,
734 BFD_RELOC_32
737 if (nbytes < 1 || nbytes > 4)
739 as_bad (_("unsupported BFD relocation size %u"), nbytes);
741 else
743 fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
747 static void
748 emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
750 char *p;
751 int lo, hi;
752 fixS * fixp;
754 p = frag_more (1);
755 *p = val->X_add_number;
756 if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
758 as_bad(_("cannot make a relative jump to an absolute location"));
760 else if (val->X_op == O_constant)
762 lo = -128;
763 hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
765 if ((val->X_add_number < lo) || (val->X_add_number > hi))
767 if (r_type == BFD_RELOC_Z80_DISP8)
768 as_bad (_("offset too large"));
769 else
770 as_warn (_("overflow"));
773 else
775 fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
776 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
777 /* FIXME : Process constant offsets immediately. */
781 static void
782 emit_word (expressionS * val)
784 char *p;
786 p = frag_more (2);
787 if ( (val->X_op == O_register)
788 || (val->X_op == O_md1))
789 ill_op ();
790 else
792 *p = val->X_add_number;
793 p[1] = (val->X_add_number>>8);
794 if (val->X_op != O_constant)
795 fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
796 val, FALSE, BFD_RELOC_16);
800 static void
801 emit_mx (char prefix, char opcode, int shift, expressionS * arg)
802 /* The operand m may be r, (hl), (ix+d), (iy+d),
803 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
805 char *q;
806 int rnum;
808 rnum = arg->X_add_number;
809 switch (arg->X_op)
811 case O_register:
812 if (arg->X_md)
814 if (rnum != REG_HL)
816 ill_op ();
817 break;
819 else
820 rnum = 6;
822 else
824 if ((prefix == 0) && (rnum & R_INDEX))
826 prefix = (rnum & R_IX) ? 0xDD : 0xFD;
827 check_mach (INS_UNDOC);
828 rnum &= ~R_INDEX;
830 if (rnum > 7)
832 ill_op ();
833 break;
836 q = frag_more (prefix ? 2 : 1);
837 if (prefix)
838 * q ++ = prefix;
839 * q ++ = opcode + (rnum << shift);
840 break;
841 case O_md1:
842 q = frag_more (2);
843 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
844 *q = (prefix) ? prefix : (opcode + (6 << shift));
845 emit_byte (symbol_get_value_expression (arg->X_add_symbol),
846 BFD_RELOC_Z80_DISP8);
847 if (prefix)
849 q = frag_more (1);
850 *q = opcode+(6<<shift);
852 break;
853 default:
854 abort ();
858 /* The operand m may be r, (hl), (ix+d), (iy+d),
859 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
860 static const char *
861 emit_m (char prefix, char opcode, const char *args)
863 expressionS arg_m;
864 const char *p;
866 p = parse_exp (args, &arg_m);
867 switch (arg_m.X_op)
869 case O_md1:
870 case O_register:
871 emit_mx (prefix, opcode, 0, &arg_m);
872 break;
873 default:
874 ill_op ();
876 return p;
879 /* The operand m may be as above or one of the undocumented
880 combinations (ix+d),r and (iy+d),r (if unportable instructions
881 are allowed). */
882 static const char *
883 emit_mr (char prefix, char opcode, const char *args)
885 expressionS arg_m, arg_r;
886 const char *p;
888 p = parse_exp (args, & arg_m);
890 switch (arg_m.X_op)
892 case O_md1:
893 if (*p == ',')
895 p = parse_exp (p + 1, & arg_r);
897 if ((arg_r.X_md == 0)
898 && (arg_r.X_op == O_register)
899 && (arg_r.X_add_number < 8))
900 opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6. */
901 else
903 ill_op ();
904 break;
906 check_mach (INS_UNPORT);
908 case O_register:
909 emit_mx (prefix, opcode, 0, & arg_m);
910 break;
911 default:
912 ill_op ();
914 return p;
917 static void
918 emit_sx (char prefix, char opcode, expressionS * arg_p)
920 char *q;
922 switch (arg_p->X_op)
924 case O_register:
925 case O_md1:
926 emit_mx (prefix, opcode, 0, arg_p);
927 break;
928 default:
929 if (arg_p->X_md)
930 ill_op ();
931 else
933 q = frag_more (prefix ? 2 : 1);
934 if (prefix)
935 *q++ = prefix;
936 *q = opcode ^ 0x46;
937 emit_byte (arg_p, BFD_RELOC_8);
942 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
943 static const char *
944 emit_s (char prefix, char opcode, const char *args)
946 expressionS arg_s;
947 const char *p;
949 p = parse_exp (args, & arg_s);
950 emit_sx (prefix, opcode, & arg_s);
951 return p;
954 static const char *
955 emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
957 expressionS addr;
958 const char *p; char *q;
960 p = parse_exp (args, &addr);
961 if (addr.X_md)
962 ill_op ();
963 else
965 q = frag_more (1);
966 *q = opcode;
967 emit_word (& addr);
969 return p;
972 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
973 static const char *
974 emit_incdec (char prefix, char opcode, const char * args)
976 expressionS operand;
977 int rnum;
978 const char *p; char *q;
980 p = parse_exp (args, &operand);
981 rnum = operand.X_add_number;
982 if ((! operand.X_md)
983 && (operand.X_op == O_register)
984 && (R_ARITH&rnum))
986 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
987 if (rnum & R_INDEX)
988 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
989 *q = prefix + ((rnum & 3) << 4);
991 else
993 if ((operand.X_op == O_md1) || (operand.X_op == O_register))
994 emit_mx (0, opcode, 3, & operand);
995 else
996 ill_op ();
998 return p;
1001 static const char *
1002 emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1004 expressionS addr;
1005 const char *p;
1006 char *q;
1008 p = parse_exp (args, &addr);
1009 if (addr.X_md)
1010 ill_op ();
1011 else
1013 q = frag_more (1);
1014 *q = opcode;
1015 emit_byte (&addr, BFD_RELOC_8_PCREL);
1017 return p;
1020 static const char *
1021 emit_jp (char prefix, char opcode, const char * args)
1023 expressionS addr;
1024 const char *p;
1025 char *q;
1026 int rnum;
1028 p = parse_exp (args, & addr);
1029 if (addr.X_md)
1031 rnum = addr.X_add_number;
1032 if ((addr.X_op == O_register && (rnum & ~R_INDEX) == REG_HL)
1033 /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
1034 in parse_exp (). */
1035 || (addr.X_op == O_md1 && addr.X_add_symbol == zero))
1037 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1038 if (rnum & R_INDEX)
1039 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1040 *q = prefix;
1042 else
1043 ill_op ();
1045 else
1047 q = frag_more (1);
1048 *q = opcode;
1049 emit_word (& addr);
1051 return p;
1054 static const char *
1055 emit_im (char prefix, char opcode, const char * args)
1057 expressionS mode;
1058 const char *p;
1059 char *q;
1061 p = parse_exp (args, & mode);
1062 if (mode.X_md || (mode.X_op != O_constant))
1063 ill_op ();
1064 else
1065 switch (mode.X_add_number)
1067 case 1:
1068 case 2:
1069 ++mode.X_add_number;
1070 /* Fall through. */
1071 case 0:
1072 q = frag_more (2);
1073 *q++ = prefix;
1074 *q = opcode + 8*mode.X_add_number;
1075 break;
1076 default:
1077 ill_op ();
1079 return p;
1082 static const char *
1083 emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1085 expressionS regp;
1086 const char *p;
1087 char *q;
1089 p = parse_exp (args, & regp);
1090 if ((!regp.X_md)
1091 && (regp.X_op == O_register)
1092 && (regp.X_add_number & R_STACKABLE))
1094 int rnum;
1096 rnum = regp.X_add_number;
1097 if (rnum&R_INDEX)
1099 q = frag_more (2);
1100 *q++ = (rnum&R_IX)?0xDD:0xFD;
1102 else
1103 q = frag_more (1);
1104 *q = opcode + ((rnum & 3) << 4);
1106 else
1107 ill_op ();
1109 return p;
1112 static const char *
1113 emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1115 char cc, *q;
1116 const char *p;
1118 p = parse_cc (args, &cc);
1119 q = frag_more (1);
1120 if (p)
1121 *q = opcode + cc;
1122 else
1123 *q = prefix;
1124 return p ? p : args;
1127 static const char *
1128 emit_adc (char prefix, char opcode, const char * args)
1130 expressionS term;
1131 int rnum;
1132 const char *p;
1133 char *q;
1135 p = parse_exp (args, &term);
1136 if (*p++ != ',')
1138 error (_("bad intruction syntax"));
1139 return p;
1142 if ((term.X_md) || (term.X_op != O_register))
1143 ill_op ();
1144 else
1145 switch (term.X_add_number)
1147 case REG_A:
1148 p = emit_s (0, prefix, p);
1149 break;
1150 case REG_HL:
1151 p = parse_exp (p, &term);
1152 if ((!term.X_md) && (term.X_op == O_register))
1154 rnum = term.X_add_number;
1155 if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1157 q = frag_more (2);
1158 *q++ = 0xED;
1159 *q = opcode + ((rnum & 3) << 4);
1160 break;
1163 /* Fall through. */
1164 default:
1165 ill_op ();
1167 return p;
1170 static const char *
1171 emit_add (char prefix, char opcode, const char * args)
1173 expressionS term;
1174 int lhs, rhs;
1175 const char *p;
1176 char *q;
1178 p = parse_exp (args, &term);
1179 if (*p++ != ',')
1181 error (_("bad intruction syntax"));
1182 return p;
1185 if ((term.X_md) || (term.X_op != O_register))
1186 ill_op ();
1187 else
1188 switch (term.X_add_number & ~R_INDEX)
1190 case REG_A:
1191 p = emit_s (0, prefix, p);
1192 break;
1193 case REG_HL:
1194 lhs = term.X_add_number;
1195 p = parse_exp (p, &term);
1196 if ((!term.X_md) && (term.X_op == O_register))
1198 rhs = term.X_add_number;
1199 if ((rhs & R_ARITH)
1200 && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
1202 q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1203 if (lhs & R_INDEX)
1204 *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1205 *q = opcode + ((rhs & 3) << 4);
1206 break;
1209 /* Fall through. */
1210 default:
1211 ill_op ();
1213 return p;
1216 static const char *
1217 emit_bit (char prefix, char opcode, const char * args)
1219 expressionS b;
1220 int bn;
1221 const char *p;
1223 p = parse_exp (args, &b);
1224 if (*p++ != ',')
1225 error (_("bad intruction syntax"));
1227 bn = b.X_add_number;
1228 if ((!b.X_md)
1229 && (b.X_op == O_constant)
1230 && (0 <= bn)
1231 && (bn < 8))
1233 if (opcode == 0x40)
1234 /* Bit : no optional third operand. */
1235 p = emit_m (prefix, opcode + (bn << 3), p);
1236 else
1237 /* Set, res : resulting byte can be copied to register. */
1238 p = emit_mr (prefix, opcode + (bn << 3), p);
1240 else
1241 ill_op ();
1242 return p;
1245 static const char *
1246 emit_jpcc (char prefix, char opcode, const char * args)
1248 char cc;
1249 const char *p;
1251 p = parse_cc (args, & cc);
1252 if (p && *p++ == ',')
1253 p = emit_call (0, opcode + cc, p);
1254 else
1255 p = (prefix == (char)0xC3)
1256 ? emit_jp (0xE9, prefix, args)
1257 : emit_call (0, prefix, args);
1258 return p;
1261 static const char *
1262 emit_jrcc (char prefix, char opcode, const char * args)
1264 char cc;
1265 const char *p;
1267 p = parse_cc (args, &cc);
1268 if (p && *p++ == ',')
1270 if (cc > (3 << 3))
1271 error (_("condition code invalid for jr"));
1272 else
1273 p = emit_jr (0, opcode + cc, p);
1275 else
1276 p = emit_jr (0, prefix, args);
1278 return p;
1281 static const char *
1282 emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1283 char opcode_in ATTRIBUTE_UNUSED, const char * args)
1285 expressionS op;
1286 const char * p;
1287 char prefix, opcode;
1289 p = parse_exp (args, &op);
1290 p = skip_space (p);
1291 if (*p++ != ',')
1293 error (_("bad instruction syntax"));
1294 return p;
1297 prefix = opcode = 0;
1298 if (op.X_op == O_register)
1299 switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1301 case REG_AF:
1302 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1304 /* The scrubber changes '\'' to '`' in this context. */
1305 if (*p == '`')
1306 ++p;
1307 opcode = 0x08;
1309 break;
1310 case REG_DE:
1311 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1312 opcode = 0xEB;
1313 break;
1314 case REG_SP|0x8000:
1315 p = parse_exp (p, & op);
1316 if (op.X_op == O_register
1317 && op.X_md == 0
1318 && (op.X_add_number & ~R_INDEX) == REG_HL)
1320 opcode = 0xE3;
1321 if (R_INDEX & op.X_add_number)
1322 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1324 break;
1326 if (opcode)
1327 emit_insn (prefix, opcode, p);
1328 else
1329 ill_op ();
1331 return p;
1334 static const char *
1335 emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1336 const char * args)
1338 expressionS reg, port;
1339 const char *p;
1340 char *q;
1342 p = parse_exp (args, &reg);
1343 if (*p++ != ',')
1345 error (_("bad intruction syntax"));
1346 return p;
1349 p = parse_exp (p, &port);
1350 if (reg.X_md == 0
1351 && reg.X_op == O_register
1352 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1353 && (port.X_md))
1355 if (port.X_op != O_md1 && port.X_op != O_register)
1357 if (REG_A == reg.X_add_number)
1359 q = frag_more (1);
1360 *q = 0xDB;
1361 emit_byte (&port, BFD_RELOC_8);
1363 else
1364 ill_op ();
1366 else
1368 if (port.X_add_number == REG_C)
1370 if (reg.X_add_number == REG_F)
1371 check_mach (INS_UNDOC);
1372 else
1374 q = frag_more (2);
1375 *q++ = 0xED;
1376 *q = 0x40|((reg.X_add_number&7)<<3);
1379 else
1380 ill_op ();
1383 else
1384 ill_op ();
1385 return p;
1388 static const char *
1389 emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1390 const char * args)
1392 expressionS reg, port;
1393 const char *p;
1394 char *q;
1396 p = parse_exp (args, & port);
1397 if (*p++ != ',')
1399 error (_("bad intruction syntax"));
1400 return p;
1402 p = parse_exp (p, &reg);
1403 if (!port.X_md)
1404 { ill_op (); return p; }
1405 /* Allow "out (c), 0" as unportable instruction. */
1406 if (reg.X_op == O_constant && reg.X_add_number == 0)
1408 check_mach (INS_UNPORT);
1409 reg.X_op = O_register;
1410 reg.X_add_number = 6;
1412 if (reg.X_md
1413 || reg.X_op != O_register
1414 || reg.X_add_number > 7)
1415 ill_op ();
1416 else
1417 if (port.X_op != O_register && port.X_op != O_md1)
1419 if (REG_A == reg.X_add_number)
1421 q = frag_more (1);
1422 *q = 0xD3;
1423 emit_byte (&port, BFD_RELOC_8);
1425 else
1426 ill_op ();
1428 else
1430 if (REG_C == port.X_add_number)
1432 q = frag_more (2);
1433 *q++ = 0xED;
1434 *q = 0x41 | (reg.X_add_number << 3);
1436 else
1437 ill_op ();
1439 return p;
1442 static const char *
1443 emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1445 expressionS addr;
1446 const char *p;
1447 char *q;
1449 p = parse_exp (args, &addr);
1450 if (addr.X_op != O_constant)
1452 error ("rst needs constant address");
1453 return p;
1456 if (addr.X_add_number & ~(7 << 3))
1457 ill_op ();
1458 else
1460 q = frag_more (1);
1461 *q = opcode + (addr.X_add_number & (7 << 3));
1463 return p;
1466 static void
1467 emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d)
1469 char *q;
1471 if (src->X_md)
1472 ill_op ();
1473 else
1475 if (src->X_op == O_register)
1477 if (src->X_add_number>7)
1478 ill_op ();
1479 if (prefix)
1481 q = frag_more (2);
1482 *q++ = prefix;
1484 else
1485 q = frag_more (1);
1486 *q = opcode + src->X_add_number;
1487 if (d)
1488 emit_byte (d, BFD_RELOC_Z80_DISP8);
1490 else
1492 if (prefix)
1494 q = frag_more (2);
1495 *q++ = prefix;
1497 else
1498 q = frag_more (1);
1499 *q = opcode^0x46;
1500 if (d)
1501 emit_byte (d, BFD_RELOC_Z80_DISP8);
1502 emit_byte (src, BFD_RELOC_8);
1507 static void
1508 emit_ldreg (int dest, expressionS * src)
1510 char *q;
1511 int rnum;
1513 switch (dest)
1515 /* 8 Bit ld group: */
1516 case REG_I:
1517 case REG_R:
1518 if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A)
1520 q = frag_more (2);
1521 *q++ = 0xED;
1522 *q = (dest == REG_I) ? 0x47 : 0x4F;
1524 else
1525 ill_op ();
1526 break;
1528 case REG_A:
1529 if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1)
1531 q = frag_more (1);
1532 *q = 0x3A;
1533 emit_word (src);
1534 break;
1537 if ((src->X_md)
1538 && src->X_op == O_register
1539 && (src->X_add_number == REG_BC || src->X_add_number == REG_DE))
1541 q = frag_more (1);
1542 *q = 0x0A + ((dest & 1) << 4);
1543 break;
1546 if ((!src->X_md)
1547 && src->X_op == O_register
1548 && (src->X_add_number == REG_R || src->X_add_number == REG_I))
1550 q = frag_more (2);
1551 *q++ = 0xED;
1552 *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F;
1553 break;
1555 /* Fall through. */
1556 case REG_B:
1557 case REG_C:
1558 case REG_D:
1559 case REG_E:
1560 emit_sx (0, 0x40 + (dest << 3), src);
1561 break;
1563 case REG_H:
1564 case REG_L:
1565 if ((src->X_md == 0)
1566 && (src->X_op == O_register)
1567 && (src->X_add_number & R_INDEX))
1568 ill_op ();
1569 else
1570 emit_sx (0, 0x40 + (dest << 3), src);
1571 break;
1573 case R_IX | REG_H:
1574 case R_IX | REG_L:
1575 case R_IY | REG_H:
1576 case R_IY | REG_L:
1577 if (src->X_md)
1579 ill_op ();
1580 break;
1582 check_mach (INS_UNDOC);
1583 if (src-> X_op == O_register)
1585 rnum = src->X_add_number;
1586 if ((rnum & ~R_INDEX) < 8
1587 && ((rnum & R_INDEX) == (dest & R_INDEX)
1588 || ( (rnum & ~R_INDEX) != REG_H
1589 && (rnum & ~R_INDEX) != REG_L)))
1591 q = frag_more (2);
1592 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1593 *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7);
1595 else
1596 ill_op ();
1598 else
1600 q = frag_more (2);
1601 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1602 *q = 0x06 + ((dest & 0x07) << 3);
1603 emit_byte (src, BFD_RELOC_8);
1605 break;
1607 /* 16 Bit ld group: */
1608 case REG_SP:
1609 if (src->X_md == 0
1610 && src->X_op == O_register
1611 && REG_HL == (src->X_add_number &~ R_INDEX))
1613 q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1);
1614 if (src->X_add_number & R_INDEX)
1615 *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD;
1616 *q = 0xF9;
1617 break;
1619 /* Fall through. */
1620 case REG_BC:
1621 case REG_DE:
1622 if (src->X_op == O_register || src->X_op == O_md1)
1623 ill_op ();
1624 q = frag_more (src->X_md ? 2 : 1);
1625 if (src->X_md)
1627 *q++ = 0xED;
1628 *q = 0x4B + ((dest & 3) << 4);
1630 else
1631 *q = 0x01 + ((dest & 3) << 4);
1632 emit_word (src);
1633 break;
1635 case REG_HL:
1636 case REG_HL | R_IX:
1637 case REG_HL | R_IY:
1638 if (src->X_op == O_register || src->X_op == O_md1)
1639 ill_op ();
1640 q = frag_more ((dest & R_INDEX) ? 2 : 1);
1641 if (dest & R_INDEX)
1642 * q ++ = (dest & R_IX) ? 0xDD : 0xFD;
1643 *q = (src->X_md) ? 0x2A : 0x21;
1644 emit_word (src);
1645 break;
1647 case REG_AF:
1648 case REG_F:
1649 ill_op ();
1650 break;
1652 default:
1653 abort ();
1657 static const char *
1658 emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
1659 const char * args)
1661 expressionS dst, src;
1662 const char *p;
1663 char *q;
1664 char prefix, opcode;
1666 p = parse_exp (args, &dst);
1667 if (*p++ != ',')
1668 error (_("bad intruction syntax"));
1669 p = parse_exp (p, &src);
1671 switch (dst.X_op)
1673 case O_md1:
1674 emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70,
1675 &src, symbol_get_value_expression (dst.X_add_symbol));
1676 break;
1678 case O_register:
1679 if (dst.X_md)
1681 switch (dst.X_add_number)
1683 case REG_BC:
1684 case REG_DE:
1685 if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A)
1687 q = frag_more (1);
1688 *q = 0x02 + ( (dst.X_add_number & 1) << 4);
1690 else
1691 ill_op ();
1692 break;
1693 case REG_HL:
1694 emit_ldxhl (0, 0x70, &src, NULL);
1695 break;
1696 default:
1697 ill_op ();
1700 else
1701 emit_ldreg (dst.X_add_number, &src);
1702 break;
1704 default:
1705 if (src.X_md != 0 || src.X_op != O_register)
1706 ill_op ();
1707 prefix = opcode = 0;
1708 switch (src.X_add_number)
1710 case REG_A:
1711 opcode = 0x32; break;
1712 case REG_BC: case REG_DE: case REG_SP:
1713 prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break;
1714 case REG_HL:
1715 opcode = 0x22; break;
1716 case REG_HL|R_IX:
1717 prefix = 0xDD; opcode = 0x22; break;
1718 case REG_HL|R_IY:
1719 prefix = 0xFD; opcode = 0x22; break;
1721 if (opcode)
1723 q = frag_more (prefix?2:1);
1724 if (prefix)
1725 *q++ = prefix;
1726 *q = opcode;
1727 emit_word (&dst);
1729 else
1730 ill_op ();
1732 return p;
1735 static void
1736 emit_data (int size ATTRIBUTE_UNUSED)
1738 const char *p, *q;
1739 char *u, quote;
1740 int cnt;
1741 expressionS exp;
1743 if (is_it_end_of_statement ())
1745 demand_empty_rest_of_line ();
1746 return;
1748 p = skip_space (input_line_pointer);
1752 if (*p == '\"' || *p == '\'')
1754 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
1756 u = frag_more (cnt);
1757 memcpy (u, q, cnt);
1758 if (!*p)
1759 as_warn (_("unterminated string"));
1760 else
1761 p = skip_space (p+1);
1763 else
1765 p = parse_exp (p, &exp);
1766 if (exp.X_op == O_md1 || exp.X_op == O_register)
1768 ill_op ();
1769 break;
1771 if (exp.X_md)
1772 as_warn (_("parentheses ignored"));
1773 emit_byte (&exp, BFD_RELOC_8);
1774 p = skip_space (p);
1777 while (*p++ == ',') ;
1778 input_line_pointer = (char *)(p-1);
1781 static const char *
1782 emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1784 const char *p;
1786 p = skip_space (args);
1787 if (TOLOWER (*p++) != 'a' || *p++ != ',')
1788 ill_op ();
1789 else
1791 char *q, reg;
1793 reg = TOLOWER (*p++);
1794 switch (reg)
1796 case 'b':
1797 case 'c':
1798 case 'd':
1799 case 'e':
1800 check_mach (INS_R800);
1801 if (!*skip_space (p))
1803 q = frag_more (2);
1804 *q++ = prefix;
1805 *q = opcode + ((reg - 'b') << 3);
1806 break;
1808 default:
1809 ill_op ();
1812 return p;
1815 static const char *
1816 emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1818 const char *p;
1820 p = skip_space (args);
1821 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
1822 ill_op ();
1823 else
1825 expressionS reg;
1826 char *q;
1828 p = parse_exp (p, & reg);
1830 if ((!reg.X_md) && reg.X_op == O_register)
1831 switch (reg.X_add_number)
1833 case REG_BC:
1834 case REG_SP:
1835 check_mach (INS_R800);
1836 q = frag_more (2);
1837 *q++ = prefix;
1838 *q = opcode + ((reg.X_add_number & 3) << 4);
1839 break;
1840 default:
1841 ill_op ();
1844 return p;
1847 /* Port specific pseudo ops. */
1848 const pseudo_typeS md_pseudo_table[] =
1850 { "db" , emit_data, 1},
1851 { "d24", cons, 3},
1852 { "d32", cons, 4},
1853 { "def24", cons, 3},
1854 { "def32", cons, 4},
1855 { "defb", emit_data, 1},
1856 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
1857 { "defw", cons, 2},
1858 { "ds", s_space, 1}, /* Fill with bytes rather than words. */
1859 { "dw", cons, 2},
1860 { "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */
1861 { "set", 0, 0}, /* Real instruction on z80. */
1862 { NULL, 0, 0 }
1865 static table_t instab[] =
1867 { "adc", 0x88, 0x4A, emit_adc },
1868 { "add", 0x80, 0x09, emit_add },
1869 { "and", 0x00, 0xA0, emit_s },
1870 { "bit", 0xCB, 0x40, emit_bit },
1871 { "call", 0xCD, 0xC4, emit_jpcc },
1872 { "ccf", 0x00, 0x3F, emit_insn },
1873 { "cp", 0x00, 0xB8, emit_s },
1874 { "cpd", 0xED, 0xA9, emit_insn },
1875 { "cpdr", 0xED, 0xB9, emit_insn },
1876 { "cpi", 0xED, 0xA1, emit_insn },
1877 { "cpir", 0xED, 0xB1, emit_insn },
1878 { "cpl", 0x00, 0x2F, emit_insn },
1879 { "daa", 0x00, 0x27, emit_insn },
1880 { "dec", 0x0B, 0x05, emit_incdec },
1881 { "di", 0x00, 0xF3, emit_insn },
1882 { "djnz", 0x00, 0x10, emit_jr },
1883 { "ei", 0x00, 0xFB, emit_insn },
1884 { "ex", 0x00, 0x00, emit_ex},
1885 { "exx", 0x00, 0xD9, emit_insn },
1886 { "halt", 0x00, 0x76, emit_insn },
1887 { "im", 0xED, 0x46, emit_im },
1888 { "in", 0x00, 0x00, emit_in },
1889 { "inc", 0x03, 0x04, emit_incdec },
1890 { "ind", 0xED, 0xAA, emit_insn },
1891 { "indr", 0xED, 0xBA, emit_insn },
1892 { "ini", 0xED, 0xA2, emit_insn },
1893 { "inir", 0xED, 0xB2, emit_insn },
1894 { "jp", 0xC3, 0xC2, emit_jpcc },
1895 { "jr", 0x18, 0x20, emit_jrcc },
1896 { "ld", 0x00, 0x00, emit_ld },
1897 { "ldd", 0xED, 0xA8, emit_insn },
1898 { "lddr", 0xED, 0xB8, emit_insn },
1899 { "ldi", 0xED, 0xA0, emit_insn },
1900 { "ldir", 0xED, 0xB0, emit_insn },
1901 { "mulub", 0xED, 0xC5, emit_mulub }, /* R800 only. */
1902 { "muluw", 0xED, 0xC3, emit_muluw }, /* R800 only. */
1903 { "neg", 0xed, 0x44, emit_insn },
1904 { "nop", 0x00, 0x00, emit_insn },
1905 { "or", 0x00, 0xB0, emit_s },
1906 { "otdr", 0xED, 0xBB, emit_insn },
1907 { "otir", 0xED, 0xB3, emit_insn },
1908 { "out", 0x00, 0x00, emit_out },
1909 { "outd", 0xED, 0xAB, emit_insn },
1910 { "outi", 0xED, 0xA3, emit_insn },
1911 { "pop", 0x00, 0xC1, emit_pop },
1912 { "push", 0x00, 0xC5, emit_pop },
1913 { "res", 0xCB, 0x80, emit_bit },
1914 { "ret", 0xC9, 0xC0, emit_retcc },
1915 { "reti", 0xED, 0x4D, emit_insn },
1916 { "retn", 0xED, 0x45, emit_insn },
1917 { "rl", 0xCB, 0x10, emit_mr },
1918 { "rla", 0x00, 0x17, emit_insn },
1919 { "rlc", 0xCB, 0x00, emit_mr },
1920 { "rlca", 0x00, 0x07, emit_insn },
1921 { "rld", 0xED, 0x6F, emit_insn },
1922 { "rr", 0xCB, 0x18, emit_mr },
1923 { "rra", 0x00, 0x1F, emit_insn },
1924 { "rrc", 0xCB, 0x08, emit_mr },
1925 { "rrca", 0x00, 0x0F, emit_insn },
1926 { "rrd", 0xED, 0x67, emit_insn },
1927 { "rst", 0x00, 0xC7, emit_rst},
1928 { "sbc", 0x98, 0x42, emit_adc },
1929 { "scf", 0x00, 0x37, emit_insn },
1930 { "set", 0xCB, 0xC0, emit_bit },
1931 { "sla", 0xCB, 0x20, emit_mr },
1932 { "sli", 0xCB, 0x30, emit_mr },
1933 { "sll", 0xCB, 0x30, emit_mr },
1934 { "sra", 0xCB, 0x28, emit_mr },
1935 { "srl", 0xCB, 0x38, emit_mr },
1936 { "sub", 0x00, 0x90, emit_s },
1937 { "xor", 0x00, 0xA8, emit_s },
1940 void
1941 md_assemble (char* str)
1943 const char *p;
1944 char * old_ptr;
1945 int i;
1946 table_t *insp;
1948 err_flag = 0;
1949 old_ptr = input_line_pointer;
1950 p = skip_space (str);
1951 for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
1952 buf[i++] = TOLOWER (*p++);
1954 if (i == BUFLEN)
1956 buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */
1957 buf[BUFLEN-1] = 0;
1958 as_bad (_("Unknown instruction '%s'"), buf);
1960 else if ((*p) && (!ISSPACE (*p)))
1961 as_bad (_("syntax error"));
1962 else
1964 buf[i] = 0;
1965 p = skip_space (p);
1966 key = buf;
1968 insp = bsearch (&key, instab, ARRAY_SIZE (instab),
1969 sizeof (instab[0]), key_cmp);
1970 if (!insp)
1971 as_bad (_("Unknown instruction '%s'"), buf);
1972 else
1974 p = insp->fp (insp->prefix, insp->opcode, p);
1975 p = skip_space (p);
1976 if ((!err_flag) && *p)
1977 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
1978 *p);
1981 input_line_pointer = old_ptr;
1984 void
1985 md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
1987 long val = * (long *) valP;
1988 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1990 switch (fixP->fx_r_type)
1992 case BFD_RELOC_8_PCREL:
1993 if (fixP->fx_addsy)
1995 fixP->fx_no_overflow = 1;
1996 fixP->fx_done = 0;
1998 else
2000 fixP->fx_no_overflow = (-128 <= val && val < 128);
2001 if (!fixP->fx_no_overflow)
2002 as_bad_where (fixP->fx_file, fixP->fx_line,
2003 _("relative jump out of range"));
2004 *buf++ = val;
2005 fixP->fx_done = 1;
2007 break;
2009 case BFD_RELOC_Z80_DISP8:
2010 if (fixP->fx_addsy)
2012 fixP->fx_no_overflow = 1;
2013 fixP->fx_done = 0;
2015 else
2017 fixP->fx_no_overflow = (-128 <= val && val < 128);
2018 if (!fixP->fx_no_overflow)
2019 as_bad_where (fixP->fx_file, fixP->fx_line,
2020 _("index offset out of range"));
2021 *buf++ = val;
2022 fixP->fx_done = 1;
2024 break;
2026 case BFD_RELOC_8:
2027 if (val > 255 || val < -128)
2028 as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
2029 *buf++ = val;
2030 fixP->fx_no_overflow = 1;
2031 if (fixP->fx_addsy == NULL)
2032 fixP->fx_done = 1;
2033 break;
2035 case BFD_RELOC_16:
2036 *buf++ = val;
2037 *buf++ = (val >> 8);
2038 fixP->fx_no_overflow = 1;
2039 if (fixP->fx_addsy == NULL)
2040 fixP->fx_done = 1;
2041 break;
2043 case BFD_RELOC_24: /* Def24 may produce this. */
2044 *buf++ = val;
2045 *buf++ = (val >> 8);
2046 *buf++ = (val >> 16);
2047 fixP->fx_no_overflow = 1;
2048 if (fixP->fx_addsy == NULL)
2049 fixP->fx_done = 1;
2050 break;
2052 case BFD_RELOC_32: /* Def32 and .long may produce this. */
2053 *buf++ = val;
2054 *buf++ = (val >> 8);
2055 *buf++ = (val >> 16);
2056 *buf++ = (val >> 24);
2057 if (fixP->fx_addsy == NULL)
2058 fixP->fx_done = 1;
2059 break;
2061 default:
2062 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
2063 abort ();
2067 /* GAS will call this to generate a reloc. GAS will pass the
2068 resulting reloc to `bfd_install_relocation'. This currently works
2069 poorly, as `bfd_install_relocation' often does the wrong thing, and
2070 instances of `tc_gen_reloc' have been written to work around the
2071 problems, which in turns makes it difficult to fix
2072 `bfd_install_relocation'. */
2074 /* If while processing a fixup, a reloc really
2075 needs to be created then it is done here. */
2077 arelent *
2078 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
2080 arelent *reloc;
2082 if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
2084 as_bad_where (fixp->fx_file, fixp->fx_line,
2085 _("reloc %d not supported by object file format"),
2086 (int) fixp->fx_r_type);
2087 return NULL;
2090 reloc = xmalloc (sizeof (arelent));
2091 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2092 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2093 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2094 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2095 reloc->addend = fixp->fx_offset;
2097 return reloc;