file config.texi was initially added on branch binutils-2_17-branch.
[binutils.git] / gas / config / tc-maxq.c
blobc1a11afc05fd994e7e2266be5c298de988f8914b
1 /* tc-maxq.c -- assembler code for a MAXQ chip.
3 Copyright 2004, 2005 Free Software Foundation, Inc.
5 Contributed by HCL Technologies Pvt. Ltd.
7 Author: Vineet Sharma(vineets@noida.hcltech.com) Inderpreet
8 S.(inderpreetb@noida.hcltech.com)
10 This file is part of GAS.
12 GAS is free software; you can redistribute it and/or modify it under the
13 terms of the GNU General Public License as published by the Free Software
14 Foundation; either version 2, or (at your option) any later version.
16 GAS is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 details.
21 You should have received a copy of the GNU General Public License along
22 with GAS; see the file COPYING. If not, write to the Free Software
23 Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
25 #include "as.h"
26 #include "safe-ctype.h"
27 #include "subsegs.h"
28 #include "dwarf2dbg.h"
29 #include "tc-maxq.h"
30 #include "opcode/maxq.h"
31 #include "ctype.h"
33 #ifndef MAXQ10S
34 #define MAXQ10S 1
35 #endif
37 #ifndef _STRING_H
38 #include "string.h"
39 #endif
41 #ifndef DEFAULT_ARCH
42 #define DEFAULT_ARCH "MAXQ20"
43 #endif
45 #ifndef MAX_OPERANDS
46 #define MAX_OPERANDS 2
47 #endif
49 #ifndef MAX_MNEM_SIZE
50 #define MAX_MNEM_SIZE 8
51 #endif
53 #ifndef END_OF_INSN
54 #define END_OF_INSN '\0'
55 #endif
57 #ifndef IMMEDIATE_PREFIX
58 #define IMMEDIATE_PREFIX '#'
59 #endif
61 #ifndef MAX_REG_NAME_SIZE
62 #define MAX_REG_NAME_SIZE 4
63 #endif
65 #ifndef MAX_MEM_NAME_SIZE
66 #define MAX_MEM_NAME_SIZE 9
67 #endif
69 /* opcode for PFX[0]. */
70 #define PFX0 0x0b
72 /* Set default to MAXQ20. */
73 unsigned int max_version = bfd_mach_maxq20;
75 const char *default_arch = DEFAULT_ARCH;
77 /* Type of the operand: Register,Immediate,Memory access,flag or bit. */
79 union _maxq20_op
81 const reg_entry * reg;
82 char imms; /* This is to store the immediate value operand. */
83 expressionS * disps;
84 symbolS * data;
85 const mem_access * mem;
86 int flag;
87 const reg_bit * r_bit;
90 typedef union _maxq20_op maxq20_opcode;
92 /* For handling optional L/S in Maxq20. */
94 /* Exposed For Linker - maps indirectly to the liker relocations. */
95 #define LONG_PREFIX MAXQ_LONGJUMP /* BFD_RELOC_16 */
96 #define SHORT_PREFIX MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
97 #define ABSOLUTE_ADDR_FOR_DATA MAXQ_INTERSEGMENT
99 #define NO_PREFIX 0
100 #define EXPLICT_LONG_PREFIX 14
102 /* The main instruction structure containing fields to describe instrn */
103 typedef struct _maxq20_insn
105 /* The opcode information for the MAXQ20 */
106 MAXQ20_OPCODE_INFO op;
108 /* The number of operands */
109 unsigned int operands;
111 /* Number of different types of operands - Comments can be removed if reqd.
113 unsigned int reg_operands, mem_operands, disp_operands, data_operands;
114 unsigned int imm_operands, imm_bit_operands, bit_operands, flag_operands;
116 /* Types of the individual operands */
117 UNKNOWN_OP types[MAX_OPERANDS];
119 /* Relocation type for operand : to be investigated into */
120 int reloc[MAX_OPERANDS];
122 /* Complete information of the Operands */
123 maxq20_opcode maxq20_op[MAX_OPERANDS];
125 /* Choice of prefix register whenever needed */
126 int prefix;
128 /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
129 unsigned char Instr_Prefix;
131 /* 16 bit Instruction word */
132 unsigned char instr[2];
134 maxq20_insn;
136 /* Definitions of all possible characters that can start an operand. */
137 const char *extra_symbol_chars = "@(#";
139 /* Special Character that would start a comment. */
140 const char comment_chars[] = ";";
142 /* Starts a comment when it appears at the start of a line. */
143 const char line_comment_chars[] = ";#";
145 const char line_separator_chars[] = ""; /* originally may b by sudeep "\n". */
147 /* The following are used for option processing. */
149 /* This is added to the mach independent string passed to getopt. */
150 const char *md_shortopts = "q";
152 /* Characters for exponent and floating point. */
153 const char EXP_CHARS[] = "eE";
154 const char FLT_CHARS[] = "";
156 /* This is for the machine dependent option handling. */
157 #define OPTION_EB (OPTION_MD_BASE + 0)
158 #define OPTION_EL (OPTION_MD_BASE + 1)
159 #define MAXQ_10 (OPTION_MD_BASE + 2)
160 #define MAXQ_20 (OPTION_MD_BASE + 3)
162 struct option md_longopts[] =
164 {"MAXQ10", no_argument, NULL, MAXQ_10},
165 {"MAXQ20", no_argument, NULL, MAXQ_20},
166 {NULL, no_argument, NULL, 0}
168 size_t md_longopts_size = sizeof (md_longopts);
170 /* md_undefined_symbol We have no need for this function. */
172 symbolS *
173 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
175 return NULL;
178 static void
179 maxq_target (int target)
181 max_version = target;
182 bfd_set_arch_mach (stdoutput, bfd_arch_maxq, max_version);
186 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
188 /* Any options support will be added onto this switch case. */
189 switch (c)
191 case MAXQ_10:
192 max_version = bfd_mach_maxq10;
193 break;
194 case MAXQ_20:
195 max_version = bfd_mach_maxq20;
196 break;
198 default:
199 return 0;
202 return 1;
205 /* When a usage message is printed, this function is called and
206 it prints a description of the machine specific options. */
208 void
209 md_show_usage (FILE * stream)
211 /* Over here we will fill the description of the machine specific options. */
213 fprintf (stream, _(" MAXQ-specific assembler options:\n"));
215 fprintf (stream, _("\
216 -MAXQ20 generate obj for MAXQ20(default)\n\
217 -MAXQ10 generate obj for MAXQ10\n\
218 "));
221 unsigned long
222 maxq20_mach (void)
224 if (!(strcmp (default_arch, "MAXQ20")))
225 return 0;
227 as_fatal (_("Unknown architecture"));
228 return 1;
231 arelent *
232 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
234 arelent *rel;
235 bfd_reloc_code_real_type code;
237 switch (fixp->fx_r_type)
239 case MAXQ_INTERSEGMENT:
240 case MAXQ_LONGJUMP:
241 case BFD_RELOC_16_PCREL_S2:
242 code = fixp->fx_r_type;
243 break;
245 case 0:
246 default:
247 switch (fixp->fx_size)
249 default:
250 as_bad_where (fixp->fx_file, fixp->fx_line,
251 _("can not do %d byte relocation"), fixp->fx_size);
252 code = BFD_RELOC_32;
253 break;
255 case 1:
256 code = BFD_RELOC_8;
257 break;
258 case 2:
259 code = BFD_RELOC_16;
260 break;
261 case 4:
262 code = BFD_RELOC_32;
263 break;
267 rel = xmalloc (sizeof (arelent));
268 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
269 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
271 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
272 rel->addend = fixp->fx_addnumber;
273 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
275 if (rel->howto == NULL)
277 as_bad_where (fixp->fx_file, fixp->fx_line,
278 _("cannot represent relocation type %s"),
279 bfd_get_reloc_code_name (code));
281 /* Set howto to a garbage value so that we can keep going. */
282 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
283 assert (rel->howto != NULL);
286 return rel;
289 /* md_estimate_size_before_relax()
291 Called just before relax() for rs_machine_dependent frags. The MAXQ
292 assembler uses these frags to handle 16 bit absolute jumps which require a
293 prefix instruction to be inserted. Any symbol that is now undefined will
294 not become defined. Return the correct fr_subtype in the frag. Return the
295 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
296 caller. The guess is actually the growth beyond the fixed part. Whatever
297 we do to grow the fixed or variable part contributes to our returned
298 value. */
301 md_estimate_size_before_relax (fragS *fragP, segT segment)
303 /* Check whether the symbol has been resolved or not.
304 Otherwise we will have to generate a fixup. */
305 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment)
306 || fragP->fr_subtype == EXPLICT_LONG_PREFIX)
308 RELOC_ENUM reloc_type;
309 unsigned char *opcode;
310 int old_fr_fix;
312 /* Now this symbol has not been defined in this file.
313 Hence we will have to create a fixup. */
314 int size = 2;
316 /* This is for the prefix instruction. */
318 if (fragP->fr_subtype == EXPLICT_LONG_PREFIX)
319 fragP->fr_subtype = LONG_PREFIX;
321 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
322 && ((!(fragP->fr_subtype) == EXPLICT_LONG_PREFIX)))
323 fragP->fr_subtype = ABSOLUTE_ADDR_FOR_DATA;
325 reloc_type =
326 (fragP->fr_subtype ? fragP->fr_subtype : ABSOLUTE_ADDR_FOR_DATA);
328 fragP->fr_subtype = reloc_type;
330 if (reloc_type == SHORT_PREFIX)
331 size = 0;
332 old_fr_fix = fragP->fr_fix;
333 opcode = (unsigned char *) fragP->fr_opcode;
335 fragP->fr_fix += (size);
337 fix_new (fragP, old_fr_fix - 2, size + 2,
338 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
339 frag_wane (fragP);
340 return fragP->fr_fix - old_fr_fix;
343 if (fragP->fr_subtype == SHORT_PREFIX)
345 fragP->fr_subtype = SHORT_PREFIX;
346 return 0;
349 if (fragP->fr_subtype == NO_PREFIX || fragP->fr_subtype == LONG_PREFIX)
351 unsigned long instr;
352 unsigned long call_addr;
353 long diff;
354 fragS *f;
355 diff = diff ^ diff;;
356 call_addr = call_addr ^ call_addr;
357 instr = 0;
358 f = NULL;
360 /* segment_info_type *seginfo = seg_info (segment); */
361 instr = fragP->fr_address + fragP->fr_fix - 2;
363 /* This is the offset if it is a PC relative jump. */
364 call_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
366 /* PC stores the value of the next instruction. */
367 diff = (call_addr - instr) - 1;
369 if (diff >= (-128 * 2) && diff <= (2 * 127))
371 /* Now as offset is an 8 bit value, we will pass
372 that to the jump instruction directly. */
373 fragP->fr_subtype = NO_PREFIX;
374 return 0;
377 fragP->fr_subtype = LONG_PREFIX;
378 return 2;
381 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
382 frag_now->fr_line);
383 return 0;
386 /* Equal to MAX_PRECISION in atof-ieee.c */
387 #define MAX_LITTLENUMS 6
389 /* Turn a string in input_line_pointer into a floating point constant of type
390 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
391 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
393 char *
394 md_atof (int type, char * litP, int * sizeP)
396 int prec;
397 LITTLENUM_TYPE words[4];
398 char *t;
399 int i;
401 switch (type)
403 case 'f':
404 prec = 2;
405 break;
407 case 'd':
408 prec = 2;
409 /* The size of Double has been changed to 2 words ie 32 bits. */
410 /* prec = 4; */
411 break;
413 default:
414 *sizeP = 0;
415 return _("bad call to md_atof");
418 t = atof_ieee (input_line_pointer, type, words);
419 if (t)
420 input_line_pointer = t;
422 *sizeP = prec * 2;
424 for (i = prec - 1; i >= 0; i--)
426 md_number_to_chars (litP, (valueT) words[i], 2);
427 litP += 2;
430 return NULL;
433 void
434 maxq20_cons_fix_new (fragS * frag, unsigned int off, unsigned int len,
435 expressionS * exp)
437 int r = 0;
439 switch (len)
441 case 2:
442 r = MAXQ_WORDDATA; /* Word+n */
443 break;
444 case 4:
445 r = MAXQ_LONGDATA; /* Long+n */
446 break;
449 fix_new_exp (frag, off, len, exp, 0, r);
450 return;
453 /* GAS will call this for every rs_machine_dependent fragment. The
454 instruction is compleated using the data from the relaxation pass. It may
455 also create any necessary relocations. */
456 void
457 md_convert_frag (bfd * headers ATTRIBUTE_UNUSED,
458 segT seg ATTRIBUTE_UNUSED,
459 fragS * fragP)
461 char *opcode;
462 offsetT target_address;
463 offsetT opcode_address;
464 offsetT displacement_from_opcode_start;
465 int address;
467 opcode = fragP->fr_opcode;
468 address = 0;
469 target_address = opcode_address = displacement_from_opcode_start = 0;
471 target_address =
472 (S_GET_VALUE (fragP->fr_symbol) / MAXQ_OCTETS_PER_BYTE) +
473 (fragP->fr_offset / MAXQ_OCTETS_PER_BYTE);
475 opcode_address =
476 (fragP->fr_address / MAXQ_OCTETS_PER_BYTE) +
477 ((fragP->fr_fix - 2) / MAXQ_OCTETS_PER_BYTE);
479 /* PC points to the next Instruction. */
480 displacement_from_opcode_start = ((target_address - opcode_address) - 1);
482 if ((displacement_from_opcode_start >= -128
483 && displacement_from_opcode_start <= 127)
484 && (fragP->fr_subtype == SHORT_PREFIX
485 || fragP->fr_subtype == NO_PREFIX))
487 /* Its a displacement. */
488 *opcode = (char) displacement_from_opcode_start;
490 else
492 /* Its an absolute 16 bit jump. Now we have to
493 load the prefix operator with the upper 8 bits. */
494 if (fragP->fr_subtype == SHORT_PREFIX)
496 as_bad (_("Cant make long jump/call into short jump/call : %d"),
497 fragP->fr_line);
498 return;
501 /* Check whether the symbol has been resolved or not.
502 Otherwise we will have to generate a fixup. */
504 if (fragP->fr_subtype != SHORT_PREFIX)
506 RELOC_ENUM reloc_type;
507 int old_fr_fix;
508 int size = 2;
510 /* Now this is a basolute jump/call.
511 Hence we will have to create a fixup. */
512 if (fragP->fr_subtype == NO_PREFIX)
513 fragP->fr_subtype = LONG_PREFIX;
515 reloc_type =
516 (fragP->fr_subtype ? fragP->fr_subtype : LONG_PREFIX);
518 if (reloc_type == 1)
519 size = 0;
520 old_fr_fix = fragP->fr_fix;
522 fragP->fr_fix += (size);
524 fix_new (fragP, old_fr_fix - 2, size + 2,
525 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
526 frag_wane (fragP);
531 long
532 md_pcrel_from (fixS *fixP)
534 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
537 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
539 void
540 maxq_number_to_chars (char *buf, valueT val, int n)
542 if (target_big_endian)
543 number_to_chars_bigendian (buf, val, n);
544 else
545 number_to_chars_littleendian (buf, val, n);
548 /* GAS will call this for each fixup. It's main objective is to store the
549 correct value in the object file. 'fixup_segment' performs the generic
550 overflow check on the 'valueT *val' argument after md_apply_fix returns.
551 If the overflow check is relevant for the target machine, then
552 'md_apply_fix' should modify 'valueT *val', typically to the value stored
553 in the object file (not to be done in MAXQ). */
555 void
556 md_apply_fix (fixS *fixP, valueT *valT, segT seg ATTRIBUTE_UNUSED)
558 char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
559 char *frag_to_fix_at =
560 fixP->fx_frag->fr_literal + fixP->fx_frag->fr_fix - 2;
562 if (fixP)
564 if (fixP->fx_frag && valT)
566 /* If the relaxation substate is not defined we make it equal
567 to the kind of relocation the fixup is generated for. */
568 if (!fixP->fx_frag->fr_subtype)
569 fixP->fx_frag->fr_subtype = fixP->fx_r_type;
571 /* For any instruction in which either we have specified an
572 absolute address or it is a long jump we need to add a PFX0
573 instruction to it. In this case as the instruction has already
574 being written at 'fx_where' in the frag we copy it at the end of
575 the frag(which is where the relocation was generated) as when
576 the relocation is generated the frag is grown by 2 type, this is
577 where we copy the contents of fx_where and add a pfx0 at
578 fx_where. */
579 if ((fixP->fx_frag->fr_subtype == ABSOLUTE_ADDR_FOR_DATA)
580 || (fixP->fx_frag->fr_subtype == LONG_PREFIX))
582 *(frag_to_fix_at + 1) = *(p + 1);
583 maxq_number_to_chars (p + 1, PFX0, 1);
586 /* Remember value for tc_gen_reloc. */
587 fixP->fx_addnumber = *valT;
590 /* Some fixups generated by GAS which gets resovled before this this
591 func. is called need to be wriiten to the frag as here we are going
592 to go away with the relocations fx_done=1. */
593 if (fixP->fx_addsy == NULL)
595 maxq_number_to_chars (p, *valT, fixP->fx_size);
596 fixP->fx_addnumber = *valT;
597 fixP->fx_done = 1;
602 /* Tables for lexical analysis. */
603 static char mnemonic_chars[256];
604 static char register_chars[256];
605 static char operand_chars[256];
606 static char identifier_chars[256];
607 static char digit_chars[256];
609 /* Lexical Macros. */
610 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
611 #define is_register_char(x) (register_chars[(unsigned char)(x)])
612 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
613 #define is_space_char(x) (x==' ')
614 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
615 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
617 /* Special characters for operands. */
618 static char operand_special_chars[] = "[]@.-+";
620 /* md_assemble() will always leave the instruction passed to it unaltered.
621 To do this we store the instruction in a special stack. */
622 static char save_stack[32];
623 static char *save_stack_p;
625 #define END_STRING_AND_SAVE(s) \
626 do \
628 *save_stack_p++ = *(s); \
629 *s = '\0'; \
631 while (0)
633 #define RESTORE_END_STRING(s) \
634 do \
636 *(s) = *(--save_stack_p); \
638 while (0)
640 /* The instruction we are assembling. */
641 static maxq20_insn i;
643 /* The current template. */
644 static MAXQ20_OPCODES *current_templates;
646 /* The displacement operand if any. */
647 static expressionS disp_expressions;
649 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
650 static int this_operand;
652 /* The prefix instruction if used. */
653 static char PFX_INSN[2];
654 static char INSERT_BUFFER[2];
656 /* For interface with expression() ????? */
657 extern char *input_line_pointer;
659 /* The HASH Tables: */
661 /* Operand Hash Table. */
662 static struct hash_control *op_hash;
664 /* Register Hash Table. */
665 static struct hash_control *reg_hash;
667 /* Memory reference Hash Table. */
668 static struct hash_control *mem_hash;
670 /* Bit hash table. */
671 static struct hash_control *bit_hash;
673 /* Memory Access syntax table. */
674 static struct hash_control *mem_syntax_hash;
676 /* This is a mapping from pseudo-op names to functions. */
678 const pseudo_typeS md_pseudo_table[] =
680 {"int", cons, 2}, /* size of 'int' has been changed to 1 word
681 (i.e) 16 bits. */
682 {"maxq10", maxq_target, bfd_mach_maxq10},
683 {"maxq20", maxq_target, bfd_mach_maxq20},
684 {NULL, 0, 0},
687 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
690 /* This function sets the PFX value coresponding to the specs. Source
691 Destination Index Selection ---------------------------------- Write To|
692 SourceRegRange | Dest Addr Range
693 ------------------------------------------------------ PFX[0] | 0h-Fh |
694 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
695 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
696 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
698 static void
699 set_prefix (void)
701 short int src_index = 0, dst_index = 0;
703 if (i.operands == 0)
704 return;
705 if (i.operands == 1) /* Only SRC is Present */
707 if (i.types[0] == REG)
709 if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
711 dst_index = i.maxq20_op[0].reg[0].Mod_index;
712 src_index = 0x00;
714 else
716 src_index = i.maxq20_op[0].reg[0].Mod_index;
717 dst_index = 0x00;
722 if (i.operands == 2)
724 if (i.types[0] == REG && i.types[1] == REG)
726 dst_index = i.maxq20_op[0].reg[0].Mod_index;
727 src_index = i.maxq20_op[1].reg[0].Mod_index;
729 else if (i.types[0] != REG && i.types[1] == REG) /* DST is Absent */
731 src_index = i.maxq20_op[1].reg[0].Mod_index;
732 dst_index = 0x00;
734 else if (i.types[0] == REG && i.types[1] != REG) /* Id SRC is Absent */
736 dst_index = i.maxq20_op[0].reg[0].Mod_index;
737 src_index = 0x00;
739 else if (i.types[0] == BIT && i.maxq20_op[0].r_bit)
741 dst_index = i.maxq20_op[0].r_bit->reg->Mod_index;
742 src_index = 0x00;
745 else if (i.types[1] == BIT && i.maxq20_op[1].r_bit)
747 dst_index = 0x00;
748 src_index = i.maxq20_op[1].r_bit->reg->Mod_index;
752 if (src_index >= 0x00 && src_index <= 0xF)
754 if (dst_index >= 0x00 && dst_index <= 0x07)
755 /* Set PFX[0] */
756 i.prefix = 0;
758 else if (dst_index >= 0x08 && dst_index <= 0x0F)
759 /* Set PFX[2] */
760 i.prefix = 2;
762 else if (dst_index >= 0x10 && dst_index <= 0x17)
763 /* Set PFX[4] */
764 i.prefix = 4;
766 else if (dst_index >= 0x18 && dst_index <= 0x1F)
767 /* Set PFX[6] */
768 i.prefix = 6;
770 else if (src_index >= 0x10 && src_index <= 0x1F)
772 if (dst_index >= 0x00 && dst_index <= 0x07)
773 /* Set PFX[1] */
774 i.prefix = 1;
776 else if (dst_index >= 0x08 && dst_index <= 0x0F)
777 /* Set PFX[3] */
778 i.prefix = 3;
780 else if (dst_index >= 0x10 && dst_index <= 0x17)
781 /* Set PFX[5] */
782 i.prefix = 5;
784 else if (dst_index >= 0x18 && dst_index <= 0x1F)
785 /* Set PFX[7] */
786 i.prefix = 7;
790 static unsigned char
791 is_a_LSinstr (const char *ln_pointer)
793 int i = 0;
795 for (i = 0; LSInstr[i] != NULL; i++)
796 if (!strcmp (LSInstr[i], ln_pointer))
797 return 1;
799 return 0;
802 static void
803 LS_processing (const char *line)
805 if (is_a_LSinstr (line))
807 if ((line[0] == 'L') || (line[0] == 'l'))
809 i.prefix = 0;
810 INSERT_BUFFER[0] = PFX0;
811 i.Instr_Prefix = LONG_PREFIX;
813 else if ((line[0] == 'S') || (line[0] == 's'))
814 i.Instr_Prefix = SHORT_PREFIX;
815 else
816 i.Instr_Prefix = NO_PREFIX;
818 else
819 i.Instr_Prefix = LONG_PREFIX;
822 /* Separate mnemonics and the operands. */
824 static char *
825 parse_insn (char *line, char *mnemonic)
827 char *l = line;
828 char *token_start = l;
829 char *mnem_p;
830 char temp[MAX_MNEM_SIZE];
831 int ii = 0;
833 memset (temp, END_OF_INSN, MAX_MNEM_SIZE);
834 mnem_p = mnemonic;
836 while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
838 ii++;
839 mnem_p++;
840 if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
842 as_bad (_("no such instruction: `%s'"), token_start);
843 return NULL;
845 l++;
848 if (!is_space_char (*l) && *l != END_OF_INSN)
850 as_bad (_("invalid character %s in mnemonic"), l);
851 return NULL;
854 while (ii)
856 temp[ii - 1] = toupper ((char) mnemonic[ii - 1]);
857 ii--;
860 LS_processing (temp);
862 if (i.Instr_Prefix != 0 && is_a_LSinstr (temp))
863 /* Skip the optional L-S. */
864 memcpy (temp, temp + 1, MAX_MNEM_SIZE);
866 /* Look up instruction (or prefix) via hash table. */
867 current_templates = (MAXQ20_OPCODES *) hash_find (op_hash, temp);
869 if (current_templates != NULL)
870 return l;
872 as_bad (_("no such instruction: `%s'"), token_start);
873 return NULL;
876 /* Function to calculate x to the power of y.
877 Just to avoid including the math libraries. */
879 static int
880 pwr (int x, int y)
882 int k, ans = 1;
884 for (k = 0; k < y; k++)
885 ans *= x;
887 return ans;
890 static reg_entry *
891 parse_reg_by_index (char *imm_start)
893 int k = 0, mid = 0, rid = 0, val = 0, j = 0;
894 char temp[4] = { 0 };
895 reg_entry *reg = NULL;
899 if (isdigit (imm_start[k]))
900 temp[k] = imm_start[k] - '0';
902 else if (isalpha (imm_start[k])
903 && (imm_start[k] = tolower (imm_start[k])) < 'g')
904 temp[k] = 10 + (int) (imm_start[k] - 'a');
906 else if (imm_start[k] == 'h')
907 break;
909 else if (imm_start[k] == END_OF_INSN)
911 imm_start[k] = 'd';
912 break;
915 else
916 return NULL; /* not a hex digit */
918 k++;
920 while (imm_start[k] != '\n');
922 switch (imm_start[k])
924 case 'h':
925 for (j = 0; j < k; j++)
926 val += temp[j] * pwr (16, k - j - 1);
927 break;
929 case 'd':
930 for (j = 0; j < k; j++)
932 if (temp[j] > 9)
933 return NULL; /* not a number */
935 val += temp[j] * pwr (10, k - j - 1);
936 break;
940 /* Get the module and register id's. */
941 mid = val & 0x0f;
942 rid = (val >> 4) & 0x0f;
944 if (mid < 6)
946 /* Search the pheripheral reg table. */
947 for (j = 0; j < num_of_reg; j++)
949 if (new_reg_table[j].opcode == val)
951 reg = (reg_entry *) & new_reg_table[j];
952 break;
957 else
959 /* Search the system register table. */
960 j = 0;
962 while (system_reg_table[j].reg_name != NULL)
964 if (system_reg_table[j].opcode == val)
966 reg = (reg_entry *) & system_reg_table[j];
967 break;
969 j++;
973 if (reg == NULL)
975 as_bad (_("Invalid register value %s"), imm_start);
976 return reg;
979 #if CHANGE_PFX
980 if (this_operand == 0 && reg != NULL)
982 if (reg->Mod_index > 7)
983 i.prefix = 2;
984 else
985 i.prefix = 0;
987 #endif
988 return (reg_entry *) reg;
991 /* REG_STRING starts *before* REGISTER_PREFIX. */
993 static reg_entry *
994 parse_register (char *reg_string, char **end_op)
996 char *s = reg_string;
997 char *p = NULL;
998 char reg_name_given[MAX_REG_NAME_SIZE + 1];
999 reg_entry *r = NULL;
1001 r = NULL;
1002 p = NULL;
1004 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1005 if (is_space_char (*s))
1006 ++s;
1008 p = reg_name_given;
1009 while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1011 if (p >= reg_name_given + MAX_REG_NAME_SIZE)
1012 return (reg_entry *) NULL;
1013 s++;
1016 *end_op = s;
1018 r = (reg_entry *) hash_find (reg_hash, reg_name_given);
1020 #if CHANGE_PFX
1021 if (this_operand == 0 && r != NULL)
1023 if (r->Mod_index > 7)
1024 i.prefix = 2;
1025 else
1026 i.prefix = 0;
1028 #endif
1029 return r;
1032 static reg_bit *
1033 parse_register_bit (char *reg_string, char **end_op)
1035 const char *s = reg_string;
1036 short k = 0;
1037 char diff = 0;
1038 reg_bit *rb = NULL;
1039 reg_entry *r = NULL;
1040 bit_name *b = NULL;
1041 char temp_bitname[MAX_REG_NAME_SIZE + 2];
1042 char temp[MAX_REG_NAME_SIZE + 1];
1044 memset (&temp, '\0', (MAX_REG_NAME_SIZE + 1));
1045 memset (&temp_bitname, '\0', (MAX_REG_NAME_SIZE + 2));
1047 diff = 0;
1048 r = NULL;
1049 rb = NULL;
1050 rb = xmalloc (sizeof (reg_bit));
1051 rb->reg = xmalloc (sizeof (reg_entry));
1052 k = 0;
1054 /* For supporting bit names. */
1055 b = (bit_name *) hash_find (bit_hash, reg_string);
1057 if (b != NULL)
1059 *end_op = reg_string + strlen (reg_string);
1060 strcpy (temp_bitname, b->reg_bit);
1061 s = temp_bitname;
1064 if (strchr (s, '.'))
1066 while (*s != '.')
1068 if (*s == '\0')
1069 return NULL;
1070 temp[k] = *s++;
1072 k++;
1074 temp[k] = '\0';
1077 if ((r = parse_register (temp, end_op)) == NULL)
1078 return NULL;
1080 rb->reg = r;
1082 /* Skip the "." */
1083 s++;
1085 if (isdigit ((char) *s))
1086 rb->bit = atoi (s);
1087 else if (isalpha ((char) *s))
1089 rb->bit = (char) *s - 'a';
1090 rb->bit += 10;
1091 if (rb->bit > 15)
1093 as_bad (_("Invalid bit number : '%c'"), (char) *s);
1094 return NULL;
1098 if (b != NULL)
1099 diff = strlen (temp_bitname) - strlen (temp) - 1;
1100 else
1101 diff = strlen (reg_string) - strlen (temp) - 1;
1103 if (*(s + diff) != '\0')
1105 as_bad (_("Illegal character after operand '%s'"), reg_string);
1106 return NULL;
1109 return rb;
1112 static void
1113 pfx_for_imm_val (int arg)
1115 if (i.prefix == -1)
1116 return;
1118 if (i.prefix == 0 && arg == 0 && PFX_INSN[1] == 0 && !(i.data_operands))
1119 return;
1121 if (!(i.prefix < 0) && !(i.prefix > 7))
1122 PFX_INSN[0] = (i.prefix << 4) | PFX0;
1124 if (!PFX_INSN[1])
1125 PFX_INSN[1] = arg;
1129 static int
1130 maxq20_immediate (char *imm_start)
1132 int val = 0, val_pfx = 0;
1133 char sign_val = 0;
1134 int k = 0, j;
1135 int temp[4] = { 0 };
1137 imm_start++;
1139 if (imm_start[1] == '\0' && (imm_start[0] == '0' || imm_start[0] == '1')
1140 && (this_operand == 1 && ((i.types[0] == BIT || i.types[0] == FLAG))))
1142 val = imm_start[0] - '0';
1143 i.imm_bit_operands++;
1144 i.types[this_operand] = IMMBIT;
1145 i.maxq20_op[this_operand].imms = (char) val;
1146 #if CHANGE_PFX
1147 if (i.prefix == 2)
1148 pfx_for_imm_val (0);
1149 #endif
1150 return 1;
1153 /* Check For Sign Charcater. */
1154 sign_val = 0;
1158 if (imm_start[k] == '-' && k == 0)
1159 sign_val = -1;
1161 else if (imm_start[k] == '+' && k == 0)
1162 sign_val = 1;
1164 else if (isdigit (imm_start[k]))
1165 temp[k] = imm_start[k] - '0';
1167 else if (isalpha (imm_start[k])
1168 && (imm_start[k] = tolower (imm_start[k])) < 'g')
1169 temp[k] = 10 + (int) (imm_start[k] - 'a');
1171 else if (imm_start[k] == 'h')
1172 break;
1174 else if (imm_start[k] == '\0')
1176 imm_start[k] = 'd';
1177 break;
1179 else
1181 as_bad (_("Invalid Character in immediate Value : %c"),
1182 imm_start[k]);
1183 return 0;
1185 k++;
1187 while (imm_start[k] != '\n');
1189 switch (imm_start[k])
1191 case 'h':
1192 for (j = (sign_val ? 1 : 0); j < k; j++)
1193 val += temp[j] * pwr (16, k - j - 1);
1194 break;
1196 case 'd':
1197 for (j = (sign_val ? 1 : 0); j < k; j++)
1199 if (temp[j] > 9)
1201 as_bad (_("Invalid Character in immediate value : %c"),
1202 imm_start[j]);
1203 return 0;
1205 val += temp[j] * pwr (10, k - j - 1);
1209 if (!sign_val)
1210 sign_val = 1;
1212 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1213 check if we are moving a 16 bit immediate value into an 8 bit register.
1214 In that case we will generate a warning and move only the lower 8 bits */
1215 if (val > 65535)
1217 as_bad (_("Immediate value greater than 16 bits"));
1218 return 0;
1221 val = val * sign_val;
1223 /* If it is a stack pointer and the value is greater than the maximum
1224 permissible size */
1225 if (this_operand == 1)
1227 if ((val * sign_val) > MAX_STACK && i.types[0] == REG
1228 && !strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
1230 as_warn (_
1231 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1232 val = val & MAX_STACK;
1235 /* Check the range for 8 bit registers. */
1236 else if (((val * sign_val) > 0xFF) && (i.types[0] == REG)
1237 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1239 as_warn (_
1240 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1241 val = val & 0xfe;
1244 else if (((sign_val == -1) || (val > 0xFF)) && (i.types[0] == REG)
1245 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1247 val_pfx = val >> 8;
1248 val = ((val) & 0x00ff);
1249 SET_PFX_ARG (val_pfx);
1250 i.maxq20_op[this_operand].imms = (char) val;
1253 else if ((val <= 0xff) && (i.types[0] == REG)
1254 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1255 i.maxq20_op[this_operand].imms = (char) val;
1258 /* Check for 16 bit registers. */
1259 else if (((sign_val == -1) || val > 0xFE) && i.types[0] == REG
1260 && i.maxq20_op[0].reg->rtype == Reg_16W)
1262 /* Add PFX for any negative value -> 16bit register. */
1263 val_pfx = val >> 8;
1264 val = ((val) & 0x00ff);
1265 SET_PFX_ARG (val_pfx);
1266 i.maxq20_op[this_operand].imms = (char) val;
1269 else if (val < 0xFF && i.types[0] == REG
1270 && i.maxq20_op[0].reg->rtype == Reg_16W)
1272 i.maxq20_op[this_operand].imms = (char) val;
1275 /* All the immediate memory access - no PFX. */
1276 else if (i.types[0] == MEM)
1278 if ((sign_val == -1) || val > 0xFE)
1280 val_pfx = val >> 8;
1281 val = ((val) & 0x00ff);
1282 SET_PFX_ARG (val_pfx);
1283 i.maxq20_op[this_operand].imms = (char) val;
1285 else
1286 i.maxq20_op[this_operand].imms = (char) val;
1289 /* Special handling for immediate jumps like jump nz, #03h etc. */
1290 else if (val < 0xFF && i.types[0] == FLAG)
1291 i.maxq20_op[this_operand].imms = (char) val;
1293 else if ((((sign_val == -1) || val > 0xFE)) && i.types[0] == FLAG)
1295 val_pfx = val >> 8;
1296 val = ((val) & 0x00ff);
1297 SET_PFX_ARG (val_pfx);
1298 i.maxq20_op[this_operand].imms = (char) val;
1300 else
1302 as_bad (_("Invalid immediate move operation"));
1303 return 0;
1306 else
1308 /* All the instruction with operation on ACC: like ADD src, etc. */
1309 if ((sign_val == -1) || val > 0xFE)
1311 val_pfx = val >> 8;
1312 val = ((val) & 0x00ff);
1313 SET_PFX_ARG (val_pfx);
1314 i.maxq20_op[this_operand].imms = (char) val;
1316 else
1317 i.maxq20_op[this_operand].imms = (char) val;
1320 i.imm_operands++;
1321 return 1;
1324 static int
1325 extract_int_val (const char *imm_start)
1327 int k, j, val;
1328 char sign_val;
1329 int temp[4];
1331 k = 0;
1332 j = 0;
1333 val = 0;
1334 sign_val = 0;
1337 if (imm_start[k] == '-' && k == 0)
1338 sign_val = -1;
1340 else if (imm_start[k] == '+' && k == 0)
1341 sign_val = 1;
1343 else if (isdigit (imm_start[k]))
1344 temp[k] = imm_start[k] - '0';
1346 else if (isalpha (imm_start[k]) && (tolower (imm_start[k])) < 'g')
1347 temp[k] = 10 + (int) (tolower (imm_start[k]) - 'a');
1349 else if (tolower (imm_start[k]) == 'h')
1350 break;
1352 else if ((imm_start[k] == '\0') || (imm_start[k] == ']'))
1353 /* imm_start[k]='d'; */
1354 break;
1356 else
1358 as_bad (_("Invalid Character in immediate Value : %c"),
1359 imm_start[k]);
1360 return 0;
1362 k++;
1364 while (imm_start[k] != '\n');
1366 switch (imm_start[k])
1368 case 'h':
1369 for (j = (sign_val ? 1 : 0); j < k; j++)
1370 val += temp[j] * pwr (16, k - j - 1);
1371 break;
1373 default:
1374 for (j = (sign_val ? 1 : 0); j < k; j++)
1376 if (temp[j] > 9)
1378 as_bad (_("Invalid Character in immediate value : %c"),
1379 imm_start[j]);
1380 return 0;
1382 val += temp[j] * pwr (10, k - j - 1);
1386 if (!sign_val)
1387 sign_val = 1;
1389 return val * sign_val;
1392 static char
1393 check_for_parse (const char *line)
1395 int val;
1397 if (*(line + 1) == '[')
1401 line++;
1402 if ((*line == '-') || (*line == '+'))
1403 break;
1405 while (!is_space_char (*line));
1407 if ((*line == '-') || (*line == '+'))
1408 val = extract_int_val (line);
1409 else
1410 val = extract_int_val (line + 1);
1412 INSERT_BUFFER[0] = 0x3E;
1413 INSERT_BUFFER[1] = val;
1415 return 1;
1418 return 0;
1421 static mem_access *
1422 maxq20_mem_access (char *mem_string, char **end_op)
1424 char *s = mem_string;
1425 char *p;
1426 char mem_name_given[MAX_MEM_NAME_SIZE + 1];
1427 mem_access *m;
1429 m = NULL;
1431 /* Skip possible whitespace. */
1432 if (is_space_char (*s))
1433 ++s;
1435 p = mem_name_given;
1436 while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1438 if (p >= mem_name_given + MAX_MEM_NAME_SIZE)
1439 return (mem_access *) NULL;
1440 s++;
1443 *end_op = s;
1445 m = (mem_access *) hash_find (mem_hash, mem_name_given);
1447 return m;
1450 /* This function checks whether the operand is a variable in the data segment
1451 and if so, it returns its symbol entry from the symbol table. */
1453 static symbolS *
1454 maxq20_data (char *op_string)
1456 symbolS *symbolP;
1457 symbolP = symbol_find (op_string);
1459 if (symbolP != NULL
1460 && S_GET_SEGMENT (symbolP) != now_seg
1461 && S_GET_SEGMENT (symbolP) != bfd_und_section_ptr)
1463 /* In case we do not want to always include the prefix instruction and
1464 let the loader handle the job or in case of a 8 bit addressing mode,
1465 we will just check for val_pfx to be equal to zero and then load the
1466 prefix instruction. Otherwise no prefix instruction needs to be
1467 loaded. */
1468 /* The prefix register will have to be loaded automatically as we have
1469 a 16 bit addressing field. */
1470 pfx_for_imm_val (0);
1471 return symbolP;
1474 return NULL;
1477 static int
1478 maxq20_displacement (char *disp_start, char *disp_end)
1480 expressionS *exp;
1481 segT exp_seg = 0;
1482 char *save_input_line_pointer;
1483 #ifndef LEX_AT
1484 char *gotfree_input_line;
1485 #endif
1487 gotfree_input_line = NULL;
1488 exp = &disp_expressions;
1489 i.maxq20_op[this_operand].disps = exp;
1490 i.disp_operands++;
1491 save_input_line_pointer = input_line_pointer;
1492 input_line_pointer = disp_start;
1494 END_STRING_AND_SAVE (disp_end);
1496 #ifndef LEX_AT
1497 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1498 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1499 #endif
1500 exp_seg = expression (exp);
1502 SKIP_WHITESPACE ();
1503 if (*input_line_pointer)
1504 as_bad (_("junk `%s' after expression"), input_line_pointer);
1505 #if GCC_ASM_O_HACK
1506 RESTORE_END_STRING (disp_end + 1);
1507 #endif
1508 RESTORE_END_STRING (disp_end);
1509 input_line_pointer = save_input_line_pointer;
1510 #ifndef LEX_AT
1511 if (gotfree_input_line)
1512 free (gotfree_input_line);
1513 #endif
1514 if (exp->X_op == O_absent || exp->X_op == O_big)
1516 /* Missing or bad expr becomes absolute 0. */
1517 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1518 disp_start);
1519 exp->X_op = O_constant;
1520 exp->X_add_number = 0;
1521 exp->X_add_symbol = (symbolS *) 0;
1522 exp->X_op_symbol = (symbolS *) 0;
1524 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1526 if (exp->X_op != O_constant
1527 && OUTPUT_FLAVOR == bfd_target_aout_flavour
1528 && exp_seg != absolute_section
1529 && exp_seg != text_section
1530 && exp_seg != data_section
1531 && exp_seg != bss_section && exp_seg != undefined_section
1532 && !bfd_is_com_section (exp_seg))
1534 as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
1535 return 0;
1537 #endif
1538 i.maxq20_op[this_operand].disps = exp;
1539 return 1;
1542 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1543 Returns non-zero on error. */
1545 static int
1546 maxq20_operand (char *operand_string)
1548 reg_entry *r = NULL;
1549 reg_bit *rb = NULL;
1550 mem_access *m = NULL;
1551 char *end_op = NULL;
1552 symbolS *sym = NULL;
1553 char *base_string = NULL;
1554 int ii = 0;
1555 /* Start and end of displacement string expression (if found). */
1556 char *displacement_string_start = NULL;
1557 char *displacement_string_end = NULL;
1558 /* This maintains the case sentivness. */
1559 char case_str_op_string[MAX_OPERAND_SIZE + 1];
1560 char str_op_string[MAX_OPERAND_SIZE + 1];
1561 char *org_case_op_string = case_str_op_string;
1562 char *op_string = str_op_string;
1565 memset (op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1566 memset (org_case_op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1568 memcpy (op_string, operand_string, strlen (operand_string) + 1);
1569 memcpy (org_case_op_string, operand_string, strlen (operand_string) + 1);
1571 ii = strlen (operand_string) + 1;
1573 if (ii > MAX_OPERAND_SIZE)
1575 as_bad (_("Size of Operand '%s' greater than %d"), op_string,
1576 MAX_OPERAND_SIZE);
1577 return 0;
1580 while (ii)
1582 op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1583 ii--;
1586 if (is_space_char (*op_string))
1587 ++op_string;
1589 if (isxdigit (operand_string[0]))
1591 /* Now the operands can start with an Integer. */
1592 r = parse_reg_by_index (op_string);
1593 if (r != NULL)
1595 if (is_space_char (*op_string))
1596 ++op_string;
1597 i.types[this_operand] = REG; /* Set the type. */
1598 i.maxq20_op[this_operand].reg = r; /* Set the Register value. */
1599 i.reg_operands++;
1600 return 1;
1603 /* Get the origanal string. */
1604 memcpy (op_string, operand_string, strlen (operand_string) + 1);
1605 ii = strlen (operand_string) + 1;
1607 while (ii)
1609 op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1610 ii--;
1614 /* Check for flags. */
1615 if (!strcmp (op_string, "Z"))
1617 if (is_space_char (*op_string))
1618 ++op_string;
1620 i.types[this_operand] = FLAG; /* Set the type. */
1621 i.maxq20_op[this_operand].flag = FLAG_Z; /* Set the Register value. */
1623 i.flag_operands++;
1625 return 1;
1628 else if (!strcmp (op_string, "NZ"))
1630 if (is_space_char (*op_string))
1631 ++op_string;
1633 i.types[this_operand] = FLAG; /* Set the type. */
1634 i.maxq20_op[this_operand].flag = FLAG_NZ; /* Set the Register value. */
1635 i.flag_operands++;
1636 return 1;
1639 else if (!strcmp (op_string, "NC"))
1641 if (is_space_char (*op_string))
1642 ++op_string;
1644 i.types[this_operand] = FLAG; /* Set the type. */
1645 i.maxq20_op[this_operand].flag = FLAG_NC; /* Set the Register value. */
1646 i.flag_operands++;
1647 return 1;
1650 else if (!strcmp (op_string, "E"))
1652 if (is_space_char (*op_string))
1653 ++op_string;
1655 i.types[this_operand] = FLAG; /* Set the type. */
1656 i.maxq20_op[this_operand].flag = FLAG_E; /* Set the Register value. */
1658 i.flag_operands++;
1660 return 1;
1663 else if (!strcmp (op_string, "S"))
1665 if (is_space_char (*op_string))
1666 ++op_string;
1668 i.types[this_operand] = FLAG; /* Set the type. */
1669 i.maxq20_op[this_operand].flag = FLAG_S; /* Set the Register value. */
1671 i.flag_operands++;
1673 return 1;
1676 else if (!strcmp (op_string, "C"))
1678 if (is_space_char (*op_string))
1679 ++op_string;
1681 i.types[this_operand] = FLAG; /* Set the type. */
1682 i.maxq20_op[this_operand].flag = FLAG_C; /* Set the Register value. */
1684 i.flag_operands++;
1686 return 1;
1689 else if (!strcmp (op_string, "NE"))
1692 if (is_space_char (*op_string))
1693 ++op_string;
1695 i.types[this_operand] = FLAG; /* Set the type. */
1697 i.maxq20_op[this_operand].flag = FLAG_NE; /* Set the Register value. */
1699 i.flag_operands++;
1701 return 1;
1704 /* CHECK FOR REGISTER BIT */
1705 else if ((rb = parse_register_bit (op_string, &end_op)) != NULL)
1707 op_string = end_op;
1709 if (is_space_char (*op_string))
1710 ++op_string;
1712 i.types[this_operand] = BIT;
1714 i.maxq20_op[this_operand].r_bit = rb;
1716 i.bit_operands++;
1718 return 1;
1721 else if (*op_string == IMMEDIATE_PREFIX) /* FOR IMMEDITE. */
1723 if (is_space_char (*op_string))
1724 ++op_string;
1726 i.types[this_operand] = IMM;
1728 if (!maxq20_immediate (op_string))
1730 as_bad (_("illegal immediate operand '%s'"), op_string);
1731 return 0;
1733 return 1;
1736 else if (*op_string == ABSOLUTE_PREFIX || !strcmp (op_string, "NUL"))
1738 if (is_space_char (*op_string))
1739 ++op_string;
1741 /* For new requiremnt of copiler of for, @(BP,cons). */
1742 if (check_for_parse (op_string))
1744 memset (op_string, '\0', strlen (op_string) + 1);
1745 memcpy (op_string, "@BP[OFFS]\0", 11);
1748 i.types[this_operand] = MEM;
1750 if ((m = maxq20_mem_access (op_string, &end_op)) == NULL)
1752 as_bad (_("Invalid operand for memory access '%s'"), op_string);
1753 return 0;
1755 i.maxq20_op[this_operand].mem = m;
1757 i.mem_operands++;
1759 return 1;
1762 else if ((r = parse_register (op_string, &end_op)) != NULL) /* Check for register. */
1764 op_string = end_op;
1766 if (is_space_char (*op_string))
1767 ++op_string;
1769 i.types[this_operand] = REG; /* Set the type. */
1770 i.maxq20_op[this_operand].reg = r; /* Set the Register value. */
1771 i.reg_operands++;
1772 return 1;
1775 if (this_operand == 1)
1777 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1778 /* The operand can either be a data reference or a symbol reference. */
1779 if ((sym = maxq20_data (org_case_op_string)) != NULL) /* Check for data memory. */
1781 while (is_space_char (*op_string))
1782 ++op_string;
1784 /* Set the type of the operand. */
1785 i.types[this_operand] = DATA;
1787 /* Set the value of the data. */
1788 i.maxq20_op[this_operand].data = sym;
1789 i.data_operands++;
1791 return 1;
1794 else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1796 /* This is a memory reference of some sort. char *base_string;
1797 Start and end of displacement string expression (if found). char
1798 *displacement_string_start; char *displacement_string_end. */
1799 base_string = org_case_op_string + strlen (org_case_op_string);
1801 --base_string;
1802 if (is_space_char (*base_string))
1803 --base_string;
1805 /* If we only have a displacement, set-up for it to be parsed
1806 later. */
1807 displacement_string_start = org_case_op_string;
1808 displacement_string_end = base_string + 1;
1809 if (displacement_string_start != displacement_string_end)
1811 if (!maxq20_displacement (displacement_string_start,
1812 displacement_string_end))
1814 as_bad (_("illegal displacement operand "));
1815 return 0;
1817 /* A displacement operand found. */
1818 i.types[this_operand] = DISP; /* Set the type. */
1819 return 1;
1824 /* Check for displacement. */
1825 else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1827 /* This is a memory reference of some sort. char *base_string;
1828 Start and end of displacement string expression (if found). char
1829 *displacement_string_start; char *displacement_string_end; */
1830 base_string = org_case_op_string + strlen (org_case_op_string);
1832 --base_string;
1833 if (is_space_char (*base_string))
1834 --base_string;
1836 /* If we only have a displacement, set-up for it to be parsed later. */
1837 displacement_string_start = org_case_op_string;
1838 displacement_string_end = base_string + 1;
1839 if (displacement_string_start != displacement_string_end)
1841 if (!maxq20_displacement (displacement_string_start,
1842 displacement_string_end))
1843 return 0;
1844 /* A displacement operand found. */
1845 i.types[this_operand] = DISP; /* Set the type. */
1848 return 1;
1851 /* Parse_operand takes as input instruction and operands and Parse operands
1852 and makes entry in the template. */
1854 static char *
1855 parse_operands (char *l, const char *mnemonic)
1857 char *token_start;
1859 /* 1 if operand is pending after ','. */
1860 short int expecting_operand = 0;
1862 /* Non-zero if operand parens not balanced. */
1863 short int paren_not_balanced;
1865 int operand_ok;
1867 /* For Overcoming Warning of unused variable. */
1868 if (mnemonic)
1869 operand_ok = 0;
1871 while (*l != END_OF_INSN)
1873 /* Skip optional white space before operand. */
1874 if (is_space_char (*l))
1875 ++l;
1877 if (!is_operand_char (*l) && *l != END_OF_INSN)
1879 as_bad (_("invalid character %c before operand %d"),
1880 (char) (*l), i.operands + 1);
1881 return NULL;
1883 token_start = l;
1885 paren_not_balanced = 0;
1886 while (paren_not_balanced || *l != ',')
1888 if (*l == END_OF_INSN)
1890 if (paren_not_balanced)
1892 as_bad (_("unbalanced brackets in operand %d."),
1893 i.operands + 1);
1894 return NULL;
1897 break;
1899 else if (!is_operand_char (*l) && !is_space_char (*l))
1901 as_bad (_("invalid character %c in operand %d"),
1902 (char) (*l), i.operands + 1);
1903 return NULL;
1905 if (*l == '[')
1906 ++paren_not_balanced;
1907 if (*l == ']')
1908 --paren_not_balanced;
1909 l++;
1912 if (l != token_start)
1914 /* Yes, we've read in another operand. */
1915 this_operand = i.operands++;
1916 if (i.operands > MAX_OPERANDS)
1918 as_bad (_("spurious operands; (%d operands/instruction max)"),
1919 MAX_OPERANDS);
1920 return NULL;
1923 /* Now parse operand adding info to 'i' as we go along. */
1924 END_STRING_AND_SAVE (l);
1926 operand_ok = maxq20_operand (token_start);
1928 RESTORE_END_STRING (l);
1930 if (!operand_ok)
1931 return NULL;
1933 else
1935 if (expecting_operand)
1937 expecting_operand_after_comma:
1938 as_bad (_("expecting operand after ','; got nothing"));
1939 return NULL;
1943 if (*l == ',')
1945 if (*(++l) == END_OF_INSN)
1946 /* Just skip it, if it's \n complain. */
1947 goto expecting_operand_after_comma;
1949 expecting_operand = 1;
1953 return l;
1956 static int
1957 match_operands (int type, MAX_ARG_TYPE flag_type, MAX_ARG_TYPE arg_type,
1958 int op_num)
1960 switch (type)
1962 case REG:
1963 if ((arg_type & A_REG) == A_REG)
1964 return 1;
1965 break;
1966 case IMM:
1967 if ((arg_type & A_IMM) == A_IMM)
1968 return 1;
1969 break;
1970 case IMMBIT:
1971 if ((arg_type & A_BIT_0) == A_BIT_0 && (i.maxq20_op[op_num].imms == 0))
1972 return 1;
1973 else if ((arg_type & A_BIT_1) == A_BIT_1
1974 && (i.maxq20_op[op_num].imms == 1))
1975 return 1;
1976 break;
1977 case MEM:
1978 if ((arg_type & A_MEM) == A_MEM)
1979 return 1;
1980 break;
1982 case FLAG:
1983 if ((arg_type & flag_type) == flag_type)
1984 return 1;
1986 break;
1988 case BIT:
1989 if ((arg_type & ACC_BIT) == ACC_BIT && !strcmp (i.maxq20_op[op_num].r_bit->reg->reg_name, "ACC"))
1990 return 1;
1991 else if ((arg_type & SRC_BIT) == SRC_BIT && (op_num == 1))
1992 return 1;
1993 else if ((op_num == 0) && (arg_type & DST_BIT) == DST_BIT)
1994 return 1;
1995 break;
1996 case DISP:
1997 if ((arg_type & A_DISP) == A_DISP)
1998 return 1;
1999 case DATA:
2000 if ((arg_type & A_DATA) == A_DATA)
2001 return 1;
2002 case BIT_BUCKET:
2003 if ((arg_type & A_BIT_BUCKET) == A_BIT_BUCKET)
2004 return 1;
2006 return 0;
2009 static int
2010 match_template (void)
2012 /* Points to template once we've found it. */
2013 const MAXQ20_OPCODE_INFO *t;
2014 char inv_oper;
2015 inv_oper = 0;
2017 for (t = current_templates->start; t < current_templates->end; t++)
2019 /* Must have right number of operands. */
2020 if (i.operands != t->op_number)
2021 continue;
2022 else if (!t->op_number)
2023 break;
2025 switch (i.operands)
2027 case 2:
2028 if (!match_operands (i.types[1], i.maxq20_op[1].flag, t->arg[1], 1))
2030 inv_oper = 1;
2031 continue;
2033 case 1:
2034 if (!match_operands (i.types[0], i.maxq20_op[0].flag, t->arg[0], 0))
2036 inv_oper = 2;
2037 continue;
2040 break;
2043 if (t == current_templates->end)
2045 /* We found no match. */
2046 as_bad (_("operand %d is invalid for `%s'"),
2047 inv_oper, current_templates->start->name);
2048 return 0;
2051 /* Copy the template we have found. */
2052 i.op = *t;
2053 return 1;
2056 /* This function filters out the various combinations of operands which are
2057 not allowed for a particular instruction. */
2059 static int
2060 match_filters (void)
2062 /* Now we have at our disposal the instruction i. We will be using the
2063 following fields i.op.name : This is the mnemonic name. i.types[2] :
2064 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2065 i.maxq20_op[2] : This contains the specific info of the operands. */
2067 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2068 SOURCE. */
2069 if (!strcmp (i.op.name, "AND") || !strcmp (i.op.name, "OR")
2070 || !strcmp (i.op.name, "XOR") || !strcmp (i.op.name, "ADD")
2071 || !strcmp (i.op.name, "ADDC") || !strcmp (i.op.name, "SUB")
2072 || !strcmp (i.op.name, "SUBB"))
2074 if (i.types[0] == REG)
2076 if (i.maxq20_op[0].reg->Mod_name == 0xa)
2078 as_bad (_
2079 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2080 return 0;
2085 if (!strcmp (i.op.name, "MOVE") && (i.types[0] == MEM || i.types[1] == MEM)
2086 && i.operands == 2)
2088 mem_access_syntax *mem_op = NULL;
2090 if (i.types[0] == MEM)
2092 mem_op =
2093 (mem_access_syntax *) hash_find (mem_syntax_hash,
2094 i.maxq20_op[0].mem->name);
2095 if ((mem_op->type == SRC) && mem_op)
2097 as_bad (_("'%s' operand cant be used as destination in %s"),
2098 mem_op->name, i.op.name);
2099 return 0;
2101 else if ((mem_op->invalid_op != NULL) && (i.types[1] == MEM)
2102 && mem_op)
2104 int k = 0;
2106 for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2108 if (mem_op->invalid_op[k] != NULL)
2109 if (!strcmp
2110 (mem_op->invalid_op[k], i.maxq20_op[1].mem->name))
2112 as_bad (_
2113 ("Invalid Instruction '%s' operand cant be used with %s"),
2114 mem_op->name, i.maxq20_op[1].mem->name);
2115 return 0;
2121 if (i.types[1] == MEM)
2123 mem_op = NULL;
2124 mem_op =
2125 (mem_access_syntax *) hash_find (mem_syntax_hash,
2126 i.maxq20_op[1].mem->name);
2127 if (mem_op->type == DST && mem_op)
2129 as_bad (_("'%s' operand cant be used as source in %s"),
2130 mem_op->name, i.op.name);
2131 return 0;
2133 else if (mem_op->invalid_op != NULL && i.types[0] == MEM && mem_op)
2135 int k = 0;
2137 for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2139 if (mem_op->invalid_op[k] != NULL)
2140 if (!strcmp
2141 (mem_op->invalid_op[k], i.maxq20_op[0].mem->name))
2143 as_bad (_
2144 ("Invalid Instruction '%s' operand cant be used with %s"),
2145 mem_op->name, i.maxq20_op[0].mem->name);
2146 return 0;
2150 else if (i.types[0] == REG
2151 && !strcmp (i.maxq20_op[0].reg->reg_name, "OFFS")
2152 && mem_op)
2154 if (!strcmp (mem_op->name, "@BP[OFFS--]")
2155 || !strcmp (mem_op->name, "@BP[OFFS++]"))
2157 as_bad (_
2158 ("Invalid Instruction '%s' operand cant be used with %s"),
2159 mem_op->name, i.maxq20_op[0].mem->name);
2160 return 0;
2166 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2167 on 10-March-2004. */
2168 if ((i.types[0] == MEM) && (i.operands == 1)
2169 && !(!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI")))
2171 mem_access_syntax *mem_op = NULL;
2173 if (i.types[0] == MEM)
2175 mem_op =
2176 (mem_access_syntax *) hash_find (mem_syntax_hash,
2177 i.maxq20_op[0].mem->name);
2178 if (mem_op->type == DST && mem_op)
2180 as_bad (_("'%s' operand cant be used as source in %s"),
2181 mem_op->name, i.op.name);
2182 return 0;
2187 if (i.operands == 2 && i.types[0] == IMM)
2189 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2190 i.op.name);
2191 return 0;
2194 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2195 if (!strcmp (i.op.name, "PUSH") || !strcmp (i.op.name, "POP")
2196 || !strcmp (i.op.name, "POPI"))
2198 if (i.types[0] == REG)
2200 if (!strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
2202 as_bad (_("SP cannot be used with %s\n"), i.op.name);
2203 return 0;
2206 else if (i.types[0] == MEM
2207 && !strcmp (i.maxq20_op[0].mem->name, "@SP--"))
2209 as_bad (_("@SP-- cannot be used with PUSH\n"));
2210 return 0;
2214 /* This filter checks that two memory references using DP's cannot be used
2215 together in an instruction */
2216 if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 2)
2218 if (strlen (i.maxq20_op[0].mem->name) != 6 ||
2219 strcmp (i.maxq20_op[0].mem->name, i.maxq20_op[1].mem->name))
2221 if (!strncmp (i.maxq20_op[0].mem->name, "@DP", 3)
2222 && !strncmp (i.maxq20_op[1].mem->name, "@DP", 3))
2224 as_bad (_
2225 ("Operands either contradictory or use the data bus in read/write state together"));
2226 return 0;
2229 if (!strncmp (i.maxq20_op[0].mem->name, "@SP", 3)
2230 && !strncmp (i.maxq20_op[1].mem->name, "@SP", 3))
2232 as_bad (_
2233 ("Operands either contradictory or use the data bus in read/write state together"));
2234 return 0;
2237 if ((i.maxq20_op[1].mem != NULL)
2238 && !strncmp (i.maxq20_op[1].mem->name, "NUL", 3))
2240 as_bad (_("MOVE Cant Use NUL as SRC"));
2241 return 0;
2245 /* This filter checks that contradictory movement between DP register and
2246 Memory access using DP followed by increment or decrement. */
2248 if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 1
2249 && i.reg_operands == 1)
2251 int memnum, regnum;
2253 memnum = (i.types[0] == MEM) ? 0 : 1;
2254 regnum = (memnum == 0) ? 1 : 0;
2255 if (!strncmp (i.maxq20_op[regnum].reg->reg_name, "DP", 2) &&
2256 !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2257 i.maxq20_op[regnum].reg->reg_name, 5)
2258 && strcmp ((i.maxq20_op[memnum].mem->name) + 1,
2259 i.maxq20_op[regnum].reg->reg_name))
2261 as_bad (_
2262 ("Contradictory movement between DP register and memory access using DP"));
2263 return 0;
2265 else if (!strcmp (i.maxq20_op[regnum].reg->reg_name, "SP") &&
2266 !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2267 i.maxq20_op[regnum].reg->reg_name, 2))
2269 as_bad (_
2270 ("SP and @SP-- cannot be used together in a move instruction"));
2271 return 0;
2275 /* This filter restricts the instructions containing source and destination
2276 bits to only CTRL module of the serial registers. Peripheral registers
2277 yet to be defined. */
2279 if (i.bit_operands == 1 && i.operands == 2)
2281 int bitnum = (i.types[0] == BIT) ? 0 : 1;
2283 if (strcmp (i.maxq20_op[bitnum].r_bit->reg->reg_name, "ACC"))
2285 if (i.maxq20_op[bitnum].r_bit->reg->Mod_name >= 0x7 &&
2286 i.maxq20_op[bitnum].r_bit->reg->Mod_name != CTRL)
2288 as_bad (_
2289 ("Only Module 8 system registers allowed in this operation"));
2290 return 0;
2295 /* This filter is for checking the register bits. */
2296 if (i.bit_operands == 1 || i.operands == 2)
2298 int bitnum = 0, size = 0;
2300 bitnum = (i.types[0] == BIT) ? 0 : 1;
2301 if (i.bit_operands == 1)
2303 switch (i.maxq20_op[bitnum].r_bit->reg->rtype)
2305 case Reg_8W:
2306 size = 7; /* 8 bit register, both read and write. */
2307 break;
2308 case Reg_16W:
2309 size = 15;
2310 break;
2311 case Reg_8R:
2312 size = 7;
2313 if (bitnum == 0)
2315 as_fatal (_("Read only Register used as destination"));
2316 return 0;
2318 break;
2320 case Reg_16R:
2321 size = 15;
2322 if (bitnum == 0)
2324 as_fatal (_("Read only Register used as destination"));
2325 return 0;
2327 break;
2330 if (size < (i.maxq20_op[bitnum].r_bit)->bit)
2332 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2333 (i.maxq20_op[bitnum].r_bit)->bit);
2334 return 0;
2338 if (i.bit_operands == 2)
2340 switch ((i.maxq20_op[0].r_bit)->reg->rtype)
2342 case Reg_8W:
2343 size = 7; /* 8 bit register, both read and write. */
2344 break;
2345 case Reg_16W:
2346 size = 15;
2347 break;
2348 case Reg_8R:
2349 case Reg_16R:
2350 as_fatal (_("Read only Register used as destination"));
2351 return 0;
2354 if (size < (i.maxq20_op[0].r_bit)->bit)
2356 as_bad (_
2357 ("Bit No '%d' exceeds register size in this operation"),
2358 (i.maxq20_op[0].r_bit)->bit);
2359 return 0;
2362 size = 0;
2363 switch ((i.maxq20_op[1].r_bit)->reg->rtype)
2365 case Reg_8R:
2366 case Reg_8W:
2367 size = 7; /* 8 bit register, both read and write. */
2368 break;
2369 case Reg_16R:
2370 case Reg_16W:
2371 size = 15;
2372 break;
2375 if (size < (i.maxq20_op[1].r_bit)->bit)
2377 as_bad (_
2378 ("Bit No '%d' exceeds register size in this operation"),
2379 (i.maxq20_op[1].r_bit)->bit);
2380 return 0;
2385 /* No branch operations should occur into the data memory. Hence any memory
2386 references have to be filtered out when used with instructions like
2387 jump, djnz[] and call. */
2389 if (!strcmp (i.op.name, "JUMP") || !strcmp (i.op.name, "CALL")
2390 || !strncmp (i.op.name, "DJNZ", 4))
2392 if (i.mem_operands)
2393 as_warn (_
2394 ("Memory References cannot be used with branching operations\n"));
2397 if (!strcmp (i.op.name, "DJNZ"))
2399 if (!
2400 (strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2401 || strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))
2403 as_bad (_("DJNZ uses only LC[n] register \n"));
2404 return 0;
2408 /* No destination register used should be read only! */
2409 if ((i.operands == 2 && i.types[0] == REG) || !strcmp (i.op.name, "POP")
2410 || !strcmp (i.op.name, "POPI"))
2411 { /* The destination is a register */
2412 int regnum = 0;
2414 if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2416 regnum = 0;
2418 if (i.types[regnum] == MEM)
2420 mem_access_syntax *mem_op = NULL;
2422 mem_op =
2423 (mem_access_syntax *) hash_find (mem_syntax_hash,
2424 i.maxq20_op[regnum].mem->
2425 name);
2426 if (mem_op->type == SRC && mem_op)
2428 as_bad (_
2429 ("'%s' operand cant be used as destination in %s"),
2430 mem_op->name, i.op.name);
2431 return 0;
2436 if (i.maxq20_op[regnum].reg->rtype == Reg_8R
2437 || i.maxq20_op[regnum].reg->rtype == Reg_16R)
2439 as_bad (_("Read only register used for writing purposes '%s'"),
2440 i.maxq20_op[regnum].reg->reg_name);
2441 return 0;
2445 /* While moving the address of a data in the data section, the destination
2446 should be either data pointers only. */
2447 if ((i.data_operands) && (i.operands == 2))
2449 if ((i.types[0] != REG) && (i.types[0] != MEM))
2451 as_bad (_("Invalid destination for this kind of source."));
2452 return 0;
2455 if (i.types[0] == REG && i.maxq20_op[0].reg->rtype == Reg_8W)
2457 as_bad (_
2458 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2459 return 0;
2462 return 1;
2465 static int
2466 decode_insn (void)
2468 /* Check for the format Bit if defined. */
2469 if (i.op.format == 0 || i.op.format == 1)
2470 i.instr[0] = i.op.format << 7;
2471 else
2473 /* Format bit not defined. We will have to be find it out ourselves. */
2474 if (i.imm_operands == 1 || i.data_operands == 1 || i.disp_operands == 1)
2475 i.op.format = 0;
2476 else
2477 i.op.format = 1;
2478 i.instr[0] = i.op.format << 7;
2481 /* Now for the destination register. */
2483 /* If destination register is already defined . The conditions are the
2484 following: (1) The second entry in the destination array should be 0 (2)
2485 If there are two operands then the first entry should not be a register,
2486 memory or a register bit (3) If there are less than two operands and the
2487 it is not a pop operation (4) The second argument is the carry
2488 flag(applicable to move Acc.<b>,C. */
2489 if (i.op.dst[1] == 0
2491 ((i.types[0] != REG && i.types[0] != MEM && i.types[0] != BIT
2492 && i.operands == 2) || (i.operands < 2 && strcmp (i.op.name, "POP")
2493 && strcmp (i.op.name, "POPI"))
2494 || (i.op.arg[1] == FLAG_C)))
2496 i.op.dst[0] &= 0x7f;
2497 i.instr[0] |= i.op.dst[0];
2499 else if (i.op.dst[1] == 0 && !strcmp (i.op.name, "DJNZ")
2501 (((i.types[0] == REG)
2502 && (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2503 || !strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))))
2505 i.op.dst[0] &= 0x7f;
2506 if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]"))
2507 i.instr[0] |= 0x4D;
2509 if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]"))
2510 i.instr[0] |= 0x5D;
2512 else
2514 unsigned char temp;
2516 /* Target register will have to be specified. */
2517 if (i.types[0] == REG
2518 && (i.op.dst[0] == REG || i.op.dst[0] == (REG | MEM)))
2520 temp = (i.maxq20_op[0].reg)->opcode;
2521 temp &= 0x7f;
2522 i.instr[0] |= temp;
2524 else if (i.types[0] == MEM && (i.op.dst[0] == (REG | MEM)))
2526 temp = (i.maxq20_op[0].mem)->opcode;
2527 temp &= 0x7f;
2528 i.instr[0] |= temp;
2530 else if (i.types[0] == BIT && (i.op.dst[0] == REG))
2532 temp = (i.maxq20_op[0].r_bit)->reg->opcode;
2533 temp &= 0x7f;
2534 i.instr[0] |= temp;
2536 else if (i.types[1] == BIT && (i.op.dst[0] == BIT))
2538 temp = (i.maxq20_op[1].r_bit)->bit;
2539 temp = temp << 4;
2540 temp |= i.op.dst[1];
2541 temp &= 0x7f;
2542 i.instr[0] |= temp;
2544 else
2546 as_bad (_("Invalid Instruction"));
2547 return 0;
2551 /* Now for the source register. */
2553 /* If Source register is already known. The following conditions are
2554 checked: (1) There are no operands (2) If there is only one operand and
2555 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2556 operation. */
2558 if (i.operands == 0 || (i.operands == 1 && i.types[0] == FLAG)
2559 || (i.types[0] == FLAG && i.types[1] == IMMBIT)
2560 || !strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2561 i.instr[1] = i.op.src[0];
2563 else if (i.imm_operands == 1 && ((i.op.src[0] & IMM) == IMM))
2564 i.instr[1] = i.maxq20_op[this_operand].imms;
2566 else if (i.types[this_operand] == REG && ((i.op.src[0] & REG) == REG))
2567 i.instr[1] = (char) ((i.maxq20_op[this_operand].reg)->opcode);
2569 else if (i.types[this_operand] == BIT && ((i.op.src[0] & REG) == REG))
2570 i.instr[1] = (char) (i.maxq20_op[this_operand].r_bit->reg->opcode);
2572 else if (i.types[this_operand] == MEM && ((i.op.src[0] & MEM) == MEM))
2573 i.instr[1] = (char) ((i.maxq20_op[this_operand].mem)->opcode);
2575 else if (i.types[this_operand] == DATA && ((i.op.src[0] & DATA) == DATA))
2576 /* This will copy only the lower order bytes into the instruction. The
2577 higher order bytes have already been copied into the prefix register. */
2578 i.instr[1] = 0;
2580 /* Decoding the source in the case when the second array entry is not 0.
2581 This means that the source register has been divided into two nibbles. */
2583 else if (i.op.src[1] != 0)
2585 /* If the first operand is a accumulator bit then
2586 the first 4 bits will be filled with the bit number. */
2587 if (i.types[0] == BIT && ((i.op.src[0] & BIT) == BIT))
2589 unsigned char temp = (i.maxq20_op[0].r_bit)->bit;
2591 temp = temp << 4;
2592 temp |= i.op.src[1];
2593 i.instr[1] = temp;
2595 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2596 has to start with a zero. This is called a ZEROBIT */
2597 else if (i.types[0] == BIT && ((i.op.src[0] & ZEROBIT) == ZEROBIT))
2599 char temp = (i.maxq20_op[0].r_bit)->bit;
2601 temp = temp << 4;
2602 temp |= i.op.src[1];
2603 temp &= 0x7f;
2604 i.instr[1] = temp;
2606 /* Similarly for a ONEBIT */
2607 else if (i.types[0] == BIT && ((i.op.src[0] & ONEBIT) == ONEBIT))
2609 char temp = (i.maxq20_op[0].r_bit)->bit;
2611 temp = temp << 4;
2612 temp |= i.op.src[1];
2613 temp |= 0x80;
2614 i.instr[1] = temp;
2616 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2617 C,src.<b> */
2618 else if (i.types[1] == BIT)
2620 if (i.op.src[1] == 0 && i.op.src[1] == REG)
2621 i.instr[1] = (i.maxq20_op[1].r_bit)->reg->opcode;
2623 else if (i.op.src[0] == BIT && i.op.src)
2625 char temp = (i.maxq20_op[1].r_bit)->bit;
2627 temp = temp << 4;
2628 temp |= i.op.src[1];
2629 i.instr[1] = temp;
2632 else
2634 as_bad (_("Invalid Instruction"));
2635 return 0;
2638 return 1;
2641 /* This is a function for outputting displacement operands. */
2643 static void
2644 output_disp (fragS *insn_start_frag, offsetT insn_start_off)
2646 char *p;
2647 relax_substateT subtype;
2648 symbolS *sym;
2649 offsetT off;
2650 int diff;
2652 diff = 0;
2653 insn_start_frag = frag_now;
2654 insn_start_off = frag_now_fix ();
2656 switch (i.Instr_Prefix)
2658 case LONG_PREFIX:
2659 subtype = EXPLICT_LONG_PREFIX;
2660 break;
2661 case SHORT_PREFIX:
2662 subtype = SHORT_PREFIX;
2663 break;
2664 default:
2665 subtype = NO_PREFIX;
2666 break;
2669 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2670 case there is no need for relaxation. But we do need support for a
2671 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2672 for prefix + 2 for the current instruction ) Hence if at a particular
2673 time we find out whether the prefix operator is reqd , we shift the
2674 current instruction two places ahead and insert the prefix instruction. */
2675 frag_grow (2 + 2);
2676 p = frag_more (2);
2678 sym = i.maxq20_op[this_operand].disps->X_add_symbol;
2679 off = i.maxq20_op[this_operand].disps->X_add_number;
2681 if (i.maxq20_op[this_operand].disps->X_add_symbol != NULL && sym && frag_now
2682 && (subtype != EXPLICT_LONG_PREFIX))
2684 /* If in the same frag. */
2685 if (frag_now == symbol_get_frag (sym))
2687 diff =
2688 ((((expressionS *) symbol_get_value_expression (sym))->
2689 X_add_number) - insn_start_off);
2691 /* PC points to the next instruction. */
2692 diff = (diff / MAXQ_OCTETS_PER_BYTE) - 1;
2694 if (diff >= -128 && diff <= 127)
2696 i.instr[1] = (char) diff;
2698 /* This will be overwritten later when the symbol is resolved. */
2699 *p = i.instr[1];
2700 *(p + 1) = i.instr[0];
2702 /* No Need to create a FIXUP. */
2703 return;
2708 /* This will be overwritten later when the symbol is resolved. */
2709 *p = i.instr[1];
2710 *(p + 1) = i.instr[0];
2712 if (i.maxq20_op[this_operand].disps->X_op != O_constant
2713 && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2715 /* Handle complex expressions. */
2716 sym = make_expr_symbol (i.maxq20_op[this_operand].disps);
2717 off = 0;
2720 /* Vineet : This has been added for md_estimate_size_before_relax to
2721 estimate the correct size. */
2722 if (subtype != SHORT_PREFIX)
2723 i.reloc[this_operand] = LONG_PREFIX;
2725 frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off, p);
2728 /* This is a function for outputting displacement operands. */
2730 static void
2731 output_data (fragS *insn_start_frag, offsetT insn_start_off)
2733 char *p;
2734 relax_substateT subtype;
2735 symbolS *sym;
2736 offsetT off;
2737 int diff;
2739 diff = 0;
2740 off = 0;
2741 insn_start_frag = frag_now;
2742 insn_start_off = frag_now_fix ();
2744 subtype = EXPLICT_LONG_PREFIX;
2746 frag_grow (2 + 2);
2747 p = frag_more (2);
2749 sym = i.maxq20_op[this_operand].data;
2750 off = 0;
2752 /* This will be overwritten later when the symbol is resolved. */
2753 *p = i.instr[1];
2754 *(p + 1) = i.instr[0];
2756 if (i.maxq20_op[this_operand].disps->X_op != O_constant
2757 && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2758 /* Handle complex expressions. */
2759 /* Because data is already in terms of symbol so no
2760 need to convert it from expression to symbol. */
2761 off = 0;
2763 frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off, p);
2766 static void
2767 output_insn (void)
2769 fragS *insn_start_frag;
2770 offsetT insn_start_off;
2771 char *p;
2773 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2774 do this after the insn has been output as the current frag may have been
2775 closed off. eg. by frag_var. */
2776 dwarf2_emit_insn (0);
2778 /* To ALign the text section on word. */
2780 frag_align (1, 0, 1);
2782 /* We initialise the frags for this particular instruction. */
2783 insn_start_frag = frag_now;
2784 insn_start_off = frag_now_fix ();
2786 /* If there are displacement operators(unresolved) present, then handle
2787 them separately. */
2788 if (i.disp_operands)
2790 output_disp (insn_start_frag, insn_start_off);
2791 return;
2794 if (i.data_operands)
2796 output_data (insn_start_frag, insn_start_off);
2797 return;
2800 /* Check whether the INSERT_BUFFER has to be written. */
2801 if (strcmp (INSERT_BUFFER, ""))
2803 p = frag_more (2);
2805 *p++ = INSERT_BUFFER[1];
2806 *p = INSERT_BUFFER[0];
2809 /* Check whether the prefix instruction has to be written. */
2810 if (strcmp (PFX_INSN, ""))
2812 p = frag_more (2);
2814 *p++ = PFX_INSN[1];
2815 *p = PFX_INSN[0];
2818 p = frag_more (2);
2819 /* For Little endian. */
2820 *p++ = i.instr[1];
2821 *p = i.instr[0];
2824 static void
2825 make_new_reg_table (void)
2827 unsigned long size_pm = sizeof (peripheral_reg_table);
2828 num_of_reg = ARRAY_SIZE (peripheral_reg_table);
2830 new_reg_table = xmalloc (size_pm);
2831 if (new_reg_table == NULL)
2832 as_bad (_("Cannot allocate memory"));
2834 memcpy (new_reg_table, peripheral_reg_table, size_pm);
2837 /* pmmain performs the initilizations for the pheripheral modules. */
2839 static void
2840 pmmain (void)
2842 make_new_reg_table ();
2843 return;
2846 void
2847 md_begin (void)
2849 const char *hash_err = NULL;
2850 int c = 0;
2851 char *p;
2852 const MAXQ20_OPCODE_INFO *optab;
2853 MAXQ20_OPCODES *core_optab; /* For opcodes of the same name. This will
2854 be inserted into the hash table. */
2855 struct reg *reg_tab;
2856 struct mem_access_syntax const *memsyntab;
2857 struct mem_access *memtab;
2858 struct bit_name *bittab;
2860 /* Initilize pherioipheral modules. */
2861 pmmain ();
2863 /* Initialise the opcode hash table. */
2864 op_hash = hash_new ();
2866 optab = op_table; /* Initialise it to the first entry of the
2867 maxq20 operand table. */
2869 /* Setup for loop. */
2870 core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2871 core_optab->start = optab;
2873 while (1)
2875 ++optab;
2876 if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0)
2878 /* different name --> ship out current template list; add to hash
2879 table; & begin anew. */
2881 core_optab->end = optab;
2882 #ifdef MAXQ10S
2883 if (max_version == bfd_mach_maxq10)
2885 if (((optab - 1)->arch == MAXQ10) || ((optab - 1)->arch == MAX))
2887 hash_err = hash_insert (op_hash,
2888 (optab - 1)->name,
2889 (PTR) core_optab);
2892 else if (max_version == bfd_mach_maxq20)
2894 if (((optab - 1)->arch == MAXQ20) || ((optab - 1)->arch == MAX))
2896 #endif
2897 hash_err = hash_insert (op_hash,
2898 (optab - 1)->name,
2899 (PTR) core_optab);
2900 #if MAXQ10S
2903 else
2904 as_fatal (_("Internal Error: Illegal Architecure specified"));
2905 #endif
2906 if (hash_err)
2907 as_fatal (_("Internal Error: Can't hash %s: %s"),
2908 (optab - 1)->name, hash_err);
2910 if (optab->name == NULL)
2911 break;
2912 core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2913 core_optab->start = optab;
2917 /* Initialise a new register table. */
2918 reg_hash = hash_new ();
2920 for (reg_tab = system_reg_table;
2921 reg_tab < (system_reg_table + ARRAY_SIZE (system_reg_table));
2922 reg_tab++)
2924 #if MAXQ10S
2925 switch (max_version)
2927 case bfd_mach_maxq10:
2928 if ((reg_tab->arch == MAXQ10) || (reg_tab->arch == MAX))
2929 hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2930 break;
2932 case bfd_mach_maxq20:
2933 if ((reg_tab->arch == MAXQ20) || (reg_tab->arch == MAX))
2935 #endif
2936 hash_err =
2937 hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2938 #if MAXQ10S
2940 break;
2941 default:
2942 as_fatal (_("Invalid architecture type"));
2944 #endif
2946 if (hash_err)
2947 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2948 reg_tab->reg_name, hash_err);
2951 /* Pheripheral Registers Entry. */
2952 for (reg_tab = new_reg_table;
2953 reg_tab < (new_reg_table + num_of_reg - 1); reg_tab++)
2955 hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2957 if (hash_err)
2958 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2959 reg_tab->reg_name, hash_err);
2962 /* Initialise a new memory operand table. */
2963 mem_hash = hash_new ();
2965 for (memtab = mem_table;
2966 memtab < mem_table + ARRAY_SIZE (mem_table);
2967 memtab++)
2969 hash_err = hash_insert (mem_hash, memtab->name, (PTR) memtab);
2970 if (hash_err)
2971 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2972 memtab->name, hash_err);
2975 bit_hash = hash_new ();
2977 for (bittab = bit_table;
2978 bittab < bit_table + ARRAY_SIZE (bit_table);
2979 bittab++)
2981 hash_err = hash_insert (bit_hash, bittab->name, (PTR) bittab);
2982 if (hash_err)
2983 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2984 bittab->name, hash_err);
2987 mem_syntax_hash = hash_new ();
2989 for (memsyntab = mem_access_syntax_table;
2990 memsyntab < mem_access_syntax_table + ARRAY_SIZE (mem_access_syntax_table);
2991 memsyntab++)
2993 hash_err =
2994 hash_insert (mem_syntax_hash, memsyntab->name, (PTR) memsyntab);
2995 if (hash_err)
2996 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2997 memsyntab->name, hash_err);
3000 /* Initialise the lexical tables,mnemonic chars,operand chars. */
3001 for (c = 0; c < 256; c++)
3003 if (ISDIGIT (c))
3005 digit_chars[c] = c;
3006 mnemonic_chars[c] = c;
3007 operand_chars[c] = c;
3008 register_chars[c] = c;
3010 else if (ISLOWER (c))
3012 mnemonic_chars[c] = c;
3013 operand_chars[c] = c;
3014 register_chars[c] = c;
3016 else if (ISUPPER (c))
3018 mnemonic_chars[c] = TOLOWER (c);
3019 register_chars[c] = c;
3020 operand_chars[c] = c;
3023 if (ISALPHA (c) || ISDIGIT (c))
3025 identifier_chars[c] = c;
3027 else if (c > 128)
3029 identifier_chars[c] = c;
3030 operand_chars[c] = c;
3034 /* All the special characters. */
3035 register_chars['@'] = '@';
3036 register_chars['+'] = '+';
3037 register_chars['-'] = '-';
3038 digit_chars['-'] = '-';
3039 identifier_chars['_'] = '_';
3040 identifier_chars['.'] = '.';
3041 register_chars['['] = '[';
3042 register_chars[']'] = ']';
3043 operand_chars['_'] = '_';
3044 operand_chars['#'] = '#';
3045 mnemonic_chars['['] = '[';
3046 mnemonic_chars[']'] = ']';
3048 for (p = operand_special_chars; *p != '\0'; p++)
3049 operand_chars[(unsigned char) *p] = (unsigned char) *p;
3051 /* Set the maxq arch type. */
3052 maxq_target (max_version);
3055 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3056 menmunonic in the operand table - Parse operands and populate the
3057 structure/template - Match the operand with opcode and its validity -
3058 Output Instr. */
3060 void
3061 md_assemble (char *line)
3063 int j;
3065 char mnemonic[MAX_MNEM_SIZE];
3066 char temp4prev[256];
3067 static char prev_insn[256];
3069 /* Initialize globals. */
3070 memset (&i, '\0', sizeof (i));
3071 for (j = 0; j < MAX_OPERANDS; j++)
3072 i.reloc[j] = NO_RELOC;
3074 i.prefix = -1;
3075 PFX_INSN[0] = 0;
3076 PFX_INSN[1] = 0;
3077 INSERT_BUFFER[0] = 0;
3078 INSERT_BUFFER[1] = 0;
3080 memcpy (temp4prev, line, strlen (line) + 1);
3082 save_stack_p = save_stack;
3084 line = (char *) parse_insn (line, mnemonic);
3085 if (line == NULL)
3086 return;
3088 line = (char *) parse_operands (line, mnemonic);
3089 if (line == NULL)
3090 return;
3092 /* Next, we find a template that matches the given insn, making sure the
3093 overlap of the given operands types is consistent with the template
3094 operand types. */
3095 if (!match_template ())
3096 return;
3098 /* In the MAXQ20, there are certain register combinations, and other
3099 restrictions which are not allowed. We will try to resolve these right
3100 now. */
3101 if (!match_filters ())
3102 return;
3104 /* Check for the approprate PFX register. */
3105 set_prefix ();
3106 pfx_for_imm_val (0);
3108 if (!decode_insn ()) /* decode insn. */
3109 need_pass_2 = 1;
3111 /* Check for Exlipct PFX instruction. */
3112 if (PFX_INSN[0] && (strstr (prev_insn, "PFX") || strstr (prev_insn, "pfx")))
3113 as_warn (_("Ineffective insntruction %s \n"), prev_insn);
3115 memcpy (prev_insn, temp4prev, strlen (temp4prev) + 1);
3117 /* We are ready to output the insn. */
3118 output_insn ();