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