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