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