1 /* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800
2 Copyright 2005 Free Software Foundation, Inc.
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "safe-ctype.h"
28 #include "libiberty.h"
30 /* Exported constants. */
31 const char comment_chars
[] = ";\0";
32 const char line_comment_chars
[] = "#;\0";
33 const char line_separator_chars
[] = "\0";
34 const char EXP_CHARS
[] = "eE\0";
35 const char FLT_CHARS
[] = "RrFf\0";
37 /* For machine specific options. */
38 const char * md_shortopts
= ""; /* None yet. */
42 OPTION_MACH_Z80
= OPTION_MD_BASE
,
57 struct option md_longopts
[] =
59 { "z80", no_argument
, NULL
, OPTION_MACH_Z80
},
60 { "r800", no_argument
, NULL
, OPTION_MACH_R800
},
61 { "ignore-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_IUD
},
62 { "Wnud", no_argument
, NULL
, OPTION_MACH_IUD
},
63 { "warn-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_WUD
},
64 { "Wud", no_argument
, NULL
, OPTION_MACH_WUD
},
65 { "forbid-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_FUD
},
66 { "Fud", no_argument
, NULL
, OPTION_MACH_FUD
},
67 { "ignore-unportable-instructions", no_argument
, NULL
, OPTION_MACH_IUP
},
68 { "Wnup", no_argument
, NULL
, OPTION_MACH_IUP
},
69 { "warn-unportable-instructions", no_argument
, NULL
, OPTION_MACH_WUP
},
70 { "Wup", no_argument
, NULL
, OPTION_MACH_WUP
},
71 { "forbid-unportable-instructions", no_argument
, NULL
, OPTION_MACH_FUP
},
72 { "Fup", no_argument
, NULL
, OPTION_MACH_FUP
},
74 { NULL
, no_argument
, NULL
, 0 }
77 size_t md_longopts_size
= sizeof (md_longopts
);
79 extern int coff_flags
;
80 /* Instruction classes that silently assembled. */
81 static int ins_ok
= INS_Z80
| INS_UNDOC
;
82 /* Instruction classes that generate errors. */
83 static int ins_err
= INS_R800
;
84 /* Instruction classes actually used, determines machine type. */
85 static int ins_used
= INS_Z80
;
88 md_parse_option (int c
, char* arg ATTRIBUTE_UNUSED
)
98 case OPTION_MACH_R800
:
99 ins_ok
= INS_Z80
| INS_UNDOC
| INS_R800
;
100 ins_err
= INS_UNPORT
;
102 case OPTION_MACH_IUD
:
104 ins_err
&= ~INS_UNDOC
;
106 case OPTION_MACH_IUP
:
107 ins_ok
|= INS_UNDOC
| INS_UNPORT
;
108 ins_err
&= ~(INS_UNDOC
| INS_UNPORT
);
110 case OPTION_MACH_WUD
:
111 if ((ins_ok
& INS_R800
) == 0)
113 ins_ok
&= ~(INS_UNDOC
|INS_UNPORT
);
114 ins_err
&= ~INS_UNDOC
;
117 case OPTION_MACH_WUP
:
118 ins_ok
&= ~INS_UNPORT
;
119 ins_err
&= ~(INS_UNDOC
|INS_UNPORT
);
121 case OPTION_MACH_FUD
:
122 if ((ins_ok
& INS_R800
) == 0)
124 ins_ok
&= (INS_UNDOC
| INS_UNPORT
);
125 ins_err
|= INS_UNDOC
| INS_UNPORT
;
128 case OPTION_MACH_FUP
:
129 ins_ok
&= ~INS_UNPORT
;
130 ins_err
|= INS_UNPORT
;
138 md_show_usage (FILE * f
)
141 CPU model/instruction set options:\n\
143 -z80\t\t assemble for Z80\n\
144 -ignore-undocumented-instructions\n\
146 \tsilently assemble undocumented Z80-instructions that work on R800\n\
147 -ignore-unportable-instructions\n\
149 \tsilently assemble all undocumented Z80-instructions\n\
150 -warn-undocumented-instructions\n\
152 \tissue warnings for undocumented Z80-instructions that work on R800\n\
153 -warn-unportable-instructions\n\
155 \tissue warnings for other undocumented Z80-instructions\n\
156 -forbid-undocumented-instructions\n\
158 \ttreat all undocumented z80-instructions as errors\n\
159 -forbid-unportable-instructions\n\
161 \ttreat undocumented z80-instructions that do not work on R800 as errors\n\
162 -r800\t assemble for R800\n\n\
163 Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n");
166 static symbolS
* zero
;
174 p
= input_line_pointer
;
175 input_line_pointer
= "0";
178 input_line_pointer
= p
;
179 zero
= make_expr_symbol (& nul
);
180 /* We do not use relaxation (yet). */
189 if (ins_used
& (INS_UNPORT
| INS_R800
))
190 ins_used
|= INS_UNDOC
;
195 mach_type
= bfd_mach_z80strict
;
197 case INS_Z80
|INS_UNDOC
:
198 mach_type
= bfd_mach_z80
;
200 case INS_Z80
|INS_UNDOC
|INS_UNPORT
:
201 mach_type
= bfd_mach_z80full
;
203 case INS_Z80
|INS_UNDOC
|INS_R800
:
204 mach_type
= bfd_mach_r800
;
210 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach_type
);
213 /* Port specific features. */
214 const pseudo_typeS md_pseudo_table
[] =
216 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
217 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
218 { "psect", obj_coff_section
, 0}, /* TODO: Translate attributes. */
219 { "set", 0, 0}, /* Real instruction on z80. */
224 skip_space (const char *s
)
226 while (*s
== ' ' || *s
== '\t')
231 /* A non-zero return-value causes a continue in the
232 function read_a_source_file () in ../read.c. */
234 z80_start_line_hook (void)
239 /* Convert one character constants. */
240 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
245 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
247 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
254 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
258 as_bad (_("-- unterminated string"));
259 ignore_rest_of_line ();
265 /* Check for <label>[:] (EQU|DEFL) <value>. */
266 if (is_name_beginner (*input_line_pointer
))
268 char c
, *rest
, *line_start
;
272 line_start
= input_line_pointer
;
277 c
= get_symbol_end ();
278 rest
= input_line_pointer
+ 1;
282 if (*rest
== ' ' || *rest
== '\t')
284 if (strncasecmp (rest
, "EQU", 3) == 0)
286 else if (strncasecmp (rest
, "DEFL", 4) == 0)
290 if (len
&& (rest
[len
] == ' ' || rest
[len
] == '\t'))
292 /* Handle assignment here. */
293 input_line_pointer
= rest
+ len
;
294 if (line_start
[-1] == '\n')
295 bump_line_counters ();
296 /* Most Z80 assemblers require the first definition of a
297 label to use "EQU" and redefinitions to have "DEFL". */
298 if (len
== 3 && (symbolP
= symbol_find (line_start
)) != NULL
)
300 if (S_IS_DEFINED (symbolP
) || symbol_equated_p (symbolP
))
301 as_bad (_("symbol `%s' is already defined"), line_start
);
303 /* All symbols may be redefined. */
304 equals (line_start
, 1);
309 /* Restore line and pointer. */
310 *input_line_pointer
= c
;
311 input_line_pointer
= line_start
;
318 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
324 md_atof (int type ATTRIBUTE_UNUSED
, char *litP ATTRIBUTE_UNUSED
,
325 int *sizeP ATTRIBUTE_UNUSED
)
327 return _("floating point numbers are not implemented");
331 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
337 md_pcrel_from (fixS
* fixp
)
339 return fixp
->fx_where
+
340 fixp
->fx_frag
->fr_address
+ 1;
343 typedef const char * (asfunc
)(char, char, const char*);
345 typedef struct _table_t
353 /* Compares the key for structs that start with a char * to the key. */
355 key_cmp (const void * a
, const void * b
)
357 const char *str_a
, *str_b
;
359 str_a
= *((const char**)a
);
360 str_b
= *((const char**)b
);
361 return strcmp (str_a
, str_b
);
364 #define BUFLEN 8 /* Large enough for any keyword. */
367 const char *key
= buf
;
369 #define R_STACKABLE (0x80)
370 #define R_ARITH (0x40)
373 #define R_INDEX (R_IX | R_IY)
382 #define REG_F (6 | 8)
386 #define REG_AF (3 | R_STACKABLE)
387 #define REG_BC (0 | R_STACKABLE | R_ARITH)
388 #define REG_DE (1 | R_STACKABLE | R_ARITH)
389 #define REG_HL (2 | R_STACKABLE | R_ARITH)
390 #define REG_SP (3 | R_ARITH)
392 static const struct reg_entry
410 {"ix", REG_HL
| R_IX
},
411 {"ixh",REG_H
| R_IX
},
412 {"ixl",REG_L
| R_IX
},
413 {"iy", REG_HL
| R_IY
},
414 {"iyh",REG_H
| R_IY
},
415 {"iyl",REG_L
| R_IY
},
421 /* Prevent an error on a line from also generating
422 a "junk at end of line" error message. */
423 static char err_flag
;
426 error (const char * message
)
435 error (_("illegal operand"));
439 wrong_mach (int ins_type
)
446 p
= "undocumented instruction";
449 p
= "instruction does not work on R800";
452 p
= "instruction only works R800";
455 p
= 0; /* Not reachables. */
458 if (ins_type
& ins_err
)
465 check_mach (int ins_type
)
467 if ((ins_type
& ins_ok
) == 0)
468 wrong_mach (ins_type
);
469 ins_used
|= ins_type
;
472 /* This function tries to subtract two symbols, the generic code does
473 that too, but this function tries harder.
474 The behaviour of this function is not altered by extra
475 fragmentations caused by the code to produce listings. */
477 z80_optimize_expr (expressionS
*resultP
, operatorT left_op
,
481 fragS
*lfrag
, *rfrag
, *cur
;
484 if (left_op
== O_subtract
485 && right
->X_op
== O_symbol
486 && resultP
->X_op
== O_symbol
)
488 lfrag
= symbol_get_frag (resultP
->X_add_symbol
);
489 rfrag
= symbol_get_frag (right
->X_add_symbol
);
491 if (S_GET_SEGMENT (right
->X_add_symbol
) != undefined_section
492 && (S_GET_SEGMENT (right
->X_add_symbol
)
493 == S_GET_SEGMENT (resultP
->X_add_symbol
)))
495 for (swap
= 0; (res
== 0) && (swap
< 2); ++swap
)
506 /* Now som == cur->fr_address - rfrag->address, except
507 the latter may not have been computed yet. */
508 for (som
= 0; cur
&& cur
!= lfrag
; cur
= cur
->fr_next
)
510 if (cur
->fr_type
== rs_fill
) /* Is the size fized? */
511 som
+= cur
->fr_fix
+cur
->fr_offset
*cur
->fr_var
;
518 resultP
->X_add_number
-= right
->X_add_number
;
519 resultP
->X_add_number
520 += (S_GET_VALUE (resultP
->X_add_symbol
)
521 - S_GET_VALUE (right
->X_add_symbol
));
522 som
-= lfrag
->fr_address
- rfrag
->fr_address
;
523 /* Correct the result if the fr_address
524 fields are not computed yet. */
525 resultP
->X_add_number
+= (swap
? -som
: som
);
526 resultP
->X_op
= O_constant
;
527 resultP
->X_add_symbol
= 0;
536 /* Check whether an expression is indirect. */
538 is_indir (const char *s
)
544 /* Indirection is indicated with parentheses. */
547 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
553 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
554 if (*p
== '\\' && p
[1])
564 p
= skip_space (p
+ 1);
570 error (_("mismatched parentheses"));
576 error (_("mismatched parentheses"));
581 /* Parse general expression. */
583 parse_exp2 (const char *s
, expressionS
*op
, segT
*pseg
)
588 const struct reg_entry
* regp
;
592 op
->X_md
= indir
= is_indir (p
);
594 p
= skip_space (p
+ 1);
596 for (i
= 0; i
< BUFLEN
; ++i
)
598 if (!ISALPHA (p
[i
])) /* Register names consist of letters only. */
600 buf
[i
] = TOLOWER (p
[i
]);
603 if ((i
< BUFLEN
) && ((p
[i
] == 0) || (strchr (")+-, \t", p
[i
]))))
606 regp
= bsearch (& key
, regtable
, ARRAY_SIZE (regtable
),
607 sizeof (regtable
[0]), key_cmp
);
611 op
->X_add_symbol
= op
->X_op_symbol
= 0;
612 op
->X_add_number
= regp
->number
;
613 op
->X_op
= O_register
;
614 p
+= strlen (regp
->name
);
620 if ((regp
->number
& R_INDEX
) && (regp
->number
& R_ARITH
))
624 if ((*p
== '+') || (*p
== '-'))
626 input_line_pointer
= (char*) p
;
627 expression (& offset
);
628 p
= skip_space (input_line_pointer
);
630 error (_("bad offset expression syntax"));
633 op
->X_add_symbol
= make_expr_symbol (& offset
);
637 /* We treat (i[xy]) as (i[xy]+0), which is how it will
638 end up anyway, unless we're processing jp (i[xy]). */
639 op
->X_add_symbol
= zero
;
644 if ((*p
== 0) || (*p
== ','))
648 /* Not an argument involving a register; use the generic parser. */
649 input_line_pointer
= (char*) s
;
650 *pseg
= expression (op
);
651 if (op
->X_op
== O_absent
)
652 error (_("missing operand"));
653 if (op
->X_op
== O_illegal
)
654 error (_("bad expression syntax"));
655 return input_line_pointer
;
659 parse_exp (const char *s
, expressionS
*op
)
662 return parse_exp2 (s
, op
, & dummy
);
665 /* Condition codes, including some synonyms provided by HiTech zas. */
666 static const struct reg_entry cc_tab
[] =
684 /* Parse condition code. */
686 parse_cc (const char *s
, char * op
)
690 struct reg_entry
* cc_p
;
692 for (i
= 0; i
< BUFLEN
; ++i
)
694 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
696 buf
[i
] = TOLOWER (s
[i
]);
700 && ((s
[i
] == 0) || (s
[i
] == ',')))
703 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
704 sizeof (cc_tab
[0]), key_cmp
);
721 emit_insn (char prefix
, char opcode
, const char * args
)
737 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
744 *p
= val
->X_add_number
;
745 if ((r_type
!= BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
748 hi
= (BFD_RELOC_8
== r_type
) ? 255 : 127;
750 if ((val
->X_add_number
< lo
) || (val
->X_add_number
> hi
))
752 if (r_type
== BFD_RELOC_Z80_DISP8
)
753 as_bad (_("offset too large"));
755 as_warn (_("overflow"));
760 fixp
= fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
761 (r_type
== BFD_RELOC_8_PCREL
) ? TRUE
: FALSE
, r_type
);
762 /* FIXME : Process constant offsets immediately. */
767 emit_word (expressionS
* val
)
772 if ( (val
->X_op
== O_register
)
773 || (val
->X_op
== O_md1
))
777 *p
= val
->X_add_number
;
778 p
[1] = (val
->X_add_number
>>8);
779 if (val
->X_op
!= O_constant
)
780 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 2,
781 val
, FALSE
, BFD_RELOC_16
);
786 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
787 /* The operand m may be r, (hl), (ix+d), (iy+d),
788 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
793 rnum
= arg
->X_add_number
;
809 if ((prefix
== 0) && (rnum
& R_INDEX
))
811 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
812 check_mach (INS_UNDOC
);
821 q
= frag_more (prefix
? 2 : 1);
824 * q
++ = opcode
+ (rnum
<< shift
);
828 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
829 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
830 emit_byte (symbol_get_value_expression (arg
->X_add_symbol
),
831 BFD_RELOC_Z80_DISP8
);
835 *q
= opcode
+(6<<shift
);
843 /* The operand m may be r, (hl), (ix+d), (iy+d),
844 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
846 emit_m (char prefix
, char opcode
, const char *args
)
851 p
= parse_exp (args
, &arg_m
);
856 emit_mx (prefix
, opcode
, 0, &arg_m
);
864 /* The operand m may be as above or one of the undocumented
865 combinations (ix+d),r and (iy+d),r (if unportable instructions
868 emit_mr (char prefix
, char opcode
, const char *args
)
870 expressionS arg_m
, arg_r
;
873 p
= parse_exp (args
, & arg_m
);
880 p
= parse_exp (p
+ 1, & arg_r
);
882 if ((arg_r
.X_md
== 0)
883 && (arg_r
.X_op
== O_register
)
884 && (arg_r
.X_add_number
< 8))
885 opcode
+= arg_r
.X_add_number
-6; /* Emit_mx () will add 6. */
891 check_mach (INS_UNPORT
);
894 emit_mx (prefix
, opcode
, 0, & arg_m
);
903 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
911 emit_mx (prefix
, opcode
, 0, arg_p
);
918 q
= frag_more (prefix
? 2 : 1);
922 emit_byte (arg_p
, BFD_RELOC_8
);
927 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
929 emit_s (char prefix
, char opcode
, const char *args
)
934 p
= parse_exp (args
, & arg_s
);
935 emit_sx (prefix
, opcode
, & arg_s
);
940 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
943 const char *p
; char *q
;
945 p
= parse_exp (args
, &addr
);
957 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
959 emit_incdec (char prefix
, char opcode
, const char * args
)
963 const char *p
; char *q
;
965 p
= parse_exp (args
, &operand
);
966 rnum
= operand
.X_add_number
;
968 && (operand
.X_op
== O_register
)
971 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
973 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
974 *q
= prefix
+ ((rnum
& 3) << 4);
978 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
979 emit_mx (0, opcode
, 3, & operand
);
987 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
993 p
= parse_exp (args
, &addr
);
1000 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1006 emit_jp (char prefix
, char opcode
, const char * args
)
1013 p
= parse_exp (args
, & addr
);
1016 rnum
= addr
.X_add_number
;
1017 if ((addr
.X_op
== O_register
&& (rnum
& ~R_INDEX
) == REG_HL
)
1018 /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
1020 || (addr
.X_op
== O_md1
&& addr
.X_add_symbol
== zero
))
1022 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1024 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1040 emit_im (char prefix
, char opcode
, const char * args
)
1046 p
= parse_exp (args
, & mode
);
1047 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1050 switch (mode
.X_add_number
)
1054 ++mode
.X_add_number
;
1059 *q
= opcode
+ 8*mode
.X_add_number
;
1068 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1074 p
= parse_exp (args
, & regp
);
1076 && (regp
.X_op
== O_register
)
1077 && (regp
.X_add_number
& R_STACKABLE
))
1081 rnum
= regp
.X_add_number
;
1085 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1089 *q
= opcode
+ ((rnum
& 3) << 4);
1098 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1103 p
= parse_cc (args
, &cc
);
1109 return p
? p
: args
;
1113 emit_adc (char prefix
, char opcode
, const char * args
)
1120 p
= parse_exp (args
, &term
);
1123 error (_("bad intruction syntax"));
1127 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1130 switch (term
.X_add_number
)
1133 p
= emit_s (0, prefix
, p
);
1136 p
= parse_exp (p
, &term
);
1137 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1139 rnum
= term
.X_add_number
;
1140 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1144 *q
= opcode
+ ((rnum
& 3) << 4);
1156 emit_add (char prefix
, char opcode
, const char * args
)
1163 p
= parse_exp (args
, &term
);
1166 error (_("bad intruction syntax"));
1170 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1173 switch (term
.X_add_number
& ~R_INDEX
)
1176 p
= emit_s (0, prefix
, p
);
1179 lhs
= term
.X_add_number
;
1180 p
= parse_exp (p
, &term
);
1181 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1183 rhs
= term
.X_add_number
;
1185 && ((rhs
== lhs
) || ((rhs
& ~R_INDEX
) != REG_HL
)))
1187 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1189 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1190 *q
= opcode
+ ((rhs
& 3) << 4);
1202 emit_bit (char prefix
, char opcode
, const char * args
)
1208 p
= parse_exp (args
, &b
);
1210 error (_("bad intruction syntax"));
1212 bn
= b
.X_add_number
;
1214 && (b
.X_op
== O_constant
)
1219 /* Bit : no optional third operand. */
1220 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1222 /* Set, res : resulting byte can be copied to register. */
1223 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1231 emit_jpcc (char prefix
, char opcode
, const char * args
)
1236 p
= parse_cc (args
, & cc
);
1237 if (p
&& *p
++ == ',')
1238 p
= emit_call (0, opcode
+ cc
, p
);
1240 p
= (prefix
== (char)0xC3)
1241 ? emit_jp (0xE9, prefix
, args
)
1242 : emit_call (0, prefix
, args
);
1247 emit_jrcc (char prefix
, char opcode
, const char * args
)
1252 p
= parse_cc (args
, &cc
);
1253 if (p
&& *p
++ == ',')
1256 error (_("condition code invalid for jr"));
1258 p
= emit_jr (0, opcode
+ cc
, p
);
1261 p
= emit_jr (0, prefix
, args
);
1267 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1268 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1272 char prefix
, opcode
;
1274 p
= parse_exp (args
, &op
);
1278 error (_("bad instruction syntax"));
1282 prefix
= opcode
= 0;
1283 if (op
.X_op
== O_register
)
1284 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1287 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1289 /* The scrubber changes '\'' to '`' in this context. */
1296 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1300 p
= parse_exp (p
, & op
);
1301 if (op
.X_op
== O_register
1303 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1306 if (R_INDEX
& op
.X_add_number
)
1307 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1312 emit_insn (prefix
, opcode
, p
);
1320 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1323 expressionS reg
, port
;
1327 p
= parse_exp (args
, ®
);
1330 error (_("bad intruction syntax"));
1334 p
= parse_exp (p
, &port
);
1336 && reg
.X_op
== O_register
1337 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1340 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1342 if (REG_A
== reg
.X_add_number
)
1346 emit_byte (&port
, BFD_RELOC_8
);
1353 if (port
.X_add_number
== REG_C
)
1355 if (reg
.X_add_number
== REG_F
)
1356 check_mach (INS_UNDOC
);
1361 *q
= 0x40|((reg
.X_add_number
&7)<<3);
1374 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1377 expressionS reg
, port
;
1381 p
= parse_exp (args
, & port
);
1384 error (_("bad intruction syntax"));
1387 p
= parse_exp (p
, ®
);
1389 { ill_op (); return p
; }
1390 /* Allow "out (c), 0" as unportable instruction. */
1391 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
1393 check_mach (INS_UNPORT
);
1394 reg
.X_op
= O_register
;
1395 reg
.X_add_number
= 6;
1398 || reg
.X_op
!= O_register
1399 || reg
.X_add_number
> 7)
1402 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
1404 if (REG_A
== reg
.X_add_number
)
1408 emit_byte (&port
, BFD_RELOC_8
);
1415 if (REG_C
== port
.X_add_number
)
1419 *q
= 0x41 | (reg
.X_add_number
<< 3);
1428 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1434 p
= parse_exp (args
, &addr
);
1435 if (addr
.X_op
!= O_constant
)
1437 error ("rst needs constant address");
1441 if (addr
.X_add_number
& ~(7 << 3))
1446 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
1452 emit_ldxhl (char prefix
, char opcode
, expressionS
*src
, expressionS
*d
)
1460 if (src
->X_op
== O_register
)
1462 if (src
->X_add_number
>7)
1471 *q
= opcode
+ src
->X_add_number
;
1473 emit_byte (d
, BFD_RELOC_Z80_DISP8
);
1486 emit_byte (d
, BFD_RELOC_Z80_DISP8
);
1487 emit_byte (src
, BFD_RELOC_8
);
1493 emit_ldreg (int dest
, expressionS
* src
)
1500 /* 8 Bit ld group: */
1503 if (src
->X_md
== 0 && src
->X_op
== O_register
&& src
->X_add_number
== REG_A
)
1507 *q
= (dest
== REG_I
) ? 0x47 : 0x4F;
1514 if ((src
->X_md
) && src
->X_op
!= O_register
&& src
->X_op
!= O_md1
)
1523 && src
->X_op
== O_register
1524 && (src
->X_add_number
== REG_BC
|| src
->X_add_number
== REG_DE
))
1527 *q
= 0x0A + ((dest
& 1) << 4);
1532 && src
->X_op
== O_register
1533 && (src
->X_add_number
== REG_R
|| src
->X_add_number
== REG_I
))
1537 *q
= (src
->X_add_number
== REG_I
) ? 0x57 : 0x5F;
1545 emit_sx (0, 0x40 + (dest
<< 3), src
);
1550 if ((src
->X_md
== 0)
1551 && (src
->X_op
== O_register
)
1552 && (src
->X_add_number
& R_INDEX
))
1555 emit_sx (0, 0x40 + (dest
<< 3), src
);
1567 check_mach (INS_UNDOC
);
1568 if (src
-> X_op
== O_register
)
1570 rnum
= src
->X_add_number
;
1571 if ((rnum
& ~R_INDEX
) < 8
1572 && ((rnum
& R_INDEX
) == (dest
& R_INDEX
)
1573 || ( (rnum
& ~R_INDEX
) != REG_H
1574 && (rnum
& ~R_INDEX
) != REG_L
)))
1577 *q
++ = (dest
& R_IX
) ? 0xDD : 0xFD;
1578 *q
= 0x40 + ((dest
& 0x07) << 3) + (rnum
& 7);
1586 *q
++ = (dest
& R_IX
) ? 0xDD : 0xFD;
1587 *q
= 0x06 + ((dest
& 0x07) << 3);
1588 emit_byte (src
, BFD_RELOC_8
);
1592 /* 16 Bit ld group: */
1595 && src
->X_op
== O_register
1596 && REG_HL
== (src
->X_add_number
&~ R_INDEX
))
1598 q
= frag_more ((src
->X_add_number
& R_INDEX
) ? 2 : 1);
1599 if (src
->X_add_number
& R_INDEX
)
1600 *q
++ = (src
->X_add_number
& R_IX
) ? 0xDD : 0xFD;
1607 if (src
->X_op
== O_register
|| src
->X_op
!= O_md1
)
1609 q
= frag_more (src
->X_md
? 2 : 1);
1613 *q
= 0x4B + ((dest
& 3) << 4);
1616 *q
= 0x01 + ((dest
& 3) << 4);
1623 if (src
->X_op
== O_register
|| src
->X_op
== O_md1
)
1625 q
= frag_more ((dest
& R_INDEX
) ? 2 : 1);
1627 * q
++ = (dest
& R_IX
) ? 0xDD : 0xFD;
1628 *q
= (src
->X_md
) ? 0x2A : 0x21;
1643 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
1646 expressionS dst
, src
;
1649 char prefix
, opcode
;
1651 p
= parse_exp (args
, &dst
);
1653 error (_("bad intruction syntax"));
1654 p
= parse_exp (p
, &src
);
1659 emit_ldxhl ((dst
.X_add_number
& R_IX
) ? 0xDD : 0xFD, 0x70,
1660 &src
, symbol_get_value_expression (dst
.X_add_symbol
));
1666 switch (dst
.X_add_number
)
1670 if (src
.X_md
== 0 && src
.X_op
== O_register
&& src
.X_add_number
== REG_A
)
1673 *q
= 0x02 + ( (dst
.X_add_number
& 1) << 4);
1679 emit_ldxhl (0, 0x70, &src
, NULL
);
1686 emit_ldreg (dst
.X_add_number
, &src
);
1690 if (src
.X_md
!= 0 || src
.X_op
!= O_register
)
1692 prefix
= opcode
= 0;
1693 switch (src
.X_add_number
)
1696 opcode
= 0x32; break;
1697 case REG_BC
: case REG_DE
: case REG_SP
:
1698 prefix
= 0xED; opcode
= 0x43 + ((src
.X_add_number
&3)<<4); break;
1700 opcode
= 0x22; break;
1702 prefix
= 0xDD; opcode
= 0x22; break;
1704 prefix
= 0xFD; opcode
= 0x22; break;
1708 q
= frag_more (prefix
?2:1);
1721 emit_data (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1728 p
= skip_space (args
);
1730 error (_("missing operand"));
1734 if (*p
== '\"' || *p
== '\'')
1738 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
1740 u
= frag_more (cnt
);
1743 as_warn (_("unterminated string"));
1745 p
= skip_space (p
+1);
1755 p
= parse_exp (p
, &exp
);
1756 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
1762 as_warn (_("parentheses ignored"));
1764 emit_byte (&exp
, BFD_RELOC_8
);
1772 as_warn (_("missing ','"));
1781 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1785 p
= skip_space (args
);
1786 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
1792 reg
= TOLOWER (*p
++);
1799 check_mach (INS_R800
);
1800 if (!*skip_space (p
))
1804 *q
= opcode
+ ((reg
- 'b') << 3);
1815 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1819 p
= skip_space (args
);
1820 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
1827 p
= parse_exp (p
, & reg
);
1829 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
1830 switch (reg
.X_add_number
)
1834 check_mach (INS_R800
);
1837 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
1846 static table_t instab
[] =
1848 { "adc", 0x88, 0x4A, emit_adc
},
1849 { "add", 0x80, 0x09, emit_add
},
1850 { "and", 0x00, 0xA0, emit_s
},
1851 { "bit", 0xCB, 0x40, emit_bit
},
1852 { "call", 0xCD, 0xC4, emit_jpcc
},
1853 { "ccf", 0x00, 0x3F, emit_insn
},
1854 { "cp", 0x00, 0xB8, emit_s
},
1855 { "cpd", 0xED, 0xA9, emit_insn
},
1856 { "cpdr", 0xED, 0xB9, emit_insn
},
1857 { "cpi", 0xED, 0xA1, emit_insn
},
1858 { "cpir", 0xED, 0xB1, emit_insn
},
1859 { "cpl", 0x00, 0x2F, emit_insn
},
1860 { "daa", 0x00, 0x27, emit_insn
},
1861 { "db", 0x00, 0x01, emit_data
},
1862 { "dec", 0x0B, 0x05, emit_incdec
},
1863 { "defb", 0x00, 0x01, emit_data
},
1864 { "defw", 0x00, 0x02, emit_data
},
1865 { "di", 0x00, 0xF3, emit_insn
},
1866 { "djnz", 0x00, 0x10, emit_jr
},
1867 { "dw", 0x00, 0x02, emit_data
},
1868 { "ei", 0x00, 0xFB, emit_insn
},
1869 { "ex", 0x00, 0x00, emit_ex
},
1870 { "exx", 0x00, 0xD9, emit_insn
},
1871 { "halt", 0x00, 0x76, emit_insn
},
1872 { "im", 0xED, 0x46, emit_im
},
1873 { "in", 0x00, 0x00, emit_in
},
1874 { "inc", 0x03, 0x04, emit_incdec
},
1875 { "ind", 0xED, 0xAA, emit_insn
},
1876 { "indr", 0xED, 0xBA, emit_insn
},
1877 { "ini", 0xED, 0xA2, emit_insn
},
1878 { "inir", 0xED, 0xB2, emit_insn
},
1879 { "jp", 0xC3, 0xC2, emit_jpcc
},
1880 { "jr", 0x18, 0x20, emit_jrcc
},
1881 { "ld", 0x00, 0x00, emit_ld
},
1882 { "ldd", 0xED, 0xA8, emit_insn
},
1883 { "lddr", 0xED, 0xB8, emit_insn
},
1884 { "ldi", 0xED, 0xA0, emit_insn
},
1885 { "ldir", 0xED, 0xB0, emit_insn
},
1886 { "mulub", 0xED, 0xC5, emit_mulub
}, /* R800 only. */
1887 { "muluw", 0xED, 0xC3, emit_muluw
}, /* R800 only. */
1888 { "neg", 0xed, 0x44, emit_insn
},
1889 { "nop", 0x00, 0x00, emit_insn
},
1890 { "or", 0x00, 0xB0, emit_s
},
1891 { "otdr", 0xED, 0xBB, emit_insn
},
1892 { "otir", 0xED, 0xB3, emit_insn
},
1893 { "out", 0x00, 0x00, emit_out
},
1894 { "outd", 0xED, 0xAB, emit_insn
},
1895 { "outi", 0xED, 0xA3, emit_insn
},
1896 { "pop", 0x00, 0xC1, emit_pop
},
1897 { "push", 0x00, 0xC5, emit_pop
},
1898 { "res", 0xCB, 0x80, emit_bit
},
1899 { "ret", 0xC9, 0xC0, emit_retcc
},
1900 { "reti", 0xED, 0x4D, emit_insn
},
1901 { "retn", 0xED, 0x45, emit_insn
},
1902 { "rl", 0xCB, 0x10, emit_mr
},
1903 { "rla", 0x00, 0x17, emit_insn
},
1904 { "rlc", 0xCB, 0x00, emit_mr
},
1905 { "rlca", 0x00, 0x07, emit_insn
},
1906 { "rld", 0xED, 0x6F, emit_insn
},
1907 { "rr", 0xCB, 0x18, emit_mr
},
1908 { "rra", 0x00, 0x1F, emit_insn
},
1909 { "rrc", 0xCB, 0x08, emit_mr
},
1910 { "rrca", 0x00, 0x0F, emit_insn
},
1911 { "rrd", 0xED, 0x67, emit_insn
},
1912 { "rst", 0x00, 0xC7, emit_rst
},
1913 { "sbc", 0x98, 0x42, emit_adc
},
1914 { "scf", 0x00, 0x37, emit_insn
},
1915 { "set", 0xCB, 0xC0, emit_bit
},
1916 { "sla", 0xCB, 0x20, emit_mr
},
1917 { "sli", 0xCB, 0x30, emit_mr
},
1918 { "sll", 0xCB, 0x30, emit_mr
},
1919 { "sra", 0xCB, 0x28, emit_mr
},
1920 { "srl", 0xCB, 0x38, emit_mr
},
1921 { "sub", 0x00, 0x90, emit_s
},
1922 { "xor", 0x00, 0xA8, emit_s
},
1926 md_assemble (char* str
)
1934 old_ptr
= input_line_pointer
;
1935 p
= skip_space (str
);
1936 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
));)
1937 buf
[i
++] = TOLOWER (*p
++);
1940 || ((*p
) && (!ISSPACE (*p
))))
1941 as_bad (_("illegal instruction '%s'"), buf
);
1947 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
1948 sizeof (instab
[0]), key_cmp
);
1950 as_bad (_("illegal instruction '%s'"), buf
);
1953 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
1955 if ((!err_flag
) && *p
)
1956 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
1959 input_line_pointer
= old_ptr
;
1963 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
1965 long val
= * (long *) valP
;
1966 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1968 switch (fixP
->fx_r_type
)
1970 case BFD_RELOC_8_PCREL
:
1973 fixP
->fx_no_overflow
= 1;
1978 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
1979 if (!fixP
->fx_no_overflow
)
1980 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1981 _("relative jump out of range"));
1987 case BFD_RELOC_Z80_DISP8
:
1990 fixP
->fx_no_overflow
= 1;
1995 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
1996 if (!fixP
->fx_no_overflow
)
1997 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1998 _("index offset out of range"));
2005 if (val
> 255 || val
< -128)
2006 as_warn_where (fixP
->fx_file
, fixP
->fx_line
, _("overflow"));
2008 if (fixP
->fx_addsy
== NULL
)
2014 *buf
++ = (val
>> 8);
2015 if (fixP
->fx_addsy
== NULL
)
2019 case BFD_RELOC_32
: /* .Long may produce this. */
2021 *buf
++ = (val
>> 8);
2022 *buf
++ = (val
>> 16);
2023 *buf
++ = (val
>> 24);
2024 if (fixP
->fx_addsy
== NULL
)
2029 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP
->fx_r_type
);
2034 /* GAS will call this to generate a reloc. GAS will pass the
2035 resulting reloc to `bfd_install_relocation'. This currently works
2036 poorly, as `bfd_install_relocation' often does the wrong thing, and
2037 instances of `tc_gen_reloc' have been written to work around the
2038 problems, which in turns makes it difficult to fix
2039 `bfd_install_relocation'. */
2041 /* If while processing a fixup, a reloc really
2042 needs to be created then it is done here. */
2045 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
2049 if (! bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
))
2051 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2052 _("reloc %d not supported by object file format"),
2053 (int) fixp
->fx_r_type
);
2057 reloc
= xmalloc (sizeof (arelent
));
2058 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2059 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2060 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2061 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2062 reloc
->addend
= fixp
->fx_offset
;