Support for the Z8k
[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 "disasm/z8kopcode.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,(operand, 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 byte AND
589 int type AND
590 op_type *operand)
591 {
592
593 fix_new(frag_now,
594 byte,
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(this_try->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(nibble/2, R_DA | R_SEG, da_address);
645 output_ptr += 4;
646 }
647 else {
648 newfix(nibble/2, R_DA, da_address);
649 output_ptr += 2;
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(nibble/2, R_IMM4L, imm_operand);
680 *output_ptr++ = 0;
681 break;
682
683 case ARG_IMM8:
684 newfix(nibble/2, R_IMM8, imm_operand);
685 *output_ptr++ = 0;
686 *output_ptr++ = 0;
687
688 case ARG_IMM16:
689 newfix(nibble/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(nibble/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 output_ptr +=8;
709 break;
710
711 default:
712 abort();
713
714
715 }
716 }
717 }
718 }
719
720 /* Copy from the nibble buffer into the frag */
721
722 {
723 char *src = buffer;
724 char *fragp = output;
725 while (src < output_ptr)
726 {
727 *fragp = (src[0] << 4) | src[1];
728 src+=2;
729 fragp++;
730 }
731
732
733 }
734
735 }
736
737 /* This is the guts of the machine-dependent assembler. STR points to a
738 machine dependent instruction. This funciton is supposed to emit
739 the frags/bytes it assembles to.
740 */
741
742
743
744 void
745 DEFUN(md_assemble,(str),
746 char *str)
747 {
748 char *op_start;
749 char *op_end;
750 unsigned int i;
751 struct z8k_op operand[2];
752 opcode_entry_type *opcode;
753 opcode_entry_type * prev_opcode;
754
755 char *dot = 0;
756 char c;
757 /* Drop leading whitespace */
758 while (*str == ' ')
759 str++;
760
761 /* find the op code end */
762 for (op_start = op_end = str;
763 *op_end != 0 && *op_end != ' ';
764 op_end ++)
765 {
766 }
767
768 ;
769
770 if (op_end == op_start)
771 {
772 as_bad("can't find opcode ");
773 }
774 c = *op_end;
775
776 *op_end = 0;
777
778 opcode = (opcode_entry_type *) hash_find(opcode_hash_control,
779 op_start);
780
781 if (opcode == NULL)
782 {
783 as_bad("unknown opcode");
784 return;
785 }
786
787
788 input_line_pointer = get_operands(opcode, op_end,
789 operand);
790 *op_end = c;
791 prev_opcode = opcode;
792
793 opcode = get_specific(opcode, operand);
794
795 if (opcode == 0)
796 {
797 /* Couldn't find an opcode which matched the operands */
798 char *where =frag_more(2);
799 where[0] = 0x0;
800 where[1] = 0x0;
801
802 as_bad("error");
803 return;
804 }
805
806 build_bytes(opcode, operand);
807 }
808
809
810 void
811 DEFUN(tc_crawl_symbol_chain, (headers),
812 object_headers *headers)
813 {
814 printf("call to tc_crawl_symbol_chain \n");
815 }
816
817 symbolS *DEFUN(md_undefined_symbol,(name),
818 char *name)
819 {
820 return 0;
821 }
822
823 void
824 DEFUN(tc_headers_hook,(headers),
825 object_headers *headers)
826 {
827 printf("call to tc_headers_hook \n");
828 }
829 void
830 DEFUN_VOID(md_end)
831 {
832 }
833
834 /* Various routines to kill one day */
835 /* Equal to MAX_PRECISION in atof-ieee.c */
836 #define MAX_LITTLENUMS 6
837
838 /* Turn a string in input_line_pointer into a floating point constant of type
839 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
840 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
841 */
842 char *
843 md_atof(type,litP,sizeP)
844 char type;
845 char *litP;
846 int *sizeP;
847 {
848 int prec;
849 LITTLENUM_TYPE words[MAX_LITTLENUMS];
850 LITTLENUM_TYPE *wordP;
851 char *t;
852 char *atof_ieee();
853
854 switch(type) {
855 case 'f':
856 case 'F':
857 case 's':
858 case 'S':
859 prec = 2;
860 break;
861
862 case 'd':
863 case 'D':
864 case 'r':
865 case 'R':
866 prec = 4;
867 break;
868
869 case 'x':
870 case 'X':
871 prec = 6;
872 break;
873
874 case 'p':
875 case 'P':
876 prec = 6;
877 break;
878
879 default:
880 *sizeP=0;
881 return "Bad call to MD_ATOF()";
882 }
883 t=atof_ieee(input_line_pointer,type,words);
884 if(t)
885 input_line_pointer=t;
886
887 *sizeP=prec * sizeof(LITTLENUM_TYPE);
888 for(wordP=words;prec--;) {
889 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
890 litP+=sizeof(LITTLENUM_TYPE);
891 }
892 return ""; /* Someone should teach Dean about null pointers */
893 }
894
895 int
896 md_parse_option(argP, cntP, vecP)
897 char **argP;
898 int *cntP;
899 char ***vecP;
900
901 {
902 return 0;
903
904 }
905
906 int md_short_jump_size;
907
908 void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n");
909 abort(); }
910 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
911 char *ptr;
912 long from_addr;
913 long to_addr;
914 fragS *frag;
915 symbolS *to_symbol;
916 {
917 as_fatal("failed sanity check.");
918 }
919
920 void
921 md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
922 char *ptr;
923 long from_addr, to_addr;
924 fragS *frag;
925 symbolS *to_symbol;
926 {
927 as_fatal("failed sanity check.");
928 }
929
930 void
931 md_convert_frag(headers, fragP)
932 object_headers *headers;
933 fragS * fragP;
934
935 { printf("call to md_convert_frag \n"); abort(); }
936
937 long
938 DEFUN(md_section_align,(seg, size),
939 segT seg AND
940 long size)
941 {
942 return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
943
944 }
945
946 void
947 md_apply_fix(fixP, val)
948 fixS *fixP;
949 long val;
950 {
951 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
952
953 switch(fixP->fx_size) {
954 case 1:
955 *buf++=val;
956 break;
957 case 2:
958 *buf++=(val>>8);
959 *buf++=val;
960 break;
961 case 4:
962 *buf++=(val>>24);
963 *buf++=(val>>16);
964 *buf++=(val>>8);
965 *buf++=val;
966 break;
967 default:
968 abort();
969
970 }
971 }
972
973 void DEFUN(md_operand, (expressionP),expressionS *expressionP)
974 { }
975
976 int md_long_jump_size;
977 int
978 md_estimate_size_before_relax(fragP, segment_type)
979 register fragS *fragP;
980 register segT segment_type;
981 {
982 printf("call tomd_estimate_size_before_relax \n"); abort(); }
983 /* Put number into target byte order */
984
985 void DEFUN(md_number_to_chars,(ptr, use, nbytes),
986 char *ptr AND
987 long use AND
988 int nbytes)
989 {
990 switch (nbytes) {
991 case 4: *ptr++ = (use >> 24) & 0xff;
992 case 3: *ptr++ = (use >> 16) & 0xff;
993 case 2: *ptr++ = (use >> 8) & 0xff;
994 case 1: *ptr++ = (use >> 0) & 0xff;
995 break;
996 default:
997 abort();
998 }
999 }
1000 long md_pcrel_from(fixP)
1001 fixS *fixP; { abort(); }
1002
1003 void tc_coff_symbol_emit_hook() { }
1004
1005
1006 void tc_reloc_mangle(fix_ptr, intr, base)
1007 fixS *fix_ptr;
1008 struct internal_reloc *intr;
1009 bfd_vma base;
1010
1011 {
1012 symbolS *symbol_ptr;
1013
1014 symbol_ptr = fix_ptr->fx_addsy;
1015
1016 /* If this relocation is attached to a symbol then it's ok
1017 to output it */
1018 if (fix_ptr->fx_r_type == RELOC_32) {
1019 /* cons likes to create reloc32's whatever the size of the reloc..
1020 */
1021 switch (fix_ptr->fx_size)
1022 {
1023
1024 case 2:
1025 intr->r_type = R_IMM16;
1026 break;
1027 case 1:
1028 intr->r_type = R_IMM8;
1029 break;
1030 default:
1031 abort();
1032
1033 }
1034
1035 }
1036 else {
1037 intr->r_type = fix_ptr->fx_r_type;
1038 }
1039
1040 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base;
1041 intr->r_offset = fix_ptr->fx_offset;
1042
1043 if (symbol_ptr)
1044 intr->r_symndx = symbol_ptr->sy_number;
1045 else
1046 intr->r_symndx = -1;
1047
1048
1049 }
1050
1051