These changes clean things up a bit, and improve Solaris cross
[deliverable/binutils-gdb.git] / gas / config / tc-z8k.c
CommitLineData
163107a1
SC
1/* tc-z8k.c -- Assemble code for the Zilog Z800N
2 Copyright (C) 1992 Free Software Foundation.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21/*
22 Written By Steve Chamberlain
23 sac@cygnus.com
24 */
25
26#include <stdio.h>
27#define DEFINE_TABLE
cfb48ce5 28#include "../opcodes/z8k-opc.h"
163107a1
SC
29
30#include "as.h"
587c4264 31#include "read.h"
163107a1
SC
32#include "bfd.h"
33#include <ctype.h>
34#include "listing.h"
35
587c4264
ILT
36const char comment_chars[] = { '!',0 };
37const char line_separator_chars[] = { ';' ,0};
38const char line_comment_chars[] = "";
163107a1
SC
39
40extern int machine;
41extern int coff_flags;
42int segmented_mode;
43int md_reloc_size ;
44
45/* This table describes all the machine specific pseudo-ops the assembler
46 has to support. The fields are:
47 pseudo-op name without dot
48 function to call to execute this pseudo-op
49 Integer arg to pass to the function
50 */
51
52void cons();
53
54
55void s_segm()
56{
57 segmented_mode = 1;
58 machine = bfd_mach_z8001;
59 coff_flags = F_Z8001;
60}
61
62void s_unseg()
63{
64 segmented_mode = 0;
65 machine = bfd_mach_z8002;
66 coff_flags = F_Z8002;
67}
68const pseudo_typeS md_pseudo_table[] =
69{
70{ "int", cons, 2 },
71{ "data.b", cons, 1 },
72{ "data.w", cons, 2 },
73{ "data.l", cons, 4 },
74{ "form", listing_psize, 0 },
75{ "heading", listing_title, 0},
76{ "import", s_ignore, 0},
77{ "page", listing_eject, 0},
78{ "program", s_ignore, 0},
587c4264
ILT
79{ "z8001", s_segm, 0},
80{ "z8002", s_unseg, 0},
163107a1
SC
81{ 0,0,0 }
82};
83
84
85const char EXP_CHARS[] = "eE";
86
87/* Chars that mean this number is a floating point constant */
88/* As in 0f12.456 */
89/* or 0d1.2345e12 */
587c4264 90const char FLT_CHARS[] = "rRsSfFdDxXpP";
163107a1
SC
91
92
93const relax_typeS md_relax_table[1];
94
95
96static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
97
98
99
100void md_begin ()
101{
102 opcode_entry_type *opcode;
103 char *prev_name= "";
104 int idx = 0;
105
106 opcode_hash_control = hash_new();
107
108
109 for (opcode = z8k_table; opcode->name; opcode++)
110 {
111 /* Only enter unique codes into the table */
112 char *src= opcode->name;
113
114 if (strcmp(opcode->name, prev_name))
115 {
116 hash_insert(opcode_hash_control, opcode->name, (char *)opcode);
117 idx++;
118 }
119 opcode->idx = idx;
120 prev_name = opcode->name;
121 }
122
123}
124
125
126struct z8k_exp {
127 char *e_beg;
128 char *e_end;
129 expressionS e_exp;
130};
131typedef struct z8k_op
132{
133 char regsize; /* 'b','w','r','q' */
134 unsigned int reg; /* 0..15 */
135
136 int mode;
137
138 unsigned int x_reg;/* any other register associated with the mode */
139 expressionS exp; /* any expression */
140} op_type;
141
142
143
587c4264
ILT
144static expressionS *da_operand;
145static expressionS *imm_operand;
163107a1 146
587c4264
ILT
147
148int reg[16];
163107a1
SC
149int the_cc;
150
151char *
152DEFUN(whatreg,(reg, src),
153 int *reg AND
154 char *src)
155{
156 if (isdigit(src[1]))
157 {
158 *reg = (src[0] - '0') * 10 +src[1] - '0';
159 return src+2;
160 }
161 else
162 {
163 *reg = (src[0] - '0');
164 return src+1;
165 }
166return 0;
167}
168
169/*
170 parse operands
171
172 rh0-rh7, rl0-rl7
173 r0-r15
174 rr0-rr14
175 rq0--rq12
176 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
177 r0l,r0h,..r7l,r7h
178 @WREG
179 @WREG+
180 @-WREG
181 #const
182
183 */
184
185
186/* try and parse a reg name, returns number of chars consumed */
187char*
188DEFUN(parse_reg,(src, mode, reg),
189 char *src AND
190 int * mode AND
191 unsigned int *reg)
192{
193 char *res = 0;
587c4264 194 if (src[0] == 'r')
163107a1 195 {
587c4264 196 if (src[1] == 'r')
163107a1
SC
197 {
198 *mode = CLASS_REG_LONG;
199 res = whatreg(reg, src+2);
200 }
587c4264 201 else if (src[1] == 'h')
163107a1
SC
202 {
203 *mode = CLASS_REG_BYTE;
204 res = whatreg(reg, src+2);
205 }
587c4264 206 else if (src[1] == 'l')
163107a1
SC
207 {
208 *mode = CLASS_REG_BYTE;
209 res = whatreg(reg, src+2);
210 }
587c4264 211 else if (src[1] == 'q')
163107a1
SC
212 {
213 * mode = CLASS_REG_QUAD;
214 res = whatreg(reg, src+2);
215 }
216 else
217 {
218 *mode = CLASS_REG_WORD;
219 res = whatreg(reg, src+1);
220 }
221 }
222 return res;
223
224
225}
226
227char *
228DEFUN(parse_exp,(s, op),
229 char *s AND
230 expressionS *op)
231{
232 char *save = input_line_pointer;
233 char *new;
234 segT seg;
235 input_line_pointer = s;
236 seg = expr(0,op);
237 new = input_line_pointer;
238 input_line_pointer = save;
239 if (SEG_NORMAL(seg))
240 return new;
241 switch (seg) {
242 case SEG_ABSOLUTE:
243 case SEG_UNKNOWN:
244 case SEG_DIFFERENCE:
245 case SEG_BIG:
246 case SEG_REGISTER:
247 return new;
248 case SEG_ABSENT:
249 as_bad("Missing operand");
250 return new;
251 default:
252 as_bad("Don't understand operand of type %s", segment_name (seg));
253 return new;
254 }
255}
256
257
258/* The many forms of operand:
259
260 <rb>
261 <r>
262 <rr>
263 <rq>
264 @r
265 #exp
266 exp
267 exp(r)
268 r(#exp)
269 r(r)
270
271
272
273 */
274
275static
276char *
277DEFUN(checkfor,(ptr, what),
278 char *ptr AND
279 char what)
280{
281if (*ptr == what) ptr++;
282else {
283as_bad("expected %c", what);
284}
285return ptr;
286}
287
288/* Make sure the mode supplied is the size of a word */
289static void
290DEFUN(regword,(mode, string),
291 int mode AND
292 char *string)
293{
294 int ok;
295 ok = CLASS_REG_WORD;
296 if (ok != mode)
297 {
298 as_bad("register is wrong size for a word %s", string);
299 }
300}
301
302/* Make sure the mode supplied is the size of an address */
303static void
304DEFUN(regaddr,(mode, string),
305 int mode AND
306 char *string)
307{
308 int ok;
309 ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
310 if (ok != mode)
311 {
312 as_bad("register is wrong size for address %s", string);
313 }
314}
315
316struct cc_names {
317int value;
318char *name;
319
320
321};
322
323struct cc_names table[] =
324{
587c4264
ILT
325 0x0,"f",
326 0x1,"lt",
327 0x2,"le",
328 0x3,"ule",
329 0x4,"ov",
330 0x4,"pe",
331 0x5,"mi",
332 0x6,"eq",
333 0x6,"z",
334 0x7,"c",
335 0x7,"ult",
336 0x8,"t",
337 0x9,"ge",
338 0xa,"gt",
339 0xb,"ugt",
340 0xc,"nov",
341 0xc,"po",
342 0xd,"pl",
343 0xe,"ne",
344 0xe,"nz",
345 0xf,"nc",
346 0xf,"uge",
163107a1
SC
347 0,0
348 };
349
350static void
351DEFUN(get_cc_operand,(ptr, mode, dst),
352 char **ptr AND
353 struct z8k_op *mode AND
354 unsigned int dst)
355{
356 char *src = *ptr;
357 int r;
358 int i;
587c4264
ILT
359 while (*src== ' ')
360 src++;
361
163107a1
SC
362 mode->mode = CLASS_CC;
363 for (i = 0; table[i].name; i++)
364 {
365 int j;
366 for (j = 0; table[i].name[j]; j++)
367 {
368 if (table[i].name[j] != src[j])
369 goto fail;
370 }
587c4264 371 the_cc = table[i].value;
163107a1
SC
372 *ptr = src + j;
373 return;
374 fail:;
375 }
587c4264 376 the_cc = 0x8;
163107a1
SC
377 return ;
378}
379
380static void
381DEFUN(get_operand,(ptr, mode, dst),
382 char **ptr AND
383 struct z8k_op *mode AND
384 unsigned int dst)
385{
386 char *src = *ptr;
387 char *end;
388 unsigned int num;
389 unsigned int len;
390 unsigned int size;
391 mode->mode = 0;
392
587c4264
ILT
393
394 while (*src == ' ')
395 src++;
163107a1
SC
396 if (*src == '#')
397 {
398 mode->mode = CLASS_IMM;
587c4264 399 imm_operand = &(mode->exp);
163107a1
SC
400 src = parse_exp(src+1, &(mode->exp));
401 }
402 else if (*src == '@') {
403 int d;
404 mode->mode = CLASS_IR;
405 src= parse_reg(src+1, &d, &mode->reg);
406 }
407 else
408 {
587c4264
ILT
409 int regn;
410 end = parse_reg(src, &mode->mode, &regn);
163107a1
SC
411
412 if (end)
413 {
414 int nw, nr;
415 src = end;
416 if (*src == '(')
417 {
418 src++;
419 end = parse_reg(src, &nw, &nr);
420 if (end)
421 {
422 /* Got Ra(Rb) */
423 src = end;
424
425 if (*src != ')')
426 {
427 as_bad("Missing ) in ra(rb)");
428 }
429 else
430 {
431 src++;
432 }
433
434 regaddr(mode->mode,"ra(rb) ra");
435 regword(mode->mode,"ra(rb) rb");
436 mode->mode = CLASS_BX;
587c4264 437 mode->reg = regn;
163107a1 438 mode->x_reg = nr;
587c4264 439 reg[ARG_RX] = nr;
163107a1
SC
440 }
441 else
442 {
443 /* Got Ra(disp) */
444 if (*src == '#')
445 src++;
446 src = parse_exp(src, &(mode->exp));
447 src = checkfor(src, ')');
448 mode->mode = CLASS_BA;
587c4264 449 mode->reg = regn;
163107a1 450 mode->x_reg = 0;
587c4264 451 da_operand = &(mode->exp);
163107a1
SC
452 }
453 }
454 else
455 {
587c4264 456 mode->reg = regn;
163107a1
SC
457 mode->x_reg = 0;
458 }
459 }
460 else
461 {
462 /* No initial reg */
463 src = parse_exp(src, &(mode->exp));
464 if (*src == '(')
465 {
466 src++;
587c4264 467 end = parse_reg(src, &(mode->mode), &regn);
163107a1
SC
468 regword(mode->mode,"addr(Ra) ra");
469 mode->mode = CLASS_X;
587c4264 470 mode->reg = regn;
163107a1 471 mode->x_reg =0;
587c4264 472 da_operand = &(mode->exp);
163107a1
SC
473 src = checkfor(end, ')');
474 }
475 else
476 {
477 /* Just an address */
478 mode->mode = CLASS_DA;
479 mode->reg = 0;
480 mode->x_reg = 0;
587c4264 481 da_operand = &(mode->exp);
163107a1
SC
482 }
483 }
484 }
485 *ptr = src;
486}
487
488static
489char *
cfb48ce5
SC
490DEFUN(get_operands,(opcode, op_end, operand),
491 opcode_entry_type *opcode AND
492 char *op_end AND
493 op_type *operand)
163107a1
SC
494{
495 char *ptr = op_end;
496 switch (opcode->noperands)
497 {
498 case 0:
499 operand[0].mode = 0;
500 operand[1].mode = 0;
501 break;
502
587c4264 503 case 1:
163107a1 504 ptr++;
587c4264
ILT
505 if (opcode->arg_info[0] == CLASS_CC)
506 {
507 get_cc_operand(&ptr, operand+0,0);
508 }
509 else
510 {
511
512 get_operand(& ptr, operand +0,0);
513 }
163107a1
SC
514 operand[1].mode =0;
515 break;
516
517 case 2:
518 ptr++;
519 if (opcode->arg_info[0] == CLASS_CC)
520 {
521 get_cc_operand(&ptr, operand+0,0);
522 }
523 else
524 {
587c4264 525
163107a1
SC
526 get_operand(& ptr, operand +0,0);
527 }
528 if (*ptr == ',') ptr++;
529 get_operand(& ptr, operand +1, 1);
530 break;
587c4264
ILT
531
532 case 3:
533 ptr++;
534 get_operand(& ptr, operand +0,0);
535 if (*ptr == ',') ptr++;
536 get_operand(& ptr, operand +1, 1);
537 if (*ptr == ',') ptr++;
538 get_operand(& ptr, operand +2, 2);
539 break;
163107a1
SC
540
541 default:
542 abort();
543 }
544
545
546 return ptr;
547}
548
549/* Passed a pointer to a list of opcodes which use different
550 addressing modes, return the opcode which matches the opcodes
551 provided
552 */
553
587c4264
ILT
554
555
163107a1
SC
556
557static
558opcode_entry_type *
559DEFUN(get_specific,(opcode, operands),
560 opcode_entry_type *opcode AND
561 op_type *operands)
562
563{
564 opcode_entry_type *this_try = opcode ;
565 int found = 0;
566 unsigned int noperands = opcode->noperands;
567
568 unsigned int dispreg;
569 unsigned int this_index = opcode->idx;
570
571 while (this_index == opcode->idx && !found)
572 {
573 unsigned int i;
574
575 this_try = opcode ++;
576 for (i = 0; i < noperands; i++)
577 {
578 int mode = operands[i].mode;
579
587c4264
ILT
580 if ((mode&CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
581 {
582 /* it could be an pc rel operand, if this is a da mode and
583 we like disps, then insert it */
584
585 if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
586 {
587 /* This is the case */
588 operands[i].mode = CLASS_DISP;
589 }
590 else {
591 /* Can't think of a way to turn what we've been given into
592 something that's ok */
593 goto fail;
594 }
595 }
596 switch (mode & CLASS_MASK) {
597 default:
598 break;
599 case CLASS_X:
600 case CLASS_IR:
601 case CLASS_BA:
602 case CLASS_BX:
603 case CLASS_DISP:
604 case CLASS_REG:
605 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
606 break;
607 }
163107a1
SC
608 }
609
610 found =1;
611 fail: ;
612 }
613 if (found)
614 return this_try;
615 else
616 return 0;
617}
618
619static void
620DEFUN(check_operand,(operand, width, string),
621 struct z8k_op *operand AND
622 unsigned int width AND
623 char *string)
624{
625 if (operand->exp.X_add_symbol == 0
626 && operand->exp.X_subtract_symbol == 0)
627 {
628
629 /* No symbol involved, let's look at offset, it's dangerous if any of
630 the high bits are not 0 or ff's, find out by oring or anding with
631 the width and seeing if the answer is 0 or all fs*/
632 if ((operand->exp.X_add_number & ~width) != 0 &&
633 (operand->exp.X_add_number | width)!= (~0))
634 {
635 as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number);
636 }
637 }
638
639}
640
641static void
642DEFUN(newfix,(ptr, type, operand),
cfb48ce5 643 int ptr AND
163107a1 644 int type AND
587c4264 645 expressionS *operand)
163107a1 646{
587c4264
ILT
647 if (operand->X_add_symbol
648 || operand->X_subtract_symbol
649 || operand->X_add_number) {
650 fix_new(frag_now,
651 ptr,
652 1,
653 operand->X_add_symbol,
654 operand->X_subtract_symbol,
655 operand->X_add_number,
656 0,
657 type);
658 }
163107a1
SC
659}
660
661
662/* Now we know what sort of opcodes it is, lets build the bytes -
663 */
664static void
665 DEFUN (build_bytes,(this_try, operand),
666 opcode_entry_type *this_try AND
667 struct z8k_op *operand)
668{
669 unsigned int i;
670 char buffer[20];
671 int length;
672 char *output;
673 char *output_ptr = buffer;
674 char part;
675 int c;
676 char high;
677 int nib;
678 int nibble;
679 unsigned short *class_ptr;
587c4264 680 memset(buffer, 20, 0);
163107a1
SC
681 class_ptr = this_try->byte_info;
682 top: ;
683
684 for (nibble = 0; c = *class_ptr++; nibble++)
685 {
686
687 switch (c & CLASS_MASK)
688 {
689 default:
587c4264 690
163107a1
SC
691 abort();
692 case CLASS_ADDRESS:
693 /* Direct address, we don't cope with the SS mode right now */
694 if (segmented_mode) {
587c4264
ILT
695 newfix((output_ptr-buffer)/2, R_DA | R_SEG, da_operand);
696 *output_ptr++ = 0;
697 *output_ptr++ = 0;
698 *output_ptr++ = 0;
699 *output_ptr++ = 0;
700 *output_ptr++ = 0;
701 *output_ptr++ = 0;
702 *output_ptr++ = 0;
703 *output_ptr++ = 0;
163107a1
SC
704 }
705 else {
587c4264
ILT
706 newfix((output_ptr-buffer)/2, R_DA, da_operand);
707 *output_ptr++ = 0;
708 *output_ptr++ = 0;
709 *output_ptr++ = 0;
710 *output_ptr++ = 0;
163107a1 711 }
587c4264 712 da_operand = 0;
163107a1 713 break;
587c4264
ILT
714 case CLASS_DISP8:
715 /* pc rel 8 bit */
716 newfix((output_ptr-buffer)/2, R_JR, da_operand);
717 da_operand = 0;
718 *output_ptr++ = 0;
719 *output_ptr++ = 0;
720 break;
721
163107a1
SC
722 case CLASS_CC:
723 *output_ptr++ = the_cc;
724 break;
725 case CLASS_BIT:
726 *output_ptr++ = c & 0xf;
727 break;
728 case CLASS_REGN0:
729 if (reg[c&0xf] == 0)
730 {
731 as_bad("can't use R0 here");
732 }
733 case CLASS_REG:
734 case CLASS_REG_BYTE:
735 case CLASS_REG_WORD:
736 case CLASS_REG_LONG:
737 case CLASS_REG_QUAD:
738 /* Insert bit mattern of
739 right reg */
740 *output_ptr++ = reg[c & 0xf];
741 break;
587c4264
ILT
742 case CLASS_DISP:
743 newfix((output_ptr-buffer)/2, R_DA, da_operand);
744 da_operand= 0;
745 output_ptr += 4;
746 break;
163107a1
SC
747 case CLASS_IMM:
748 {
749 nib = 0;
750 switch (c & ARG_MASK)
751 {
752 case ARG_IMM4:
587c4264
ILT
753 *output_ptr ++ = imm_operand->X_add_number;
754 imm_operand->X_add_number = 0;
755 newfix((output_ptr-buffer)/2, R_IMM4L, imm_operand);
756 break;
757 case ARG_IMMNMINUS1:
758 imm_operand->X_add_number --;
cfb48ce5 759 newfix((output_ptr-buffer)/2, R_IMM4L, imm_operand);
163107a1
SC
760 *output_ptr++ = 0;
761 break;
163107a1 762 case ARG_IMM8:
cfb48ce5 763 newfix((output_ptr-buffer)/2, R_IMM8, imm_operand);
163107a1
SC
764 *output_ptr++ = 0;
765 *output_ptr++ = 0;
766
587c4264
ILT
767 case ARG_NIM16:
768 imm_operand->X_add_number = - imm_operand->X_add_number;
769 newfix((output_ptr-buffer)/2, R_DA, imm_operand);
163107a1
SC
770 *output_ptr++ = 0;
771 *output_ptr++ = 0;
772 *output_ptr++ = 0;
773 *output_ptr++ = 0;
774 break;
775
587c4264
ILT
776 case ARG_IMM16:
777 {
778 int n = imm_operand->X_add_number ;
779 imm_operand->X_add_number = 0;
780 newfix((output_ptr-buffer)/2, R_DA, imm_operand);
781 *output_ptr++ = n>>24;
782 *output_ptr++ = n>>16;
783 *output_ptr++ = n>>8;
784 *output_ptr++ = n;
785 }
786
787 break;
788
163107a1 789 case ARG_IMM32:
cfb48ce5 790 newfix((output_ptr-buffer)/2, R_IMM32, imm_operand);
163107a1
SC
791 *output_ptr++ = 0;
792 *output_ptr++ = 0;
793 *output_ptr++ = 0;
794 *output_ptr++ = 0;
795
796 *output_ptr++ = 0;
797 *output_ptr++ = 0;
798 *output_ptr++ = 0;
799 *output_ptr++ = 0;
800
163107a1
SC
801 break;
802
803 default:
804 abort();
805
806
807 }
808 }
809 }
810 }
811
812 /* Copy from the nibble buffer into the frag */
813
814 {
587c4264 815 int length = (output_ptr - buffer) / 2 ;
163107a1 816 char *src = buffer;
587c4264
ILT
817 char *fragp = frag_more(length);
818 frag_wane(frag_now);
819 frag_new(0);
163107a1
SC
820 while (src < output_ptr)
821 {
822 *fragp = (src[0] << 4) | src[1];
823 src+=2;
824 fragp++;
825 }
826
827
828 }
829
830}
831
832/* This is the guts of the machine-dependent assembler. STR points to a
833 machine dependent instruction. This funciton is supposed to emit
834 the frags/bytes it assembles to.
835 */
836
837
838
839void
840 DEFUN(md_assemble,(str),
841 char *str)
842{
843 char *op_start;
844 char *op_end;
845 unsigned int i;
587c4264 846 struct z8k_op operand[3];
163107a1
SC
847 opcode_entry_type *opcode;
848 opcode_entry_type * prev_opcode;
849
850 char *dot = 0;
851 char c;
852 /* Drop leading whitespace */
853 while (*str == ' ')
854 str++;
855
856 /* find the op code end */
857 for (op_start = op_end = str;
858 *op_end != 0 && *op_end != ' ';
859 op_end ++)
860 {
861 }
862
863 ;
864
865 if (op_end == op_start)
866 {
867 as_bad("can't find opcode ");
868 }
869 c = *op_end;
870
871 *op_end = 0;
872
873 opcode = (opcode_entry_type *) hash_find(opcode_hash_control,
874 op_start);
875
876 if (opcode == NULL)
877 {
878 as_bad("unknown opcode");
879 return;
880 }
881
882
883 input_line_pointer = get_operands(opcode, op_end,
884 operand);
885 *op_end = c;
886 prev_opcode = opcode;
887
888 opcode = get_specific(opcode, operand);
889
890 if (opcode == 0)
891 {
892 /* Couldn't find an opcode which matched the operands */
893 char *where =frag_more(2);
894 where[0] = 0x0;
895 where[1] = 0x0;
896
cfb48ce5 897 as_bad("Can't find opcode to match operands");
163107a1
SC
898 return;
899 }
900
901 build_bytes(opcode, operand);
902}
903
904
905void
906 DEFUN(tc_crawl_symbol_chain, (headers),
907 object_headers *headers)
908{
909 printf("call to tc_crawl_symbol_chain \n");
910}
911
912symbolS *DEFUN(md_undefined_symbol,(name),
913 char *name)
914{
915 return 0;
916}
917
918void
919 DEFUN(tc_headers_hook,(headers),
920 object_headers *headers)
921{
922 printf("call to tc_headers_hook \n");
923}
924void
925 DEFUN_VOID(md_end)
926{
927}
928
929/* Various routines to kill one day */
930/* Equal to MAX_PRECISION in atof-ieee.c */
931#define MAX_LITTLENUMS 6
932
933/* Turn a string in input_line_pointer into a floating point constant of type
934 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
935 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
936 */
937char *
938 md_atof(type,litP,sizeP)
939char type;
940char *litP;
941int *sizeP;
942{
943 int prec;
944 LITTLENUM_TYPE words[MAX_LITTLENUMS];
945 LITTLENUM_TYPE *wordP;
946 char *t;
947 char *atof_ieee();
948
949 switch(type) {
950 case 'f':
951 case 'F':
952 case 's':
953 case 'S':
954 prec = 2;
955 break;
956
957 case 'd':
958 case 'D':
959 case 'r':
960 case 'R':
961 prec = 4;
962 break;
963
964 case 'x':
965 case 'X':
966 prec = 6;
967 break;
968
969 case 'p':
970 case 'P':
971 prec = 6;
972 break;
973
974 default:
975 *sizeP=0;
976 return "Bad call to MD_ATOF()";
977 }
978 t=atof_ieee(input_line_pointer,type,words);
979 if(t)
980 input_line_pointer=t;
981
982 *sizeP=prec * sizeof(LITTLENUM_TYPE);
983 for(wordP=words;prec--;) {
984 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
985 litP+=sizeof(LITTLENUM_TYPE);
986 }
987 return ""; /* Someone should teach Dean about null pointers */
988}
989
990int
991 md_parse_option(argP, cntP, vecP)
992char **argP;
993int *cntP;
994char ***vecP;
995
996{
997 return 0;
998
999}
1000
1001int md_short_jump_size;
1002
1003void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n");
1004 abort(); }
1005void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
1006char *ptr;
1007long from_addr;
1008long to_addr;
1009fragS *frag;
1010symbolS *to_symbol;
1011{
1012 as_fatal("failed sanity check.");
1013}
1014
1015void
1016 md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
1017char *ptr;
1018long from_addr, to_addr;
1019fragS *frag;
1020symbolS *to_symbol;
1021{
1022 as_fatal("failed sanity check.");
1023}
1024
1025void
1026 md_convert_frag(headers, fragP)
1027object_headers *headers;
1028fragS * fragP;
1029
1030{ printf("call to md_convert_frag \n"); abort(); }
1031
1032long
1033 DEFUN(md_section_align,(seg, size),
1034 segT seg AND
1035 long size)
1036{
1037 return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
1038
1039}
1040
1041void
1042 md_apply_fix(fixP, val)
1043fixS *fixP;
1044long val;
1045{
1046 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1047
cfb48ce5
SC
1048 switch(fixP->fx_r_type) {
1049 case R_IMM4L:
1050 buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
163107a1 1051 break;
cfb48ce5 1052
587c4264
ILT
1053 case R_JR:
1054
1055 *buf++= val;
1056/* if (val != 0) abort();*/
1057 break;
1058
1059
cfb48ce5
SC
1060 case R_IMM8:
1061 buf[0] += val;
1062 break;
587c4264 1063 break;
cfb48ce5 1064 case R_DA:
163107a1
SC
1065 *buf++=(val>>8);
1066 *buf++=val;
1067 break;
cfb48ce5 1068 case R_IMM32:
163107a1
SC
1069 *buf++=(val>>24);
1070 *buf++=(val>>16);
1071 *buf++=(val>>8);
1072 *buf++=val;
1073 break;
cfb48ce5
SC
1074 case R_DA | R_SEG:
1075 *buf++ = (val>>16);
1076 *buf++ = 0x00;
1077 *buf++ = (val>>8);
1078 *buf++ = val;
1079 break;
163107a1
SC
1080 default:
1081 abort();
1082
1083 }
1084}
1085
1086void DEFUN(md_operand, (expressionP),expressionS *expressionP)
1087{ }
1088
1089int md_long_jump_size;
1090int
1091 md_estimate_size_before_relax(fragP, segment_type)
1092register fragS *fragP;
1093register segT segment_type;
1094{
1095 printf("call tomd_estimate_size_before_relax \n"); abort(); }
1096/* Put number into target byte order */
1097
1098void DEFUN(md_number_to_chars,(ptr, use, nbytes),
1099 char *ptr AND
1100 long use AND
1101 int nbytes)
1102{
1103 switch (nbytes) {
1104 case 4: *ptr++ = (use >> 24) & 0xff;
1105 case 3: *ptr++ = (use >> 16) & 0xff;
1106 case 2: *ptr++ = (use >> 8) & 0xff;
1107 case 1: *ptr++ = (use >> 0) & 0xff;
1108 break;
1109 default:
1110 abort();
1111 }
1112}
1113long md_pcrel_from(fixP)
1114fixS *fixP; { abort(); }
1115
1116void tc_coff_symbol_emit_hook() { }
1117
1118
1119void tc_reloc_mangle(fix_ptr, intr, base)
1120fixS *fix_ptr;
1121struct internal_reloc *intr;
1122bfd_vma base;
1123
1124{
1125 symbolS *symbol_ptr;
1126
1127 symbol_ptr = fix_ptr->fx_addsy;
1128
1129 /* If this relocation is attached to a symbol then it's ok
1130 to output it */
1131 if (fix_ptr->fx_r_type == RELOC_32) {
1132 /* cons likes to create reloc32's whatever the size of the reloc..
1133 */
1134 switch (fix_ptr->fx_size)
1135 {
1136
1137 case 2:
587c4264 1138 intr->r_type = R_DA;
163107a1
SC
1139 break;
1140 case 1:
1141 intr->r_type = R_IMM8;
1142 break;
1143 default:
1144 abort();
1145
1146 }
1147
1148 }
1149 else {
1150 intr->r_type = fix_ptr->fx_r_type;
1151 }
1152
1153 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base;
1154 intr->r_offset = fix_ptr->fx_offset;
1155
1156 if (symbol_ptr)
1157 intr->r_symndx = symbol_ptr->sy_number;
1158 else
1159 intr->r_symndx = -1;
1160
1161
1162}
1163
1164
This page took 0.076286 seconds and 4 git commands to generate.