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