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