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