[PATCH, COMMITTED] [AArch64] Replace the :got_prel19: address modifier with :got:
[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,
00a3147e 3 2005, 2006, 2007, 2009, 2013 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
00a3147e
CG
37/* This is non-zero if target was set from the command line.
38 If non-zero, 1 means Z8002 (non-segmented), 2 means Z8001 (segmented). */
7f31df7c
CG
39static int z8k_target_from_cmdline;
40
78a33af2 41static void
464800ca 42s_segm (int segm)
252b5132 43{
7f31df7c
CG
44 if (segm)
45 {
d5bf5799 46 segmented_mode = 1;
c0524131 47 bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001);
7f31df7c
CG
48 }
49 else
50 {
d5bf5799 51 segmented_mode = 0;
c0524131 52 bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002);
7f31df7c 53 }
252b5132
RH
54}
55
e0c6ed95 56static void
464800ca 57even (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
58{
59 frag_align (1, 0, 0);
60 record_alignment (now_seg, 1);
61}
62
78a33af2 63static int
464800ca 64tohex (int c)
252b5132 65{
3882b010 66 if (ISDIGIT (c))
252b5132 67 return c - '0';
3882b010 68 if (ISLOWER (c))
252b5132
RH
69 return c - 'a' + 10;
70 return c - 'A' + 10;
71}
72
78a33af2 73static void
464800ca 74sval (int ignore ATTRIBUTE_UNUSED)
252b5132 75{
252b5132
RH
76 SKIP_WHITESPACE ();
77 if (*input_line_pointer == '\'')
78 {
79 int c;
80 input_line_pointer++;
81 c = *input_line_pointer++;
82 while (c != '\'')
83 {
84 if (c == '%')
85 {
86 c = (tohex (input_line_pointer[0]) << 4)
87 | tohex (input_line_pointer[1]);
88 input_line_pointer += 2;
89 }
90 FRAG_APPEND_1_CHAR (c);
91 c = *input_line_pointer++;
92 }
93 demand_empty_rest_of_line ();
94 }
252b5132 95}
e0c6ed95
AM
96
97/* This table describes all the machine specific pseudo-ops the assembler
98 has to support. The fields are:
99 pseudo-op name without dot
100 function to call to execute this pseudo-op
101 Integer arg to pass to the function
102 */
103
104const pseudo_typeS md_pseudo_table[] = {
105 {"int" , cons , 2},
106 {"data.b" , cons , 1},
107 {"data.w" , cons , 2},
108 {"data.l" , cons , 4},
109 {"form" , listing_psize , 0},
110 {"heading", listing_title , 0},
111 {"import" , s_ignore , 0},
112 {"page" , listing_eject , 0},
113 {"program", s_ignore , 0},
7f31df7c
CG
114 {"z8001" , s_segm , 1},
115 {"z8002" , s_segm , 0},
e0c6ed95 116
7f31df7c
CG
117 {"segm" , s_segm , 1},
118 {"unsegm" , s_segm , 0},
119 {"unseg" , s_segm , 0},
e0c6ed95
AM
120 {"name" , s_app_file , 0},
121 {"global" , s_globl , 0},
122 {"wval" , cons , 2},
123 {"lval" , cons , 4},
124 {"bval" , cons , 1},
125 {"sval" , sval , 0},
126 {"rsect" , obj_coff_section, 0},
127 {"sect" , obj_coff_section, 0},
128 {"block" , s_space , 0},
129 {"even" , even , 0},
130 {0 , 0 , 0}
252b5132
RH
131};
132
133const char EXP_CHARS[] = "eE";
134
e0c6ed95
AM
135/* Chars that mean this number is a floating point constant.
136 As in 0f12.456
137 or 0d1.2345e12 */
252b5132
RH
138const char FLT_CHARS[] = "rRsSfFdDxXpP";
139
e0c6ed95
AM
140/* Opcode mnemonics. */
141static struct hash_control *opcode_hash_control;
252b5132
RH
142
143void
464800ca 144md_begin (void)
252b5132 145{
78a33af2
AM
146 const opcode_entry_type *opcode;
147 int idx = -1;
252b5132
RH
148
149 opcode_hash_control = hash_new ();
150
151 for (opcode = z8k_table; opcode->name; opcode++)
152 {
e0c6ed95 153 /* Only enter unique codes into the table. */
78a33af2
AM
154 if (idx != opcode->idx)
155 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
156 idx = opcode->idx;
252b5132
RH
157 }
158
e0c6ed95 159 /* Default to z8002. */
00a3147e 160 s_segm (z8k_target_from_cmdline ? z8k_target_from_cmdline - 1 : 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 *
91d6fa6a 206whatreg (unsigned int *preg, 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
91d6fa6a 225 *preg = new_reg;
41d3b056 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 *
91d6fa6a 247parse_reg (char *src, int *mode, unsigned int *preg)
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;
91d6fa6a 260 *preg = 14;
e0c6ed95 261 }
252b5132 262 else
e0c6ed95
AM
263 {
264 *mode = CLASS_REG_WORD;
91d6fa6a 265 *preg = 15;
e0c6ed95 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 276 *mode = CLASS_REG_LONG;
91d6fa6a 277 res = whatreg (preg, src + 2);
41d3b056
CG
278 if (res == NULL)
279 return NULL; /* Not a valid register name. */
91d6fa6a 280 regno = *preg;
252b5132 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 290 *mode = CLASS_REG_BYTE;
91d6fa6a 291 res = whatreg (preg, src + 2);
41d3b056
CG
292 if (res == NULL)
293 return NULL; /* Not a valid register name. */
91d6fa6a 294 regno = *preg;
252b5132 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 302 *mode = CLASS_REG_BYTE;
91d6fa6a 303 res = whatreg (preg, src + 2);
41d3b056
CG
304 if (res == NULL)
305 return NULL; /* Not a valid register name. */
91d6fa6a 306 regno = *preg;
252b5132 307 if (regno > 7)
f590b86e 308 as_bad (_("register rl%d out of range"), regno);
91d6fa6a 309 *preg += 8;
e0c6ed95 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 315 *mode = CLASS_REG_QUAD;
91d6fa6a 316 res = whatreg (preg, src + 2);
41d3b056
CG
317 if (res == NULL)
318 return NULL; /* Not a valid register name. */
91d6fa6a 319 regno = *preg;
252b5132 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 329 *mode = CLASS_REG_WORD;
91d6fa6a 330 res = whatreg (preg, src + 1);
41d3b056
CG
331 if (res == NULL)
332 return NULL; /* Not a valid register name. */
91d6fa6a 333 regno = *preg;
252b5132 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;
d3ce72d0 345 char *new_pointer;
252b5132
RH
346
347 input_line_pointer = s;
348 expression (op);
349 if (op->X_op == O_absent)
350 as_bad (_("missing operand"));
d3ce72d0 351 new_pointer = input_line_pointer;
252b5132 352 input_line_pointer = save;
d3ce72d0 353 return new_pointer;
252b5132
RH
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 1287/* Various routines to kill one day. */
e0c6ed95 1288
252b5132 1289char *
464800ca 1290md_atof (int type, char *litP, int *sizeP)
252b5132 1291{
499ac353 1292 return ieee_md_atof (type, litP, sizeP, TRUE);
252b5132
RH
1293}
1294\f
5a38dc70 1295const char *md_shortopts = "z:";
e0c6ed95 1296
3c25c5f6
NC
1297struct option md_longopts[] =
1298 {
7f31df7c
CG
1299#define OPTION_RELAX (OPTION_MD_BASE)
1300 {"linkrelax", no_argument, NULL, OPTION_RELAX},
3c25c5f6
NC
1301 {NULL, no_argument, NULL, 0}
1302 };
e0c6ed95
AM
1303
1304size_t md_longopts_size = sizeof (md_longopts);
252b5132
RH
1305
1306int
464800ca 1307md_parse_option (int c, char *arg)
252b5132
RH
1308{
1309 switch (c)
1310 {
1311 case 'z':
1312 if (!strcmp (arg, "8001"))
00a3147e 1313 z8k_target_from_cmdline = 2;
252b5132 1314 else if (!strcmp (arg, "8002"))
00a3147e 1315 z8k_target_from_cmdline = 1;
252b5132
RH
1316 else
1317 {
1318 as_bad (_("invalid architecture -z%s"), arg);
1319 return 0;
1320 }
7f31df7c
CG
1321 break;
1322
1323 case OPTION_RELAX:
1324 linkrelax = 1;
252b5132
RH
1325 break;
1326
1327 default:
1328 return 0;
1329 }
1330
1331 return 1;
1332}
1333
1334void
464800ca 1335md_show_usage (FILE *stream)
252b5132 1336{
e0c6ed95 1337 fprintf (stream, _("\
7f31df7c
CG
1338 Z8K options:\n\
1339 -z8001 generate segmented code\n\
1340 -z8002 generate unsegmented code\n\
1341 -linkrelax create linker relaxable code\n"));
252b5132
RH
1342}
1343\f
252b5132 1344void
c0524131
NC
1345md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1346 segT sec ATTRIBUTE_UNUSED,
464800ca 1347 fragS *fragP ATTRIBUTE_UNUSED)
252b5132 1348{
7f31df7c 1349 printf (_("call to md_convert_frag\n"));
252b5132
RH
1350 abort ();
1351}
1352
c0524131
NC
1353/* Generate a machine dependent reloc from a fixup. */
1354
1355arelent*
1356tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1357 fixS *fixp ATTRIBUTE_UNUSED)
1358{
1359 arelent *reloc;
1360
1361 reloc = xmalloc (sizeof (*reloc));
1362 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1363 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1364 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1365 reloc->addend = fixp->fx_offset;
1366 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1367
1368 if (! reloc->howto)
1369 {
1370 as_bad_where (fixp->fx_file, fixp->fx_line,
20203fb9 1371 _("Cannot represent %s relocation in object file"),
c0524131
NC
1372 bfd_get_reloc_code_name (fixp->fx_r_type));
1373 abort ();
1374 }
1375 return reloc;
1376}
1377
252b5132 1378valueT
464800ca 1379md_section_align (segT seg, valueT size)
252b5132 1380{
c0524131
NC
1381 int align = bfd_get_section_alignment (stdoutput, seg);
1382 valueT mask = ((valueT) 1 << align) - 1;
1383
1384 return (size + mask) & ~mask;
252b5132
RH
1385}
1386
a72d6b4e
CG
1387/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1388 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1389 we will have to generate a reloc entry. */
252b5132 1390void
55cf6793 1391md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
252b5132 1392{
94f592af 1393 long val = * (long *) valP;
252b5132
RH
1394 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1395
1396 switch (fixP->fx_r_type)
1397 {
c0524131
NC
1398 case BFD_RELOC_Z8K_IMM4L:
1399 if (fixP->fx_addsy)
1400 {
1401 fixP->fx_no_overflow = 1;
1402 fixP->fx_done = 0;
1403 }
1404 else
1405 buf[0] = (buf[0] & 0xf0) | (val & 0xf);
1406 break;
1407
1408 case BFD_RELOC_8:
1409 if (fixP->fx_addsy)
1410 {
1411 fixP->fx_no_overflow = 1;
1412 fixP->fx_done = 0;
1413 }
1414 else
1415 *buf++ = val;
1416 break;
1417
1418 case BFD_RELOC_16:
1419 if (fixP->fx_addsy)
1420 {
1421 fixP->fx_no_overflow = 1;
1422 fixP->fx_done = 0;
1423 }
1424 else
1425 {
1426 *buf++ = (val >> 8);
1427 *buf++ = val;
1428 }
1429 break;
1430
1431 case BFD_RELOC_32:
1432 if (fixP->fx_addsy)
1433 {
1434 fixP->fx_no_overflow = 1;
1435 fixP->fx_done = 0;
1436 }
1437 else
1438 {
1439 *buf++ = (val >> 24);
1440 *buf++ = (val >> 16);
1441 *buf++ = (val >> 8);
1442 *buf++ = val;
1443 }
252b5132
RH
1444 break;
1445
c0524131 1446 case BFD_RELOC_8_PCREL:
a72d6b4e
CG
1447 if (fixP->fx_addsy)
1448 {
1449 fixP->fx_no_overflow = 1;
1450 fixP->fx_done = 0;
1451 }
1452 else
1453 {
f87a1e0c
CG
1454 if (val & 1)
1455 as_bad_where (fixP->fx_file, fixP->fx_line,
1456 _("cannot branch to odd address"));
1457 val /= 2;
1458 if (val > 127 || val < -128)
befd69ef
CG
1459 as_bad_where (fixP->fx_file, fixP->fx_line,
1460 _("relative jump out of range"));
f87a1e0c
CG
1461 *buf++ = val;
1462 fixP->fx_no_overflow = 1;
a72d6b4e
CG
1463 fixP->fx_done = 1;
1464 }
252b5132
RH
1465 break;
1466
c0524131 1467 case BFD_RELOC_16_PCREL:
a72d6b4e
CG
1468 if (fixP->fx_addsy)
1469 {
1470 fixP->fx_no_overflow = 1;
1471 fixP->fx_done = 0;
1472 }
1473 else
1474 {
c0524131
NC
1475 val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
1476 if (val > 32767 || val < -32768)
f87a1e0c 1477 as_bad_where (fixP->fx_file, fixP->fx_line,
c0524131
NC
1478 _("relative address out of range"));
1479 *buf++ = (val >> 8);
1480 *buf++ = val;
d5bf5799 1481 fixP->fx_no_overflow = 1;
a72d6b4e
CG
1482 fixP->fx_done = 1;
1483 }
7f31df7c 1484 break;
252b5132 1485
c0524131 1486 case BFD_RELOC_Z8K_CALLR:
a72d6b4e
CG
1487 if (fixP->fx_addsy)
1488 {
1489 fixP->fx_no_overflow = 1;
1490 fixP->fx_done = 0;
1491 }
1492 else
1493 {
1494 if (val & 1)
f87a1e0c
CG
1495 as_bad_where (fixP->fx_file, fixP->fx_line,
1496 _("cannot branch to odd address"));
a72d6b4e 1497 if (val > 4096 || val < -4095)
f87a1e0c
CG
1498 as_bad_where (fixP->fx_file, fixP->fx_line,
1499 _("relative call out of range"));
a72d6b4e 1500 val = -val / 2;
d5bf5799
CG
1501 *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
1502 buf++;
1503 *buf++ = val & 0xff;
a72d6b4e
CG
1504 fixP->fx_no_overflow = 1;
1505 fixP->fx_done = 1;
1506 }
252b5132
RH
1507 break;
1508
c0524131
NC
1509 case BFD_RELOC_Z8K_DISP7:
1510 if (fixP->fx_addsy)
1511 {
1512 fixP->fx_no_overflow = 1;
1513 fixP->fx_done = 0;
1514 }
1515 else
1516 {
1517 if (val & 1)
1518 as_bad_where (fixP->fx_file, fixP->fx_line,
1519 _("cannot branch to odd address"));
1520 val /= 2;
1521 if (val > 0 || val < -127)
1522 as_bad_where (fixP->fx_file, fixP->fx_line,
1523 _("relative jump out of range"));
1524 *buf = (*buf & 0x80) | (-val & 0x7f);
1525 fixP->fx_no_overflow = 1;
1526 fixP->fx_done = 1;
1527 }
252b5132
RH
1528 break;
1529
1530 default:
55cf6793 1531 printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
252b5132 1532 abort ();
252b5132 1533 }
94f592af
NC
1534
1535 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1536 fixP->fx_done = 1;
252b5132
RH
1537}
1538
1539int
464800ca
CG
1540md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1541 segT segment_type ATTRIBUTE_UNUSED)
252b5132 1542{
7f31df7c 1543 printf (_("call to md_estimate_size_before_relax\n"));
252b5132
RH
1544 abort ();
1545}
1546
e0c6ed95 1547/* Put number into target byte order. */
252b5132
RH
1548
1549void
464800ca 1550md_number_to_chars (char *ptr, valueT use, int nbytes)
252b5132
RH
1551{
1552 number_to_chars_bigendian (ptr, use, nbytes);
1553}
e0c6ed95 1554
a72d6b4e
CG
1555/* On the Z8000, a PC-relative offset is relative to the address of the
1556 instruction plus its size. */
252b5132 1557long
464800ca 1558md_pcrel_from (fixS *fixP)
252b5132 1559{
a72d6b4e 1560 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
252b5132
RH
1561}
1562
1563void
464800ca 1564tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)
252b5132
RH
1565{
1566}
This page took 0.68188 seconds and 4 git commands to generate.