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