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
);
214 skip_space (const char *s
)
216 while (*s
== ' ' || *s
== '\t')
221 /* A non-zero return-value causes a continue in the
222 function read_a_source_file () in ../read.c. */
224 z80_start_line_hook (void)
229 /* Convert one character constants. */
230 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
235 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
237 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
244 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
248 as_bad (_("-- unterminated string"));
249 ignore_rest_of_line ();
255 /* Check for <label>[:] [.](EQU|DEFL) <value>. */
256 if (is_name_beginner (*input_line_pointer
))
258 char c
, *rest
, *line_start
;
262 line_start
= input_line_pointer
;
267 c
= get_symbol_end ();
268 rest
= input_line_pointer
+ 1;
272 if (*rest
== ' ' || *rest
== '\t')
276 if (strncasecmp (rest
, "EQU", 3) == 0)
278 else if (strncasecmp (rest
, "DEFL", 4) == 0)
282 if (len
&& (rest
[len
] == ' ' || rest
[len
] == '\t'))
284 /* Handle assignment here. */
285 input_line_pointer
= rest
+ len
;
286 if (line_start
[-1] == '\n')
287 bump_line_counters ();
288 /* Most Z80 assemblers require the first definition of a
289 label to use "EQU" and redefinitions to have "DEFL". */
290 if (len
== 3 && (symbolP
= symbol_find (line_start
)) != NULL
)
292 if (S_IS_DEFINED (symbolP
) || symbol_equated_p (symbolP
))
293 as_bad (_("symbol `%s' is already defined"), line_start
);
295 equals (line_start
, 1);
300 /* Restore line and pointer. */
301 *input_line_pointer
= c
;
302 input_line_pointer
= line_start
;
309 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
315 md_atof (int type ATTRIBUTE_UNUSED
, char *litP ATTRIBUTE_UNUSED
,
316 int *sizeP ATTRIBUTE_UNUSED
)
318 return _("floating point numbers are not implemented");
322 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
328 md_pcrel_from (fixS
* fixp
)
330 return fixp
->fx_where
+
331 fixp
->fx_frag
->fr_address
+ 1;
334 typedef const char * (asfunc
)(char, char, const char*);
336 typedef struct _table_t
344 /* Compares the key for structs that start with a char * to the key. */
346 key_cmp (const void * a
, const void * b
)
348 const char *str_a
, *str_b
;
350 str_a
= *((const char**)a
);
351 str_b
= *((const char**)b
);
352 return strcmp (str_a
, str_b
);
355 #define BUFLEN 8 /* Large enough for any keyword. */
358 const char *key
= buf
;
360 #define R_STACKABLE (0x80)
361 #define R_ARITH (0x40)
364 #define R_INDEX (R_IX | R_IY)
373 #define REG_F (6 | 8)
377 #define REG_AF (3 | R_STACKABLE)
378 #define REG_BC (0 | R_STACKABLE | R_ARITH)
379 #define REG_DE (1 | R_STACKABLE | R_ARITH)
380 #define REG_HL (2 | R_STACKABLE | R_ARITH)
381 #define REG_SP (3 | R_ARITH)
383 static const struct reg_entry
401 {"ix", REG_HL
| R_IX
},
402 {"ixh",REG_H
| R_IX
},
403 {"ixl",REG_L
| R_IX
},
404 {"iy", REG_HL
| R_IY
},
405 {"iyh",REG_H
| R_IY
},
406 {"iyl",REG_L
| R_IY
},
412 /* Prevent an error on a line from also generating
413 a "junk at end of line" error message. */
414 static char err_flag
;
417 error (const char * message
)
426 error (_("illegal operand"));
430 wrong_mach (int ins_type
)
437 p
= "undocumented instruction";
440 p
= "instruction does not work on R800";
443 p
= "instruction only works R800";
446 p
= 0; /* Not reachable. */
449 if (ins_type
& ins_err
)
456 check_mach (int ins_type
)
458 if ((ins_type
& ins_ok
) == 0)
459 wrong_mach (ins_type
);
460 ins_used
|= ins_type
;
463 /* This function tries to subtract two symbols, the generic code does
464 that too, but this function tries harder.
465 The behaviour of this function is not altered by extra
466 fragmentations caused by the code to produce listings. */
468 z80_optimize_expr (expressionS
*resultP
, operatorT left_op
,
472 fragS
*lfrag
, *rfrag
, *cur
;
475 if (left_op
== O_subtract
476 && right
->X_op
== O_symbol
477 && resultP
->X_op
== O_symbol
)
479 lfrag
= symbol_get_frag (resultP
->X_add_symbol
);
480 rfrag
= symbol_get_frag (right
->X_add_symbol
);
482 if (S_GET_SEGMENT (right
->X_add_symbol
) != undefined_section
483 && (S_GET_SEGMENT (right
->X_add_symbol
)
484 == S_GET_SEGMENT (resultP
->X_add_symbol
)))
486 for (swap
= 0; (res
== 0) && (swap
< 2); ++swap
)
497 /* Now som == cur->fr_address - rfrag->address, except
498 the latter may not have been computed yet. */
499 for (som
= 0; cur
&& cur
!= lfrag
; cur
= cur
->fr_next
)
501 if (cur
->fr_type
== rs_fill
) /* Is the size fized? */
502 som
+= cur
->fr_fix
+cur
->fr_offset
*cur
->fr_var
;
509 resultP
->X_add_number
-= right
->X_add_number
;
510 resultP
->X_add_number
511 += (S_GET_VALUE (resultP
->X_add_symbol
)
512 - S_GET_VALUE (right
->X_add_symbol
));
513 som
-= lfrag
->fr_address
- rfrag
->fr_address
;
514 /* Correct the result if the fr_address
515 fields are not computed yet. */
516 resultP
->X_add_number
+= (swap
? -som
: som
);
517 resultP
->X_op
= O_constant
;
518 resultP
->X_add_symbol
= 0;
527 /* Check whether an expression is indirect. */
529 is_indir (const char *s
)
535 /* Indirection is indicated with parentheses. */
538 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
544 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
545 if (*p
== '\\' && p
[1])
555 p
= skip_space (p
+ 1);
561 error (_("mismatched parentheses"));
567 error (_("mismatched parentheses"));
572 /* Parse general expression. */
574 parse_exp2 (const char *s
, expressionS
*op
, segT
*pseg
)
579 const struct reg_entry
* regp
;
583 op
->X_md
= indir
= is_indir (p
);
585 p
= skip_space (p
+ 1);
587 for (i
= 0; i
< BUFLEN
; ++i
)
589 if (!ISALPHA (p
[i
])) /* Register names consist of letters only. */
591 buf
[i
] = TOLOWER (p
[i
]);
594 if ((i
< BUFLEN
) && ((p
[i
] == 0) || (strchr (")+-, \t", p
[i
]))))
597 regp
= bsearch (& key
, regtable
, ARRAY_SIZE (regtable
),
598 sizeof (regtable
[0]), key_cmp
);
602 op
->X_add_symbol
= op
->X_op_symbol
= 0;
603 op
->X_add_number
= regp
->number
;
604 op
->X_op
= O_register
;
605 p
+= strlen (regp
->name
);
611 if ((regp
->number
& R_INDEX
) && (regp
->number
& R_ARITH
))
615 if ((*p
== '+') || (*p
== '-'))
617 input_line_pointer
= (char*) p
;
618 expression (& offset
);
619 p
= skip_space (input_line_pointer
);
621 error (_("bad offset expression syntax"));
624 op
->X_add_symbol
= make_expr_symbol (& offset
);
628 /* We treat (i[xy]) as (i[xy]+0), which is how it will
629 end up anyway, unless we're processing jp (i[xy]). */
630 op
->X_add_symbol
= zero
;
635 if ((*p
== 0) || (*p
== ','))
639 /* Not an argument involving a register; use the generic parser. */
640 input_line_pointer
= (char*) s
;
641 *pseg
= expression (op
);
642 if (op
->X_op
== O_absent
)
643 error (_("missing operand"));
644 if (op
->X_op
== O_illegal
)
645 error (_("bad expression syntax"));
646 return input_line_pointer
;
650 parse_exp (const char *s
, expressionS
*op
)
653 return parse_exp2 (s
, op
, & dummy
);
656 /* Condition codes, including some synonyms provided by HiTech zas. */
657 static const struct reg_entry cc_tab
[] =
675 /* Parse condition code. */
677 parse_cc (const char *s
, char * op
)
681 struct reg_entry
* cc_p
;
683 for (i
= 0; i
< BUFLEN
; ++i
)
685 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
687 buf
[i
] = TOLOWER (s
[i
]);
691 && ((s
[i
] == 0) || (s
[i
] == ',')))
694 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
695 sizeof (cc_tab
[0]), key_cmp
);
712 emit_insn (char prefix
, char opcode
, const char * args
)
727 void z80_cons_fix_new (fragS
*frag_p
, int offset
, int nbytes
, expressionS
*exp
)
729 bfd_reloc_code_real_type r
[4] =
737 if (nbytes
< 1 || nbytes
> 4)
739 as_bad (_("unsupported BFD relocation size %u"), nbytes
);
743 fix_new_exp (frag_p
, offset
, nbytes
, exp
, 0, r
[nbytes
-1]);
748 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
755 *p
= val
->X_add_number
;
756 if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
758 as_bad(_("cannot make a relative jump to an absolute location"));
760 else if (val
->X_op
== O_constant
)
763 hi
= (BFD_RELOC_8
== r_type
) ? 255 : 127;
765 if ((val
->X_add_number
< lo
) || (val
->X_add_number
> hi
))
767 if (r_type
== BFD_RELOC_Z80_DISP8
)
768 as_bad (_("offset too large"));
770 as_warn (_("overflow"));
775 fixp
= fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
776 (r_type
== BFD_RELOC_8_PCREL
) ? TRUE
: FALSE
, r_type
);
777 /* FIXME : Process constant offsets immediately. */
782 emit_word (expressionS
* val
)
787 if ( (val
->X_op
== O_register
)
788 || (val
->X_op
== O_md1
))
792 *p
= val
->X_add_number
;
793 p
[1] = (val
->X_add_number
>>8);
794 if (val
->X_op
!= O_constant
)
795 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 2,
796 val
, FALSE
, BFD_RELOC_16
);
801 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
802 /* The operand m may be r, (hl), (ix+d), (iy+d),
803 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
808 rnum
= arg
->X_add_number
;
824 if ((prefix
== 0) && (rnum
& R_INDEX
))
826 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
827 check_mach (INS_UNDOC
);
836 q
= frag_more (prefix
? 2 : 1);
839 * q
++ = opcode
+ (rnum
<< shift
);
843 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
844 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
845 emit_byte (symbol_get_value_expression (arg
->X_add_symbol
),
846 BFD_RELOC_Z80_DISP8
);
850 *q
= opcode
+(6<<shift
);
858 /* The operand m may be r, (hl), (ix+d), (iy+d),
859 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
861 emit_m (char prefix
, char opcode
, const char *args
)
866 p
= parse_exp (args
, &arg_m
);
871 emit_mx (prefix
, opcode
, 0, &arg_m
);
879 /* The operand m may be as above or one of the undocumented
880 combinations (ix+d),r and (iy+d),r (if unportable instructions
883 emit_mr (char prefix
, char opcode
, const char *args
)
885 expressionS arg_m
, arg_r
;
888 p
= parse_exp (args
, & arg_m
);
895 p
= parse_exp (p
+ 1, & arg_r
);
897 if ((arg_r
.X_md
== 0)
898 && (arg_r
.X_op
== O_register
)
899 && (arg_r
.X_add_number
< 8))
900 opcode
+= arg_r
.X_add_number
-6; /* Emit_mx () will add 6. */
906 check_mach (INS_UNPORT
);
909 emit_mx (prefix
, opcode
, 0, & arg_m
);
918 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
926 emit_mx (prefix
, opcode
, 0, arg_p
);
933 q
= frag_more (prefix
? 2 : 1);
937 emit_byte (arg_p
, BFD_RELOC_8
);
942 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
944 emit_s (char prefix
, char opcode
, const char *args
)
949 p
= parse_exp (args
, & arg_s
);
950 emit_sx (prefix
, opcode
, & arg_s
);
955 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
958 const char *p
; char *q
;
960 p
= parse_exp (args
, &addr
);
972 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
974 emit_incdec (char prefix
, char opcode
, const char * args
)
978 const char *p
; char *q
;
980 p
= parse_exp (args
, &operand
);
981 rnum
= operand
.X_add_number
;
983 && (operand
.X_op
== O_register
)
986 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
988 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
989 *q
= prefix
+ ((rnum
& 3) << 4);
993 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
994 emit_mx (0, opcode
, 3, & operand
);
1002 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1008 p
= parse_exp (args
, &addr
);
1015 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1021 emit_jp (char prefix
, char opcode
, const char * args
)
1028 p
= parse_exp (args
, & addr
);
1031 rnum
= addr
.X_add_number
;
1032 if ((addr
.X_op
== O_register
&& (rnum
& ~R_INDEX
) == REG_HL
)
1033 /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
1035 || (addr
.X_op
== O_md1
&& addr
.X_add_symbol
== zero
))
1037 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1039 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1055 emit_im (char prefix
, char opcode
, const char * args
)
1061 p
= parse_exp (args
, & mode
);
1062 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1065 switch (mode
.X_add_number
)
1069 ++mode
.X_add_number
;
1074 *q
= opcode
+ 8*mode
.X_add_number
;
1083 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1089 p
= parse_exp (args
, & regp
);
1091 && (regp
.X_op
== O_register
)
1092 && (regp
.X_add_number
& R_STACKABLE
))
1096 rnum
= regp
.X_add_number
;
1100 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1104 *q
= opcode
+ ((rnum
& 3) << 4);
1113 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1118 p
= parse_cc (args
, &cc
);
1124 return p
? p
: args
;
1128 emit_adc (char prefix
, char opcode
, const char * args
)
1135 p
= parse_exp (args
, &term
);
1138 error (_("bad intruction syntax"));
1142 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1145 switch (term
.X_add_number
)
1148 p
= emit_s (0, prefix
, p
);
1151 p
= parse_exp (p
, &term
);
1152 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1154 rnum
= term
.X_add_number
;
1155 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1159 *q
= opcode
+ ((rnum
& 3) << 4);
1171 emit_add (char prefix
, char opcode
, const char * args
)
1178 p
= parse_exp (args
, &term
);
1181 error (_("bad intruction syntax"));
1185 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1188 switch (term
.X_add_number
& ~R_INDEX
)
1191 p
= emit_s (0, prefix
, p
);
1194 lhs
= term
.X_add_number
;
1195 p
= parse_exp (p
, &term
);
1196 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1198 rhs
= term
.X_add_number
;
1200 && ((rhs
== lhs
) || ((rhs
& ~R_INDEX
) != REG_HL
)))
1202 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1204 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1205 *q
= opcode
+ ((rhs
& 3) << 4);
1217 emit_bit (char prefix
, char opcode
, const char * args
)
1223 p
= parse_exp (args
, &b
);
1225 error (_("bad intruction syntax"));
1227 bn
= b
.X_add_number
;
1229 && (b
.X_op
== O_constant
)
1234 /* Bit : no optional third operand. */
1235 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1237 /* Set, res : resulting byte can be copied to register. */
1238 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1246 emit_jpcc (char prefix
, char opcode
, const char * args
)
1251 p
= parse_cc (args
, & cc
);
1252 if (p
&& *p
++ == ',')
1253 p
= emit_call (0, opcode
+ cc
, p
);
1255 p
= (prefix
== (char)0xC3)
1256 ? emit_jp (0xE9, prefix
, args
)
1257 : emit_call (0, prefix
, args
);
1262 emit_jrcc (char prefix
, char opcode
, const char * args
)
1267 p
= parse_cc (args
, &cc
);
1268 if (p
&& *p
++ == ',')
1271 error (_("condition code invalid for jr"));
1273 p
= emit_jr (0, opcode
+ cc
, p
);
1276 p
= emit_jr (0, prefix
, args
);
1282 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1283 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1287 char prefix
, opcode
;
1289 p
= parse_exp (args
, &op
);
1293 error (_("bad instruction syntax"));
1297 prefix
= opcode
= 0;
1298 if (op
.X_op
== O_register
)
1299 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1302 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1304 /* The scrubber changes '\'' to '`' in this context. */
1311 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1315 p
= parse_exp (p
, & op
);
1316 if (op
.X_op
== O_register
1318 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1321 if (R_INDEX
& op
.X_add_number
)
1322 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1327 emit_insn (prefix
, opcode
, p
);
1335 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1338 expressionS reg
, port
;
1342 p
= parse_exp (args
, ®
);
1345 error (_("bad intruction syntax"));
1349 p
= parse_exp (p
, &port
);
1351 && reg
.X_op
== O_register
1352 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1355 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1357 if (REG_A
== reg
.X_add_number
)
1361 emit_byte (&port
, BFD_RELOC_8
);
1368 if (port
.X_add_number
== REG_C
)
1370 if (reg
.X_add_number
== REG_F
)
1371 check_mach (INS_UNDOC
);
1376 *q
= 0x40|((reg
.X_add_number
&7)<<3);
1389 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1392 expressionS reg
, port
;
1396 p
= parse_exp (args
, & port
);
1399 error (_("bad intruction syntax"));
1402 p
= parse_exp (p
, ®
);
1404 { ill_op (); return p
; }
1405 /* Allow "out (c), 0" as unportable instruction. */
1406 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
1408 check_mach (INS_UNPORT
);
1409 reg
.X_op
= O_register
;
1410 reg
.X_add_number
= 6;
1413 || reg
.X_op
!= O_register
1414 || reg
.X_add_number
> 7)
1417 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
1419 if (REG_A
== reg
.X_add_number
)
1423 emit_byte (&port
, BFD_RELOC_8
);
1430 if (REG_C
== port
.X_add_number
)
1434 *q
= 0x41 | (reg
.X_add_number
<< 3);
1443 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1449 p
= parse_exp (args
, &addr
);
1450 if (addr
.X_op
!= O_constant
)
1452 error ("rst needs constant address");
1456 if (addr
.X_add_number
& ~(7 << 3))
1461 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
1467 emit_ldxhl (char prefix
, char opcode
, expressionS
*src
, expressionS
*d
)
1475 if (src
->X_op
== O_register
)
1477 if (src
->X_add_number
>7)
1486 *q
= opcode
+ src
->X_add_number
;
1488 emit_byte (d
, BFD_RELOC_Z80_DISP8
);
1501 emit_byte (d
, BFD_RELOC_Z80_DISP8
);
1502 emit_byte (src
, BFD_RELOC_8
);
1508 emit_ldreg (int dest
, expressionS
* src
)
1515 /* 8 Bit ld group: */
1518 if (src
->X_md
== 0 && src
->X_op
== O_register
&& src
->X_add_number
== REG_A
)
1522 *q
= (dest
== REG_I
) ? 0x47 : 0x4F;
1529 if ((src
->X_md
) && src
->X_op
!= O_register
&& src
->X_op
!= O_md1
)
1538 && src
->X_op
== O_register
1539 && (src
->X_add_number
== REG_BC
|| src
->X_add_number
== REG_DE
))
1542 *q
= 0x0A + ((dest
& 1) << 4);
1547 && src
->X_op
== O_register
1548 && (src
->X_add_number
== REG_R
|| src
->X_add_number
== REG_I
))
1552 *q
= (src
->X_add_number
== REG_I
) ? 0x57 : 0x5F;
1560 emit_sx (0, 0x40 + (dest
<< 3), src
);
1565 if ((src
->X_md
== 0)
1566 && (src
->X_op
== O_register
)
1567 && (src
->X_add_number
& R_INDEX
))
1570 emit_sx (0, 0x40 + (dest
<< 3), src
);
1582 check_mach (INS_UNDOC
);
1583 if (src
-> X_op
== O_register
)
1585 rnum
= src
->X_add_number
;
1586 if ((rnum
& ~R_INDEX
) < 8
1587 && ((rnum
& R_INDEX
) == (dest
& R_INDEX
)
1588 || ( (rnum
& ~R_INDEX
) != REG_H
1589 && (rnum
& ~R_INDEX
) != REG_L
)))
1592 *q
++ = (dest
& R_IX
) ? 0xDD : 0xFD;
1593 *q
= 0x40 + ((dest
& 0x07) << 3) + (rnum
& 7);
1601 *q
++ = (dest
& R_IX
) ? 0xDD : 0xFD;
1602 *q
= 0x06 + ((dest
& 0x07) << 3);
1603 emit_byte (src
, BFD_RELOC_8
);
1607 /* 16 Bit ld group: */
1610 && src
->X_op
== O_register
1611 && REG_HL
== (src
->X_add_number
&~ R_INDEX
))
1613 q
= frag_more ((src
->X_add_number
& R_INDEX
) ? 2 : 1);
1614 if (src
->X_add_number
& R_INDEX
)
1615 *q
++ = (src
->X_add_number
& R_IX
) ? 0xDD : 0xFD;
1622 if (src
->X_op
== O_register
|| src
->X_op
== O_md1
)
1624 q
= frag_more (src
->X_md
? 2 : 1);
1628 *q
= 0x4B + ((dest
& 3) << 4);
1631 *q
= 0x01 + ((dest
& 3) << 4);
1638 if (src
->X_op
== O_register
|| src
->X_op
== O_md1
)
1640 q
= frag_more ((dest
& R_INDEX
) ? 2 : 1);
1642 * q
++ = (dest
& R_IX
) ? 0xDD : 0xFD;
1643 *q
= (src
->X_md
) ? 0x2A : 0x21;
1658 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
1661 expressionS dst
, src
;
1664 char prefix
, opcode
;
1666 p
= parse_exp (args
, &dst
);
1668 error (_("bad intruction syntax"));
1669 p
= parse_exp (p
, &src
);
1674 emit_ldxhl ((dst
.X_add_number
& R_IX
) ? 0xDD : 0xFD, 0x70,
1675 &src
, symbol_get_value_expression (dst
.X_add_symbol
));
1681 switch (dst
.X_add_number
)
1685 if (src
.X_md
== 0 && src
.X_op
== O_register
&& src
.X_add_number
== REG_A
)
1688 *q
= 0x02 + ( (dst
.X_add_number
& 1) << 4);
1694 emit_ldxhl (0, 0x70, &src
, NULL
);
1701 emit_ldreg (dst
.X_add_number
, &src
);
1705 if (src
.X_md
!= 0 || src
.X_op
!= O_register
)
1707 prefix
= opcode
= 0;
1708 switch (src
.X_add_number
)
1711 opcode
= 0x32; break;
1712 case REG_BC
: case REG_DE
: case REG_SP
:
1713 prefix
= 0xED; opcode
= 0x43 + ((src
.X_add_number
&3)<<4); break;
1715 opcode
= 0x22; break;
1717 prefix
= 0xDD; opcode
= 0x22; break;
1719 prefix
= 0xFD; opcode
= 0x22; break;
1723 q
= frag_more (prefix
?2:1);
1736 emit_data (int size ATTRIBUTE_UNUSED
)
1743 if (is_it_end_of_statement ())
1745 demand_empty_rest_of_line ();
1748 p
= skip_space (input_line_pointer
);
1752 if (*p
== '\"' || *p
== '\'')
1754 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
1756 u
= frag_more (cnt
);
1759 as_warn (_("unterminated string"));
1761 p
= skip_space (p
+1);
1765 p
= parse_exp (p
, &exp
);
1766 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
1772 as_warn (_("parentheses ignored"));
1773 emit_byte (&exp
, BFD_RELOC_8
);
1777 while (*p
++ == ',') ;
1778 input_line_pointer
= (char *)(p
-1);
1782 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1786 p
= skip_space (args
);
1787 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
1793 reg
= TOLOWER (*p
++);
1800 check_mach (INS_R800
);
1801 if (!*skip_space (p
))
1805 *q
= opcode
+ ((reg
- 'b') << 3);
1816 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1820 p
= skip_space (args
);
1821 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
1828 p
= parse_exp (p
, & reg
);
1830 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
1831 switch (reg
.X_add_number
)
1835 check_mach (INS_R800
);
1838 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
1847 /* Port specific pseudo ops. */
1848 const pseudo_typeS md_pseudo_table
[] =
1850 { "db" , emit_data
, 1},
1853 { "def24", cons
, 3},
1854 { "def32", cons
, 4},
1855 { "defb", emit_data
, 1},
1856 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
1858 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
1860 { "psect", obj_coff_section
, 0}, /* TODO: Translate attributes. */
1861 { "set", 0, 0}, /* Real instruction on z80. */
1865 static table_t instab
[] =
1867 { "adc", 0x88, 0x4A, emit_adc
},
1868 { "add", 0x80, 0x09, emit_add
},
1869 { "and", 0x00, 0xA0, emit_s
},
1870 { "bit", 0xCB, 0x40, emit_bit
},
1871 { "call", 0xCD, 0xC4, emit_jpcc
},
1872 { "ccf", 0x00, 0x3F, emit_insn
},
1873 { "cp", 0x00, 0xB8, emit_s
},
1874 { "cpd", 0xED, 0xA9, emit_insn
},
1875 { "cpdr", 0xED, 0xB9, emit_insn
},
1876 { "cpi", 0xED, 0xA1, emit_insn
},
1877 { "cpir", 0xED, 0xB1, emit_insn
},
1878 { "cpl", 0x00, 0x2F, emit_insn
},
1879 { "daa", 0x00, 0x27, emit_insn
},
1880 { "dec", 0x0B, 0x05, emit_incdec
},
1881 { "di", 0x00, 0xF3, emit_insn
},
1882 { "djnz", 0x00, 0x10, emit_jr
},
1883 { "ei", 0x00, 0xFB, emit_insn
},
1884 { "ex", 0x00, 0x00, emit_ex
},
1885 { "exx", 0x00, 0xD9, emit_insn
},
1886 { "halt", 0x00, 0x76, emit_insn
},
1887 { "im", 0xED, 0x46, emit_im
},
1888 { "in", 0x00, 0x00, emit_in
},
1889 { "inc", 0x03, 0x04, emit_incdec
},
1890 { "ind", 0xED, 0xAA, emit_insn
},
1891 { "indr", 0xED, 0xBA, emit_insn
},
1892 { "ini", 0xED, 0xA2, emit_insn
},
1893 { "inir", 0xED, 0xB2, emit_insn
},
1894 { "jp", 0xC3, 0xC2, emit_jpcc
},
1895 { "jr", 0x18, 0x20, emit_jrcc
},
1896 { "ld", 0x00, 0x00, emit_ld
},
1897 { "ldd", 0xED, 0xA8, emit_insn
},
1898 { "lddr", 0xED, 0xB8, emit_insn
},
1899 { "ldi", 0xED, 0xA0, emit_insn
},
1900 { "ldir", 0xED, 0xB0, emit_insn
},
1901 { "mulub", 0xED, 0xC5, emit_mulub
}, /* R800 only. */
1902 { "muluw", 0xED, 0xC3, emit_muluw
}, /* R800 only. */
1903 { "neg", 0xed, 0x44, emit_insn
},
1904 { "nop", 0x00, 0x00, emit_insn
},
1905 { "or", 0x00, 0xB0, emit_s
},
1906 { "otdr", 0xED, 0xBB, emit_insn
},
1907 { "otir", 0xED, 0xB3, emit_insn
},
1908 { "out", 0x00, 0x00, emit_out
},
1909 { "outd", 0xED, 0xAB, emit_insn
},
1910 { "outi", 0xED, 0xA3, emit_insn
},
1911 { "pop", 0x00, 0xC1, emit_pop
},
1912 { "push", 0x00, 0xC5, emit_pop
},
1913 { "res", 0xCB, 0x80, emit_bit
},
1914 { "ret", 0xC9, 0xC0, emit_retcc
},
1915 { "reti", 0xED, 0x4D, emit_insn
},
1916 { "retn", 0xED, 0x45, emit_insn
},
1917 { "rl", 0xCB, 0x10, emit_mr
},
1918 { "rla", 0x00, 0x17, emit_insn
},
1919 { "rlc", 0xCB, 0x00, emit_mr
},
1920 { "rlca", 0x00, 0x07, emit_insn
},
1921 { "rld", 0xED, 0x6F, emit_insn
},
1922 { "rr", 0xCB, 0x18, emit_mr
},
1923 { "rra", 0x00, 0x1F, emit_insn
},
1924 { "rrc", 0xCB, 0x08, emit_mr
},
1925 { "rrca", 0x00, 0x0F, emit_insn
},
1926 { "rrd", 0xED, 0x67, emit_insn
},
1927 { "rst", 0x00, 0xC7, emit_rst
},
1928 { "sbc", 0x98, 0x42, emit_adc
},
1929 { "scf", 0x00, 0x37, emit_insn
},
1930 { "set", 0xCB, 0xC0, emit_bit
},
1931 { "sla", 0xCB, 0x20, emit_mr
},
1932 { "sli", 0xCB, 0x30, emit_mr
},
1933 { "sll", 0xCB, 0x30, emit_mr
},
1934 { "sra", 0xCB, 0x28, emit_mr
},
1935 { "srl", 0xCB, 0x38, emit_mr
},
1936 { "sub", 0x00, 0x90, emit_s
},
1937 { "xor", 0x00, 0xA8, emit_s
},
1941 md_assemble (char* str
)
1949 old_ptr
= input_line_pointer
;
1950 p
= skip_space (str
);
1951 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
));)
1952 buf
[i
++] = TOLOWER (*p
++);
1956 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
1958 as_bad (_("Unknown instruction '%s'"), buf
);
1960 else if ((*p
) && (!ISSPACE (*p
)))
1961 as_bad (_("syntax error"));
1968 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
1969 sizeof (instab
[0]), key_cmp
);
1971 as_bad (_("Unknown instruction '%s'"), buf
);
1974 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
1976 if ((!err_flag
) && *p
)
1977 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
1981 input_line_pointer
= old_ptr
;
1985 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
1987 long val
= * (long *) valP
;
1988 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1990 switch (fixP
->fx_r_type
)
1992 case BFD_RELOC_8_PCREL
:
1995 fixP
->fx_no_overflow
= 1;
2000 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
2001 if (!fixP
->fx_no_overflow
)
2002 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2003 _("relative jump out of range"));
2009 case BFD_RELOC_Z80_DISP8
:
2012 fixP
->fx_no_overflow
= 1;
2017 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
2018 if (!fixP
->fx_no_overflow
)
2019 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2020 _("index offset out of range"));
2027 if (val
> 255 || val
< -128)
2028 as_warn_where (fixP
->fx_file
, fixP
->fx_line
, _("overflow"));
2030 fixP
->fx_no_overflow
= 1;
2031 if (fixP
->fx_addsy
== NULL
)
2037 *buf
++ = (val
>> 8);
2038 fixP
->fx_no_overflow
= 1;
2039 if (fixP
->fx_addsy
== NULL
)
2043 case BFD_RELOC_24
: /* Def24 may produce this. */
2045 *buf
++ = (val
>> 8);
2046 *buf
++ = (val
>> 16);
2047 fixP
->fx_no_overflow
= 1;
2048 if (fixP
->fx_addsy
== NULL
)
2052 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
2054 *buf
++ = (val
>> 8);
2055 *buf
++ = (val
>> 16);
2056 *buf
++ = (val
>> 24);
2057 if (fixP
->fx_addsy
== NULL
)
2062 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP
->fx_r_type
);
2067 /* GAS will call this to generate a reloc. GAS will pass the
2068 resulting reloc to `bfd_install_relocation'. This currently works
2069 poorly, as `bfd_install_relocation' often does the wrong thing, and
2070 instances of `tc_gen_reloc' have been written to work around the
2071 problems, which in turns makes it difficult to fix
2072 `bfd_install_relocation'. */
2074 /* If while processing a fixup, a reloc really
2075 needs to be created then it is done here. */
2078 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
2082 if (! bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
))
2084 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2085 _("reloc %d not supported by object file format"),
2086 (int) fixp
->fx_r_type
);
2090 reloc
= xmalloc (sizeof (arelent
));
2091 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2092 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2093 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2094 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2095 reloc
->addend
= fixp
->fx_offset
;