]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-z8k.c
Remove SIM_CHECK_MEMBER* in sim/common/.
[thirdparty/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 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"))
7f31df7c 1313 s_segm (1);
252b5132 1314 else if (!strcmp (arg, "8002"))
7f31df7c 1315 s_segm (0);
252b5132
RH
1316 else
1317 {
1318 as_bad (_("invalid architecture -z%s"), arg);
1319 return 0;
1320 }
7f31df7c
CG
1321 z8k_target_from_cmdline = 1;
1322 break;
1323
1324 case OPTION_RELAX:
1325 linkrelax = 1;
252b5132
RH
1326 break;
1327
1328 default:
1329 return 0;
1330 }
1331
1332 return 1;
1333}
1334
1335void
464800ca 1336md_show_usage (FILE *stream)
252b5132 1337{
e0c6ed95 1338 fprintf (stream, _("\
7f31df7c
CG
1339 Z8K options:\n\
1340 -z8001 generate segmented code\n\
1341 -z8002 generate unsegmented code\n\
1342 -linkrelax create linker relaxable code\n"));
252b5132
RH
1343}
1344\f
252b5132 1345void
c0524131
NC
1346md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1347 segT sec ATTRIBUTE_UNUSED,
464800ca 1348 fragS *fragP ATTRIBUTE_UNUSED)
252b5132 1349{
7f31df7c 1350 printf (_("call to md_convert_frag\n"));
252b5132
RH
1351 abort ();
1352}
1353
c0524131
NC
1354/* Generate a machine dependent reloc from a fixup. */
1355
1356arelent*
1357tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1358 fixS *fixp ATTRIBUTE_UNUSED)
1359{
1360 arelent *reloc;
1361
1362 reloc = xmalloc (sizeof (*reloc));
1363 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1364 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1365 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1366 reloc->addend = fixp->fx_offset;
1367 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1368
1369 if (! reloc->howto)
1370 {
1371 as_bad_where (fixp->fx_file, fixp->fx_line,
20203fb9 1372 _("Cannot represent %s relocation in object file"),
c0524131
NC
1373 bfd_get_reloc_code_name (fixp->fx_r_type));
1374 abort ();
1375 }
1376 return reloc;
1377}
1378
252b5132 1379valueT
464800ca 1380md_section_align (segT seg, valueT size)
252b5132 1381{
c0524131
NC
1382 int align = bfd_get_section_alignment (stdoutput, seg);
1383 valueT mask = ((valueT) 1 << align) - 1;
1384
1385 return (size + mask) & ~mask;
252b5132
RH
1386}
1387
a72d6b4e
CG
1388/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1389 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1390 we will have to generate a reloc entry. */
252b5132 1391void
55cf6793 1392md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
252b5132 1393{
94f592af 1394 long val = * (long *) valP;
252b5132
RH
1395 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1396
1397 switch (fixP->fx_r_type)
1398 {
c0524131
NC
1399 case BFD_RELOC_Z8K_IMM4L:
1400 if (fixP->fx_addsy)
1401 {
1402 fixP->fx_no_overflow = 1;
1403 fixP->fx_done = 0;
1404 }
1405 else
1406 buf[0] = (buf[0] & 0xf0) | (val & 0xf);
1407 break;
1408
1409 case BFD_RELOC_8:
1410 if (fixP->fx_addsy)
1411 {
1412 fixP->fx_no_overflow = 1;
1413 fixP->fx_done = 0;
1414 }
1415 else
1416 *buf++ = val;
1417 break;
1418
1419 case BFD_RELOC_16:
1420 if (fixP->fx_addsy)
1421 {
1422 fixP->fx_no_overflow = 1;
1423 fixP->fx_done = 0;
1424 }
1425 else
1426 {
1427 *buf++ = (val >> 8);
1428 *buf++ = val;
1429 }
1430 break;
1431
1432 case BFD_RELOC_32:
1433 if (fixP->fx_addsy)
1434 {
1435 fixP->fx_no_overflow = 1;
1436 fixP->fx_done = 0;
1437 }
1438 else
1439 {
1440 *buf++ = (val >> 24);
1441 *buf++ = (val >> 16);
1442 *buf++ = (val >> 8);
1443 *buf++ = val;
1444 }
252b5132
RH
1445 break;
1446
c0524131 1447 case BFD_RELOC_8_PCREL:
a72d6b4e
CG
1448 if (fixP->fx_addsy)
1449 {
1450 fixP->fx_no_overflow = 1;
1451 fixP->fx_done = 0;
1452 }
1453 else
1454 {
f87a1e0c
CG
1455 if (val & 1)
1456 as_bad_where (fixP->fx_file, fixP->fx_line,
1457 _("cannot branch to odd address"));
1458 val /= 2;
1459 if (val > 127 || val < -128)
befd69ef
CG
1460 as_bad_where (fixP->fx_file, fixP->fx_line,
1461 _("relative jump out of range"));
f87a1e0c
CG
1462 *buf++ = val;
1463 fixP->fx_no_overflow = 1;
a72d6b4e
CG
1464 fixP->fx_done = 1;
1465 }
252b5132
RH
1466 break;
1467
c0524131 1468 case BFD_RELOC_16_PCREL:
a72d6b4e
CG
1469 if (fixP->fx_addsy)
1470 {
1471 fixP->fx_no_overflow = 1;
1472 fixP->fx_done = 0;
1473 }
1474 else
1475 {
c0524131
NC
1476 val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
1477 if (val > 32767 || val < -32768)
f87a1e0c 1478 as_bad_where (fixP->fx_file, fixP->fx_line,
c0524131
NC
1479 _("relative address out of range"));
1480 *buf++ = (val >> 8);
1481 *buf++ = val;
d5bf5799 1482 fixP->fx_no_overflow = 1;
a72d6b4e
CG
1483 fixP->fx_done = 1;
1484 }
7f31df7c 1485 break;
252b5132 1486
c0524131 1487 case BFD_RELOC_Z8K_CALLR:
a72d6b4e
CG
1488 if (fixP->fx_addsy)
1489 {
1490 fixP->fx_no_overflow = 1;
1491 fixP->fx_done = 0;
1492 }
1493 else
1494 {
1495 if (val & 1)
f87a1e0c
CG
1496 as_bad_where (fixP->fx_file, fixP->fx_line,
1497 _("cannot branch to odd address"));
a72d6b4e 1498 if (val > 4096 || val < -4095)
f87a1e0c
CG
1499 as_bad_where (fixP->fx_file, fixP->fx_line,
1500 _("relative call out of range"));
a72d6b4e 1501 val = -val / 2;
d5bf5799
CG
1502 *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
1503 buf++;
1504 *buf++ = val & 0xff;
a72d6b4e
CG
1505 fixP->fx_no_overflow = 1;
1506 fixP->fx_done = 1;
1507 }
252b5132
RH
1508 break;
1509
c0524131
NC
1510 case BFD_RELOC_Z8K_DISP7:
1511 if (fixP->fx_addsy)
1512 {
1513 fixP->fx_no_overflow = 1;
1514 fixP->fx_done = 0;
1515 }
1516 else
1517 {
1518 if (val & 1)
1519 as_bad_where (fixP->fx_file, fixP->fx_line,
1520 _("cannot branch to odd address"));
1521 val /= 2;
1522 if (val > 0 || val < -127)
1523 as_bad_where (fixP->fx_file, fixP->fx_line,
1524 _("relative jump out of range"));
1525 *buf = (*buf & 0x80) | (-val & 0x7f);
1526 fixP->fx_no_overflow = 1;
1527 fixP->fx_done = 1;
1528 }
252b5132
RH
1529 break;
1530
1531 default:
55cf6793 1532 printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
252b5132 1533 abort ();
252b5132 1534 }
94f592af
NC
1535
1536 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1537 fixP->fx_done = 1;
252b5132
RH
1538}
1539
1540int
464800ca
CG
1541md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1542 segT segment_type ATTRIBUTE_UNUSED)
252b5132 1543{
7f31df7c 1544 printf (_("call to md_estimate_size_before_relax\n"));
252b5132
RH
1545 abort ();
1546}
1547
e0c6ed95 1548/* Put number into target byte order. */
252b5132
RH
1549
1550void
464800ca 1551md_number_to_chars (char *ptr, valueT use, int nbytes)
252b5132
RH
1552{
1553 number_to_chars_bigendian (ptr, use, nbytes);
1554}
e0c6ed95 1555
a72d6b4e
CG
1556/* On the Z8000, a PC-relative offset is relative to the address of the
1557 instruction plus its size. */
252b5132 1558long
464800ca 1559md_pcrel_from (fixS *fixP)
252b5132 1560{
a72d6b4e 1561 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
252b5132
RH
1562}
1563
1564void
464800ca 1565tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)
252b5132
RH
1566{
1567}