1 /* tc-z8k.c -- Assemble code for the Zilog Z800N
2 Copyright (C) 1992 Free Software Foundation.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
22 Written By Steve Chamberlain
28 #include "disasm/z8kopcode.h"
35 char comment_chars[] = { ';',0 };
36 char line_separator_chars[] = { '$' ,0};
39 extern int coff_flags;
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
56 machine = bfd_mach_z8001;
63 machine = bfd_mach_z8002;
66 const pseudo_typeS md_pseudo_table[] =
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},
78 { "UNSEG", s_unseg, 0},
83 const char EXP_CHARS[] = "eE";
85 /* Chars that mean this number is a floating point constant */
88 char FLT_CHARS[] = "rRsSfFdDxXpP";
91 const relax_typeS md_relax_table[1];
94 static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
100 opcode_entry_type *opcode;
104 opcode_hash_control = hash_new();
107 for (opcode = z8k_table; opcode->name; opcode++)
109 /* Only enter unique codes into the table */
110 char *src= opcode->name;
112 if (strcmp(opcode->name, prev_name))
114 hash_insert(opcode_hash_control, opcode->name, (char *)opcode);
118 prev_name = opcode->name;
129 typedef struct z8k_op
131 char regsize; /* 'b','w','r','q' */
132 unsigned int reg; /* 0..15 */
136 unsigned int x_reg;/* any other register associated with the mode */
137 expressionS exp; /* any expression */
142 static op_type *da_address;
143 static op_type *imm_operand;
148 DEFUN(whatreg,(reg, src),
154 *reg = (src[0] - '0') * 10 +src[1] - '0';
159 *reg = (src[0] - '0');
172 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
182 /* try and parse a reg name, returns number of chars consumed */
184 DEFUN(parse_reg,(src, mode, reg),
194 *mode = CLASS_REG_LONG;
195 res = whatreg(reg, src+2);
197 else if (src[1] == 'H')
199 *mode = CLASS_REG_BYTE;
200 res = whatreg(reg, src+2);
202 else if (src[1] == 'L')
204 *mode = CLASS_REG_BYTE;
205 res = whatreg(reg, src+2);
207 else if (src[1] == 'Q')
209 * mode = CLASS_REG_QUAD;
210 res = whatreg(reg, src+2);
214 *mode = CLASS_REG_WORD;
215 res = whatreg(reg, src+1);
224 DEFUN(parse_exp,(s, op),
228 char *save = input_line_pointer;
231 input_line_pointer = s;
233 new = input_line_pointer;
234 input_line_pointer = save;
245 as_bad("Missing operand");
248 as_bad("Don't understand operand of type %s", segment_name (seg));
254 /* The many forms of operand:
273 DEFUN(checkfor,(ptr, what),
277 if (*ptr == what) ptr++;
279 as_bad("expected %c", what);
284 /* Make sure the mode supplied is the size of a word */
286 DEFUN(regword,(mode, string),
294 as_bad("register is wrong size for a word %s", string);
298 /* Make sure the mode supplied is the size of an address */
300 DEFUN(regaddr,(mode, string),
305 ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
308 as_bad("register is wrong size for address %s", string);
319 struct cc_names table[] =
346 DEFUN(get_cc_operand,(ptr, mode, dst),
348 struct z8k_op *mode AND
354 mode->mode = CLASS_CC;
355 for (i = 0; table[i].name; i++)
358 for (j = 0; table[i].name[j]; j++)
360 if (table[i].name[j] != src[j])
363 the_cc = table[i].value;
373 DEFUN(get_operand,(ptr, mode, dst),
375 struct z8k_op *mode AND
387 mode->mode = CLASS_IMM;
389 src = parse_exp(src+1, &(mode->exp));
391 else if (*src == '@') {
393 mode->mode = CLASS_IR;
394 src= parse_reg(src+1, &d, &mode->reg);
399 end = parse_reg(src, &mode->mode, ®);
408 end = parse_reg(src, &nw, &nr);
416 as_bad("Missing ) in ra(rb)");
423 regaddr(mode->mode,"ra(rb) ra");
424 regword(mode->mode,"ra(rb) rb");
425 mode->mode = CLASS_BX;
435 src = parse_exp(src, &(mode->exp));
436 src = checkfor(src, ')');
437 mode->mode = CLASS_BA;
451 src = parse_exp(src, &(mode->exp));
455 end = parse_reg(src, &(mode->mode), ®);
456 regword(mode->mode,"addr(Ra) ra");
457 mode->mode = CLASS_X;
461 src = checkfor(end, ')');
465 /* Just an address */
466 mode->mode = CLASS_DA;
478 DEFUN(get_operands,(operand, op_end, operand),
479 opcode_entry_type *opcode AND
484 switch (opcode->noperands)
493 get_operand(& ptr, operand +0,0);
499 if (opcode->arg_info[0] == CLASS_CC)
501 get_cc_operand(&ptr, operand+0,0);
505 get_operand(& ptr, operand +0,0);
507 if (*ptr == ',') ptr++;
508 get_operand(& ptr, operand +1, 1);
519 /* Passed a pointer to a list of opcodes which use different
520 addressing modes, return the opcode which matches the opcodes
529 DEFUN(get_specific,(opcode, operands),
530 opcode_entry_type *opcode AND
534 opcode_entry_type *this_try = opcode ;
536 unsigned int noperands = opcode->noperands;
538 unsigned int dispreg;
539 unsigned int this_index = opcode->idx;
541 while (this_index == opcode->idx && !found)
545 this_try = opcode ++;
546 for (i = 0; i < noperands; i++)
548 int mode = operands[i].mode;
550 if ((mode&CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK)) goto fail;
552 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
565 DEFUN(check_operand,(operand, width, string),
566 struct z8k_op *operand AND
567 unsigned int width AND
570 if (operand->exp.X_add_symbol == 0
571 && operand->exp.X_subtract_symbol == 0)
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))
580 as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number);
587 DEFUN(newfix,(ptr, type, operand),
596 operand->exp.X_add_symbol,
597 operand->exp.X_subtract_symbol,
598 operand->exp.X_add_number,
604 /* Now we know what sort of opcodes it is, lets build the bytes -
607 DEFUN (build_bytes,(this_try, operand),
608 opcode_entry_type *this_try AND
609 struct z8k_op *operand)
615 char *output_ptr = buffer;
621 unsigned short *class_ptr;
622 length = this_try->length;
623 if (segmented_mode && da_address)
625 /* two more bytes when in segmented mode and using da address
629 output = frag_more(this_try->length);
630 memset(buffer, 20, 0);
631 class_ptr = this_try->byte_info;
634 for (nibble = 0; c = *class_ptr++; nibble++)
637 switch (c & CLASS_MASK)
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);
648 newfix(nibble/2, R_DA, da_address);
654 *output_ptr++ = the_cc;
657 *output_ptr++ = c & 0xf;
662 as_bad("can't use R0 here");
669 /* Insert bit mattern of
671 *output_ptr++ = reg[c & 0xf];
676 switch (c & ARG_MASK)
679 newfix(nibble/2, R_IMM4L, imm_operand);
684 newfix(nibble/2, R_IMM8, imm_operand);
689 newfix(nibble/2, R_IMM16, imm_operand);
697 newfix(nibble/2, R_IMM32, imm_operand);
720 /* Copy from the nibble buffer into the frag */
724 char *fragp = output;
725 while (src < output_ptr)
727 *fragp = (src[0] << 4) | src[1];
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.
745 DEFUN(md_assemble,(str),
751 struct z8k_op operand[2];
752 opcode_entry_type *opcode;
753 opcode_entry_type * prev_opcode;
757 /* Drop leading whitespace */
761 /* find the op code end */
762 for (op_start = op_end = str;
763 *op_end != 0 && *op_end != ' ';
770 if (op_end == op_start)
772 as_bad("can't find opcode ");
778 opcode = (opcode_entry_type *) hash_find(opcode_hash_control,
783 as_bad("unknown opcode");
788 input_line_pointer = get_operands(opcode, op_end,
791 prev_opcode = opcode;
793 opcode = get_specific(opcode, operand);
797 /* Couldn't find an opcode which matched the operands */
798 char *where =frag_more(2);
806 build_bytes(opcode, operand);
811 DEFUN(tc_crawl_symbol_chain, (headers),
812 object_headers *headers)
814 printf("call to tc_crawl_symbol_chain \n");
817 symbolS *DEFUN(md_undefined_symbol,(name),
824 DEFUN(tc_headers_hook,(headers),
825 object_headers *headers)
827 printf("call to tc_headers_hook \n");
834 /* Various routines to kill one day */
835 /* Equal to MAX_PRECISION in atof-ieee.c */
836 #define MAX_LITTLENUMS 6
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.
843 md_atof(type,litP,sizeP)
849 LITTLENUM_TYPE words[MAX_LITTLENUMS];
850 LITTLENUM_TYPE *wordP;
881 return "Bad call to MD_ATOF()";
883 t=atof_ieee(input_line_pointer,type,words);
885 input_line_pointer=t;
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);
892 return ""; /* Someone should teach Dean about null pointers */
896 md_parse_option(argP, cntP, vecP)
906 int md_short_jump_size;
908 void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n");
910 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
917 as_fatal("failed sanity check.");
921 md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
923 long from_addr, to_addr;
927 as_fatal("failed sanity check.");
931 md_convert_frag(headers, fragP)
932 object_headers *headers;
935 { printf("call to md_convert_frag \n"); abort(); }
938 DEFUN(md_section_align,(seg, size),
942 return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
947 md_apply_fix(fixP, val)
951 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
953 switch(fixP->fx_size) {
973 void DEFUN(md_operand, (expressionP),expressionS *expressionP)
976 int md_long_jump_size;
978 md_estimate_size_before_relax(fragP, segment_type)
979 register fragS *fragP;
980 register segT segment_type;
982 printf("call tomd_estimate_size_before_relax \n"); abort(); }
983 /* Put number into target byte order */
985 void DEFUN(md_number_to_chars,(ptr, use, 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;
1000 long md_pcrel_from(fixP)
1001 fixS *fixP; { abort(); }
1003 void tc_coff_symbol_emit_hook() { }
1006 void tc_reloc_mangle(fix_ptr, intr, base)
1008 struct internal_reloc *intr;
1012 symbolS *symbol_ptr;
1014 symbol_ptr = fix_ptr->fx_addsy;
1016 /* If this relocation is attached to a symbol then it's ok
1018 if (fix_ptr->fx_r_type == RELOC_32) {
1019 /* cons likes to create reloc32's whatever the size of the reloc..
1021 switch (fix_ptr->fx_size)
1025 intr->r_type = R_IMM16;
1028 intr->r_type = R_IMM8;
1037 intr->r_type = fix_ptr->fx_r_type;
1040 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base;
1041 intr->r_offset = fix_ptr->fx_offset;
1044 intr->r_symndx = symbol_ptr->sy_number;
1046 intr->r_symndx = -1;