tc-z8k.c revision 1.1.1.1 1 1.1 christos /* tc-z8k.c -- Assemble code for the Zilog Z800n
2 1.1 christos Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003,
3 1.1 christos 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GAS, the GNU Assembler.
6 1.1 christos
7 1.1 christos GAS is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3, or (at your option)
10 1.1 christos any later version.
11 1.1 christos
12 1.1 christos GAS is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with GAS; see the file COPYING. If not, write to the Free
19 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 1.1 christos 02110-1301, USA. */
21 1.1 christos
22 1.1 christos /* Written By Steve Chamberlain <sac (at) cygnus.com>. */
23 1.1 christos
24 1.1 christos #include "as.h"
25 1.1 christos #include "safe-ctype.h"
26 1.1 christos #define DEFINE_TABLE
27 1.1 christos #include "opcodes/z8k-opc.h"
28 1.1 christos
29 1.1 christos const char comment_chars[] = "!";
30 1.1 christos const char line_comment_chars[] = "#";
31 1.1 christos const char line_separator_chars[] = ";";
32 1.1 christos
33 1.1 christos extern int machine;
34 1.1 christos extern int coff_flags;
35 1.1 christos int segmented_mode;
36 1.1 christos
37 1.1 christos /* This is non-zero if target was set from the command line. */
38 1.1 christos static int z8k_target_from_cmdline;
39 1.1 christos
40 1.1 christos static void
41 1.1 christos s_segm (int segm)
42 1.1 christos {
43 1.1 christos if (segm)
44 1.1 christos {
45 1.1 christos segmented_mode = 1;
46 1.1 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001);
47 1.1 christos }
48 1.1 christos else
49 1.1 christos {
50 1.1 christos segmented_mode = 0;
51 1.1 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002);
52 1.1 christos }
53 1.1 christos }
54 1.1 christos
55 1.1 christos static void
56 1.1 christos even (int ignore ATTRIBUTE_UNUSED)
57 1.1 christos {
58 1.1 christos frag_align (1, 0, 0);
59 1.1 christos record_alignment (now_seg, 1);
60 1.1 christos }
61 1.1 christos
62 1.1 christos static int
63 1.1 christos tohex (int c)
64 1.1 christos {
65 1.1 christos if (ISDIGIT (c))
66 1.1 christos return c - '0';
67 1.1 christos if (ISLOWER (c))
68 1.1 christos return c - 'a' + 10;
69 1.1 christos return c - 'A' + 10;
70 1.1 christos }
71 1.1 christos
72 1.1 christos static void
73 1.1 christos sval (int ignore ATTRIBUTE_UNUSED)
74 1.1 christos {
75 1.1 christos SKIP_WHITESPACE ();
76 1.1 christos if (*input_line_pointer == '\'')
77 1.1 christos {
78 1.1 christos int c;
79 1.1 christos input_line_pointer++;
80 1.1 christos c = *input_line_pointer++;
81 1.1 christos while (c != '\'')
82 1.1 christos {
83 1.1 christos if (c == '%')
84 1.1 christos {
85 1.1 christos c = (tohex (input_line_pointer[0]) << 4)
86 1.1 christos | tohex (input_line_pointer[1]);
87 1.1 christos input_line_pointer += 2;
88 1.1 christos }
89 1.1 christos FRAG_APPEND_1_CHAR (c);
90 1.1 christos c = *input_line_pointer++;
91 1.1 christos }
92 1.1 christos demand_empty_rest_of_line ();
93 1.1 christos }
94 1.1 christos }
95 1.1 christos
96 1.1 christos /* This table describes all the machine specific pseudo-ops the assembler
97 1.1 christos has to support. The fields are:
98 1.1 christos pseudo-op name without dot
99 1.1 christos function to call to execute this pseudo-op
100 1.1 christos Integer arg to pass to the function
101 1.1 christos */
102 1.1 christos
103 1.1 christos const pseudo_typeS md_pseudo_table[] = {
104 1.1 christos {"int" , cons , 2},
105 1.1 christos {"data.b" , cons , 1},
106 1.1 christos {"data.w" , cons , 2},
107 1.1 christos {"data.l" , cons , 4},
108 1.1 christos {"form" , listing_psize , 0},
109 1.1 christos {"heading", listing_title , 0},
110 1.1 christos {"import" , s_ignore , 0},
111 1.1 christos {"page" , listing_eject , 0},
112 1.1 christos {"program", s_ignore , 0},
113 1.1 christos {"z8001" , s_segm , 1},
114 1.1 christos {"z8002" , s_segm , 0},
115 1.1 christos
116 1.1 christos {"segm" , s_segm , 1},
117 1.1 christos {"unsegm" , s_segm , 0},
118 1.1 christos {"unseg" , s_segm , 0},
119 1.1 christos {"name" , s_app_file , 0},
120 1.1 christos {"global" , s_globl , 0},
121 1.1 christos {"wval" , cons , 2},
122 1.1 christos {"lval" , cons , 4},
123 1.1 christos {"bval" , cons , 1},
124 1.1 christos {"sval" , sval , 0},
125 1.1 christos {"rsect" , obj_coff_section, 0},
126 1.1 christos {"sect" , obj_coff_section, 0},
127 1.1 christos {"block" , s_space , 0},
128 1.1 christos {"even" , even , 0},
129 1.1 christos {0 , 0 , 0}
130 1.1 christos };
131 1.1 christos
132 1.1 christos const char EXP_CHARS[] = "eE";
133 1.1 christos
134 1.1 christos /* Chars that mean this number is a floating point constant.
135 1.1 christos As in 0f12.456
136 1.1 christos or 0d1.2345e12 */
137 1.1 christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
138 1.1 christos
139 1.1 christos /* Opcode mnemonics. */
140 1.1 christos static struct hash_control *opcode_hash_control;
141 1.1 christos
142 1.1 christos void
143 1.1 christos md_begin (void)
144 1.1 christos {
145 1.1 christos const opcode_entry_type *opcode;
146 1.1 christos int idx = -1;
147 1.1 christos
148 1.1 christos opcode_hash_control = hash_new ();
149 1.1 christos
150 1.1 christos for (opcode = z8k_table; opcode->name; opcode++)
151 1.1 christos {
152 1.1 christos /* Only enter unique codes into the table. */
153 1.1 christos if (idx != opcode->idx)
154 1.1 christos hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
155 1.1 christos idx = opcode->idx;
156 1.1 christos }
157 1.1 christos
158 1.1 christos /* Default to z8002. */
159 1.1 christos if (! z8k_target_from_cmdline)
160 1.1 christos s_segm (0);
161 1.1 christos
162 1.1 christos /* Insert the pseudo ops, too. */
163 1.1 christos for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
164 1.1 christos {
165 1.1 christos opcode_entry_type *fake_opcode;
166 1.1 christos fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
167 1.1 christos fake_opcode->name = md_pseudo_table[idx].poc_name;
168 1.1 christos fake_opcode->func = (void *) (md_pseudo_table + idx);
169 1.1 christos fake_opcode->opcode = 250;
170 1.1 christos hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
171 1.1 christos }
172 1.1 christos }
173 1.1 christos
174 1.1 christos typedef struct z8k_op {
175 1.1 christos /* CLASS_REG_xxx. */
176 1.1 christos int regsize;
177 1.1 christos
178 1.1 christos /* 0 .. 15. */
179 1.1 christos unsigned int reg;
180 1.1 christos
181 1.1 christos int mode;
182 1.1 christos
183 1.1 christos /* Any other register associated with the mode. */
184 1.1 christos unsigned int x_reg;
185 1.1 christos
186 1.1 christos /* Any expression. */
187 1.1 christos expressionS exp;
188 1.1 christos } op_type;
189 1.1 christos
190 1.1 christos static expressionS *da_operand;
191 1.1 christos static expressionS *imm_operand;
192 1.1 christos
193 1.1 christos static int reg[16];
194 1.1 christos static int the_cc;
195 1.1 christos static int the_ctrl;
196 1.1 christos static int the_flags;
197 1.1 christos static int the_interrupt;
198 1.1 christos
199 1.1 christos /* Determine register number. src points to the ascii number
200 1.1 christos (after "rl", "rh", "r", "rr", or "rq"). If a character
201 1.1 christos outside the set of {0,',',')','('} follows the number,
202 1.1 christos return NULL to indicate that it's not a valid register
203 1.1 christos number. */
204 1.1 christos
205 1.1 christos static char *
206 1.1 christos whatreg (unsigned int *preg, char *src)
207 1.1 christos {
208 1.1 christos unsigned int new_reg;
209 1.1 christos
210 1.1 christos /* src[0] is already known to be a digit. */
211 1.1 christos if (ISDIGIT (src[1]))
212 1.1 christos {
213 1.1 christos new_reg = (src[0] - '0') * 10 + src[1] - '0';
214 1.1 christos src += 2;
215 1.1 christos }
216 1.1 christos else
217 1.1 christos {
218 1.1 christos new_reg = (src[0] - '0');
219 1.1 christos src += 1;
220 1.1 christos }
221 1.1 christos
222 1.1 christos if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')')
223 1.1 christos return NULL;
224 1.1 christos
225 1.1 christos *preg = new_reg;
226 1.1 christos return src;
227 1.1 christos }
228 1.1 christos
229 1.1 christos /* Parse operands
230 1.1 christos
231 1.1 christos rh0-rh7, rl0-rl7
232 1.1 christos r0-r15
233 1.1 christos rr0-rr14
234 1.1 christos rq0--rq12
235 1.1 christos WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
236 1.1 christos r0l,r0h,..r7l,r7h
237 1.1 christos @WREG
238 1.1 christos @WREG+
239 1.1 christos @-WREG
240 1.1 christos #const
241 1.1 christos */
242 1.1 christos
243 1.1 christos /* Try to parse a reg name. Return a pointer to the first character
244 1.1 christos in SRC after the reg name. */
245 1.1 christos
246 1.1 christos static char *
247 1.1 christos parse_reg (char *src, int *mode, unsigned int *preg)
248 1.1 christos {
249 1.1 christos char *res = NULL;
250 1.1 christos char regno;
251 1.1 christos
252 1.1 christos /* Check for stack pointer "sp" alias. */
253 1.1 christos if ((src[0] == 's' || src[0] == 'S')
254 1.1 christos && (src[1] == 'p' || src[1] == 'P')
255 1.1 christos && (src[2] == 0 || src[2] == ','))
256 1.1 christos {
257 1.1 christos if (segmented_mode)
258 1.1 christos {
259 1.1 christos *mode = CLASS_REG_LONG;
260 1.1 christos *preg = 14;
261 1.1 christos }
262 1.1 christos else
263 1.1 christos {
264 1.1 christos *mode = CLASS_REG_WORD;
265 1.1 christos *preg = 15;
266 1.1 christos }
267 1.1 christos return src + 2;
268 1.1 christos }
269 1.1 christos
270 1.1 christos if (src[0] == 'r' || src[0] == 'R')
271 1.1 christos {
272 1.1 christos if (src[1] == 'r' || src[1] == 'R')
273 1.1 christos {
274 1.1 christos if (src[2] < '0' || src[2] > '9')
275 1.1 christos return NULL; /* Assume no register name but a label starting with 'rr'. */
276 1.1 christos *mode = CLASS_REG_LONG;
277 1.1 christos res = whatreg (preg, src + 2);
278 1.1 christos if (res == NULL)
279 1.1 christos return NULL; /* Not a valid register name. */
280 1.1 christos regno = *preg;
281 1.1 christos if (regno > 14)
282 1.1 christos as_bad (_("register rr%d out of range"), regno);
283 1.1 christos if (regno & 1)
284 1.1 christos as_bad (_("register rr%d does not exist"), regno);
285 1.1 christos }
286 1.1 christos else if (src[1] == 'h' || src[1] == 'H')
287 1.1 christos {
288 1.1 christos if (src[2] < '0' || src[2] > '9')
289 1.1 christos return NULL; /* Assume no register name but a label starting with 'rh'. */
290 1.1 christos *mode = CLASS_REG_BYTE;
291 1.1 christos res = whatreg (preg, src + 2);
292 1.1 christos if (res == NULL)
293 1.1 christos return NULL; /* Not a valid register name. */
294 1.1 christos regno = *preg;
295 1.1 christos if (regno > 7)
296 1.1 christos as_bad (_("register rh%d out of range"), regno);
297 1.1 christos }
298 1.1 christos else if (src[1] == 'l' || src[1] == 'L')
299 1.1 christos {
300 1.1 christos if (src[2] < '0' || src[2] > '9')
301 1.1 christos return NULL; /* Assume no register name but a label starting with 'rl'. */
302 1.1 christos *mode = CLASS_REG_BYTE;
303 1.1 christos res = whatreg (preg, src + 2);
304 1.1 christos if (res == NULL)
305 1.1 christos return NULL; /* Not a valid register name. */
306 1.1 christos regno = *preg;
307 1.1 christos if (regno > 7)
308 1.1 christos as_bad (_("register rl%d out of range"), regno);
309 1.1 christos *preg += 8;
310 1.1 christos }
311 1.1 christos else if (src[1] == 'q' || src[1] == 'Q')
312 1.1 christos {
313 1.1 christos if (src[2] < '0' || src[2] > '9')
314 1.1 christos return NULL; /* Assume no register name but a label starting with 'rq'. */
315 1.1 christos *mode = CLASS_REG_QUAD;
316 1.1 christos res = whatreg (preg, src + 2);
317 1.1 christos if (res == NULL)
318 1.1 christos return NULL; /* Not a valid register name. */
319 1.1 christos regno = *preg;
320 1.1 christos if (regno > 12)
321 1.1 christos as_bad (_("register rq%d out of range"), regno);
322 1.1 christos if (regno & 3)
323 1.1 christos as_bad (_("register rq%d does not exist"), regno);
324 1.1 christos }
325 1.1 christos else
326 1.1 christos {
327 1.1 christos if (src[1] < '0' || src[1] > '9')
328 1.1 christos return NULL; /* Assume no register name but a label starting with 'r'. */
329 1.1 christos *mode = CLASS_REG_WORD;
330 1.1 christos res = whatreg (preg, src + 1);
331 1.1 christos if (res == NULL)
332 1.1 christos return NULL; /* Not a valid register name. */
333 1.1 christos regno = *preg;
334 1.1 christos if (regno > 15)
335 1.1 christos as_bad (_("register r%d out of range"), regno);
336 1.1 christos }
337 1.1 christos }
338 1.1 christos return res;
339 1.1 christos }
340 1.1 christos
341 1.1 christos static char *
342 1.1 christos parse_exp (char *s, expressionS *op)
343 1.1 christos {
344 1.1 christos char *save = input_line_pointer;
345 1.1 christos char *new_pointer;
346 1.1 christos
347 1.1 christos input_line_pointer = s;
348 1.1 christos expression (op);
349 1.1 christos if (op->X_op == O_absent)
350 1.1 christos as_bad (_("missing operand"));
351 1.1 christos new_pointer = input_line_pointer;
352 1.1 christos input_line_pointer = save;
353 1.1 christos return new_pointer;
354 1.1 christos }
355 1.1 christos
356 1.1 christos /* The many forms of operand:
357 1.1 christos
358 1.1 christos <rb>
359 1.1 christos <r>
360 1.1 christos <rr>
361 1.1 christos <rq>
362 1.1 christos @r
363 1.1 christos #exp
364 1.1 christos exp
365 1.1 christos exp(r)
366 1.1 christos r(#exp)
367 1.1 christos r(r)
368 1.1 christos */
369 1.1 christos
370 1.1 christos static char *
371 1.1 christos checkfor (char *ptr, char what)
372 1.1 christos {
373 1.1 christos if (*ptr == what)
374 1.1 christos ptr++;
375 1.1 christos else
376 1.1 christos as_bad (_("expected %c"), what);
377 1.1 christos
378 1.1 christos return ptr;
379 1.1 christos }
380 1.1 christos
381 1.1 christos /* Make sure the mode supplied is the size of a word. */
382 1.1 christos
383 1.1 christos static void
384 1.1 christos regword (int mode, char *string)
385 1.1 christos {
386 1.1 christos int ok;
387 1.1 christos
388 1.1 christos ok = CLASS_REG_WORD;
389 1.1 christos if (ok != mode)
390 1.1 christos {
391 1.1 christos as_bad (_("register is wrong size for a word %s"), string);
392 1.1 christos }
393 1.1 christos }
394 1.1 christos
395 1.1 christos /* Make sure the mode supplied is the size of an address. */
396 1.1 christos
397 1.1 christos static void
398 1.1 christos regaddr (int mode, char *string)
399 1.1 christos {
400 1.1 christos int ok;
401 1.1 christos
402 1.1 christos ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
403 1.1 christos if (ok != mode)
404 1.1 christos {
405 1.1 christos as_bad (_("register is wrong size for address %s"), string);
406 1.1 christos }
407 1.1 christos }
408 1.1 christos
409 1.1 christos struct ctrl_names {
410 1.1 christos int value;
411 1.1 christos char *name;
412 1.1 christos };
413 1.1 christos
414 1.1 christos static struct ctrl_names ctrl_table[] = {
415 1.1 christos { 0x1, "flags" }, /* ldctlb only. */
416 1.1 christos { 0x2, "fcw" }, /* ldctl only. Applies to all remaining control registers. */
417 1.1 christos { 0x3, "refresh" },
418 1.1 christos { 0x4, "psapseg" },
419 1.1 christos { 0x5, "psapoff" },
420 1.1 christos { 0x5, "psap" },
421 1.1 christos { 0x6, "nspseg" },
422 1.1 christos { 0x7, "nspoff" },
423 1.1 christos { 0x7, "nsp" },
424 1.1 christos { 0 , 0 }
425 1.1 christos };
426 1.1 christos
427 1.1 christos static void
428 1.1 christos get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
429 1.1 christos {
430 1.1 christos char *src = *ptr;
431 1.1 christos int i, l;
432 1.1 christos
433 1.1 christos while (*src == ' ')
434 1.1 christos src++;
435 1.1 christos
436 1.1 christos mode->mode = CLASS_CTRL;
437 1.1 christos for (i = 0; ctrl_table[i].name; i++)
438 1.1 christos {
439 1.1 christos l = strlen (ctrl_table[i].name);
440 1.1 christos if (! strncasecmp (ctrl_table[i].name, src, l))
441 1.1 christos {
442 1.1 christos the_ctrl = ctrl_table[i].value;
443 1.1 christos if (*(src + l) && *(src + l) != ',')
444 1.1 christos break;
445 1.1 christos *ptr = src + l; /* Valid control name found: "consume" it. */
446 1.1 christos return;
447 1.1 christos }
448 1.1 christos }
449 1.1 christos the_ctrl = 0;
450 1.1 christos }
451 1.1 christos
452 1.1 christos struct flag_names {
453 1.1 christos int value;
454 1.1 christos char *name;
455 1.1 christos };
456 1.1 christos
457 1.1 christos static struct flag_names flag_table[] = {
458 1.1 christos { 0x1, "P" },
459 1.1 christos { 0x1, "V" },
460 1.1 christos { 0x2, "S" },
461 1.1 christos { 0x4, "Z" },
462 1.1 christos { 0x8, "C" },
463 1.1 christos { 0x0, "+" },
464 1.1 christos { 0x0, "," },
465 1.1 christos { 0, 0 }
466 1.1 christos };
467 1.1 christos
468 1.1 christos static void
469 1.1 christos get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
470 1.1 christos {
471 1.1 christos char *src = *ptr;
472 1.1 christos char c;
473 1.1 christos int i;
474 1.1 christos int j;
475 1.1 christos
476 1.1 christos while (*src == ' ')
477 1.1 christos src++;
478 1.1 christos
479 1.1 christos mode->mode = CLASS_FLAGS;
480 1.1 christos the_flags = 0;
481 1.1 christos for (j = 0; j <= 9; j++)
482 1.1 christos {
483 1.1 christos if (!src[j])
484 1.1 christos goto done;
485 1.1 christos c = TOUPPER(src[j]);
486 1.1 christos for (i = 0; flag_table[i].name; i++)
487 1.1 christos {
488 1.1 christos if (flag_table[i].name[0] == c)
489 1.1 christos {
490 1.1 christos the_flags = the_flags | flag_table[i].value;
491 1.1 christos goto match;
492 1.1 christos }
493 1.1 christos }
494 1.1 christos goto done;
495 1.1 christos match:
496 1.1 christos ;
497 1.1 christos }
498 1.1 christos done:
499 1.1 christos *ptr = src + j;
500 1.1 christos }
501 1.1 christos
502 1.1 christos struct interrupt_names {
503 1.1 christos int value;
504 1.1 christos char *name;
505 1.1 christos };
506 1.1 christos
507 1.1 christos static struct interrupt_names intr_table[] = {
508 1.1 christos { 0x1, "nvi" },
509 1.1 christos { 0x2, "vi" },
510 1.1 christos { 0x3, "both" },
511 1.1 christos { 0x3, "all" },
512 1.1 christos { 0, 0 }
513 1.1 christos };
514 1.1 christos
515 1.1 christos static void
516 1.1 christos get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
517 1.1 christos {
518 1.1 christos char *src = *ptr;
519 1.1 christos int i, l;
520 1.1 christos
521 1.1 christos while (*src == ' ')
522 1.1 christos src++;
523 1.1 christos
524 1.1 christos mode->mode = CLASS_IMM;
525 1.1 christos the_interrupt = 0;
526 1.1 christos
527 1.1 christos while (*src)
528 1.1 christos {
529 1.1 christos for (i = 0; intr_table[i].name; i++)
530 1.1 christos {
531 1.1 christos l = strlen (intr_table[i].name);
532 1.1 christos if (! strncasecmp (intr_table[i].name, src, l))
533 1.1 christos {
534 1.1 christos the_interrupt |= intr_table[i].value;
535 1.1 christos if (*(src + l) && *(src + l) != ',')
536 1.1 christos {
537 1.1 christos *ptr = src + l;
538 1.1 christos invalid:
539 1.1 christos as_bad (_("unknown interrupt %s"), src);
540 1.1 christos while (**ptr && ! is_end_of_line[(unsigned char) **ptr])
541 1.1 christos (*ptr)++; /* Consume rest of line. */
542 1.1 christos return;
543 1.1 christos }
544 1.1 christos src += l;
545 1.1 christos if (! *src)
546 1.1 christos {
547 1.1 christos *ptr = src;
548 1.1 christos return;
549 1.1 christos }
550 1.1 christos }
551 1.1 christos }
552 1.1 christos if (*src == ',')
553 1.1 christos src++;
554 1.1 christos else
555 1.1 christos {
556 1.1 christos *ptr = src;
557 1.1 christos goto invalid;
558 1.1 christos }
559 1.1 christos }
560 1.1 christos
561 1.1 christos /* No interrupt type specified, opcode won't do anything. */
562 1.1 christos as_warn (_("opcode has no effect"));
563 1.1 christos the_interrupt = 0x0;
564 1.1 christos }
565 1.1 christos
566 1.1 christos struct cc_names {
567 1.1 christos int value;
568 1.1 christos char *name;
569 1.1 christos };
570 1.1 christos
571 1.1 christos static struct cc_names table[] = {
572 1.1 christos { 0x0, "f" },
573 1.1 christos { 0x1, "lt" },
574 1.1 christos { 0x2, "le" },
575 1.1 christos { 0x3, "ule" },
576 1.1 christos { 0x4, "ov/pe" },
577 1.1 christos { 0x4, "ov" },
578 1.1 christos { 0x4, "pe/ov" },
579 1.1 christos { 0x4, "pe" },
580 1.1 christos { 0x5, "mi" },
581 1.1 christos { 0x6, "eq" },
582 1.1 christos { 0x6, "z" },
583 1.1 christos { 0x7, "c/ult" },
584 1.1 christos { 0x7, "c" },
585 1.1 christos { 0x7, "ult/c" },
586 1.1 christos { 0x7, "ult" },
587 1.1 christos { 0x8, "t" },
588 1.1 christos { 0x9, "ge" },
589 1.1 christos { 0xa, "gt" },
590 1.1 christos { 0xb, "ugt" },
591 1.1 christos { 0xc, "nov/po" },
592 1.1 christos { 0xc, "nov" },
593 1.1 christos { 0xc, "po/nov" },
594 1.1 christos { 0xc, "po" },
595 1.1 christos { 0xd, "pl" },
596 1.1 christos { 0xe, "ne" },
597 1.1 christos { 0xe, "nz" },
598 1.1 christos { 0xf, "nc/uge" },
599 1.1 christos { 0xf, "nc" },
600 1.1 christos { 0xf, "uge/nc" },
601 1.1 christos { 0xf, "uge" },
602 1.1 christos { 0 , 0 }
603 1.1 christos };
604 1.1 christos
605 1.1 christos static void
606 1.1 christos get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
607 1.1 christos {
608 1.1 christos char *src = *ptr;
609 1.1 christos int i, l;
610 1.1 christos
611 1.1 christos while (*src == ' ')
612 1.1 christos src++;
613 1.1 christos
614 1.1 christos mode->mode = CLASS_CC;
615 1.1 christos for (i = 0; table[i].name; i++)
616 1.1 christos {
617 1.1 christos l = strlen (table[i].name);
618 1.1 christos if (! strncasecmp (table[i].name, src, l))
619 1.1 christos {
620 1.1 christos the_cc = table[i].value;
621 1.1 christos if (*(src + l) && *(src + l) != ',')
622 1.1 christos break;
623 1.1 christos *ptr = src + l; /* Valid cc found: "consume" it. */
624 1.1 christos return;
625 1.1 christos }
626 1.1 christos }
627 1.1 christos the_cc = 0x8; /* Not recognizing the cc defaults to t. (Assuming no cc present.) */
628 1.1 christos }
629 1.1 christos
630 1.1 christos static void
631 1.1 christos get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
632 1.1 christos {
633 1.1 christos char *src = *ptr;
634 1.1 christos char *end;
635 1.1 christos
636 1.1 christos mode->mode = 0;
637 1.1 christos
638 1.1 christos while (*src == ' ')
639 1.1 christos src++;
640 1.1 christos if (*src == '#')
641 1.1 christos {
642 1.1 christos mode->mode = CLASS_IMM;
643 1.1 christos imm_operand = &(mode->exp);
644 1.1 christos src = parse_exp (src + 1, &(mode->exp));
645 1.1 christos }
646 1.1 christos else if (*src == '@')
647 1.1 christos {
648 1.1 christos mode->mode = CLASS_IR;
649 1.1 christos src = parse_reg (src + 1, &mode->regsize, &mode->reg);
650 1.1 christos }
651 1.1 christos else
652 1.1 christos {
653 1.1 christos unsigned int regn;
654 1.1 christos
655 1.1 christos end = parse_reg (src, &mode->mode, ®n);
656 1.1 christos
657 1.1 christos if (end)
658 1.1 christos {
659 1.1 christos int nw;
660 1.1 christos unsigned int nr;
661 1.1 christos
662 1.1 christos src = end;
663 1.1 christos if (*src == '(')
664 1.1 christos {
665 1.1 christos src++;
666 1.1 christos end = parse_reg (src, &nw, &nr);
667 1.1 christos if (end)
668 1.1 christos {
669 1.1 christos /* Got Ra(Rb). */
670 1.1 christos src = end;
671 1.1 christos
672 1.1 christos if (*src != ')')
673 1.1 christos as_bad (_("Missing ) in ra(rb)"));
674 1.1 christos else
675 1.1 christos src++;
676 1.1 christos
677 1.1 christos regaddr (mode->mode, "ra(rb) ra");
678 1.1 christos mode->mode = CLASS_BX;
679 1.1 christos mode->reg = regn;
680 1.1 christos mode->x_reg = nr;
681 1.1 christos reg[ARG_RX] = nr;
682 1.1 christos }
683 1.1 christos else
684 1.1 christos {
685 1.1 christos /* Got Ra(disp). */
686 1.1 christos if (*src == '#')
687 1.1 christos src++;
688 1.1 christos src = parse_exp (src, &(mode->exp));
689 1.1 christos src = checkfor (src, ')');
690 1.1 christos mode->mode = CLASS_BA;
691 1.1 christos mode->reg = regn;
692 1.1 christos mode->x_reg = 0;
693 1.1 christos imm_operand = &(mode->exp);
694 1.1 christos }
695 1.1 christos }
696 1.1 christos else
697 1.1 christos {
698 1.1 christos mode->reg = regn;
699 1.1 christos mode->x_reg = 0;
700 1.1 christos }
701 1.1 christos }
702 1.1 christos else
703 1.1 christos {
704 1.1 christos /* No initial reg. */
705 1.1 christos src = parse_exp (src, &(mode->exp));
706 1.1 christos if (*src == '(')
707 1.1 christos {
708 1.1 christos src++;
709 1.1 christos end = parse_reg (src, &(mode->mode), ®n);
710 1.1 christos regword (mode->mode, "addr(Ra) ra");
711 1.1 christos mode->mode = CLASS_X;
712 1.1 christos mode->reg = regn;
713 1.1 christos mode->x_reg = 0;
714 1.1 christos da_operand = &(mode->exp);
715 1.1 christos src = checkfor (end, ')');
716 1.1 christos }
717 1.1 christos else
718 1.1 christos {
719 1.1 christos /* Just an address. */
720 1.1 christos mode->mode = CLASS_DA;
721 1.1 christos mode->reg = 0;
722 1.1 christos mode->x_reg = 0;
723 1.1 christos da_operand = &(mode->exp);
724 1.1 christos }
725 1.1 christos }
726 1.1 christos }
727 1.1 christos *ptr = src;
728 1.1 christos }
729 1.1 christos
730 1.1 christos static char *
731 1.1 christos get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand)
732 1.1 christos {
733 1.1 christos char *ptr = op_end;
734 1.1 christos char *savptr;
735 1.1 christos
736 1.1 christos switch (opcode->noperands)
737 1.1 christos {
738 1.1 christos case 0:
739 1.1 christos operand[0].mode = 0;
740 1.1 christos operand[1].mode = 0;
741 1.1 christos while (*ptr == ' ')
742 1.1 christos ptr++;
743 1.1 christos break;
744 1.1 christos
745 1.1 christos case 1:
746 1.1 christos if (opcode->arg_info[0] == CLASS_CC)
747 1.1 christos {
748 1.1 christos get_cc_operand (&ptr, operand + 0, 0);
749 1.1 christos while (*ptr == ' ')
750 1.1 christos ptr++;
751 1.1 christos if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
752 1.1 christos {
753 1.1 christos as_bad (_("invalid condition code '%s'"), ptr);
754 1.1 christos while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
755 1.1 christos ptr++; /* Consume rest of line. */
756 1.1 christos }
757 1.1 christos }
758 1.1 christos else if (opcode->arg_info[0] == CLASS_FLAGS)
759 1.1 christos {
760 1.1 christos get_flags_operand (&ptr, operand + 0, 0);
761 1.1 christos while (*ptr == ' ')
762 1.1 christos ptr++;
763 1.1 christos if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
764 1.1 christos {
765 1.1 christos as_bad (_("invalid flag '%s'"), ptr);
766 1.1 christos while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
767 1.1 christos ptr++; /* Consume rest of line. */
768 1.1 christos }
769 1.1 christos }
770 1.1 christos else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
771 1.1 christos get_interrupt_operand (&ptr, operand + 0, 0);
772 1.1 christos else
773 1.1 christos get_operand (&ptr, operand + 0, 0);
774 1.1 christos
775 1.1 christos operand[1].mode = 0;
776 1.1 christos break;
777 1.1 christos
778 1.1 christos case 2:
779 1.1 christos savptr = ptr;
780 1.1 christos if (opcode->arg_info[0] == CLASS_CC)
781 1.1 christos {
782 1.1 christos get_cc_operand (&ptr, operand + 0, 0);
783 1.1 christos while (*ptr == ' ')
784 1.1 christos ptr++;
785 1.1 christos if (*ptr != ',' && strchr (ptr + 1, ','))
786 1.1 christos {
787 1.1 christos savptr = ptr;
788 1.1 christos while (*ptr != ',')
789 1.1 christos ptr++;
790 1.1 christos *ptr = 0;
791 1.1 christos ptr++;
792 1.1 christos as_bad (_("invalid condition code '%s'"), savptr);
793 1.1 christos }
794 1.1 christos }
795 1.1 christos else if (opcode->arg_info[0] == CLASS_CTRL)
796 1.1 christos {
797 1.1 christos get_ctrl_operand (&ptr, operand + 0, 0);
798 1.1 christos
799 1.1 christos if (the_ctrl == 0)
800 1.1 christos {
801 1.1 christos ptr = savptr;
802 1.1 christos get_operand (&ptr, operand + 0, 0);
803 1.1 christos
804 1.1 christos if (ptr == 0)
805 1.1 christos return NULL;
806 1.1 christos if (*ptr == ',')
807 1.1 christos ptr++;
808 1.1 christos get_ctrl_operand (&ptr, operand + 1, 1);
809 1.1 christos if (the_ctrl == 0)
810 1.1 christos return NULL;
811 1.1 christos return ptr;
812 1.1 christos }
813 1.1 christos }
814 1.1 christos else
815 1.1 christos get_operand (&ptr, operand + 0, 0);
816 1.1 christos
817 1.1 christos if (ptr == 0)
818 1.1 christos return NULL;
819 1.1 christos if (*ptr == ',')
820 1.1 christos ptr++;
821 1.1 christos get_operand (&ptr, operand + 1, 1);
822 1.1 christos break;
823 1.1 christos
824 1.1 christos case 3:
825 1.1 christos get_operand (&ptr, operand + 0, 0);
826 1.1 christos if (*ptr == ',')
827 1.1 christos ptr++;
828 1.1 christos get_operand (&ptr, operand + 1, 1);
829 1.1 christos if (*ptr == ',')
830 1.1 christos ptr++;
831 1.1 christos get_operand (&ptr, operand + 2, 2);
832 1.1 christos break;
833 1.1 christos
834 1.1 christos case 4:
835 1.1 christos get_operand (&ptr, operand + 0, 0);
836 1.1 christos if (*ptr == ',')
837 1.1 christos ptr++;
838 1.1 christos get_operand (&ptr, operand + 1, 1);
839 1.1 christos if (*ptr == ',')
840 1.1 christos ptr++;
841 1.1 christos get_operand (&ptr, operand + 2, 2);
842 1.1 christos if (*ptr == ',')
843 1.1 christos ptr++;
844 1.1 christos get_cc_operand (&ptr, operand + 3, 3);
845 1.1 christos break;
846 1.1 christos
847 1.1 christos default:
848 1.1 christos abort ();
849 1.1 christos }
850 1.1 christos
851 1.1 christos return ptr;
852 1.1 christos }
853 1.1 christos
854 1.1 christos /* Passed a pointer to a list of opcodes which use different
855 1.1 christos addressing modes. Return the opcode which matches the opcodes
856 1.1 christos provided. */
857 1.1 christos
858 1.1 christos static opcode_entry_type *
859 1.1 christos get_specific (opcode_entry_type *opcode, op_type *operands)
860 1.1 christos {
861 1.1 christos opcode_entry_type *this_try = opcode;
862 1.1 christos int found = 0;
863 1.1 christos unsigned int noperands = opcode->noperands;
864 1.1 christos
865 1.1 christos int this_index = opcode->idx;
866 1.1 christos
867 1.1 christos while (this_index == opcode->idx && !found)
868 1.1 christos {
869 1.1 christos unsigned int i;
870 1.1 christos
871 1.1 christos this_try = opcode++;
872 1.1 christos for (i = 0; i < noperands; i++)
873 1.1 christos {
874 1.1 christos unsigned int mode = operands[i].mode;
875 1.1 christos
876 1.1 christos if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO))
877 1.1 christos {
878 1.1 christos mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO;
879 1.1 christos }
880 1.1 christos
881 1.1 christos if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
882 1.1 christos {
883 1.1 christos /* It could be a pc rel operand, if this is a da mode
884 1.1 christos and we like disps, then insert it. */
885 1.1 christos
886 1.1 christos if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
887 1.1 christos {
888 1.1 christos /* This is the case. */
889 1.1 christos operands[i].mode = CLASS_DISP;
890 1.1 christos }
891 1.1 christos else if (mode == CLASS_BA && this_try->arg_info[i])
892 1.1 christos {
893 1.1 christos /* Can't think of a way to turn what we've been
894 1.1 christos given into something that's OK. */
895 1.1 christos goto fail;
896 1.1 christos }
897 1.1 christos else if (this_try->arg_info[i] & CLASS_PR)
898 1.1 christos {
899 1.1 christos if (mode == CLASS_REG_LONG && segmented_mode)
900 1.1 christos {
901 1.1 christos /* OK. */
902 1.1 christos }
903 1.1 christos else if (mode == CLASS_REG_WORD && !segmented_mode)
904 1.1 christos {
905 1.1 christos /* OK. */
906 1.1 christos }
907 1.1 christos else
908 1.1 christos goto fail;
909 1.1 christos }
910 1.1 christos else
911 1.1 christos goto fail;
912 1.1 christos }
913 1.1 christos switch (mode & CLASS_MASK)
914 1.1 christos {
915 1.1 christos default:
916 1.1 christos break;
917 1.1 christos case CLASS_IRO:
918 1.1 christos if (operands[i].regsize != CLASS_REG_WORD)
919 1.1 christos as_bad (_("invalid indirect register size"));
920 1.1 christos reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
921 1.1 christos break;
922 1.1 christos case CLASS_IR:
923 1.1 christos if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG)
924 1.1 christos || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD))
925 1.1 christos as_bad (_("invalid indirect register size"));
926 1.1 christos reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
927 1.1 christos break;
928 1.1 christos case CLASS_X:
929 1.1 christos case CLASS_BA:
930 1.1 christos case CLASS_BX:
931 1.1 christos case CLASS_DISP:
932 1.1 christos case CLASS_REG:
933 1.1 christos case CLASS_REG_WORD:
934 1.1 christos case CLASS_REG_BYTE:
935 1.1 christos case CLASS_REG_QUAD:
936 1.1 christos case CLASS_REG_LONG:
937 1.1 christos case CLASS_REGN0:
938 1.1 christos reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
939 1.1 christos break;
940 1.1 christos case CLASS_CTRL:
941 1.1 christos if (this_try->opcode == OPC_ldctlb && the_ctrl != 1)
942 1.1 christos as_bad (_("invalid control register name"));
943 1.1 christos break;
944 1.1 christos }
945 1.1 christos }
946 1.1 christos
947 1.1 christos found = 1;
948 1.1 christos fail:
949 1.1 christos ;
950 1.1 christos }
951 1.1 christos if (found)
952 1.1 christos return this_try;
953 1.1 christos else
954 1.1 christos return 0;
955 1.1 christos }
956 1.1 christos
957 1.1 christos static char buffer[20];
958 1.1 christos
959 1.1 christos static void
960 1.1 christos newfix (int ptr, int type, int size, expressionS *operand)
961 1.1 christos {
962 1.1 christos int is_pcrel = 0;
963 1.1 christos fixS *fixP;
964 1.1 christos
965 1.1 christos /* Size is in nibbles. */
966 1.1 christos if (operand->X_add_symbol
967 1.1 christos || operand->X_op_symbol
968 1.1 christos || operand->X_add_number)
969 1.1 christos {
970 1.1 christos switch(type)
971 1.1 christos {
972 1.1 christos case BFD_RELOC_8_PCREL:
973 1.1 christos case BFD_RELOC_Z8K_CALLR:
974 1.1 christos case BFD_RELOC_Z8K_DISP7:
975 1.1 christos is_pcrel = 1;
976 1.1 christos }
977 1.1 christos fixP = fix_new_exp (frag_now, ptr, size / 2,
978 1.1 christos operand, is_pcrel, type);
979 1.1 christos if (is_pcrel)
980 1.1 christos fixP->fx_no_overflow = 1;
981 1.1 christos }
982 1.1 christos }
983 1.1 christos
984 1.1 christos static char *
985 1.1 christos apply_fix (char *ptr, int type, expressionS *operand, int size)
986 1.1 christos {
987 1.1 christos long n = operand->X_add_number;
988 1.1 christos
989 1.1 christos /* size is in nibbles. */
990 1.1 christos
991 1.1 christos newfix ((ptr - buffer) / 2, type, size + 1, operand);
992 1.1 christos switch (size)
993 1.1 christos {
994 1.1 christos case 8: /* 8 nibbles == 32 bits. */
995 1.1 christos *ptr++ = n >> 28;
996 1.1 christos *ptr++ = n >> 24;
997 1.1 christos *ptr++ = n >> 20;
998 1.1 christos *ptr++ = n >> 16;
999 1.1 christos case 4: /* 4 nibbles == 16 bits. */
1000 1.1 christos *ptr++ = n >> 12;
1001 1.1 christos *ptr++ = n >> 8;
1002 1.1 christos case 2:
1003 1.1 christos *ptr++ = n >> 4;
1004 1.1 christos case 1:
1005 1.1 christos *ptr++ = n >> 0;
1006 1.1 christos break;
1007 1.1 christos }
1008 1.1 christos return ptr;
1009 1.1 christos }
1010 1.1 christos
1011 1.1 christos /* Now we know what sort of opcodes it is. Let's build the bytes. */
1012 1.1 christos
1013 1.1 christos static void
1014 1.1 christos build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED)
1015 1.1 christos {
1016 1.1 christos char *output_ptr = buffer;
1017 1.1 christos int c;
1018 1.1 christos int nibble;
1019 1.1 christos unsigned int *class_ptr;
1020 1.1 christos
1021 1.1 christos frag_wane (frag_now);
1022 1.1 christos frag_new (0);
1023 1.1 christos
1024 1.1 christos if (frag_room () < 8)
1025 1.1 christos frag_grow (8); /* Make room for maximum instruction size. */
1026 1.1 christos
1027 1.1 christos memset (buffer, 0, sizeof (buffer));
1028 1.1 christos class_ptr = this_try->byte_info;
1029 1.1 christos
1030 1.1 christos for (nibble = 0; (c = *class_ptr++); nibble++)
1031 1.1 christos {
1032 1.1 christos
1033 1.1 christos switch (c & CLASS_MASK)
1034 1.1 christos {
1035 1.1 christos default:
1036 1.1 christos abort ();
1037 1.1 christos
1038 1.1 christos case CLASS_ADDRESS:
1039 1.1 christos /* Direct address, we don't cope with the SS mode right now. */
1040 1.1 christos if (segmented_mode)
1041 1.1 christos {
1042 1.1 christos /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */
1043 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8);
1044 1.1 christos }
1045 1.1 christos else
1046 1.1 christos {
1047 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
1048 1.1 christos }
1049 1.1 christos da_operand = 0;
1050 1.1 christos break;
1051 1.1 christos case CLASS_DISP8:
1052 1.1 christos /* pc rel 8 bit */
1053 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2);
1054 1.1 christos da_operand = 0;
1055 1.1 christos break;
1056 1.1 christos
1057 1.1 christos case CLASS_0DISP7:
1058 1.1 christos /* pc rel 7 bit */
1059 1.1 christos *output_ptr = 0;
1060 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
1061 1.1 christos da_operand = 0;
1062 1.1 christos break;
1063 1.1 christos
1064 1.1 christos case CLASS_1DISP7:
1065 1.1 christos /* pc rel 7 bit */
1066 1.1 christos *output_ptr = 0x80;
1067 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
1068 1.1 christos output_ptr[-2] = 0x8;
1069 1.1 christos da_operand = 0;
1070 1.1 christos break;
1071 1.1 christos
1072 1.1 christos case CLASS_BIT_1OR2:
1073 1.1 christos *output_ptr = c & 0xf;
1074 1.1 christos if (imm_operand)
1075 1.1 christos {
1076 1.1 christos if (imm_operand->X_add_number == 2)
1077 1.1 christos *output_ptr |= 2;
1078 1.1 christos else if (imm_operand->X_add_number != 1)
1079 1.1 christos as_bad (_("immediate must be 1 or 2"));
1080 1.1 christos }
1081 1.1 christos else
1082 1.1 christos as_bad (_("immediate 1 or 2 expected"));
1083 1.1 christos output_ptr++;
1084 1.1 christos break;
1085 1.1 christos case CLASS_CC:
1086 1.1 christos *output_ptr++ = the_cc;
1087 1.1 christos break;
1088 1.1 christos case CLASS_0CCC:
1089 1.1 christos if (the_ctrl < 2 || the_ctrl > 7)
1090 1.1 christos as_bad (_("invalid control register name"));
1091 1.1 christos *output_ptr++ = the_ctrl;
1092 1.1 christos break;
1093 1.1 christos case CLASS_1CCC:
1094 1.1 christos if (the_ctrl < 2 || the_ctrl > 7)
1095 1.1 christos as_bad (_("invalid control register name"));
1096 1.1 christos *output_ptr++ = the_ctrl | 0x8;
1097 1.1 christos break;
1098 1.1 christos case CLASS_00II:
1099 1.1 christos *output_ptr++ = (~the_interrupt & 0x3);
1100 1.1 christos break;
1101 1.1 christos case CLASS_01II:
1102 1.1 christos *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
1103 1.1 christos break;
1104 1.1 christos case CLASS_FLAGS:
1105 1.1 christos *output_ptr++ = the_flags;
1106 1.1 christos break;
1107 1.1 christos case CLASS_IGNORE:
1108 1.1 christos case CLASS_BIT:
1109 1.1 christos *output_ptr++ = c & 0xf;
1110 1.1 christos break;
1111 1.1 christos case CLASS_REGN0:
1112 1.1 christos if (reg[c & 0xf] == 0)
1113 1.1 christos as_bad (_("can't use R0 here"));
1114 1.1 christos /* Fall through. */
1115 1.1 christos case CLASS_REG:
1116 1.1 christos case CLASS_REG_BYTE:
1117 1.1 christos case CLASS_REG_WORD:
1118 1.1 christos case CLASS_REG_LONG:
1119 1.1 christos case CLASS_REG_QUAD:
1120 1.1 christos /* Insert bit mattern of right reg. */
1121 1.1 christos *output_ptr++ = reg[c & 0xf];
1122 1.1 christos break;
1123 1.1 christos case CLASS_DISP:
1124 1.1 christos switch (c & ARG_MASK)
1125 1.1 christos {
1126 1.1 christos case ARG_DISP12:
1127 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4);
1128 1.1 christos break;
1129 1.1 christos case ARG_DISP16:
1130 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4);
1131 1.1 christos break;
1132 1.1 christos default:
1133 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
1134 1.1 christos }
1135 1.1 christos da_operand = 0;
1136 1.1 christos break;
1137 1.1 christos
1138 1.1 christos case CLASS_IMM:
1139 1.1 christos {
1140 1.1 christos switch (c & ARG_MASK)
1141 1.1 christos {
1142 1.1 christos case ARG_NIM4:
1143 1.1 christos if (imm_operand->X_add_number > 15)
1144 1.1 christos as_bad (_("immediate value out of range"));
1145 1.1 christos imm_operand->X_add_number = -imm_operand->X_add_number;
1146 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
1147 1.1 christos break;
1148 1.1 christos /*case ARG_IMMNMINUS1: not used. */
1149 1.1 christos case ARG_IMM4M1:
1150 1.1 christos imm_operand->X_add_number--;
1151 1.1 christos /* Drop through. */
1152 1.1 christos case ARG_IMM4:
1153 1.1 christos if (imm_operand->X_add_number > 15)
1154 1.1 christos as_bad (_("immediate value out of range"));
1155 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
1156 1.1 christos break;
1157 1.1 christos case ARG_NIM8:
1158 1.1 christos imm_operand->X_add_number = -imm_operand->X_add_number;
1159 1.1 christos /* Drop through. */
1160 1.1 christos case ARG_IMM8:
1161 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2);
1162 1.1 christos break;
1163 1.1 christos case ARG_IMM16:
1164 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4);
1165 1.1 christos break;
1166 1.1 christos case ARG_IMM32:
1167 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8);
1168 1.1 christos break;
1169 1.1 christos default:
1170 1.1 christos abort ();
1171 1.1 christos }
1172 1.1 christos }
1173 1.1 christos }
1174 1.1 christos }
1175 1.1 christos
1176 1.1 christos /* Copy from the nibble buffer into the frag. */
1177 1.1 christos {
1178 1.1 christos int length = (output_ptr - buffer) / 2;
1179 1.1 christos char *src = buffer;
1180 1.1 christos char *fragp = frag_more (length);
1181 1.1 christos
1182 1.1 christos while (src < output_ptr)
1183 1.1 christos {
1184 1.1 christos *fragp = (src[0] << 4) | src[1];
1185 1.1 christos src += 2;
1186 1.1 christos fragp++;
1187 1.1 christos }
1188 1.1 christos }
1189 1.1 christos }
1190 1.1 christos
1191 1.1 christos /* This is the guts of the machine-dependent assembler. STR points to a
1192 1.1 christos machine dependent instruction. This function is supposed to emit
1193 1.1 christos the frags/bytes it assembles to. */
1194 1.1 christos
1195 1.1 christos void
1196 1.1 christos md_assemble (char *str)
1197 1.1 christos {
1198 1.1 christos char c;
1199 1.1 christos char *op_start;
1200 1.1 christos char *op_end;
1201 1.1 christos struct z8k_op operand[4];
1202 1.1 christos opcode_entry_type *opcode;
1203 1.1 christos
1204 1.1 christos /* Drop leading whitespace. */
1205 1.1 christos while (*str == ' ')
1206 1.1 christos str++;
1207 1.1 christos
1208 1.1 christos /* Find the op code end. */
1209 1.1 christos for (op_start = op_end = str;
1210 1.1 christos *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end];
1211 1.1 christos op_end++)
1212 1.1 christos ;
1213 1.1 christos
1214 1.1 christos if (op_end == op_start)
1215 1.1 christos {
1216 1.1 christos as_bad (_("can't find opcode "));
1217 1.1 christos }
1218 1.1 christos c = *op_end;
1219 1.1 christos
1220 1.1 christos *op_end = 0; /* Zero-terminate op code string for hash_find() call. */
1221 1.1 christos
1222 1.1 christos opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
1223 1.1 christos
1224 1.1 christos if (opcode == NULL)
1225 1.1 christos {
1226 1.1 christos as_bad (_("unknown opcode"));
1227 1.1 christos return;
1228 1.1 christos }
1229 1.1 christos
1230 1.1 christos *op_end = c; /* Restore original string. */
1231 1.1 christos
1232 1.1 christos if (opcode->opcode == 250)
1233 1.1 christos {
1234 1.1 christos pseudo_typeS *p;
1235 1.1 christos char oc;
1236 1.1 christos char *old = input_line_pointer;
1237 1.1 christos
1238 1.1 christos /* Was really a pseudo op. */
1239 1.1 christos
1240 1.1 christos input_line_pointer = op_end;
1241 1.1 christos
1242 1.1 christos oc = *old;
1243 1.1 christos *old = '\n';
1244 1.1 christos while (*input_line_pointer == ' ')
1245 1.1 christos input_line_pointer++;
1246 1.1 christos p = (pseudo_typeS *) (opcode->func);
1247 1.1 christos
1248 1.1 christos (p->poc_handler) (p->poc_val);
1249 1.1 christos input_line_pointer = old;
1250 1.1 christos *old = oc;
1251 1.1 christos }
1252 1.1 christos else
1253 1.1 christos {
1254 1.1 christos char *new_input_line_pointer;
1255 1.1 christos
1256 1.1 christos new_input_line_pointer = get_operands (opcode, op_end, operand);
1257 1.1 christos if (new_input_line_pointer)
1258 1.1 christos {
1259 1.1 christos input_line_pointer = new_input_line_pointer;
1260 1.1 christos opcode = get_specific (opcode, operand);
1261 1.1 christos }
1262 1.1 christos
1263 1.1 christos if (new_input_line_pointer == NULL || opcode == NULL)
1264 1.1 christos {
1265 1.1 christos /* Couldn't find an opcode which matched the operands. */
1266 1.1 christos char *where = frag_more (2);
1267 1.1 christos
1268 1.1 christos where[0] = 0x0;
1269 1.1 christos where[1] = 0x0;
1270 1.1 christos
1271 1.1 christos as_bad (_("Can't find opcode to match operands"));
1272 1.1 christos return;
1273 1.1 christos }
1274 1.1 christos
1275 1.1 christos build_bytes (opcode, operand);
1276 1.1 christos }
1277 1.1 christos }
1278 1.1 christos
1279 1.1 christos /* We have no need to default values of symbols. */
1280 1.1 christos
1281 1.1 christos symbolS *
1282 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1283 1.1 christos {
1284 1.1 christos return 0;
1285 1.1 christos }
1286 1.1 christos
1287 1.1 christos /* Various routines to kill one day. */
1288 1.1 christos
1289 1.1 christos char *
1290 1.1 christos md_atof (int type, char *litP, int *sizeP)
1291 1.1 christos {
1292 1.1 christos return ieee_md_atof (type, litP, sizeP, TRUE);
1293 1.1 christos }
1294 1.1 christos
1295 1.1 christos const char *md_shortopts = "z:";
1297 1.1 christos
1298 1.1 christos struct option md_longopts[] =
1299 1.1 christos {
1300 1.1 christos #define OPTION_RELAX (OPTION_MD_BASE)
1301 1.1 christos {"linkrelax", no_argument, NULL, OPTION_RELAX},
1302 1.1 christos {NULL, no_argument, NULL, 0}
1303 1.1 christos };
1304 1.1 christos
1305 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
1306 1.1 christos
1307 1.1 christos int
1308 1.1 christos md_parse_option (int c, char *arg)
1309 1.1 christos {
1310 1.1 christos switch (c)
1311 1.1 christos {
1312 1.1 christos case 'z':
1313 1.1 christos if (!strcmp (arg, "8001"))
1314 1.1 christos s_segm (1);
1315 1.1 christos else if (!strcmp (arg, "8002"))
1316 1.1 christos s_segm (0);
1317 1.1 christos else
1318 1.1 christos {
1319 1.1 christos as_bad (_("invalid architecture -z%s"), arg);
1320 1.1 christos return 0;
1321 1.1 christos }
1322 1.1 christos z8k_target_from_cmdline = 1;
1323 1.1 christos break;
1324 1.1 christos
1325 1.1 christos case OPTION_RELAX:
1326 1.1 christos linkrelax = 1;
1327 1.1 christos break;
1328 1.1 christos
1329 1.1 christos default:
1330 1.1 christos return 0;
1331 1.1 christos }
1332 1.1 christos
1333 1.1 christos return 1;
1334 1.1 christos }
1335 1.1 christos
1336 1.1 christos void
1337 1.1 christos md_show_usage (FILE *stream)
1338 1.1 christos {
1339 1.1 christos fprintf (stream, _("\
1340 1.1 christos Z8K options:\n\
1341 1.1 christos -z8001 generate segmented code\n\
1342 1.1 christos -z8002 generate unsegmented code\n\
1343 1.1 christos -linkrelax create linker relaxable code\n"));
1344 1.1 christos }
1345 1.1 christos
1346 1.1 christos void
1348 1.1 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1349 1.1 christos segT sec ATTRIBUTE_UNUSED,
1350 1.1 christos fragS *fragP ATTRIBUTE_UNUSED)
1351 1.1 christos {
1352 1.1 christos printf (_("call to md_convert_frag\n"));
1353 1.1 christos abort ();
1354 1.1 christos }
1355 1.1 christos
1356 1.1 christos /* Generate a machine dependent reloc from a fixup. */
1357 1.1 christos
1358 1.1 christos arelent*
1359 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1360 1.1 christos fixS *fixp ATTRIBUTE_UNUSED)
1361 1.1 christos {
1362 1.1 christos arelent *reloc;
1363 1.1 christos
1364 1.1 christos reloc = xmalloc (sizeof (*reloc));
1365 1.1 christos reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1366 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1367 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1368 1.1 christos reloc->addend = fixp->fx_offset;
1369 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1370 1.1 christos
1371 1.1 christos if (! reloc->howto)
1372 1.1 christos {
1373 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
1374 1.1 christos _("Cannot represent %s relocation in object file"),
1375 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type));
1376 1.1 christos abort ();
1377 1.1 christos }
1378 1.1 christos return reloc;
1379 1.1 christos }
1380 1.1 christos
1381 1.1 christos valueT
1382 1.1 christos md_section_align (segT seg, valueT size)
1383 1.1 christos {
1384 1.1 christos int align = bfd_get_section_alignment (stdoutput, seg);
1385 1.1 christos valueT mask = ((valueT) 1 << align) - 1;
1386 1.1 christos
1387 1.1 christos return (size + mask) & ~mask;
1388 1.1 christos }
1389 1.1 christos
1390 1.1 christos /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1391 1.1 christos has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1392 1.1 christos we will have to generate a reloc entry. */
1393 1.1 christos void
1394 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
1395 1.1 christos {
1396 1.1 christos long val = * (long *) valP;
1397 1.1 christos char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1398 1.1 christos
1399 1.1 christos switch (fixP->fx_r_type)
1400 1.1 christos {
1401 1.1 christos case BFD_RELOC_Z8K_IMM4L:
1402 1.1 christos if (fixP->fx_addsy)
1403 1.1 christos {
1404 1.1 christos fixP->fx_no_overflow = 1;
1405 1.1 christos fixP->fx_done = 0;
1406 1.1 christos }
1407 1.1 christos else
1408 1.1 christos buf[0] = (buf[0] & 0xf0) | (val & 0xf);
1409 1.1 christos break;
1410 1.1 christos
1411 1.1 christos case BFD_RELOC_8:
1412 1.1 christos if (fixP->fx_addsy)
1413 1.1 christos {
1414 1.1 christos fixP->fx_no_overflow = 1;
1415 1.1 christos fixP->fx_done = 0;
1416 1.1 christos }
1417 1.1 christos else
1418 1.1 christos *buf++ = val;
1419 1.1 christos break;
1420 1.1 christos
1421 1.1 christos case BFD_RELOC_16:
1422 1.1 christos if (fixP->fx_addsy)
1423 1.1 christos {
1424 1.1 christos fixP->fx_no_overflow = 1;
1425 1.1 christos fixP->fx_done = 0;
1426 1.1 christos }
1427 1.1 christos else
1428 1.1 christos {
1429 1.1 christos *buf++ = (val >> 8);
1430 1.1 christos *buf++ = val;
1431 1.1 christos }
1432 1.1 christos break;
1433 1.1 christos
1434 1.1 christos case BFD_RELOC_32:
1435 1.1 christos if (fixP->fx_addsy)
1436 1.1 christos {
1437 1.1 christos fixP->fx_no_overflow = 1;
1438 1.1 christos fixP->fx_done = 0;
1439 1.1 christos }
1440 1.1 christos else
1441 1.1 christos {
1442 1.1 christos *buf++ = (val >> 24);
1443 1.1 christos *buf++ = (val >> 16);
1444 1.1 christos *buf++ = (val >> 8);
1445 1.1 christos *buf++ = val;
1446 1.1 christos }
1447 1.1 christos break;
1448 1.1 christos
1449 1.1 christos case BFD_RELOC_8_PCREL:
1450 1.1 christos if (fixP->fx_addsy)
1451 1.1 christos {
1452 1.1 christos fixP->fx_no_overflow = 1;
1453 1.1 christos fixP->fx_done = 0;
1454 1.1 christos }
1455 1.1 christos else
1456 1.1 christos {
1457 1.1 christos if (val & 1)
1458 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1459 1.1 christos _("cannot branch to odd address"));
1460 1.1 christos val /= 2;
1461 1.1 christos if (val > 127 || val < -128)
1462 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1463 1.1 christos _("relative jump out of range"));
1464 1.1 christos *buf++ = val;
1465 1.1 christos fixP->fx_no_overflow = 1;
1466 1.1 christos fixP->fx_done = 1;
1467 1.1 christos }
1468 1.1 christos break;
1469 1.1 christos
1470 1.1 christos case BFD_RELOC_16_PCREL:
1471 1.1 christos if (fixP->fx_addsy)
1472 1.1 christos {
1473 1.1 christos fixP->fx_no_overflow = 1;
1474 1.1 christos fixP->fx_done = 0;
1475 1.1 christos }
1476 1.1 christos else
1477 1.1 christos {
1478 1.1 christos val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
1479 1.1 christos if (val > 32767 || val < -32768)
1480 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1481 1.1 christos _("relative address out of range"));
1482 1.1 christos *buf++ = (val >> 8);
1483 1.1 christos *buf++ = val;
1484 1.1 christos fixP->fx_no_overflow = 1;
1485 1.1 christos fixP->fx_done = 1;
1486 1.1 christos }
1487 1.1 christos break;
1488 1.1 christos
1489 1.1 christos case BFD_RELOC_Z8K_CALLR:
1490 1.1 christos if (fixP->fx_addsy)
1491 1.1 christos {
1492 1.1 christos fixP->fx_no_overflow = 1;
1493 1.1 christos fixP->fx_done = 0;
1494 1.1 christos }
1495 1.1 christos else
1496 1.1 christos {
1497 1.1 christos if (val & 1)
1498 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1499 1.1 christos _("cannot branch to odd address"));
1500 1.1 christos if (val > 4096 || val < -4095)
1501 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1502 1.1 christos _("relative call out of range"));
1503 1.1 christos val = -val / 2;
1504 1.1 christos *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
1505 1.1 christos buf++;
1506 1.1 christos *buf++ = val & 0xff;
1507 1.1 christos fixP->fx_no_overflow = 1;
1508 1.1 christos fixP->fx_done = 1;
1509 1.1 christos }
1510 1.1 christos break;
1511 1.1 christos
1512 1.1 christos case BFD_RELOC_Z8K_DISP7:
1513 1.1 christos if (fixP->fx_addsy)
1514 1.1 christos {
1515 1.1 christos fixP->fx_no_overflow = 1;
1516 1.1 christos fixP->fx_done = 0;
1517 1.1 christos }
1518 1.1 christos else
1519 1.1 christos {
1520 1.1 christos if (val & 1)
1521 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1522 1.1 christos _("cannot branch to odd address"));
1523 1.1 christos val /= 2;
1524 1.1 christos if (val > 0 || val < -127)
1525 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
1526 1.1 christos _("relative jump out of range"));
1527 1.1 christos *buf = (*buf & 0x80) | (-val & 0x7f);
1528 1.1 christos fixP->fx_no_overflow = 1;
1529 1.1 christos fixP->fx_done = 1;
1530 1.1 christos }
1531 1.1 christos break;
1532 1.1 christos
1533 1.1 christos default:
1534 1.1 christos printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
1535 1.1 christos abort ();
1536 1.1 christos }
1537 1.1 christos
1538 1.1 christos if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1539 1.1 christos fixP->fx_done = 1;
1540 1.1 christos }
1541 1.1 christos
1542 1.1 christos int
1543 1.1 christos md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1544 1.1 christos segT segment_type ATTRIBUTE_UNUSED)
1545 1.1 christos {
1546 1.1 christos printf (_("call to md_estimate_size_before_relax\n"));
1547 1.1 christos abort ();
1548 1.1 christos }
1549 1.1 christos
1550 1.1 christos /* Put number into target byte order. */
1551 1.1 christos
1552 1.1 christos void
1553 1.1 christos md_number_to_chars (char *ptr, valueT use, int nbytes)
1554 1.1 christos {
1555 1.1 christos number_to_chars_bigendian (ptr, use, nbytes);
1556 1.1 christos }
1557 1.1 christos
1558 1.1 christos /* On the Z8000, a PC-relative offset is relative to the address of the
1559 1.1 christos instruction plus its size. */
1560 1.1 christos long
1561 1.1 christos md_pcrel_from (fixS *fixP)
1562 1.1 christos {
1563 1.1 christos return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1564 1.1 christos }
1565 1.1 christos
1566 1.1 christos void
1567 1.1 christos tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)
1568 {
1569 }
1570