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. */
21 Written By Steve Chamberlain
27 #include "../opcodes/z8k-opc.h"
33 const char comment_chars[] =
35 const char line_separator_chars[] =
37 const char line_comment_chars[] =
41 extern int coff_flags;
43 const int md_reloc_size;
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
58 machine = bfd_mach_z8001;
66 machine = bfd_mach_z8002;
75 record_alignment (now_seg, 1);
78 void obj_coff_section ();
96 if (*input_line_pointer == '\'')
100 c = *input_line_pointer++;
105 c = (tohex (input_line_pointer[0]) << 4)
106 | tohex (input_line_pointer[1]);
107 input_line_pointer += 2;
109 FRAG_APPEND_1_CHAR (c);
110 c = *input_line_pointer++;
112 demand_empty_rest_of_line ();
116 const pseudo_typeS md_pseudo_table[] =
122 {"form", listing_psize, 0},
123 {"heading", listing_title, 0},
124 {"import", s_ignore, 0},
125 {"page", listing_eject, 0},
126 {"program", s_ignore, 0},
127 {"z8001", s_segm, 0},
128 {"z8002", s_unseg, 0},
132 {"unsegm", s_unseg, 0},
133 {"unseg", s_unseg, 0},
134 {"name", s_app_file, 0},
135 {"global", s_globl, 0},
140 {"rsect", obj_coff_section, 0},
141 {"sect", obj_coff_section, 0},
142 {"block", s_space, 0},
147 const char EXP_CHARS[] = "eE";
149 /* Chars that mean this number is a floating point constant */
152 const char FLT_CHARS[] = "rRsSfFdDxXpP";
154 const relax_typeS md_relax_table[1];
156 static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
161 opcode_entry_type *opcode;
162 char *prev_name = "";
165 opcode_hash_control = hash_new ();
167 for (opcode = z8k_table; opcode->name; opcode++)
169 /* Only enter unique codes into the table */
170 char *src = opcode->name;
172 if (strcmp (opcode->name, prev_name))
174 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
178 prev_name = opcode->name;
181 /* default to z8002 */
184 /* insert the pseudo ops too */
185 for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
187 opcode_entry_type *fake_opcode;
188 fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
189 fake_opcode->name = md_pseudo_table[idx].poc_name,
190 fake_opcode->func = (void *) (md_pseudo_table + idx);
191 fake_opcode->opcode = 250;
193 hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
204 typedef struct z8k_op
206 char regsize; /* 'b','w','r','q' */
207 unsigned int reg; /* 0..15 */
211 unsigned int x_reg; /* any other register associated with the mode */
212 expressionS exp; /* any expression */
217 static expressionS *da_operand;
218 static expressionS *imm_operand;
224 DEFUN (whatreg, (reg, src),
228 if (isdigit (src[1]))
230 *reg = (src[0] - '0') * 10 + src[1] - '0';
235 *reg = (src[0] - '0');
247 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
256 /* try and parse a reg name, returns number of chars consumed */
258 DEFUN (parse_reg, (src, mode, reg),
265 if (src[0] == 's' && src[1] == 'p')
269 *mode = CLASS_REG_LONG;
274 *mode = CLASS_REG_WORD;
283 *mode = CLASS_REG_LONG;
284 res = whatreg (reg, src + 2);
286 else if (src[1] == 'h')
288 *mode = CLASS_REG_BYTE;
289 res = whatreg (reg, src + 2);
291 else if (src[1] == 'l')
293 *mode = CLASS_REG_BYTE;
294 res = whatreg (reg, src + 2);
297 else if (src[1] == 'q')
299 *mode = CLASS_REG_QUAD;
300 res = whatreg (reg, src + 2);
304 *mode = CLASS_REG_WORD;
305 res = whatreg (reg, src + 1);
313 DEFUN (parse_exp, (s, op),
317 char *save = input_line_pointer;
320 input_line_pointer = s;
322 if (op->X_op == O_absent)
323 as_bad ("missing operand");
324 new = input_line_pointer;
325 input_line_pointer = save;
329 /* The many forms of operand:
348 DEFUN (checkfor, (ptr, what),
356 as_bad ("expected %c", what);
361 /* Make sure the mode supplied is the size of a word */
363 DEFUN (regword, (mode, string),
372 as_bad ("register is wrong size for a word %s", string);
376 /* Make sure the mode supplied is the size of an address */
378 DEFUN (regaddr, (mode, string),
384 ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
387 as_bad ("register is wrong size for address %s", string);
398 struct cc_names table[] =
426 DEFUN (get_cc_operand, (ptr, mode, dst),
428 struct z8k_op *mode AND
438 mode->mode = CLASS_CC;
439 for (i = 0; table[i].name; i++)
443 for (j = 0; table[i].name[j]; j++)
445 if (table[i].name[j] != src[j])
448 the_cc = table[i].value;
458 get_operand (ptr, mode, dst)
475 mode->mode = CLASS_IMM;
476 imm_operand = &(mode->exp);
477 src = parse_exp (src + 1, &(mode->exp));
479 else if (*src == '@')
483 mode->mode = CLASS_IR;
484 src = parse_reg (src + 1, &d, &mode->reg);
490 end = parse_reg (src, &mode->mode, ®n);
500 end = parse_reg (src, &nw, &nr);
508 as_bad ("Missing ) in ra(rb)");
515 regaddr (mode->mode, "ra(rb) ra");
516 /* regword (mode->mode, "ra(rb) rb");*/
517 mode->mode = CLASS_BX;
527 src = parse_exp (src, &(mode->exp));
528 src = checkfor (src, ')');
529 mode->mode = CLASS_BA;
532 imm_operand = &(mode->exp);
544 src = parse_exp (src, &(mode->exp));
548 end = parse_reg (src, &(mode->mode), ®n);
549 regword (mode->mode, "addr(Ra) ra");
550 mode->mode = CLASS_X;
553 da_operand = &(mode->exp);
554 src = checkfor (end, ')');
558 /* Just an address */
559 mode->mode = CLASS_DA;
562 da_operand = &(mode->exp);
571 get_operands (opcode, op_end, operand)
572 opcode_entry_type *opcode;
578 switch (opcode->noperands)
587 if (opcode->arg_info[0] == CLASS_CC)
589 get_cc_operand (&ptr, operand + 0, 0);
594 get_operand (&ptr, operand + 0, 0);
601 if (opcode->arg_info[0] == CLASS_CC)
603 get_cc_operand (&ptr, operand + 0, 0);
608 get_operand (&ptr, operand + 0, 0);
614 get_operand (&ptr, operand + 1, 1);
619 get_operand (&ptr, operand + 0, 0);
622 get_operand (&ptr, operand + 1, 1);
625 get_operand (&ptr, operand + 2, 2);
630 get_operand (&ptr, operand + 0, 0);
633 get_operand (&ptr, operand + 1, 1);
636 get_operand (&ptr, operand + 2, 2);
639 get_cc_operand (&ptr, operand + 3, 3);
648 /* Passed a pointer to a list of opcodes which use different
649 addressing modes, return the opcode which matches the opcodes
655 DEFUN (get_specific, (opcode, operands),
656 opcode_entry_type * opcode AND
660 opcode_entry_type *this_try = opcode;
662 unsigned int noperands = opcode->noperands;
664 unsigned int dispreg;
665 unsigned int this_index = opcode->idx;
667 while (this_index == opcode->idx && !found)
672 for (i = 0; i < noperands; i++)
674 int mode = operands[i].mode;
676 if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
678 /* it could be an pc rel operand, if this is a da mode and
679 we like disps, then insert it */
681 if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
683 /* This is the case */
684 operands[i].mode = CLASS_DISP;
686 else if (mode == CLASS_BA && this_try->arg_info[i])
688 /* Can't think of a way to turn what we've been given into
689 something that's ok */
692 else if (this_try->arg_info[i] & CLASS_PR)
694 if (mode == CLASS_REG_LONG && segmented_mode)
698 else if (mode == CLASS_REG_WORD && !segmented_mode)
708 switch (mode & CLASS_MASK)
723 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
738 DEFUN (check_operand, (operand, width, string),
739 struct z8k_op *operand AND
740 unsigned int width AND
743 if (operand->exp.X_add_symbol == 0
744 && operand->exp.X_op_symbol == 0)
747 /* No symbol involved, let's look at offset, it's dangerous if any of
748 the high bits are not 0 or ff's, find out by oring or anding with
749 the width and seeing if the answer is 0 or all fs*/
750 if ((operand->exp.X_add_number & ~width) != 0 &&
751 (operand->exp.X_add_number | width) != (~0))
753 as_warn ("operand %s0x%x out of range.", string, operand->exp.X_add_number);
759 static char buffer[20];
762 DEFUN (newfix, (ptr, type, operand),
765 expressionS * operand)
767 if (operand->X_add_symbol
768 || operand->X_op_symbol
769 || operand->X_add_number)
771 fix_new_exp (frag_now,
781 DEFUN (apply_fix, (ptr, type, operand, size),
784 expressionS * operand AND
787 int n = operand->X_add_number;
789 operand->X_add_number = n;
790 newfix ((ptr - buffer) / 2, type, operand);
794 case 8: /* 8 nibbles == 32 bits */
799 case 4: /* 4 niblles == 16 bits */
813 /* Now we know what sort of opcodes it is, lets build the bytes -
815 #define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
817 build_bytes (this_try, operand)
818 opcode_entry_type * this_try;
819 struct z8k_op *operand;
825 char *output_ptr = buffer;
831 unsigned int *class_ptr;
833 frag_wane (frag_now);
836 memset (buffer, 20, 0);
837 class_ptr = this_try->byte_info;
840 for (nibble = 0; c = *class_ptr++; nibble++)
843 switch (c & CLASS_MASK)
849 /* Direct address, we don't cope with the SS mode right now */
852 da_operand->X_add_number |= 0x80000000;
853 output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);
857 output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
863 output_ptr = apply_fix (output_ptr, R_JR, da_operand, 2);
870 output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
877 output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
882 *output_ptr = c & 0xf;
885 if (imm_operand->X_add_number == 2)
889 else if (imm_operand->X_add_number != 1)
891 as_bad ("immediate must be 1 or 2");
896 as_bad ("immediate 1 or 2 expected");
901 *output_ptr++ = the_cc;
904 *output_ptr++ = c & 0xf;
907 if (reg[c & 0xf] == 0)
909 as_bad ("can't use R0 here");
916 /* Insert bit mattern of
918 *output_ptr++ = reg[c & 0xf];
921 output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
928 switch (c & ARG_MASK)
931 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
934 imm_operand->X_add_number--;
935 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
938 imm_operand->X_add_number--;
939 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
942 imm_operand->X_add_number = -imm_operand->X_add_number;
944 output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);
947 output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);
951 output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
961 /* Copy from the nibble buffer into the frag */
964 int length = (output_ptr - buffer) / 2;
966 char *fragp = frag_more (length);
968 while (src < output_ptr)
970 *fragp = (src[0] << 4) | src[1];
979 /* This is the guts of the machine-dependent assembler. STR points to a
980 machine dependent instruction. This funciton is supposed to emit
981 the frags/bytes it assembles to.
985 DEFUN (md_assemble, (str),
991 struct z8k_op operand[3];
992 opcode_entry_type *opcode;
993 opcode_entry_type *prev_opcode;
998 /* Drop leading whitespace */
1002 /* find the op code end */
1003 for (op_start = op_end = str;
1004 *op_end != 0 && *op_end != ' ';
1011 if (op_end == op_start)
1013 as_bad ("can't find opcode ");
1019 opcode = (opcode_entry_type *) hash_find (opcode_hash_control,
1025 as_bad ("unknown opcode");
1029 if (opcode->opcode == 250)
1031 /* was really a pseudo op */
1036 char *old = input_line_pointer;
1040 input_line_pointer = op_end;
1044 while (*input_line_pointer == ' ')
1045 input_line_pointer++;
1046 p = (pseudo_typeS *) (opcode->func);
1048 (p->poc_handler) (p->poc_val);
1049 input_line_pointer = old;
1054 input_line_pointer = get_operands (opcode, op_end,
1056 prev_opcode = opcode;
1058 opcode = get_specific (opcode, operand);
1062 /* Couldn't find an opcode which matched the operands */
1063 char *where = frag_more (2);
1068 as_bad ("Can't find opcode to match operands");
1072 build_bytes (opcode, operand);
1077 DEFUN (tc_crawl_symbol_chain, (headers),
1078 object_headers * headers)
1080 printf ("call to tc_crawl_symbol_chain \n");
1084 DEFUN (md_undefined_symbol, (name),
1091 DEFUN (tc_headers_hook, (headers),
1092 object_headers * headers)
1094 printf ("call to tc_headers_hook \n");
1102 /* Various routines to kill one day */
1103 /* Equal to MAX_PRECISION in atof-ieee.c */
1104 #define MAX_LITTLENUMS 6
1106 /* Turn a string in input_line_pointer into a floating point constant of type
1107 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1108 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1111 md_atof (type, litP, sizeP)
1117 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1118 LITTLENUM_TYPE *wordP;
1150 return "Bad call to MD_ATOF()";
1152 t = atof_ieee (input_line_pointer, type, words);
1154 input_line_pointer = t;
1156 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1157 for (wordP = words; prec--;)
1159 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1160 litP += sizeof (LITTLENUM_TYPE);
1166 md_parse_option (argP, cntP, vecP)
1172 if (!strcmp (*argP, "z8001"))
1176 else if (!strcmp (*argP, "z8002"))
1186 int md_short_jump_size;
1189 tc_aout_fix_to_chars ()
1191 printf ("call to tc_aout_fix_to_chars \n");
1196 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
1203 as_fatal ("failed sanity check.");
1207 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
1209 addressT from_addr, to_addr;
1213 as_fatal ("failed sanity check.");
1217 md_convert_frag (headers, fragP)
1218 object_headers *headers;
1222 printf ("call to md_convert_frag \n");
1227 DEFUN (md_section_align, (seg, size),
1231 return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
1236 md_apply_fix (fixP, val)
1240 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1242 switch (fixP->fx_r_type)
1245 buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
1251 /* if (val != 0) abort();*/
1257 /* if (val != 0) abort();*/
1264 *buf++ = (val >> 8);
1268 *buf++ = (val >> 24);
1269 *buf++ = (val >> 16);
1270 *buf++ = (val >> 8);
1275 *buf++ = (val >> 16);
1277 *buf++ = (val >> 8);
1289 DEFUN (md_operand, (expressionP), expressionS * expressionP)
1293 int md_long_jump_size;
1295 md_estimate_size_before_relax (fragP, segment_type)
1296 register fragS *fragP;
1297 register segT segment_type;
1299 printf ("call tomd_estimate_size_before_relax \n");
1303 /* Put number into target byte order */
1306 DEFUN (md_number_to_chars, (ptr, use, nbytes),
1314 *ptr++ = (use >> 24) & 0xff;
1316 *ptr++ = (use >> 16) & 0xff;
1318 *ptr++ = (use >> 8) & 0xff;
1320 *ptr++ = (use >> 0) & 0xff;
1327 md_pcrel_from (fixP)
1334 tc_coff_symbol_emit_hook ()
1339 tc_reloc_mangle (fix_ptr, intr, base)
1341 struct internal_reloc *intr;
1345 symbolS *symbol_ptr;
1347 symbol_ptr = fix_ptr->fx_addsy;
1349 /* If this relocation is attached to a symbol then it's ok
1351 if (fix_ptr->fx_r_type == 0)
1353 /* cons likes to create reloc32's whatever the size of the reloc..
1355 switch (fix_ptr->fx_size)
1359 intr->r_type = R_IMM16;
1362 intr->r_type = R_IMM8;
1365 intr->r_type = R_IMM32;
1375 intr->r_type = fix_ptr->fx_r_type;
1378 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1379 intr->r_offset = fix_ptr->fx_offset;
1382 intr->r_symndx = symbol_ptr->sy_number;
1384 intr->r_symndx = -1;