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