tc-z80.c revision 1.8 1 1.7 christos /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
2 1.8 christos Copyright (C) 2005-2022 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.7 christos #include "elf/z80.h"
26 1.7 christos #include "dwarf2dbg.h"
27 1.8 christos #include "dw2gencfi.h"
28 1.1 christos
29 1.1 christos /* Exported constants. */
30 1.1 christos const char comment_chars[] = ";\0";
31 1.1 christos const char line_comment_chars[] = "#;\0";
32 1.1 christos const char line_separator_chars[] = "\0";
33 1.1 christos const char EXP_CHARS[] = "eE\0";
34 1.7 christos const char FLT_CHARS[] = "RrDdFfSsHh\0";
35 1.1 christos
36 1.1 christos /* For machine specific options. */
37 1.1 christos const char * md_shortopts = ""; /* None yet. */
38 1.1 christos
39 1.1 christos enum options
40 1.1 christos {
41 1.8 christos OPTION_MARCH = OPTION_MD_BASE,
42 1.8 christos OPTION_MACH_Z80,
43 1.1 christos OPTION_MACH_R800,
44 1.7 christos OPTION_MACH_Z180,
45 1.7 christos OPTION_MACH_EZ80_Z80,
46 1.7 christos OPTION_MACH_EZ80_ADL,
47 1.7 christos OPTION_MACH_INST,
48 1.7 christos OPTION_MACH_NO_INST,
49 1.1 christos OPTION_MACH_IUD,
50 1.1 christos OPTION_MACH_WUD,
51 1.1 christos OPTION_MACH_FUD,
52 1.1 christos OPTION_MACH_IUP,
53 1.1 christos OPTION_MACH_WUP,
54 1.7 christos OPTION_MACH_FUP,
55 1.7 christos OPTION_FP_SINGLE_FORMAT,
56 1.7 christos OPTION_FP_DOUBLE_FORMAT,
57 1.7 christos OPTION_COMPAT_LL_PREFIX,
58 1.7 christos OPTION_COMPAT_COLONLESS,
59 1.7 christos OPTION_COMPAT_SDCC
60 1.1 christos };
61 1.1 christos
62 1.7 christos #define INS_Z80 (1 << 0)
63 1.7 christos #define INS_R800 (1 << 1)
64 1.7 christos #define INS_GBZ80 (1 << 2)
65 1.7 christos #define INS_Z180 (1 << 3)
66 1.7 christos #define INS_EZ80 (1 << 4)
67 1.8 christos #define INS_Z80N (1 << 5)
68 1.7 christos #define INS_MARCH_MASK 0xffff
69 1.7 christos
70 1.7 christos #define INS_IDX_HALF (1 << 16)
71 1.7 christos #define INS_IN_F_C (1 << 17)
72 1.7 christos #define INS_OUT_C_0 (1 << 18)
73 1.7 christos #define INS_SLI (1 << 19)
74 1.7 christos #define INS_ROT_II_LD (1 << 20) /* instructions like SLA (ii+d),r; which is: LD r,(ii+d); SLA r; LD (ii+d),r */
75 1.7 christos #define INS_TUNE_MASK 0xffff0000
76 1.7 christos
77 1.8 christos #define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80 | INS_Z80N)
78 1.7 christos
79 1.7 christos #define INS_ALL 0
80 1.7 christos #define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
81 1.7 christos #define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD)
82 1.1 christos
83 1.1 christos struct option md_longopts[] =
84 1.1 christos {
85 1.8 christos { "march", required_argument, NULL, OPTION_MARCH},
86 1.1 christos { "z80", no_argument, NULL, OPTION_MACH_Z80},
87 1.1 christos { "r800", no_argument, NULL, OPTION_MACH_R800},
88 1.7 christos { "z180", no_argument, NULL, OPTION_MACH_Z180},
89 1.7 christos { "ez80", no_argument, NULL, OPTION_MACH_EZ80_Z80},
90 1.7 christos { "ez80-adl", no_argument, NULL, OPTION_MACH_EZ80_ADL},
91 1.7 christos { "fp-s", required_argument, NULL, OPTION_FP_SINGLE_FORMAT},
92 1.7 christos { "fp-d", required_argument, NULL, OPTION_FP_DOUBLE_FORMAT},
93 1.7 christos { "strict", no_argument, NULL, OPTION_MACH_FUD},
94 1.7 christos { "full", no_argument, NULL, OPTION_MACH_IUP},
95 1.7 christos { "with-inst", required_argument, NULL, OPTION_MACH_INST},
96 1.7 christos { "Wnins", required_argument, NULL, OPTION_MACH_INST},
97 1.7 christos { "without-inst", required_argument, NULL, OPTION_MACH_NO_INST},
98 1.7 christos { "local-prefix", required_argument, NULL, OPTION_COMPAT_LL_PREFIX},
99 1.7 christos { "colonless", no_argument, NULL, OPTION_COMPAT_COLONLESS},
100 1.7 christos { "sdcc", no_argument, NULL, OPTION_COMPAT_SDCC},
101 1.7 christos { "Fins", required_argument, NULL, OPTION_MACH_NO_INST},
102 1.1 christos { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD },
103 1.1 christos { "Wnud", no_argument, NULL, OPTION_MACH_IUD },
104 1.1 christos { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD },
105 1.1 christos { "Wud", no_argument, NULL, OPTION_MACH_WUD },
106 1.1 christos { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD },
107 1.1 christos { "Fud", no_argument, NULL, OPTION_MACH_FUD },
108 1.1 christos { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP },
109 1.1 christos { "Wnup", no_argument, NULL, OPTION_MACH_IUP },
110 1.1 christos { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP },
111 1.1 christos { "Wup", no_argument, NULL, OPTION_MACH_WUP },
112 1.1 christos { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP },
113 1.1 christos { "Fup", no_argument, NULL, OPTION_MACH_FUP },
114 1.1 christos
115 1.1 christos { NULL, no_argument, NULL, 0 }
116 1.1 christos } ;
117 1.1 christos
118 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
119 1.1 christos
120 1.1 christos extern int coff_flags;
121 1.1 christos /* Instruction classes that silently assembled. */
122 1.1 christos static int ins_ok = INS_Z80 | INS_UNDOC;
123 1.1 christos /* Instruction classes that generate errors. */
124 1.7 christos static int ins_err = ~(INS_Z80 | INS_UNDOC);
125 1.7 christos /* eZ80 CPU mode (ADL or Z80) */
126 1.7 christos static int cpu_mode = 0; /* 0 - Z80, 1 - ADL */
127 1.7 christos /* accept SDCC specific instruction encoding */
128 1.7 christos static int sdcc_compat = 0;
129 1.7 christos /* accept colonless labels */
130 1.7 christos static int colonless_labels = 0;
131 1.7 christos /* local label prefix (NULL - default) */
132 1.7 christos static const char *local_label_prefix = NULL;
133 1.7 christos /* floating point support */
134 1.7 christos typedef const char *(*str_to_float_t)(char *litP, int *sizeP);
135 1.7 christos static str_to_float_t str_to_float;
136 1.7 christos static str_to_float_t str_to_double;
137 1.7 christos
138 1.7 christos /* mode of current instruction */
139 1.7 christos #define INST_MODE_S 0 /* short data mode */
140 1.7 christos #define INST_MODE_IS 0 /* short instruction mode */
141 1.7 christos #define INST_MODE_L 2 /* long data mode */
142 1.7 christos #define INST_MODE_IL 1 /* long instruction mode */
143 1.7 christos #define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/
144 1.7 christos static char inst_mode;
145 1.7 christos
146 1.8 christos struct match_info
147 1.8 christos {
148 1.8 christos const char *name;
149 1.8 christos int ins_ok;
150 1.8 christos int ins_err;
151 1.8 christos int cpu_mode;
152 1.8 christos const char *comment;
153 1.8 christos };
154 1.8 christos
155 1.8 christos static const struct match_info
156 1.8 christos match_cpu_table [] =
157 1.8 christos {
158 1.8 christos {"z80", INS_Z80, 0, 0, "Zilog Z80" },
159 1.8 christos {"ez80", INS_EZ80, 0, 0, "Zilog eZ80" },
160 1.8 christos {"gbz80", INS_GBZ80, INS_UNDOC|INS_UNPORT, 0, "GameBoy Z80" },
161 1.8 christos {"r800", INS_R800, INS_UNPORT, 0, "Ascii R800" },
162 1.8 christos {"z180", INS_Z180, INS_UNDOC|INS_UNPORT, 0, "Zilog Z180" },
163 1.8 christos {"z80n", INS_Z80N, 0, 0, "Z80 Next" }
164 1.8 christos };
165 1.8 christos
166 1.8 christos static const struct match_info
167 1.8 christos match_ext_table [] =
168 1.8 christos {
169 1.8 christos {"full", INS_UNDOC|INS_UNPORT, 0, 0, "assemble all known instructions" },
170 1.8 christos {"adl", 0, 0, 1, "eZ80 ADL mode by default" },
171 1.8 christos {"xyhl", INS_IDX_HALF, 0, 0, "instructions with halves of index registers" },
172 1.8 christos {"infc", INS_IN_F_C, 0, 0, "instruction IN F,(C)" },
173 1.8 christos {"outc0", INS_OUT_C_0, 0, 0, "instruction OUT (C),0" },
174 1.8 christos {"sli", INS_SLI, 0, 0, "instruction known as SLI, SLL, or SL1" },
175 1.8 christos {"xdcb", INS_ROT_II_LD, 0, 0, "instructions like RL (IX+d),R (DD/FD CB dd oo)" }
176 1.8 christos };
177 1.8 christos
178 1.8 christos
179 1.8 christos static int signed_overflow (signed long value, unsigned bitsize);
180 1.8 christos static int unsigned_overflow (unsigned long value, unsigned bitsize);
181 1.8 christos static int is_overflow (long value, unsigned bitsize);
182 1.8 christos
183 1.8 christos static void
184 1.8 christos setup_march (const char *name, int *ok, int *err, int *mode)
185 1.8 christos {
186 1.8 christos unsigned i;
187 1.8 christos size_t len = strcspn (name, "+-");
188 1.8 christos for (i = 0; i < ARRAY_SIZE (match_cpu_table); ++i)
189 1.8 christos if (!strncasecmp (name, match_cpu_table[i].name, len)
190 1.8 christos && strlen (match_cpu_table[i].name) == len)
191 1.8 christos {
192 1.8 christos *ok = match_cpu_table[i].ins_ok;
193 1.8 christos *err = match_cpu_table[i].ins_err;
194 1.8 christos *mode = match_cpu_table[i].cpu_mode;
195 1.8 christos break;
196 1.8 christos }
197 1.8 christos
198 1.8 christos if (i >= ARRAY_SIZE (match_cpu_table))
199 1.8 christos as_fatal (_("Invalid CPU is specified: %s"), name);
200 1.8 christos
201 1.8 christos while (name[len])
202 1.8 christos {
203 1.8 christos name = &name[len + 1];
204 1.8 christos len = strcspn (name, "+-");
205 1.8 christos for (i = 0; i < ARRAY_SIZE (match_ext_table); ++i)
206 1.8 christos if (!strncasecmp (name, match_ext_table[i].name, len)
207 1.8 christos && strlen (match_ext_table[i].name) == len)
208 1.8 christos {
209 1.8 christos if (name[-1] == '+')
210 1.8 christos {
211 1.8 christos *ok |= match_ext_table[i].ins_ok;
212 1.8 christos *err &= ~match_ext_table[i].ins_ok;
213 1.8 christos *mode |= match_ext_table[i].cpu_mode;
214 1.8 christos }
215 1.8 christos else
216 1.8 christos {
217 1.8 christos *ok &= ~match_ext_table[i].ins_ok;
218 1.8 christos *err |= match_ext_table[i].ins_ok;
219 1.8 christos *mode &= ~match_ext_table[i].cpu_mode;
220 1.8 christos }
221 1.8 christos break;
222 1.8 christos }
223 1.8 christos if (i >= ARRAY_SIZE (match_ext_table))
224 1.8 christos as_fatal (_("Invalid EXTENSION is specified: %s"), name);
225 1.8 christos }
226 1.8 christos }
227 1.8 christos
228 1.7 christos static int
229 1.7 christos setup_instruction (const char *inst, int *add, int *sub)
230 1.7 christos {
231 1.7 christos int n;
232 1.7 christos if (!strcmp (inst, "idx-reg-halves"))
233 1.7 christos n = INS_IDX_HALF;
234 1.7 christos else if (!strcmp (inst, "sli"))
235 1.7 christos n = INS_SLI;
236 1.7 christos else if (!strcmp (inst, "op-ii-ld"))
237 1.7 christos n = INS_ROT_II_LD;
238 1.7 christos else if (!strcmp (inst, "in-f-c"))
239 1.7 christos n = INS_IN_F_C;
240 1.7 christos else if (!strcmp (inst, "out-c-0"))
241 1.7 christos n = INS_OUT_C_0;
242 1.7 christos else
243 1.7 christos return 0;
244 1.7 christos *add |= n;
245 1.7 christos *sub &= ~n;
246 1.7 christos return 1;
247 1.7 christos }
248 1.7 christos
249 1.7 christos static const char *
250 1.7 christos str_to_zeda32 (char *litP, int *sizeP);
251 1.7 christos static const char *
252 1.7 christos str_to_float48 (char *litP, int *sizeP);
253 1.7 christos static const char *
254 1.7 christos str_to_ieee754_h (char *litP, int *sizeP);
255 1.7 christos static const char *
256 1.7 christos str_to_ieee754_s (char *litP, int *sizeP);
257 1.7 christos static const char *
258 1.7 christos str_to_ieee754_d (char *litP, int *sizeP);
259 1.7 christos
260 1.7 christos static str_to_float_t
261 1.7 christos get_str_to_float (const char *arg)
262 1.7 christos {
263 1.7 christos if (strcasecmp (arg, "zeda32") == 0)
264 1.7 christos return str_to_zeda32;
265 1.7 christos
266 1.7 christos if (strcasecmp (arg, "math48") == 0)
267 1.7 christos return str_to_float48;
268 1.7 christos
269 1.7 christos if (strcasecmp (arg, "half") != 0)
270 1.7 christos return str_to_ieee754_h;
271 1.7 christos
272 1.7 christos if (strcasecmp (arg, "single") != 0)
273 1.7 christos return str_to_ieee754_s;
274 1.7 christos
275 1.7 christos if (strcasecmp (arg, "double") != 0)
276 1.7 christos return str_to_ieee754_d;
277 1.7 christos
278 1.7 christos if (strcasecmp (arg, "ieee754") == 0)
279 1.7 christos as_fatal (_("invalid floating point numbers type `%s'"), arg);
280 1.7 christos return NULL;
281 1.7 christos }
282 1.7 christos
283 1.7 christos static int
284 1.7 christos setup_instruction_list (const char *list, int *add, int *sub)
285 1.7 christos {
286 1.7 christos char buf[16];
287 1.7 christos const char *b;
288 1.7 christos const char *e;
289 1.7 christos int sz;
290 1.7 christos int res = 0;
291 1.7 christos for (b = list; *b != '\0';)
292 1.7 christos {
293 1.7 christos e = strchr (b, ',');
294 1.7 christos if (e == NULL)
295 1.7 christos sz = strlen (b);
296 1.7 christos else
297 1.7 christos sz = e - b;
298 1.7 christos if (sz == 0 || sz >= (int)sizeof (buf))
299 1.7 christos {
300 1.7 christos as_bad (_("invalid INST in command line: %s"), b);
301 1.7 christos return 0;
302 1.7 christos }
303 1.7 christos memcpy (buf, b, sz);
304 1.7 christos buf[sz] = '\0';
305 1.7 christos if (setup_instruction (buf, add, sub))
306 1.7 christos res++;
307 1.7 christos else
308 1.7 christos {
309 1.7 christos as_bad (_("invalid INST in command line: %s"), buf);
310 1.7 christos return 0;
311 1.7 christos }
312 1.7 christos b = &b[sz];
313 1.7 christos if (*b == ',')
314 1.7 christos ++b;
315 1.7 christos }
316 1.7 christos return res;
317 1.7 christos }
318 1.1 christos
319 1.1 christos int
320 1.7 christos md_parse_option (int c, const char* arg)
321 1.1 christos {
322 1.1 christos switch (c)
323 1.1 christos {
324 1.1 christos default:
325 1.1 christos return 0;
326 1.8 christos case OPTION_MARCH:
327 1.8 christos setup_march (arg, & ins_ok, & ins_err, & cpu_mode);
328 1.8 christos break;
329 1.1 christos case OPTION_MACH_Z80:
330 1.8 christos setup_march ("z80", & ins_ok, & ins_err, & cpu_mode);
331 1.1 christos break;
332 1.1 christos case OPTION_MACH_R800:
333 1.8 christos setup_march ("r800", & ins_ok, & ins_err, & cpu_mode);
334 1.1 christos break;
335 1.7 christos case OPTION_MACH_Z180:
336 1.8 christos setup_march ("z180", & ins_ok, & ins_err, & cpu_mode);
337 1.7 christos break;
338 1.7 christos case OPTION_MACH_EZ80_Z80:
339 1.8 christos setup_march ("ez80", & ins_ok, & ins_err, & cpu_mode);
340 1.7 christos break;
341 1.7 christos case OPTION_MACH_EZ80_ADL:
342 1.8 christos setup_march ("ez80+adl", & ins_ok, & ins_err, & cpu_mode);
343 1.7 christos break;
344 1.7 christos case OPTION_FP_SINGLE_FORMAT:
345 1.7 christos str_to_float = get_str_to_float (arg);
346 1.7 christos break;
347 1.7 christos case OPTION_FP_DOUBLE_FORMAT:
348 1.7 christos str_to_double = get_str_to_float (arg);
349 1.7 christos break;
350 1.7 christos case OPTION_MACH_INST:
351 1.7 christos if ((ins_ok & INS_GBZ80) == 0)
352 1.7 christos return setup_instruction_list (arg, & ins_ok, & ins_err);
353 1.7 christos break;
354 1.7 christos case OPTION_MACH_NO_INST:
355 1.7 christos if ((ins_ok & INS_GBZ80) == 0)
356 1.7 christos return setup_instruction_list (arg, & ins_err, & ins_ok);
357 1.1 christos break;
358 1.1 christos case OPTION_MACH_WUD:
359 1.7 christos case OPTION_MACH_IUD:
360 1.7 christos if ((ins_ok & INS_GBZ80) == 0)
361 1.7 christos {
362 1.7 christos ins_ok |= INS_UNDOC;
363 1.7 christos ins_err &= ~INS_UNDOC;
364 1.7 christos }
365 1.1 christos break;
366 1.1 christos case OPTION_MACH_WUP:
367 1.7 christos case OPTION_MACH_IUP:
368 1.7 christos if ((ins_ok & INS_GBZ80) == 0)
369 1.7 christos {
370 1.7 christos ins_ok |= INS_UNDOC | INS_UNPORT;
371 1.7 christos ins_err &= ~(INS_UNDOC | INS_UNPORT);
372 1.7 christos }
373 1.1 christos break;
374 1.1 christos case OPTION_MACH_FUD:
375 1.7 christos if ((ins_ok & (INS_R800 | INS_GBZ80)) == 0)
376 1.1 christos {
377 1.1 christos ins_ok &= (INS_UNDOC | INS_UNPORT);
378 1.1 christos ins_err |= INS_UNDOC | INS_UNPORT;
379 1.1 christos }
380 1.1 christos break;
381 1.1 christos case OPTION_MACH_FUP:
382 1.1 christos ins_ok &= ~INS_UNPORT;
383 1.1 christos ins_err |= INS_UNPORT;
384 1.1 christos break;
385 1.7 christos case OPTION_COMPAT_LL_PREFIX:
386 1.7 christos local_label_prefix = (arg && *arg) ? arg : NULL;
387 1.7 christos break;
388 1.7 christos case OPTION_COMPAT_SDCC:
389 1.7 christos sdcc_compat = 1;
390 1.7 christos break;
391 1.7 christos case OPTION_COMPAT_COLONLESS:
392 1.7 christos colonless_labels = 1;
393 1.7 christos break;
394 1.1 christos }
395 1.1 christos
396 1.1 christos return 1;
397 1.1 christos }
398 1.1 christos
399 1.1 christos void
400 1.1 christos md_show_usage (FILE * f)
401 1.1 christos {
402 1.8 christos unsigned i;
403 1.8 christos fprintf (f, _("\n\
404 1.7 christos CPU model options:\n\
405 1.8 christos -march=CPU[+EXT...][-EXT...]\n\
406 1.8 christos \t\t\t generate code for CPU, where CPU is one of:\n"));
407 1.8 christos for (i = 0; i < ARRAY_SIZE(match_cpu_table); ++i)
408 1.8 christos fprintf (f, " %-8s\t\t %s\n", match_cpu_table[i].name, match_cpu_table[i].comment);
409 1.8 christos fprintf (f, _("And EXT is combination (+EXT - add, -EXT - remove) of:\n"));
410 1.8 christos for (i = 0; i < ARRAY_SIZE(match_ext_table); ++i)
411 1.8 christos fprintf (f, " %-8s\t\t %s\n", match_ext_table[i].name, match_ext_table[i].comment);
412 1.8 christos fprintf (f, _("\n\
413 1.7 christos Compatibility options:\n\
414 1.7 christos -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
415 1.7 christos -colonless\t\t permit colonless labels\n\
416 1.7 christos -sdcc\t\t\t accept SDCC specific instruction syntax\n\
417 1.8 christos -fp-s=FORMAT\t\t set single precision FP numbers format\n\
418 1.8 christos -fp-d=FORMAT\t\t set double precision FP numbers format\n\
419 1.7 christos Where FORMAT one of:\n\
420 1.8 christos ieee754\t\t IEEE754 compatible (depends on directive)\n\
421 1.7 christos half\t\t\t IEEE754 half precision (16 bit)\n\
422 1.7 christos single\t\t IEEE754 single precision (32 bit)\n\
423 1.7 christos double\t\t IEEE754 double precision (64 bit)\n\
424 1.7 christos zeda32\t\t Zeda z80float library 32 bit format\n\
425 1.7 christos math48\t\t 48 bit format from Math48 library\n\
426 1.1 christos \n\
427 1.8 christos Default: -march=z80+xyhl+infc\n"));
428 1.1 christos }
429 1.1 christos
430 1.1 christos static symbolS * zero;
431 1.1 christos
432 1.1 christos struct reg_entry
433 1.1 christos {
434 1.5 christos const char* name;
435 1.1 christos int number;
436 1.8 christos int isa;
437 1.1 christos };
438 1.1 christos #define R_STACKABLE (0x80)
439 1.1 christos #define R_ARITH (0x40)
440 1.1 christos #define R_IX (0x20)
441 1.1 christos #define R_IY (0x10)
442 1.1 christos #define R_INDEX (R_IX | R_IY)
443 1.1 christos
444 1.1 christos #define REG_A (7)
445 1.1 christos #define REG_B (0)
446 1.1 christos #define REG_C (1)
447 1.1 christos #define REG_D (2)
448 1.1 christos #define REG_E (3)
449 1.1 christos #define REG_H (4)
450 1.1 christos #define REG_L (5)
451 1.1 christos #define REG_F (6 | 8)
452 1.1 christos #define REG_I (9)
453 1.1 christos #define REG_R (10)
454 1.7 christos #define REG_MB (11)
455 1.1 christos
456 1.1 christos #define REG_AF (3 | R_STACKABLE)
457 1.1 christos #define REG_BC (0 | R_STACKABLE | R_ARITH)
458 1.1 christos #define REG_DE (1 | R_STACKABLE | R_ARITH)
459 1.1 christos #define REG_HL (2 | R_STACKABLE | R_ARITH)
460 1.1 christos #define REG_IX (REG_HL | R_IX)
461 1.1 christos #define REG_IY (REG_HL | R_IY)
462 1.1 christos #define REG_SP (3 | R_ARITH)
463 1.1 christos
464 1.1 christos static const struct reg_entry regtable[] =
465 1.1 christos {
466 1.8 christos {"a", REG_A, INS_ALL },
467 1.8 christos {"af", REG_AF, INS_ALL },
468 1.8 christos {"b", REG_B, INS_ALL },
469 1.8 christos {"bc", REG_BC, INS_ALL },
470 1.8 christos {"c", REG_C, INS_ALL },
471 1.8 christos {"d", REG_D, INS_ALL },
472 1.8 christos {"de", REG_DE, INS_ALL },
473 1.8 christos {"e", REG_E, INS_ALL },
474 1.8 christos {"f", REG_F, INS_IN_F_C | INS_Z80N | INS_R800 },
475 1.8 christos {"h", REG_H, INS_ALL },
476 1.8 christos {"hl", REG_HL, INS_ALL },
477 1.8 christos {"i", REG_I, INS_NOT_GBZ80 },
478 1.8 christos {"ix", REG_IX, INS_NOT_GBZ80 },
479 1.8 christos {"ixh", REG_H | R_IX, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
480 1.8 christos {"ixl", REG_L | R_IX, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
481 1.8 christos {"iy", REG_IY, INS_NOT_GBZ80 },
482 1.8 christos {"iyh", REG_H | R_IY, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
483 1.8 christos {"iyl", REG_L | R_IY, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
484 1.8 christos {"l", REG_L, INS_ALL },
485 1.8 christos {"mb", REG_MB, INS_EZ80 },
486 1.8 christos {"r", REG_R, INS_NOT_GBZ80 },
487 1.8 christos {"sp", REG_SP, INS_ALL },
488 1.1 christos } ;
489 1.1 christos
490 1.1 christos #define BUFLEN 8 /* Large enough for any keyword. */
491 1.1 christos
492 1.1 christos void
493 1.1 christos md_begin (void)
494 1.1 christos {
495 1.1 christos expressionS nul, reg;
496 1.1 christos char * p;
497 1.1 christos unsigned int i, j, k;
498 1.1 christos char buf[BUFLEN];
499 1.1 christos
500 1.8 christos memset (®, 0, sizeof (reg));
501 1.8 christos memset (&nul, 0, sizeof (nul));
502 1.8 christos
503 1.7 christos if (ins_ok & INS_EZ80) /* if select EZ80 cpu then */
504 1.7 christos listing_lhs_width = 6; /* use 6 bytes per line in the listing */
505 1.7 christos
506 1.1 christos reg.X_op = O_register;
507 1.1 christos reg.X_md = 0;
508 1.1 christos reg.X_add_symbol = reg.X_op_symbol = 0;
509 1.1 christos for ( i = 0 ; i < ARRAY_SIZE ( regtable ) ; ++i )
510 1.1 christos {
511 1.8 christos if (regtable[i].isa && !(regtable[i].isa & ins_ok))
512 1.8 christos continue;
513 1.1 christos reg.X_add_number = regtable[i].number;
514 1.1 christos k = strlen ( regtable[i].name );
515 1.1 christos buf[k] = 0;
516 1.1 christos if ( k+1 < BUFLEN )
517 1.1 christos {
518 1.1 christos for ( j = ( 1<<k ) ; j ; --j )
519 1.1 christos {
520 1.1 christos for ( k = 0 ; regtable[i].name[k] ; ++k )
521 1.1 christos {
522 1.7 christos buf[k] = ( j & ( 1<<k ) ) ? TOUPPER (regtable[i].name[k]) : regtable[i].name[k];
523 1.1 christos }
524 1.7 christos symbolS * psym = symbol_find_or_make (buf);
525 1.7 christos S_SET_SEGMENT (psym, reg_section);
526 1.7 christos symbol_set_value_expression (psym, ®);
527 1.1 christos }
528 1.1 christos }
529 1.1 christos }
530 1.1 christos p = input_line_pointer;
531 1.5 christos input_line_pointer = (char *) "0";
532 1.1 christos nul.X_md=0;
533 1.1 christos expression (& nul);
534 1.1 christos input_line_pointer = p;
535 1.1 christos zero = make_expr_symbol (& nul);
536 1.1 christos /* We do not use relaxation (yet). */
537 1.1 christos linkrelax = 0;
538 1.1 christos }
539 1.1 christos
540 1.1 christos void
541 1.1 christos z80_md_end (void)
542 1.1 christos {
543 1.1 christos int mach_type;
544 1.1 christos
545 1.7 christos switch (ins_ok & INS_MARCH_MASK)
546 1.1 christos {
547 1.1 christos case INS_Z80:
548 1.8 christos mach_type = bfd_mach_z80;
549 1.7 christos break;
550 1.7 christos case INS_R800:
551 1.7 christos mach_type = bfd_mach_r800;
552 1.1 christos break;
553 1.7 christos case INS_Z180:
554 1.7 christos mach_type = bfd_mach_z180;
555 1.1 christos break;
556 1.7 christos case INS_GBZ80:
557 1.7 christos mach_type = bfd_mach_gbz80;
558 1.1 christos break;
559 1.7 christos case INS_EZ80:
560 1.7 christos mach_type = cpu_mode ? bfd_mach_ez80_adl : bfd_mach_ez80_z80;
561 1.1 christos break;
562 1.8 christos case INS_Z80N:
563 1.8 christos mach_type = bfd_mach_z80n;
564 1.8 christos break;
565 1.1 christos default:
566 1.1 christos mach_type = 0;
567 1.1 christos }
568 1.1 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
569 1.1 christos }
570 1.1 christos
571 1.7 christos #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
572 1.7 christos void
573 1.7 christos z80_elf_final_processing (void)
574 1.8 christos {/* nothing to do, all is done by BFD itself */
575 1.8 christos /*
576 1.7 christos unsigned elf_flags;
577 1.7 christos elf_elfheader (stdoutput)->e_flags = elf_flags;
578 1.8 christos */
579 1.7 christos }
580 1.7 christos #endif
581 1.7 christos
582 1.1 christos static const char *
583 1.1 christos skip_space (const char *s)
584 1.1 christos {
585 1.1 christos while (*s == ' ' || *s == '\t')
586 1.1 christos ++s;
587 1.1 christos return s;
588 1.1 christos }
589 1.1 christos
590 1.1 christos /* A non-zero return-value causes a continue in the
591 1.1 christos function read_a_source_file () in ../read.c. */
592 1.1 christos int
593 1.1 christos z80_start_line_hook (void)
594 1.1 christos {
595 1.1 christos char *p, quote;
596 1.1 christos char buf[4];
597 1.1 christos
598 1.1 christos /* Convert one character constants. */
599 1.1 christos for (p = input_line_pointer; *p && *p != '\n'; ++p)
600 1.1 christos {
601 1.1 christos switch (*p)
602 1.1 christos {
603 1.1 christos case '\'':
604 1.1 christos if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
605 1.1 christos {
606 1.1 christos snprintf (buf, 4, "%3d", (unsigned char)p[1]);
607 1.1 christos *p++ = buf[0];
608 1.1 christos *p++ = buf[1];
609 1.1 christos *p++ = buf[2];
610 1.1 christos break;
611 1.1 christos }
612 1.6 christos /* Fall through. */
613 1.1 christos case '"':
614 1.1 christos for (quote = *p++; quote != *p && '\n' != *p; ++p)
615 1.1 christos /* No escapes. */ ;
616 1.1 christos if (quote != *p)
617 1.1 christos {
618 1.1 christos as_bad (_("-- unterminated string"));
619 1.1 christos ignore_rest_of_line ();
620 1.1 christos return 1;
621 1.1 christos }
622 1.1 christos break;
623 1.8 christos case '#': /* force to use next expression as immediate value in SDCC */
624 1.8 christos if (!sdcc_compat)
625 1.8 christos break;
626 1.8 christos if (ISSPACE(p[1]) && *skip_space (p + 1) == '(')
627 1.8 christos { /* ld a,# (expr)... -> ld a,0+(expr)... */
628 1.8 christos *p++ = '0';
629 1.8 christos *p = '+';
630 1.8 christos }
631 1.8 christos else /* ld a,#(expr)... -> ld a,+(expr); ld a,#expr -> ld a, expr */
632 1.8 christos *p = (p[1] == '(') ? '+' : ' ';
633 1.7 christos break;
634 1.1 christos }
635 1.1 christos }
636 1.8 christos /* Check for <label>[:] =|([.](EQU|DEFL)) <value>. */
637 1.1 christos if (is_name_beginner (*input_line_pointer))
638 1.1 christos {
639 1.3 christos char *name;
640 1.1 christos char c, *rest, *line_start;
641 1.1 christos int len;
642 1.1 christos
643 1.1 christos line_start = input_line_pointer;
644 1.1 christos if (ignore_input ())
645 1.1 christos return 0;
646 1.3 christos c = get_symbol_name (&name);
647 1.1 christos rest = input_line_pointer + 1;
648 1.8 christos if (c == ':' && *rest == ':')
649 1.7 christos {
650 1.7 christos /* remove second colon if SDCC compatibility enabled */
651 1.7 christos if (sdcc_compat)
652 1.7 christos *rest = ' ';
653 1.7 christos ++rest;
654 1.7 christos }
655 1.7 christos rest = (char*)skip_space (rest);
656 1.8 christos if (*rest == '=')
657 1.8 christos len = (rest[1] == '=') ? 2 : 1;
658 1.1 christos else
659 1.8 christos {
660 1.8 christos if (*rest == '.')
661 1.8 christos ++rest;
662 1.8 christos if (strncasecmp (rest, "EQU", 3) == 0)
663 1.8 christos len = 3;
664 1.8 christos else if (strncasecmp (rest, "DEFL", 4) == 0)
665 1.8 christos len = 4;
666 1.8 christos else
667 1.8 christos len = 0;
668 1.8 christos }
669 1.8 christos if (len && (len <= 2 || !ISALPHA (rest[len])))
670 1.1 christos {
671 1.1 christos /* Handle assignment here. */
672 1.1 christos if (line_start[-1] == '\n')
673 1.1 christos {
674 1.1 christos bump_line_counters ();
675 1.1 christos LISTING_NEWLINE ();
676 1.1 christos }
677 1.1 christos input_line_pointer = rest + len - 1;
678 1.1 christos /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
679 1.8 christos switch (len)
680 1.8 christos {
681 1.8 christos case 1: /* label = expr */
682 1.8 christos case 4: /* label DEFL expr */
683 1.8 christos equals (name, 1);
684 1.8 christos break;
685 1.8 christos case 2: /* label == expr */
686 1.8 christos case 3: /* label EQU expr */
687 1.8 christos equals (name, 0);
688 1.8 christos break;
689 1.8 christos }
690 1.1 christos return 1;
691 1.1 christos }
692 1.1 christos else
693 1.1 christos {
694 1.1 christos /* Restore line and pointer. */
695 1.3 christos (void) restore_line_pointer (c);
696 1.1 christos input_line_pointer = line_start;
697 1.1 christos }
698 1.1 christos }
699 1.1 christos return 0;
700 1.1 christos }
701 1.1 christos
702 1.1 christos symbolS *
703 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
704 1.1 christos {
705 1.1 christos return NULL;
706 1.1 christos }
707 1.1 christos
708 1.5 christos const char *
709 1.7 christos md_atof (int type, char *litP, int *sizeP)
710 1.1 christos {
711 1.7 christos switch (type)
712 1.7 christos {
713 1.7 christos case 'f':
714 1.7 christos case 'F':
715 1.7 christos case 's':
716 1.7 christos case 'S':
717 1.7 christos if (str_to_float)
718 1.7 christos return str_to_float (litP, sizeP);
719 1.7 christos break;
720 1.7 christos case 'd':
721 1.7 christos case 'D':
722 1.7 christos case 'r':
723 1.7 christos case 'R':
724 1.7 christos if (str_to_double)
725 1.7 christos return str_to_double (litP, sizeP);
726 1.7 christos break;
727 1.7 christos }
728 1.8 christos return ieee_md_atof (type, litP, sizeP, false);
729 1.1 christos }
730 1.1 christos
731 1.1 christos valueT
732 1.1 christos md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
733 1.1 christos {
734 1.1 christos return size;
735 1.1 christos }
736 1.1 christos
737 1.1 christos long
738 1.1 christos md_pcrel_from (fixS * fixp)
739 1.1 christos {
740 1.7 christos return fixp->fx_where + fixp->fx_frag->fr_address;
741 1.1 christos }
742 1.1 christos
743 1.1 christos typedef const char * (asfunc)(char, char, const char*);
744 1.1 christos
745 1.1 christos typedef struct _table_t
746 1.1 christos {
747 1.5 christos const char* name;
748 1.5 christos unsigned char prefix;
749 1.5 christos unsigned char opcode;
750 1.1 christos asfunc * fp;
751 1.7 christos unsigned inss; /*0 - all CPU types or list of supported INS_* */
752 1.1 christos } table_t;
753 1.1 christos
754 1.1 christos /* Compares the key for structs that start with a char * to the key. */
755 1.1 christos static int
756 1.1 christos key_cmp (const void * a, const void * b)
757 1.1 christos {
758 1.1 christos const char *str_a, *str_b;
759 1.1 christos
760 1.1 christos str_a = *((const char**)a);
761 1.1 christos str_b = *((const char**)b);
762 1.1 christos return strcmp (str_a, str_b);
763 1.1 christos }
764 1.1 christos
765 1.1 christos char buf[BUFLEN];
766 1.1 christos const char *key = buf;
767 1.1 christos
768 1.1 christos /* Prevent an error on a line from also generating
769 1.1 christos a "junk at end of line" error message. */
770 1.1 christos static char err_flag;
771 1.1 christos
772 1.1 christos static void
773 1.1 christos error (const char * message)
774 1.1 christos {
775 1.7 christos if (err_flag)
776 1.7 christos return;
777 1.7 christos
778 1.1 christos as_bad ("%s", message);
779 1.1 christos err_flag = 1;
780 1.1 christos }
781 1.1 christos
782 1.1 christos static void
783 1.1 christos ill_op (void)
784 1.1 christos {
785 1.1 christos error (_("illegal operand"));
786 1.1 christos }
787 1.1 christos
788 1.1 christos static void
789 1.1 christos wrong_mach (int ins_type)
790 1.1 christos {
791 1.1 christos if (ins_type & ins_err)
792 1.7 christos ill_op ();
793 1.1 christos else
794 1.7 christos as_warn (_("undocumented instruction"));
795 1.1 christos }
796 1.1 christos
797 1.1 christos static void
798 1.1 christos check_mach (int ins_type)
799 1.1 christos {
800 1.1 christos if ((ins_type & ins_ok) == 0)
801 1.1 christos wrong_mach (ins_type);
802 1.1 christos }
803 1.1 christos
804 1.1 christos /* Check whether an expression is indirect. */
805 1.1 christos static int
806 1.1 christos is_indir (const char *s)
807 1.1 christos {
808 1.1 christos char quote;
809 1.1 christos const char *p;
810 1.1 christos int indir, depth;
811 1.1 christos
812 1.1 christos /* Indirection is indicated with parentheses. */
813 1.1 christos indir = (*s == '(');
814 1.1 christos
815 1.1 christos for (p = s, depth = 0; *p && *p != ','; ++p)
816 1.1 christos {
817 1.1 christos switch (*p)
818 1.1 christos {
819 1.1 christos case '"':
820 1.1 christos case '\'':
821 1.1 christos for (quote = *p++; quote != *p && *p != '\n'; ++p)
822 1.1 christos if (*p == '\\' && p[1])
823 1.1 christos ++p;
824 1.1 christos break;
825 1.1 christos case '(':
826 1.1 christos ++ depth;
827 1.1 christos break;
828 1.1 christos case ')':
829 1.1 christos -- depth;
830 1.1 christos if (depth == 0)
831 1.1 christos {
832 1.1 christos p = skip_space (p + 1);
833 1.1 christos if (*p && *p != ',')
834 1.1 christos indir = 0;
835 1.1 christos --p;
836 1.1 christos }
837 1.1 christos if (depth < 0)
838 1.1 christos error (_("mismatched parentheses"));
839 1.1 christos break;
840 1.1 christos }
841 1.1 christos }
842 1.1 christos
843 1.1 christos if (depth != 0)
844 1.1 christos error (_("mismatched parentheses"));
845 1.1 christos
846 1.1 christos return indir;
847 1.1 christos }
848 1.1 christos
849 1.1 christos /* Check whether a symbol involves a register. */
850 1.8 christos static bool
851 1.7 christos contains_register (symbolS *sym)
852 1.1 christos {
853 1.1 christos if (sym)
854 1.7 christos {
855 1.8 christos expressionS * ex = symbol_get_value_expression (sym);
856 1.8 christos
857 1.8 christos switch (ex->X_op)
858 1.8 christos {
859 1.8 christos case O_register:
860 1.8 christos return true;
861 1.8 christos
862 1.8 christos case O_add:
863 1.8 christos case O_subtract:
864 1.8 christos if (ex->X_op_symbol && contains_register (ex->X_op_symbol))
865 1.8 christos return true;
866 1.8 christos /* Fall through. */
867 1.8 christos case O_uminus:
868 1.8 christos case O_symbol:
869 1.8 christos if (ex->X_add_symbol && contains_register (ex->X_add_symbol))
870 1.8 christos return true;
871 1.8 christos break;
872 1.7 christos
873 1.8 christos default:
874 1.8 christos break;
875 1.8 christos }
876 1.7 christos }
877 1.7 christos
878 1.8 christos return false;
879 1.1 christos }
880 1.1 christos
881 1.6 christos /* Parse general expression, not looking for indexed addressing. */
882 1.1 christos static const char *
883 1.1 christos parse_exp_not_indexed (const char *s, expressionS *op)
884 1.1 christos {
885 1.1 christos const char *p;
886 1.1 christos int indir;
887 1.7 christos int make_shift = -1;
888 1.1 christos
889 1.8 christos memset (op, 0, sizeof (*op));
890 1.1 christos p = skip_space (s);
891 1.7 christos if (sdcc_compat && (*p == '<' || *p == '>'))
892 1.7 christos {
893 1.7 christos switch (*p)
894 1.7 christos {
895 1.7 christos case '<': /* LSB request */
896 1.7 christos make_shift = 0;
897 1.7 christos break;
898 1.7 christos case '>': /* MSB request */
899 1.7 christos make_shift = cpu_mode ? 16 : 8;
900 1.7 christos break;
901 1.7 christos }
902 1.7 christos s = ++p;
903 1.7 christos p = skip_space (p);
904 1.7 christos }
905 1.7 christos
906 1.8 christos if (make_shift == -1)
907 1.8 christos indir = is_indir (p);
908 1.8 christos else
909 1.8 christos indir = 0;
910 1.8 christos op->X_md = indir;
911 1.8 christos if (indir && (ins_ok & INS_GBZ80))
912 1.8 christos { /* check for instructions like ld a,(hl+), ld (hl-),a */
913 1.8 christos p = skip_space (p+1);
914 1.8 christos if (!strncasecmp (p, "hl", 2))
915 1.8 christos {
916 1.8 christos p = skip_space(p+2);
917 1.8 christos if (*skip_space(p+1) == ')' && (*p == '+' || *p == '-'))
918 1.8 christos {
919 1.8 christos op->X_op = O_md1;
920 1.8 christos op->X_add_symbol = NULL;
921 1.8 christos op->X_add_number = (*p == '+') ? REG_HL : -REG_HL;
922 1.8 christos input_line_pointer = (char*)skip_space(p + 1) + 1;
923 1.8 christos return input_line_pointer;
924 1.8 christos }
925 1.8 christos }
926 1.8 christos }
927 1.1 christos input_line_pointer = (char*) s ;
928 1.3 christos expression (op);
929 1.1 christos switch (op->X_op)
930 1.1 christos {
931 1.1 christos case O_absent:
932 1.1 christos error (_("missing operand"));
933 1.1 christos break;
934 1.1 christos case O_illegal:
935 1.1 christos error (_("bad expression syntax"));
936 1.1 christos break;
937 1.3 christos default:
938 1.3 christos break;
939 1.1 christos }
940 1.7 christos
941 1.7 christos if (make_shift >= 0)
942 1.7 christos {
943 1.7 christos /* replace [op] by [op >> shift] */
944 1.7 christos expressionS data;
945 1.7 christos op->X_add_symbol = make_expr_symbol (op);
946 1.7 christos op->X_add_number = 0;
947 1.7 christos op->X_op = O_right_shift;
948 1.7 christos memset (&data, 0, sizeof (data));
949 1.7 christos data.X_op = O_constant;
950 1.7 christos data.X_add_number = make_shift;
951 1.7 christos op->X_op_symbol = make_expr_symbol (&data);
952 1.7 christos }
953 1.1 christos return input_line_pointer;
954 1.1 christos }
955 1.1 christos
956 1.7 christos static int
957 1.7 christos unify_indexed (expressionS *op)
958 1.7 christos {
959 1.7 christos if (O_register != symbol_get_value_expression (op->X_add_symbol)->X_op)
960 1.7 christos return 0;
961 1.7 christos
962 1.7 christos int rnum = symbol_get_value_expression (op->X_add_symbol)->X_add_number;
963 1.7 christos if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register (op->X_op_symbol))
964 1.7 christos {
965 1.7 christos ill_op ();
966 1.7 christos return 0;
967 1.7 christos }
968 1.7 christos
969 1.7 christos /* Convert subtraction to addition of negative value. */
970 1.7 christos if (O_subtract == op->X_op)
971 1.7 christos {
972 1.7 christos expressionS minus;
973 1.8 christos memset (&minus, 0, sizeof (minus));
974 1.7 christos minus.X_op = O_uminus;
975 1.7 christos minus.X_add_symbol = op->X_op_symbol;
976 1.7 christos op->X_op_symbol = make_expr_symbol (&minus);
977 1.7 christos op->X_op = O_add;
978 1.7 christos }
979 1.7 christos
980 1.7 christos /* Clear X_add_number of the expression. */
981 1.7 christos if (op->X_add_number != 0)
982 1.7 christos {
983 1.7 christos expressionS add;
984 1.7 christos memset (&add, 0, sizeof (add));
985 1.7 christos add.X_op = O_symbol;
986 1.7 christos add.X_add_number = op->X_add_number;
987 1.7 christos add.X_add_symbol = op->X_op_symbol;
988 1.7 christos op->X_add_symbol = make_expr_symbol (&add);
989 1.7 christos }
990 1.7 christos else
991 1.7 christos op->X_add_symbol = op->X_op_symbol;
992 1.7 christos
993 1.7 christos op->X_add_number = rnum;
994 1.7 christos op->X_op_symbol = 0;
995 1.7 christos return 1;
996 1.7 christos }
997 1.7 christos
998 1.7 christos /* Parse expression, change operator to O_md1 for indexed addressing. */
999 1.1 christos static const char *
1000 1.1 christos parse_exp (const char *s, expressionS *op)
1001 1.1 christos {
1002 1.1 christos const char* res = parse_exp_not_indexed (s, op);
1003 1.1 christos switch (op->X_op)
1004 1.1 christos {
1005 1.1 christos case O_add:
1006 1.1 christos case O_subtract:
1007 1.7 christos if (unify_indexed (op) && op->X_md)
1008 1.7 christos op->X_op = O_md1;
1009 1.1 christos break;
1010 1.1 christos case O_register:
1011 1.7 christos if (op->X_md && ((REG_IX == op->X_add_number) || (REG_IY == op->X_add_number)))
1012 1.1 christos {
1013 1.1 christos op->X_add_symbol = zero;
1014 1.1 christos op->X_op = O_md1;
1015 1.1 christos }
1016 1.1 christos break;
1017 1.7 christos case O_constant:
1018 1.7 christos /* parse SDCC syntax where index register offset placed before parentheses */
1019 1.7 christos if (sdcc_compat && is_indir (res))
1020 1.7 christos {
1021 1.7 christos expressionS off;
1022 1.7 christos off = *op;
1023 1.7 christos res = parse_exp (res, op);
1024 1.7 christos if (op->X_op != O_md1 || op->X_add_symbol != zero)
1025 1.7 christos ill_op ();
1026 1.7 christos else
1027 1.7 christos op->X_add_symbol = make_expr_symbol (&off);
1028 1.7 christos }
1029 1.7 christos break;
1030 1.3 christos default:
1031 1.3 christos break;
1032 1.1 christos }
1033 1.1 christos return res;
1034 1.1 christos }
1035 1.1 christos
1036 1.1 christos /* Condition codes, including some synonyms provided by HiTech zas. */
1037 1.1 christos static const struct reg_entry cc_tab[] =
1038 1.1 christos {
1039 1.8 christos { "age", 6 << 3, INS_ALL },
1040 1.8 christos { "alt", 7 << 3, INS_ALL },
1041 1.8 christos { "c", 3 << 3, INS_ALL },
1042 1.8 christos { "di", 4 << 3, INS_ALL },
1043 1.8 christos { "ei", 5 << 3, INS_ALL },
1044 1.8 christos { "lge", 2 << 3, INS_ALL },
1045 1.8 christos { "llt", 3 << 3, INS_ALL },
1046 1.8 christos { "m", 7 << 3, INS_ALL },
1047 1.8 christos { "nc", 2 << 3, INS_ALL },
1048 1.8 christos { "nz", 0 << 3, INS_ALL },
1049 1.8 christos { "p", 6 << 3, INS_ALL },
1050 1.8 christos { "pe", 5 << 3, INS_ALL },
1051 1.8 christos { "po", 4 << 3, INS_ALL },
1052 1.8 christos { "z", 1 << 3, INS_ALL },
1053 1.1 christos } ;
1054 1.1 christos
1055 1.1 christos /* Parse condition code. */
1056 1.1 christos static const char *
1057 1.1 christos parse_cc (const char *s, char * op)
1058 1.1 christos {
1059 1.1 christos const char *p;
1060 1.1 christos int i;
1061 1.1 christos struct reg_entry * cc_p;
1062 1.1 christos
1063 1.1 christos for (i = 0; i < BUFLEN; ++i)
1064 1.1 christos {
1065 1.1 christos if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
1066 1.1 christos break;
1067 1.1 christos buf[i] = TOLOWER (s[i]);
1068 1.1 christos }
1069 1.1 christos
1070 1.1 christos if ((i < BUFLEN)
1071 1.1 christos && ((s[i] == 0) || (s[i] == ',')))
1072 1.1 christos {
1073 1.1 christos buf[i] = 0;
1074 1.1 christos cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
1075 1.1 christos sizeof (cc_tab[0]), key_cmp);
1076 1.1 christos }
1077 1.1 christos else
1078 1.1 christos cc_p = NULL;
1079 1.1 christos
1080 1.1 christos if (cc_p)
1081 1.1 christos {
1082 1.1 christos *op = cc_p->number;
1083 1.1 christos p = s + i;
1084 1.1 christos }
1085 1.1 christos else
1086 1.1 christos p = NULL;
1087 1.1 christos
1088 1.1 christos return p;
1089 1.1 christos }
1090 1.1 christos
1091 1.1 christos static const char *
1092 1.1 christos emit_insn (char prefix, char opcode, const char * args)
1093 1.1 christos {
1094 1.1 christos char *p;
1095 1.1 christos
1096 1.1 christos if (prefix)
1097 1.1 christos {
1098 1.1 christos p = frag_more (2);
1099 1.1 christos *p++ = prefix;
1100 1.1 christos }
1101 1.1 christos else
1102 1.1 christos p = frag_more (1);
1103 1.1 christos *p = opcode;
1104 1.1 christos return args;
1105 1.1 christos }
1106 1.1 christos
1107 1.1 christos void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
1108 1.1 christos {
1109 1.1 christos bfd_reloc_code_real_type r[4] =
1110 1.1 christos {
1111 1.1 christos BFD_RELOC_8,
1112 1.1 christos BFD_RELOC_16,
1113 1.1 christos BFD_RELOC_24,
1114 1.1 christos BFD_RELOC_32
1115 1.1 christos };
1116 1.1 christos
1117 1.3 christos if (nbytes < 1 || nbytes > 4)
1118 1.1 christos {
1119 1.1 christos as_bad (_("unsupported BFD relocation size %u"), nbytes);
1120 1.1 christos }
1121 1.1 christos else
1122 1.1 christos {
1123 1.1 christos fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
1124 1.1 christos }
1125 1.1 christos }
1126 1.1 christos
1127 1.1 christos static void
1128 1.7 christos emit_data_val (expressionS * val, int size)
1129 1.7 christos {
1130 1.7 christos char *p;
1131 1.7 christos bfd_reloc_code_real_type r_type;
1132 1.7 christos
1133 1.7 christos p = frag_more (size);
1134 1.7 christos if (val->X_op == O_constant)
1135 1.7 christos {
1136 1.7 christos int i;
1137 1.8 christos
1138 1.8 christos /* PR 28791:
1139 1.8 christos Check for overflow, but ignore values that were generated by bit
1140 1.8 christos manipulation operators (eg ~0xe6 and -7). This does mean that
1141 1.8 christos manipluated overlarge values will not be reported (eg ~0x1234),
1142 1.8 christos but it does help to maintain compatibility with earlier versions
1143 1.8 christos of the assembler. */
1144 1.8 christos if (! val->X_extrabit
1145 1.8 christos && is_overflow (val->X_add_number, size*8))
1146 1.8 christos as_warn ( _("%d-bit overflow (%+ld)"), size*8, val->X_add_number);
1147 1.7 christos for (i = 0; i < size; ++i)
1148 1.7 christos p[i] = (char)(val->X_add_number >> (i*8));
1149 1.7 christos return;
1150 1.7 christos }
1151 1.7 christos
1152 1.7 christos switch (size)
1153 1.7 christos {
1154 1.7 christos case 1: r_type = BFD_RELOC_8; break;
1155 1.7 christos case 2: r_type = BFD_RELOC_16; break;
1156 1.7 christos case 3: r_type = BFD_RELOC_24; break;
1157 1.7 christos case 4: r_type = BFD_RELOC_32; break;
1158 1.7 christos case 8: r_type = BFD_RELOC_64; break;
1159 1.7 christos default:
1160 1.7 christos as_fatal (_("invalid data size %d"), size);
1161 1.7 christos }
1162 1.7 christos
1163 1.7 christos if ( (val->X_op == O_register)
1164 1.7 christos || (val->X_op == O_md1)
1165 1.7 christos || contains_register (val->X_add_symbol)
1166 1.7 christos || contains_register (val->X_op_symbol))
1167 1.7 christos ill_op ();
1168 1.7 christos
1169 1.7 christos if (size <= 2 && val->X_op_symbol)
1170 1.7 christos {
1171 1.8 christos bool simplify = true;
1172 1.7 christos int shift = symbol_get_value_expression (val->X_op_symbol)->X_add_number;
1173 1.7 christos if (val->X_op == O_bit_and && shift == (1 << (size*8))-1)
1174 1.7 christos shift = 0;
1175 1.7 christos else if (val->X_op != O_right_shift)
1176 1.7 christos shift = -1;
1177 1.7 christos
1178 1.7 christos if (size == 1)
1179 1.7 christos {
1180 1.7 christos switch (shift)
1181 1.7 christos {
1182 1.7 christos case 0: r_type = BFD_RELOC_Z80_BYTE0; break;
1183 1.7 christos case 8: r_type = BFD_RELOC_Z80_BYTE1; break;
1184 1.7 christos case 16: r_type = BFD_RELOC_Z80_BYTE2; break;
1185 1.7 christos case 24: r_type = BFD_RELOC_Z80_BYTE3; break;
1186 1.8 christos default: simplify = false;
1187 1.7 christos }
1188 1.7 christos }
1189 1.7 christos else /* if (size == 2) */
1190 1.7 christos {
1191 1.7 christos switch (shift)
1192 1.7 christos {
1193 1.7 christos case 0: r_type = BFD_RELOC_Z80_WORD0; break;
1194 1.7 christos case 16: r_type = BFD_RELOC_Z80_WORD1; break;
1195 1.8 christos case 8:
1196 1.8 christos case 24: /* add two byte fixups */
1197 1.8 christos val->X_op = O_symbol;
1198 1.8 christos val->X_op_symbol = NULL;
1199 1.8 christos val->X_add_number = 0;
1200 1.8 christos if (shift == 8)
1201 1.8 christos {
1202 1.8 christos fix_new_exp (frag_now, p++ - frag_now->fr_literal, 1, val, false,
1203 1.8 christos BFD_RELOC_Z80_BYTE1);
1204 1.8 christos /* prepare to next byte */
1205 1.8 christos r_type = BFD_RELOC_Z80_BYTE2;
1206 1.8 christos }
1207 1.8 christos else
1208 1.8 christos r_type = BFD_RELOC_Z80_BYTE3; /* high byte will be 0 */
1209 1.8 christos size = 1;
1210 1.8 christos simplify = false;
1211 1.8 christos break;
1212 1.8 christos default: simplify = false;
1213 1.7 christos }
1214 1.7 christos }
1215 1.7 christos
1216 1.7 christos if (simplify)
1217 1.7 christos {
1218 1.7 christos val->X_op = O_symbol;
1219 1.7 christos val->X_op_symbol = NULL;
1220 1.7 christos val->X_add_number = 0;
1221 1.7 christos }
1222 1.7 christos }
1223 1.7 christos
1224 1.8 christos fix_new_exp (frag_now, p - frag_now->fr_literal, size, val, false, r_type);
1225 1.7 christos }
1226 1.7 christos
1227 1.7 christos static void
1228 1.1 christos emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
1229 1.1 christos {
1230 1.1 christos char *p;
1231 1.1 christos
1232 1.7 christos if (r_type == BFD_RELOC_8)
1233 1.7 christos {
1234 1.7 christos emit_data_val (val, 1);
1235 1.7 christos return;
1236 1.7 christos }
1237 1.1 christos p = frag_more (1);
1238 1.1 christos *p = val->X_add_number;
1239 1.8 christos if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol))
1240 1.1 christos {
1241 1.7 christos ill_op ();
1242 1.1 christos }
1243 1.1 christos else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
1244 1.1 christos {
1245 1.1 christos as_bad (_("cannot make a relative jump to an absolute location"));
1246 1.1 christos }
1247 1.1 christos else if (val->X_op == O_constant)
1248 1.1 christos {
1249 1.8 christos if ((val->X_add_number < -128) || (val->X_add_number >= 128))
1250 1.1 christos {
1251 1.1 christos if (r_type == BFD_RELOC_Z80_DISP8)
1252 1.8 christos as_bad (_("index overflow (%+ld)"), val->X_add_number);
1253 1.1 christos else
1254 1.8 christos as_bad (_("offset overflow (%+ld)"), val->X_add_number);
1255 1.1 christos }
1256 1.1 christos }
1257 1.1 christos else
1258 1.1 christos {
1259 1.8 christos /* For symbols only, constants are stored at begin of function. */
1260 1.3 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
1261 1.8 christos r_type == BFD_RELOC_8_PCREL, r_type);
1262 1.1 christos }
1263 1.1 christos }
1264 1.1 christos
1265 1.1 christos static void
1266 1.1 christos emit_word (expressionS * val)
1267 1.1 christos {
1268 1.7 christos emit_data_val (val, (inst_mode & INST_MODE_IL) ? 3 : 2);
1269 1.1 christos }
1270 1.1 christos
1271 1.1 christos static void
1272 1.1 christos emit_mx (char prefix, char opcode, int shift, expressionS * arg)
1273 1.1 christos /* The operand m may be r, (hl), (ix+d), (iy+d),
1274 1.1 christos if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1275 1.1 christos {
1276 1.1 christos char *q;
1277 1.1 christos int rnum;
1278 1.1 christos
1279 1.1 christos rnum = arg->X_add_number;
1280 1.1 christos switch (arg->X_op)
1281 1.1 christos {
1282 1.1 christos case O_register:
1283 1.1 christos if (arg->X_md)
1284 1.1 christos {
1285 1.1 christos if (rnum != REG_HL)
1286 1.1 christos {
1287 1.1 christos ill_op ();
1288 1.1 christos break;
1289 1.1 christos }
1290 1.1 christos else
1291 1.1 christos rnum = 6;
1292 1.1 christos }
1293 1.1 christos else
1294 1.1 christos {
1295 1.1 christos if ((prefix == 0) && (rnum & R_INDEX))
1296 1.1 christos {
1297 1.1 christos prefix = (rnum & R_IX) ? 0xDD : 0xFD;
1298 1.8 christos if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
1299 1.7 christos check_mach (INS_IDX_HALF);
1300 1.1 christos rnum &= ~R_INDEX;
1301 1.1 christos }
1302 1.1 christos if (rnum > 7)
1303 1.1 christos {
1304 1.1 christos ill_op ();
1305 1.1 christos break;
1306 1.1 christos }
1307 1.1 christos }
1308 1.1 christos q = frag_more (prefix ? 2 : 1);
1309 1.1 christos if (prefix)
1310 1.1 christos * q ++ = prefix;
1311 1.1 christos * q ++ = opcode + (rnum << shift);
1312 1.1 christos break;
1313 1.1 christos case O_md1:
1314 1.7 christos if (ins_ok & INS_GBZ80)
1315 1.7 christos {
1316 1.7 christos ill_op ();
1317 1.7 christos break;
1318 1.7 christos }
1319 1.1 christos q = frag_more (2);
1320 1.1 christos *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1321 1.1 christos *q = (prefix) ? prefix : (opcode + (6 << shift));
1322 1.1 christos {
1323 1.1 christos expressionS offset = *arg;
1324 1.1 christos offset.X_op = O_symbol;
1325 1.1 christos offset.X_add_number = 0;
1326 1.1 christos emit_byte (&offset, BFD_RELOC_Z80_DISP8);
1327 1.1 christos }
1328 1.1 christos if (prefix)
1329 1.1 christos {
1330 1.1 christos q = frag_more (1);
1331 1.1 christos *q = opcode+(6<<shift);
1332 1.1 christos }
1333 1.1 christos break;
1334 1.1 christos default:
1335 1.1 christos abort ();
1336 1.1 christos }
1337 1.1 christos }
1338 1.1 christos
1339 1.1 christos /* The operand m may be r, (hl), (ix+d), (iy+d),
1340 1.1 christos if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1341 1.1 christos static const char *
1342 1.1 christos emit_m (char prefix, char opcode, const char *args)
1343 1.1 christos {
1344 1.1 christos expressionS arg_m;
1345 1.1 christos const char *p;
1346 1.1 christos
1347 1.1 christos p = parse_exp (args, &arg_m);
1348 1.1 christos switch (arg_m.X_op)
1349 1.1 christos {
1350 1.1 christos case O_md1:
1351 1.1 christos case O_register:
1352 1.1 christos emit_mx (prefix, opcode, 0, &arg_m);
1353 1.1 christos break;
1354 1.1 christos default:
1355 1.1 christos ill_op ();
1356 1.1 christos }
1357 1.1 christos return p;
1358 1.1 christos }
1359 1.1 christos
1360 1.1 christos /* The operand m may be as above or one of the undocumented
1361 1.1 christos combinations (ix+d),r and (iy+d),r (if unportable instructions
1362 1.1 christos are allowed). */
1363 1.7 christos
1364 1.1 christos static const char *
1365 1.1 christos emit_mr (char prefix, char opcode, const char *args)
1366 1.1 christos {
1367 1.1 christos expressionS arg_m, arg_r;
1368 1.1 christos const char *p;
1369 1.1 christos
1370 1.1 christos p = parse_exp (args, & arg_m);
1371 1.1 christos
1372 1.1 christos switch (arg_m.X_op)
1373 1.1 christos {
1374 1.1 christos case O_md1:
1375 1.1 christos if (*p == ',')
1376 1.1 christos {
1377 1.1 christos p = parse_exp (p + 1, & arg_r);
1378 1.1 christos
1379 1.1 christos if ((arg_r.X_md == 0)
1380 1.1 christos && (arg_r.X_op == O_register)
1381 1.1 christos && (arg_r.X_add_number < 8))
1382 1.7 christos opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6. */
1383 1.1 christos else
1384 1.1 christos {
1385 1.1 christos ill_op ();
1386 1.1 christos break;
1387 1.1 christos }
1388 1.8 christos if (!(ins_ok & INS_Z80N))
1389 1.8 christos check_mach (INS_ROT_II_LD);
1390 1.1 christos }
1391 1.6 christos /* Fall through. */
1392 1.1 christos case O_register:
1393 1.1 christos emit_mx (prefix, opcode, 0, & arg_m);
1394 1.1 christos break;
1395 1.1 christos default:
1396 1.1 christos ill_op ();
1397 1.1 christos }
1398 1.1 christos return p;
1399 1.1 christos }
1400 1.1 christos
1401 1.1 christos static void
1402 1.1 christos emit_sx (char prefix, char opcode, expressionS * arg_p)
1403 1.1 christos {
1404 1.1 christos char *q;
1405 1.1 christos
1406 1.1 christos switch (arg_p->X_op)
1407 1.1 christos {
1408 1.1 christos case O_register:
1409 1.1 christos case O_md1:
1410 1.1 christos emit_mx (prefix, opcode, 0, arg_p);
1411 1.1 christos break;
1412 1.1 christos default:
1413 1.1 christos if (arg_p->X_md)
1414 1.1 christos ill_op ();
1415 1.1 christos else
1416 1.1 christos {
1417 1.1 christos q = frag_more (prefix ? 2 : 1);
1418 1.1 christos if (prefix)
1419 1.1 christos *q++ = prefix;
1420 1.1 christos *q = opcode ^ 0x46;
1421 1.1 christos emit_byte (arg_p, BFD_RELOC_8);
1422 1.1 christos }
1423 1.1 christos }
1424 1.1 christos }
1425 1.1 christos
1426 1.1 christos /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1427 1.1 christos static const char *
1428 1.1 christos emit_s (char prefix, char opcode, const char *args)
1429 1.1 christos {
1430 1.1 christos expressionS arg_s;
1431 1.1 christos const char *p;
1432 1.1 christos
1433 1.1 christos p = parse_exp (args, & arg_s);
1434 1.7 christos if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
1435 1.7 christos { /* possible instruction in generic format op A,x */
1436 1.7 christos if (!(ins_ok & INS_EZ80) && !sdcc_compat)
1437 1.7 christos ill_op ();
1438 1.7 christos ++p;
1439 1.7 christos p = parse_exp (p, & arg_s);
1440 1.7 christos }
1441 1.1 christos emit_sx (prefix, opcode, & arg_s);
1442 1.1 christos return p;
1443 1.1 christos }
1444 1.1 christos
1445 1.1 christos static const char *
1446 1.8 christos emit_sub (char prefix, char opcode, const char *args)
1447 1.8 christos {
1448 1.8 christos expressionS arg_s;
1449 1.8 christos const char *p;
1450 1.8 christos
1451 1.8 christos if (!(ins_ok & INS_GBZ80))
1452 1.8 christos return emit_s (prefix, opcode, args);
1453 1.8 christos p = parse_exp (args, & arg_s);
1454 1.8 christos if (*p++ != ',')
1455 1.8 christos {
1456 1.8 christos error (_("bad instruction syntax"));
1457 1.8 christos return p;
1458 1.8 christos }
1459 1.8 christos
1460 1.8 christos if (arg_s.X_md != 0 || arg_s.X_op != O_register || arg_s.X_add_number != REG_A)
1461 1.8 christos ill_op ();
1462 1.8 christos
1463 1.8 christos p = parse_exp (p, & arg_s);
1464 1.8 christos
1465 1.8 christos emit_sx (prefix, opcode, & arg_s);
1466 1.8 christos return p;
1467 1.8 christos }
1468 1.8 christos
1469 1.8 christos static const char *
1470 1.8 christos emit_swap (char prefix, char opcode, const char *args)
1471 1.8 christos {
1472 1.8 christos expressionS reg;
1473 1.8 christos const char *p;
1474 1.8 christos char *q;
1475 1.8 christos
1476 1.8 christos if (!(ins_ok & INS_Z80N))
1477 1.8 christos return emit_mr (prefix, opcode, args);
1478 1.8 christos
1479 1.8 christos /* check for alias swap a for swapnib of Z80N */
1480 1.8 christos p = parse_exp (args, ®);
1481 1.8 christos if (reg.X_md != 0 || reg.X_op != O_register || reg.X_add_number != REG_A)
1482 1.8 christos ill_op ();
1483 1.8 christos
1484 1.8 christos q = frag_more (2);
1485 1.8 christos *q++ = 0xED;
1486 1.8 christos *q = 0x23;
1487 1.8 christos return p;
1488 1.8 christos }
1489 1.8 christos
1490 1.8 christos static const char *
1491 1.1 christos emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1492 1.1 christos {
1493 1.1 christos expressionS addr;
1494 1.1 christos const char *p; char *q;
1495 1.1 christos
1496 1.1 christos p = parse_exp_not_indexed (args, &addr);
1497 1.1 christos if (addr.X_md)
1498 1.1 christos ill_op ();
1499 1.1 christos else
1500 1.1 christos {
1501 1.1 christos q = frag_more (1);
1502 1.1 christos *q = opcode;
1503 1.1 christos emit_word (& addr);
1504 1.1 christos }
1505 1.1 christos return p;
1506 1.1 christos }
1507 1.1 christos
1508 1.1 christos /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1509 1.1 christos static const char *
1510 1.1 christos emit_incdec (char prefix, char opcode, const char * args)
1511 1.1 christos {
1512 1.1 christos expressionS operand;
1513 1.1 christos int rnum;
1514 1.1 christos const char *p; char *q;
1515 1.1 christos
1516 1.1 christos p = parse_exp (args, &operand);
1517 1.1 christos rnum = operand.X_add_number;
1518 1.1 christos if ((! operand.X_md)
1519 1.1 christos && (operand.X_op == O_register)
1520 1.1 christos && (R_ARITH&rnum))
1521 1.1 christos {
1522 1.1 christos q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1523 1.1 christos if (rnum & R_INDEX)
1524 1.1 christos *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1525 1.1 christos *q = prefix + ((rnum & 3) << 4);
1526 1.1 christos }
1527 1.1 christos else
1528 1.1 christos {
1529 1.1 christos if ((operand.X_op == O_md1) || (operand.X_op == O_register))
1530 1.1 christos emit_mx (0, opcode, 3, & operand);
1531 1.1 christos else
1532 1.1 christos ill_op ();
1533 1.1 christos }
1534 1.1 christos return p;
1535 1.1 christos }
1536 1.1 christos
1537 1.1 christos static const char *
1538 1.1 christos emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1539 1.1 christos {
1540 1.1 christos expressionS addr;
1541 1.1 christos const char *p;
1542 1.1 christos char *q;
1543 1.1 christos
1544 1.1 christos p = parse_exp_not_indexed (args, &addr);
1545 1.1 christos if (addr.X_md)
1546 1.1 christos ill_op ();
1547 1.1 christos else
1548 1.1 christos {
1549 1.1 christos q = frag_more (1);
1550 1.1 christos *q = opcode;
1551 1.7 christos addr.X_add_number--; /* pcrel computes after offset code */
1552 1.1 christos emit_byte (&addr, BFD_RELOC_8_PCREL);
1553 1.1 christos }
1554 1.1 christos return p;
1555 1.1 christos }
1556 1.1 christos
1557 1.1 christos static const char *
1558 1.1 christos emit_jp (char prefix, char opcode, const char * args)
1559 1.1 christos {
1560 1.1 christos expressionS addr;
1561 1.1 christos const char *p;
1562 1.1 christos char *q;
1563 1.1 christos int rnum;
1564 1.1 christos
1565 1.1 christos p = parse_exp_not_indexed (args, & addr);
1566 1.1 christos if (addr.X_md)
1567 1.1 christos {
1568 1.1 christos rnum = addr.X_add_number;
1569 1.1 christos if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX)))
1570 1.1 christos {
1571 1.1 christos q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1572 1.1 christos if (rnum & R_INDEX)
1573 1.1 christos *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1574 1.1 christos *q = prefix;
1575 1.1 christos }
1576 1.8 christos else if (addr.X_op == O_register && rnum == REG_C && (ins_ok & INS_Z80N))
1577 1.8 christos {
1578 1.8 christos q = frag_more (2);
1579 1.8 christos *q++ = 0xED;
1580 1.8 christos *q = 0x98;
1581 1.8 christos }
1582 1.1 christos else
1583 1.1 christos ill_op ();
1584 1.1 christos }
1585 1.1 christos else
1586 1.1 christos {
1587 1.1 christos q = frag_more (1);
1588 1.1 christos *q = opcode;
1589 1.1 christos emit_word (& addr);
1590 1.1 christos }
1591 1.1 christos return p;
1592 1.1 christos }
1593 1.1 christos
1594 1.1 christos static const char *
1595 1.1 christos emit_im (char prefix, char opcode, const char * args)
1596 1.1 christos {
1597 1.1 christos expressionS mode;
1598 1.1 christos const char *p;
1599 1.1 christos char *q;
1600 1.1 christos
1601 1.1 christos p = parse_exp (args, & mode);
1602 1.1 christos if (mode.X_md || (mode.X_op != O_constant))
1603 1.1 christos ill_op ();
1604 1.1 christos else
1605 1.1 christos switch (mode.X_add_number)
1606 1.1 christos {
1607 1.1 christos case 1:
1608 1.1 christos case 2:
1609 1.1 christos ++mode.X_add_number;
1610 1.1 christos /* Fall through. */
1611 1.1 christos case 0:
1612 1.1 christos q = frag_more (2);
1613 1.1 christos *q++ = prefix;
1614 1.1 christos *q = opcode + 8*mode.X_add_number;
1615 1.1 christos break;
1616 1.1 christos default:
1617 1.1 christos ill_op ();
1618 1.1 christos }
1619 1.1 christos return p;
1620 1.1 christos }
1621 1.1 christos
1622 1.1 christos static const char *
1623 1.1 christos emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1624 1.1 christos {
1625 1.1 christos expressionS regp;
1626 1.1 christos const char *p;
1627 1.1 christos char *q;
1628 1.1 christos
1629 1.1 christos p = parse_exp (args, & regp);
1630 1.1 christos if ((!regp.X_md)
1631 1.1 christos && (regp.X_op == O_register)
1632 1.1 christos && (regp.X_add_number & R_STACKABLE))
1633 1.1 christos {
1634 1.1 christos int rnum;
1635 1.1 christos
1636 1.1 christos rnum = regp.X_add_number;
1637 1.1 christos if (rnum&R_INDEX)
1638 1.1 christos {
1639 1.1 christos q = frag_more (2);
1640 1.1 christos *q++ = (rnum&R_IX)?0xDD:0xFD;
1641 1.1 christos }
1642 1.1 christos else
1643 1.1 christos q = frag_more (1);
1644 1.1 christos *q = opcode + ((rnum & 3) << 4);
1645 1.1 christos }
1646 1.1 christos else
1647 1.1 christos ill_op ();
1648 1.1 christos
1649 1.1 christos return p;
1650 1.1 christos }
1651 1.1 christos
1652 1.1 christos static const char *
1653 1.8 christos emit_push (char prefix, char opcode, const char * args)
1654 1.8 christos {
1655 1.8 christos expressionS arg;
1656 1.8 christos const char *p;
1657 1.8 christos char *q;
1658 1.8 christos
1659 1.8 christos p = parse_exp (args, & arg);
1660 1.8 christos if (arg.X_op == O_register)
1661 1.8 christos return emit_pop (prefix, opcode, args);
1662 1.8 christos
1663 1.8 christos if (arg.X_md || arg.X_op == O_md1 || !(ins_ok & INS_Z80N))
1664 1.8 christos ill_op ();
1665 1.8 christos
1666 1.8 christos q = frag_more (2);
1667 1.8 christos *q++ = 0xED;
1668 1.8 christos *q = 0x8A;
1669 1.8 christos
1670 1.8 christos q = frag_more (2);
1671 1.8 christos fix_new_exp (frag_now, q - frag_now->fr_literal, 2, &arg, false,
1672 1.8 christos BFD_RELOC_Z80_16_BE);
1673 1.8 christos
1674 1.8 christos return p;
1675 1.8 christos }
1676 1.8 christos
1677 1.8 christos static const char *
1678 1.1 christos emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1679 1.1 christos {
1680 1.1 christos char cc, *q;
1681 1.1 christos const char *p;
1682 1.1 christos
1683 1.1 christos p = parse_cc (args, &cc);
1684 1.1 christos q = frag_more (1);
1685 1.1 christos if (p)
1686 1.1 christos *q = opcode + cc;
1687 1.1 christos else
1688 1.1 christos *q = prefix;
1689 1.1 christos return p ? p : args;
1690 1.1 christos }
1691 1.1 christos
1692 1.1 christos static const char *
1693 1.1 christos emit_adc (char prefix, char opcode, const char * args)
1694 1.1 christos {
1695 1.1 christos expressionS term;
1696 1.1 christos int rnum;
1697 1.1 christos const char *p;
1698 1.1 christos char *q;
1699 1.1 christos
1700 1.1 christos p = parse_exp (args, &term);
1701 1.1 christos if (*p++ != ',')
1702 1.1 christos {
1703 1.3 christos error (_("bad instruction syntax"));
1704 1.1 christos return p;
1705 1.1 christos }
1706 1.1 christos
1707 1.1 christos if ((term.X_md) || (term.X_op != O_register))
1708 1.1 christos ill_op ();
1709 1.1 christos else
1710 1.1 christos switch (term.X_add_number)
1711 1.1 christos {
1712 1.1 christos case REG_A:
1713 1.1 christos p = emit_s (0, prefix, p);
1714 1.1 christos break;
1715 1.1 christos case REG_HL:
1716 1.1 christos p = parse_exp (p, &term);
1717 1.1 christos if ((!term.X_md) && (term.X_op == O_register))
1718 1.1 christos {
1719 1.1 christos rnum = term.X_add_number;
1720 1.1 christos if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1721 1.1 christos {
1722 1.1 christos q = frag_more (2);
1723 1.1 christos *q++ = 0xED;
1724 1.1 christos *q = opcode + ((rnum & 3) << 4);
1725 1.1 christos break;
1726 1.1 christos }
1727 1.1 christos }
1728 1.1 christos /* Fall through. */
1729 1.1 christos default:
1730 1.1 christos ill_op ();
1731 1.1 christos }
1732 1.1 christos return p;
1733 1.1 christos }
1734 1.1 christos
1735 1.1 christos static const char *
1736 1.1 christos emit_add (char prefix, char opcode, const char * args)
1737 1.1 christos {
1738 1.1 christos expressionS term;
1739 1.1 christos int lhs, rhs;
1740 1.1 christos const char *p;
1741 1.1 christos char *q;
1742 1.1 christos
1743 1.1 christos p = parse_exp (args, &term);
1744 1.1 christos if (*p++ != ',')
1745 1.1 christos {
1746 1.3 christos error (_("bad instruction syntax"));
1747 1.1 christos return p;
1748 1.1 christos }
1749 1.1 christos
1750 1.1 christos if ((term.X_md) || (term.X_op != O_register))
1751 1.1 christos ill_op ();
1752 1.1 christos else
1753 1.8 christos switch (term.X_add_number)
1754 1.1 christos {
1755 1.1 christos case REG_A:
1756 1.1 christos p = emit_s (0, prefix, p);
1757 1.1 christos break;
1758 1.8 christos case REG_SP:
1759 1.8 christos p = parse_exp (p, &term);
1760 1.8 christos if (!(ins_ok & INS_GBZ80) || term.X_md || term.X_op == O_register)
1761 1.8 christos ill_op ();
1762 1.8 christos q = frag_more (1);
1763 1.8 christos *q = 0xE8;
1764 1.8 christos emit_byte (&term, BFD_RELOC_Z80_DISP8);
1765 1.8 christos break;
1766 1.8 christos case REG_BC:
1767 1.8 christos case REG_DE:
1768 1.8 christos if (!(ins_ok & INS_Z80N))
1769 1.8 christos {
1770 1.8 christos ill_op ();
1771 1.8 christos break;
1772 1.8 christos }
1773 1.8 christos /* Fall through. */
1774 1.1 christos case REG_HL:
1775 1.8 christos case REG_IX:
1776 1.8 christos case REG_IY:
1777 1.1 christos lhs = term.X_add_number;
1778 1.1 christos p = parse_exp (p, &term);
1779 1.8 christos rhs = term.X_add_number;
1780 1.8 christos if (term.X_md != 0 || term.X_op == O_md1)
1781 1.8 christos ill_op ();
1782 1.8 christos else if ((term.X_op == O_register) && (rhs & R_ARITH) && (rhs == lhs || (rhs & ~R_INDEX) != REG_HL))
1783 1.1 christos {
1784 1.8 christos if (1)
1785 1.1 christos {
1786 1.1 christos q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1787 1.1 christos if (lhs & R_INDEX)
1788 1.1 christos *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1789 1.1 christos *q = opcode + ((rhs & 3) << 4);
1790 1.1 christos break;
1791 1.1 christos }
1792 1.1 christos }
1793 1.8 christos else if (!(lhs & R_INDEX) && (ins_ok & INS_Z80N))
1794 1.8 christos {
1795 1.8 christos if (term.X_op == O_register && rhs == REG_A)
1796 1.8 christos { /* ADD BC/DE/HL,A */
1797 1.8 christos q = frag_more (2);
1798 1.8 christos *q++ = 0xED;
1799 1.8 christos *q = 0x33 - (lhs & 3);
1800 1.8 christos break;
1801 1.8 christos }
1802 1.8 christos else if (term.X_op != O_register && term.X_op != O_md1)
1803 1.8 christos { /* ADD BC/DE/HL,nn */
1804 1.8 christos q = frag_more (2);
1805 1.8 christos *q++ = 0xED;
1806 1.8 christos *q = 0x36 - (lhs & 3);
1807 1.8 christos emit_word (&term);
1808 1.8 christos break;
1809 1.8 christos }
1810 1.8 christos }
1811 1.1 christos /* Fall through. */
1812 1.1 christos default:
1813 1.1 christos ill_op ();
1814 1.1 christos }
1815 1.1 christos return p;
1816 1.1 christos }
1817 1.1 christos
1818 1.1 christos static const char *
1819 1.1 christos emit_bit (char prefix, char opcode, const char * args)
1820 1.1 christos {
1821 1.1 christos expressionS b;
1822 1.1 christos int bn;
1823 1.1 christos const char *p;
1824 1.1 christos
1825 1.1 christos p = parse_exp (args, &b);
1826 1.1 christos if (*p++ != ',')
1827 1.3 christos error (_("bad instruction syntax"));
1828 1.1 christos
1829 1.1 christos bn = b.X_add_number;
1830 1.1 christos if ((!b.X_md)
1831 1.1 christos && (b.X_op == O_constant)
1832 1.1 christos && (0 <= bn)
1833 1.1 christos && (bn < 8))
1834 1.1 christos {
1835 1.1 christos if (opcode == 0x40)
1836 1.1 christos /* Bit : no optional third operand. */
1837 1.1 christos p = emit_m (prefix, opcode + (bn << 3), p);
1838 1.1 christos else
1839 1.1 christos /* Set, res : resulting byte can be copied to register. */
1840 1.7 christos p = emit_mr (prefix, opcode + (bn << 3), p);
1841 1.1 christos }
1842 1.1 christos else
1843 1.1 christos ill_op ();
1844 1.1 christos return p;
1845 1.1 christos }
1846 1.1 christos
1847 1.8 christos /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1848 1.8 christos static const char *
1849 1.8 christos emit_bshft (char prefix, char opcode, const char * args)
1850 1.8 christos {
1851 1.8 christos expressionS r1, r2;
1852 1.8 christos const char *p;
1853 1.8 christos char *q;
1854 1.8 christos
1855 1.8 christos p = parse_exp (args, & r1);
1856 1.8 christos if (*p++ != ',')
1857 1.8 christos error (_("bad instruction syntax"));
1858 1.8 christos p = parse_exp (p, & r2);
1859 1.8 christos if (r1.X_md || r1.X_op != O_register || r1.X_add_number != REG_DE ||
1860 1.8 christos r2.X_md || r2.X_op != O_register || r2.X_add_number != REG_B)
1861 1.8 christos ill_op ();
1862 1.8 christos q = frag_more (2);
1863 1.8 christos *q++ = prefix;
1864 1.8 christos *q = opcode;
1865 1.8 christos return p;
1866 1.8 christos }
1867 1.8 christos
1868 1.1 christos static const char *
1869 1.1 christos emit_jpcc (char prefix, char opcode, const char * args)
1870 1.1 christos {
1871 1.1 christos char cc;
1872 1.1 christos const char *p;
1873 1.1 christos
1874 1.1 christos p = parse_cc (args, & cc);
1875 1.1 christos if (p && *p++ == ',')
1876 1.1 christos p = emit_call (0, opcode + cc, p);
1877 1.1 christos else
1878 1.1 christos p = (prefix == (char)0xC3)
1879 1.1 christos ? emit_jp (0xE9, prefix, args)
1880 1.1 christos : emit_call (0, prefix, args);
1881 1.1 christos return p;
1882 1.1 christos }
1883 1.1 christos
1884 1.1 christos static const char *
1885 1.1 christos emit_jrcc (char prefix, char opcode, const char * args)
1886 1.1 christos {
1887 1.1 christos char cc;
1888 1.1 christos const char *p;
1889 1.1 christos
1890 1.1 christos p = parse_cc (args, &cc);
1891 1.1 christos if (p && *p++ == ',')
1892 1.1 christos {
1893 1.1 christos if (cc > (3 << 3))
1894 1.1 christos error (_("condition code invalid for jr"));
1895 1.1 christos else
1896 1.1 christos p = emit_jr (0, opcode + cc, p);
1897 1.1 christos }
1898 1.1 christos else
1899 1.1 christos p = emit_jr (0, prefix, args);
1900 1.1 christos
1901 1.1 christos return p;
1902 1.1 christos }
1903 1.1 christos
1904 1.1 christos static const char *
1905 1.1 christos emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1906 1.1 christos char opcode_in ATTRIBUTE_UNUSED, const char * args)
1907 1.1 christos {
1908 1.1 christos expressionS op;
1909 1.1 christos const char * p;
1910 1.1 christos char prefix, opcode;
1911 1.1 christos
1912 1.1 christos p = parse_exp_not_indexed (args, &op);
1913 1.1 christos p = skip_space (p);
1914 1.1 christos if (*p++ != ',')
1915 1.1 christos {
1916 1.1 christos error (_("bad instruction syntax"));
1917 1.1 christos return p;
1918 1.1 christos }
1919 1.1 christos
1920 1.1 christos prefix = opcode = 0;
1921 1.1 christos if (op.X_op == O_register)
1922 1.1 christos switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1923 1.1 christos {
1924 1.1 christos case REG_AF:
1925 1.1 christos if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1926 1.1 christos {
1927 1.1 christos /* The scrubber changes '\'' to '`' in this context. */
1928 1.1 christos if (*p == '`')
1929 1.1 christos ++p;
1930 1.1 christos opcode = 0x08;
1931 1.1 christos }
1932 1.1 christos break;
1933 1.1 christos case REG_DE:
1934 1.1 christos if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1935 1.1 christos opcode = 0xEB;
1936 1.1 christos break;
1937 1.1 christos case REG_SP|0x8000:
1938 1.1 christos p = parse_exp (p, & op);
1939 1.1 christos if (op.X_op == O_register
1940 1.1 christos && op.X_md == 0
1941 1.1 christos && (op.X_add_number & ~R_INDEX) == REG_HL)
1942 1.1 christos {
1943 1.1 christos opcode = 0xE3;
1944 1.1 christos if (R_INDEX & op.X_add_number)
1945 1.1 christos prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1946 1.1 christos }
1947 1.1 christos break;
1948 1.1 christos }
1949 1.1 christos if (opcode)
1950 1.1 christos emit_insn (prefix, opcode, p);
1951 1.1 christos else
1952 1.1 christos ill_op ();
1953 1.1 christos
1954 1.1 christos return p;
1955 1.1 christos }
1956 1.1 christos
1957 1.1 christos static const char *
1958 1.1 christos emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1959 1.1 christos const char * args)
1960 1.1 christos {
1961 1.1 christos expressionS reg, port;
1962 1.1 christos const char *p;
1963 1.1 christos char *q;
1964 1.1 christos
1965 1.1 christos p = parse_exp (args, ®);
1966 1.8 christos if (reg.X_md && reg.X_op == O_register && reg.X_add_number == REG_C)
1967 1.8 christos { /* permit instruction in (c) as alias for in f,(c) */
1968 1.8 christos port = reg;
1969 1.8 christos reg.X_md = 0;
1970 1.8 christos reg.X_add_number = REG_F;
1971 1.8 christos }
1972 1.8 christos else
1973 1.1 christos {
1974 1.8 christos if (*p++ != ',')
1975 1.8 christos {
1976 1.8 christos error (_("bad instruction syntax"));
1977 1.8 christos return p;
1978 1.8 christos }
1979 1.8 christos p = parse_exp (p, &port);
1980 1.1 christos }
1981 1.1 christos if (reg.X_md == 0
1982 1.1 christos && reg.X_op == O_register
1983 1.1 christos && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1984 1.1 christos && (port.X_md))
1985 1.1 christos {
1986 1.1 christos if (port.X_op != O_md1 && port.X_op != O_register)
1987 1.1 christos {
1988 1.1 christos if (REG_A == reg.X_add_number)
1989 1.1 christos {
1990 1.1 christos q = frag_more (1);
1991 1.1 christos *q = 0xDB;
1992 1.1 christos emit_byte (&port, BFD_RELOC_8);
1993 1.1 christos }
1994 1.1 christos else
1995 1.1 christos ill_op ();
1996 1.1 christos }
1997 1.1 christos else
1998 1.1 christos {
1999 1.7 christos if (port.X_add_number == REG_C || port.X_add_number == REG_BC)
2000 1.1 christos {
2001 1.7 christos if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
2002 1.7 christos ill_op ();
2003 1.8 christos else if (reg.X_add_number == REG_F && !(ins_ok & (INS_R800|INS_Z80N)))
2004 1.7 christos check_mach (INS_IN_F_C);
2005 1.7 christos q = frag_more (2);
2006 1.7 christos *q++ = 0xED;
2007 1.7 christos *q = 0x40|((reg.X_add_number&7)<<3);
2008 1.1 christos }
2009 1.1 christos else
2010 1.1 christos ill_op ();
2011 1.1 christos }
2012 1.1 christos }
2013 1.1 christos else
2014 1.1 christos ill_op ();
2015 1.1 christos return p;
2016 1.1 christos }
2017 1.1 christos
2018 1.1 christos static const char *
2019 1.7 christos emit_in0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2020 1.7 christos const char * args)
2021 1.7 christos {
2022 1.7 christos expressionS reg, port;
2023 1.7 christos const char *p;
2024 1.7 christos char *q;
2025 1.7 christos
2026 1.7 christos p = parse_exp (args, ®);
2027 1.7 christos if (*p++ != ',')
2028 1.7 christos {
2029 1.7 christos error (_("bad instruction syntax"));
2030 1.7 christos return p;
2031 1.7 christos }
2032 1.7 christos
2033 1.7 christos p = parse_exp (p, &port);
2034 1.7 christos if (reg.X_md == 0
2035 1.7 christos && reg.X_op == O_register
2036 1.7 christos && reg.X_add_number <= 7
2037 1.7 christos && port.X_md
2038 1.7 christos && port.X_op != O_md1
2039 1.7 christos && port.X_op != O_register)
2040 1.7 christos {
2041 1.7 christos q = frag_more (2);
2042 1.7 christos *q++ = 0xED;
2043 1.7 christos *q = 0x00|(reg.X_add_number << 3);
2044 1.7 christos emit_byte (&port, BFD_RELOC_8);
2045 1.7 christos }
2046 1.7 christos else
2047 1.7 christos ill_op ();
2048 1.7 christos return p;
2049 1.7 christos }
2050 1.7 christos
2051 1.7 christos static const char *
2052 1.1 christos emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2053 1.1 christos const char * args)
2054 1.1 christos {
2055 1.1 christos expressionS reg, port;
2056 1.1 christos const char *p;
2057 1.1 christos char *q;
2058 1.1 christos
2059 1.1 christos p = parse_exp (args, & port);
2060 1.1 christos if (*p++ != ',')
2061 1.1 christos {
2062 1.3 christos error (_("bad instruction syntax"));
2063 1.1 christos return p;
2064 1.1 christos }
2065 1.1 christos p = parse_exp (p, ®);
2066 1.1 christos if (!port.X_md)
2067 1.1 christos { ill_op (); return p; }
2068 1.1 christos /* Allow "out (c), 0" as unportable instruction. */
2069 1.1 christos if (reg.X_op == O_constant && reg.X_add_number == 0)
2070 1.1 christos {
2071 1.8 christos if (!(ins_ok & INS_Z80N))
2072 1.8 christos check_mach (INS_OUT_C_0);
2073 1.1 christos reg.X_op = O_register;
2074 1.1 christos reg.X_add_number = 6;
2075 1.1 christos }
2076 1.1 christos if (reg.X_md
2077 1.1 christos || reg.X_op != O_register
2078 1.1 christos || reg.X_add_number > 7)
2079 1.1 christos ill_op ();
2080 1.1 christos else
2081 1.1 christos if (port.X_op != O_register && port.X_op != O_md1)
2082 1.1 christos {
2083 1.1 christos if (REG_A == reg.X_add_number)
2084 1.1 christos {
2085 1.1 christos q = frag_more (1);
2086 1.1 christos *q = 0xD3;
2087 1.1 christos emit_byte (&port, BFD_RELOC_8);
2088 1.1 christos }
2089 1.1 christos else
2090 1.1 christos ill_op ();
2091 1.1 christos }
2092 1.1 christos else
2093 1.1 christos {
2094 1.7 christos if (REG_C == port.X_add_number || port.X_add_number == REG_BC)
2095 1.1 christos {
2096 1.7 christos if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
2097 1.7 christos ill_op ();
2098 1.1 christos q = frag_more (2);
2099 1.1 christos *q++ = 0xED;
2100 1.1 christos *q = 0x41 | (reg.X_add_number << 3);
2101 1.1 christos }
2102 1.1 christos else
2103 1.1 christos ill_op ();
2104 1.1 christos }
2105 1.1 christos return p;
2106 1.1 christos }
2107 1.1 christos
2108 1.1 christos static const char *
2109 1.7 christos emit_out0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2110 1.7 christos const char * args)
2111 1.7 christos {
2112 1.7 christos expressionS reg, port;
2113 1.7 christos const char *p;
2114 1.7 christos char *q;
2115 1.7 christos
2116 1.7 christos p = parse_exp (args, & port);
2117 1.7 christos if (*p++ != ',')
2118 1.7 christos {
2119 1.7 christos error (_("bad instruction syntax"));
2120 1.7 christos return p;
2121 1.7 christos }
2122 1.7 christos p = parse_exp (p, ®);
2123 1.7 christos if (port.X_md != 0
2124 1.7 christos && port.X_op != O_register
2125 1.7 christos && port.X_op != O_md1
2126 1.7 christos && reg.X_md == 0
2127 1.7 christos && reg.X_op == O_register
2128 1.7 christos && reg.X_add_number <= 7)
2129 1.7 christos {
2130 1.7 christos q = frag_more (2);
2131 1.7 christos *q++ = 0xED;
2132 1.7 christos *q = 0x01 | (reg.X_add_number << 3);
2133 1.7 christos emit_byte (&port, BFD_RELOC_8);
2134 1.7 christos }
2135 1.7 christos else
2136 1.7 christos ill_op ();
2137 1.7 christos return p;
2138 1.7 christos }
2139 1.7 christos
2140 1.7 christos static const char *
2141 1.1 christos emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2142 1.1 christos {
2143 1.1 christos expressionS addr;
2144 1.1 christos const char *p;
2145 1.1 christos char *q;
2146 1.1 christos
2147 1.1 christos p = parse_exp_not_indexed (args, &addr);
2148 1.1 christos if (addr.X_op != O_constant)
2149 1.1 christos {
2150 1.1 christos error ("rst needs constant address");
2151 1.1 christos return p;
2152 1.1 christos }
2153 1.1 christos
2154 1.1 christos if (addr.X_add_number & ~(7 << 3))
2155 1.1 christos ill_op ();
2156 1.1 christos else
2157 1.1 christos {
2158 1.1 christos q = frag_more (1);
2159 1.1 christos *q = opcode + (addr.X_add_number & (7 << 3));
2160 1.1 christos }
2161 1.1 christos return p;
2162 1.1 christos }
2163 1.1 christos
2164 1.7 christos /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2165 1.1 christos static void
2166 1.7 christos emit_ld_m_n (expressionS *dst, expressionS *src)
2167 1.1 christos {
2168 1.1 christos char *q;
2169 1.7 christos char prefix;
2170 1.7 christos expressionS dst_offset;
2171 1.1 christos
2172 1.7 christos switch (dst->X_add_number)
2173 1.7 christos {
2174 1.7 christos case REG_HL: prefix = 0x00; break;
2175 1.7 christos case REG_IX: prefix = 0xDD; break;
2176 1.7 christos case REG_IY: prefix = 0xFD; break;
2177 1.7 christos default:
2178 1.7 christos ill_op ();
2179 1.7 christos return;
2180 1.7 christos }
2181 1.7 christos
2182 1.7 christos q = frag_more (prefix ? 2 : 1);
2183 1.7 christos if (prefix)
2184 1.7 christos *q++ = prefix;
2185 1.7 christos *q = 0x36;
2186 1.7 christos if (prefix)
2187 1.1 christos {
2188 1.7 christos dst_offset = *dst;
2189 1.7 christos dst_offset.X_op = O_symbol;
2190 1.7 christos dst_offset.X_add_number = 0;
2191 1.7 christos emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2192 1.7 christos }
2193 1.7 christos emit_byte (src, BFD_RELOC_8);
2194 1.7 christos }
2195 1.7 christos
2196 1.7 christos /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2197 1.7 christos static void
2198 1.7 christos emit_ld_m_r (expressionS *dst, expressionS *src)
2199 1.7 christos {
2200 1.7 christos char *q;
2201 1.7 christos char prefix = 0;
2202 1.7 christos expressionS dst_offset;
2203 1.7 christos
2204 1.7 christos switch (dst->X_op)
2205 1.7 christos {
2206 1.7 christos case O_md1:
2207 1.8 christos if (ins_ok & INS_GBZ80)
2208 1.8 christos { /* LD (HL+),A or LD (HL-),A */
2209 1.8 christos if (src->X_op != O_register || src->X_add_number != REG_A)
2210 1.8 christos break;
2211 1.8 christos *frag_more (1) = (dst->X_add_number == REG_HL) ? 0x22 : 0x32;
2212 1.8 christos return;
2213 1.8 christos }
2214 1.8 christos else
2215 1.8 christos prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
2216 1.7 christos /* Fall through. */
2217 1.7 christos case O_register:
2218 1.7 christos switch (dst->X_add_number)
2219 1.7 christos {
2220 1.7 christos case REG_BC: /* LD (BC),A */
2221 1.7 christos case REG_DE: /* LD (DE),A */
2222 1.7 christos if (src->X_add_number == REG_A)
2223 1.7 christos {
2224 1.7 christos q = frag_more (1);
2225 1.7 christos *q = 0x02 | ((dst->X_add_number & 3) << 4);
2226 1.7 christos return;
2227 1.7 christos }
2228 1.7 christos break;
2229 1.7 christos case REG_IX:
2230 1.7 christos case REG_IY:
2231 1.7 christos case REG_HL: /* LD (HL),r or LD (ii+d),r */
2232 1.7 christos if (src->X_add_number <= 7)
2233 1.7 christos {
2234 1.7 christos q = frag_more (prefix ? 2 : 1);
2235 1.7 christos if (prefix)
2236 1.7 christos *q++ = prefix;
2237 1.7 christos *q = 0x70 | src->X_add_number;
2238 1.7 christos if (prefix)
2239 1.7 christos {
2240 1.7 christos dst_offset = *dst;
2241 1.7 christos dst_offset.X_op = O_symbol;
2242 1.7 christos dst_offset.X_add_number = 0;
2243 1.7 christos emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2244 1.7 christos }
2245 1.7 christos return;
2246 1.7 christos }
2247 1.7 christos break;
2248 1.7 christos default:;
2249 1.7 christos }
2250 1.7 christos break;
2251 1.7 christos default: /* LD (nn),A */
2252 1.7 christos if (src->X_add_number == REG_A)
2253 1.7 christos {
2254 1.7 christos q = frag_more (1);
2255 1.8 christos *q = (ins_ok & INS_GBZ80) ? 0xEA : 0x32;
2256 1.7 christos emit_word (dst);
2257 1.7 christos return;
2258 1.7 christos }
2259 1.7 christos break;
2260 1.7 christos }
2261 1.7 christos ill_op ();
2262 1.7 christos }
2263 1.7 christos
2264 1.7 christos /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2265 1.7 christos static void
2266 1.7 christos emit_ld_m_rr (expressionS *dst, expressionS *src)
2267 1.7 christos {
2268 1.7 christos char *q;
2269 1.7 christos int prefix = 0;
2270 1.7 christos int opcode = 0;
2271 1.7 christos expressionS dst_offset;
2272 1.7 christos
2273 1.7 christos switch (dst->X_op)
2274 1.7 christos {
2275 1.7 christos case O_md1: /* eZ80 instructions LD (ii+d),rr */
2276 1.7 christos case O_register: /* eZ80 instructions LD (HL),rr */
2277 1.7 christos if (!(ins_ok & INS_EZ80)) /* 16-bit indirect load group is supported by eZ80 only */
2278 1.7 christos ill_op ();
2279 1.7 christos switch (dst->X_add_number)
2280 1.7 christos {
2281 1.7 christos case REG_IX: prefix = 0xDD; break;
2282 1.7 christos case REG_IY: prefix = 0xFD; break;
2283 1.7 christos case REG_HL: prefix = 0xED; break;
2284 1.7 christos default:
2285 1.7 christos ill_op ();
2286 1.7 christos }
2287 1.7 christos switch (src->X_add_number)
2288 1.7 christos {
2289 1.7 christos case REG_BC: opcode = 0x0F; break;
2290 1.7 christos case REG_DE: opcode = 0x1F; break;
2291 1.7 christos case REG_HL: opcode = 0x2F; break;
2292 1.7 christos case REG_IX: opcode = (prefix != 0xFD) ? 0x3F : 0x3E; break;
2293 1.7 christos case REG_IY: opcode = (prefix != 0xFD) ? 0x3E : 0x3F; break;
2294 1.7 christos default:
2295 1.7 christos ill_op ();
2296 1.7 christos }
2297 1.7 christos q = frag_more (prefix ? 2 : 1);
2298 1.7 christos *q++ = prefix;
2299 1.7 christos *q = opcode;
2300 1.7 christos if (prefix == 0xFD || prefix == 0xDD)
2301 1.7 christos {
2302 1.7 christos dst_offset = *dst;
2303 1.7 christos dst_offset.X_op = O_symbol;
2304 1.7 christos dst_offset.X_add_number = 0;
2305 1.7 christos emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2306 1.7 christos }
2307 1.7 christos break;
2308 1.7 christos default: /* LD (nn),rr */
2309 1.7 christos if (ins_ok & INS_GBZ80)
2310 1.7 christos {
2311 1.7 christos /* GBZ80 supports only LD (nn),SP */
2312 1.7 christos if (src->X_add_number == REG_SP)
2313 1.7 christos {
2314 1.7 christos prefix = 0x00;
2315 1.7 christos opcode = 0x08;
2316 1.7 christos }
2317 1.7 christos else
2318 1.7 christos ill_op ();
2319 1.7 christos }
2320 1.1 christos else
2321 1.7 christos {
2322 1.7 christos switch (src->X_add_number)
2323 1.7 christos {
2324 1.7 christos case REG_BC: prefix = 0xED; opcode = 0x43; break;
2325 1.7 christos case REG_DE: prefix = 0xED; opcode = 0x53; break;
2326 1.7 christos case REG_HL: prefix = 0x00; opcode = 0x22; break;
2327 1.7 christos case REG_IX: prefix = 0xDD; opcode = 0x22; break;
2328 1.7 christos case REG_IY: prefix = 0xFD; opcode = 0x22; break;
2329 1.7 christos case REG_SP: prefix = 0xED; opcode = 0x73; break;
2330 1.7 christos default:
2331 1.7 christos ill_op ();
2332 1.7 christos }
2333 1.7 christos }
2334 1.7 christos q = frag_more (prefix ? 2 : 1);
2335 1.7 christos if (prefix)
2336 1.7 christos *q++ = prefix;
2337 1.7 christos *q = opcode;
2338 1.7 christos emit_word (dst);
2339 1.7 christos }
2340 1.7 christos }
2341 1.7 christos
2342 1.7 christos static void
2343 1.7 christos emit_ld_r_m (expressionS *dst, expressionS *src)
2344 1.7 christos { /* for 8-bit memory load to register: LD r,(xxx) */
2345 1.7 christos char *q;
2346 1.7 christos char prefix = 0;
2347 1.7 christos char opcode = 0;
2348 1.7 christos expressionS src_offset;
2349 1.7 christos
2350 1.7 christos if (dst->X_add_number == REG_A && src->X_op == O_register)
2351 1.7 christos { /* LD A,(BC) or LD A,(DE) */
2352 1.7 christos switch (src->X_add_number)
2353 1.7 christos {
2354 1.7 christos case REG_BC: opcode = 0x0A; break;
2355 1.7 christos case REG_DE: opcode = 0x1A; break;
2356 1.7 christos default: break;
2357 1.7 christos }
2358 1.7 christos if (opcode != 0)
2359 1.7 christos {
2360 1.7 christos q = frag_more (1);
2361 1.7 christos *q = opcode;
2362 1.7 christos return;
2363 1.7 christos }
2364 1.7 christos }
2365 1.7 christos
2366 1.7 christos switch (src->X_op)
2367 1.7 christos {
2368 1.7 christos case O_md1:
2369 1.8 christos if (ins_ok & INS_GBZ80)
2370 1.8 christos { /* LD A,(HL+) or LD A,(HL-) */
2371 1.8 christos if (dst->X_op == O_register && dst->X_add_number == REG_A)
2372 1.8 christos *frag_more (1) = (src->X_add_number == REG_HL) ? 0x2A : 0x3A;
2373 1.8 christos else
2374 1.8 christos ill_op ();
2375 1.8 christos break;
2376 1.8 christos }
2377 1.8 christos /* Fall through. */
2378 1.7 christos case O_register:
2379 1.7 christos if (dst->X_add_number > 7)
2380 1.7 christos ill_op ();
2381 1.7 christos opcode = 0x46; /* LD B,(HL) */
2382 1.7 christos switch (src->X_add_number)
2383 1.7 christos {
2384 1.7 christos case REG_HL: prefix = 0x00; break;
2385 1.7 christos case REG_IX: prefix = 0xDD; break;
2386 1.7 christos case REG_IY: prefix = 0xFD; break;
2387 1.7 christos default:
2388 1.7 christos ill_op ();
2389 1.7 christos }
2390 1.7 christos q = frag_more (prefix ? 2 : 1);
2391 1.7 christos if (prefix)
2392 1.7 christos *q++ = prefix;
2393 1.7 christos *q = opcode | ((dst->X_add_number & 7) << 3);
2394 1.7 christos if (prefix)
2395 1.7 christos {
2396 1.7 christos src_offset = *src;
2397 1.7 christos src_offset.X_op = O_symbol;
2398 1.7 christos src_offset.X_add_number = 0;
2399 1.7 christos emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2400 1.7 christos }
2401 1.7 christos break;
2402 1.7 christos default: /* LD A,(nn) */
2403 1.7 christos if (dst->X_add_number == REG_A)
2404 1.7 christos {
2405 1.7 christos q = frag_more (1);
2406 1.8 christos *q = (ins_ok & INS_GBZ80) ? 0xFA : 0x3A;
2407 1.7 christos emit_word (src);
2408 1.7 christos }
2409 1.8 christos else
2410 1.8 christos ill_op ();
2411 1.7 christos }
2412 1.7 christos }
2413 1.7 christos
2414 1.7 christos static void
2415 1.7 christos emit_ld_r_n (expressionS *dst, expressionS *src)
2416 1.7 christos { /* for 8-bit immediate value load to register: LD r,n */
2417 1.7 christos char *q;
2418 1.7 christos char prefix = 0;
2419 1.7 christos
2420 1.7 christos switch (dst->X_add_number)
2421 1.7 christos {
2422 1.7 christos case REG_H|R_IX:
2423 1.7 christos case REG_L|R_IX:
2424 1.7 christos prefix = 0xDD;
2425 1.7 christos break;
2426 1.7 christos case REG_H|R_IY:
2427 1.7 christos case REG_L|R_IY:
2428 1.7 christos prefix = 0xFD;
2429 1.7 christos break;
2430 1.7 christos case REG_A:
2431 1.7 christos case REG_B:
2432 1.7 christos case REG_C:
2433 1.7 christos case REG_D:
2434 1.7 christos case REG_E:
2435 1.7 christos case REG_H:
2436 1.7 christos case REG_L:
2437 1.7 christos break;
2438 1.7 christos default:
2439 1.7 christos ill_op ();
2440 1.7 christos }
2441 1.7 christos
2442 1.7 christos q = frag_more (prefix ? 2 : 1);
2443 1.7 christos if (prefix)
2444 1.7 christos {
2445 1.7 christos if (ins_ok & INS_GBZ80)
2446 1.7 christos ill_op ();
2447 1.8 christos else if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
2448 1.7 christos check_mach (INS_IDX_HALF);
2449 1.7 christos *q++ = prefix;
2450 1.1 christos }
2451 1.7 christos *q = 0x06 | ((dst->X_add_number & 7) << 3);
2452 1.7 christos emit_byte (src, BFD_RELOC_8);
2453 1.1 christos }
2454 1.1 christos
2455 1.1 christos static void
2456 1.7 christos emit_ld_r_r (expressionS *dst, expressionS *src)
2457 1.7 christos { /* mostly 8-bit load register from register instructions: LD r,r */
2458 1.7 christos /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2459 1.1 christos char *q;
2460 1.7 christos int prefix = 0;
2461 1.7 christos int opcode = 0;
2462 1.7 christos int ii_halves = 0;
2463 1.1 christos
2464 1.7 christos switch (dst->X_add_number)
2465 1.1 christos {
2466 1.7 christos case REG_SP:
2467 1.7 christos switch (src->X_add_number)
2468 1.7 christos {
2469 1.7 christos case REG_HL: prefix = 0x00; break;
2470 1.7 christos case REG_IX: prefix = 0xDD; break;
2471 1.7 christos case REG_IY: prefix = 0xFD; break;
2472 1.7 christos default:
2473 1.7 christos ill_op ();
2474 1.7 christos }
2475 1.7 christos opcode = 0xF9;
2476 1.7 christos break;
2477 1.7 christos case REG_HL:
2478 1.7 christos if (!(ins_ok & INS_EZ80))
2479 1.7 christos ill_op ();
2480 1.7 christos if (src->X_add_number != REG_I)
2481 1.7 christos ill_op ();
2482 1.7 christos if (cpu_mode < 1)
2483 1.7 christos error (_("ADL mode instruction"));
2484 1.7 christos /* LD HL,I */
2485 1.7 christos prefix = 0xED;
2486 1.7 christos opcode = 0xD7;
2487 1.7 christos break;
2488 1.1 christos case REG_I:
2489 1.7 christos if (src->X_add_number == REG_HL)
2490 1.7 christos {
2491 1.7 christos if (!(ins_ok & INS_EZ80))
2492 1.7 christos ill_op ();
2493 1.7 christos if (cpu_mode < 1)
2494 1.7 christos error (_("ADL mode instruction"));
2495 1.7 christos prefix = 0xED;
2496 1.7 christos opcode = 0xC7;
2497 1.7 christos }
2498 1.7 christos else if (src->X_add_number == REG_A)
2499 1.7 christos {
2500 1.7 christos prefix = 0xED;
2501 1.7 christos opcode = 0x47;
2502 1.7 christos }
2503 1.7 christos else
2504 1.7 christos ill_op ();
2505 1.7 christos break;
2506 1.7 christos case REG_MB:
2507 1.7 christos if (!(ins_ok & INS_EZ80) || (src->X_add_number != REG_A))
2508 1.7 christos ill_op ();
2509 1.7 christos if (cpu_mode < 1)
2510 1.7 christos error (_("ADL mode instruction"));
2511 1.7 christos prefix = 0xED;
2512 1.7 christos opcode = 0x6D;
2513 1.7 christos break;
2514 1.1 christos case REG_R:
2515 1.7 christos if (src->X_add_number == REG_A) /* LD R,A */
2516 1.7 christos {
2517 1.7 christos prefix = 0xED;
2518 1.7 christos opcode = 0x4F;
2519 1.7 christos }
2520 1.1 christos else
2521 1.7 christos ill_op ();
2522 1.1 christos break;
2523 1.1 christos case REG_A:
2524 1.7 christos if (src->X_add_number == REG_I) /* LD A,I */
2525 1.7 christos {
2526 1.7 christos prefix = 0xED;
2527 1.7 christos opcode = 0x57;
2528 1.7 christos break;
2529 1.7 christos }
2530 1.7 christos else if (src->X_add_number == REG_R) /* LD A,R */
2531 1.7 christos {
2532 1.7 christos prefix = 0xED;
2533 1.7 christos opcode = 0x5F;
2534 1.7 christos break;
2535 1.7 christos }
2536 1.7 christos else if (src->X_add_number == REG_MB) /* LD A,MB */
2537 1.7 christos {
2538 1.7 christos if (!(ins_ok & INS_EZ80))
2539 1.7 christos ill_op ();
2540 1.7 christos else
2541 1.7 christos {
2542 1.7 christos if (cpu_mode < 1)
2543 1.7 christos error (_("ADL mode instruction"));
2544 1.7 christos prefix = 0xED;
2545 1.7 christos opcode = 0x6E;
2546 1.7 christos }
2547 1.7 christos break;
2548 1.7 christos }
2549 1.7 christos /* Fall through. */
2550 1.1 christos case REG_B:
2551 1.1 christos case REG_C:
2552 1.1 christos case REG_D:
2553 1.1 christos case REG_E:
2554 1.7 christos case REG_H:
2555 1.7 christos case REG_L:
2556 1.7 christos prefix = 0x00;
2557 1.7 christos break;
2558 1.7 christos case REG_H|R_IX:
2559 1.7 christos case REG_L|R_IX:
2560 1.7 christos prefix = 0xDD;
2561 1.7 christos ii_halves = 1;
2562 1.7 christos break;
2563 1.7 christos case REG_H|R_IY:
2564 1.7 christos case REG_L|R_IY:
2565 1.7 christos prefix = 0xFD;
2566 1.7 christos ii_halves = 1;
2567 1.7 christos break;
2568 1.7 christos default:
2569 1.7 christos ill_op ();
2570 1.7 christos }
2571 1.7 christos
2572 1.7 christos if (opcode == 0)
2573 1.7 christos {
2574 1.7 christos switch (src->X_add_number)
2575 1.7 christos {
2576 1.7 christos case REG_A:
2577 1.7 christos case REG_B:
2578 1.7 christos case REG_C:
2579 1.7 christos case REG_D:
2580 1.7 christos case REG_E:
2581 1.7 christos break;
2582 1.7 christos case REG_H:
2583 1.7 christos case REG_L:
2584 1.7 christos if (prefix != 0)
2585 1.7 christos ill_op (); /* LD iiH/L,H/L are not permitted */
2586 1.7 christos break;
2587 1.7 christos case REG_H|R_IX:
2588 1.7 christos case REG_L|R_IX:
2589 1.7 christos if (prefix == 0xFD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
2590 1.7 christos ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2591 1.7 christos prefix = 0xDD;
2592 1.7 christos ii_halves = 1;
2593 1.7 christos break;
2594 1.7 christos case REG_H|R_IY:
2595 1.7 christos case REG_L|R_IY:
2596 1.7 christos if (prefix == 0xDD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
2597 1.7 christos ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2598 1.7 christos prefix = 0xFD;
2599 1.7 christos ii_halves = 1;
2600 1.7 christos break;
2601 1.7 christos default:
2602 1.7 christos ill_op ();
2603 1.7 christos }
2604 1.7 christos opcode = 0x40 + ((dst->X_add_number & 7) << 3) + (src->X_add_number & 7);
2605 1.7 christos }
2606 1.7 christos if ((ins_ok & INS_GBZ80) && prefix != 0)
2607 1.7 christos ill_op ();
2608 1.8 christos if (ii_halves && !(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
2609 1.7 christos check_mach (INS_IDX_HALF);
2610 1.7 christos if (prefix == 0 && (ins_ok & INS_EZ80))
2611 1.7 christos {
2612 1.7 christos switch (opcode)
2613 1.7 christos {
2614 1.7 christos case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2615 1.7 christos case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2616 1.7 christos case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2617 1.7 christos case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2618 1.7 christos as_warn (_("unsupported instruction, assembled as NOP"));
2619 1.7 christos opcode = 0x00;
2620 1.7 christos break;
2621 1.7 christos default:;
2622 1.7 christos }
2623 1.7 christos }
2624 1.7 christos q = frag_more (prefix ? 2 : 1);
2625 1.7 christos if (prefix)
2626 1.7 christos *q++ = prefix;
2627 1.7 christos *q = opcode;
2628 1.7 christos }
2629 1.7 christos
2630 1.7 christos static void
2631 1.7 christos emit_ld_rr_m (expressionS *dst, expressionS *src)
2632 1.7 christos { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2633 1.7 christos char *q;
2634 1.7 christos int prefix = 0;
2635 1.7 christos int opcode = 0;
2636 1.7 christos expressionS src_offset;
2637 1.7 christos
2638 1.7 christos /* GBZ80 has no support for 16-bit load from memory instructions */
2639 1.7 christos if (ins_ok & INS_GBZ80)
2640 1.7 christos ill_op ();
2641 1.7 christos
2642 1.7 christos prefix = 0xED;
2643 1.7 christos switch (src->X_op)
2644 1.7 christos {
2645 1.7 christos case O_md1: /* LD rr,(ii+d) */
2646 1.7 christos prefix = (src->X_add_number == REG_IX) ? 0xDD : 0xFD;
2647 1.7 christos /* Fall through. */
2648 1.7 christos case O_register: /* LD rr,(HL) */
2649 1.7 christos /* currently only EZ80 has support for 16bit indirect memory load instructions */
2650 1.7 christos if (!(ins_ok & INS_EZ80))
2651 1.7 christos ill_op ();
2652 1.7 christos switch (dst->X_add_number)
2653 1.7 christos {
2654 1.7 christos case REG_BC: opcode = 0x07; break;
2655 1.7 christos case REG_DE: opcode = 0x17; break;
2656 1.7 christos case REG_HL: opcode = 0x27; break;
2657 1.8 christos case REG_IX: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x37 : 0x31; break;
2658 1.8 christos case REG_IY: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x31 : 0x37; break;
2659 1.7 christos default:
2660 1.7 christos ill_op ();
2661 1.7 christos }
2662 1.7 christos q = frag_more (2);
2663 1.7 christos *q++ = prefix;
2664 1.7 christos *q = opcode;
2665 1.7 christos if (prefix != 0xED)
2666 1.7 christos {
2667 1.7 christos src_offset = *src;
2668 1.7 christos src_offset.X_op = O_symbol;
2669 1.7 christos src_offset.X_add_number = 0;
2670 1.7 christos emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2671 1.7 christos }
2672 1.7 christos break;
2673 1.7 christos default: /* LD rr,(nn) */
2674 1.7 christos switch (dst->X_add_number)
2675 1.7 christos {
2676 1.7 christos case REG_BC: prefix = 0xED; opcode = 0x4B; break;
2677 1.7 christos case REG_DE: prefix = 0xED; opcode = 0x5B; break;
2678 1.7 christos case REG_HL: prefix = 0x00; opcode = 0x2A; break;
2679 1.7 christos case REG_SP: prefix = 0xED; opcode = 0x7B; break;
2680 1.7 christos case REG_IX: prefix = 0xDD; opcode = 0x2A; break;
2681 1.7 christos case REG_IY: prefix = 0xFD; opcode = 0x2A; break;
2682 1.7 christos default:
2683 1.7 christos ill_op ();
2684 1.7 christos }
2685 1.7 christos q = frag_more (prefix ? 2 : 1);
2686 1.7 christos if (prefix)
2687 1.7 christos *q++ = prefix;
2688 1.7 christos *q = opcode;
2689 1.7 christos emit_word (src);
2690 1.7 christos }
2691 1.7 christos return;
2692 1.7 christos }
2693 1.7 christos
2694 1.7 christos static void
2695 1.7 christos emit_ld_rr_nn (expressionS *dst, expressionS *src)
2696 1.7 christos { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2697 1.7 christos char *q;
2698 1.7 christos int prefix = 0x00;
2699 1.7 christos int opcode = 0x21; /* LD HL,nn */
2700 1.7 christos switch (dst->X_add_number)
2701 1.7 christos {
2702 1.7 christos case REG_IX:
2703 1.7 christos prefix = 0xDD;
2704 1.7 christos break;
2705 1.7 christos case REG_IY:
2706 1.7 christos prefix = 0xFD;
2707 1.1 christos break;
2708 1.7 christos case REG_HL:
2709 1.7 christos break;
2710 1.7 christos case REG_BC:
2711 1.7 christos case REG_DE:
2712 1.7 christos case REG_SP:
2713 1.7 christos opcode = 0x01 + ((dst->X_add_number & 3) << 4);
2714 1.7 christos break;
2715 1.7 christos default:
2716 1.7 christos ill_op ();
2717 1.7 christos return;
2718 1.7 christos }
2719 1.7 christos if (prefix && (ins_ok & INS_GBZ80))
2720 1.7 christos ill_op ();
2721 1.7 christos q = frag_more (prefix ? 2 : 1);
2722 1.7 christos if (prefix)
2723 1.7 christos *q++ = prefix;
2724 1.7 christos *q = opcode;
2725 1.7 christos emit_word (src);
2726 1.7 christos }
2727 1.7 christos
2728 1.7 christos static const char *
2729 1.7 christos emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
2730 1.7 christos const char * args)
2731 1.7 christos {
2732 1.7 christos expressionS dst, src;
2733 1.7 christos const char *p;
2734 1.7 christos
2735 1.7 christos p = parse_exp (args, & dst);
2736 1.7 christos if (*p++ != ',')
2737 1.7 christos error (_("bad instruction syntax"));
2738 1.7 christos p = parse_exp (p, & src);
2739 1.7 christos
2740 1.7 christos if (dst.X_md)
2741 1.7 christos {
2742 1.7 christos if (src.X_op == O_register)
2743 1.7 christos {
2744 1.7 christos if (src.X_add_number <= 7)
2745 1.7 christos emit_ld_m_r (& dst, & src); /* LD (xxx),r */
2746 1.7 christos else
2747 1.7 christos emit_ld_m_rr (& dst, & src); /* LD (xxx),rr */
2748 1.7 christos }
2749 1.7 christos else
2750 1.7 christos emit_ld_m_n (& dst, & src); /* LD (hl),n or LD (ix/y+r),n */
2751 1.7 christos }
2752 1.7 christos else if (dst.X_op == O_register)
2753 1.7 christos {
2754 1.7 christos if (src.X_md)
2755 1.7 christos {
2756 1.7 christos if (dst.X_add_number <= 7)
2757 1.7 christos emit_ld_r_m (& dst, & src);
2758 1.7 christos else
2759 1.7 christos emit_ld_rr_m (& dst, & src);
2760 1.7 christos }
2761 1.7 christos else if (src.X_op == O_register)
2762 1.7 christos emit_ld_r_r (& dst, & src);
2763 1.7 christos else if ((dst.X_add_number & ~R_INDEX) <= 7)
2764 1.7 christos emit_ld_r_n (& dst, & src);
2765 1.7 christos else
2766 1.7 christos emit_ld_rr_nn (& dst, & src);
2767 1.7 christos }
2768 1.7 christos else
2769 1.7 christos ill_op ();
2770 1.7 christos
2771 1.7 christos return p;
2772 1.7 christos }
2773 1.7 christos
2774 1.7 christos static const char *
2775 1.7 christos emit_lddldi (char prefix, char opcode, const char * args)
2776 1.7 christos {
2777 1.7 christos expressionS dst, src;
2778 1.7 christos const char *p;
2779 1.7 christos char *q;
2780 1.7 christos
2781 1.7 christos if (!(ins_ok & INS_GBZ80))
2782 1.7 christos return emit_insn (prefix, opcode, args);
2783 1.7 christos
2784 1.7 christos p = parse_exp (args, & dst);
2785 1.7 christos if (*p++ != ',')
2786 1.7 christos error (_("bad instruction syntax"));
2787 1.8 christos p = parse_exp (p, & src);
2788 1.7 christos
2789 1.7 christos if (dst.X_op != O_register || src.X_op != O_register)
2790 1.7 christos ill_op ();
2791 1.7 christos
2792 1.7 christos /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2793 1.7 christos opcode = (opcode & 0x08) * 2 + 0x22;
2794 1.7 christos
2795 1.7 christos if (dst.X_md != 0
2796 1.7 christos && dst.X_add_number == REG_HL
2797 1.7 christos && src.X_md == 0
2798 1.7 christos && src.X_add_number == REG_A)
2799 1.7 christos opcode |= 0x00; /* LDx (HL),A */
2800 1.7 christos else if (dst.X_md == 0
2801 1.7 christos && dst.X_add_number == REG_A
2802 1.7 christos && src.X_md != 0
2803 1.7 christos && src.X_add_number == REG_HL)
2804 1.7 christos opcode |= 0x08; /* LDx A,(HL) */
2805 1.7 christos else
2806 1.7 christos ill_op ();
2807 1.7 christos
2808 1.7 christos q = frag_more (1);
2809 1.7 christos *q = opcode;
2810 1.7 christos return p;
2811 1.7 christos }
2812 1.7 christos
2813 1.7 christos static const char *
2814 1.7 christos emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2815 1.7 christos const char * args)
2816 1.7 christos {
2817 1.7 christos expressionS dst, src;
2818 1.7 christos const char *p;
2819 1.7 christos char *q;
2820 1.1 christos
2821 1.7 christos p = parse_exp (args, & dst);
2822 1.7 christos if (*p++ != ',')
2823 1.7 christos {
2824 1.7 christos error (_("bad instruction syntax"));
2825 1.7 christos return p;
2826 1.7 christos }
2827 1.7 christos
2828 1.7 christos p = parse_exp (p, & src);
2829 1.7 christos if (dst.X_md == 0
2830 1.7 christos && dst.X_op == O_register
2831 1.7 christos && dst.X_add_number == REG_A
2832 1.7 christos && src.X_md != 0
2833 1.8 christos && src.X_op != O_md1)
2834 1.7 christos {
2835 1.8 christos if (src.X_op != O_register)
2836 1.8 christos {
2837 1.8 christos q = frag_more (1);
2838 1.8 christos *q = 0xF0;
2839 1.8 christos emit_byte (& src, BFD_RELOC_8);
2840 1.8 christos }
2841 1.8 christos else if (src.X_add_number == REG_C)
2842 1.8 christos *frag_more (1) = 0xF2;
2843 1.8 christos else
2844 1.8 christos ill_op ();
2845 1.7 christos }
2846 1.7 christos else if (dst.X_md != 0
2847 1.7 christos && dst.X_op != O_md1
2848 1.7 christos && src.X_md == 0
2849 1.7 christos && src.X_op == O_register
2850 1.7 christos && src.X_add_number == REG_A)
2851 1.7 christos {
2852 1.7 christos if (dst.X_op == O_register)
2853 1.7 christos {
2854 1.7 christos if (dst.X_add_number == REG_C)
2855 1.7 christos {
2856 1.7 christos q = frag_more (1);
2857 1.7 christos *q = 0xE2;
2858 1.7 christos }
2859 1.7 christos else
2860 1.7 christos ill_op ();
2861 1.7 christos }
2862 1.1 christos else
2863 1.7 christos {
2864 1.7 christos q = frag_more (1);
2865 1.7 christos *q = 0xE0;
2866 1.7 christos emit_byte (& dst, BFD_RELOC_8);
2867 1.7 christos }
2868 1.7 christos }
2869 1.7 christos else
2870 1.7 christos ill_op ();
2871 1.7 christos
2872 1.7 christos return p;
2873 1.7 christos }
2874 1.7 christos
2875 1.7 christos static const char *
2876 1.8 christos emit_ldhl (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2877 1.8 christos {
2878 1.8 christos expressionS dst, src;
2879 1.8 christos const char *p;
2880 1.8 christos char *q;
2881 1.8 christos p = parse_exp (args, & dst);
2882 1.8 christos if (*p++ != ',')
2883 1.8 christos {
2884 1.8 christos error (_("bad instruction syntax"));
2885 1.8 christos return p;
2886 1.8 christos }
2887 1.8 christos
2888 1.8 christos p = parse_exp (p, & src);
2889 1.8 christos if (dst.X_md || dst.X_op != O_register || dst.X_add_number != REG_SP
2890 1.8 christos || src.X_md || src.X_op == O_register || src.X_op == O_md1)
2891 1.8 christos ill_op ();
2892 1.8 christos q = frag_more (1);
2893 1.8 christos *q = opcode;
2894 1.8 christos emit_byte (& src, BFD_RELOC_Z80_DISP8);
2895 1.8 christos return p;
2896 1.8 christos }
2897 1.8 christos
2898 1.8 christos static const char *
2899 1.7 christos parse_lea_pea_args (const char * args, expressionS *op)
2900 1.7 christos {
2901 1.7 christos const char *p;
2902 1.7 christos p = parse_exp (args, op);
2903 1.7 christos if (sdcc_compat && *p == ',' && op->X_op == O_register)
2904 1.7 christos {
2905 1.7 christos expressionS off;
2906 1.7 christos p = parse_exp (p + 1, &off);
2907 1.7 christos op->X_op = O_add;
2908 1.7 christos op->X_add_symbol = make_expr_symbol (&off);
2909 1.7 christos }
2910 1.7 christos return p;
2911 1.7 christos }
2912 1.7 christos
2913 1.7 christos static const char *
2914 1.7 christos emit_lea (char prefix, char opcode, const char * args)
2915 1.7 christos {
2916 1.7 christos expressionS dst, src;
2917 1.7 christos const char *p;
2918 1.7 christos char *q;
2919 1.7 christos int rnum;
2920 1.7 christos
2921 1.7 christos p = parse_exp (args, & dst);
2922 1.7 christos if (dst.X_md != 0 || dst.X_op != O_register)
2923 1.7 christos ill_op ();
2924 1.7 christos
2925 1.7 christos rnum = dst.X_add_number;
2926 1.7 christos switch (rnum)
2927 1.7 christos {
2928 1.7 christos case REG_BC:
2929 1.7 christos case REG_DE:
2930 1.7 christos case REG_HL:
2931 1.7 christos opcode = 0x02 | ((rnum & 0x03) << 4);
2932 1.7 christos break;
2933 1.7 christos case REG_IX:
2934 1.7 christos opcode = 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2935 1.7 christos break;
2936 1.7 christos case REG_IY:
2937 1.7 christos opcode = 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2938 1.7 christos break;
2939 1.7 christos default:
2940 1.7 christos ill_op ();
2941 1.7 christos }
2942 1.7 christos
2943 1.7 christos if (*p++ != ',')
2944 1.7 christos error (_("bad instruction syntax"));
2945 1.7 christos
2946 1.7 christos p = parse_lea_pea_args (p, & src);
2947 1.7 christos if (src.X_md != 0 || src.X_op != O_add /*&& src.X_op != O_register*/)
2948 1.7 christos ill_op ();
2949 1.7 christos
2950 1.7 christos rnum = src.X_add_number;
2951 1.7 christos switch (src.X_op)
2952 1.7 christos {
2953 1.7 christos case O_add:
2954 1.1 christos break;
2955 1.7 christos case O_register: /* permit instructions like LEA rr,IX without displacement specified */
2956 1.7 christos src.X_add_symbol = zero;
2957 1.7 christos break;
2958 1.7 christos default:
2959 1.7 christos ill_op ();
2960 1.7 christos }
2961 1.7 christos
2962 1.7 christos switch (rnum)
2963 1.7 christos {
2964 1.7 christos case REG_IX:
2965 1.7 christos opcode = (opcode == (char)0x33) ? 0x55 : (opcode|0x00);
2966 1.7 christos break;
2967 1.7 christos case REG_IY:
2968 1.7 christos opcode = (opcode == (char)0x32) ? 0x54 : (opcode|0x01);
2969 1.7 christos }
2970 1.7 christos
2971 1.7 christos q = frag_more (2);
2972 1.7 christos *q++ = prefix;
2973 1.7 christos *q = opcode;
2974 1.7 christos
2975 1.7 christos src.X_op = O_symbol;
2976 1.7 christos src.X_add_number = 0;
2977 1.7 christos emit_byte (& src, BFD_RELOC_Z80_DISP8);
2978 1.7 christos
2979 1.7 christos return p;
2980 1.7 christos }
2981 1.7 christos
2982 1.7 christos static const char *
2983 1.7 christos emit_mlt (char prefix, char opcode, const char * args)
2984 1.7 christos {
2985 1.7 christos expressionS arg;
2986 1.7 christos const char *p;
2987 1.7 christos char *q;
2988 1.7 christos
2989 1.7 christos p = parse_exp (args, & arg);
2990 1.7 christos if (arg.X_md != 0 || arg.X_op != O_register || !(arg.X_add_number & R_ARITH))
2991 1.7 christos ill_op ();
2992 1.7 christos
2993 1.7 christos q = frag_more (2);
2994 1.8 christos if (ins_ok & INS_Z80N)
2995 1.8 christos {
2996 1.8 christos if (arg.X_add_number != REG_DE)
2997 1.8 christos ill_op ();
2998 1.8 christos *q++ = 0xED;
2999 1.8 christos *q = 0x30;
3000 1.8 christos }
3001 1.8 christos else
3002 1.8 christos {
3003 1.8 christos *q++ = prefix;
3004 1.8 christos *q = opcode | ((arg.X_add_number & 3) << 4);
3005 1.8 christos }
3006 1.8 christos
3007 1.8 christos return p;
3008 1.8 christos }
3009 1.8 christos
3010 1.8 christos /* MUL D,E (Z80N only) */
3011 1.8 christos static const char *
3012 1.8 christos emit_mul (char prefix, char opcode, const char * args)
3013 1.8 christos {
3014 1.8 christos expressionS r1, r2;
3015 1.8 christos const char *p;
3016 1.8 christos char *q;
3017 1.8 christos
3018 1.8 christos p = parse_exp (args, & r1);
3019 1.8 christos if (*p++ != ',')
3020 1.8 christos error (_("bad instruction syntax"));
3021 1.8 christos p = parse_exp (p, & r2);
3022 1.8 christos
3023 1.8 christos if (r1.X_md != 0 || r1.X_op != O_register || r1.X_add_number != REG_D ||
3024 1.8 christos r2.X_md != 0 || r2.X_op != O_register || r2.X_add_number != REG_E)
3025 1.8 christos ill_op ();
3026 1.8 christos
3027 1.8 christos q = frag_more (2);
3028 1.7 christos *q++ = prefix;
3029 1.8 christos *q = opcode;
3030 1.7 christos
3031 1.7 christos return p;
3032 1.7 christos }
3033 1.7 christos
3034 1.7 christos static const char *
3035 1.8 christos emit_nextreg (char prefix, char opcode ATTRIBUTE_UNUSED, const char * args)
3036 1.8 christos {
3037 1.8 christos expressionS rr, nn;
3038 1.8 christos const char *p;
3039 1.8 christos char *q;
3040 1.8 christos
3041 1.8 christos p = parse_exp (args, & rr);
3042 1.8 christos if (*p++ != ',')
3043 1.8 christos error (_("bad instruction syntax"));
3044 1.8 christos p = parse_exp (p, & nn);
3045 1.8 christos if (rr.X_md != 0 || rr.X_op == O_register || rr.X_op == O_md1 ||
3046 1.8 christos nn.X_md != 0 || nn.X_op == O_md1)
3047 1.8 christos ill_op ();
3048 1.8 christos q = frag_more (2);
3049 1.8 christos *q++ = prefix;
3050 1.8 christos emit_byte (&rr, BFD_RELOC_8);
3051 1.8 christos if (nn.X_op == O_register && nn.X_add_number == REG_A)
3052 1.8 christos *q = 0x92;
3053 1.8 christos else if (nn.X_op != O_register)
3054 1.8 christos {
3055 1.8 christos *q = 0x91;
3056 1.8 christos emit_byte (&nn, BFD_RELOC_8);
3057 1.8 christos }
3058 1.8 christos else
3059 1.8 christos ill_op ();
3060 1.8 christos return p;
3061 1.8 christos }
3062 1.8 christos
3063 1.8 christos static const char *
3064 1.7 christos emit_pea (char prefix, char opcode, const char * args)
3065 1.7 christos {
3066 1.7 christos expressionS arg;
3067 1.7 christos const char *p;
3068 1.7 christos char *q;
3069 1.1 christos
3070 1.7 christos p = parse_lea_pea_args (args, & arg);
3071 1.7 christos if (arg.X_md != 0
3072 1.7 christos || (/*arg.X_op != O_register &&*/ arg.X_op != O_add)
3073 1.7 christos || !(arg.X_add_number & R_INDEX))
3074 1.7 christos ill_op ();
3075 1.7 christos /* PEA ii without displacement is mostly typo,
3076 1.7 christos because there is PUSH instruction which is shorter and faster */
3077 1.7 christos /*if (arg.X_op == O_register)
3078 1.7 christos as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3079 1.7 christos
3080 1.7 christos q = frag_more (2);
3081 1.7 christos *q++ = prefix;
3082 1.7 christos *q = opcode + (arg.X_add_number == REG_IY ? 1 : 0);
3083 1.1 christos
3084 1.7 christos arg.X_op = O_symbol;
3085 1.7 christos arg.X_add_number = 0;
3086 1.7 christos emit_byte (& arg, BFD_RELOC_Z80_DISP8);
3087 1.1 christos
3088 1.7 christos return p;
3089 1.7 christos }
3090 1.1 christos
3091 1.7 christos static const char *
3092 1.7 christos emit_reti (char prefix, char opcode, const char * args)
3093 1.7 christos {
3094 1.7 christos if (ins_ok & INS_GBZ80)
3095 1.7 christos return emit_insn (0x00, 0xD9, args);
3096 1.1 christos
3097 1.7 christos return emit_insn (prefix, opcode, args);
3098 1.1 christos }
3099 1.1 christos
3100 1.1 christos static const char *
3101 1.7 christos emit_tst (char prefix, char opcode, const char *args)
3102 1.1 christos {
3103 1.7 christos expressionS arg_s;
3104 1.1 christos const char *p;
3105 1.1 christos char *q;
3106 1.7 christos int rnum;
3107 1.1 christos
3108 1.7 christos p = parse_exp (args, & arg_s);
3109 1.7 christos if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
3110 1.7 christos {
3111 1.7 christos if (!(ins_ok & INS_EZ80))
3112 1.7 christos ill_op ();
3113 1.7 christos ++p;
3114 1.7 christos p = parse_exp (p, & arg_s);
3115 1.7 christos }
3116 1.1 christos
3117 1.7 christos rnum = arg_s.X_add_number;
3118 1.7 christos switch (arg_s.X_op)
3119 1.1 christos {
3120 1.1 christos case O_md1:
3121 1.7 christos ill_op ();
3122 1.1 christos break;
3123 1.1 christos case O_register:
3124 1.7 christos rnum = arg_s.X_add_number;
3125 1.7 christos if (arg_s.X_md != 0)
3126 1.7 christos {
3127 1.7 christos if (rnum != REG_HL)
3128 1.7 christos ill_op ();
3129 1.7 christos else
3130 1.7 christos rnum = 6;
3131 1.7 christos }
3132 1.7 christos q = frag_more (2);
3133 1.7 christos *q++ = prefix;
3134 1.7 christos *q = opcode | (rnum << 3);
3135 1.1 christos break;
3136 1.1 christos default:
3137 1.7 christos if (arg_s.X_md)
3138 1.7 christos ill_op ();
3139 1.7 christos q = frag_more (2);
3140 1.8 christos if (ins_ok & INS_Z80N)
3141 1.8 christos {
3142 1.8 christos *q++ = 0xED;
3143 1.8 christos *q = 0x27;
3144 1.8 christos }
3145 1.8 christos else
3146 1.8 christos {
3147 1.8 christos *q++ = prefix;
3148 1.8 christos *q = opcode | 0x60;
3149 1.8 christos }
3150 1.7 christos emit_byte (& arg_s, BFD_RELOC_8);
3151 1.1 christos }
3152 1.1 christos return p;
3153 1.1 christos }
3154 1.1 christos
3155 1.7 christos static const char *
3156 1.8 christos emit_insn_n (char prefix, char opcode, const char *args)
3157 1.7 christos {
3158 1.7 christos expressionS arg;
3159 1.7 christos const char *p;
3160 1.7 christos char *q;
3161 1.7 christos
3162 1.7 christos p = parse_exp (args, & arg);
3163 1.7 christos if (arg.X_md || arg.X_op == O_register || arg.X_op == O_md1)
3164 1.7 christos ill_op ();
3165 1.7 christos
3166 1.7 christos q = frag_more (2);
3167 1.7 christos *q++ = prefix;
3168 1.7 christos *q = opcode;
3169 1.7 christos emit_byte (& arg, BFD_RELOC_8);
3170 1.7 christos
3171 1.7 christos return p;
3172 1.7 christos }
3173 1.7 christos
3174 1.1 christos static void
3175 1.1 christos emit_data (int size ATTRIBUTE_UNUSED)
3176 1.1 christos {
3177 1.1 christos const char *p, *q;
3178 1.1 christos char *u, quote;
3179 1.1 christos int cnt;
3180 1.1 christos expressionS exp;
3181 1.1 christos
3182 1.1 christos if (is_it_end_of_statement ())
3183 1.1 christos {
3184 1.1 christos demand_empty_rest_of_line ();
3185 1.1 christos return;
3186 1.1 christos }
3187 1.1 christos p = skip_space (input_line_pointer);
3188 1.1 christos
3189 1.1 christos do
3190 1.1 christos {
3191 1.1 christos if (*p == '\"' || *p == '\'')
3192 1.1 christos {
3193 1.1 christos for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
3194 1.1 christos ;
3195 1.1 christos u = frag_more (cnt);
3196 1.1 christos memcpy (u, q, cnt);
3197 1.1 christos if (!*p)
3198 1.1 christos as_warn (_("unterminated string"));
3199 1.1 christos else
3200 1.1 christos p = skip_space (p+1);
3201 1.1 christos }
3202 1.1 christos else
3203 1.1 christos {
3204 1.1 christos p = parse_exp (p, &exp);
3205 1.1 christos if (exp.X_op == O_md1 || exp.X_op == O_register)
3206 1.1 christos {
3207 1.1 christos ill_op ();
3208 1.1 christos break;
3209 1.1 christos }
3210 1.1 christos if (exp.X_md)
3211 1.1 christos as_warn (_("parentheses ignored"));
3212 1.1 christos emit_byte (&exp, BFD_RELOC_8);
3213 1.1 christos p = skip_space (p);
3214 1.1 christos }
3215 1.1 christos }
3216 1.1 christos while (*p++ == ',') ;
3217 1.1 christos input_line_pointer = (char *)(p-1);
3218 1.1 christos }
3219 1.1 christos
3220 1.7 christos static void
3221 1.7 christos z80_cons (int size)
3222 1.7 christos {
3223 1.7 christos const char *p;
3224 1.7 christos expressionS exp;
3225 1.7 christos
3226 1.7 christos if (is_it_end_of_statement ())
3227 1.7 christos {
3228 1.7 christos demand_empty_rest_of_line ();
3229 1.7 christos return;
3230 1.7 christos }
3231 1.7 christos p = skip_space (input_line_pointer);
3232 1.7 christos
3233 1.7 christos do
3234 1.7 christos {
3235 1.7 christos p = parse_exp (p, &exp);
3236 1.7 christos if (exp.X_op == O_md1 || exp.X_op == O_register)
3237 1.7 christos {
3238 1.7 christos ill_op ();
3239 1.7 christos break;
3240 1.7 christos }
3241 1.7 christos if (exp.X_md)
3242 1.7 christos as_warn (_("parentheses ignored"));
3243 1.7 christos emit_data_val (&exp, size);
3244 1.7 christos p = skip_space (p);
3245 1.7 christos } while (*p++ == ',') ;
3246 1.7 christos input_line_pointer = (char *)(p-1);
3247 1.7 christos }
3248 1.7 christos
3249 1.7 christos /* next functions were commented out because it is difficult to mix
3250 1.7 christos both ADL and Z80 mode instructions within one COFF file:
3251 1.7 christos objdump cannot recognize point of mode switching.
3252 1.7 christos */
3253 1.7 christos static void
3254 1.7 christos set_cpu_mode (int mode)
3255 1.7 christos {
3256 1.7 christos if (ins_ok & INS_EZ80)
3257 1.7 christos cpu_mode = mode;
3258 1.7 christos else
3259 1.7 christos error (_("CPU mode is unsupported by target"));
3260 1.7 christos }
3261 1.7 christos
3262 1.7 christos static void
3263 1.7 christos assume (int arg ATTRIBUTE_UNUSED)
3264 1.7 christos {
3265 1.7 christos char *name;
3266 1.7 christos char c;
3267 1.7 christos int n;
3268 1.7 christos
3269 1.7 christos input_line_pointer = (char*)skip_space (input_line_pointer);
3270 1.7 christos c = get_symbol_name (& name);
3271 1.7 christos if (strncasecmp (name, "ADL", 4) != 0)
3272 1.7 christos {
3273 1.7 christos ill_op ();
3274 1.7 christos return;
3275 1.7 christos }
3276 1.7 christos
3277 1.7 christos restore_line_pointer (c);
3278 1.7 christos input_line_pointer = (char*)skip_space (input_line_pointer);
3279 1.7 christos if (*input_line_pointer++ != '=')
3280 1.7 christos {
3281 1.7 christos error (_("assignment expected"));
3282 1.7 christos return;
3283 1.7 christos }
3284 1.7 christos input_line_pointer = (char*)skip_space (input_line_pointer);
3285 1.7 christos n = get_single_number ();
3286 1.7 christos
3287 1.7 christos set_cpu_mode (n);
3288 1.7 christos }
3289 1.7 christos
3290 1.1 christos static const char *
3291 1.1 christos emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
3292 1.1 christos {
3293 1.1 christos const char *p;
3294 1.1 christos
3295 1.1 christos p = skip_space (args);
3296 1.1 christos if (TOLOWER (*p++) != 'a' || *p++ != ',')
3297 1.1 christos ill_op ();
3298 1.1 christos else
3299 1.1 christos {
3300 1.1 christos char *q, reg;
3301 1.1 christos
3302 1.1 christos reg = TOLOWER (*p++);
3303 1.1 christos switch (reg)
3304 1.1 christos {
3305 1.1 christos case 'b':
3306 1.1 christos case 'c':
3307 1.1 christos case 'd':
3308 1.1 christos case 'e':
3309 1.1 christos check_mach (INS_R800);
3310 1.1 christos if (!*skip_space (p))
3311 1.1 christos {
3312 1.1 christos q = frag_more (2);
3313 1.1 christos *q++ = prefix;
3314 1.1 christos *q = opcode + ((reg - 'b') << 3);
3315 1.1 christos break;
3316 1.1 christos }
3317 1.6 christos /* Fall through. */
3318 1.1 christos default:
3319 1.1 christos ill_op ();
3320 1.1 christos }
3321 1.1 christos }
3322 1.1 christos return p;
3323 1.1 christos }
3324 1.1 christos
3325 1.1 christos static const char *
3326 1.1 christos emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
3327 1.1 christos {
3328 1.1 christos const char *p;
3329 1.1 christos
3330 1.1 christos p = skip_space (args);
3331 1.1 christos if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
3332 1.1 christos ill_op ();
3333 1.1 christos else
3334 1.1 christos {
3335 1.1 christos expressionS reg;
3336 1.1 christos char *q;
3337 1.1 christos
3338 1.1 christos p = parse_exp (p, & reg);
3339 1.1 christos
3340 1.1 christos if ((!reg.X_md) && reg.X_op == O_register)
3341 1.1 christos switch (reg.X_add_number)
3342 1.1 christos {
3343 1.1 christos case REG_BC:
3344 1.1 christos case REG_SP:
3345 1.1 christos check_mach (INS_R800);
3346 1.1 christos q = frag_more (2);
3347 1.1 christos *q++ = prefix;
3348 1.1 christos *q = opcode + ((reg.X_add_number & 3) << 4);
3349 1.1 christos break;
3350 1.1 christos default:
3351 1.1 christos ill_op ();
3352 1.1 christos }
3353 1.1 christos }
3354 1.1 christos return p;
3355 1.1 christos }
3356 1.1 christos
3357 1.7 christos static int
3358 1.7 christos assemble_suffix (const char **suffix)
3359 1.7 christos {
3360 1.7 christos static
3361 1.7 christos const char sf[8][4] =
3362 1.7 christos {
3363 1.7 christos "il",
3364 1.7 christos "is",
3365 1.7 christos "l",
3366 1.7 christos "lil",
3367 1.7 christos "lis",
3368 1.7 christos "s",
3369 1.7 christos "sil",
3370 1.7 christos "sis"
3371 1.7 christos };
3372 1.7 christos const char *p;
3373 1.7 christos const char (*t)[4];
3374 1.7 christos char sbuf[4];
3375 1.7 christos int i;
3376 1.7 christos
3377 1.7 christos p = *suffix;
3378 1.7 christos if (*p++ != '.')
3379 1.7 christos return 0;
3380 1.7 christos
3381 1.7 christos for (i = 0; (i < 3) && (ISALPHA (*p)); i++)
3382 1.7 christos sbuf[i] = TOLOWER (*p++);
3383 1.7 christos if (*p && !ISSPACE (*p))
3384 1.7 christos return 0;
3385 1.7 christos *suffix = p;
3386 1.7 christos sbuf[i] = 0;
3387 1.7 christos
3388 1.7 christos t = bsearch (sbuf, sf, ARRAY_SIZE (sf), sizeof (sf[0]), (int(*)(const void*, const void*)) strcmp);
3389 1.7 christos if (t == NULL)
3390 1.7 christos return 0;
3391 1.7 christos i = t - sf;
3392 1.7 christos switch (i)
3393 1.7 christos {
3394 1.7 christos case 0: /* IL */
3395 1.7 christos i = cpu_mode ? 0x5B : 0x52;
3396 1.7 christos break;
3397 1.7 christos case 1: /* IS */
3398 1.7 christos i = cpu_mode ? 0x49 : 0x40;
3399 1.7 christos break;
3400 1.7 christos case 2: /* L */
3401 1.7 christos i = cpu_mode ? 0x5B : 0x49;
3402 1.7 christos break;
3403 1.7 christos case 3: /* LIL */
3404 1.7 christos i = 0x5B;
3405 1.7 christos break;
3406 1.7 christos case 4: /* LIS */
3407 1.7 christos i = 0x49;
3408 1.7 christos break;
3409 1.7 christos case 5: /* S */
3410 1.7 christos i = cpu_mode ? 0x52 : 0x40;
3411 1.7 christos break;
3412 1.7 christos case 6: /* SIL */
3413 1.7 christos i = 0x52;
3414 1.7 christos break;
3415 1.7 christos case 7: /* SIS */
3416 1.7 christos i = 0x40;
3417 1.7 christos break;
3418 1.7 christos }
3419 1.7 christos *frag_more (1) = (char)i;
3420 1.7 christos switch (i)
3421 1.7 christos {
3422 1.7 christos case 0x40: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IS; break;
3423 1.7 christos case 0x49: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IS; break;
3424 1.7 christos case 0x52: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IL; break;
3425 1.7 christos case 0x5B: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IL; break;
3426 1.7 christos }
3427 1.7 christos return 1;
3428 1.7 christos }
3429 1.7 christos
3430 1.7 christos static void
3431 1.7 christos psect (int arg)
3432 1.7 christos {
3433 1.7 christos #if defined(OBJ_ELF)
3434 1.7 christos return obj_elf_section (arg);
3435 1.7 christos #elif defined(OBJ_COFF)
3436 1.7 christos return obj_coff_section (arg);
3437 1.7 christos #else
3438 1.7 christos #error Unknown object format
3439 1.7 christos #endif
3440 1.7 christos }
3441 1.7 christos
3442 1.7 christos static void
3443 1.7 christos set_inss (int inss)
3444 1.7 christos {
3445 1.7 christos int old_ins;
3446 1.7 christos
3447 1.7 christos if (!sdcc_compat)
3448 1.7 christos as_fatal (_("Invalid directive"));
3449 1.7 christos
3450 1.7 christos old_ins = ins_ok;
3451 1.7 christos ins_ok &= INS_MARCH_MASK;
3452 1.7 christos ins_ok |= inss;
3453 1.7 christos if (old_ins != ins_ok)
3454 1.7 christos cpu_mode = 0;
3455 1.7 christos }
3456 1.7 christos
3457 1.7 christos static void
3458 1.7 christos ignore (int arg ATTRIBUTE_UNUSED)
3459 1.7 christos {
3460 1.7 christos ignore_rest_of_line ();
3461 1.7 christos }
3462 1.7 christos
3463 1.7 christos static void
3464 1.7 christos area (int arg)
3465 1.7 christos {
3466 1.7 christos char *p;
3467 1.7 christos if (!sdcc_compat)
3468 1.7 christos as_fatal (_("Invalid directive"));
3469 1.7 christos for (p = input_line_pointer; *p && *p != '(' && *p != '\n'; p++)
3470 1.7 christos ;
3471 1.7 christos if (*p == '(')
3472 1.7 christos {
3473 1.7 christos *p = '\n';
3474 1.7 christos psect (arg);
3475 1.7 christos *p++ = '(';
3476 1.7 christos ignore_rest_of_line ();
3477 1.7 christos }
3478 1.7 christos else
3479 1.7 christos psect (arg);
3480 1.7 christos }
3481 1.7 christos
3482 1.8 christos /* Handle the .bss pseudo-op. */
3483 1.8 christos
3484 1.8 christos static void
3485 1.8 christos s_bss (int ignore ATTRIBUTE_UNUSED)
3486 1.8 christos {
3487 1.8 christos subseg_set (bss_section, 0);
3488 1.8 christos demand_empty_rest_of_line ();
3489 1.8 christos }
3490 1.8 christos
3491 1.1 christos /* Port specific pseudo ops. */
3492 1.1 christos const pseudo_typeS md_pseudo_table[] =
3493 1.1 christos {
3494 1.7 christos { ".area", area, 0},
3495 1.7 christos { ".assume", assume, 0},
3496 1.7 christos { ".ez80", set_inss, INS_EZ80},
3497 1.7 christos { ".gbz80", set_inss, INS_GBZ80},
3498 1.7 christos { ".module", ignore, 0},
3499 1.7 christos { ".optsdcc", ignore, 0},
3500 1.7 christos { ".r800", set_inss, INS_R800},
3501 1.7 christos { ".set", s_set, 0},
3502 1.7 christos { ".z180", set_inss, INS_Z180},
3503 1.8 christos { ".hd64", set_inss, INS_Z180},
3504 1.7 christos { ".z80", set_inss, INS_Z80},
3505 1.8 christos { ".z80n", set_inss, INS_Z80N},
3506 1.8 christos { "bss", s_bss, 0},
3507 1.1 christos { "db" , emit_data, 1},
3508 1.7 christos { "d24", z80_cons, 3},
3509 1.7 christos { "d32", z80_cons, 4},
3510 1.7 christos { "def24", z80_cons, 3},
3511 1.7 christos { "def32", z80_cons, 4},
3512 1.3 christos { "defb", emit_data, 1},
3513 1.7 christos { "defm", emit_data, 1},
3514 1.1 christos { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
3515 1.7 christos { "defw", z80_cons, 2},
3516 1.1 christos { "ds", s_space, 1}, /* Fill with bytes rather than words. */
3517 1.7 christos { "dw", z80_cons, 2},
3518 1.7 christos { "psect", psect, 0}, /* TODO: Translate attributes. */
3519 1.1 christos { "set", 0, 0}, /* Real instruction on z80. */
3520 1.8 christos { "xdef", s_globl, 0}, /* Synonym for .GLOBAL */
3521 1.8 christos { "xref", s_ignore, 0}, /* Synonym for .EXTERN */
3522 1.1 christos { NULL, 0, 0 }
3523 1.1 christos } ;
3524 1.1 christos
3525 1.1 christos static table_t instab[] =
3526 1.1 christos {
3527 1.7 christos { "adc", 0x88, 0x4A, emit_adc, INS_ALL },
3528 1.7 christos { "add", 0x80, 0x09, emit_add, INS_ALL },
3529 1.7 christos { "and", 0x00, 0xA0, emit_s, INS_ALL },
3530 1.7 christos { "bit", 0xCB, 0x40, emit_bit, INS_ALL },
3531 1.8 christos { "brlc", 0xED, 0x2C, emit_bshft,INS_Z80N },
3532 1.8 christos { "bsla", 0xED, 0x28, emit_bshft,INS_Z80N },
3533 1.8 christos { "bsra", 0xED, 0x29, emit_bshft,INS_Z80N },
3534 1.8 christos { "bsrf", 0xED, 0x2B, emit_bshft,INS_Z80N },
3535 1.8 christos { "bsrl", 0xED, 0x2A, emit_bshft,INS_Z80N },
3536 1.7 christos { "call", 0xCD, 0xC4, emit_jpcc, INS_ALL },
3537 1.7 christos { "ccf", 0x00, 0x3F, emit_insn, INS_ALL },
3538 1.7 christos { "cp", 0x00, 0xB8, emit_s, INS_ALL },
3539 1.7 christos { "cpd", 0xED, 0xA9, emit_insn, INS_NOT_GBZ80 },
3540 1.7 christos { "cpdr", 0xED, 0xB9, emit_insn, INS_NOT_GBZ80 },
3541 1.7 christos { "cpi", 0xED, 0xA1, emit_insn, INS_NOT_GBZ80 },
3542 1.7 christos { "cpir", 0xED, 0xB1, emit_insn, INS_NOT_GBZ80 },
3543 1.7 christos { "cpl", 0x00, 0x2F, emit_insn, INS_ALL },
3544 1.7 christos { "daa", 0x00, 0x27, emit_insn, INS_ALL },
3545 1.7 christos { "dec", 0x0B, 0x05, emit_incdec,INS_ALL },
3546 1.7 christos { "di", 0x00, 0xF3, emit_insn, INS_ALL },
3547 1.7 christos { "djnz", 0x00, 0x10, emit_jr, INS_NOT_GBZ80 },
3548 1.7 christos { "ei", 0x00, 0xFB, emit_insn, INS_ALL },
3549 1.7 christos { "ex", 0x00, 0x00, emit_ex, INS_NOT_GBZ80 },
3550 1.7 christos { "exx", 0x00, 0xD9, emit_insn, INS_NOT_GBZ80 },
3551 1.7 christos { "halt", 0x00, 0x76, emit_insn, INS_ALL },
3552 1.7 christos { "im", 0xED, 0x46, emit_im, INS_NOT_GBZ80 },
3553 1.7 christos { "in", 0x00, 0x00, emit_in, INS_NOT_GBZ80 },
3554 1.7 christos { "in0", 0xED, 0x00, emit_in0, INS_Z180|INS_EZ80 },
3555 1.7 christos { "inc", 0x03, 0x04, emit_incdec,INS_ALL },
3556 1.7 christos { "ind", 0xED, 0xAA, emit_insn, INS_NOT_GBZ80 },
3557 1.7 christos { "ind2", 0xED, 0x8C, emit_insn, INS_EZ80 },
3558 1.7 christos { "ind2r",0xED, 0x9C, emit_insn, INS_EZ80 },
3559 1.7 christos { "indm", 0xED, 0x8A, emit_insn, INS_EZ80 },
3560 1.7 christos { "indmr",0xED, 0x9A, emit_insn, INS_EZ80 },
3561 1.7 christos { "indr", 0xED, 0xBA, emit_insn, INS_NOT_GBZ80 },
3562 1.7 christos { "indrx",0xED, 0xCA, emit_insn, INS_EZ80 },
3563 1.7 christos { "ini", 0xED, 0xA2, emit_insn, INS_NOT_GBZ80 },
3564 1.7 christos { "ini2", 0xED, 0x84, emit_insn, INS_EZ80 },
3565 1.7 christos { "ini2r",0xED, 0x94, emit_insn, INS_EZ80 },
3566 1.7 christos { "inim", 0xED, 0x82, emit_insn, INS_EZ80 },
3567 1.7 christos { "inimr",0xED, 0x92, emit_insn, INS_EZ80 },
3568 1.7 christos { "inir", 0xED, 0xB2, emit_insn, INS_NOT_GBZ80 },
3569 1.7 christos { "inirx",0xED, 0xC2, emit_insn, INS_EZ80 },
3570 1.7 christos { "jp", 0xC3, 0xC2, emit_jpcc, INS_ALL },
3571 1.7 christos { "jr", 0x18, 0x20, emit_jrcc, INS_ALL },
3572 1.7 christos { "ld", 0x00, 0x00, emit_ld, INS_ALL },
3573 1.7 christos { "ldd", 0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3574 1.7 christos { "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 },
3575 1.8 christos { "lddrx",0xED, 0xBC, emit_insn, INS_Z80N },
3576 1.8 christos { "lddx", 0xED, 0xAC, emit_insn, INS_Z80N },
3577 1.7 christos { "ldh", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
3578 1.8 christos { "ldhl", 0x00, 0xF8, emit_ldhl, INS_GBZ80 },
3579 1.7 christos { "ldi", 0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3580 1.7 christos { "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 },
3581 1.8 christos { "ldirx",0xED, 0xB4, emit_insn, INS_Z80N },
3582 1.8 christos { "ldix", 0xED, 0xA4, emit_insn, INS_Z80N },
3583 1.8 christos { "ldpirx",0xED,0xB7, emit_insn, INS_Z80N },
3584 1.8 christos { "ldws", 0xED, 0xA5, emit_insn, INS_Z80N },
3585 1.7 christos { "lea", 0xED, 0x02, emit_lea, INS_EZ80 },
3586 1.8 christos { "mirror",0xED,0x24, emit_insn, INS_Z80N },
3587 1.8 christos { "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80|INS_Z80N },
3588 1.8 christos { "mul", 0xED, 0x30, emit_mul, INS_Z80N },
3589 1.7 christos { "mulub",0xED, 0xC5, emit_mulub,INS_R800 },
3590 1.7 christos { "muluw",0xED, 0xC3, emit_muluw,INS_R800 },
3591 1.8 christos { "neg", 0xED, 0x44, emit_insn, INS_NOT_GBZ80 },
3592 1.8 christos { "nextreg",0xED,0x91,emit_nextreg,INS_Z80N },
3593 1.7 christos { "nop", 0x00, 0x00, emit_insn, INS_ALL },
3594 1.7 christos { "or", 0x00, 0xB0, emit_s, INS_ALL },
3595 1.7 christos { "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 },
3596 1.7 christos { "otdm", 0xED, 0x8B, emit_insn, INS_Z180|INS_EZ80 },
3597 1.7 christos { "otdmr",0xED, 0x9B, emit_insn, INS_Z180|INS_EZ80 },
3598 1.7 christos { "otdr", 0xED, 0xBB, emit_insn, INS_NOT_GBZ80 },
3599 1.7 christos { "otdrx",0xED, 0xCB, emit_insn, INS_EZ80 },
3600 1.7 christos { "oti2r",0xED, 0xB4, emit_insn, INS_EZ80 },
3601 1.7 christos { "otim", 0xED, 0x83, emit_insn, INS_Z180|INS_EZ80 },
3602 1.7 christos { "otimr",0xED, 0x93, emit_insn, INS_Z180|INS_EZ80 },
3603 1.7 christos { "otir", 0xED, 0xB3, emit_insn, INS_NOT_GBZ80 },
3604 1.7 christos { "otirx",0xED, 0xC3, emit_insn, INS_EZ80 },
3605 1.7 christos { "out", 0x00, 0x00, emit_out, INS_NOT_GBZ80 },
3606 1.7 christos { "out0", 0xED, 0x01, emit_out0, INS_Z180|INS_EZ80 },
3607 1.7 christos { "outd", 0xED, 0xAB, emit_insn, INS_NOT_GBZ80 },
3608 1.7 christos { "outd2",0xED, 0xAC, emit_insn, INS_EZ80 },
3609 1.7 christos { "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 },
3610 1.7 christos { "outi2",0xED, 0xA4, emit_insn, INS_EZ80 },
3611 1.8 christos { "outinb",0xED,0x90, emit_insn, INS_Z80N },
3612 1.7 christos { "pea", 0xED, 0x65, emit_pea, INS_EZ80 },
3613 1.8 christos { "pixelad",0xED,0x94,emit_insn, INS_Z80N },
3614 1.8 christos { "pixeldn",0xED,0x93,emit_insn, INS_Z80N },
3615 1.7 christos { "pop", 0x00, 0xC1, emit_pop, INS_ALL },
3616 1.8 christos { "push", 0x00, 0xC5, emit_push, INS_ALL },
3617 1.7 christos { "res", 0xCB, 0x80, emit_bit, INS_ALL },
3618 1.7 christos { "ret", 0xC9, 0xC0, emit_retcc,INS_ALL },
3619 1.7 christos { "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/
3620 1.7 christos { "retn", 0xED, 0x45, emit_insn, INS_NOT_GBZ80 },
3621 1.7 christos { "rl", 0xCB, 0x10, emit_mr, INS_ALL },
3622 1.7 christos { "rla", 0x00, 0x17, emit_insn, INS_ALL },
3623 1.7 christos { "rlc", 0xCB, 0x00, emit_mr, INS_ALL },
3624 1.7 christos { "rlca", 0x00, 0x07, emit_insn, INS_ALL },
3625 1.7 christos { "rld", 0xED, 0x6F, emit_insn, INS_NOT_GBZ80 },
3626 1.7 christos { "rr", 0xCB, 0x18, emit_mr, INS_ALL },
3627 1.7 christos { "rra", 0x00, 0x1F, emit_insn, INS_ALL },
3628 1.7 christos { "rrc", 0xCB, 0x08, emit_mr, INS_ALL },
3629 1.7 christos { "rrca", 0x00, 0x0F, emit_insn, INS_ALL },
3630 1.7 christos { "rrd", 0xED, 0x67, emit_insn, INS_NOT_GBZ80 },
3631 1.7 christos { "rsmix",0xED, 0x7E, emit_insn, INS_EZ80 },
3632 1.7 christos { "rst", 0x00, 0xC7, emit_rst, INS_ALL },
3633 1.7 christos { "sbc", 0x98, 0x42, emit_adc, INS_ALL },
3634 1.7 christos { "scf", 0x00, 0x37, emit_insn, INS_ALL },
3635 1.7 christos { "set", 0xCB, 0xC0, emit_bit, INS_ALL },
3636 1.8 christos { "setae",0xED, 0x95, emit_insn, INS_Z80N },
3637 1.8 christos { "sl1", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3638 1.7 christos { "sla", 0xCB, 0x20, emit_mr, INS_ALL },
3639 1.8 christos { "sli", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3640 1.8 christos { "sll", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3641 1.7 christos { "slp", 0xED, 0x76, emit_insn, INS_Z180|INS_EZ80 },
3642 1.7 christos { "sra", 0xCB, 0x28, emit_mr, INS_ALL },
3643 1.7 christos { "srl", 0xCB, 0x38, emit_mr, INS_ALL },
3644 1.7 christos { "stmix",0xED, 0x7D, emit_insn, INS_EZ80 },
3645 1.7 christos { "stop", 0x00, 0x10, emit_insn, INS_GBZ80 },
3646 1.8 christos { "sub", 0x00, 0x90, emit_sub, INS_ALL },
3647 1.8 christos { "swap", 0xCB, 0x30, emit_swap, INS_GBZ80|INS_Z80N },
3648 1.8 christos { "swapnib",0xED,0x23,emit_insn, INS_Z80N },
3649 1.8 christos { "test", 0xED, 0x27, emit_insn_n, INS_Z80N },
3650 1.8 christos { "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80|INS_Z80N },
3651 1.8 christos { "tstio",0xED, 0x74, emit_insn_n,INS_Z180|INS_EZ80 },
3652 1.7 christos { "xor", 0x00, 0xA8, emit_s, INS_ALL },
3653 1.1 christos } ;
3654 1.1 christos
3655 1.1 christos void
3656 1.7 christos md_assemble (char *str)
3657 1.1 christos {
3658 1.1 christos const char *p;
3659 1.1 christos char * old_ptr;
3660 1.1 christos int i;
3661 1.1 christos table_t *insp;
3662 1.1 christos
3663 1.1 christos err_flag = 0;
3664 1.7 christos inst_mode = cpu_mode ? (INST_MODE_L | INST_MODE_IL) : (INST_MODE_S | INST_MODE_IS);
3665 1.1 christos old_ptr = input_line_pointer;
3666 1.1 christos p = skip_space (str);
3667 1.7 christos for (i = 0; (i < BUFLEN) && (ISALPHA (*p) || ISDIGIT (*p));)
3668 1.1 christos buf[i++] = TOLOWER (*p++);
3669 1.1 christos
3670 1.1 christos if (i == BUFLEN)
3671 1.1 christos {
3672 1.1 christos buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */
3673 1.1 christos buf[BUFLEN-1] = 0;
3674 1.1 christos as_bad (_("Unknown instruction '%s'"), buf);
3675 1.1 christos }
3676 1.3 christos else
3677 1.1 christos {
3678 1.7 christos dwarf2_emit_insn (0);
3679 1.7 christos if ((*p) && (!ISSPACE (*p)))
3680 1.7 christos {
3681 1.7 christos if (*p != '.' || !(ins_ok & INS_EZ80) || !assemble_suffix (&p))
3682 1.7 christos {
3683 1.7 christos as_bad (_("syntax error"));
3684 1.7 christos goto end;
3685 1.7 christos }
3686 1.7 christos }
3687 1.1 christos buf[i] = 0;
3688 1.1 christos p = skip_space (p);
3689 1.1 christos key = buf;
3690 1.3 christos
3691 1.1 christos insp = bsearch (&key, instab, ARRAY_SIZE (instab),
3692 1.1 christos sizeof (instab[0]), key_cmp);
3693 1.7 christos if (!insp || (insp->inss && !(insp->inss & ins_ok)))
3694 1.8 christos {
3695 1.8 christos *frag_more (1) = 0;
3696 1.8 christos as_bad (_("Unknown instruction `%s'"), buf);
3697 1.8 christos }
3698 1.1 christos else
3699 1.1 christos {
3700 1.1 christos p = insp->fp (insp->prefix, insp->opcode, p);
3701 1.1 christos p = skip_space (p);
3702 1.8 christos if ((!err_flag) && *p)
3703 1.8 christos as_bad (_("junk at end of line, "
3704 1.8 christos "first unrecognized character is `%c'"), *p);
3705 1.1 christos }
3706 1.1 christos }
3707 1.8 christos end:
3708 1.1 christos input_line_pointer = old_ptr;
3709 1.1 christos }
3710 1.1 christos
3711 1.8 christos static int
3712 1.8 christos signed_overflow (signed long value, unsigned bitsize)
3713 1.8 christos {
3714 1.8 christos signed long max = (signed long) ((1UL << (bitsize - 1)) - 1);
3715 1.8 christos return value < -max - 1 || value > max;
3716 1.8 christos }
3717 1.8 christos
3718 1.8 christos static int
3719 1.8 christos unsigned_overflow (unsigned long value, unsigned bitsize)
3720 1.8 christos {
3721 1.8 christos return value >> (bitsize - 1) >> 1 != 0;
3722 1.8 christos }
3723 1.8 christos
3724 1.8 christos static int
3725 1.8 christos is_overflow (long value, unsigned bitsize)
3726 1.8 christos {
3727 1.8 christos if (value < 0)
3728 1.8 christos return signed_overflow (value, bitsize);
3729 1.8 christos return unsigned_overflow ((unsigned long)value, bitsize);
3730 1.8 christos }
3731 1.8 christos
3732 1.1 christos void
3733 1.8 christos md_apply_fix (fixS * fixP, valueT* valP, segT seg)
3734 1.1 christos {
3735 1.8 christos long val = *valP;
3736 1.1 christos char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
3737 1.1 christos
3738 1.8 christos if (fixP->fx_addsy == NULL)
3739 1.8 christos fixP->fx_done = 1;
3740 1.8 christos else if (fixP->fx_pcrel)
3741 1.8 christos {
3742 1.8 christos segT s = S_GET_SEGMENT (fixP->fx_addsy);
3743 1.8 christos if (s == seg || s == absolute_section)
3744 1.8 christos {
3745 1.8 christos val += S_GET_VALUE (fixP->fx_addsy);
3746 1.8 christos fixP->fx_done = 1;
3747 1.8 christos }
3748 1.8 christos }
3749 1.8 christos
3750 1.1 christos switch (fixP->fx_r_type)
3751 1.1 christos {
3752 1.1 christos case BFD_RELOC_8_PCREL:
3753 1.8 christos case BFD_RELOC_Z80_DISP8:
3754 1.8 christos case BFD_RELOC_8:
3755 1.8 christos case BFD_RELOC_16:
3756 1.8 christos case BFD_RELOC_24:
3757 1.8 christos case BFD_RELOC_32:
3758 1.8 christos case BFD_RELOC_Z80_16_BE:
3759 1.8 christos fixP->fx_no_overflow = 0;
3760 1.8 christos break;
3761 1.8 christos default:
3762 1.8 christos fixP->fx_no_overflow = 1;
3763 1.1 christos break;
3764 1.8 christos }
3765 1.1 christos
3766 1.8 christos switch (fixP->fx_r_type)
3767 1.8 christos {
3768 1.8 christos case BFD_RELOC_8_PCREL:
3769 1.1 christos case BFD_RELOC_Z80_DISP8:
3770 1.8 christos if (fixP->fx_done && signed_overflow (val, 8))
3771 1.8 christos as_bad_where (fixP->fx_file, fixP->fx_line,
3772 1.8 christos _("8-bit signed offset out of range (%+ld)"), val);
3773 1.8 christos *p_lit++ = val;
3774 1.1 christos break;
3775 1.1 christos
3776 1.7 christos case BFD_RELOC_Z80_BYTE0:
3777 1.7 christos *p_lit++ = val;
3778 1.7 christos break;
3779 1.7 christos
3780 1.7 christos case BFD_RELOC_Z80_BYTE1:
3781 1.7 christos *p_lit++ = (val >> 8);
3782 1.7 christos break;
3783 1.7 christos
3784 1.7 christos case BFD_RELOC_Z80_BYTE2:
3785 1.7 christos *p_lit++ = (val >> 16);
3786 1.7 christos break;
3787 1.7 christos
3788 1.7 christos case BFD_RELOC_Z80_BYTE3:
3789 1.7 christos *p_lit++ = (val >> 24);
3790 1.7 christos break;
3791 1.7 christos
3792 1.1 christos case BFD_RELOC_8:
3793 1.8 christos if (fixP->fx_done && is_overflow(val, 8))
3794 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3795 1.8 christos _("8-bit overflow (%+ld)"), val);
3796 1.1 christos *p_lit++ = val;
3797 1.1 christos break;
3798 1.1 christos
3799 1.7 christos case BFD_RELOC_Z80_WORD1:
3800 1.7 christos *p_lit++ = (val >> 16);
3801 1.7 christos *p_lit++ = (val >> 24);
3802 1.7 christos break;
3803 1.7 christos
3804 1.7 christos case BFD_RELOC_Z80_WORD0:
3805 1.8 christos *p_lit++ = val;
3806 1.8 christos *p_lit++ = (val >> 8);
3807 1.8 christos break;
3808 1.8 christos
3809 1.1 christos case BFD_RELOC_16:
3810 1.8 christos if (fixP->fx_done && is_overflow(val, 16))
3811 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3812 1.8 christos _("16-bit overflow (%+ld)"), val);
3813 1.1 christos *p_lit++ = val;
3814 1.1 christos *p_lit++ = (val >> 8);
3815 1.1 christos break;
3816 1.1 christos
3817 1.1 christos case BFD_RELOC_24: /* Def24 may produce this. */
3818 1.8 christos if (fixP->fx_done && is_overflow(val, 24))
3819 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3820 1.8 christos _("24-bit overflow (%+ld)"), val);
3821 1.1 christos *p_lit++ = val;
3822 1.1 christos *p_lit++ = (val >> 8);
3823 1.1 christos *p_lit++ = (val >> 16);
3824 1.1 christos break;
3825 1.1 christos
3826 1.1 christos case BFD_RELOC_32: /* Def32 and .long may produce this. */
3827 1.8 christos if (fixP->fx_done && is_overflow(val, 32))
3828 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3829 1.8 christos _("32-bit overflow (%+ld)"), val);
3830 1.1 christos *p_lit++ = val;
3831 1.1 christos *p_lit++ = (val >> 8);
3832 1.1 christos *p_lit++ = (val >> 16);
3833 1.1 christos *p_lit++ = (val >> 24);
3834 1.8 christos break;
3835 1.8 christos
3836 1.8 christos case BFD_RELOC_Z80_16_BE: /* Z80N PUSH nn instruction produce this. */
3837 1.8 christos *p_lit++ = val >> 8;
3838 1.8 christos *p_lit++ = val;
3839 1.1 christos break;
3840 1.1 christos
3841 1.1 christos default:
3842 1.8 christos printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP->fx_r_type);
3843 1.1 christos abort ();
3844 1.1 christos }
3845 1.1 christos }
3846 1.1 christos
3847 1.1 christos /* GAS will call this to generate a reloc. GAS will pass the
3848 1.1 christos resulting reloc to `bfd_install_relocation'. This currently works
3849 1.1 christos poorly, as `bfd_install_relocation' often does the wrong thing, and
3850 1.1 christos instances of `tc_gen_reloc' have been written to work around the
3851 1.1 christos problems, which in turns makes it difficult to fix
3852 1.1 christos `bfd_install_relocation'. */
3853 1.1 christos
3854 1.1 christos /* If while processing a fixup, a reloc really
3855 1.1 christos needs to be created then it is done here. */
3856 1.1 christos
3857 1.1 christos arelent *
3858 1.1 christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
3859 1.1 christos {
3860 1.1 christos arelent *reloc;
3861 1.1 christos
3862 1.8 christos if (fixp->fx_subsy != NULL)
3863 1.1 christos {
3864 1.8 christos as_bad_subtract (fixp);
3865 1.1 christos return NULL;
3866 1.1 christos }
3867 1.1 christos
3868 1.5 christos reloc = XNEW (arelent);
3869 1.5 christos reloc->sym_ptr_ptr = XNEW (asymbol *);
3870 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3871 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3872 1.8 christos reloc->addend = fixp->fx_offset;
3873 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3874 1.8 christos if (reloc->howto == NULL)
3875 1.8 christos {
3876 1.8 christos as_bad_where (fixp->fx_file, fixp->fx_line,
3877 1.8 christos _("reloc %d not supported by object file format"),
3878 1.8 christos (int) fixp->fx_r_type);
3879 1.8 christos return NULL;
3880 1.8 christos }
3881 1.8 christos
3882 1.8 christos if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3883 1.8 christos || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3884 1.8 christos reloc->address = fixp->fx_offset;
3885 1.1 christos
3886 1.1 christos return reloc;
3887 1.1 christos }
3888 1.7 christos
3889 1.7 christos int
3890 1.8 christos z80_tc_labels_without_colon (void)
3891 1.8 christos {
3892 1.8 christos return colonless_labels;
3893 1.8 christos }
3894 1.8 christos
3895 1.8 christos int
3896 1.7 christos z80_tc_label_is_local (const char *name)
3897 1.7 christos {
3898 1.7 christos const char *n;
3899 1.7 christos const char *p;
3900 1.7 christos if (local_label_prefix == NULL)
3901 1.7 christos return 0;
3902 1.7 christos for (p = local_label_prefix, n = name; *p && *n && *n == *p; p++, n++)
3903 1.7 christos ;
3904 1.7 christos return *p == '\0';
3905 1.7 christos }
3906 1.7 christos
3907 1.7 christos /* Parse floating point number from string and compute mantissa and
3908 1.7 christos exponent. Mantissa is normalized.
3909 1.7 christos */
3910 1.7 christos #define EXP_MIN -0x10000
3911 1.7 christos #define EXP_MAX 0x10000
3912 1.7 christos static int
3913 1.8 christos str_to_broken_float (bool *signP, uint64_t *mantissaP, int *expP)
3914 1.7 christos {
3915 1.7 christos char *p;
3916 1.8 christos bool sign;
3917 1.8 christos uint64_t mantissa = 0;
3918 1.7 christos int exponent = 0;
3919 1.7 christos int i;
3920 1.7 christos
3921 1.7 christos p = (char*)skip_space (input_line_pointer);
3922 1.7 christos sign = (*p == '-');
3923 1.7 christos *signP = sign;
3924 1.7 christos if (sign || *p == '+')
3925 1.7 christos ++p;
3926 1.7 christos if (strncasecmp (p, "NaN", 3) == 0)
3927 1.7 christos {
3928 1.7 christos *mantissaP = 0;
3929 1.7 christos *expP = 0;
3930 1.7 christos input_line_pointer = p + 3;
3931 1.7 christos return 1;
3932 1.7 christos }
3933 1.7 christos if (strncasecmp (p, "inf", 3) == 0)
3934 1.7 christos {
3935 1.7 christos *mantissaP = 1ull << 63;
3936 1.7 christos *expP = EXP_MAX;
3937 1.7 christos input_line_pointer = p + 3;
3938 1.7 christos return 1;
3939 1.7 christos }
3940 1.7 christos for (; ISDIGIT (*p); ++p)
3941 1.7 christos {
3942 1.7 christos if (mantissa >> 60)
3943 1.7 christos {
3944 1.7 christos if (*p >= '5')
3945 1.7 christos mantissa++;
3946 1.7 christos break;
3947 1.7 christos }
3948 1.7 christos mantissa = mantissa * 10 + (*p - '0');
3949 1.7 christos }
3950 1.7 christos /* skip non-significant digits */
3951 1.7 christos for (; ISDIGIT (*p); ++p)
3952 1.7 christos exponent++;
3953 1.7 christos
3954 1.7 christos if (*p == '.')
3955 1.7 christos {
3956 1.7 christos p++;
3957 1.8 christos if (!exponent) /* If no precision overflow. */
3958 1.7 christos {
3959 1.7 christos for (; ISDIGIT (*p); ++p, --exponent)
3960 1.7 christos {
3961 1.7 christos if (mantissa >> 60)
3962 1.7 christos {
3963 1.7 christos if (*p >= '5')
3964 1.7 christos mantissa++;
3965 1.7 christos break;
3966 1.7 christos }
3967 1.7 christos mantissa = mantissa * 10 + (*p - '0');
3968 1.7 christos }
3969 1.7 christos }
3970 1.7 christos for (; ISDIGIT (*p); ++p)
3971 1.7 christos ;
3972 1.7 christos }
3973 1.7 christos if (*p == 'e' || *p == 'E')
3974 1.7 christos {
3975 1.7 christos int es;
3976 1.7 christos int t = 0;
3977 1.7 christos ++p;
3978 1.7 christos es = (*p == '-');
3979 1.7 christos if (es || *p == '+')
3980 1.7 christos p++;
3981 1.7 christos for (; ISDIGIT (*p); ++p)
3982 1.7 christos {
3983 1.7 christos if (t < 100)
3984 1.7 christos t = t * 10 + (*p - '0');
3985 1.7 christos }
3986 1.7 christos exponent += (es) ? -t : t;
3987 1.7 christos }
3988 1.7 christos if (ISALNUM (*p) || *p == '.')
3989 1.7 christos return 0;
3990 1.7 christos input_line_pointer = p;
3991 1.7 christos if (mantissa == 0)
3992 1.7 christos {
3993 1.7 christos *mantissaP = 1ull << 63;
3994 1.7 christos *expP = EXP_MIN;
3995 1.7 christos return 1; /* result is 0 */
3996 1.7 christos }
3997 1.7 christos /* normalization */
3998 1.7 christos for (; mantissa <= ~0ull/10; --exponent)
3999 1.7 christos mantissa *= 10;
4000 1.7 christos /* Now we have sign, mantissa, and signed decimal exponent
4001 1.7 christos need to recompute to binary exponent. */
4002 1.7 christos for (i = 64; exponent > 0; --exponent)
4003 1.7 christos {
4004 1.7 christos /* be sure that no integer overflow */
4005 1.7 christos while (mantissa > ~0ull/10)
4006 1.7 christos {
4007 1.7 christos mantissa >>= 1;
4008 1.7 christos i += 1;
4009 1.7 christos }
4010 1.7 christos mantissa *= 10;
4011 1.7 christos }
4012 1.7 christos for (; exponent < 0; ++exponent)
4013 1.7 christos {
4014 1.7 christos while (!(mantissa >> 63))
4015 1.7 christos {
4016 1.7 christos mantissa <<= 1;
4017 1.7 christos i -= 1;
4018 1.7 christos }
4019 1.7 christos mantissa /= 10;
4020 1.7 christos }
4021 1.7 christos /* normalization */
4022 1.7 christos for (; !(mantissa >> 63); --i)
4023 1.7 christos mantissa <<= 1;
4024 1.7 christos *mantissaP = mantissa;
4025 1.7 christos *expP = i;
4026 1.7 christos return 1;
4027 1.7 christos }
4028 1.7 christos
4029 1.7 christos static const char *
4030 1.7 christos str_to_zeda32(char *litP, int *sizeP)
4031 1.7 christos {
4032 1.8 christos uint64_t mantissa;
4033 1.8 christos bool sign;
4034 1.7 christos int exponent;
4035 1.7 christos unsigned i;
4036 1.7 christos
4037 1.7 christos *sizeP = 4;
4038 1.7 christos if (!str_to_broken_float (&sign, &mantissa, &exponent))
4039 1.7 christos return _("invalid syntax");
4040 1.7 christos /* I do not know why decrement is needed */
4041 1.7 christos --exponent;
4042 1.7 christos /* shift by 39 bits right keeping 25 bit mantissa for rounding */
4043 1.7 christos mantissa >>= 39;
4044 1.7 christos /* do rounding */
4045 1.7 christos ++mantissa;
4046 1.7 christos /* make 24 bit mantissa */
4047 1.7 christos mantissa >>= 1;
4048 1.7 christos /* check for overflow */
4049 1.7 christos if (mantissa >> 24)
4050 1.7 christos {
4051 1.7 christos mantissa >>= 1;
4052 1.7 christos ++exponent;
4053 1.7 christos }
4054 1.7 christos /* check for 0 */
4055 1.7 christos if (exponent < -127)
4056 1.7 christos {
4057 1.7 christos exponent = -128;
4058 1.7 christos mantissa = 0;
4059 1.7 christos }
4060 1.7 christos else if (exponent > 127)
4061 1.7 christos {
4062 1.7 christos exponent = -128;
4063 1.7 christos mantissa = sign ? 0xc00000 : 0x400000;
4064 1.7 christos }
4065 1.7 christos else if (mantissa == 0)
4066 1.7 christos {
4067 1.7 christos exponent = -128;
4068 1.7 christos mantissa = 0x200000;
4069 1.7 christos }
4070 1.7 christos else if (!sign)
4071 1.7 christos mantissa &= (1ull << 23) - 1;
4072 1.7 christos for (i = 0; i < 24; i += 8)
4073 1.7 christos *litP++ = (char)(mantissa >> i);
4074 1.7 christos *litP = (char)(0x80 + exponent);
4075 1.7 christos return NULL;
4076 1.7 christos }
4077 1.7 christos
4078 1.7 christos /*
4079 1.7 christos Math48 by Anders Hejlsberg support.
4080 1.7 christos Mantissa is 39 bits wide, exponent 8 bit wide.
4081 1.7 christos Format is:
4082 1.7 christos bit 47: sign
4083 1.7 christos bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4084 1.7 christos bit 7-0: exponent+128 (0 - value is null)
4085 1.7 christos MIN: 2.938735877e-39
4086 1.7 christos MAX: 1.701411835e+38
4087 1.7 christos */
4088 1.7 christos static const char *
4089 1.7 christos str_to_float48(char *litP, int *sizeP)
4090 1.7 christos {
4091 1.8 christos uint64_t mantissa;
4092 1.8 christos bool sign;
4093 1.7 christos int exponent;
4094 1.7 christos unsigned i;
4095 1.7 christos
4096 1.7 christos *sizeP = 6;
4097 1.7 christos if (!str_to_broken_float (&sign, &mantissa, &exponent))
4098 1.7 christos return _("invalid syntax");
4099 1.7 christos /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4100 1.7 christos mantissa >>= 23;
4101 1.7 christos /* do rounding */
4102 1.7 christos ++mantissa;
4103 1.7 christos /* make 40 bit mantissa */
4104 1.7 christos mantissa >>= 1;
4105 1.7 christos /* check for overflow */
4106 1.7 christos if (mantissa >> 40)
4107 1.7 christos {
4108 1.7 christos mantissa >>= 1;
4109 1.7 christos ++exponent;
4110 1.7 christos }
4111 1.7 christos if (exponent < -127)
4112 1.7 christos {
4113 1.7 christos memset (litP, 0, 6);
4114 1.7 christos return NULL;
4115 1.7 christos }
4116 1.7 christos if (exponent > 127)
4117 1.7 christos return _("overflow");
4118 1.7 christos if (!sign)
4119 1.7 christos mantissa &= (1ull << 39) - 1;
4120 1.7 christos *litP++ = (char)(0x80 + exponent);
4121 1.7 christos for (i = 0; i < 40; i += 8)
4122 1.7 christos *litP++ = (char)(mantissa >> i);
4123 1.7 christos return NULL;
4124 1.7 christos }
4125 1.7 christos
4126 1.7 christos static const char *
4127 1.7 christos str_to_ieee754_h(char *litP, int *sizeP)
4128 1.7 christos {
4129 1.8 christos return ieee_md_atof ('h', litP, sizeP, false);
4130 1.7 christos }
4131 1.7 christos
4132 1.7 christos static const char *
4133 1.7 christos str_to_ieee754_s(char *litP, int *sizeP)
4134 1.7 christos {
4135 1.8 christos return ieee_md_atof ('s', litP, sizeP, false);
4136 1.7 christos }
4137 1.7 christos
4138 1.7 christos static const char *
4139 1.7 christos str_to_ieee754_d(char *litP, int *sizeP)
4140 1.7 christos {
4141 1.8 christos return ieee_md_atof ('d', litP, sizeP, false);
4142 1.8 christos }
4143 1.8 christos
4144 1.8 christos #ifdef TARGET_USE_CFIPOP
4145 1.8 christos /* Initialize the DWARF-2 unwind information for this procedure. */
4146 1.8 christos void
4147 1.8 christos z80_tc_frame_initial_instructions (void)
4148 1.8 christos {
4149 1.8 christos static int sp_regno = -1;
4150 1.8 christos
4151 1.8 christos if (sp_regno < 0)
4152 1.8 christos sp_regno = z80_tc_regname_to_dw2regnum ("sp");
4153 1.8 christos
4154 1.8 christos cfi_add_CFA_def_cfa (sp_regno, 0);
4155 1.8 christos }
4156 1.8 christos
4157 1.8 christos int
4158 1.8 christos z80_tc_regname_to_dw2regnum (const char *regname)
4159 1.8 christos {
4160 1.8 christos static const char *regs[] =
4161 1.8 christos { /* same registers as for GDB */
4162 1.8 christos "af", "bc", "de", "hl",
4163 1.8 christos "sp", "pc", "ix", "iy",
4164 1.8 christos "af_", "bc_", "de_", "hl_",
4165 1.8 christos "ir"
4166 1.8 christos };
4167 1.8 christos unsigned i;
4168 1.8 christos
4169 1.8 christos for (i = 0; i < ARRAY_SIZE(regs); ++i)
4170 1.8 christos if (!strcasecmp (regs[i], regname))
4171 1.8 christos return i;
4172 1.8 christos
4173 1.8 christos return -1;
4174 1.8 christos }
4175 1.8 christos #endif
4176 1.8 christos
4177 1.8 christos /* Implement DWARF2_ADDR_SIZE. */
4178 1.8 christos int
4179 1.8 christos z80_dwarf2_addr_size (const bfd *abfd)
4180 1.8 christos {
4181 1.8 christos switch (bfd_get_mach (abfd))
4182 1.8 christos {
4183 1.8 christos case bfd_mach_ez80_adl:
4184 1.8 christos return 3;
4185 1.8 christos default:
4186 1.8 christos return 2;
4187 1.8 christos }
4188 1.7 christos }
4189