tc-z80.c revision 1.9 1 1.7 christos /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
2 1.9 christos Copyright (C) 2005-2024 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.9 christos z80_md_finish (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.9 christos resolve_register (op);
930 1.1 christos switch (op->X_op)
931 1.1 christos {
932 1.1 christos case O_absent:
933 1.1 christos error (_("missing operand"));
934 1.1 christos break;
935 1.1 christos case O_illegal:
936 1.1 christos error (_("bad expression syntax"));
937 1.1 christos break;
938 1.3 christos default:
939 1.3 christos break;
940 1.1 christos }
941 1.7 christos
942 1.7 christos if (make_shift >= 0)
943 1.7 christos {
944 1.7 christos /* replace [op] by [op >> shift] */
945 1.7 christos expressionS data;
946 1.7 christos op->X_add_symbol = make_expr_symbol (op);
947 1.7 christos op->X_add_number = 0;
948 1.7 christos op->X_op = O_right_shift;
949 1.7 christos memset (&data, 0, sizeof (data));
950 1.7 christos data.X_op = O_constant;
951 1.7 christos data.X_add_number = make_shift;
952 1.7 christos op->X_op_symbol = make_expr_symbol (&data);
953 1.7 christos }
954 1.1 christos return input_line_pointer;
955 1.1 christos }
956 1.1 christos
957 1.7 christos static int
958 1.7 christos unify_indexed (expressionS *op)
959 1.7 christos {
960 1.7 christos if (O_register != symbol_get_value_expression (op->X_add_symbol)->X_op)
961 1.7 christos return 0;
962 1.7 christos
963 1.7 christos int rnum = symbol_get_value_expression (op->X_add_symbol)->X_add_number;
964 1.7 christos if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register (op->X_op_symbol))
965 1.7 christos {
966 1.7 christos ill_op ();
967 1.7 christos return 0;
968 1.7 christos }
969 1.7 christos
970 1.7 christos /* Convert subtraction to addition of negative value. */
971 1.7 christos if (O_subtract == op->X_op)
972 1.7 christos {
973 1.7 christos expressionS minus;
974 1.8 christos memset (&minus, 0, sizeof (minus));
975 1.7 christos minus.X_op = O_uminus;
976 1.7 christos minus.X_add_symbol = op->X_op_symbol;
977 1.7 christos op->X_op_symbol = make_expr_symbol (&minus);
978 1.7 christos op->X_op = O_add;
979 1.7 christos }
980 1.7 christos
981 1.7 christos /* Clear X_add_number of the expression. */
982 1.7 christos if (op->X_add_number != 0)
983 1.7 christos {
984 1.7 christos expressionS add;
985 1.7 christos memset (&add, 0, sizeof (add));
986 1.7 christos add.X_op = O_symbol;
987 1.7 christos add.X_add_number = op->X_add_number;
988 1.7 christos add.X_add_symbol = op->X_op_symbol;
989 1.7 christos op->X_add_symbol = make_expr_symbol (&add);
990 1.7 christos }
991 1.7 christos else
992 1.7 christos op->X_add_symbol = op->X_op_symbol;
993 1.7 christos
994 1.7 christos op->X_add_number = rnum;
995 1.7 christos op->X_op_symbol = 0;
996 1.7 christos return 1;
997 1.7 christos }
998 1.7 christos
999 1.7 christos /* Parse expression, change operator to O_md1 for indexed addressing. */
1000 1.1 christos static const char *
1001 1.1 christos parse_exp (const char *s, expressionS *op)
1002 1.1 christos {
1003 1.1 christos const char* res = parse_exp_not_indexed (s, op);
1004 1.1 christos switch (op->X_op)
1005 1.1 christos {
1006 1.1 christos case O_add:
1007 1.1 christos case O_subtract:
1008 1.7 christos if (unify_indexed (op) && op->X_md)
1009 1.7 christos op->X_op = O_md1;
1010 1.1 christos break;
1011 1.1 christos case O_register:
1012 1.7 christos if (op->X_md && ((REG_IX == op->X_add_number) || (REG_IY == op->X_add_number)))
1013 1.1 christos {
1014 1.1 christos op->X_add_symbol = zero;
1015 1.1 christos op->X_op = O_md1;
1016 1.1 christos }
1017 1.1 christos break;
1018 1.7 christos case O_constant:
1019 1.7 christos /* parse SDCC syntax where index register offset placed before parentheses */
1020 1.7 christos if (sdcc_compat && is_indir (res))
1021 1.7 christos {
1022 1.7 christos expressionS off;
1023 1.7 christos off = *op;
1024 1.7 christos res = parse_exp (res, op);
1025 1.7 christos if (op->X_op != O_md1 || op->X_add_symbol != zero)
1026 1.7 christos ill_op ();
1027 1.7 christos else
1028 1.7 christos op->X_add_symbol = make_expr_symbol (&off);
1029 1.7 christos }
1030 1.7 christos break;
1031 1.3 christos default:
1032 1.3 christos break;
1033 1.1 christos }
1034 1.1 christos return res;
1035 1.1 christos }
1036 1.1 christos
1037 1.1 christos /* Condition codes, including some synonyms provided by HiTech zas. */
1038 1.1 christos static const struct reg_entry cc_tab[] =
1039 1.1 christos {
1040 1.8 christos { "age", 6 << 3, INS_ALL },
1041 1.8 christos { "alt", 7 << 3, INS_ALL },
1042 1.8 christos { "c", 3 << 3, INS_ALL },
1043 1.8 christos { "di", 4 << 3, INS_ALL },
1044 1.8 christos { "ei", 5 << 3, INS_ALL },
1045 1.8 christos { "lge", 2 << 3, INS_ALL },
1046 1.8 christos { "llt", 3 << 3, INS_ALL },
1047 1.8 christos { "m", 7 << 3, INS_ALL },
1048 1.8 christos { "nc", 2 << 3, INS_ALL },
1049 1.8 christos { "nz", 0 << 3, INS_ALL },
1050 1.8 christos { "p", 6 << 3, INS_ALL },
1051 1.8 christos { "pe", 5 << 3, INS_ALL },
1052 1.8 christos { "po", 4 << 3, INS_ALL },
1053 1.8 christos { "z", 1 << 3, INS_ALL },
1054 1.1 christos } ;
1055 1.1 christos
1056 1.1 christos /* Parse condition code. */
1057 1.1 christos static const char *
1058 1.1 christos parse_cc (const char *s, char * op)
1059 1.1 christos {
1060 1.1 christos const char *p;
1061 1.1 christos int i;
1062 1.1 christos struct reg_entry * cc_p;
1063 1.1 christos
1064 1.1 christos for (i = 0; i < BUFLEN; ++i)
1065 1.1 christos {
1066 1.1 christos if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
1067 1.1 christos break;
1068 1.1 christos buf[i] = TOLOWER (s[i]);
1069 1.1 christos }
1070 1.1 christos
1071 1.1 christos if ((i < BUFLEN)
1072 1.1 christos && ((s[i] == 0) || (s[i] == ',')))
1073 1.1 christos {
1074 1.1 christos buf[i] = 0;
1075 1.1 christos cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
1076 1.1 christos sizeof (cc_tab[0]), key_cmp);
1077 1.1 christos }
1078 1.1 christos else
1079 1.1 christos cc_p = NULL;
1080 1.1 christos
1081 1.1 christos if (cc_p)
1082 1.1 christos {
1083 1.1 christos *op = cc_p->number;
1084 1.1 christos p = s + i;
1085 1.1 christos }
1086 1.1 christos else
1087 1.1 christos p = NULL;
1088 1.1 christos
1089 1.1 christos return p;
1090 1.1 christos }
1091 1.1 christos
1092 1.1 christos static const char *
1093 1.1 christos emit_insn (char prefix, char opcode, const char * args)
1094 1.1 christos {
1095 1.1 christos char *p;
1096 1.1 christos
1097 1.1 christos if (prefix)
1098 1.1 christos {
1099 1.1 christos p = frag_more (2);
1100 1.1 christos *p++ = prefix;
1101 1.1 christos }
1102 1.1 christos else
1103 1.1 christos p = frag_more (1);
1104 1.1 christos *p = opcode;
1105 1.1 christos return args;
1106 1.1 christos }
1107 1.1 christos
1108 1.1 christos void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
1109 1.1 christos {
1110 1.1 christos bfd_reloc_code_real_type r[4] =
1111 1.1 christos {
1112 1.1 christos BFD_RELOC_8,
1113 1.1 christos BFD_RELOC_16,
1114 1.1 christos BFD_RELOC_24,
1115 1.1 christos BFD_RELOC_32
1116 1.1 christos };
1117 1.1 christos
1118 1.3 christos if (nbytes < 1 || nbytes > 4)
1119 1.1 christos {
1120 1.1 christos as_bad (_("unsupported BFD relocation size %u"), nbytes);
1121 1.1 christos }
1122 1.1 christos else
1123 1.1 christos {
1124 1.1 christos fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
1125 1.1 christos }
1126 1.1 christos }
1127 1.1 christos
1128 1.1 christos static void
1129 1.7 christos emit_data_val (expressionS * val, int size)
1130 1.7 christos {
1131 1.7 christos char *p;
1132 1.7 christos bfd_reloc_code_real_type r_type;
1133 1.7 christos
1134 1.7 christos p = frag_more (size);
1135 1.7 christos if (val->X_op == O_constant)
1136 1.7 christos {
1137 1.7 christos int i;
1138 1.8 christos
1139 1.8 christos /* PR 28791:
1140 1.8 christos Check for overflow, but ignore values that were generated by bit
1141 1.8 christos manipulation operators (eg ~0xe6 and -7). This does mean that
1142 1.8 christos manipluated overlarge values will not be reported (eg ~0x1234),
1143 1.8 christos but it does help to maintain compatibility with earlier versions
1144 1.8 christos of the assembler. */
1145 1.8 christos if (! val->X_extrabit
1146 1.9 christos && is_overflow (val->X_add_number, size * 8))
1147 1.9 christos as_warn ( _("%d-bit overflow (%+" PRId64 ")"), size * 8,
1148 1.9 christos (int64_t) val->X_add_number);
1149 1.7 christos for (i = 0; i < size; ++i)
1150 1.9 christos p[i] = (val->X_add_number >> (i * 8)) & 0xff;
1151 1.7 christos return;
1152 1.7 christos }
1153 1.7 christos
1154 1.7 christos switch (size)
1155 1.7 christos {
1156 1.7 christos case 1: r_type = BFD_RELOC_8; break;
1157 1.7 christos case 2: r_type = BFD_RELOC_16; break;
1158 1.7 christos case 3: r_type = BFD_RELOC_24; break;
1159 1.7 christos case 4: r_type = BFD_RELOC_32; break;
1160 1.7 christos case 8: r_type = BFD_RELOC_64; break;
1161 1.7 christos default:
1162 1.7 christos as_fatal (_("invalid data size %d"), size);
1163 1.7 christos }
1164 1.7 christos
1165 1.7 christos if ( (val->X_op == O_register)
1166 1.7 christos || (val->X_op == O_md1)
1167 1.7 christos || contains_register (val->X_add_symbol)
1168 1.7 christos || contains_register (val->X_op_symbol))
1169 1.7 christos ill_op ();
1170 1.7 christos
1171 1.7 christos if (size <= 2 && val->X_op_symbol)
1172 1.7 christos {
1173 1.8 christos bool simplify = true;
1174 1.7 christos int shift = symbol_get_value_expression (val->X_op_symbol)->X_add_number;
1175 1.7 christos if (val->X_op == O_bit_and && shift == (1 << (size*8))-1)
1176 1.7 christos shift = 0;
1177 1.7 christos else if (val->X_op != O_right_shift)
1178 1.7 christos shift = -1;
1179 1.7 christos
1180 1.7 christos if (size == 1)
1181 1.7 christos {
1182 1.7 christos switch (shift)
1183 1.7 christos {
1184 1.7 christos case 0: r_type = BFD_RELOC_Z80_BYTE0; break;
1185 1.7 christos case 8: r_type = BFD_RELOC_Z80_BYTE1; break;
1186 1.7 christos case 16: r_type = BFD_RELOC_Z80_BYTE2; break;
1187 1.7 christos case 24: r_type = BFD_RELOC_Z80_BYTE3; break;
1188 1.8 christos default: simplify = false;
1189 1.7 christos }
1190 1.7 christos }
1191 1.7 christos else /* if (size == 2) */
1192 1.7 christos {
1193 1.7 christos switch (shift)
1194 1.7 christos {
1195 1.7 christos case 0: r_type = BFD_RELOC_Z80_WORD0; break;
1196 1.7 christos case 16: r_type = BFD_RELOC_Z80_WORD1; break;
1197 1.8 christos case 8:
1198 1.8 christos case 24: /* add two byte fixups */
1199 1.8 christos val->X_op = O_symbol;
1200 1.8 christos val->X_op_symbol = NULL;
1201 1.8 christos val->X_add_number = 0;
1202 1.8 christos if (shift == 8)
1203 1.8 christos {
1204 1.8 christos fix_new_exp (frag_now, p++ - frag_now->fr_literal, 1, val, false,
1205 1.8 christos BFD_RELOC_Z80_BYTE1);
1206 1.8 christos /* prepare to next byte */
1207 1.8 christos r_type = BFD_RELOC_Z80_BYTE2;
1208 1.8 christos }
1209 1.8 christos else
1210 1.8 christos r_type = BFD_RELOC_Z80_BYTE3; /* high byte will be 0 */
1211 1.8 christos size = 1;
1212 1.8 christos simplify = false;
1213 1.8 christos break;
1214 1.8 christos default: simplify = false;
1215 1.7 christos }
1216 1.7 christos }
1217 1.7 christos
1218 1.7 christos if (simplify)
1219 1.7 christos {
1220 1.7 christos val->X_op = O_symbol;
1221 1.7 christos val->X_op_symbol = NULL;
1222 1.7 christos val->X_add_number = 0;
1223 1.7 christos }
1224 1.7 christos }
1225 1.7 christos
1226 1.8 christos fix_new_exp (frag_now, p - frag_now->fr_literal, size, val, false, r_type);
1227 1.7 christos }
1228 1.7 christos
1229 1.7 christos static void
1230 1.1 christos emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
1231 1.1 christos {
1232 1.1 christos char *p;
1233 1.1 christos
1234 1.7 christos if (r_type == BFD_RELOC_8)
1235 1.7 christos {
1236 1.7 christos emit_data_val (val, 1);
1237 1.7 christos return;
1238 1.7 christos }
1239 1.1 christos p = frag_more (1);
1240 1.1 christos *p = val->X_add_number;
1241 1.8 christos if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol))
1242 1.1 christos {
1243 1.7 christos ill_op ();
1244 1.1 christos }
1245 1.1 christos else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
1246 1.1 christos {
1247 1.1 christos as_bad (_("cannot make a relative jump to an absolute location"));
1248 1.1 christos }
1249 1.1 christos else if (val->X_op == O_constant)
1250 1.1 christos {
1251 1.8 christos if ((val->X_add_number < -128) || (val->X_add_number >= 128))
1252 1.1 christos {
1253 1.1 christos if (r_type == BFD_RELOC_Z80_DISP8)
1254 1.9 christos as_bad (_("index overflow (%+" PRId64 ")"),
1255 1.9 christos (int64_t) val->X_add_number);
1256 1.1 christos else
1257 1.9 christos as_bad (_("offset overflow (%+" PRId64 ")"),
1258 1.9 christos (int64_t) val->X_add_number);
1259 1.1 christos }
1260 1.1 christos }
1261 1.1 christos else
1262 1.1 christos {
1263 1.8 christos /* For symbols only, constants are stored at begin of function. */
1264 1.3 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
1265 1.8 christos r_type == BFD_RELOC_8_PCREL, r_type);
1266 1.1 christos }
1267 1.1 christos }
1268 1.1 christos
1269 1.1 christos static void
1270 1.1 christos emit_word (expressionS * val)
1271 1.1 christos {
1272 1.7 christos emit_data_val (val, (inst_mode & INST_MODE_IL) ? 3 : 2);
1273 1.1 christos }
1274 1.1 christos
1275 1.1 christos static void
1276 1.1 christos emit_mx (char prefix, char opcode, int shift, expressionS * arg)
1277 1.1 christos /* The operand m may be r, (hl), (ix+d), (iy+d),
1278 1.1 christos if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1279 1.1 christos {
1280 1.1 christos char *q;
1281 1.1 christos int rnum;
1282 1.1 christos
1283 1.1 christos rnum = arg->X_add_number;
1284 1.1 christos switch (arg->X_op)
1285 1.1 christos {
1286 1.1 christos case O_register:
1287 1.1 christos if (arg->X_md)
1288 1.1 christos {
1289 1.1 christos if (rnum != REG_HL)
1290 1.1 christos {
1291 1.1 christos ill_op ();
1292 1.1 christos break;
1293 1.1 christos }
1294 1.1 christos else
1295 1.1 christos rnum = 6;
1296 1.1 christos }
1297 1.1 christos else
1298 1.1 christos {
1299 1.1 christos if ((prefix == 0) && (rnum & R_INDEX))
1300 1.1 christos {
1301 1.1 christos prefix = (rnum & R_IX) ? 0xDD : 0xFD;
1302 1.8 christos if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
1303 1.7 christos check_mach (INS_IDX_HALF);
1304 1.1 christos rnum &= ~R_INDEX;
1305 1.1 christos }
1306 1.1 christos if (rnum > 7)
1307 1.1 christos {
1308 1.1 christos ill_op ();
1309 1.1 christos break;
1310 1.1 christos }
1311 1.1 christos }
1312 1.1 christos q = frag_more (prefix ? 2 : 1);
1313 1.1 christos if (prefix)
1314 1.1 christos * q ++ = prefix;
1315 1.1 christos * q ++ = opcode + (rnum << shift);
1316 1.1 christos break;
1317 1.1 christos case O_md1:
1318 1.7 christos if (ins_ok & INS_GBZ80)
1319 1.7 christos {
1320 1.7 christos ill_op ();
1321 1.7 christos break;
1322 1.7 christos }
1323 1.1 christos q = frag_more (2);
1324 1.1 christos *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1325 1.1 christos *q = (prefix) ? prefix : (opcode + (6 << shift));
1326 1.1 christos {
1327 1.1 christos expressionS offset = *arg;
1328 1.1 christos offset.X_op = O_symbol;
1329 1.1 christos offset.X_add_number = 0;
1330 1.1 christos emit_byte (&offset, BFD_RELOC_Z80_DISP8);
1331 1.1 christos }
1332 1.1 christos if (prefix)
1333 1.1 christos {
1334 1.1 christos q = frag_more (1);
1335 1.1 christos *q = opcode+(6<<shift);
1336 1.1 christos }
1337 1.1 christos break;
1338 1.1 christos default:
1339 1.1 christos abort ();
1340 1.1 christos }
1341 1.1 christos }
1342 1.1 christos
1343 1.1 christos /* The operand m may be r, (hl), (ix+d), (iy+d),
1344 1.1 christos if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1345 1.1 christos static const char *
1346 1.1 christos emit_m (char prefix, char opcode, const char *args)
1347 1.1 christos {
1348 1.1 christos expressionS arg_m;
1349 1.1 christos const char *p;
1350 1.1 christos
1351 1.1 christos p = parse_exp (args, &arg_m);
1352 1.1 christos switch (arg_m.X_op)
1353 1.1 christos {
1354 1.1 christos case O_md1:
1355 1.1 christos case O_register:
1356 1.1 christos emit_mx (prefix, opcode, 0, &arg_m);
1357 1.1 christos break;
1358 1.1 christos default:
1359 1.1 christos ill_op ();
1360 1.1 christos }
1361 1.1 christos return p;
1362 1.1 christos }
1363 1.1 christos
1364 1.1 christos /* The operand m may be as above or one of the undocumented
1365 1.1 christos combinations (ix+d),r and (iy+d),r (if unportable instructions
1366 1.1 christos are allowed). */
1367 1.7 christos
1368 1.1 christos static const char *
1369 1.1 christos emit_mr (char prefix, char opcode, const char *args)
1370 1.1 christos {
1371 1.1 christos expressionS arg_m, arg_r;
1372 1.1 christos const char *p;
1373 1.1 christos
1374 1.1 christos p = parse_exp (args, & arg_m);
1375 1.1 christos
1376 1.1 christos switch (arg_m.X_op)
1377 1.1 christos {
1378 1.1 christos case O_md1:
1379 1.1 christos if (*p == ',')
1380 1.1 christos {
1381 1.1 christos p = parse_exp (p + 1, & arg_r);
1382 1.1 christos
1383 1.1 christos if ((arg_r.X_md == 0)
1384 1.1 christos && (arg_r.X_op == O_register)
1385 1.1 christos && (arg_r.X_add_number < 8))
1386 1.7 christos opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6. */
1387 1.1 christos else
1388 1.1 christos {
1389 1.1 christos ill_op ();
1390 1.1 christos break;
1391 1.1 christos }
1392 1.8 christos if (!(ins_ok & INS_Z80N))
1393 1.8 christos check_mach (INS_ROT_II_LD);
1394 1.1 christos }
1395 1.6 christos /* Fall through. */
1396 1.1 christos case O_register:
1397 1.1 christos emit_mx (prefix, opcode, 0, & arg_m);
1398 1.1 christos break;
1399 1.1 christos default:
1400 1.1 christos ill_op ();
1401 1.1 christos }
1402 1.1 christos return p;
1403 1.1 christos }
1404 1.1 christos
1405 1.1 christos static void
1406 1.1 christos emit_sx (char prefix, char opcode, expressionS * arg_p)
1407 1.1 christos {
1408 1.1 christos char *q;
1409 1.1 christos
1410 1.1 christos switch (arg_p->X_op)
1411 1.1 christos {
1412 1.1 christos case O_register:
1413 1.1 christos case O_md1:
1414 1.1 christos emit_mx (prefix, opcode, 0, arg_p);
1415 1.1 christos break;
1416 1.1 christos default:
1417 1.1 christos if (arg_p->X_md)
1418 1.1 christos ill_op ();
1419 1.1 christos else
1420 1.1 christos {
1421 1.1 christos q = frag_more (prefix ? 2 : 1);
1422 1.1 christos if (prefix)
1423 1.1 christos *q++ = prefix;
1424 1.1 christos *q = opcode ^ 0x46;
1425 1.1 christos emit_byte (arg_p, BFD_RELOC_8);
1426 1.1 christos }
1427 1.1 christos }
1428 1.1 christos }
1429 1.1 christos
1430 1.1 christos /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1431 1.1 christos static const char *
1432 1.1 christos emit_s (char prefix, char opcode, const char *args)
1433 1.1 christos {
1434 1.1 christos expressionS arg_s;
1435 1.1 christos const char *p;
1436 1.1 christos
1437 1.1 christos p = parse_exp (args, & arg_s);
1438 1.7 christos if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
1439 1.7 christos { /* possible instruction in generic format op A,x */
1440 1.7 christos if (!(ins_ok & INS_EZ80) && !sdcc_compat)
1441 1.7 christos ill_op ();
1442 1.7 christos ++p;
1443 1.7 christos p = parse_exp (p, & arg_s);
1444 1.7 christos }
1445 1.1 christos emit_sx (prefix, opcode, & arg_s);
1446 1.1 christos return p;
1447 1.1 christos }
1448 1.1 christos
1449 1.1 christos static const char *
1450 1.8 christos emit_sub (char prefix, char opcode, const char *args)
1451 1.8 christos {
1452 1.8 christos expressionS arg_s;
1453 1.8 christos const char *p;
1454 1.8 christos
1455 1.8 christos if (!(ins_ok & INS_GBZ80))
1456 1.8 christos return emit_s (prefix, opcode, args);
1457 1.8 christos p = parse_exp (args, & arg_s);
1458 1.8 christos if (*p++ != ',')
1459 1.8 christos {
1460 1.8 christos error (_("bad instruction syntax"));
1461 1.8 christos return p;
1462 1.8 christos }
1463 1.8 christos
1464 1.8 christos if (arg_s.X_md != 0 || arg_s.X_op != O_register || arg_s.X_add_number != REG_A)
1465 1.8 christos ill_op ();
1466 1.8 christos
1467 1.8 christos p = parse_exp (p, & arg_s);
1468 1.8 christos
1469 1.8 christos emit_sx (prefix, opcode, & arg_s);
1470 1.8 christos return p;
1471 1.8 christos }
1472 1.8 christos
1473 1.8 christos static const char *
1474 1.8 christos emit_swap (char prefix, char opcode, const char *args)
1475 1.8 christos {
1476 1.8 christos expressionS reg;
1477 1.8 christos const char *p;
1478 1.8 christos char *q;
1479 1.8 christos
1480 1.8 christos if (!(ins_ok & INS_Z80N))
1481 1.8 christos return emit_mr (prefix, opcode, args);
1482 1.8 christos
1483 1.8 christos /* check for alias swap a for swapnib of Z80N */
1484 1.8 christos p = parse_exp (args, ®);
1485 1.8 christos if (reg.X_md != 0 || reg.X_op != O_register || reg.X_add_number != REG_A)
1486 1.8 christos ill_op ();
1487 1.8 christos
1488 1.8 christos q = frag_more (2);
1489 1.8 christos *q++ = 0xED;
1490 1.8 christos *q = 0x23;
1491 1.8 christos return p;
1492 1.8 christos }
1493 1.8 christos
1494 1.8 christos static const char *
1495 1.1 christos emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1496 1.1 christos {
1497 1.1 christos expressionS addr;
1498 1.1 christos const char *p; char *q;
1499 1.1 christos
1500 1.1 christos p = parse_exp_not_indexed (args, &addr);
1501 1.1 christos if (addr.X_md)
1502 1.1 christos ill_op ();
1503 1.1 christos else
1504 1.1 christos {
1505 1.1 christos q = frag_more (1);
1506 1.1 christos *q = opcode;
1507 1.1 christos emit_word (& addr);
1508 1.1 christos }
1509 1.1 christos return p;
1510 1.1 christos }
1511 1.1 christos
1512 1.1 christos /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1513 1.1 christos static const char *
1514 1.1 christos emit_incdec (char prefix, char opcode, const char * args)
1515 1.1 christos {
1516 1.1 christos expressionS operand;
1517 1.1 christos int rnum;
1518 1.1 christos const char *p; char *q;
1519 1.1 christos
1520 1.1 christos p = parse_exp (args, &operand);
1521 1.1 christos rnum = operand.X_add_number;
1522 1.1 christos if ((! operand.X_md)
1523 1.1 christos && (operand.X_op == O_register)
1524 1.1 christos && (R_ARITH&rnum))
1525 1.1 christos {
1526 1.1 christos q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1527 1.1 christos if (rnum & R_INDEX)
1528 1.1 christos *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1529 1.1 christos *q = prefix + ((rnum & 3) << 4);
1530 1.1 christos }
1531 1.1 christos else
1532 1.1 christos {
1533 1.1 christos if ((operand.X_op == O_md1) || (operand.X_op == O_register))
1534 1.1 christos emit_mx (0, opcode, 3, & operand);
1535 1.1 christos else
1536 1.1 christos ill_op ();
1537 1.1 christos }
1538 1.1 christos return p;
1539 1.1 christos }
1540 1.1 christos
1541 1.1 christos static const char *
1542 1.1 christos emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1543 1.1 christos {
1544 1.1 christos expressionS addr;
1545 1.1 christos const char *p;
1546 1.1 christos char *q;
1547 1.1 christos
1548 1.1 christos p = parse_exp_not_indexed (args, &addr);
1549 1.1 christos if (addr.X_md)
1550 1.1 christos ill_op ();
1551 1.1 christos else
1552 1.1 christos {
1553 1.1 christos q = frag_more (1);
1554 1.1 christos *q = opcode;
1555 1.7 christos addr.X_add_number--; /* pcrel computes after offset code */
1556 1.1 christos emit_byte (&addr, BFD_RELOC_8_PCREL);
1557 1.1 christos }
1558 1.1 christos return p;
1559 1.1 christos }
1560 1.1 christos
1561 1.1 christos static const char *
1562 1.1 christos emit_jp (char prefix, char opcode, const char * args)
1563 1.1 christos {
1564 1.1 christos expressionS addr;
1565 1.1 christos const char *p;
1566 1.1 christos char *q;
1567 1.1 christos int rnum;
1568 1.1 christos
1569 1.1 christos p = parse_exp_not_indexed (args, & addr);
1570 1.1 christos if (addr.X_md)
1571 1.1 christos {
1572 1.1 christos rnum = addr.X_add_number;
1573 1.1 christos if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX)))
1574 1.1 christos {
1575 1.1 christos q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1576 1.1 christos if (rnum & R_INDEX)
1577 1.1 christos *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1578 1.1 christos *q = prefix;
1579 1.1 christos }
1580 1.8 christos else if (addr.X_op == O_register && rnum == REG_C && (ins_ok & INS_Z80N))
1581 1.8 christos {
1582 1.8 christos q = frag_more (2);
1583 1.8 christos *q++ = 0xED;
1584 1.8 christos *q = 0x98;
1585 1.8 christos }
1586 1.1 christos else
1587 1.1 christos ill_op ();
1588 1.1 christos }
1589 1.1 christos else
1590 1.1 christos {
1591 1.1 christos q = frag_more (1);
1592 1.1 christos *q = opcode;
1593 1.1 christos emit_word (& addr);
1594 1.1 christos }
1595 1.1 christos return p;
1596 1.1 christos }
1597 1.1 christos
1598 1.1 christos static const char *
1599 1.1 christos emit_im (char prefix, char opcode, const char * args)
1600 1.1 christos {
1601 1.1 christos expressionS mode;
1602 1.1 christos const char *p;
1603 1.1 christos char *q;
1604 1.1 christos
1605 1.1 christos p = parse_exp (args, & mode);
1606 1.1 christos if (mode.X_md || (mode.X_op != O_constant))
1607 1.1 christos ill_op ();
1608 1.1 christos else
1609 1.1 christos switch (mode.X_add_number)
1610 1.1 christos {
1611 1.1 christos case 1:
1612 1.1 christos case 2:
1613 1.1 christos ++mode.X_add_number;
1614 1.1 christos /* Fall through. */
1615 1.1 christos case 0:
1616 1.1 christos q = frag_more (2);
1617 1.1 christos *q++ = prefix;
1618 1.1 christos *q = opcode + 8*mode.X_add_number;
1619 1.1 christos break;
1620 1.1 christos default:
1621 1.1 christos ill_op ();
1622 1.1 christos }
1623 1.1 christos return p;
1624 1.1 christos }
1625 1.1 christos
1626 1.1 christos static const char *
1627 1.1 christos emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1628 1.1 christos {
1629 1.1 christos expressionS regp;
1630 1.1 christos const char *p;
1631 1.1 christos char *q;
1632 1.1 christos
1633 1.1 christos p = parse_exp (args, & regp);
1634 1.1 christos if ((!regp.X_md)
1635 1.1 christos && (regp.X_op == O_register)
1636 1.1 christos && (regp.X_add_number & R_STACKABLE))
1637 1.1 christos {
1638 1.1 christos int rnum;
1639 1.1 christos
1640 1.1 christos rnum = regp.X_add_number;
1641 1.1 christos if (rnum&R_INDEX)
1642 1.1 christos {
1643 1.1 christos q = frag_more (2);
1644 1.1 christos *q++ = (rnum&R_IX)?0xDD:0xFD;
1645 1.1 christos }
1646 1.1 christos else
1647 1.1 christos q = frag_more (1);
1648 1.1 christos *q = opcode + ((rnum & 3) << 4);
1649 1.1 christos }
1650 1.1 christos else
1651 1.1 christos ill_op ();
1652 1.1 christos
1653 1.1 christos return p;
1654 1.1 christos }
1655 1.1 christos
1656 1.1 christos static const char *
1657 1.8 christos emit_push (char prefix, char opcode, const char * args)
1658 1.8 christos {
1659 1.8 christos expressionS arg;
1660 1.8 christos const char *p;
1661 1.8 christos char *q;
1662 1.8 christos
1663 1.8 christos p = parse_exp (args, & arg);
1664 1.8 christos if (arg.X_op == O_register)
1665 1.8 christos return emit_pop (prefix, opcode, args);
1666 1.8 christos
1667 1.8 christos if (arg.X_md || arg.X_op == O_md1 || !(ins_ok & INS_Z80N))
1668 1.8 christos ill_op ();
1669 1.8 christos
1670 1.8 christos q = frag_more (2);
1671 1.8 christos *q++ = 0xED;
1672 1.8 christos *q = 0x8A;
1673 1.8 christos
1674 1.8 christos q = frag_more (2);
1675 1.8 christos fix_new_exp (frag_now, q - frag_now->fr_literal, 2, &arg, false,
1676 1.8 christos BFD_RELOC_Z80_16_BE);
1677 1.8 christos
1678 1.8 christos return p;
1679 1.8 christos }
1680 1.8 christos
1681 1.8 christos static const char *
1682 1.1 christos emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1683 1.1 christos {
1684 1.1 christos char cc, *q;
1685 1.1 christos const char *p;
1686 1.1 christos
1687 1.1 christos p = parse_cc (args, &cc);
1688 1.1 christos q = frag_more (1);
1689 1.1 christos if (p)
1690 1.1 christos *q = opcode + cc;
1691 1.1 christos else
1692 1.1 christos *q = prefix;
1693 1.1 christos return p ? p : args;
1694 1.1 christos }
1695 1.1 christos
1696 1.1 christos static const char *
1697 1.1 christos emit_adc (char prefix, char opcode, const char * args)
1698 1.1 christos {
1699 1.1 christos expressionS term;
1700 1.1 christos int rnum;
1701 1.1 christos const char *p;
1702 1.1 christos char *q;
1703 1.1 christos
1704 1.1 christos p = parse_exp (args, &term);
1705 1.1 christos if (*p++ != ',')
1706 1.1 christos {
1707 1.3 christos error (_("bad instruction syntax"));
1708 1.1 christos return p;
1709 1.1 christos }
1710 1.1 christos
1711 1.1 christos if ((term.X_md) || (term.X_op != O_register))
1712 1.1 christos ill_op ();
1713 1.1 christos else
1714 1.1 christos switch (term.X_add_number)
1715 1.1 christos {
1716 1.1 christos case REG_A:
1717 1.1 christos p = emit_s (0, prefix, p);
1718 1.1 christos break;
1719 1.1 christos case REG_HL:
1720 1.1 christos p = parse_exp (p, &term);
1721 1.1 christos if ((!term.X_md) && (term.X_op == O_register))
1722 1.1 christos {
1723 1.1 christos rnum = term.X_add_number;
1724 1.1 christos if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1725 1.1 christos {
1726 1.1 christos q = frag_more (2);
1727 1.1 christos *q++ = 0xED;
1728 1.1 christos *q = opcode + ((rnum & 3) << 4);
1729 1.1 christos break;
1730 1.1 christos }
1731 1.1 christos }
1732 1.1 christos /* Fall through. */
1733 1.1 christos default:
1734 1.1 christos ill_op ();
1735 1.1 christos }
1736 1.1 christos return p;
1737 1.1 christos }
1738 1.1 christos
1739 1.1 christos static const char *
1740 1.1 christos emit_add (char prefix, char opcode, const char * args)
1741 1.1 christos {
1742 1.1 christos expressionS term;
1743 1.1 christos int lhs, rhs;
1744 1.1 christos const char *p;
1745 1.1 christos char *q;
1746 1.1 christos
1747 1.1 christos p = parse_exp (args, &term);
1748 1.1 christos if (*p++ != ',')
1749 1.1 christos {
1750 1.3 christos error (_("bad instruction syntax"));
1751 1.1 christos return p;
1752 1.1 christos }
1753 1.1 christos
1754 1.1 christos if ((term.X_md) || (term.X_op != O_register))
1755 1.1 christos ill_op ();
1756 1.1 christos else
1757 1.8 christos switch (term.X_add_number)
1758 1.1 christos {
1759 1.1 christos case REG_A:
1760 1.1 christos p = emit_s (0, prefix, p);
1761 1.1 christos break;
1762 1.8 christos case REG_SP:
1763 1.8 christos p = parse_exp (p, &term);
1764 1.8 christos if (!(ins_ok & INS_GBZ80) || term.X_md || term.X_op == O_register)
1765 1.8 christos ill_op ();
1766 1.8 christos q = frag_more (1);
1767 1.8 christos *q = 0xE8;
1768 1.8 christos emit_byte (&term, BFD_RELOC_Z80_DISP8);
1769 1.8 christos break;
1770 1.8 christos case REG_BC:
1771 1.8 christos case REG_DE:
1772 1.8 christos if (!(ins_ok & INS_Z80N))
1773 1.8 christos {
1774 1.8 christos ill_op ();
1775 1.8 christos break;
1776 1.8 christos }
1777 1.8 christos /* Fall through. */
1778 1.1 christos case REG_HL:
1779 1.8 christos case REG_IX:
1780 1.8 christos case REG_IY:
1781 1.1 christos lhs = term.X_add_number;
1782 1.1 christos p = parse_exp (p, &term);
1783 1.8 christos rhs = term.X_add_number;
1784 1.8 christos if (term.X_md != 0 || term.X_op == O_md1)
1785 1.8 christos ill_op ();
1786 1.8 christos else if ((term.X_op == O_register) && (rhs & R_ARITH) && (rhs == lhs || (rhs & ~R_INDEX) != REG_HL))
1787 1.1 christos {
1788 1.8 christos if (1)
1789 1.1 christos {
1790 1.1 christos q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1791 1.1 christos if (lhs & R_INDEX)
1792 1.1 christos *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1793 1.1 christos *q = opcode + ((rhs & 3) << 4);
1794 1.1 christos break;
1795 1.1 christos }
1796 1.1 christos }
1797 1.8 christos else if (!(lhs & R_INDEX) && (ins_ok & INS_Z80N))
1798 1.8 christos {
1799 1.8 christos if (term.X_op == O_register && rhs == REG_A)
1800 1.8 christos { /* ADD BC/DE/HL,A */
1801 1.8 christos q = frag_more (2);
1802 1.8 christos *q++ = 0xED;
1803 1.8 christos *q = 0x33 - (lhs & 3);
1804 1.8 christos break;
1805 1.8 christos }
1806 1.8 christos else if (term.X_op != O_register && term.X_op != O_md1)
1807 1.8 christos { /* ADD BC/DE/HL,nn */
1808 1.8 christos q = frag_more (2);
1809 1.8 christos *q++ = 0xED;
1810 1.8 christos *q = 0x36 - (lhs & 3);
1811 1.8 christos emit_word (&term);
1812 1.8 christos break;
1813 1.8 christos }
1814 1.8 christos }
1815 1.1 christos /* Fall through. */
1816 1.1 christos default:
1817 1.1 christos ill_op ();
1818 1.1 christos }
1819 1.1 christos return p;
1820 1.1 christos }
1821 1.1 christos
1822 1.1 christos static const char *
1823 1.1 christos emit_bit (char prefix, char opcode, const char * args)
1824 1.1 christos {
1825 1.1 christos expressionS b;
1826 1.1 christos int bn;
1827 1.1 christos const char *p;
1828 1.1 christos
1829 1.1 christos p = parse_exp (args, &b);
1830 1.1 christos if (*p++ != ',')
1831 1.3 christos error (_("bad instruction syntax"));
1832 1.1 christos
1833 1.1 christos bn = b.X_add_number;
1834 1.1 christos if ((!b.X_md)
1835 1.1 christos && (b.X_op == O_constant)
1836 1.1 christos && (0 <= bn)
1837 1.1 christos && (bn < 8))
1838 1.1 christos {
1839 1.1 christos if (opcode == 0x40)
1840 1.1 christos /* Bit : no optional third operand. */
1841 1.1 christos p = emit_m (prefix, opcode + (bn << 3), p);
1842 1.1 christos else
1843 1.1 christos /* Set, res : resulting byte can be copied to register. */
1844 1.7 christos p = emit_mr (prefix, opcode + (bn << 3), p);
1845 1.1 christos }
1846 1.1 christos else
1847 1.1 christos ill_op ();
1848 1.1 christos return p;
1849 1.1 christos }
1850 1.1 christos
1851 1.8 christos /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1852 1.8 christos static const char *
1853 1.8 christos emit_bshft (char prefix, char opcode, const char * args)
1854 1.8 christos {
1855 1.8 christos expressionS r1, r2;
1856 1.8 christos const char *p;
1857 1.8 christos char *q;
1858 1.8 christos
1859 1.8 christos p = parse_exp (args, & r1);
1860 1.8 christos if (*p++ != ',')
1861 1.8 christos error (_("bad instruction syntax"));
1862 1.8 christos p = parse_exp (p, & r2);
1863 1.8 christos if (r1.X_md || r1.X_op != O_register || r1.X_add_number != REG_DE ||
1864 1.8 christos r2.X_md || r2.X_op != O_register || r2.X_add_number != REG_B)
1865 1.8 christos ill_op ();
1866 1.8 christos q = frag_more (2);
1867 1.8 christos *q++ = prefix;
1868 1.8 christos *q = opcode;
1869 1.8 christos return p;
1870 1.8 christos }
1871 1.8 christos
1872 1.1 christos static const char *
1873 1.1 christos emit_jpcc (char prefix, char opcode, const char * args)
1874 1.1 christos {
1875 1.1 christos char cc;
1876 1.1 christos const char *p;
1877 1.1 christos
1878 1.1 christos p = parse_cc (args, & cc);
1879 1.1 christos if (p && *p++ == ',')
1880 1.1 christos p = emit_call (0, opcode + cc, p);
1881 1.1 christos else
1882 1.1 christos p = (prefix == (char)0xC3)
1883 1.1 christos ? emit_jp (0xE9, prefix, args)
1884 1.1 christos : emit_call (0, prefix, args);
1885 1.1 christos return p;
1886 1.1 christos }
1887 1.1 christos
1888 1.1 christos static const char *
1889 1.1 christos emit_jrcc (char prefix, char opcode, const char * args)
1890 1.1 christos {
1891 1.1 christos char cc;
1892 1.1 christos const char *p;
1893 1.1 christos
1894 1.1 christos p = parse_cc (args, &cc);
1895 1.1 christos if (p && *p++ == ',')
1896 1.1 christos {
1897 1.1 christos if (cc > (3 << 3))
1898 1.1 christos error (_("condition code invalid for jr"));
1899 1.1 christos else
1900 1.1 christos p = emit_jr (0, opcode + cc, p);
1901 1.1 christos }
1902 1.1 christos else
1903 1.1 christos p = emit_jr (0, prefix, args);
1904 1.1 christos
1905 1.1 christos return p;
1906 1.1 christos }
1907 1.1 christos
1908 1.1 christos static const char *
1909 1.1 christos emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1910 1.1 christos char opcode_in ATTRIBUTE_UNUSED, const char * args)
1911 1.1 christos {
1912 1.1 christos expressionS op;
1913 1.1 christos const char * p;
1914 1.1 christos char prefix, opcode;
1915 1.1 christos
1916 1.1 christos p = parse_exp_not_indexed (args, &op);
1917 1.1 christos p = skip_space (p);
1918 1.1 christos if (*p++ != ',')
1919 1.1 christos {
1920 1.1 christos error (_("bad instruction syntax"));
1921 1.1 christos return p;
1922 1.1 christos }
1923 1.1 christos
1924 1.1 christos prefix = opcode = 0;
1925 1.1 christos if (op.X_op == O_register)
1926 1.1 christos switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1927 1.1 christos {
1928 1.1 christos case REG_AF:
1929 1.1 christos if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1930 1.1 christos {
1931 1.1 christos /* The scrubber changes '\'' to '`' in this context. */
1932 1.1 christos if (*p == '`')
1933 1.1 christos ++p;
1934 1.1 christos opcode = 0x08;
1935 1.1 christos }
1936 1.1 christos break;
1937 1.1 christos case REG_DE:
1938 1.1 christos if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1939 1.1 christos opcode = 0xEB;
1940 1.1 christos break;
1941 1.1 christos case REG_SP|0x8000:
1942 1.1 christos p = parse_exp (p, & op);
1943 1.1 christos if (op.X_op == O_register
1944 1.1 christos && op.X_md == 0
1945 1.1 christos && (op.X_add_number & ~R_INDEX) == REG_HL)
1946 1.1 christos {
1947 1.1 christos opcode = 0xE3;
1948 1.1 christos if (R_INDEX & op.X_add_number)
1949 1.1 christos prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1950 1.1 christos }
1951 1.1 christos break;
1952 1.1 christos }
1953 1.1 christos if (opcode)
1954 1.1 christos emit_insn (prefix, opcode, p);
1955 1.1 christos else
1956 1.1 christos ill_op ();
1957 1.1 christos
1958 1.1 christos return p;
1959 1.1 christos }
1960 1.1 christos
1961 1.1 christos static const char *
1962 1.1 christos emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1963 1.1 christos const char * args)
1964 1.1 christos {
1965 1.1 christos expressionS reg, port;
1966 1.1 christos const char *p;
1967 1.1 christos char *q;
1968 1.1 christos
1969 1.1 christos p = parse_exp (args, ®);
1970 1.8 christos if (reg.X_md && reg.X_op == O_register && reg.X_add_number == REG_C)
1971 1.8 christos { /* permit instruction in (c) as alias for in f,(c) */
1972 1.8 christos port = reg;
1973 1.8 christos reg.X_md = 0;
1974 1.8 christos reg.X_add_number = REG_F;
1975 1.8 christos }
1976 1.8 christos else
1977 1.1 christos {
1978 1.8 christos if (*p++ != ',')
1979 1.8 christos {
1980 1.8 christos error (_("bad instruction syntax"));
1981 1.8 christos return p;
1982 1.8 christos }
1983 1.8 christos p = parse_exp (p, &port);
1984 1.1 christos }
1985 1.1 christos if (reg.X_md == 0
1986 1.1 christos && reg.X_op == O_register
1987 1.1 christos && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1988 1.1 christos && (port.X_md))
1989 1.1 christos {
1990 1.1 christos if (port.X_op != O_md1 && port.X_op != O_register)
1991 1.1 christos {
1992 1.1 christos if (REG_A == reg.X_add_number)
1993 1.1 christos {
1994 1.1 christos q = frag_more (1);
1995 1.1 christos *q = 0xDB;
1996 1.1 christos emit_byte (&port, BFD_RELOC_8);
1997 1.1 christos }
1998 1.1 christos else
1999 1.1 christos ill_op ();
2000 1.1 christos }
2001 1.1 christos else
2002 1.1 christos {
2003 1.7 christos if (port.X_add_number == REG_C || port.X_add_number == REG_BC)
2004 1.1 christos {
2005 1.7 christos if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
2006 1.7 christos ill_op ();
2007 1.8 christos else if (reg.X_add_number == REG_F && !(ins_ok & (INS_R800|INS_Z80N)))
2008 1.7 christos check_mach (INS_IN_F_C);
2009 1.7 christos q = frag_more (2);
2010 1.7 christos *q++ = 0xED;
2011 1.7 christos *q = 0x40|((reg.X_add_number&7)<<3);
2012 1.1 christos }
2013 1.1 christos else
2014 1.1 christos ill_op ();
2015 1.1 christos }
2016 1.1 christos }
2017 1.1 christos else
2018 1.1 christos ill_op ();
2019 1.1 christos return p;
2020 1.1 christos }
2021 1.1 christos
2022 1.1 christos static const char *
2023 1.7 christos emit_in0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2024 1.7 christos const char * args)
2025 1.7 christos {
2026 1.7 christos expressionS reg, port;
2027 1.7 christos const char *p;
2028 1.7 christos char *q;
2029 1.7 christos
2030 1.7 christos p = parse_exp (args, ®);
2031 1.7 christos if (*p++ != ',')
2032 1.7 christos {
2033 1.7 christos error (_("bad instruction syntax"));
2034 1.7 christos return p;
2035 1.7 christos }
2036 1.7 christos
2037 1.7 christos p = parse_exp (p, &port);
2038 1.7 christos if (reg.X_md == 0
2039 1.7 christos && reg.X_op == O_register
2040 1.7 christos && reg.X_add_number <= 7
2041 1.7 christos && port.X_md
2042 1.7 christos && port.X_op != O_md1
2043 1.7 christos && port.X_op != O_register)
2044 1.7 christos {
2045 1.7 christos q = frag_more (2);
2046 1.7 christos *q++ = 0xED;
2047 1.7 christos *q = 0x00|(reg.X_add_number << 3);
2048 1.7 christos emit_byte (&port, BFD_RELOC_8);
2049 1.7 christos }
2050 1.7 christos else
2051 1.7 christos ill_op ();
2052 1.7 christos return p;
2053 1.7 christos }
2054 1.7 christos
2055 1.7 christos static const char *
2056 1.1 christos emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2057 1.1 christos const char * args)
2058 1.1 christos {
2059 1.1 christos expressionS reg, port;
2060 1.1 christos const char *p;
2061 1.1 christos char *q;
2062 1.1 christos
2063 1.1 christos p = parse_exp (args, & port);
2064 1.1 christos if (*p++ != ',')
2065 1.1 christos {
2066 1.3 christos error (_("bad instruction syntax"));
2067 1.1 christos return p;
2068 1.1 christos }
2069 1.1 christos p = parse_exp (p, ®);
2070 1.1 christos if (!port.X_md)
2071 1.1 christos { ill_op (); return p; }
2072 1.1 christos /* Allow "out (c), 0" as unportable instruction. */
2073 1.1 christos if (reg.X_op == O_constant && reg.X_add_number == 0)
2074 1.1 christos {
2075 1.8 christos if (!(ins_ok & INS_Z80N))
2076 1.8 christos check_mach (INS_OUT_C_0);
2077 1.1 christos reg.X_op = O_register;
2078 1.1 christos reg.X_add_number = 6;
2079 1.1 christos }
2080 1.1 christos if (reg.X_md
2081 1.1 christos || reg.X_op != O_register
2082 1.1 christos || reg.X_add_number > 7)
2083 1.1 christos ill_op ();
2084 1.1 christos else
2085 1.1 christos if (port.X_op != O_register && port.X_op != O_md1)
2086 1.1 christos {
2087 1.1 christos if (REG_A == reg.X_add_number)
2088 1.1 christos {
2089 1.1 christos q = frag_more (1);
2090 1.1 christos *q = 0xD3;
2091 1.1 christos emit_byte (&port, BFD_RELOC_8);
2092 1.1 christos }
2093 1.1 christos else
2094 1.1 christos ill_op ();
2095 1.1 christos }
2096 1.1 christos else
2097 1.1 christos {
2098 1.7 christos if (REG_C == port.X_add_number || port.X_add_number == REG_BC)
2099 1.1 christos {
2100 1.7 christos if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
2101 1.7 christos ill_op ();
2102 1.1 christos q = frag_more (2);
2103 1.1 christos *q++ = 0xED;
2104 1.1 christos *q = 0x41 | (reg.X_add_number << 3);
2105 1.1 christos }
2106 1.1 christos else
2107 1.1 christos ill_op ();
2108 1.1 christos }
2109 1.1 christos return p;
2110 1.1 christos }
2111 1.1 christos
2112 1.1 christos static const char *
2113 1.7 christos emit_out0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2114 1.7 christos const char * args)
2115 1.7 christos {
2116 1.7 christos expressionS reg, port;
2117 1.7 christos const char *p;
2118 1.7 christos char *q;
2119 1.7 christos
2120 1.7 christos p = parse_exp (args, & port);
2121 1.7 christos if (*p++ != ',')
2122 1.7 christos {
2123 1.7 christos error (_("bad instruction syntax"));
2124 1.7 christos return p;
2125 1.7 christos }
2126 1.7 christos p = parse_exp (p, ®);
2127 1.7 christos if (port.X_md != 0
2128 1.7 christos && port.X_op != O_register
2129 1.7 christos && port.X_op != O_md1
2130 1.7 christos && reg.X_md == 0
2131 1.7 christos && reg.X_op == O_register
2132 1.7 christos && reg.X_add_number <= 7)
2133 1.7 christos {
2134 1.7 christos q = frag_more (2);
2135 1.7 christos *q++ = 0xED;
2136 1.7 christos *q = 0x01 | (reg.X_add_number << 3);
2137 1.7 christos emit_byte (&port, BFD_RELOC_8);
2138 1.7 christos }
2139 1.7 christos else
2140 1.7 christos ill_op ();
2141 1.7 christos return p;
2142 1.7 christos }
2143 1.7 christos
2144 1.7 christos static const char *
2145 1.1 christos emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2146 1.1 christos {
2147 1.1 christos expressionS addr;
2148 1.1 christos const char *p;
2149 1.1 christos char *q;
2150 1.1 christos
2151 1.1 christos p = parse_exp_not_indexed (args, &addr);
2152 1.1 christos if (addr.X_op != O_constant)
2153 1.1 christos {
2154 1.1 christos error ("rst needs constant address");
2155 1.1 christos return p;
2156 1.1 christos }
2157 1.1 christos
2158 1.1 christos if (addr.X_add_number & ~(7 << 3))
2159 1.1 christos ill_op ();
2160 1.1 christos else
2161 1.1 christos {
2162 1.1 christos q = frag_more (1);
2163 1.1 christos *q = opcode + (addr.X_add_number & (7 << 3));
2164 1.1 christos }
2165 1.1 christos return p;
2166 1.1 christos }
2167 1.1 christos
2168 1.7 christos /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2169 1.1 christos static void
2170 1.7 christos emit_ld_m_n (expressionS *dst, expressionS *src)
2171 1.1 christos {
2172 1.1 christos char *q;
2173 1.7 christos char prefix;
2174 1.7 christos expressionS dst_offset;
2175 1.1 christos
2176 1.7 christos switch (dst->X_add_number)
2177 1.7 christos {
2178 1.7 christos case REG_HL: prefix = 0x00; break;
2179 1.7 christos case REG_IX: prefix = 0xDD; break;
2180 1.7 christos case REG_IY: prefix = 0xFD; break;
2181 1.7 christos default:
2182 1.7 christos ill_op ();
2183 1.7 christos return;
2184 1.7 christos }
2185 1.7 christos
2186 1.7 christos q = frag_more (prefix ? 2 : 1);
2187 1.7 christos if (prefix)
2188 1.7 christos *q++ = prefix;
2189 1.7 christos *q = 0x36;
2190 1.7 christos if (prefix)
2191 1.1 christos {
2192 1.7 christos dst_offset = *dst;
2193 1.7 christos dst_offset.X_op = O_symbol;
2194 1.7 christos dst_offset.X_add_number = 0;
2195 1.7 christos emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2196 1.7 christos }
2197 1.7 christos emit_byte (src, BFD_RELOC_8);
2198 1.7 christos }
2199 1.7 christos
2200 1.7 christos /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2201 1.7 christos static void
2202 1.7 christos emit_ld_m_r (expressionS *dst, expressionS *src)
2203 1.7 christos {
2204 1.7 christos char *q;
2205 1.7 christos char prefix = 0;
2206 1.7 christos expressionS dst_offset;
2207 1.7 christos
2208 1.7 christos switch (dst->X_op)
2209 1.7 christos {
2210 1.7 christos case O_md1:
2211 1.8 christos if (ins_ok & INS_GBZ80)
2212 1.8 christos { /* LD (HL+),A or LD (HL-),A */
2213 1.8 christos if (src->X_op != O_register || src->X_add_number != REG_A)
2214 1.8 christos break;
2215 1.8 christos *frag_more (1) = (dst->X_add_number == REG_HL) ? 0x22 : 0x32;
2216 1.8 christos return;
2217 1.8 christos }
2218 1.8 christos else
2219 1.8 christos prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
2220 1.7 christos /* Fall through. */
2221 1.7 christos case O_register:
2222 1.7 christos switch (dst->X_add_number)
2223 1.7 christos {
2224 1.7 christos case REG_BC: /* LD (BC),A */
2225 1.7 christos case REG_DE: /* LD (DE),A */
2226 1.7 christos if (src->X_add_number == REG_A)
2227 1.7 christos {
2228 1.7 christos q = frag_more (1);
2229 1.7 christos *q = 0x02 | ((dst->X_add_number & 3) << 4);
2230 1.7 christos return;
2231 1.7 christos }
2232 1.7 christos break;
2233 1.7 christos case REG_IX:
2234 1.7 christos case REG_IY:
2235 1.7 christos case REG_HL: /* LD (HL),r or LD (ii+d),r */
2236 1.7 christos if (src->X_add_number <= 7)
2237 1.7 christos {
2238 1.7 christos q = frag_more (prefix ? 2 : 1);
2239 1.7 christos if (prefix)
2240 1.7 christos *q++ = prefix;
2241 1.7 christos *q = 0x70 | src->X_add_number;
2242 1.7 christos if (prefix)
2243 1.7 christos {
2244 1.7 christos dst_offset = *dst;
2245 1.7 christos dst_offset.X_op = O_symbol;
2246 1.7 christos dst_offset.X_add_number = 0;
2247 1.7 christos emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2248 1.7 christos }
2249 1.7 christos return;
2250 1.7 christos }
2251 1.7 christos break;
2252 1.7 christos default:;
2253 1.7 christos }
2254 1.7 christos break;
2255 1.7 christos default: /* LD (nn),A */
2256 1.7 christos if (src->X_add_number == REG_A)
2257 1.7 christos {
2258 1.7 christos q = frag_more (1);
2259 1.8 christos *q = (ins_ok & INS_GBZ80) ? 0xEA : 0x32;
2260 1.7 christos emit_word (dst);
2261 1.7 christos return;
2262 1.7 christos }
2263 1.7 christos break;
2264 1.7 christos }
2265 1.7 christos ill_op ();
2266 1.7 christos }
2267 1.7 christos
2268 1.7 christos /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2269 1.7 christos static void
2270 1.7 christos emit_ld_m_rr (expressionS *dst, expressionS *src)
2271 1.7 christos {
2272 1.7 christos char *q;
2273 1.7 christos int prefix = 0;
2274 1.7 christos int opcode = 0;
2275 1.7 christos expressionS dst_offset;
2276 1.7 christos
2277 1.7 christos switch (dst->X_op)
2278 1.7 christos {
2279 1.7 christos case O_md1: /* eZ80 instructions LD (ii+d),rr */
2280 1.7 christos case O_register: /* eZ80 instructions LD (HL),rr */
2281 1.7 christos if (!(ins_ok & INS_EZ80)) /* 16-bit indirect load group is supported by eZ80 only */
2282 1.7 christos ill_op ();
2283 1.7 christos switch (dst->X_add_number)
2284 1.7 christos {
2285 1.7 christos case REG_IX: prefix = 0xDD; break;
2286 1.7 christos case REG_IY: prefix = 0xFD; break;
2287 1.7 christos case REG_HL: prefix = 0xED; break;
2288 1.7 christos default:
2289 1.7 christos ill_op ();
2290 1.7 christos }
2291 1.7 christos switch (src->X_add_number)
2292 1.7 christos {
2293 1.7 christos case REG_BC: opcode = 0x0F; break;
2294 1.7 christos case REG_DE: opcode = 0x1F; break;
2295 1.7 christos case REG_HL: opcode = 0x2F; break;
2296 1.7 christos case REG_IX: opcode = (prefix != 0xFD) ? 0x3F : 0x3E; break;
2297 1.7 christos case REG_IY: opcode = (prefix != 0xFD) ? 0x3E : 0x3F; break;
2298 1.7 christos default:
2299 1.7 christos ill_op ();
2300 1.7 christos }
2301 1.7 christos q = frag_more (prefix ? 2 : 1);
2302 1.7 christos *q++ = prefix;
2303 1.7 christos *q = opcode;
2304 1.7 christos if (prefix == 0xFD || prefix == 0xDD)
2305 1.7 christos {
2306 1.7 christos dst_offset = *dst;
2307 1.7 christos dst_offset.X_op = O_symbol;
2308 1.7 christos dst_offset.X_add_number = 0;
2309 1.7 christos emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2310 1.7 christos }
2311 1.7 christos break;
2312 1.7 christos default: /* LD (nn),rr */
2313 1.7 christos if (ins_ok & INS_GBZ80)
2314 1.7 christos {
2315 1.7 christos /* GBZ80 supports only LD (nn),SP */
2316 1.7 christos if (src->X_add_number == REG_SP)
2317 1.7 christos {
2318 1.7 christos prefix = 0x00;
2319 1.7 christos opcode = 0x08;
2320 1.7 christos }
2321 1.7 christos else
2322 1.7 christos ill_op ();
2323 1.7 christos }
2324 1.1 christos else
2325 1.7 christos {
2326 1.7 christos switch (src->X_add_number)
2327 1.7 christos {
2328 1.7 christos case REG_BC: prefix = 0xED; opcode = 0x43; break;
2329 1.7 christos case REG_DE: prefix = 0xED; opcode = 0x53; break;
2330 1.7 christos case REG_HL: prefix = 0x00; opcode = 0x22; break;
2331 1.7 christos case REG_IX: prefix = 0xDD; opcode = 0x22; break;
2332 1.7 christos case REG_IY: prefix = 0xFD; opcode = 0x22; break;
2333 1.7 christos case REG_SP: prefix = 0xED; opcode = 0x73; break;
2334 1.7 christos default:
2335 1.7 christos ill_op ();
2336 1.7 christos }
2337 1.7 christos }
2338 1.7 christos q = frag_more (prefix ? 2 : 1);
2339 1.7 christos if (prefix)
2340 1.7 christos *q++ = prefix;
2341 1.7 christos *q = opcode;
2342 1.7 christos emit_word (dst);
2343 1.7 christos }
2344 1.7 christos }
2345 1.7 christos
2346 1.7 christos static void
2347 1.7 christos emit_ld_r_m (expressionS *dst, expressionS *src)
2348 1.7 christos { /* for 8-bit memory load to register: LD r,(xxx) */
2349 1.7 christos char *q;
2350 1.7 christos char prefix = 0;
2351 1.7 christos char opcode = 0;
2352 1.7 christos expressionS src_offset;
2353 1.7 christos
2354 1.7 christos if (dst->X_add_number == REG_A && src->X_op == O_register)
2355 1.7 christos { /* LD A,(BC) or LD A,(DE) */
2356 1.7 christos switch (src->X_add_number)
2357 1.7 christos {
2358 1.7 christos case REG_BC: opcode = 0x0A; break;
2359 1.7 christos case REG_DE: opcode = 0x1A; break;
2360 1.7 christos default: break;
2361 1.7 christos }
2362 1.7 christos if (opcode != 0)
2363 1.7 christos {
2364 1.7 christos q = frag_more (1);
2365 1.7 christos *q = opcode;
2366 1.7 christos return;
2367 1.7 christos }
2368 1.7 christos }
2369 1.7 christos
2370 1.7 christos switch (src->X_op)
2371 1.7 christos {
2372 1.7 christos case O_md1:
2373 1.8 christos if (ins_ok & INS_GBZ80)
2374 1.8 christos { /* LD A,(HL+) or LD A,(HL-) */
2375 1.8 christos if (dst->X_op == O_register && dst->X_add_number == REG_A)
2376 1.8 christos *frag_more (1) = (src->X_add_number == REG_HL) ? 0x2A : 0x3A;
2377 1.8 christos else
2378 1.8 christos ill_op ();
2379 1.8 christos break;
2380 1.8 christos }
2381 1.8 christos /* Fall through. */
2382 1.7 christos case O_register:
2383 1.7 christos if (dst->X_add_number > 7)
2384 1.7 christos ill_op ();
2385 1.7 christos opcode = 0x46; /* LD B,(HL) */
2386 1.7 christos switch (src->X_add_number)
2387 1.7 christos {
2388 1.7 christos case REG_HL: prefix = 0x00; break;
2389 1.7 christos case REG_IX: prefix = 0xDD; break;
2390 1.7 christos case REG_IY: prefix = 0xFD; break;
2391 1.7 christos default:
2392 1.7 christos ill_op ();
2393 1.7 christos }
2394 1.7 christos q = frag_more (prefix ? 2 : 1);
2395 1.7 christos if (prefix)
2396 1.7 christos *q++ = prefix;
2397 1.7 christos *q = opcode | ((dst->X_add_number & 7) << 3);
2398 1.7 christos if (prefix)
2399 1.7 christos {
2400 1.7 christos src_offset = *src;
2401 1.7 christos src_offset.X_op = O_symbol;
2402 1.7 christos src_offset.X_add_number = 0;
2403 1.7 christos emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2404 1.7 christos }
2405 1.7 christos break;
2406 1.7 christos default: /* LD A,(nn) */
2407 1.7 christos if (dst->X_add_number == REG_A)
2408 1.7 christos {
2409 1.7 christos q = frag_more (1);
2410 1.8 christos *q = (ins_ok & INS_GBZ80) ? 0xFA : 0x3A;
2411 1.7 christos emit_word (src);
2412 1.7 christos }
2413 1.8 christos else
2414 1.8 christos ill_op ();
2415 1.7 christos }
2416 1.7 christos }
2417 1.7 christos
2418 1.7 christos static void
2419 1.7 christos emit_ld_r_n (expressionS *dst, expressionS *src)
2420 1.7 christos { /* for 8-bit immediate value load to register: LD r,n */
2421 1.7 christos char *q;
2422 1.7 christos char prefix = 0;
2423 1.7 christos
2424 1.7 christos switch (dst->X_add_number)
2425 1.7 christos {
2426 1.7 christos case REG_H|R_IX:
2427 1.7 christos case REG_L|R_IX:
2428 1.7 christos prefix = 0xDD;
2429 1.7 christos break;
2430 1.7 christos case REG_H|R_IY:
2431 1.7 christos case REG_L|R_IY:
2432 1.7 christos prefix = 0xFD;
2433 1.7 christos break;
2434 1.7 christos case REG_A:
2435 1.7 christos case REG_B:
2436 1.7 christos case REG_C:
2437 1.7 christos case REG_D:
2438 1.7 christos case REG_E:
2439 1.7 christos case REG_H:
2440 1.7 christos case REG_L:
2441 1.7 christos break;
2442 1.7 christos default:
2443 1.7 christos ill_op ();
2444 1.7 christos }
2445 1.7 christos
2446 1.7 christos q = frag_more (prefix ? 2 : 1);
2447 1.7 christos if (prefix)
2448 1.7 christos {
2449 1.7 christos if (ins_ok & INS_GBZ80)
2450 1.7 christos ill_op ();
2451 1.8 christos else if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
2452 1.7 christos check_mach (INS_IDX_HALF);
2453 1.7 christos *q++ = prefix;
2454 1.1 christos }
2455 1.7 christos *q = 0x06 | ((dst->X_add_number & 7) << 3);
2456 1.7 christos emit_byte (src, BFD_RELOC_8);
2457 1.1 christos }
2458 1.1 christos
2459 1.1 christos static void
2460 1.7 christos emit_ld_r_r (expressionS *dst, expressionS *src)
2461 1.7 christos { /* mostly 8-bit load register from register instructions: LD r,r */
2462 1.7 christos /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2463 1.1 christos char *q;
2464 1.7 christos int prefix = 0;
2465 1.7 christos int opcode = 0;
2466 1.7 christos int ii_halves = 0;
2467 1.1 christos
2468 1.7 christos switch (dst->X_add_number)
2469 1.1 christos {
2470 1.7 christos case REG_SP:
2471 1.7 christos switch (src->X_add_number)
2472 1.7 christos {
2473 1.7 christos case REG_HL: prefix = 0x00; break;
2474 1.7 christos case REG_IX: prefix = 0xDD; break;
2475 1.7 christos case REG_IY: prefix = 0xFD; break;
2476 1.7 christos default:
2477 1.7 christos ill_op ();
2478 1.7 christos }
2479 1.7 christos opcode = 0xF9;
2480 1.7 christos break;
2481 1.7 christos case REG_HL:
2482 1.7 christos if (!(ins_ok & INS_EZ80))
2483 1.7 christos ill_op ();
2484 1.7 christos if (src->X_add_number != REG_I)
2485 1.7 christos ill_op ();
2486 1.7 christos if (cpu_mode < 1)
2487 1.7 christos error (_("ADL mode instruction"));
2488 1.7 christos /* LD HL,I */
2489 1.7 christos prefix = 0xED;
2490 1.7 christos opcode = 0xD7;
2491 1.7 christos break;
2492 1.1 christos case REG_I:
2493 1.7 christos if (src->X_add_number == REG_HL)
2494 1.7 christos {
2495 1.7 christos if (!(ins_ok & INS_EZ80))
2496 1.7 christos ill_op ();
2497 1.7 christos if (cpu_mode < 1)
2498 1.7 christos error (_("ADL mode instruction"));
2499 1.7 christos prefix = 0xED;
2500 1.7 christos opcode = 0xC7;
2501 1.7 christos }
2502 1.7 christos else if (src->X_add_number == REG_A)
2503 1.7 christos {
2504 1.7 christos prefix = 0xED;
2505 1.7 christos opcode = 0x47;
2506 1.7 christos }
2507 1.7 christos else
2508 1.7 christos ill_op ();
2509 1.7 christos break;
2510 1.7 christos case REG_MB:
2511 1.7 christos if (!(ins_ok & INS_EZ80) || (src->X_add_number != REG_A))
2512 1.7 christos ill_op ();
2513 1.7 christos if (cpu_mode < 1)
2514 1.7 christos error (_("ADL mode instruction"));
2515 1.7 christos prefix = 0xED;
2516 1.7 christos opcode = 0x6D;
2517 1.7 christos break;
2518 1.1 christos case REG_R:
2519 1.7 christos if (src->X_add_number == REG_A) /* LD R,A */
2520 1.7 christos {
2521 1.7 christos prefix = 0xED;
2522 1.7 christos opcode = 0x4F;
2523 1.7 christos }
2524 1.1 christos else
2525 1.7 christos ill_op ();
2526 1.1 christos break;
2527 1.1 christos case REG_A:
2528 1.7 christos if (src->X_add_number == REG_I) /* LD A,I */
2529 1.7 christos {
2530 1.7 christos prefix = 0xED;
2531 1.7 christos opcode = 0x57;
2532 1.7 christos break;
2533 1.7 christos }
2534 1.7 christos else if (src->X_add_number == REG_R) /* LD A,R */
2535 1.7 christos {
2536 1.7 christos prefix = 0xED;
2537 1.7 christos opcode = 0x5F;
2538 1.7 christos break;
2539 1.7 christos }
2540 1.7 christos else if (src->X_add_number == REG_MB) /* LD A,MB */
2541 1.7 christos {
2542 1.7 christos if (!(ins_ok & INS_EZ80))
2543 1.7 christos ill_op ();
2544 1.7 christos else
2545 1.7 christos {
2546 1.7 christos if (cpu_mode < 1)
2547 1.7 christos error (_("ADL mode instruction"));
2548 1.7 christos prefix = 0xED;
2549 1.7 christos opcode = 0x6E;
2550 1.7 christos }
2551 1.7 christos break;
2552 1.7 christos }
2553 1.7 christos /* Fall through. */
2554 1.1 christos case REG_B:
2555 1.1 christos case REG_C:
2556 1.1 christos case REG_D:
2557 1.1 christos case REG_E:
2558 1.7 christos case REG_H:
2559 1.7 christos case REG_L:
2560 1.7 christos prefix = 0x00;
2561 1.7 christos break;
2562 1.7 christos case REG_H|R_IX:
2563 1.7 christos case REG_L|R_IX:
2564 1.7 christos prefix = 0xDD;
2565 1.7 christos ii_halves = 1;
2566 1.7 christos break;
2567 1.7 christos case REG_H|R_IY:
2568 1.7 christos case REG_L|R_IY:
2569 1.7 christos prefix = 0xFD;
2570 1.7 christos ii_halves = 1;
2571 1.7 christos break;
2572 1.7 christos default:
2573 1.7 christos ill_op ();
2574 1.7 christos }
2575 1.7 christos
2576 1.7 christos if (opcode == 0)
2577 1.7 christos {
2578 1.7 christos switch (src->X_add_number)
2579 1.7 christos {
2580 1.7 christos case REG_A:
2581 1.7 christos case REG_B:
2582 1.7 christos case REG_C:
2583 1.7 christos case REG_D:
2584 1.7 christos case REG_E:
2585 1.7 christos break;
2586 1.7 christos case REG_H:
2587 1.7 christos case REG_L:
2588 1.7 christos if (prefix != 0)
2589 1.7 christos ill_op (); /* LD iiH/L,H/L are not permitted */
2590 1.7 christos break;
2591 1.7 christos case REG_H|R_IX:
2592 1.7 christos case REG_L|R_IX:
2593 1.7 christos if (prefix == 0xFD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
2594 1.7 christos ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2595 1.7 christos prefix = 0xDD;
2596 1.7 christos ii_halves = 1;
2597 1.7 christos break;
2598 1.7 christos case REG_H|R_IY:
2599 1.7 christos case REG_L|R_IY:
2600 1.7 christos if (prefix == 0xDD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
2601 1.7 christos ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2602 1.7 christos prefix = 0xFD;
2603 1.7 christos ii_halves = 1;
2604 1.7 christos break;
2605 1.7 christos default:
2606 1.7 christos ill_op ();
2607 1.7 christos }
2608 1.7 christos opcode = 0x40 + ((dst->X_add_number & 7) << 3) + (src->X_add_number & 7);
2609 1.7 christos }
2610 1.7 christos if ((ins_ok & INS_GBZ80) && prefix != 0)
2611 1.7 christos ill_op ();
2612 1.8 christos if (ii_halves && !(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
2613 1.7 christos check_mach (INS_IDX_HALF);
2614 1.7 christos if (prefix == 0 && (ins_ok & INS_EZ80))
2615 1.7 christos {
2616 1.7 christos switch (opcode)
2617 1.7 christos {
2618 1.7 christos case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2619 1.7 christos case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2620 1.7 christos case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2621 1.7 christos case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2622 1.7 christos as_warn (_("unsupported instruction, assembled as NOP"));
2623 1.7 christos opcode = 0x00;
2624 1.7 christos break;
2625 1.7 christos default:;
2626 1.7 christos }
2627 1.7 christos }
2628 1.7 christos q = frag_more (prefix ? 2 : 1);
2629 1.7 christos if (prefix)
2630 1.7 christos *q++ = prefix;
2631 1.7 christos *q = opcode;
2632 1.7 christos }
2633 1.7 christos
2634 1.7 christos static void
2635 1.7 christos emit_ld_rr_m (expressionS *dst, expressionS *src)
2636 1.7 christos { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2637 1.7 christos char *q;
2638 1.7 christos int prefix = 0;
2639 1.7 christos int opcode = 0;
2640 1.7 christos expressionS src_offset;
2641 1.7 christos
2642 1.7 christos /* GBZ80 has no support for 16-bit load from memory instructions */
2643 1.7 christos if (ins_ok & INS_GBZ80)
2644 1.7 christos ill_op ();
2645 1.7 christos
2646 1.7 christos prefix = 0xED;
2647 1.7 christos switch (src->X_op)
2648 1.7 christos {
2649 1.7 christos case O_md1: /* LD rr,(ii+d) */
2650 1.7 christos prefix = (src->X_add_number == REG_IX) ? 0xDD : 0xFD;
2651 1.7 christos /* Fall through. */
2652 1.7 christos case O_register: /* LD rr,(HL) */
2653 1.7 christos /* currently only EZ80 has support for 16bit indirect memory load instructions */
2654 1.7 christos if (!(ins_ok & INS_EZ80))
2655 1.7 christos ill_op ();
2656 1.7 christos switch (dst->X_add_number)
2657 1.7 christos {
2658 1.7 christos case REG_BC: opcode = 0x07; break;
2659 1.7 christos case REG_DE: opcode = 0x17; break;
2660 1.7 christos case REG_HL: opcode = 0x27; break;
2661 1.8 christos case REG_IX: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x37 : 0x31; break;
2662 1.8 christos case REG_IY: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x31 : 0x37; break;
2663 1.7 christos default:
2664 1.7 christos ill_op ();
2665 1.7 christos }
2666 1.7 christos q = frag_more (2);
2667 1.7 christos *q++ = prefix;
2668 1.7 christos *q = opcode;
2669 1.7 christos if (prefix != 0xED)
2670 1.7 christos {
2671 1.7 christos src_offset = *src;
2672 1.7 christos src_offset.X_op = O_symbol;
2673 1.7 christos src_offset.X_add_number = 0;
2674 1.7 christos emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2675 1.7 christos }
2676 1.7 christos break;
2677 1.7 christos default: /* LD rr,(nn) */
2678 1.7 christos switch (dst->X_add_number)
2679 1.7 christos {
2680 1.7 christos case REG_BC: prefix = 0xED; opcode = 0x4B; break;
2681 1.7 christos case REG_DE: prefix = 0xED; opcode = 0x5B; break;
2682 1.7 christos case REG_HL: prefix = 0x00; opcode = 0x2A; break;
2683 1.7 christos case REG_SP: prefix = 0xED; opcode = 0x7B; break;
2684 1.7 christos case REG_IX: prefix = 0xDD; opcode = 0x2A; break;
2685 1.7 christos case REG_IY: prefix = 0xFD; opcode = 0x2A; break;
2686 1.7 christos default:
2687 1.7 christos ill_op ();
2688 1.7 christos }
2689 1.7 christos q = frag_more (prefix ? 2 : 1);
2690 1.7 christos if (prefix)
2691 1.7 christos *q++ = prefix;
2692 1.7 christos *q = opcode;
2693 1.7 christos emit_word (src);
2694 1.7 christos }
2695 1.7 christos return;
2696 1.7 christos }
2697 1.7 christos
2698 1.7 christos static void
2699 1.7 christos emit_ld_rr_nn (expressionS *dst, expressionS *src)
2700 1.7 christos { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2701 1.7 christos char *q;
2702 1.7 christos int prefix = 0x00;
2703 1.7 christos int opcode = 0x21; /* LD HL,nn */
2704 1.7 christos switch (dst->X_add_number)
2705 1.7 christos {
2706 1.7 christos case REG_IX:
2707 1.7 christos prefix = 0xDD;
2708 1.7 christos break;
2709 1.7 christos case REG_IY:
2710 1.7 christos prefix = 0xFD;
2711 1.1 christos break;
2712 1.7 christos case REG_HL:
2713 1.7 christos break;
2714 1.7 christos case REG_BC:
2715 1.7 christos case REG_DE:
2716 1.7 christos case REG_SP:
2717 1.7 christos opcode = 0x01 + ((dst->X_add_number & 3) << 4);
2718 1.7 christos break;
2719 1.7 christos default:
2720 1.7 christos ill_op ();
2721 1.7 christos return;
2722 1.7 christos }
2723 1.7 christos if (prefix && (ins_ok & INS_GBZ80))
2724 1.7 christos ill_op ();
2725 1.7 christos q = frag_more (prefix ? 2 : 1);
2726 1.7 christos if (prefix)
2727 1.7 christos *q++ = prefix;
2728 1.7 christos *q = opcode;
2729 1.7 christos emit_word (src);
2730 1.7 christos }
2731 1.7 christos
2732 1.7 christos static const char *
2733 1.7 christos emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
2734 1.7 christos const char * args)
2735 1.7 christos {
2736 1.7 christos expressionS dst, src;
2737 1.7 christos const char *p;
2738 1.7 christos
2739 1.7 christos p = parse_exp (args, & dst);
2740 1.7 christos if (*p++ != ',')
2741 1.7 christos error (_("bad instruction syntax"));
2742 1.7 christos p = parse_exp (p, & src);
2743 1.7 christos
2744 1.7 christos if (dst.X_md)
2745 1.7 christos {
2746 1.7 christos if (src.X_op == O_register)
2747 1.7 christos {
2748 1.7 christos if (src.X_add_number <= 7)
2749 1.7 christos emit_ld_m_r (& dst, & src); /* LD (xxx),r */
2750 1.7 christos else
2751 1.7 christos emit_ld_m_rr (& dst, & src); /* LD (xxx),rr */
2752 1.7 christos }
2753 1.7 christos else
2754 1.7 christos emit_ld_m_n (& dst, & src); /* LD (hl),n or LD (ix/y+r),n */
2755 1.7 christos }
2756 1.7 christos else if (dst.X_op == O_register)
2757 1.7 christos {
2758 1.7 christos if (src.X_md)
2759 1.7 christos {
2760 1.7 christos if (dst.X_add_number <= 7)
2761 1.7 christos emit_ld_r_m (& dst, & src);
2762 1.7 christos else
2763 1.7 christos emit_ld_rr_m (& dst, & src);
2764 1.7 christos }
2765 1.7 christos else if (src.X_op == O_register)
2766 1.7 christos emit_ld_r_r (& dst, & src);
2767 1.7 christos else if ((dst.X_add_number & ~R_INDEX) <= 7)
2768 1.7 christos emit_ld_r_n (& dst, & src);
2769 1.7 christos else
2770 1.7 christos emit_ld_rr_nn (& dst, & src);
2771 1.7 christos }
2772 1.7 christos else
2773 1.7 christos ill_op ();
2774 1.7 christos
2775 1.7 christos return p;
2776 1.7 christos }
2777 1.7 christos
2778 1.7 christos static const char *
2779 1.7 christos emit_lddldi (char prefix, char opcode, const char * args)
2780 1.7 christos {
2781 1.7 christos expressionS dst, src;
2782 1.7 christos const char *p;
2783 1.7 christos char *q;
2784 1.7 christos
2785 1.7 christos if (!(ins_ok & INS_GBZ80))
2786 1.7 christos return emit_insn (prefix, opcode, args);
2787 1.7 christos
2788 1.7 christos p = parse_exp (args, & dst);
2789 1.7 christos if (*p++ != ',')
2790 1.7 christos error (_("bad instruction syntax"));
2791 1.8 christos p = parse_exp (p, & src);
2792 1.7 christos
2793 1.7 christos if (dst.X_op != O_register || src.X_op != O_register)
2794 1.7 christos ill_op ();
2795 1.7 christos
2796 1.7 christos /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2797 1.7 christos opcode = (opcode & 0x08) * 2 + 0x22;
2798 1.7 christos
2799 1.7 christos if (dst.X_md != 0
2800 1.7 christos && dst.X_add_number == REG_HL
2801 1.7 christos && src.X_md == 0
2802 1.7 christos && src.X_add_number == REG_A)
2803 1.7 christos opcode |= 0x00; /* LDx (HL),A */
2804 1.7 christos else if (dst.X_md == 0
2805 1.7 christos && dst.X_add_number == REG_A
2806 1.7 christos && src.X_md != 0
2807 1.7 christos && src.X_add_number == REG_HL)
2808 1.7 christos opcode |= 0x08; /* LDx A,(HL) */
2809 1.7 christos else
2810 1.7 christos ill_op ();
2811 1.7 christos
2812 1.7 christos q = frag_more (1);
2813 1.7 christos *q = opcode;
2814 1.7 christos return p;
2815 1.7 christos }
2816 1.7 christos
2817 1.7 christos static const char *
2818 1.7 christos emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2819 1.7 christos const char * args)
2820 1.7 christos {
2821 1.7 christos expressionS dst, src;
2822 1.7 christos const char *p;
2823 1.7 christos char *q;
2824 1.1 christos
2825 1.7 christos p = parse_exp (args, & dst);
2826 1.7 christos if (*p++ != ',')
2827 1.7 christos {
2828 1.7 christos error (_("bad instruction syntax"));
2829 1.7 christos return p;
2830 1.7 christos }
2831 1.7 christos
2832 1.7 christos p = parse_exp (p, & src);
2833 1.7 christos if (dst.X_md == 0
2834 1.7 christos && dst.X_op == O_register
2835 1.7 christos && dst.X_add_number == REG_A
2836 1.7 christos && src.X_md != 0
2837 1.8 christos && src.X_op != O_md1)
2838 1.7 christos {
2839 1.8 christos if (src.X_op != O_register)
2840 1.8 christos {
2841 1.8 christos q = frag_more (1);
2842 1.8 christos *q = 0xF0;
2843 1.8 christos emit_byte (& src, BFD_RELOC_8);
2844 1.8 christos }
2845 1.8 christos else if (src.X_add_number == REG_C)
2846 1.8 christos *frag_more (1) = 0xF2;
2847 1.8 christos else
2848 1.8 christos ill_op ();
2849 1.7 christos }
2850 1.7 christos else if (dst.X_md != 0
2851 1.7 christos && dst.X_op != O_md1
2852 1.7 christos && src.X_md == 0
2853 1.7 christos && src.X_op == O_register
2854 1.7 christos && src.X_add_number == REG_A)
2855 1.7 christos {
2856 1.7 christos if (dst.X_op == O_register)
2857 1.7 christos {
2858 1.7 christos if (dst.X_add_number == REG_C)
2859 1.7 christos {
2860 1.7 christos q = frag_more (1);
2861 1.7 christos *q = 0xE2;
2862 1.7 christos }
2863 1.7 christos else
2864 1.7 christos ill_op ();
2865 1.7 christos }
2866 1.1 christos else
2867 1.7 christos {
2868 1.7 christos q = frag_more (1);
2869 1.7 christos *q = 0xE0;
2870 1.7 christos emit_byte (& dst, BFD_RELOC_8);
2871 1.7 christos }
2872 1.7 christos }
2873 1.7 christos else
2874 1.7 christos ill_op ();
2875 1.7 christos
2876 1.7 christos return p;
2877 1.7 christos }
2878 1.7 christos
2879 1.7 christos static const char *
2880 1.8 christos emit_ldhl (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2881 1.8 christos {
2882 1.8 christos expressionS dst, src;
2883 1.8 christos const char *p;
2884 1.8 christos char *q;
2885 1.8 christos p = parse_exp (args, & dst);
2886 1.8 christos if (*p++ != ',')
2887 1.8 christos {
2888 1.8 christos error (_("bad instruction syntax"));
2889 1.8 christos return p;
2890 1.8 christos }
2891 1.8 christos
2892 1.8 christos p = parse_exp (p, & src);
2893 1.8 christos if (dst.X_md || dst.X_op != O_register || dst.X_add_number != REG_SP
2894 1.8 christos || src.X_md || src.X_op == O_register || src.X_op == O_md1)
2895 1.8 christos ill_op ();
2896 1.8 christos q = frag_more (1);
2897 1.8 christos *q = opcode;
2898 1.8 christos emit_byte (& src, BFD_RELOC_Z80_DISP8);
2899 1.8 christos return p;
2900 1.8 christos }
2901 1.8 christos
2902 1.8 christos static const char *
2903 1.7 christos parse_lea_pea_args (const char * args, expressionS *op)
2904 1.7 christos {
2905 1.7 christos const char *p;
2906 1.7 christos p = parse_exp (args, op);
2907 1.7 christos if (sdcc_compat && *p == ',' && op->X_op == O_register)
2908 1.7 christos {
2909 1.7 christos expressionS off;
2910 1.7 christos p = parse_exp (p + 1, &off);
2911 1.7 christos op->X_op = O_add;
2912 1.7 christos op->X_add_symbol = make_expr_symbol (&off);
2913 1.7 christos }
2914 1.7 christos return p;
2915 1.7 christos }
2916 1.7 christos
2917 1.7 christos static const char *
2918 1.7 christos emit_lea (char prefix, char opcode, const char * args)
2919 1.7 christos {
2920 1.7 christos expressionS dst, src;
2921 1.7 christos const char *p;
2922 1.7 christos char *q;
2923 1.7 christos int rnum;
2924 1.7 christos
2925 1.7 christos p = parse_exp (args, & dst);
2926 1.7 christos if (dst.X_md != 0 || dst.X_op != O_register)
2927 1.7 christos ill_op ();
2928 1.7 christos
2929 1.7 christos rnum = dst.X_add_number;
2930 1.7 christos switch (rnum)
2931 1.7 christos {
2932 1.7 christos case REG_BC:
2933 1.7 christos case REG_DE:
2934 1.7 christos case REG_HL:
2935 1.7 christos opcode = 0x02 | ((rnum & 0x03) << 4);
2936 1.7 christos break;
2937 1.7 christos case REG_IX:
2938 1.7 christos opcode = 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2939 1.7 christos break;
2940 1.7 christos case REG_IY:
2941 1.7 christos opcode = 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2942 1.7 christos break;
2943 1.7 christos default:
2944 1.7 christos ill_op ();
2945 1.7 christos }
2946 1.7 christos
2947 1.7 christos if (*p++ != ',')
2948 1.7 christos error (_("bad instruction syntax"));
2949 1.7 christos
2950 1.7 christos p = parse_lea_pea_args (p, & src);
2951 1.7 christos if (src.X_md != 0 || src.X_op != O_add /*&& src.X_op != O_register*/)
2952 1.7 christos ill_op ();
2953 1.7 christos
2954 1.7 christos rnum = src.X_add_number;
2955 1.7 christos switch (src.X_op)
2956 1.7 christos {
2957 1.7 christos case O_add:
2958 1.1 christos break;
2959 1.7 christos case O_register: /* permit instructions like LEA rr,IX without displacement specified */
2960 1.7 christos src.X_add_symbol = zero;
2961 1.7 christos break;
2962 1.7 christos default:
2963 1.7 christos ill_op ();
2964 1.7 christos }
2965 1.7 christos
2966 1.7 christos switch (rnum)
2967 1.7 christos {
2968 1.7 christos case REG_IX:
2969 1.7 christos opcode = (opcode == (char)0x33) ? 0x55 : (opcode|0x00);
2970 1.7 christos break;
2971 1.7 christos case REG_IY:
2972 1.7 christos opcode = (opcode == (char)0x32) ? 0x54 : (opcode|0x01);
2973 1.7 christos }
2974 1.7 christos
2975 1.7 christos q = frag_more (2);
2976 1.7 christos *q++ = prefix;
2977 1.7 christos *q = opcode;
2978 1.7 christos
2979 1.7 christos src.X_op = O_symbol;
2980 1.7 christos src.X_add_number = 0;
2981 1.7 christos emit_byte (& src, BFD_RELOC_Z80_DISP8);
2982 1.7 christos
2983 1.7 christos return p;
2984 1.7 christos }
2985 1.7 christos
2986 1.7 christos static const char *
2987 1.7 christos emit_mlt (char prefix, char opcode, const char * args)
2988 1.7 christos {
2989 1.7 christos expressionS arg;
2990 1.7 christos const char *p;
2991 1.7 christos char *q;
2992 1.7 christos
2993 1.7 christos p = parse_exp (args, & arg);
2994 1.7 christos if (arg.X_md != 0 || arg.X_op != O_register || !(arg.X_add_number & R_ARITH))
2995 1.7 christos ill_op ();
2996 1.7 christos
2997 1.7 christos q = frag_more (2);
2998 1.8 christos if (ins_ok & INS_Z80N)
2999 1.8 christos {
3000 1.8 christos if (arg.X_add_number != REG_DE)
3001 1.8 christos ill_op ();
3002 1.8 christos *q++ = 0xED;
3003 1.8 christos *q = 0x30;
3004 1.8 christos }
3005 1.8 christos else
3006 1.8 christos {
3007 1.8 christos *q++ = prefix;
3008 1.8 christos *q = opcode | ((arg.X_add_number & 3) << 4);
3009 1.8 christos }
3010 1.8 christos
3011 1.8 christos return p;
3012 1.8 christos }
3013 1.8 christos
3014 1.8 christos /* MUL D,E (Z80N only) */
3015 1.8 christos static const char *
3016 1.8 christos emit_mul (char prefix, char opcode, const char * args)
3017 1.8 christos {
3018 1.8 christos expressionS r1, r2;
3019 1.8 christos const char *p;
3020 1.8 christos char *q;
3021 1.8 christos
3022 1.8 christos p = parse_exp (args, & r1);
3023 1.8 christos if (*p++ != ',')
3024 1.8 christos error (_("bad instruction syntax"));
3025 1.8 christos p = parse_exp (p, & r2);
3026 1.8 christos
3027 1.8 christos if (r1.X_md != 0 || r1.X_op != O_register || r1.X_add_number != REG_D ||
3028 1.8 christos r2.X_md != 0 || r2.X_op != O_register || r2.X_add_number != REG_E)
3029 1.8 christos ill_op ();
3030 1.8 christos
3031 1.8 christos q = frag_more (2);
3032 1.7 christos *q++ = prefix;
3033 1.8 christos *q = opcode;
3034 1.7 christos
3035 1.7 christos return p;
3036 1.7 christos }
3037 1.7 christos
3038 1.7 christos static const char *
3039 1.8 christos emit_nextreg (char prefix, char opcode ATTRIBUTE_UNUSED, const char * args)
3040 1.8 christos {
3041 1.8 christos expressionS rr, nn;
3042 1.8 christos const char *p;
3043 1.8 christos char *q;
3044 1.8 christos
3045 1.8 christos p = parse_exp (args, & rr);
3046 1.8 christos if (*p++ != ',')
3047 1.8 christos error (_("bad instruction syntax"));
3048 1.8 christos p = parse_exp (p, & nn);
3049 1.8 christos if (rr.X_md != 0 || rr.X_op == O_register || rr.X_op == O_md1 ||
3050 1.8 christos nn.X_md != 0 || nn.X_op == O_md1)
3051 1.8 christos ill_op ();
3052 1.8 christos q = frag_more (2);
3053 1.8 christos *q++ = prefix;
3054 1.8 christos emit_byte (&rr, BFD_RELOC_8);
3055 1.8 christos if (nn.X_op == O_register && nn.X_add_number == REG_A)
3056 1.8 christos *q = 0x92;
3057 1.8 christos else if (nn.X_op != O_register)
3058 1.8 christos {
3059 1.8 christos *q = 0x91;
3060 1.8 christos emit_byte (&nn, BFD_RELOC_8);
3061 1.8 christos }
3062 1.8 christos else
3063 1.8 christos ill_op ();
3064 1.8 christos return p;
3065 1.8 christos }
3066 1.8 christos
3067 1.8 christos static const char *
3068 1.7 christos emit_pea (char prefix, char opcode, const char * args)
3069 1.7 christos {
3070 1.7 christos expressionS arg;
3071 1.7 christos const char *p;
3072 1.7 christos char *q;
3073 1.1 christos
3074 1.7 christos p = parse_lea_pea_args (args, & arg);
3075 1.7 christos if (arg.X_md != 0
3076 1.7 christos || (/*arg.X_op != O_register &&*/ arg.X_op != O_add)
3077 1.7 christos || !(arg.X_add_number & R_INDEX))
3078 1.7 christos ill_op ();
3079 1.7 christos /* PEA ii without displacement is mostly typo,
3080 1.7 christos because there is PUSH instruction which is shorter and faster */
3081 1.7 christos /*if (arg.X_op == O_register)
3082 1.7 christos as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3083 1.7 christos
3084 1.7 christos q = frag_more (2);
3085 1.7 christos *q++ = prefix;
3086 1.7 christos *q = opcode + (arg.X_add_number == REG_IY ? 1 : 0);
3087 1.1 christos
3088 1.7 christos arg.X_op = O_symbol;
3089 1.7 christos arg.X_add_number = 0;
3090 1.7 christos emit_byte (& arg, BFD_RELOC_Z80_DISP8);
3091 1.1 christos
3092 1.7 christos return p;
3093 1.7 christos }
3094 1.1 christos
3095 1.7 christos static const char *
3096 1.7 christos emit_reti (char prefix, char opcode, const char * args)
3097 1.7 christos {
3098 1.7 christos if (ins_ok & INS_GBZ80)
3099 1.7 christos return emit_insn (0x00, 0xD9, args);
3100 1.1 christos
3101 1.7 christos return emit_insn (prefix, opcode, args);
3102 1.1 christos }
3103 1.1 christos
3104 1.1 christos static const char *
3105 1.7 christos emit_tst (char prefix, char opcode, const char *args)
3106 1.1 christos {
3107 1.7 christos expressionS arg_s;
3108 1.1 christos const char *p;
3109 1.1 christos char *q;
3110 1.7 christos int rnum;
3111 1.1 christos
3112 1.7 christos p = parse_exp (args, & arg_s);
3113 1.7 christos if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
3114 1.7 christos {
3115 1.7 christos if (!(ins_ok & INS_EZ80))
3116 1.7 christos ill_op ();
3117 1.7 christos ++p;
3118 1.7 christos p = parse_exp (p, & arg_s);
3119 1.7 christos }
3120 1.1 christos
3121 1.7 christos rnum = arg_s.X_add_number;
3122 1.7 christos switch (arg_s.X_op)
3123 1.1 christos {
3124 1.1 christos case O_md1:
3125 1.7 christos ill_op ();
3126 1.1 christos break;
3127 1.1 christos case O_register:
3128 1.7 christos rnum = arg_s.X_add_number;
3129 1.7 christos if (arg_s.X_md != 0)
3130 1.7 christos {
3131 1.7 christos if (rnum != REG_HL)
3132 1.7 christos ill_op ();
3133 1.7 christos else
3134 1.7 christos rnum = 6;
3135 1.7 christos }
3136 1.7 christos q = frag_more (2);
3137 1.7 christos *q++ = prefix;
3138 1.7 christos *q = opcode | (rnum << 3);
3139 1.1 christos break;
3140 1.1 christos default:
3141 1.7 christos if (arg_s.X_md)
3142 1.7 christos ill_op ();
3143 1.7 christos q = frag_more (2);
3144 1.8 christos if (ins_ok & INS_Z80N)
3145 1.8 christos {
3146 1.8 christos *q++ = 0xED;
3147 1.8 christos *q = 0x27;
3148 1.8 christos }
3149 1.8 christos else
3150 1.8 christos {
3151 1.8 christos *q++ = prefix;
3152 1.8 christos *q = opcode | 0x60;
3153 1.8 christos }
3154 1.7 christos emit_byte (& arg_s, BFD_RELOC_8);
3155 1.1 christos }
3156 1.1 christos return p;
3157 1.1 christos }
3158 1.1 christos
3159 1.7 christos static const char *
3160 1.8 christos emit_insn_n (char prefix, char opcode, const char *args)
3161 1.7 christos {
3162 1.7 christos expressionS arg;
3163 1.7 christos const char *p;
3164 1.7 christos char *q;
3165 1.7 christos
3166 1.7 christos p = parse_exp (args, & arg);
3167 1.7 christos if (arg.X_md || arg.X_op == O_register || arg.X_op == O_md1)
3168 1.7 christos ill_op ();
3169 1.7 christos
3170 1.7 christos q = frag_more (2);
3171 1.7 christos *q++ = prefix;
3172 1.7 christos *q = opcode;
3173 1.7 christos emit_byte (& arg, BFD_RELOC_8);
3174 1.7 christos
3175 1.7 christos return p;
3176 1.7 christos }
3177 1.7 christos
3178 1.1 christos static void
3179 1.1 christos emit_data (int size ATTRIBUTE_UNUSED)
3180 1.1 christos {
3181 1.1 christos const char *p, *q;
3182 1.1 christos char *u, quote;
3183 1.1 christos int cnt;
3184 1.1 christos expressionS exp;
3185 1.1 christos
3186 1.1 christos if (is_it_end_of_statement ())
3187 1.1 christos {
3188 1.1 christos demand_empty_rest_of_line ();
3189 1.1 christos return;
3190 1.1 christos }
3191 1.1 christos p = skip_space (input_line_pointer);
3192 1.1 christos
3193 1.1 christos do
3194 1.1 christos {
3195 1.1 christos if (*p == '\"' || *p == '\'')
3196 1.1 christos {
3197 1.1 christos for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
3198 1.1 christos ;
3199 1.1 christos u = frag_more (cnt);
3200 1.1 christos memcpy (u, q, cnt);
3201 1.1 christos if (!*p)
3202 1.1 christos as_warn (_("unterminated string"));
3203 1.1 christos else
3204 1.1 christos p = skip_space (p+1);
3205 1.1 christos }
3206 1.1 christos else
3207 1.1 christos {
3208 1.1 christos p = parse_exp (p, &exp);
3209 1.1 christos if (exp.X_op == O_md1 || exp.X_op == O_register)
3210 1.1 christos {
3211 1.1 christos ill_op ();
3212 1.1 christos break;
3213 1.1 christos }
3214 1.1 christos if (exp.X_md)
3215 1.1 christos as_warn (_("parentheses ignored"));
3216 1.1 christos emit_byte (&exp, BFD_RELOC_8);
3217 1.1 christos p = skip_space (p);
3218 1.1 christos }
3219 1.1 christos }
3220 1.1 christos while (*p++ == ',') ;
3221 1.1 christos input_line_pointer = (char *)(p-1);
3222 1.1 christos }
3223 1.1 christos
3224 1.7 christos static void
3225 1.7 christos z80_cons (int size)
3226 1.7 christos {
3227 1.7 christos const char *p;
3228 1.7 christos expressionS exp;
3229 1.7 christos
3230 1.7 christos if (is_it_end_of_statement ())
3231 1.7 christos {
3232 1.7 christos demand_empty_rest_of_line ();
3233 1.7 christos return;
3234 1.7 christos }
3235 1.7 christos p = skip_space (input_line_pointer);
3236 1.7 christos
3237 1.7 christos do
3238 1.7 christos {
3239 1.7 christos p = parse_exp (p, &exp);
3240 1.7 christos if (exp.X_op == O_md1 || exp.X_op == O_register)
3241 1.7 christos {
3242 1.7 christos ill_op ();
3243 1.7 christos break;
3244 1.7 christos }
3245 1.7 christos if (exp.X_md)
3246 1.7 christos as_warn (_("parentheses ignored"));
3247 1.7 christos emit_data_val (&exp, size);
3248 1.7 christos p = skip_space (p);
3249 1.7 christos } while (*p++ == ',') ;
3250 1.7 christos input_line_pointer = (char *)(p-1);
3251 1.7 christos }
3252 1.7 christos
3253 1.7 christos /* next functions were commented out because it is difficult to mix
3254 1.7 christos both ADL and Z80 mode instructions within one COFF file:
3255 1.7 christos objdump cannot recognize point of mode switching.
3256 1.7 christos */
3257 1.7 christos static void
3258 1.7 christos set_cpu_mode (int mode)
3259 1.7 christos {
3260 1.7 christos if (ins_ok & INS_EZ80)
3261 1.7 christos cpu_mode = mode;
3262 1.7 christos else
3263 1.7 christos error (_("CPU mode is unsupported by target"));
3264 1.7 christos }
3265 1.7 christos
3266 1.7 christos static void
3267 1.7 christos assume (int arg ATTRIBUTE_UNUSED)
3268 1.7 christos {
3269 1.7 christos char *name;
3270 1.7 christos char c;
3271 1.7 christos int n;
3272 1.7 christos
3273 1.7 christos input_line_pointer = (char*)skip_space (input_line_pointer);
3274 1.7 christos c = get_symbol_name (& name);
3275 1.7 christos if (strncasecmp (name, "ADL", 4) != 0)
3276 1.7 christos {
3277 1.7 christos ill_op ();
3278 1.7 christos return;
3279 1.7 christos }
3280 1.7 christos
3281 1.7 christos restore_line_pointer (c);
3282 1.7 christos input_line_pointer = (char*)skip_space (input_line_pointer);
3283 1.7 christos if (*input_line_pointer++ != '=')
3284 1.7 christos {
3285 1.7 christos error (_("assignment expected"));
3286 1.7 christos return;
3287 1.7 christos }
3288 1.7 christos input_line_pointer = (char*)skip_space (input_line_pointer);
3289 1.7 christos n = get_single_number ();
3290 1.7 christos
3291 1.7 christos set_cpu_mode (n);
3292 1.7 christos }
3293 1.7 christos
3294 1.1 christos static const char *
3295 1.1 christos emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
3296 1.1 christos {
3297 1.1 christos const char *p;
3298 1.1 christos
3299 1.1 christos p = skip_space (args);
3300 1.1 christos if (TOLOWER (*p++) != 'a' || *p++ != ',')
3301 1.1 christos ill_op ();
3302 1.1 christos else
3303 1.1 christos {
3304 1.1 christos char *q, reg;
3305 1.1 christos
3306 1.1 christos reg = TOLOWER (*p++);
3307 1.1 christos switch (reg)
3308 1.1 christos {
3309 1.1 christos case 'b':
3310 1.1 christos case 'c':
3311 1.1 christos case 'd':
3312 1.1 christos case 'e':
3313 1.1 christos check_mach (INS_R800);
3314 1.1 christos if (!*skip_space (p))
3315 1.1 christos {
3316 1.1 christos q = frag_more (2);
3317 1.1 christos *q++ = prefix;
3318 1.1 christos *q = opcode + ((reg - 'b') << 3);
3319 1.1 christos break;
3320 1.1 christos }
3321 1.6 christos /* Fall through. */
3322 1.1 christos default:
3323 1.1 christos ill_op ();
3324 1.1 christos }
3325 1.1 christos }
3326 1.1 christos return p;
3327 1.1 christos }
3328 1.1 christos
3329 1.1 christos static const char *
3330 1.1 christos emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
3331 1.1 christos {
3332 1.1 christos const char *p;
3333 1.1 christos
3334 1.1 christos p = skip_space (args);
3335 1.1 christos if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
3336 1.1 christos ill_op ();
3337 1.1 christos else
3338 1.1 christos {
3339 1.1 christos expressionS reg;
3340 1.1 christos char *q;
3341 1.1 christos
3342 1.1 christos p = parse_exp (p, & reg);
3343 1.1 christos
3344 1.1 christos if ((!reg.X_md) && reg.X_op == O_register)
3345 1.1 christos switch (reg.X_add_number)
3346 1.1 christos {
3347 1.1 christos case REG_BC:
3348 1.1 christos case REG_SP:
3349 1.1 christos check_mach (INS_R800);
3350 1.1 christos q = frag_more (2);
3351 1.1 christos *q++ = prefix;
3352 1.1 christos *q = opcode + ((reg.X_add_number & 3) << 4);
3353 1.1 christos break;
3354 1.1 christos default:
3355 1.1 christos ill_op ();
3356 1.1 christos }
3357 1.1 christos }
3358 1.1 christos return p;
3359 1.1 christos }
3360 1.1 christos
3361 1.7 christos static int
3362 1.7 christos assemble_suffix (const char **suffix)
3363 1.7 christos {
3364 1.7 christos static
3365 1.7 christos const char sf[8][4] =
3366 1.7 christos {
3367 1.7 christos "il",
3368 1.7 christos "is",
3369 1.7 christos "l",
3370 1.7 christos "lil",
3371 1.7 christos "lis",
3372 1.7 christos "s",
3373 1.7 christos "sil",
3374 1.7 christos "sis"
3375 1.7 christos };
3376 1.7 christos const char *p;
3377 1.7 christos const char (*t)[4];
3378 1.7 christos char sbuf[4];
3379 1.7 christos int i;
3380 1.7 christos
3381 1.7 christos p = *suffix;
3382 1.7 christos if (*p++ != '.')
3383 1.7 christos return 0;
3384 1.7 christos
3385 1.7 christos for (i = 0; (i < 3) && (ISALPHA (*p)); i++)
3386 1.7 christos sbuf[i] = TOLOWER (*p++);
3387 1.7 christos if (*p && !ISSPACE (*p))
3388 1.7 christos return 0;
3389 1.7 christos *suffix = p;
3390 1.7 christos sbuf[i] = 0;
3391 1.7 christos
3392 1.7 christos t = bsearch (sbuf, sf, ARRAY_SIZE (sf), sizeof (sf[0]), (int(*)(const void*, const void*)) strcmp);
3393 1.7 christos if (t == NULL)
3394 1.7 christos return 0;
3395 1.7 christos i = t - sf;
3396 1.7 christos switch (i)
3397 1.7 christos {
3398 1.7 christos case 0: /* IL */
3399 1.7 christos i = cpu_mode ? 0x5B : 0x52;
3400 1.7 christos break;
3401 1.7 christos case 1: /* IS */
3402 1.7 christos i = cpu_mode ? 0x49 : 0x40;
3403 1.7 christos break;
3404 1.7 christos case 2: /* L */
3405 1.7 christos i = cpu_mode ? 0x5B : 0x49;
3406 1.7 christos break;
3407 1.7 christos case 3: /* LIL */
3408 1.7 christos i = 0x5B;
3409 1.7 christos break;
3410 1.7 christos case 4: /* LIS */
3411 1.7 christos i = 0x49;
3412 1.7 christos break;
3413 1.7 christos case 5: /* S */
3414 1.7 christos i = cpu_mode ? 0x52 : 0x40;
3415 1.7 christos break;
3416 1.7 christos case 6: /* SIL */
3417 1.7 christos i = 0x52;
3418 1.7 christos break;
3419 1.7 christos case 7: /* SIS */
3420 1.7 christos i = 0x40;
3421 1.7 christos break;
3422 1.7 christos }
3423 1.7 christos *frag_more (1) = (char)i;
3424 1.7 christos switch (i)
3425 1.7 christos {
3426 1.7 christos case 0x40: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IS; break;
3427 1.7 christos case 0x49: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IS; break;
3428 1.7 christos case 0x52: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IL; break;
3429 1.7 christos case 0x5B: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IL; break;
3430 1.7 christos }
3431 1.7 christos return 1;
3432 1.7 christos }
3433 1.7 christos
3434 1.7 christos static void
3435 1.7 christos psect (int arg)
3436 1.7 christos {
3437 1.7 christos #if defined(OBJ_ELF)
3438 1.7 christos return obj_elf_section (arg);
3439 1.7 christos #elif defined(OBJ_COFF)
3440 1.7 christos return obj_coff_section (arg);
3441 1.7 christos #else
3442 1.7 christos #error Unknown object format
3443 1.7 christos #endif
3444 1.7 christos }
3445 1.7 christos
3446 1.7 christos static void
3447 1.7 christos set_inss (int inss)
3448 1.7 christos {
3449 1.7 christos int old_ins;
3450 1.7 christos
3451 1.7 christos if (!sdcc_compat)
3452 1.7 christos as_fatal (_("Invalid directive"));
3453 1.7 christos
3454 1.7 christos old_ins = ins_ok;
3455 1.7 christos ins_ok &= INS_MARCH_MASK;
3456 1.7 christos ins_ok |= inss;
3457 1.7 christos if (old_ins != ins_ok)
3458 1.7 christos cpu_mode = 0;
3459 1.7 christos }
3460 1.7 christos
3461 1.7 christos static void
3462 1.7 christos ignore (int arg ATTRIBUTE_UNUSED)
3463 1.7 christos {
3464 1.7 christos ignore_rest_of_line ();
3465 1.7 christos }
3466 1.7 christos
3467 1.7 christos static void
3468 1.7 christos area (int arg)
3469 1.7 christos {
3470 1.7 christos char *p;
3471 1.7 christos if (!sdcc_compat)
3472 1.7 christos as_fatal (_("Invalid directive"));
3473 1.7 christos for (p = input_line_pointer; *p && *p != '(' && *p != '\n'; p++)
3474 1.7 christos ;
3475 1.7 christos if (*p == '(')
3476 1.7 christos {
3477 1.7 christos *p = '\n';
3478 1.7 christos psect (arg);
3479 1.7 christos *p++ = '(';
3480 1.7 christos ignore_rest_of_line ();
3481 1.7 christos }
3482 1.7 christos else
3483 1.7 christos psect (arg);
3484 1.7 christos }
3485 1.7 christos
3486 1.1 christos /* Port specific pseudo ops. */
3487 1.1 christos const pseudo_typeS md_pseudo_table[] =
3488 1.1 christos {
3489 1.7 christos { ".area", area, 0},
3490 1.7 christos { ".assume", assume, 0},
3491 1.7 christos { ".ez80", set_inss, INS_EZ80},
3492 1.7 christos { ".gbz80", set_inss, INS_GBZ80},
3493 1.7 christos { ".module", ignore, 0},
3494 1.7 christos { ".optsdcc", ignore, 0},
3495 1.7 christos { ".r800", set_inss, INS_R800},
3496 1.7 christos { ".set", s_set, 0},
3497 1.7 christos { ".z180", set_inss, INS_Z180},
3498 1.8 christos { ".hd64", set_inss, INS_Z180},
3499 1.7 christos { ".z80", set_inss, INS_Z80},
3500 1.8 christos { ".z80n", set_inss, INS_Z80N},
3501 1.1 christos { "db" , emit_data, 1},
3502 1.7 christos { "d24", z80_cons, 3},
3503 1.7 christos { "d32", z80_cons, 4},
3504 1.7 christos { "def24", z80_cons, 3},
3505 1.7 christos { "def32", z80_cons, 4},
3506 1.3 christos { "defb", emit_data, 1},
3507 1.7 christos { "defm", emit_data, 1},
3508 1.1 christos { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
3509 1.7 christos { "defw", z80_cons, 2},
3510 1.1 christos { "ds", s_space, 1}, /* Fill with bytes rather than words. */
3511 1.7 christos { "dw", z80_cons, 2},
3512 1.7 christos { "psect", psect, 0}, /* TODO: Translate attributes. */
3513 1.1 christos { "set", 0, 0}, /* Real instruction on z80. */
3514 1.8 christos { "xdef", s_globl, 0}, /* Synonym for .GLOBAL */
3515 1.8 christos { "xref", s_ignore, 0}, /* Synonym for .EXTERN */
3516 1.1 christos { NULL, 0, 0 }
3517 1.1 christos } ;
3518 1.1 christos
3519 1.1 christos static table_t instab[] =
3520 1.1 christos {
3521 1.7 christos { "adc", 0x88, 0x4A, emit_adc, INS_ALL },
3522 1.7 christos { "add", 0x80, 0x09, emit_add, INS_ALL },
3523 1.7 christos { "and", 0x00, 0xA0, emit_s, INS_ALL },
3524 1.7 christos { "bit", 0xCB, 0x40, emit_bit, INS_ALL },
3525 1.8 christos { "brlc", 0xED, 0x2C, emit_bshft,INS_Z80N },
3526 1.8 christos { "bsla", 0xED, 0x28, emit_bshft,INS_Z80N },
3527 1.8 christos { "bsra", 0xED, 0x29, emit_bshft,INS_Z80N },
3528 1.8 christos { "bsrf", 0xED, 0x2B, emit_bshft,INS_Z80N },
3529 1.8 christos { "bsrl", 0xED, 0x2A, emit_bshft,INS_Z80N },
3530 1.7 christos { "call", 0xCD, 0xC4, emit_jpcc, INS_ALL },
3531 1.7 christos { "ccf", 0x00, 0x3F, emit_insn, INS_ALL },
3532 1.7 christos { "cp", 0x00, 0xB8, emit_s, INS_ALL },
3533 1.7 christos { "cpd", 0xED, 0xA9, emit_insn, INS_NOT_GBZ80 },
3534 1.7 christos { "cpdr", 0xED, 0xB9, emit_insn, INS_NOT_GBZ80 },
3535 1.7 christos { "cpi", 0xED, 0xA1, emit_insn, INS_NOT_GBZ80 },
3536 1.7 christos { "cpir", 0xED, 0xB1, emit_insn, INS_NOT_GBZ80 },
3537 1.7 christos { "cpl", 0x00, 0x2F, emit_insn, INS_ALL },
3538 1.7 christos { "daa", 0x00, 0x27, emit_insn, INS_ALL },
3539 1.7 christos { "dec", 0x0B, 0x05, emit_incdec,INS_ALL },
3540 1.7 christos { "di", 0x00, 0xF3, emit_insn, INS_ALL },
3541 1.7 christos { "djnz", 0x00, 0x10, emit_jr, INS_NOT_GBZ80 },
3542 1.7 christos { "ei", 0x00, 0xFB, emit_insn, INS_ALL },
3543 1.7 christos { "ex", 0x00, 0x00, emit_ex, INS_NOT_GBZ80 },
3544 1.7 christos { "exx", 0x00, 0xD9, emit_insn, INS_NOT_GBZ80 },
3545 1.7 christos { "halt", 0x00, 0x76, emit_insn, INS_ALL },
3546 1.7 christos { "im", 0xED, 0x46, emit_im, INS_NOT_GBZ80 },
3547 1.7 christos { "in", 0x00, 0x00, emit_in, INS_NOT_GBZ80 },
3548 1.7 christos { "in0", 0xED, 0x00, emit_in0, INS_Z180|INS_EZ80 },
3549 1.7 christos { "inc", 0x03, 0x04, emit_incdec,INS_ALL },
3550 1.7 christos { "ind", 0xED, 0xAA, emit_insn, INS_NOT_GBZ80 },
3551 1.7 christos { "ind2", 0xED, 0x8C, emit_insn, INS_EZ80 },
3552 1.7 christos { "ind2r",0xED, 0x9C, emit_insn, INS_EZ80 },
3553 1.7 christos { "indm", 0xED, 0x8A, emit_insn, INS_EZ80 },
3554 1.7 christos { "indmr",0xED, 0x9A, emit_insn, INS_EZ80 },
3555 1.7 christos { "indr", 0xED, 0xBA, emit_insn, INS_NOT_GBZ80 },
3556 1.7 christos { "indrx",0xED, 0xCA, emit_insn, INS_EZ80 },
3557 1.7 christos { "ini", 0xED, 0xA2, emit_insn, INS_NOT_GBZ80 },
3558 1.7 christos { "ini2", 0xED, 0x84, emit_insn, INS_EZ80 },
3559 1.7 christos { "ini2r",0xED, 0x94, emit_insn, INS_EZ80 },
3560 1.7 christos { "inim", 0xED, 0x82, emit_insn, INS_EZ80 },
3561 1.7 christos { "inimr",0xED, 0x92, emit_insn, INS_EZ80 },
3562 1.7 christos { "inir", 0xED, 0xB2, emit_insn, INS_NOT_GBZ80 },
3563 1.7 christos { "inirx",0xED, 0xC2, emit_insn, INS_EZ80 },
3564 1.7 christos { "jp", 0xC3, 0xC2, emit_jpcc, INS_ALL },
3565 1.7 christos { "jr", 0x18, 0x20, emit_jrcc, INS_ALL },
3566 1.7 christos { "ld", 0x00, 0x00, emit_ld, INS_ALL },
3567 1.7 christos { "ldd", 0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3568 1.7 christos { "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 },
3569 1.8 christos { "lddrx",0xED, 0xBC, emit_insn, INS_Z80N },
3570 1.8 christos { "lddx", 0xED, 0xAC, emit_insn, INS_Z80N },
3571 1.7 christos { "ldh", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
3572 1.8 christos { "ldhl", 0x00, 0xF8, emit_ldhl, INS_GBZ80 },
3573 1.7 christos { "ldi", 0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3574 1.7 christos { "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 },
3575 1.8 christos { "ldirx",0xED, 0xB4, emit_insn, INS_Z80N },
3576 1.8 christos { "ldix", 0xED, 0xA4, emit_insn, INS_Z80N },
3577 1.8 christos { "ldpirx",0xED,0xB7, emit_insn, INS_Z80N },
3578 1.8 christos { "ldws", 0xED, 0xA5, emit_insn, INS_Z80N },
3579 1.7 christos { "lea", 0xED, 0x02, emit_lea, INS_EZ80 },
3580 1.8 christos { "mirror",0xED,0x24, emit_insn, INS_Z80N },
3581 1.8 christos { "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80|INS_Z80N },
3582 1.8 christos { "mul", 0xED, 0x30, emit_mul, INS_Z80N },
3583 1.7 christos { "mulub",0xED, 0xC5, emit_mulub,INS_R800 },
3584 1.7 christos { "muluw",0xED, 0xC3, emit_muluw,INS_R800 },
3585 1.8 christos { "neg", 0xED, 0x44, emit_insn, INS_NOT_GBZ80 },
3586 1.8 christos { "nextreg",0xED,0x91,emit_nextreg,INS_Z80N },
3587 1.7 christos { "nop", 0x00, 0x00, emit_insn, INS_ALL },
3588 1.7 christos { "or", 0x00, 0xB0, emit_s, INS_ALL },
3589 1.7 christos { "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 },
3590 1.7 christos { "otdm", 0xED, 0x8B, emit_insn, INS_Z180|INS_EZ80 },
3591 1.7 christos { "otdmr",0xED, 0x9B, emit_insn, INS_Z180|INS_EZ80 },
3592 1.7 christos { "otdr", 0xED, 0xBB, emit_insn, INS_NOT_GBZ80 },
3593 1.7 christos { "otdrx",0xED, 0xCB, emit_insn, INS_EZ80 },
3594 1.7 christos { "oti2r",0xED, 0xB4, emit_insn, INS_EZ80 },
3595 1.7 christos { "otim", 0xED, 0x83, emit_insn, INS_Z180|INS_EZ80 },
3596 1.7 christos { "otimr",0xED, 0x93, emit_insn, INS_Z180|INS_EZ80 },
3597 1.7 christos { "otir", 0xED, 0xB3, emit_insn, INS_NOT_GBZ80 },
3598 1.7 christos { "otirx",0xED, 0xC3, emit_insn, INS_EZ80 },
3599 1.7 christos { "out", 0x00, 0x00, emit_out, INS_NOT_GBZ80 },
3600 1.7 christos { "out0", 0xED, 0x01, emit_out0, INS_Z180|INS_EZ80 },
3601 1.7 christos { "outd", 0xED, 0xAB, emit_insn, INS_NOT_GBZ80 },
3602 1.7 christos { "outd2",0xED, 0xAC, emit_insn, INS_EZ80 },
3603 1.7 christos { "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 },
3604 1.7 christos { "outi2",0xED, 0xA4, emit_insn, INS_EZ80 },
3605 1.8 christos { "outinb",0xED,0x90, emit_insn, INS_Z80N },
3606 1.7 christos { "pea", 0xED, 0x65, emit_pea, INS_EZ80 },
3607 1.8 christos { "pixelad",0xED,0x94,emit_insn, INS_Z80N },
3608 1.8 christos { "pixeldn",0xED,0x93,emit_insn, INS_Z80N },
3609 1.7 christos { "pop", 0x00, 0xC1, emit_pop, INS_ALL },
3610 1.8 christos { "push", 0x00, 0xC5, emit_push, INS_ALL },
3611 1.7 christos { "res", 0xCB, 0x80, emit_bit, INS_ALL },
3612 1.7 christos { "ret", 0xC9, 0xC0, emit_retcc,INS_ALL },
3613 1.7 christos { "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/
3614 1.7 christos { "retn", 0xED, 0x45, emit_insn, INS_NOT_GBZ80 },
3615 1.7 christos { "rl", 0xCB, 0x10, emit_mr, INS_ALL },
3616 1.7 christos { "rla", 0x00, 0x17, emit_insn, INS_ALL },
3617 1.7 christos { "rlc", 0xCB, 0x00, emit_mr, INS_ALL },
3618 1.7 christos { "rlca", 0x00, 0x07, emit_insn, INS_ALL },
3619 1.7 christos { "rld", 0xED, 0x6F, emit_insn, INS_NOT_GBZ80 },
3620 1.7 christos { "rr", 0xCB, 0x18, emit_mr, INS_ALL },
3621 1.7 christos { "rra", 0x00, 0x1F, emit_insn, INS_ALL },
3622 1.7 christos { "rrc", 0xCB, 0x08, emit_mr, INS_ALL },
3623 1.7 christos { "rrca", 0x00, 0x0F, emit_insn, INS_ALL },
3624 1.7 christos { "rrd", 0xED, 0x67, emit_insn, INS_NOT_GBZ80 },
3625 1.7 christos { "rsmix",0xED, 0x7E, emit_insn, INS_EZ80 },
3626 1.7 christos { "rst", 0x00, 0xC7, emit_rst, INS_ALL },
3627 1.7 christos { "sbc", 0x98, 0x42, emit_adc, INS_ALL },
3628 1.7 christos { "scf", 0x00, 0x37, emit_insn, INS_ALL },
3629 1.7 christos { "set", 0xCB, 0xC0, emit_bit, INS_ALL },
3630 1.8 christos { "setae",0xED, 0x95, emit_insn, INS_Z80N },
3631 1.8 christos { "sl1", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3632 1.7 christos { "sla", 0xCB, 0x20, emit_mr, INS_ALL },
3633 1.8 christos { "sli", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3634 1.8 christos { "sll", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3635 1.7 christos { "slp", 0xED, 0x76, emit_insn, INS_Z180|INS_EZ80 },
3636 1.7 christos { "sra", 0xCB, 0x28, emit_mr, INS_ALL },
3637 1.7 christos { "srl", 0xCB, 0x38, emit_mr, INS_ALL },
3638 1.7 christos { "stmix",0xED, 0x7D, emit_insn, INS_EZ80 },
3639 1.7 christos { "stop", 0x00, 0x10, emit_insn, INS_GBZ80 },
3640 1.8 christos { "sub", 0x00, 0x90, emit_sub, INS_ALL },
3641 1.8 christos { "swap", 0xCB, 0x30, emit_swap, INS_GBZ80|INS_Z80N },
3642 1.8 christos { "swapnib",0xED,0x23,emit_insn, INS_Z80N },
3643 1.8 christos { "test", 0xED, 0x27, emit_insn_n, INS_Z80N },
3644 1.8 christos { "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80|INS_Z80N },
3645 1.8 christos { "tstio",0xED, 0x74, emit_insn_n,INS_Z180|INS_EZ80 },
3646 1.7 christos { "xor", 0x00, 0xA8, emit_s, INS_ALL },
3647 1.1 christos } ;
3648 1.1 christos
3649 1.1 christos void
3650 1.7 christos md_assemble (char *str)
3651 1.1 christos {
3652 1.1 christos const char *p;
3653 1.1 christos char * old_ptr;
3654 1.1 christos int i;
3655 1.1 christos table_t *insp;
3656 1.1 christos
3657 1.1 christos err_flag = 0;
3658 1.7 christos inst_mode = cpu_mode ? (INST_MODE_L | INST_MODE_IL) : (INST_MODE_S | INST_MODE_IS);
3659 1.1 christos old_ptr = input_line_pointer;
3660 1.1 christos p = skip_space (str);
3661 1.7 christos for (i = 0; (i < BUFLEN) && (ISALPHA (*p) || ISDIGIT (*p));)
3662 1.1 christos buf[i++] = TOLOWER (*p++);
3663 1.1 christos
3664 1.1 christos if (i == BUFLEN)
3665 1.1 christos {
3666 1.1 christos buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */
3667 1.1 christos buf[BUFLEN-1] = 0;
3668 1.1 christos as_bad (_("Unknown instruction '%s'"), buf);
3669 1.1 christos }
3670 1.3 christos else
3671 1.1 christos {
3672 1.7 christos dwarf2_emit_insn (0);
3673 1.7 christos if ((*p) && (!ISSPACE (*p)))
3674 1.7 christos {
3675 1.7 christos if (*p != '.' || !(ins_ok & INS_EZ80) || !assemble_suffix (&p))
3676 1.7 christos {
3677 1.7 christos as_bad (_("syntax error"));
3678 1.7 christos goto end;
3679 1.7 christos }
3680 1.7 christos }
3681 1.1 christos buf[i] = 0;
3682 1.1 christos p = skip_space (p);
3683 1.1 christos key = buf;
3684 1.3 christos
3685 1.1 christos insp = bsearch (&key, instab, ARRAY_SIZE (instab),
3686 1.1 christos sizeof (instab[0]), key_cmp);
3687 1.7 christos if (!insp || (insp->inss && !(insp->inss & ins_ok)))
3688 1.8 christos {
3689 1.8 christos *frag_more (1) = 0;
3690 1.8 christos as_bad (_("Unknown instruction `%s'"), buf);
3691 1.8 christos }
3692 1.1 christos else
3693 1.1 christos {
3694 1.1 christos p = insp->fp (insp->prefix, insp->opcode, p);
3695 1.1 christos p = skip_space (p);
3696 1.8 christos if ((!err_flag) && *p)
3697 1.8 christos as_bad (_("junk at end of line, "
3698 1.8 christos "first unrecognized character is `%c'"), *p);
3699 1.1 christos }
3700 1.1 christos }
3701 1.8 christos end:
3702 1.1 christos input_line_pointer = old_ptr;
3703 1.1 christos }
3704 1.1 christos
3705 1.8 christos static int
3706 1.8 christos signed_overflow (signed long value, unsigned bitsize)
3707 1.8 christos {
3708 1.8 christos signed long max = (signed long) ((1UL << (bitsize - 1)) - 1);
3709 1.8 christos return value < -max - 1 || value > max;
3710 1.8 christos }
3711 1.8 christos
3712 1.8 christos static int
3713 1.8 christos unsigned_overflow (unsigned long value, unsigned bitsize)
3714 1.8 christos {
3715 1.8 christos return value >> (bitsize - 1) >> 1 != 0;
3716 1.8 christos }
3717 1.8 christos
3718 1.8 christos static int
3719 1.8 christos is_overflow (long value, unsigned bitsize)
3720 1.8 christos {
3721 1.8 christos if (value < 0)
3722 1.8 christos return signed_overflow (value, bitsize);
3723 1.8 christos return unsigned_overflow ((unsigned long)value, bitsize);
3724 1.8 christos }
3725 1.8 christos
3726 1.1 christos void
3727 1.8 christos md_apply_fix (fixS * fixP, valueT* valP, segT seg)
3728 1.1 christos {
3729 1.8 christos long val = *valP;
3730 1.1 christos char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
3731 1.1 christos
3732 1.8 christos if (fixP->fx_addsy == NULL)
3733 1.8 christos fixP->fx_done = 1;
3734 1.8 christos else if (fixP->fx_pcrel)
3735 1.8 christos {
3736 1.8 christos segT s = S_GET_SEGMENT (fixP->fx_addsy);
3737 1.8 christos if (s == seg || s == absolute_section)
3738 1.8 christos {
3739 1.8 christos val += S_GET_VALUE (fixP->fx_addsy);
3740 1.8 christos fixP->fx_done = 1;
3741 1.8 christos }
3742 1.8 christos }
3743 1.8 christos
3744 1.1 christos switch (fixP->fx_r_type)
3745 1.1 christos {
3746 1.1 christos case BFD_RELOC_8_PCREL:
3747 1.8 christos case BFD_RELOC_Z80_DISP8:
3748 1.8 christos case BFD_RELOC_8:
3749 1.8 christos case BFD_RELOC_16:
3750 1.8 christos case BFD_RELOC_24:
3751 1.8 christos case BFD_RELOC_32:
3752 1.8 christos case BFD_RELOC_Z80_16_BE:
3753 1.8 christos fixP->fx_no_overflow = 0;
3754 1.8 christos break;
3755 1.8 christos default:
3756 1.8 christos fixP->fx_no_overflow = 1;
3757 1.1 christos break;
3758 1.8 christos }
3759 1.1 christos
3760 1.8 christos switch (fixP->fx_r_type)
3761 1.8 christos {
3762 1.8 christos case BFD_RELOC_8_PCREL:
3763 1.1 christos case BFD_RELOC_Z80_DISP8:
3764 1.8 christos if (fixP->fx_done && signed_overflow (val, 8))
3765 1.8 christos as_bad_where (fixP->fx_file, fixP->fx_line,
3766 1.8 christos _("8-bit signed offset out of range (%+ld)"), val);
3767 1.8 christos *p_lit++ = val;
3768 1.1 christos break;
3769 1.1 christos
3770 1.7 christos case BFD_RELOC_Z80_BYTE0:
3771 1.7 christos *p_lit++ = val;
3772 1.7 christos break;
3773 1.7 christos
3774 1.7 christos case BFD_RELOC_Z80_BYTE1:
3775 1.7 christos *p_lit++ = (val >> 8);
3776 1.7 christos break;
3777 1.7 christos
3778 1.7 christos case BFD_RELOC_Z80_BYTE2:
3779 1.7 christos *p_lit++ = (val >> 16);
3780 1.7 christos break;
3781 1.7 christos
3782 1.7 christos case BFD_RELOC_Z80_BYTE3:
3783 1.7 christos *p_lit++ = (val >> 24);
3784 1.7 christos break;
3785 1.7 christos
3786 1.1 christos case BFD_RELOC_8:
3787 1.8 christos if (fixP->fx_done && is_overflow(val, 8))
3788 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3789 1.8 christos _("8-bit overflow (%+ld)"), val);
3790 1.1 christos *p_lit++ = val;
3791 1.1 christos break;
3792 1.1 christos
3793 1.7 christos case BFD_RELOC_Z80_WORD1:
3794 1.7 christos *p_lit++ = (val >> 16);
3795 1.7 christos *p_lit++ = (val >> 24);
3796 1.7 christos break;
3797 1.7 christos
3798 1.7 christos case BFD_RELOC_Z80_WORD0:
3799 1.8 christos *p_lit++ = val;
3800 1.8 christos *p_lit++ = (val >> 8);
3801 1.8 christos break;
3802 1.8 christos
3803 1.1 christos case BFD_RELOC_16:
3804 1.8 christos if (fixP->fx_done && is_overflow(val, 16))
3805 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3806 1.8 christos _("16-bit overflow (%+ld)"), val);
3807 1.1 christos *p_lit++ = val;
3808 1.1 christos *p_lit++ = (val >> 8);
3809 1.1 christos break;
3810 1.1 christos
3811 1.1 christos case BFD_RELOC_24: /* Def24 may produce this. */
3812 1.8 christos if (fixP->fx_done && is_overflow(val, 24))
3813 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3814 1.8 christos _("24-bit overflow (%+ld)"), val);
3815 1.1 christos *p_lit++ = val;
3816 1.1 christos *p_lit++ = (val >> 8);
3817 1.1 christos *p_lit++ = (val >> 16);
3818 1.1 christos break;
3819 1.1 christos
3820 1.1 christos case BFD_RELOC_32: /* Def32 and .long may produce this. */
3821 1.8 christos if (fixP->fx_done && is_overflow(val, 32))
3822 1.8 christos as_warn_where (fixP->fx_file, fixP->fx_line,
3823 1.8 christos _("32-bit overflow (%+ld)"), val);
3824 1.1 christos *p_lit++ = val;
3825 1.1 christos *p_lit++ = (val >> 8);
3826 1.1 christos *p_lit++ = (val >> 16);
3827 1.1 christos *p_lit++ = (val >> 24);
3828 1.8 christos break;
3829 1.8 christos
3830 1.8 christos case BFD_RELOC_Z80_16_BE: /* Z80N PUSH nn instruction produce this. */
3831 1.8 christos *p_lit++ = val >> 8;
3832 1.8 christos *p_lit++ = val;
3833 1.1 christos break;
3834 1.1 christos
3835 1.1 christos default:
3836 1.8 christos printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP->fx_r_type);
3837 1.1 christos abort ();
3838 1.1 christos }
3839 1.1 christos }
3840 1.1 christos
3841 1.1 christos /* GAS will call this to generate a reloc. GAS will pass the
3842 1.1 christos resulting reloc to `bfd_install_relocation'. This currently works
3843 1.1 christos poorly, as `bfd_install_relocation' often does the wrong thing, and
3844 1.1 christos instances of `tc_gen_reloc' have been written to work around the
3845 1.1 christos problems, which in turns makes it difficult to fix
3846 1.1 christos `bfd_install_relocation'. */
3847 1.1 christos
3848 1.1 christos /* If while processing a fixup, a reloc really
3849 1.1 christos needs to be created then it is done here. */
3850 1.1 christos
3851 1.1 christos arelent *
3852 1.1 christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
3853 1.1 christos {
3854 1.1 christos arelent *reloc;
3855 1.1 christos
3856 1.8 christos if (fixp->fx_subsy != NULL)
3857 1.1 christos {
3858 1.8 christos as_bad_subtract (fixp);
3859 1.1 christos return NULL;
3860 1.1 christos }
3861 1.1 christos
3862 1.5 christos reloc = XNEW (arelent);
3863 1.5 christos reloc->sym_ptr_ptr = XNEW (asymbol *);
3864 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3865 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3866 1.8 christos reloc->addend = fixp->fx_offset;
3867 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3868 1.8 christos if (reloc->howto == NULL)
3869 1.8 christos {
3870 1.8 christos as_bad_where (fixp->fx_file, fixp->fx_line,
3871 1.8 christos _("reloc %d not supported by object file format"),
3872 1.8 christos (int) fixp->fx_r_type);
3873 1.8 christos return NULL;
3874 1.8 christos }
3875 1.8 christos
3876 1.8 christos if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3877 1.8 christos || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3878 1.8 christos reloc->address = fixp->fx_offset;
3879 1.1 christos
3880 1.1 christos return reloc;
3881 1.1 christos }
3882 1.7 christos
3883 1.7 christos int
3884 1.8 christos z80_tc_labels_without_colon (void)
3885 1.8 christos {
3886 1.8 christos return colonless_labels;
3887 1.8 christos }
3888 1.8 christos
3889 1.8 christos int
3890 1.7 christos z80_tc_label_is_local (const char *name)
3891 1.7 christos {
3892 1.7 christos const char *n;
3893 1.7 christos const char *p;
3894 1.7 christos if (local_label_prefix == NULL)
3895 1.7 christos return 0;
3896 1.7 christos for (p = local_label_prefix, n = name; *p && *n && *n == *p; p++, n++)
3897 1.7 christos ;
3898 1.7 christos return *p == '\0';
3899 1.7 christos }
3900 1.7 christos
3901 1.7 christos /* Parse floating point number from string and compute mantissa and
3902 1.7 christos exponent. Mantissa is normalized.
3903 1.7 christos */
3904 1.7 christos #define EXP_MIN -0x10000
3905 1.7 christos #define EXP_MAX 0x10000
3906 1.7 christos static int
3907 1.8 christos str_to_broken_float (bool *signP, uint64_t *mantissaP, int *expP)
3908 1.7 christos {
3909 1.7 christos char *p;
3910 1.8 christos bool sign;
3911 1.8 christos uint64_t mantissa = 0;
3912 1.7 christos int exponent = 0;
3913 1.7 christos int i;
3914 1.7 christos
3915 1.7 christos p = (char*)skip_space (input_line_pointer);
3916 1.7 christos sign = (*p == '-');
3917 1.7 christos *signP = sign;
3918 1.7 christos if (sign || *p == '+')
3919 1.7 christos ++p;
3920 1.7 christos if (strncasecmp (p, "NaN", 3) == 0)
3921 1.7 christos {
3922 1.7 christos *mantissaP = 0;
3923 1.7 christos *expP = 0;
3924 1.7 christos input_line_pointer = p + 3;
3925 1.7 christos return 1;
3926 1.7 christos }
3927 1.7 christos if (strncasecmp (p, "inf", 3) == 0)
3928 1.7 christos {
3929 1.7 christos *mantissaP = 1ull << 63;
3930 1.7 christos *expP = EXP_MAX;
3931 1.7 christos input_line_pointer = p + 3;
3932 1.7 christos return 1;
3933 1.7 christos }
3934 1.7 christos for (; ISDIGIT (*p); ++p)
3935 1.7 christos {
3936 1.7 christos if (mantissa >> 60)
3937 1.7 christos {
3938 1.7 christos if (*p >= '5')
3939 1.7 christos mantissa++;
3940 1.7 christos break;
3941 1.7 christos }
3942 1.7 christos mantissa = mantissa * 10 + (*p - '0');
3943 1.7 christos }
3944 1.7 christos /* skip non-significant digits */
3945 1.7 christos for (; ISDIGIT (*p); ++p)
3946 1.7 christos exponent++;
3947 1.7 christos
3948 1.7 christos if (*p == '.')
3949 1.7 christos {
3950 1.7 christos p++;
3951 1.8 christos if (!exponent) /* If no precision overflow. */
3952 1.7 christos {
3953 1.7 christos for (; ISDIGIT (*p); ++p, --exponent)
3954 1.7 christos {
3955 1.7 christos if (mantissa >> 60)
3956 1.7 christos {
3957 1.7 christos if (*p >= '5')
3958 1.7 christos mantissa++;
3959 1.7 christos break;
3960 1.7 christos }
3961 1.7 christos mantissa = mantissa * 10 + (*p - '0');
3962 1.7 christos }
3963 1.7 christos }
3964 1.7 christos for (; ISDIGIT (*p); ++p)
3965 1.7 christos ;
3966 1.7 christos }
3967 1.7 christos if (*p == 'e' || *p == 'E')
3968 1.7 christos {
3969 1.7 christos int es;
3970 1.7 christos int t = 0;
3971 1.7 christos ++p;
3972 1.7 christos es = (*p == '-');
3973 1.7 christos if (es || *p == '+')
3974 1.7 christos p++;
3975 1.7 christos for (; ISDIGIT (*p); ++p)
3976 1.7 christos {
3977 1.7 christos if (t < 100)
3978 1.7 christos t = t * 10 + (*p - '0');
3979 1.7 christos }
3980 1.7 christos exponent += (es) ? -t : t;
3981 1.7 christos }
3982 1.7 christos if (ISALNUM (*p) || *p == '.')
3983 1.7 christos return 0;
3984 1.7 christos input_line_pointer = p;
3985 1.7 christos if (mantissa == 0)
3986 1.7 christos {
3987 1.7 christos *mantissaP = 1ull << 63;
3988 1.7 christos *expP = EXP_MIN;
3989 1.7 christos return 1; /* result is 0 */
3990 1.7 christos }
3991 1.7 christos /* normalization */
3992 1.7 christos for (; mantissa <= ~0ull/10; --exponent)
3993 1.7 christos mantissa *= 10;
3994 1.7 christos /* Now we have sign, mantissa, and signed decimal exponent
3995 1.7 christos need to recompute to binary exponent. */
3996 1.7 christos for (i = 64; exponent > 0; --exponent)
3997 1.7 christos {
3998 1.7 christos /* be sure that no integer overflow */
3999 1.7 christos while (mantissa > ~0ull/10)
4000 1.7 christos {
4001 1.7 christos mantissa >>= 1;
4002 1.7 christos i += 1;
4003 1.7 christos }
4004 1.7 christos mantissa *= 10;
4005 1.7 christos }
4006 1.7 christos for (; exponent < 0; ++exponent)
4007 1.7 christos {
4008 1.7 christos while (!(mantissa >> 63))
4009 1.7 christos {
4010 1.7 christos mantissa <<= 1;
4011 1.7 christos i -= 1;
4012 1.7 christos }
4013 1.7 christos mantissa /= 10;
4014 1.7 christos }
4015 1.7 christos /* normalization */
4016 1.7 christos for (; !(mantissa >> 63); --i)
4017 1.7 christos mantissa <<= 1;
4018 1.7 christos *mantissaP = mantissa;
4019 1.7 christos *expP = i;
4020 1.7 christos return 1;
4021 1.7 christos }
4022 1.7 christos
4023 1.7 christos static const char *
4024 1.7 christos str_to_zeda32(char *litP, int *sizeP)
4025 1.7 christos {
4026 1.8 christos uint64_t mantissa;
4027 1.8 christos bool sign;
4028 1.7 christos int exponent;
4029 1.7 christos unsigned i;
4030 1.7 christos
4031 1.7 christos *sizeP = 4;
4032 1.7 christos if (!str_to_broken_float (&sign, &mantissa, &exponent))
4033 1.7 christos return _("invalid syntax");
4034 1.7 christos /* I do not know why decrement is needed */
4035 1.7 christos --exponent;
4036 1.7 christos /* shift by 39 bits right keeping 25 bit mantissa for rounding */
4037 1.7 christos mantissa >>= 39;
4038 1.7 christos /* do rounding */
4039 1.7 christos ++mantissa;
4040 1.7 christos /* make 24 bit mantissa */
4041 1.7 christos mantissa >>= 1;
4042 1.7 christos /* check for overflow */
4043 1.7 christos if (mantissa >> 24)
4044 1.7 christos {
4045 1.7 christos mantissa >>= 1;
4046 1.7 christos ++exponent;
4047 1.7 christos }
4048 1.7 christos /* check for 0 */
4049 1.7 christos if (exponent < -127)
4050 1.7 christos {
4051 1.7 christos exponent = -128;
4052 1.7 christos mantissa = 0;
4053 1.7 christos }
4054 1.7 christos else if (exponent > 127)
4055 1.7 christos {
4056 1.7 christos exponent = -128;
4057 1.7 christos mantissa = sign ? 0xc00000 : 0x400000;
4058 1.7 christos }
4059 1.7 christos else if (mantissa == 0)
4060 1.7 christos {
4061 1.7 christos exponent = -128;
4062 1.7 christos mantissa = 0x200000;
4063 1.7 christos }
4064 1.7 christos else if (!sign)
4065 1.7 christos mantissa &= (1ull << 23) - 1;
4066 1.7 christos for (i = 0; i < 24; i += 8)
4067 1.7 christos *litP++ = (char)(mantissa >> i);
4068 1.7 christos *litP = (char)(0x80 + exponent);
4069 1.7 christos return NULL;
4070 1.7 christos }
4071 1.7 christos
4072 1.7 christos /*
4073 1.7 christos Math48 by Anders Hejlsberg support.
4074 1.7 christos Mantissa is 39 bits wide, exponent 8 bit wide.
4075 1.7 christos Format is:
4076 1.7 christos bit 47: sign
4077 1.7 christos bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4078 1.7 christos bit 7-0: exponent+128 (0 - value is null)
4079 1.7 christos MIN: 2.938735877e-39
4080 1.7 christos MAX: 1.701411835e+38
4081 1.7 christos */
4082 1.7 christos static const char *
4083 1.7 christos str_to_float48(char *litP, int *sizeP)
4084 1.7 christos {
4085 1.8 christos uint64_t mantissa;
4086 1.8 christos bool sign;
4087 1.7 christos int exponent;
4088 1.7 christos unsigned i;
4089 1.7 christos
4090 1.7 christos *sizeP = 6;
4091 1.7 christos if (!str_to_broken_float (&sign, &mantissa, &exponent))
4092 1.7 christos return _("invalid syntax");
4093 1.7 christos /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4094 1.7 christos mantissa >>= 23;
4095 1.7 christos /* do rounding */
4096 1.7 christos ++mantissa;
4097 1.7 christos /* make 40 bit mantissa */
4098 1.7 christos mantissa >>= 1;
4099 1.7 christos /* check for overflow */
4100 1.7 christos if (mantissa >> 40)
4101 1.7 christos {
4102 1.7 christos mantissa >>= 1;
4103 1.7 christos ++exponent;
4104 1.7 christos }
4105 1.7 christos if (exponent < -127)
4106 1.7 christos {
4107 1.7 christos memset (litP, 0, 6);
4108 1.7 christos return NULL;
4109 1.7 christos }
4110 1.7 christos if (exponent > 127)
4111 1.7 christos return _("overflow");
4112 1.7 christos if (!sign)
4113 1.7 christos mantissa &= (1ull << 39) - 1;
4114 1.7 christos *litP++ = (char)(0x80 + exponent);
4115 1.7 christos for (i = 0; i < 40; i += 8)
4116 1.7 christos *litP++ = (char)(mantissa >> i);
4117 1.7 christos return NULL;
4118 1.7 christos }
4119 1.7 christos
4120 1.7 christos static const char *
4121 1.7 christos str_to_ieee754_h(char *litP, int *sizeP)
4122 1.7 christos {
4123 1.8 christos return ieee_md_atof ('h', litP, sizeP, false);
4124 1.7 christos }
4125 1.7 christos
4126 1.7 christos static const char *
4127 1.7 christos str_to_ieee754_s(char *litP, int *sizeP)
4128 1.7 christos {
4129 1.8 christos return ieee_md_atof ('s', 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_d(char *litP, int *sizeP)
4134 1.7 christos {
4135 1.8 christos return ieee_md_atof ('d', litP, sizeP, false);
4136 1.8 christos }
4137 1.8 christos
4138 1.8 christos #ifdef TARGET_USE_CFIPOP
4139 1.8 christos /* Initialize the DWARF-2 unwind information for this procedure. */
4140 1.8 christos void
4141 1.8 christos z80_tc_frame_initial_instructions (void)
4142 1.8 christos {
4143 1.8 christos static int sp_regno = -1;
4144 1.8 christos
4145 1.8 christos if (sp_regno < 0)
4146 1.8 christos sp_regno = z80_tc_regname_to_dw2regnum ("sp");
4147 1.8 christos
4148 1.8 christos cfi_add_CFA_def_cfa (sp_regno, 0);
4149 1.8 christos }
4150 1.8 christos
4151 1.8 christos int
4152 1.8 christos z80_tc_regname_to_dw2regnum (const char *regname)
4153 1.8 christos {
4154 1.8 christos static const char *regs[] =
4155 1.8 christos { /* same registers as for GDB */
4156 1.8 christos "af", "bc", "de", "hl",
4157 1.8 christos "sp", "pc", "ix", "iy",
4158 1.8 christos "af_", "bc_", "de_", "hl_",
4159 1.8 christos "ir"
4160 1.8 christos };
4161 1.8 christos unsigned i;
4162 1.8 christos
4163 1.8 christos for (i = 0; i < ARRAY_SIZE(regs); ++i)
4164 1.8 christos if (!strcasecmp (regs[i], regname))
4165 1.8 christos return i;
4166 1.8 christos
4167 1.8 christos return -1;
4168 1.8 christos }
4169 1.8 christos #endif
4170 1.8 christos
4171 1.8 christos /* Implement DWARF2_ADDR_SIZE. */
4172 1.8 christos int
4173 1.8 christos z80_dwarf2_addr_size (const bfd *abfd)
4174 1.8 christos {
4175 1.8 christos switch (bfd_get_mach (abfd))
4176 1.8 christos {
4177 1.8 christos case bfd_mach_ez80_adl:
4178 1.8 christos return 3;
4179 1.8 christos default:
4180 1.8 christos return 2;
4181 1.8 christos }
4182 1.7 christos }
4183