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