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