Add support for the Z80 processor family
[deliverable/binutils-gdb.git] / gas / config / tc-z80.c
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>
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, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
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"
29
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";
36
37 /* For machine specific options. */
38 const char * md_shortopts = ""; /* None yet. */
39
40 enum options
41 {
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
50 };
51
52 #define INS_Z80 1
53 #define INS_UNDOC 2
54 #define INS_UNPORT 4
55 #define INS_R800 8
56
57 struct option md_longopts[] =
58 {
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 },
73
74 { NULL, no_argument, NULL, 0 }
75 } ;
76
77 size_t md_longopts_size = sizeof (md_longopts);
78
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;
86
87 int
88 md_parse_option (int c, char* arg ATTRIBUTE_UNUSED)
89 {
90 switch (c)
91 {
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)
112 {
113 ins_ok &= ~(INS_UNDOC|INS_UNPORT);
114 ins_err &= ~INS_UNDOC;
115 }
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)
123 {
124 ins_ok &= (INS_UNDOC | INS_UNPORT);
125 ins_err |= INS_UNDOC | INS_UNPORT;
126 }
127 break;
128 case OPTION_MACH_FUP:
129 ins_ok &= ~INS_UNPORT;
130 ins_err |= INS_UNPORT;
131 break;
132 }
133
134 return 1;
135 }
136
137 void
138 md_show_usage (FILE * f)
139 {
140 fprintf (f, "\n\
141 CPU model/instruction set options:\n\
142 \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");
164 }
165
166 static symbolS * zero;
167
168 void
169 md_begin (void)
170 {
171 expressionS nul;
172 char * p;
173
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;
182 }
183
184 void
185 z80_md_end (void)
186 {
187 int mach_type;
188
189 if (ins_used & (INS_UNPORT | INS_R800))
190 ins_used |= INS_UNDOC;
191
192 switch (ins_used)
193 {
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;
208 }
209
210 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
211 }
212
213 /* Port specific features. */
214 const pseudo_typeS md_pseudo_table[] =
215 {
216 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
217 { "ds", s_space, 1}, /* Fill with bytes rather than words. */
218 { "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */
219 { "set", 0, 0}, /* Real instruction on z80. */
220 { NULL, 0, 0 }
221 } ;
222
223 static const char *
224 skip_space (const char *s)
225 {
226 while (*s == ' ' || *s == '\t')
227 ++s;
228 return s;
229 }
230
231 /* A non-zero return-value causes a continue in the
232 function read_a_source_file () in ../read.c. */
233 int
234 z80_start_line_hook (void)
235 {
236 char *p, quote;
237 char buf[4];
238
239 /* Convert one character constants. */
240 for (p = input_line_pointer; *p && *p != '\n'; ++p)
241 {
242 switch (*p)
243 {
244 case '\'':
245 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
246 {
247 snprintf (buf, 4, "%3d", (unsigned char)p[1]);
248 *p++ = buf[0];
249 *p++ = buf[1];
250 *p++ = buf[2];
251 break;
252 }
253 case '"':
254 for (quote = *p++; quote != *p && '\n' != *p; ++p)
255 /* No escapes. */ ;
256 if (quote != *p)
257 {
258 as_bad (_("-- unterminated string"));
259 ignore_rest_of_line ();
260 return 1;
261 }
262 break;
263 }
264 }
265 /* Check for <label>[:] (EQU|DEFL) <value>. */
266 if (is_name_beginner (*input_line_pointer))
267 {
268 char c, *rest, *line_start;
269 int len;
270
271 line_start = input_line_pointer;
272 LISTING_NEWLINE ();
273 if (ignore_input ())
274 return 0;
275
276 c = get_symbol_end ();
277 rest = input_line_pointer + 1;
278
279 if (*rest == ':')
280 ++rest;
281 if (*rest == ' ' || *rest == '\t')
282 ++rest;
283 if (strncasecmp (rest, "EQU", 3) == 0)
284 len = 3;
285 else if (strncasecmp (rest, "DEFL", 4) == 0)
286 len = 4;
287 else
288 len = 0;
289 if (len && (rest[len] == ' ' || rest[len] == '\t'))
290 {
291 /* Handle assignment here. */
292 input_line_pointer = rest + len;
293 if (line_start[-1] == '\n')
294 bump_line_counters ();
295 /* Most Z80 assemblers require the first definition of a
296 label to use "EQU" and redefinitions to have "DEFL".
297 That does not fit the way GNU as deals with labels, so
298 GNU as is more permissive. */
299 equals (line_start, TRUE);
300 return 1;
301 }
302 else
303 {
304 /* Restore line and pointer. */
305 *input_line_pointer = c;
306 input_line_pointer = line_start;
307 }
308 }
309 return 0;
310 }
311
312 symbolS *
313 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
314 {
315 return NULL;
316 }
317
318 char *
319 md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED,
320 int *sizeP ATTRIBUTE_UNUSED)
321 {
322 return _("floating point numbers are not implemented");
323 }
324
325 valueT
326 md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
327 {
328 return size;
329 }
330
331 long
332 md_pcrel_from (fixS * fixp)
333 {
334 return fixp->fx_where +
335 fixp->fx_frag->fr_address + 1;
336 }
337
338 typedef const char * (asfunc)(char, char, const char*);
339
340 typedef struct _table_t
341 {
342 char* name;
343 char prefix;
344 char opcode;
345 asfunc * fp;
346 } table_t;
347
348 /* Compares the key for structs that start with a char * to the key. */
349 static int
350 key_cmp (const void * a, const void * b)
351 {
352 const char *str_a, *str_b;
353
354 str_a = *((const char**)a);
355 str_b = *((const char**)b);
356 return strcmp (str_a, str_b);
357 }
358
359 #define BUFLEN 8 /* Large enough for any keyword. */
360
361 char buf[BUFLEN];
362 const char *key = buf;
363
364 #define R_STACKABLE (0x80)
365 #define R_ARITH (0x40)
366 #define R_IX (0x20)
367 #define R_IY (0x10)
368 #define R_INDEX (R_IX | R_IY)
369
370 #define REG_A (7)
371 #define REG_B (0)
372 #define REG_C (1)
373 #define REG_D (2)
374 #define REG_E (3)
375 #define REG_H (4)
376 #define REG_L (5)
377 #define REG_F (6 | 8)
378 #define REG_I (9)
379 #define REG_R (10)
380
381 #define REG_AF (3 | R_STACKABLE)
382 #define REG_BC (0 | R_STACKABLE | R_ARITH)
383 #define REG_DE (1 | R_STACKABLE | R_ARITH)
384 #define REG_HL (2 | R_STACKABLE | R_ARITH)
385 #define REG_SP (3 | R_ARITH)
386
387 static const struct reg_entry
388 {
389 char* name;
390 int number;
391 } regtable[] =
392 {
393 {"a", REG_A },
394 {"af", REG_AF },
395 {"b", REG_B },
396 {"bc", REG_BC },
397 {"c", REG_C },
398 {"d", REG_D },
399 {"de", REG_DE },
400 {"e", REG_E },
401 {"f", REG_F },
402 {"h", REG_H },
403 {"hl", REG_HL },
404 {"i", REG_I },
405 {"ix", REG_HL | R_IX },
406 {"ixh",REG_H | R_IX },
407 {"ixl",REG_L | R_IX },
408 {"iy", REG_HL | R_IY },
409 {"iyh",REG_H | R_IY },
410 {"iyl",REG_L | R_IY },
411 {"l", REG_L },
412 {"r", REG_R },
413 {"sp", REG_SP },
414 } ;
415
416 /* Prevent an error on a line from also generating
417 a "junk at end of line" error message. */
418 static char err_flag;
419
420 static void
421 error (const char * message)
422 {
423 as_bad (message);
424 err_flag = 1;
425 }
426
427 static void
428 ill_op (void)
429 {
430 error (_("illegal operand"));
431 }
432
433 static void
434 wrong_mach (int ins_type)
435 {
436 const char *p;
437
438 switch (ins_type)
439 {
440 case INS_UNDOC:
441 p = "undocumented instruction";
442 break;
443 case INS_UNPORT:
444 p = "instruction does not work on R800";
445 break;
446 case INS_R800:
447 p = "instruction only works R800";
448 break;
449 default:
450 p = 0; /* Not reachables. */
451 }
452
453 if (ins_type & ins_err)
454 error (_(p));
455 else
456 as_warn (_(p));
457 }
458
459 static void
460 check_mach (int ins_type)
461 {
462 if ((ins_type & ins_ok) == 0)
463 wrong_mach (ins_type);
464 ins_used |= ins_type;
465 }
466
467 /* This function tries to subtract two symbols, the generic code does
468 that too, but this function tries harder.
469 The behaviour of this function is not altered by extra
470 fragmentations caused by the code to produce listings. */
471 int
472 z80_optimize_expr (expressionS *resultP, operatorT left_op,
473 expressionS *right)
474 {
475 int res, swap, som;
476 fragS *lfrag, *rfrag, *cur;
477
478 res = 0;
479 if (left_op == O_subtract
480 && right->X_op == O_symbol
481 && resultP->X_op == O_symbol)
482 {
483 lfrag = symbol_get_frag (resultP->X_add_symbol);
484 rfrag = symbol_get_frag (right->X_add_symbol);
485
486 if (S_GET_SEGMENT (right->X_add_symbol) != undefined_section
487 && (S_GET_SEGMENT (right->X_add_symbol)
488 == S_GET_SEGMENT (resultP->X_add_symbol)))
489 {
490 for (swap = 0; (res == 0) && (swap < 2); ++swap)
491 {
492 if (swap)
493 {
494 cur = lfrag;
495 lfrag = rfrag;
496 rfrag = cur;
497 }
498 else
499 cur = rfrag;
500
501 /* Now som == cur->fr_address - rfrag->address, except
502 the latter may not have been computed yet. */
503 for (som = 0; cur && cur != lfrag; cur = cur->fr_next)
504 {
505 if (cur->fr_type == rs_fill) /* Is the size fized? */
506 som += cur->fr_fix+cur->fr_offset*cur->fr_var;
507 else
508 break;
509 }
510
511 if (cur == lfrag)
512 {
513 resultP->X_add_number -= right->X_add_number;
514 resultP->X_add_number
515 += (S_GET_VALUE (resultP->X_add_symbol)
516 - S_GET_VALUE (right->X_add_symbol));
517 som -= lfrag->fr_address - rfrag->fr_address;
518 /* Correct the result if the fr_address
519 fields are not computed yet. */
520 resultP->X_add_number += (swap ? -som : som);
521 resultP->X_op = O_constant;
522 resultP->X_add_symbol = 0;
523 res = 1;
524 }
525 }
526 }
527 }
528 return res;
529 }
530
531 /* Check whether an expression is indirect. */
532 static int
533 is_indir (const char *s)
534 {
535 char quote;
536 const char *p;
537 int indir, depth;
538
539 /* Indirection is indicated with parentheses. */
540 indir = (*s == '(');
541
542 for (p = s, depth = 0; *p && *p != ','; ++p)
543 {
544 switch (*p)
545 {
546 case '"':
547 case '\'':
548 for (quote = *p++; quote != *p && *p != '\n'; ++p)
549 if (*p == '\\' && p[1])
550 ++p;
551 break;
552 case '(':
553 ++ depth;
554 break;
555 case ')':
556 -- depth;
557 if (depth == 0)
558 {
559 p = skip_space (p + 1);
560 if (*p && *p != ',')
561 indir = 0;
562 --p;
563 }
564 if (depth < 0)
565 error (_("mismatched parentheses"));
566 break;
567 }
568 }
569
570 if (depth != 0)
571 error (_("mismatched parentheses"));
572
573 return indir;
574 }
575
576 /* Parse general expression. */
577 static const char *
578 parse_exp2 (const char *s, expressionS *op, segT *pseg)
579 {
580 const char *p;
581 int indir;
582 int i;
583 const struct reg_entry * regp;
584 expressionS offset;
585
586 p = skip_space (s);
587 op->X_md = indir = is_indir (p);
588 if (indir)
589 p = skip_space (p + 1);
590
591 for (i = 0; i < BUFLEN; ++i)
592 {
593 if (!ISALPHA (p[i])) /* Register names consist of letters only. */
594 break;
595 buf[i] = TOLOWER (p[i]);
596 }
597
598 if ((i < BUFLEN) && ((p[i] == 0) || (strchr (")+-, \t", p[i]))))
599 {
600 buf[i] = 0;
601 regp = bsearch (& key, regtable, ARRAY_SIZE (regtable),
602 sizeof (regtable[0]), key_cmp);
603 if (regp)
604 {
605 *pseg = reg_section;
606 op->X_add_symbol = op->X_op_symbol = 0;
607 op->X_add_number = regp->number;
608 op->X_op = O_register;
609 p += strlen (regp->name);
610 p = skip_space (p);
611 if (indir)
612 {
613 if (*p == ')')
614 ++p;
615 if ((regp->number & R_INDEX) && (regp->number & R_ARITH))
616 {
617 op->X_op = O_md1;
618
619 if ((*p == '+') || (*p == '-'))
620 {
621 input_line_pointer = (char*) p;
622 expression (& offset);
623 p = skip_space (input_line_pointer);
624 if (*p != ')')
625 error (_("bad offset expression syntax"));
626 else
627 ++ p;
628 op->X_add_symbol = make_expr_symbol (& offset);
629 return p;
630 }
631
632 /* We treat (i[xy]) as (i[xy]+0), which is how it will
633 end up anyway, unless we're processing jp (i[xy]). */
634 op->X_add_symbol = zero;
635 }
636 }
637 p = skip_space (p);
638
639 if ((*p == 0) || (*p == ','))
640 return p;
641 }
642 }
643 /* Not an argument involving a register; use the generic parser. */
644 input_line_pointer = (char*) s ;
645 *pseg = expression (op);
646 if (op->X_op == O_absent)
647 error (_("missing operand"));
648 if (op->X_op == O_illegal)
649 error (_("bad expression syntax"));
650 return input_line_pointer;
651 }
652
653 static const char *
654 parse_exp (const char *s, expressionS *op)
655 {
656 segT dummy;
657 return parse_exp2 (s, op, & dummy);
658 }
659
660 /* Condition codes, including some synonyms provided by HiTech zas. */
661 static const struct reg_entry cc_tab[] =
662 {
663 { "age", 6 << 3 },
664 { "alt", 7 << 3 },
665 { "c", 3 << 3 },
666 { "di", 4 << 3 },
667 { "ei", 5 << 3 },
668 { "lge", 2 << 3 },
669 { "llt", 3 << 3 },
670 { "m", 7 << 3 },
671 { "nc", 2 << 3 },
672 { "nz", 0 << 3 },
673 { "p", 6 << 3 },
674 { "pe", 5 << 3 },
675 { "po", 4 << 3 },
676 { "z", 1 << 3 },
677 } ;
678
679 /* Parse condition code. */
680 static const char *
681 parse_cc (const char *s, char * op)
682 {
683 const char *p;
684 int i;
685 struct reg_entry * cc_p;
686
687 for (i = 0; i < BUFLEN; ++i)
688 {
689 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
690 break;
691 buf[i] = TOLOWER (s[i]);
692 }
693
694 if ((i < BUFLEN)
695 && ((s[i] == 0) || (s[i] == ',')))
696 {
697 buf[i] = 0;
698 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
699 sizeof (cc_tab[0]), key_cmp);
700 }
701 else
702 cc_p = NULL;
703
704 if (cc_p)
705 {
706 *op = cc_p->number;
707 p = s + i;
708 }
709 else
710 p = NULL;
711
712 return p;
713 }
714
715 static const char *
716 emit_insn (char prefix, char opcode, const char * args)
717 {
718 char *p;
719
720 if (prefix)
721 {
722 p = frag_more (2);
723 *p++ = prefix;
724 }
725 else
726 p = frag_more (1);
727 *p = opcode;
728 return args;
729 }
730
731 static void
732 emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
733 {
734 char *p;
735 int lo, hi;
736 fixS * fixp;
737
738 p = frag_more (1);
739 *p = val->X_add_number;
740 if ((r_type != BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
741 {
742 lo = -128;
743 hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
744
745 if ((val->X_add_number < lo) || (val->X_add_number > hi))
746 {
747 if (r_type == BFD_RELOC_Z80_DISP8)
748 as_bad (_("offset too large"));
749 else
750 as_warn (_("overflow"));
751 }
752 }
753 else
754 {
755 fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
756 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
757 /* FIXME : Process constant offsets immediately. */
758 }
759 }
760
761 static void
762 emit_word (expressionS * val)
763 {
764 char *p;
765
766 p = frag_more (2);
767 if ( (val->X_op == O_register)
768 || (val->X_op == O_md1))
769 ill_op ();
770 else
771 {
772 *p = val->X_add_number;
773 p[1] = (val->X_add_number>>8);
774 if (val->X_op != O_constant)
775 fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
776 val, FALSE, BFD_RELOC_16);
777 }
778 }
779
780 static void
781 emit_mx (char prefix, char opcode, int shift, expressionS * arg)
782 /* The operand m may be r, (hl), (ix+d), (iy+d),
783 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
784 {
785 char *q;
786 int rnum;
787
788 rnum = arg->X_add_number;
789 switch (arg->X_op)
790 {
791 case O_register:
792 if (arg->X_md)
793 {
794 if (rnum != REG_HL)
795 {
796 ill_op ();
797 break;
798 }
799 else
800 rnum = 6;
801 }
802 else
803 {
804 if ((prefix == 0) && (rnum & R_INDEX))
805 {
806 prefix = (rnum & R_IX) ? 0xDD : 0xFD;
807 check_mach (INS_UNDOC);
808 rnum &= ~R_INDEX;
809 }
810 if (rnum > 7)
811 {
812 ill_op ();
813 break;
814 }
815 }
816 q = frag_more (prefix ? 2 : 1);
817 if (prefix)
818 * q ++ = prefix;
819 * q ++ = opcode + (rnum << shift);
820 break;
821 case O_md1:
822 q = frag_more (2);
823 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
824 *q = (prefix) ? prefix : (opcode + (6 << shift));
825 emit_byte (symbol_get_value_expression (arg->X_add_symbol),
826 BFD_RELOC_Z80_DISP8);
827 if (prefix)
828 {
829 q = frag_more (1);
830 *q = opcode+(6<<shift);
831 }
832 break;
833 default:
834 abort ();
835 }
836 }
837
838 /* The operand m may be r, (hl), (ix+d), (iy+d),
839 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
840 static const char *
841 emit_m (char prefix, char opcode, const char *args)
842 {
843 expressionS arg_m;
844 const char *p;
845
846 p = parse_exp (args, &arg_m);
847 switch (arg_m.X_op)
848 {
849 case O_md1:
850 case O_register:
851 emit_mx (prefix, opcode, 0, &arg_m);
852 break;
853 default:
854 ill_op ();
855 }
856 return p;
857 }
858
859 /* The operand m may be as above or one of the undocumented
860 combinations (ix+d),r and (iy+d),r (if unportable instructions
861 are allowed). */
862 static const char *
863 emit_mr (char prefix, char opcode, const char *args)
864 {
865 expressionS arg_m, arg_r;
866 const char *p;
867
868 p = parse_exp (args, & arg_m);
869
870 switch (arg_m.X_op)
871 {
872 case O_md1:
873 if (*p == ',')
874 {
875 p = parse_exp (p + 1, & arg_r);
876
877 if ((arg_r.X_md == 0)
878 && (arg_r.X_op == O_register)
879 && (arg_r.X_add_number < 8))
880 opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6. */
881 else
882 {
883 ill_op ();
884 break;
885 }
886 check_mach (INS_UNPORT);
887 }
888 case O_register:
889 emit_mx (prefix, opcode, 0, & arg_m);
890 break;
891 default:
892 ill_op ();
893 }
894 return p;
895 }
896
897 static void
898 emit_sx (char prefix, char opcode, expressionS * arg_p)
899 {
900 char *q;
901
902 switch (arg_p->X_op)
903 {
904 case O_register:
905 case O_md1:
906 emit_mx (prefix, opcode, 0, arg_p);
907 break;
908 default:
909 if (arg_p->X_md)
910 ill_op ();
911 else
912 {
913 q = frag_more (prefix ? 2 : 1);
914 if (prefix)
915 *q++ = prefix;
916 *q = opcode ^ 0x46;
917 emit_byte (arg_p, BFD_RELOC_8);
918 }
919 }
920 }
921
922 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
923 static const char *
924 emit_s (char prefix, char opcode, const char *args)
925 {
926 expressionS arg_s;
927 const char *p;
928
929 p = parse_exp (args, & arg_s);
930 emit_sx (prefix, opcode, & arg_s);
931 return p;
932 }
933
934 static const char *
935 emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
936 {
937 expressionS addr;
938 const char *p; char *q;
939
940 p = parse_exp (args, &addr);
941 if (addr.X_md)
942 ill_op ();
943 else
944 {
945 q = frag_more (1);
946 *q = opcode;
947 emit_word (& addr);
948 }
949 return p;
950 }
951
952 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
953 static const char *
954 emit_incdec (char prefix, char opcode, const char * args)
955 {
956 expressionS operand;
957 int rnum;
958 const char *p; char *q;
959
960 p = parse_exp (args, &operand);
961 rnum = operand.X_add_number;
962 if ((! operand.X_md)
963 && (operand.X_op == O_register)
964 && (R_ARITH&rnum))
965 {
966 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
967 if (rnum & R_INDEX)
968 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
969 *q = prefix + ((rnum & 3) << 4);
970 }
971 else
972 {
973 if ((operand.X_op == O_md1) || (operand.X_op == O_register))
974 emit_mx (0, opcode, 3, & operand);
975 else
976 ill_op ();
977 }
978 return p;
979 }
980
981 static const char *
982 emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
983 {
984 expressionS addr;
985 const char *p;
986 char *q;
987
988 p = parse_exp (args, &addr);
989 if (addr.X_md)
990 ill_op ();
991 else
992 {
993 q = frag_more (1);
994 *q = opcode;
995 emit_byte (&addr, BFD_RELOC_8_PCREL);
996 }
997 return p;
998 }
999
1000 static const char *
1001 emit_jp (char prefix, char opcode, const char * args)
1002 {
1003 expressionS addr;
1004 const char *p;
1005 char *q;
1006 int rnum;
1007
1008 p = parse_exp (args, & addr);
1009 if (addr.X_md)
1010 {
1011 rnum = addr.X_add_number;
1012 if ((addr.X_op == O_register && (rnum & ~R_INDEX) == REG_HL)
1013 /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
1014 in parse_exp (). */
1015 || (addr.X_op == O_md1 && addr.X_add_symbol == zero))
1016 {
1017 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1018 if (rnum & R_INDEX)
1019 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1020 *q = prefix;
1021 }
1022 else
1023 ill_op ();
1024 }
1025 else
1026 {
1027 q = frag_more (1);
1028 *q = opcode;
1029 emit_word (& addr);
1030 }
1031 return p;
1032 }
1033
1034 static const char *
1035 emit_im (char prefix, char opcode, const char * args)
1036 {
1037 expressionS mode;
1038 const char *p;
1039 char *q;
1040
1041 p = parse_exp (args, & mode);
1042 if (mode.X_md || (mode.X_op != O_constant))
1043 ill_op ();
1044 else
1045 switch (mode.X_add_number)
1046 {
1047 case 1:
1048 case 2:
1049 ++mode.X_add_number;
1050 /* Fall through. */
1051 case 0:
1052 q = frag_more (2);
1053 *q++ = prefix;
1054 *q = opcode + 8*mode.X_add_number;
1055 break;
1056 default:
1057 ill_op ();
1058 }
1059 return p;
1060 }
1061
1062 static const char *
1063 emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1064 {
1065 expressionS regp;
1066 const char *p;
1067 char *q;
1068
1069 p = parse_exp (args, & regp);
1070 if ((!regp.X_md)
1071 && (regp.X_op == O_register)
1072 && (regp.X_add_number & R_STACKABLE))
1073 {
1074 int rnum;
1075
1076 rnum = regp.X_add_number;
1077 if (rnum&R_INDEX)
1078 {
1079 q = frag_more (2);
1080 *q++ = (rnum&R_IX)?0xDD:0xFD;
1081 }
1082 else
1083 q = frag_more (1);
1084 *q = opcode + ((rnum & 3) << 4);
1085 }
1086 else
1087 ill_op ();
1088
1089 return p;
1090 }
1091
1092 static const char *
1093 emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1094 {
1095 char cc, *q;
1096 const char *p;
1097
1098 p = parse_cc (args, &cc);
1099 q = frag_more (1);
1100 if (p)
1101 *q = opcode + cc;
1102 else
1103 *q = prefix;
1104 return p ? p : args;
1105 }
1106
1107 static const char *
1108 emit_adc (char prefix, char opcode, const char * args)
1109 {
1110 expressionS term;
1111 int rnum;
1112 const char *p;
1113 char *q;
1114
1115 p = parse_exp (args, &term);
1116 if (*p++ != ',')
1117 {
1118 error (_("bad intruction syntax"));
1119 return p;
1120 }
1121
1122 if ((term.X_md) || (term.X_op != O_register))
1123 ill_op ();
1124 else
1125 switch (term.X_add_number)
1126 {
1127 case REG_A:
1128 p = emit_s (0, prefix, p);
1129 break;
1130 case REG_HL:
1131 p = parse_exp (p, &term);
1132 if ((!term.X_md) && (term.X_op == O_register))
1133 {
1134 rnum = term.X_add_number;
1135 if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1136 {
1137 q = frag_more (2);
1138 *q++ = 0xED;
1139 *q = opcode + ((rnum & 3) << 4);
1140 break;
1141 }
1142 }
1143 /* Fall through. */
1144 default:
1145 ill_op ();
1146 }
1147 return p;
1148 }
1149
1150 static const char *
1151 emit_add (char prefix, char opcode, const char * args)
1152 {
1153 expressionS term;
1154 int lhs, rhs;
1155 const char *p;
1156 char *q;
1157
1158 p = parse_exp (args, &term);
1159 if (*p++ != ',')
1160 {
1161 error (_("bad intruction syntax"));
1162 return p;
1163 }
1164
1165 if ((term.X_md) || (term.X_op != O_register))
1166 ill_op ();
1167 else
1168 switch (term.X_add_number & ~R_INDEX)
1169 {
1170 case REG_A:
1171 p = emit_s (0, prefix, p);
1172 break;
1173 case REG_HL:
1174 lhs = term.X_add_number;
1175 p = parse_exp (p, &term);
1176 if ((!term.X_md) && (term.X_op == O_register))
1177 {
1178 rhs = term.X_add_number;
1179 if ((rhs & R_ARITH)
1180 && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
1181 {
1182 q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1183 if (lhs & R_INDEX)
1184 *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1185 *q = opcode + ((rhs & 3) << 4);
1186 break;
1187 }
1188 }
1189 /* Fall through. */
1190 default:
1191 ill_op ();
1192 }
1193 return p;
1194 }
1195
1196 static const char *
1197 emit_bit (char prefix, char opcode, const char * args)
1198 {
1199 expressionS b;
1200 int bn;
1201 const char *p;
1202
1203 p = parse_exp (args, &b);
1204 if (*p++ != ',')
1205 error (_("bad intruction syntax"));
1206
1207 bn = b.X_add_number;
1208 if ((!b.X_md)
1209 && (b.X_op == O_constant)
1210 && (0 <= bn)
1211 && (bn < 8))
1212 {
1213 if (opcode == 0x40)
1214 /* Bit : no optional third operand. */
1215 p = emit_m (prefix, opcode + (bn << 3), p);
1216 else
1217 /* Set, res : resulting byte can be copied to register. */
1218 p = emit_mr (prefix, opcode + (bn << 3), p);
1219 }
1220 else
1221 ill_op ();
1222 return p;
1223 }
1224
1225 static const char *
1226 emit_jpcc (char prefix, char opcode, const char * args)
1227 {
1228 char cc;
1229 const char *p;
1230
1231 p = parse_cc (args, & cc);
1232 if (p && *p++ == ',')
1233 p = emit_call (0, opcode + cc, p);
1234 else
1235 p = (prefix == (char)0xC3)
1236 ? emit_jp (0xE9, prefix, args)
1237 : emit_call (0, prefix, args);
1238 return p;
1239 }
1240
1241 static const char *
1242 emit_jrcc (char prefix, char opcode, const char * args)
1243 {
1244 char cc;
1245 const char *p;
1246
1247 p = parse_cc (args, &cc);
1248 if (p && *p++ == ',')
1249 {
1250 if (cc > (3 << 3))
1251 error (_("condition code invalid for jr"));
1252 else
1253 p = emit_jr (0, opcode + cc, p);
1254 }
1255 else
1256 p = emit_jr (0, prefix, args);
1257
1258 return p;
1259 }
1260
1261 static const char *
1262 emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1263 char opcode_in ATTRIBUTE_UNUSED, const char * args)
1264 {
1265 expressionS op;
1266 const char * p;
1267 char prefix, opcode;
1268
1269 p = parse_exp (args, &op);
1270 p = skip_space (p);
1271 if (*p++ != ',')
1272 {
1273 error (_("bad instruction syntax"));
1274 return p;
1275 }
1276
1277 prefix = opcode = 0;
1278 if (op.X_op == O_register)
1279 switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1280 {
1281 case REG_AF:
1282 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1283 {
1284 /* The scrubber changes '\'' to '`' in this context. */
1285 if (*p == '`')
1286 ++p;
1287 opcode = 0x08;
1288 }
1289 break;
1290 case REG_DE:
1291 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1292 opcode = 0xEB;
1293 break;
1294 case REG_SP|0x8000:
1295 p = parse_exp (p, & op);
1296 if (op.X_op == O_register
1297 && op.X_md == 0
1298 && (op.X_add_number & ~R_INDEX) == REG_HL)
1299 {
1300 opcode = 0xE3;
1301 if (R_INDEX & op.X_add_number)
1302 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1303 }
1304 break;
1305 }
1306 if (opcode)
1307 emit_insn (prefix, opcode, p);
1308 else
1309 ill_op ();
1310
1311 return p;
1312 }
1313
1314 static const char *
1315 emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1316 const char * args)
1317 {
1318 expressionS reg, port;
1319 const char *p;
1320 char *q;
1321
1322 p = parse_exp (args, &reg);
1323 if (*p++ != ',')
1324 {
1325 error (_("bad intruction syntax"));
1326 return p;
1327 }
1328
1329 p = parse_exp (p, &port);
1330 if (reg.X_md == 0
1331 && reg.X_op == O_register
1332 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1333 && (port.X_md))
1334 {
1335 if (port.X_op != O_md1 && port.X_op != O_register)
1336 {
1337 if (REG_A == reg.X_add_number)
1338 {
1339 q = frag_more (1);
1340 *q = 0xDB;
1341 emit_byte (&port, BFD_RELOC_8);
1342 }
1343 else
1344 ill_op ();
1345 }
1346 else
1347 {
1348 if (port.X_add_number == REG_C)
1349 {
1350 if (reg.X_add_number == REG_F)
1351 check_mach (INS_UNDOC);
1352 else
1353 {
1354 q = frag_more (2);
1355 *q++ = 0xED;
1356 *q = 0x40|((reg.X_add_number&7)<<3);
1357 }
1358 }
1359 else
1360 ill_op ();
1361 }
1362 }
1363 else
1364 ill_op ();
1365 return p;
1366 }
1367
1368 static const char *
1369 emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1370 const char * args)
1371 {
1372 expressionS reg, port;
1373 const char *p;
1374 char *q;
1375
1376 p = parse_exp (args, & port);
1377 if (*p++ != ',')
1378 {
1379 error (_("bad intruction syntax"));
1380 return p;
1381 }
1382 p = parse_exp (p, &reg);
1383 if (!port.X_md)
1384 { ill_op (); return p; }
1385 /* Allow "out (c), 0" as unportable instruction. */
1386 if (reg.X_op == O_constant && reg.X_add_number == 0)
1387 {
1388 check_mach (INS_UNPORT);
1389 reg.X_op = O_register;
1390 reg.X_add_number = 6;
1391 }
1392 if (reg.X_md
1393 || reg.X_op != O_register
1394 || reg.X_add_number > 7)
1395 ill_op ();
1396 else
1397 if (port.X_op != O_register && port.X_op != O_md1)
1398 {
1399 if (REG_A == reg.X_add_number)
1400 {
1401 q = frag_more (1);
1402 *q = 0xD3;
1403 emit_byte (&port, BFD_RELOC_8);
1404 }
1405 else
1406 ill_op ();
1407 }
1408 else
1409 {
1410 if (REG_C == port.X_add_number)
1411 {
1412 q = frag_more (2);
1413 *q++ = 0xED;
1414 *q = 0x41 | (reg.X_add_number << 3);
1415 }
1416 else
1417 ill_op ();
1418 }
1419 return p;
1420 }
1421
1422 static const char *
1423 emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1424 {
1425 expressionS addr;
1426 const char *p;
1427 char *q;
1428
1429 p = parse_exp (args, &addr);
1430 if (addr.X_op != O_constant)
1431 {
1432 error ("rst needs constant address");
1433 return p;
1434 }
1435
1436 if (addr.X_add_number & ~(7 << 3))
1437 ill_op ();
1438 else
1439 {
1440 q = frag_more (1);
1441 *q = opcode + (addr.X_add_number & (7 << 3));
1442 }
1443 return p;
1444 }
1445
1446 static void
1447 emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d)
1448 {
1449 char *q;
1450
1451 if (src->X_md)
1452 ill_op ();
1453 else
1454 {
1455 if (src->X_op == O_register)
1456 {
1457 if (src->X_add_number>7)
1458 ill_op ();
1459 if (prefix)
1460 {
1461 q = frag_more (2);
1462 *q++ = prefix;
1463 }
1464 else
1465 q = frag_more (1);
1466 *q = opcode + src->X_add_number;
1467 if (d)
1468 emit_byte (d, BFD_RELOC_Z80_DISP8);
1469 }
1470 else
1471 {
1472 if (prefix)
1473 {
1474 q = frag_more (2);
1475 *q++ = prefix;
1476 }
1477 else
1478 q = frag_more (1);
1479 *q = opcode^0x46;
1480 if (d)
1481 emit_byte (d, BFD_RELOC_Z80_DISP8);
1482 emit_byte (src, BFD_RELOC_8);
1483 }
1484 }
1485 }
1486
1487 static void
1488 emit_ldreg (int dest, expressionS * src)
1489 {
1490 char *q;
1491 int rnum;
1492
1493 switch (dest)
1494 {
1495 /* 8 Bit ld group: */
1496 case REG_I:
1497 case REG_R:
1498 if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A)
1499 {
1500 q = frag_more (2);
1501 *q++ = 0xED;
1502 *q = (dest == REG_I) ? 0x47 : 0x4F;
1503 }
1504 else
1505 ill_op ();
1506 break;
1507
1508 case REG_A:
1509 if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1)
1510 {
1511 q = frag_more (1);
1512 *q = 0x3A;
1513 emit_word (src);
1514 break;
1515 }
1516
1517 if ((src->X_md)
1518 && src->X_op == O_register
1519 && (src->X_add_number == REG_BC || src->X_add_number == REG_DE))
1520 {
1521 q = frag_more (1);
1522 *q = 0x0A + ((dest & 1) << 4);
1523 break;
1524 }
1525
1526 if ((!src->X_md)
1527 && src->X_op == O_register
1528 && (src->X_add_number == REG_R || src->X_add_number == REG_I))
1529 {
1530 q = frag_more (2);
1531 *q++ = 0xED;
1532 *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F;
1533 break;
1534 }
1535 /* Fall through. */
1536 case REG_B:
1537 case REG_C:
1538 case REG_D:
1539 case REG_E:
1540 emit_sx (0, 0x40 + (dest << 3), src);
1541 break;
1542
1543 case REG_H:
1544 case REG_L:
1545 if ((src->X_md == 0)
1546 && (src->X_op == O_register)
1547 && (src->X_add_number & R_INDEX))
1548 ill_op ();
1549 else
1550 emit_sx (0, 0x40 + (dest << 3), src);
1551 break;
1552
1553 case R_IX | REG_H:
1554 case R_IX | REG_L:
1555 case R_IY | REG_H:
1556 case R_IY | REG_L:
1557 if (src->X_md)
1558 {
1559 ill_op ();
1560 break;
1561 }
1562 check_mach (INS_UNDOC);
1563 if (src-> X_op == O_register)
1564 {
1565 rnum = src->X_add_number;
1566 if ((rnum & ~R_INDEX) < 8
1567 && ((rnum & R_INDEX) == (dest & R_INDEX)
1568 || ( (rnum & ~R_INDEX) != REG_H
1569 && (rnum & ~R_INDEX) != REG_L)))
1570 {
1571 q = frag_more (2);
1572 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1573 *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7);
1574 }
1575 else
1576 ill_op ();
1577 }
1578 else
1579 {
1580 q = frag_more (2);
1581 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1582 *q = 0x06 + ((dest & 0x07) << 3);
1583 emit_byte (src, BFD_RELOC_8);
1584 }
1585 break;
1586
1587 /* 16 Bit ld group: */
1588 case REG_SP:
1589 if (src->X_md == 0
1590 && src->X_op == O_register
1591 && REG_HL == (src->X_add_number &~ R_INDEX))
1592 {
1593 q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1);
1594 if (src->X_add_number & R_INDEX)
1595 *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD;
1596 *q = 0xF9;
1597 break;
1598 }
1599 /* Fall through. */
1600 case REG_BC:
1601 case REG_DE:
1602 if (src->X_op == O_register || src->X_op != O_md1)
1603 ill_op ();
1604 q = frag_more (src->X_md ? 2 : 1);
1605 if (src->X_md)
1606 {
1607 *q++ = 0xED;
1608 *q = 0x4B + ((dest & 3) << 4);
1609 }
1610 else
1611 *q = 0x01 + ((dest & 3) << 4);
1612 emit_word (src);
1613 break;
1614
1615 case REG_HL:
1616 case REG_HL | R_IX:
1617 case REG_HL | R_IY:
1618 if (src->X_op == O_register || src->X_op == O_md1)
1619 ill_op ();
1620 q = frag_more ((dest & R_INDEX) ? 2 : 1);
1621 if (dest & R_INDEX)
1622 * q ++ = (dest & R_IX) ? 0xDD : 0xFD;
1623 *q = (src->X_md) ? 0x2A : 0x21;
1624 emit_word (src);
1625 break;
1626
1627 case REG_AF:
1628 case REG_F:
1629 ill_op ();
1630 break;
1631
1632 default:
1633 abort ();
1634 }
1635 }
1636
1637 static const char *
1638 emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
1639 const char * args)
1640 {
1641 expressionS dst, src;
1642 const char *p;
1643 char *q;
1644 char prefix, opcode;
1645
1646 p = parse_exp (args, &dst);
1647 if (*p++ != ',')
1648 error (_("bad intruction syntax"));
1649 p = parse_exp (p, &src);
1650
1651 switch (dst.X_op)
1652 {
1653 case O_md1:
1654 emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70,
1655 &src, symbol_get_value_expression (dst.X_add_symbol));
1656 break;
1657
1658 case O_register:
1659 if (dst.X_md)
1660 {
1661 switch (dst.X_add_number)
1662 {
1663 case REG_BC:
1664 case REG_DE:
1665 if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A)
1666 {
1667 q = frag_more (1);
1668 *q = 0x02 + ( (dst.X_add_number & 1) << 4);
1669 }
1670 else
1671 ill_op ();
1672 break;
1673 case REG_HL:
1674 emit_ldxhl (0, 0x70, &src, NULL);
1675 break;
1676 default:
1677 ill_op ();
1678 }
1679 }
1680 else
1681 emit_ldreg (dst.X_add_number, &src);
1682 break;
1683
1684 default:
1685 if (src.X_md != 0 || src.X_op != O_register)
1686 ill_op ();
1687 prefix = opcode = 0;
1688 switch (src.X_add_number)
1689 {
1690 case REG_A:
1691 opcode = 0x32; break;
1692 case REG_BC: case REG_DE: case REG_SP:
1693 prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break;
1694 case REG_HL:
1695 opcode = 0x22; break;
1696 case REG_HL|R_IX:
1697 prefix = 0xDD; opcode = 0x22; break;
1698 case REG_HL|R_IY:
1699 prefix = 0xFD; opcode = 0x22; break;
1700 }
1701 if (opcode)
1702 {
1703 q = frag_more (prefix?2:1);
1704 if (prefix)
1705 *q++ = prefix;
1706 *q = opcode;
1707 emit_word (&dst);
1708 }
1709 else
1710 ill_op ();
1711 }
1712 return p;
1713 }
1714
1715 static const char *
1716 emit_data (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1717 {
1718 const char *p, *q;
1719 char *u, quote;
1720 int cnt;
1721 expressionS exp;
1722
1723 p = skip_space (args);
1724 if (!*p)
1725 error (_("missing operand"));
1726
1727 while (*p)
1728 {
1729 if (*p == '\"' || *p == '\'')
1730 {
1731 if (opcode == 1)
1732 {
1733 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
1734 ;
1735 u = frag_more (cnt);
1736 memcpy (u, q, cnt);
1737 if (!*p)
1738 as_warn (_("unterminated string"));
1739 else
1740 p = skip_space (p+1);
1741 }
1742 else
1743 {
1744 ill_op ();
1745 break;
1746 }
1747 }
1748 else
1749 {
1750 p = parse_exp (p, &exp);
1751 if (exp.X_op == O_md1 || exp.X_op == O_register)
1752 {
1753 ill_op ();
1754 break;
1755 }
1756 if (exp.X_md)
1757 as_warn (_("parentheses ignored"));
1758 if (opcode == 1)
1759 emit_byte (&exp, BFD_RELOC_8);
1760 else
1761 emit_word (&exp);
1762 p = skip_space (p);
1763 }
1764 if (*p)
1765 {
1766 if (*p != ',')
1767 as_warn (_("missing ','"));
1768 else
1769 ++p;
1770 }
1771 }
1772 return p;
1773 }
1774
1775 static const char *
1776 emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1777 {
1778 const char *p;
1779
1780 p = skip_space (args);
1781 if (TOLOWER (*p++) != 'a' || *p++ != ',')
1782 ill_op ();
1783 else
1784 {
1785 char *q, reg;
1786
1787 reg = TOLOWER (*p++);
1788 switch (reg)
1789 {
1790 case 'b':
1791 case 'c':
1792 case 'd':
1793 case 'e':
1794 check_mach (INS_R800);
1795 if (!*skip_space (p))
1796 {
1797 q = frag_more (2);
1798 *q++ = prefix;
1799 *q = opcode + ((reg - 'b') << 3);
1800 break;
1801 }
1802 default:
1803 ill_op ();
1804 }
1805 }
1806 return p;
1807 }
1808
1809 static const char *
1810 emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1811 {
1812 const char *p;
1813
1814 p = skip_space (args);
1815 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
1816 ill_op ();
1817 else
1818 {
1819 expressionS reg;
1820 char *q;
1821
1822 p = parse_exp (p, & reg);
1823
1824 if ((!reg.X_md) && reg.X_op == O_register)
1825 switch (reg.X_add_number)
1826 {
1827 case REG_BC:
1828 case REG_SP:
1829 check_mach (INS_R800);
1830 q = frag_more (2);
1831 *q++ = prefix;
1832 *q = opcode + ((reg.X_add_number & 3) << 4);
1833 break;
1834 default:
1835 ill_op ();
1836 }
1837 }
1838 return p;
1839 }
1840
1841 static table_t instab[] =
1842 {
1843 { "adc", 0x88, 0x4A, emit_adc },
1844 { "add", 0x80, 0x09, emit_add },
1845 { "and", 0x00, 0xA0, emit_s },
1846 { "bit", 0xCB, 0x40, emit_bit },
1847 { "call", 0xCD, 0xC4, emit_jpcc },
1848 { "ccf", 0x00, 0x3F, emit_insn },
1849 { "cp", 0x00, 0xB8, emit_s },
1850 { "cpd", 0xED, 0xA9, emit_insn },
1851 { "cpdr", 0xED, 0xB9, emit_insn },
1852 { "cpi", 0xED, 0xA1, emit_insn },
1853 { "cpir", 0xED, 0xB1, emit_insn },
1854 { "cpl", 0x00, 0x2F, emit_insn },
1855 { "daa", 0x00, 0x27, emit_insn },
1856 { "db", 0x00, 0x01, emit_data },
1857 { "dec", 0x0B, 0x05, emit_incdec },
1858 { "defb", 0x00, 0x01, emit_data },
1859 { "defw", 0x00, 0x02, emit_data },
1860 { "di", 0x00, 0xF3, emit_insn },
1861 { "djnz", 0x00, 0x10, emit_jr },
1862 { "dw", 0x00, 0x02, emit_data },
1863 { "ei", 0x00, 0xFB, emit_insn },
1864 { "ex", 0x00, 0x00, emit_ex},
1865 { "exx", 0x00, 0xD9, emit_insn },
1866 { "halt", 0x00, 0x76, emit_insn },
1867 { "im", 0xED, 0x46, emit_im },
1868 { "in", 0x00, 0x00, emit_in },
1869 { "inc", 0x03, 0x04, emit_incdec },
1870 { "ind", 0xED, 0xAA, emit_insn },
1871 { "indr", 0xED, 0xBA, emit_insn },
1872 { "ini", 0xED, 0xA2, emit_insn },
1873 { "inir", 0xED, 0xB2, emit_insn },
1874 { "jp", 0xC3, 0xC2, emit_jpcc },
1875 { "jr", 0x18, 0x20, emit_jrcc },
1876 { "ld", 0x00, 0x00, emit_ld },
1877 { "ldd", 0xED, 0xA8, emit_insn },
1878 { "lddr", 0xED, 0xB8, emit_insn },
1879 { "ldi", 0xED, 0xA0, emit_insn },
1880 { "ldir", 0xED, 0xB0, emit_insn },
1881 { "mulub", 0xED, 0xC5, emit_mulub }, /* R800 only. */
1882 { "muluw", 0xED, 0xC3, emit_muluw }, /* R800 only. */
1883 { "neg", 0xed, 0x44, emit_insn },
1884 { "nop", 0x00, 0x00, emit_insn },
1885 { "or", 0x00, 0xB0, emit_s },
1886 { "otdr", 0xED, 0xBB, emit_insn },
1887 { "otir", 0xED, 0xB3, emit_insn },
1888 { "out", 0x00, 0x00, emit_out },
1889 { "outd", 0xED, 0xAB, emit_insn },
1890 { "outi", 0xED, 0xA3, emit_insn },
1891 { "pop", 0x00, 0xC1, emit_pop },
1892 { "push", 0x00, 0xC5, emit_pop },
1893 { "res", 0xCB, 0x80, emit_bit },
1894 { "ret", 0xC9, 0xC0, emit_retcc },
1895 { "reti", 0xED, 0x4D, emit_insn },
1896 { "retn", 0xED, 0x45, emit_insn },
1897 { "rl", 0xCB, 0x10, emit_mr },
1898 { "rla", 0x00, 0x17, emit_insn },
1899 { "rlc", 0xCB, 0x00, emit_mr },
1900 { "rlca", 0x00, 0x07, emit_insn },
1901 { "rld", 0xED, 0x6F, emit_insn },
1902 { "rr", 0xCB, 0x18, emit_mr },
1903 { "rra", 0x00, 0x1F, emit_insn },
1904 { "rrc", 0xCB, 0x08, emit_mr },
1905 { "rrca", 0x00, 0x0F, emit_insn },
1906 { "rrd", 0xED, 0x67, emit_insn },
1907 { "rst", 0x00, 0xC7, emit_rst},
1908 { "sbc", 0x98, 0x42, emit_adc },
1909 { "scf", 0x00, 0x37, emit_insn },
1910 { "set", 0xCB, 0xC0, emit_bit },
1911 { "sla", 0xCB, 0x20, emit_mr },
1912 { "sli", 0xCB, 0x30, emit_mr },
1913 { "sll", 0xCB, 0x30, emit_mr },
1914 { "sra", 0xCB, 0x28, emit_mr },
1915 { "srl", 0xCB, 0x38, emit_mr },
1916 { "sub", 0x00, 0x90, emit_s },
1917 { "xor", 0x00, 0xA8, emit_s },
1918 } ;
1919
1920 void
1921 md_assemble (char* str)
1922 {
1923 const char *p;
1924 char * old_ptr;
1925 int i;
1926 table_t *insp;
1927
1928 err_flag = 0;
1929 old_ptr = input_line_pointer;
1930 p = skip_space (str);
1931 for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
1932 buf[i++] = TOLOWER (*p++);
1933
1934 if ((i == BUFLEN)
1935 || ((*p) && (!ISSPACE (*p))))
1936 as_bad (_("illegal instruction '%s'"), buf);
1937
1938 buf[i] = 0;
1939 p = skip_space (p);
1940 key = buf;
1941
1942 insp = bsearch (&key, instab, ARRAY_SIZE (instab),
1943 sizeof (instab[0]), key_cmp);
1944 if (!insp)
1945 as_bad (_("illegal instruction '%s'"), buf);
1946 else
1947 {
1948 p = insp->fp (insp->prefix, insp->opcode, p);
1949 p = skip_space (p);
1950 if ((!err_flag) && *p)
1951 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
1952 *p);
1953 }
1954 input_line_pointer = old_ptr;
1955 }
1956
1957 void
1958 md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
1959 {
1960 long val = * (long *) valP;
1961 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1962
1963 switch (fixP->fx_r_type)
1964 {
1965 case BFD_RELOC_8_PCREL:
1966 if (fixP->fx_addsy)
1967 {
1968 fixP->fx_no_overflow = 1;
1969 fixP->fx_done = 0;
1970 }
1971 else
1972 {
1973 fixP->fx_no_overflow = (-128 <= val && val < 128);
1974 if (!fixP->fx_no_overflow)
1975 as_bad_where (fixP->fx_file, fixP->fx_line,
1976 _("relative jump out of range"));
1977 *buf++ = val;
1978 fixP->fx_done = 1;
1979 }
1980 break;
1981
1982 case BFD_RELOC_Z80_DISP8:
1983 if (fixP->fx_addsy)
1984 {
1985 fixP->fx_no_overflow = 1;
1986 fixP->fx_done = 0;
1987 }
1988 else
1989 {
1990 fixP->fx_no_overflow = (-128 <= val && val < 128);
1991 if (!fixP->fx_no_overflow)
1992 as_bad_where (fixP->fx_file, fixP->fx_line,
1993 _("index offset out of range"));
1994 *buf++ = val;
1995 fixP->fx_done = 1;
1996 }
1997 break;
1998
1999 case BFD_RELOC_8:
2000 if (val > 255 || val < -128)
2001 as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
2002 *buf++ = val;
2003 if (fixP->fx_addsy == NULL)
2004 fixP->fx_done = 1;
2005 break;
2006
2007 case BFD_RELOC_16:
2008 *buf++ = val;
2009 *buf++ = (val >> 8);
2010 if (fixP->fx_addsy == NULL)
2011 fixP->fx_done = 1;
2012 break;
2013
2014 case BFD_RELOC_32: /* .Long may produce this. */
2015 *buf++ = val;
2016 *buf++ = (val >> 8);
2017 *buf++ = (val >> 16);
2018 *buf++ = (val >> 24);
2019 if (fixP->fx_addsy == NULL)
2020 fixP->fx_done = 1;
2021 break;
2022
2023 default:
2024 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
2025 abort ();
2026 }
2027 }
2028
2029 /* GAS will call this to generate a reloc. GAS will pass the
2030 resulting reloc to `bfd_install_relocation'. This currently works
2031 poorly, as `bfd_install_relocation' often does the wrong thing, and
2032 instances of `tc_gen_reloc' have been written to work around the
2033 problems, which in turns makes it difficult to fix
2034 `bfd_install_relocation'. */
2035
2036 /* If while processing a fixup, a reloc really
2037 needs to be created then it is done here. */
2038
2039 arelent *
2040 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
2041 {
2042 arelent *reloc;
2043
2044 if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
2045 {
2046 as_bad_where (fixp->fx_file, fixp->fx_line,
2047 _("reloc %d not supported by object file format"),
2048 (int) fixp->fx_r_type);
2049 return NULL;
2050 }
2051
2052 reloc = xmalloc (sizeof (arelent));
2053 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2054 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2055 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2056 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2057 reloc->addend = fixp->fx_offset;
2058
2059 return reloc;
2060 }
2061
This page took 0.091866 seconds and 4 git commands to generate.