2010-06-01 Rafael Espindola <espindola@google.com>
[binutils.git] / gas / config / tc-maxq.c
blobcd4dd42743458109f7df5f3f65fab6790dbe8277
1 /* tc-maxq.c -- assembler code for a MAXQ chip.
3 Copyright 2004, 2005, 2006, 2007, 2008, 2009 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 3, 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 DEFAULT_ARCH
38 #define DEFAULT_ARCH "MAXQ20"
39 #endif
41 #ifndef MAX_OPERANDS
42 #define MAX_OPERANDS 2
43 #endif
45 #ifndef MAX_MNEM_SIZE
46 #define MAX_MNEM_SIZE 8
47 #endif
49 #ifndef END_OF_INSN
50 #define END_OF_INSN '\0'
51 #endif
53 #ifndef IMMEDIATE_PREFIX
54 #define IMMEDIATE_PREFIX '#'
55 #endif
57 #ifndef MAX_REG_NAME_SIZE
58 #define MAX_REG_NAME_SIZE 4
59 #endif
61 #ifndef MAX_MEM_NAME_SIZE
62 #define MAX_MEM_NAME_SIZE 9
63 #endif
65 /* opcode for PFX[0]. */
66 #define PFX0 0x0b
68 /* Set default to MAXQ20. */
69 unsigned int max_version = bfd_mach_maxq20;
71 const char *default_arch = DEFAULT_ARCH;
73 /* Type of the operand: Register,Immediate,Memory access,flag or bit. */
75 union _maxq20_op
77 const reg_entry * reg;
78 char imms; /* This is to store the immediate value operand. */
79 expressionS * disps;
80 symbolS * data;
81 const mem_access * mem;
82 int flag;
83 const reg_bit * r_bit;
86 typedef union _maxq20_op maxq20_opcode;
88 /* For handling optional L/S in Maxq20. */
90 /* Exposed For Linker - maps indirectly to the liker relocations. */
91 #define LONG_PREFIX MAXQ_LONGJUMP /* BFD_RELOC_16 */
92 #define SHORT_PREFIX MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
93 #define ABSOLUTE_ADDR_FOR_DATA MAXQ_INTERSEGMENT
95 #define NO_PREFIX 0
96 #define EXPLICT_LONG_PREFIX 14
98 /* The main instruction structure containing fields to describe instrn */
99 typedef struct _maxq20_insn
101 /* The opcode information for the MAXQ20 */
102 MAXQ20_OPCODE_INFO op;
104 /* The number of operands */
105 unsigned int operands;
107 /* Number of different types of operands - Comments can be removed if reqd.
109 unsigned int reg_operands, mem_operands, disp_operands, data_operands;
110 unsigned int imm_operands, imm_bit_operands, bit_operands, flag_operands;
112 /* Types of the individual operands */
113 UNKNOWN_OP types[MAX_OPERANDS];
115 /* Relocation type for operand : to be investigated into */
116 int reloc[MAX_OPERANDS];
118 /* Complete information of the Operands */
119 maxq20_opcode maxq20_op[MAX_OPERANDS];
121 /* Choice of prefix register whenever needed */
122 int prefix;
124 /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
125 unsigned char Instr_Prefix;
127 /* 16 bit Instruction word */
128 unsigned char instr[2];
130 maxq20_insn;
132 /* Definitions of all possible characters that can start an operand. */
133 const char *extra_symbol_chars = "@(#";
135 /* Special Character that would start a comment. */
136 const char comment_chars[] = ";";
138 /* Starts a comment when it appears at the start of a line. */
139 const char line_comment_chars[] = ";#";
141 const char line_separator_chars[] = ""; /* originally may b by sudeep "\n". */
143 /* The following are used for option processing. */
145 /* This is added to the mach independent string passed to getopt. */
146 const char *md_shortopts = "q";
148 /* Characters for exponent and floating point. */
149 const char EXP_CHARS[] = "eE";
150 const char FLT_CHARS[] = "";
152 /* This is for the machine dependent option handling. */
153 #define OPTION_EB (OPTION_MD_BASE + 0)
154 #define OPTION_EL (OPTION_MD_BASE + 1)
155 #define MAXQ_10 (OPTION_MD_BASE + 2)
156 #define MAXQ_20 (OPTION_MD_BASE + 3)
158 struct option md_longopts[] =
160 {"MAXQ10", no_argument, NULL, MAXQ_10},
161 {"MAXQ20", no_argument, NULL, MAXQ_20},
162 {NULL, no_argument, NULL, 0}
164 size_t md_longopts_size = sizeof (md_longopts);
166 /* md_undefined_symbol We have no need for this function. */
168 symbolS *
169 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
171 return NULL;
174 static void
175 maxq_target (int target)
177 max_version = target;
178 bfd_set_arch_mach (stdoutput, bfd_arch_maxq, max_version);
182 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
184 /* Any options support will be added onto this switch case. */
185 switch (c)
187 case MAXQ_10:
188 max_version = bfd_mach_maxq10;
189 break;
190 case MAXQ_20:
191 max_version = bfd_mach_maxq20;
192 break;
194 default:
195 return 0;
198 return 1;
201 /* When a usage message is printed, this function is called and
202 it prints a description of the machine specific options. */
204 void
205 md_show_usage (FILE * stream)
207 /* Over here we will fill the description of the machine specific options. */
209 fprintf (stream, _(" MAXQ-specific assembler options:\n"));
211 fprintf (stream, _("\
212 -MAXQ20 generate obj for MAXQ20(default)\n\
213 -MAXQ10 generate obj for MAXQ10\n\
214 "));
217 unsigned long
218 maxq20_mach (void)
220 if (!(strcmp (default_arch, "MAXQ20")))
221 return 0;
223 as_fatal (_("Unknown architecture"));
224 return 1;
227 arelent *
228 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
230 arelent *rel;
231 bfd_reloc_code_real_type code;
233 switch (fixp->fx_r_type)
235 case MAXQ_INTERSEGMENT:
236 case MAXQ_LONGJUMP:
237 case BFD_RELOC_16_PCREL_S2:
238 code = fixp->fx_r_type;
239 break;
241 case 0:
242 default:
243 switch (fixp->fx_size)
245 default:
246 as_bad_where (fixp->fx_file, fixp->fx_line,
247 _("can not do %d byte relocation"), fixp->fx_size);
248 code = BFD_RELOC_32;
249 break;
251 case 1:
252 code = BFD_RELOC_8;
253 break;
254 case 2:
255 code = BFD_RELOC_16;
256 break;
257 case 4:
258 code = BFD_RELOC_32;
259 break;
263 rel = xmalloc (sizeof (arelent));
264 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
265 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
267 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
268 rel->addend = fixp->fx_addnumber;
269 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
271 if (rel->howto == NULL)
273 as_bad_where (fixp->fx_file, fixp->fx_line,
274 _("cannot represent relocation type %s"),
275 bfd_get_reloc_code_name (code));
277 /* Set howto to a garbage value so that we can keep going. */
278 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
279 gas_assert (rel->howto != NULL);
282 return rel;
285 /* md_estimate_size_before_relax()
287 Called just before relax() for rs_machine_dependent frags. The MAXQ
288 assembler uses these frags to handle 16 bit absolute jumps which require a
289 prefix instruction to be inserted. Any symbol that is now undefined will
290 not become defined. Return the correct fr_subtype in the frag. Return the
291 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
292 caller. The guess is actually the growth beyond the fixed part. Whatever
293 we do to grow the fixed or variable part contributes to our returned
294 value. */
297 md_estimate_size_before_relax (fragS *fragP, segT segment)
299 /* Check whether the symbol has been resolved or not.
300 Otherwise we will have to generate a fixup. */
301 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment)
302 || fragP->fr_subtype == EXPLICT_LONG_PREFIX)
304 RELOC_ENUM reloc_type;
305 unsigned char *opcode;
306 int old_fr_fix;
308 /* Now this symbol has not been defined in this file.
309 Hence we will have to create a fixup. */
310 int size = 2;
312 /* This is for the prefix instruction. */
314 if (fragP->fr_subtype == EXPLICT_LONG_PREFIX)
315 fragP->fr_subtype = LONG_PREFIX;
317 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
318 && ((!(fragP->fr_subtype) == EXPLICT_LONG_PREFIX)))
319 fragP->fr_subtype = ABSOLUTE_ADDR_FOR_DATA;
321 reloc_type =
322 (fragP->fr_subtype ? fragP->fr_subtype : ABSOLUTE_ADDR_FOR_DATA);
324 fragP->fr_subtype = reloc_type;
326 if (reloc_type == SHORT_PREFIX)
327 size = 0;
328 old_fr_fix = fragP->fr_fix;
329 opcode = (unsigned char *) fragP->fr_opcode;
331 fragP->fr_fix += (size);
333 fix_new (fragP, old_fr_fix - 2, size + 2,
334 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
335 frag_wane (fragP);
336 return fragP->fr_fix - old_fr_fix;
339 if (fragP->fr_subtype == SHORT_PREFIX)
341 fragP->fr_subtype = SHORT_PREFIX;
342 return 0;
345 if (fragP->fr_subtype == NO_PREFIX || fragP->fr_subtype == LONG_PREFIX)
347 unsigned long instr;
348 unsigned long call_addr;
349 long diff;
350 fragS *f;
351 diff = diff ^ diff;;
352 call_addr = call_addr ^ call_addr;
353 instr = 0;
354 f = NULL;
356 /* segment_info_type *seginfo = seg_info (segment); */
357 instr = fragP->fr_address + fragP->fr_fix - 2;
359 /* This is the offset if it is a PC relative jump. */
360 call_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
362 /* PC stores the value of the next instruction. */
363 diff = (call_addr - instr) - 1;
365 if (diff >= (-128 * 2) && diff <= (2 * 127))
367 /* Now as offset is an 8 bit value, we will pass
368 that to the jump instruction directly. */
369 fragP->fr_subtype = NO_PREFIX;
370 return 0;
373 fragP->fr_subtype = LONG_PREFIX;
374 return 2;
377 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
378 frag_now->fr_line);
379 return 0;
382 char *
383 md_atof (int type, char * litP, int * sizeP)
385 if (type == 'd')
386 /* The size of Double has been changed to 2 words ie 32 bits. */
387 type = 'f';
388 return ieee_md_atof (type, litP, sizeP, FALSE);
391 void
392 maxq20_cons_fix_new (fragS * frag, unsigned int off, unsigned int len,
393 expressionS * exp)
395 int r = 0;
397 switch (len)
399 case 2:
400 r = MAXQ_WORDDATA; /* Word+n */
401 break;
402 case 4:
403 r = MAXQ_LONGDATA; /* Long+n */
404 break;
407 fix_new_exp (frag, off, len, exp, 0, r);
408 return;
411 /* GAS will call this for every rs_machine_dependent fragment. The
412 instruction is completed using the data from the relaxation pass. It may
413 also create any necessary relocations. */
414 void
415 md_convert_frag (bfd * headers ATTRIBUTE_UNUSED,
416 segT seg ATTRIBUTE_UNUSED,
417 fragS * fragP)
419 char *opcode;
420 offsetT target_address;
421 offsetT opcode_address;
422 offsetT displacement_from_opcode_start;
423 int address;
425 opcode = fragP->fr_opcode;
426 address = 0;
427 target_address = opcode_address = displacement_from_opcode_start = 0;
429 target_address =
430 (S_GET_VALUE (fragP->fr_symbol) / MAXQ_OCTETS_PER_BYTE) +
431 (fragP->fr_offset / MAXQ_OCTETS_PER_BYTE);
433 opcode_address =
434 (fragP->fr_address / MAXQ_OCTETS_PER_BYTE) +
435 ((fragP->fr_fix - 2) / MAXQ_OCTETS_PER_BYTE);
437 /* PC points to the next Instruction. */
438 displacement_from_opcode_start = ((target_address - opcode_address) - 1);
440 if ((displacement_from_opcode_start >= -128
441 && displacement_from_opcode_start <= 127)
442 && (fragP->fr_subtype == SHORT_PREFIX
443 || fragP->fr_subtype == NO_PREFIX))
445 /* Its a displacement. */
446 *opcode = (char) displacement_from_opcode_start;
448 else
450 /* Its an absolute 16 bit jump. Now we have to
451 load the prefix operator with the upper 8 bits. */
452 if (fragP->fr_subtype == SHORT_PREFIX)
454 as_bad (_("Cant make long jump/call into short jump/call : %d"),
455 fragP->fr_line);
456 return;
459 /* Check whether the symbol has been resolved or not.
460 Otherwise we will have to generate a fixup. */
462 if (fragP->fr_subtype != SHORT_PREFIX)
464 RELOC_ENUM reloc_type;
465 int old_fr_fix;
466 int size = 2;
468 /* Now this is a basolute jump/call.
469 Hence we will have to create a fixup. */
470 if (fragP->fr_subtype == NO_PREFIX)
471 fragP->fr_subtype = LONG_PREFIX;
473 reloc_type =
474 (fragP->fr_subtype ? fragP->fr_subtype : LONG_PREFIX);
476 if (reloc_type == 1)
477 size = 0;
478 old_fr_fix = fragP->fr_fix;
480 fragP->fr_fix += (size);
482 fix_new (fragP, old_fr_fix - 2, size + 2,
483 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
484 frag_wane (fragP);
489 long
490 md_pcrel_from (fixS *fixP)
492 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
495 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
497 void
498 maxq_number_to_chars (char *buf, valueT val, int n)
500 if (target_big_endian)
501 number_to_chars_bigendian (buf, val, n);
502 else
503 number_to_chars_littleendian (buf, val, n);
506 /* GAS will call this for each fixup. It's main objective is to store the
507 correct value in the object file. 'fixup_segment' performs the generic
508 overflow check on the 'valueT *val' argument after md_apply_fix returns.
509 If the overflow check is relevant for the target machine, then
510 'md_apply_fix' should modify 'valueT *val', typically to the value stored
511 in the object file (not to be done in MAXQ). */
513 void
514 md_apply_fix (fixS *fixP, valueT *valT, segT seg ATTRIBUTE_UNUSED)
516 char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
517 char *frag_to_fix_at =
518 fixP->fx_frag->fr_literal + fixP->fx_frag->fr_fix - 2;
520 if (fixP)
522 if (fixP->fx_frag && valT)
524 /* If the relaxation substate is not defined we make it equal
525 to the kind of relocation the fixup is generated for. */
526 if (!fixP->fx_frag->fr_subtype)
527 fixP->fx_frag->fr_subtype = fixP->fx_r_type;
529 /* For any instruction in which either we have specified an
530 absolute address or it is a long jump we need to add a PFX0
531 instruction to it. In this case as the instruction has already
532 being written at 'fx_where' in the frag we copy it at the end of
533 the frag(which is where the relocation was generated) as when
534 the relocation is generated the frag is grown by 2 type, this is
535 where we copy the contents of fx_where and add a pfx0 at
536 fx_where. */
537 if ((fixP->fx_frag->fr_subtype == ABSOLUTE_ADDR_FOR_DATA)
538 || (fixP->fx_frag->fr_subtype == LONG_PREFIX))
540 *(frag_to_fix_at + 1) = *(p + 1);
541 maxq_number_to_chars (p + 1, PFX0, 1);
544 /* Remember value for tc_gen_reloc. */
545 fixP->fx_addnumber = *valT;
548 /* Some fixups generated by GAS which gets resovled before this this
549 func. is called need to be wriiten to the frag as here we are going
550 to go away with the relocations fx_done=1. */
551 if (fixP->fx_addsy == NULL)
553 maxq_number_to_chars (p, *valT, fixP->fx_size);
554 fixP->fx_addnumber = *valT;
555 fixP->fx_done = 1;
560 /* Tables for lexical analysis. */
561 static char mnemonic_chars[256];
562 static char register_chars[256];
563 static char operand_chars[256];
564 static char identifier_chars[256];
565 static char digit_chars[256];
567 /* Lexical Macros. */
568 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
569 #define is_register_char(x) (register_chars[(unsigned char)(x)])
570 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
571 #define is_space_char(x) (x==' ')
572 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
573 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
575 /* Special characters for operands. */
576 static char operand_special_chars[] = "[]@.-+";
578 /* md_assemble() will always leave the instruction passed to it unaltered.
579 To do this we store the instruction in a special stack. */
580 static char save_stack[32];
581 static char *save_stack_p;
583 #define END_STRING_AND_SAVE(s) \
584 do \
586 *save_stack_p++ = *(s); \
587 *s = '\0'; \
589 while (0)
591 #define RESTORE_END_STRING(s) \
592 do \
594 *(s) = *(--save_stack_p); \
596 while (0)
598 /* The instruction we are assembling. */
599 static maxq20_insn i;
601 /* The current template. */
602 static MAXQ20_OPCODES *current_templates;
604 /* The displacement operand if any. */
605 static expressionS disp_expressions;
607 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
608 static int this_operand;
610 /* The prefix instruction if used. */
611 static char PFX_INSN[2];
612 static char INSERT_BUFFER[2];
614 /* For interface with expression() ????? */
615 extern char *input_line_pointer;
617 /* The HASH Tables: */
619 /* Operand Hash Table. */
620 static struct hash_control *op_hash;
622 /* Register Hash Table. */
623 static struct hash_control *reg_hash;
625 /* Memory reference Hash Table. */
626 static struct hash_control *mem_hash;
628 /* Bit hash table. */
629 static struct hash_control *bit_hash;
631 /* Memory Access syntax table. */
632 static struct hash_control *mem_syntax_hash;
634 /* This is a mapping from pseudo-op names to functions. */
636 const pseudo_typeS md_pseudo_table[] =
638 {"int", cons, 2}, /* size of 'int' has been changed to 1 word
639 (i.e) 16 bits. */
640 {"maxq10", maxq_target, bfd_mach_maxq10},
641 {"maxq20", maxq_target, bfd_mach_maxq20},
642 {NULL, 0, 0},
645 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
648 /* This function sets the PFX value corresponding to the specs. Source
649 Destination Index Selection ---------------------------------- Write To|
650 SourceRegRange | Dest Addr Range
651 ------------------------------------------------------ PFX[0] | 0h-Fh |
652 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
653 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
654 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
656 static void
657 set_prefix (void)
659 short int src_index = 0, dst_index = 0;
661 if (i.operands == 0)
662 return;
663 if (i.operands == 1) /* Only SRC is Present */
665 if (i.types[0] == REG)
667 if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
669 dst_index = i.maxq20_op[0].reg[0].Mod_index;
670 src_index = 0x00;
672 else
674 src_index = i.maxq20_op[0].reg[0].Mod_index;
675 dst_index = 0x00;
680 if (i.operands == 2)
682 if (i.types[0] == REG && i.types[1] == REG)
684 dst_index = i.maxq20_op[0].reg[0].Mod_index;
685 src_index = i.maxq20_op[1].reg[0].Mod_index;
687 else if (i.types[0] != REG && i.types[1] == REG) /* DST is Absent */
689 src_index = i.maxq20_op[1].reg[0].Mod_index;
690 dst_index = 0x00;
692 else if (i.types[0] == REG && i.types[1] != REG) /* Id SRC is Absent */
694 dst_index = i.maxq20_op[0].reg[0].Mod_index;
695 src_index = 0x00;
697 else if (i.types[0] == BIT && i.maxq20_op[0].r_bit)
699 dst_index = i.maxq20_op[0].r_bit->reg->Mod_index;
700 src_index = 0x00;
703 else if (i.types[1] == BIT && i.maxq20_op[1].r_bit)
705 dst_index = 0x00;
706 src_index = i.maxq20_op[1].r_bit->reg->Mod_index;
710 if (src_index >= 0x00 && src_index <= 0xF)
712 if (dst_index >= 0x00 && dst_index <= 0x07)
713 /* Set PFX[0] */
714 i.prefix = 0;
716 else if (dst_index >= 0x08 && dst_index <= 0x0F)
717 /* Set PFX[2] */
718 i.prefix = 2;
720 else if (dst_index >= 0x10 && dst_index <= 0x17)
721 /* Set PFX[4] */
722 i.prefix = 4;
724 else if (dst_index >= 0x18 && dst_index <= 0x1F)
725 /* Set PFX[6] */
726 i.prefix = 6;
728 else if (src_index >= 0x10 && src_index <= 0x1F)
730 if (dst_index >= 0x00 && dst_index <= 0x07)
731 /* Set PFX[1] */
732 i.prefix = 1;
734 else if (dst_index >= 0x08 && dst_index <= 0x0F)
735 /* Set PFX[3] */
736 i.prefix = 3;
738 else if (dst_index >= 0x10 && dst_index <= 0x17)
739 /* Set PFX[5] */
740 i.prefix = 5;
742 else if (dst_index >= 0x18 && dst_index <= 0x1F)
743 /* Set PFX[7] */
744 i.prefix = 7;
748 static unsigned char
749 is_a_LSinstr (const char *ln_pointer)
751 int i = 0;
753 for (i = 0; LSInstr[i] != NULL; i++)
754 if (!strcmp (LSInstr[i], ln_pointer))
755 return 1;
757 return 0;
760 static void
761 LS_processing (const char *line)
763 if (is_a_LSinstr (line))
765 if ((line[0] == 'L') || (line[0] == 'l'))
767 i.prefix = 0;
768 INSERT_BUFFER[0] = PFX0;
769 i.Instr_Prefix = LONG_PREFIX;
771 else if ((line[0] == 'S') || (line[0] == 's'))
772 i.Instr_Prefix = SHORT_PREFIX;
773 else
774 i.Instr_Prefix = NO_PREFIX;
776 else
777 i.Instr_Prefix = LONG_PREFIX;
780 /* Separate mnemonics and the operands. */
782 static char *
783 parse_insn (char *line, char *mnemonic)
785 char *l = line;
786 char *token_start = l;
787 char *mnem_p;
788 char temp[MAX_MNEM_SIZE];
789 int ii = 0;
791 memset (temp, END_OF_INSN, MAX_MNEM_SIZE);
792 mnem_p = mnemonic;
794 while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
796 ii++;
797 mnem_p++;
798 if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
800 as_bad (_("no such instruction: `%s'"), token_start);
801 return NULL;
803 l++;
806 if (!is_space_char (*l) && *l != END_OF_INSN)
808 as_bad (_("invalid character %s in mnemonic"), l);
809 return NULL;
812 while (ii)
814 temp[ii - 1] = toupper ((char) mnemonic[ii - 1]);
815 ii--;
818 LS_processing (temp);
820 if (i.Instr_Prefix != 0 && is_a_LSinstr (temp))
821 /* Skip the optional L-S. */
822 memcpy (temp, temp + 1, MAX_MNEM_SIZE);
824 /* Look up instruction (or prefix) via hash table. */
825 current_templates = (MAXQ20_OPCODES *) hash_find (op_hash, temp);
827 if (current_templates != NULL)
828 return l;
830 as_bad (_("no such instruction: `%s'"), token_start);
831 return NULL;
834 /* Function to calculate x to the power of y.
835 Just to avoid including the math libraries. */
837 static int
838 pwr (int x, int y)
840 int k, ans = 1;
842 for (k = 0; k < y; k++)
843 ans *= x;
845 return ans;
848 static reg_entry *
849 parse_reg_by_index (char *imm_start)
851 int k = 0, mid = 0, rid = 0, val = 0, j = 0;
852 char temp[4] = { 0 };
853 reg_entry *reg = NULL;
857 if (isdigit (imm_start[k]))
858 temp[k] = imm_start[k] - '0';
860 else if (isalpha (imm_start[k])
861 && (imm_start[k] = tolower (imm_start[k])) < 'g')
862 temp[k] = 10 + (int) (imm_start[k] - 'a');
864 else if (imm_start[k] == 'h')
865 break;
867 else if (imm_start[k] == END_OF_INSN)
869 imm_start[k] = 'd';
870 break;
873 else
874 return NULL; /* not a hex digit */
876 k++;
878 while (imm_start[k] != '\n');
880 switch (imm_start[k])
882 case 'h':
883 for (j = 0; j < k; j++)
884 val += temp[j] * pwr (16, k - j - 1);
885 break;
887 case 'd':
888 for (j = 0; j < k; j++)
890 if (temp[j] > 9)
891 return NULL; /* not a number */
893 val += temp[j] * pwr (10, k - j - 1);
894 break;
898 /* Get the module and register id's. */
899 mid = val & 0x0f;
900 rid = (val >> 4) & 0x0f;
902 if (mid < 6)
904 /* Search the pheripheral reg table. */
905 for (j = 0; j < num_of_reg; j++)
907 if (new_reg_table[j].opcode == val)
909 reg = (reg_entry *) & new_reg_table[j];
910 break;
915 else
917 /* Search the system register table. */
918 j = 0;
920 while (system_reg_table[j].reg_name != NULL)
922 if (system_reg_table[j].opcode == val)
924 reg = (reg_entry *) & system_reg_table[j];
925 break;
927 j++;
931 if (reg == NULL)
933 as_bad (_("Invalid register value %s"), imm_start);
934 return reg;
937 #if CHANGE_PFX
938 if (this_operand == 0 && reg != NULL)
940 if (reg->Mod_index > 7)
941 i.prefix = 2;
942 else
943 i.prefix = 0;
945 #endif
946 return (reg_entry *) reg;
949 /* REG_STRING starts *before* REGISTER_PREFIX. */
951 static reg_entry *
952 parse_register (char *reg_string, char **end_op)
954 char *s = reg_string;
955 char *p = NULL;
956 char reg_name_given[MAX_REG_NAME_SIZE + 1];
957 reg_entry *r = NULL;
959 r = NULL;
960 p = NULL;
962 /* Skip possible REGISTER_PREFIX and possible whitespace. */
963 if (is_space_char (*s))
964 ++s;
966 p = reg_name_given;
967 while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
969 if (p >= reg_name_given + MAX_REG_NAME_SIZE)
970 return (reg_entry *) NULL;
971 s++;
974 *end_op = s;
976 r = (reg_entry *) hash_find (reg_hash, reg_name_given);
978 #if CHANGE_PFX
979 if (this_operand == 0 && r != NULL)
981 if (r->Mod_index > 7)
982 i.prefix = 2;
983 else
984 i.prefix = 0;
986 #endif
987 return r;
990 static reg_bit *
991 parse_register_bit (char *reg_string, char **end_op)
993 const char *s = reg_string;
994 short k = 0;
995 char diff = 0;
996 reg_bit *rb = NULL;
997 reg_entry *r = NULL;
998 bit_name *b = NULL;
999 char temp_bitname[MAX_REG_NAME_SIZE + 2];
1000 char temp[MAX_REG_NAME_SIZE + 1];
1002 memset (&temp, '\0', (MAX_REG_NAME_SIZE + 1));
1003 memset (&temp_bitname, '\0', (MAX_REG_NAME_SIZE + 2));
1005 diff = 0;
1006 r = NULL;
1007 rb = NULL;
1008 rb = xmalloc (sizeof (reg_bit));
1009 rb->reg = xmalloc (sizeof (reg_entry));
1010 k = 0;
1012 /* For supporting bit names. */
1013 b = (bit_name *) hash_find (bit_hash, reg_string);
1015 if (b != NULL)
1017 *end_op = reg_string + strlen (reg_string);
1018 strcpy (temp_bitname, b->reg_bit);
1019 s = temp_bitname;
1022 if (strchr (s, '.'))
1024 while (*s != '.')
1026 if (*s == '\0')
1027 return NULL;
1028 temp[k] = *s++;
1030 k++;
1032 temp[k] = '\0';
1035 if ((r = parse_register (temp, end_op)) == NULL)
1036 return NULL;
1038 rb->reg = r;
1040 /* Skip the "." */
1041 s++;
1043 if (isdigit ((char) *s))
1044 rb->bit = atoi (s);
1045 else if (isalpha ((char) *s))
1047 rb->bit = (char) *s - 'a';
1048 rb->bit += 10;
1049 if (rb->bit > 15)
1051 as_bad (_("Invalid bit number : '%c'"), (char) *s);
1052 return NULL;
1056 if (b != NULL)
1057 diff = strlen (temp_bitname) - strlen (temp) - 1;
1058 else
1059 diff = strlen (reg_string) - strlen (temp) - 1;
1061 if (*(s + diff) != '\0')
1063 as_bad (_("Illegal character after operand '%s'"), reg_string);
1064 return NULL;
1067 return rb;
1070 static void
1071 pfx_for_imm_val (int arg)
1073 if (i.prefix == -1)
1074 return;
1076 if (i.prefix == 0 && arg == 0 && PFX_INSN[1] == 0 && !(i.data_operands))
1077 return;
1079 if (!(i.prefix < 0) && !(i.prefix > 7))
1080 PFX_INSN[0] = (i.prefix << 4) | PFX0;
1082 if (!PFX_INSN[1])
1083 PFX_INSN[1] = arg;
1087 static int
1088 maxq20_immediate (char *imm_start)
1090 int val = 0, val_pfx = 0;
1091 char sign_val = 0;
1092 int k = 0, j;
1093 int temp[4] = { 0 };
1095 imm_start++;
1097 if (imm_start[1] == '\0' && (imm_start[0] == '0' || imm_start[0] == '1')
1098 && (this_operand == 1 && ((i.types[0] == BIT || i.types[0] == FLAG))))
1100 val = imm_start[0] - '0';
1101 i.imm_bit_operands++;
1102 i.types[this_operand] = IMMBIT;
1103 i.maxq20_op[this_operand].imms = (char) val;
1104 #if CHANGE_PFX
1105 if (i.prefix == 2)
1106 pfx_for_imm_val (0);
1107 #endif
1108 return 1;
1111 /* Check For Sign Character. */
1112 sign_val = 0;
1116 if (imm_start[k] == '-' && k == 0)
1117 sign_val = -1;
1119 else if (imm_start[k] == '+' && k == 0)
1120 sign_val = 1;
1122 else if (isdigit (imm_start[k]))
1123 temp[k] = imm_start[k] - '0';
1125 else if (isalpha (imm_start[k])
1126 && (imm_start[k] = tolower (imm_start[k])) < 'g')
1127 temp[k] = 10 + (int) (imm_start[k] - 'a');
1129 else if (imm_start[k] == 'h')
1130 break;
1132 else if (imm_start[k] == '\0')
1134 imm_start[k] = 'd';
1135 break;
1137 else
1139 as_bad (_("Invalid Character in immediate Value : %c"),
1140 imm_start[k]);
1141 return 0;
1143 k++;
1145 while (imm_start[k] != '\n');
1147 switch (imm_start[k])
1149 case 'h':
1150 for (j = (sign_val ? 1 : 0); j < k; j++)
1151 val += temp[j] * pwr (16, k - j - 1);
1152 break;
1154 case 'd':
1155 for (j = (sign_val ? 1 : 0); j < k; j++)
1157 if (temp[j] > 9)
1159 as_bad (_("Invalid Character in immediate value : %c"),
1160 imm_start[j]);
1161 return 0;
1163 val += temp[j] * pwr (10, k - j - 1);
1167 if (!sign_val)
1168 sign_val = 1;
1170 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1171 check if we are moving a 16 bit immediate value into an 8 bit register.
1172 In that case we will generate a warning and move only the lower 8 bits */
1173 if (val > 65535)
1175 as_bad (_("Immediate value greater than 16 bits"));
1176 return 0;
1179 val = val * sign_val;
1181 /* If it is a stack pointer and the value is greater than the maximum
1182 permissible size */
1183 if (this_operand == 1)
1185 if ((val * sign_val) > MAX_STACK && i.types[0] == REG
1186 && !strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
1188 as_warn (_
1189 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1190 val = val & MAX_STACK;
1193 /* Check the range for 8 bit registers. */
1194 else if (((val * sign_val) > 0xFF) && (i.types[0] == REG)
1195 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1197 as_warn (_
1198 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1199 val = val & 0xfe;
1202 else if (((sign_val == -1) || (val > 0xFF)) && (i.types[0] == REG)
1203 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1205 val_pfx = val >> 8;
1206 val = ((val) & 0x00ff);
1207 SET_PFX_ARG (val_pfx);
1208 i.maxq20_op[this_operand].imms = (char) val;
1211 else if ((val <= 0xff) && (i.types[0] == REG)
1212 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1213 i.maxq20_op[this_operand].imms = (char) val;
1216 /* Check for 16 bit registers. */
1217 else if (((sign_val == -1) || val > 0xFE) && i.types[0] == REG
1218 && i.maxq20_op[0].reg->rtype == Reg_16W)
1220 /* Add PFX for any negative value -> 16bit register. */
1221 val_pfx = val >> 8;
1222 val = ((val) & 0x00ff);
1223 SET_PFX_ARG (val_pfx);
1224 i.maxq20_op[this_operand].imms = (char) val;
1227 else if (val < 0xFF && i.types[0] == REG
1228 && i.maxq20_op[0].reg->rtype == Reg_16W)
1230 i.maxq20_op[this_operand].imms = (char) val;
1233 /* All the immediate memory access - no PFX. */
1234 else if (i.types[0] == MEM)
1236 if ((sign_val == -1) || val > 0xFE)
1238 val_pfx = val >> 8;
1239 val = ((val) & 0x00ff);
1240 SET_PFX_ARG (val_pfx);
1241 i.maxq20_op[this_operand].imms = (char) val;
1243 else
1244 i.maxq20_op[this_operand].imms = (char) val;
1247 /* Special handling for immediate jumps like jump nz, #03h etc. */
1248 else if (val < 0xFF && i.types[0] == FLAG)
1249 i.maxq20_op[this_operand].imms = (char) val;
1251 else if ((((sign_val == -1) || val > 0xFE)) && i.types[0] == FLAG)
1253 val_pfx = val >> 8;
1254 val = ((val) & 0x00ff);
1255 SET_PFX_ARG (val_pfx);
1256 i.maxq20_op[this_operand].imms = (char) val;
1258 else
1260 as_bad (_("Invalid immediate move operation"));
1261 return 0;
1264 else
1266 /* All the instruction with operation on ACC: like ADD src, etc. */
1267 if ((sign_val == -1) || val > 0xFE)
1269 val_pfx = val >> 8;
1270 val = ((val) & 0x00ff);
1271 SET_PFX_ARG (val_pfx);
1272 i.maxq20_op[this_operand].imms = (char) val;
1274 else
1275 i.maxq20_op[this_operand].imms = (char) val;
1278 i.imm_operands++;
1279 return 1;
1282 static int
1283 extract_int_val (const char *imm_start)
1285 int k, j, val;
1286 char sign_val;
1287 int temp[4];
1289 k = 0;
1290 j = 0;
1291 val = 0;
1292 sign_val = 0;
1295 if (imm_start[k] == '-' && k == 0)
1296 sign_val = -1;
1298 else if (imm_start[k] == '+' && k == 0)
1299 sign_val = 1;
1301 else if (isdigit (imm_start[k]))
1302 temp[k] = imm_start[k] - '0';
1304 else if (isalpha (imm_start[k]) && (tolower (imm_start[k])) < 'g')
1305 temp[k] = 10 + (int) (tolower (imm_start[k]) - 'a');
1307 else if (tolower (imm_start[k]) == 'h')
1308 break;
1310 else if ((imm_start[k] == '\0') || (imm_start[k] == ']'))
1311 /* imm_start[k]='d'; */
1312 break;
1314 else
1316 as_bad (_("Invalid Character in immediate Value : %c"),
1317 imm_start[k]);
1318 return 0;
1320 k++;
1322 while (imm_start[k] != '\n');
1324 switch (imm_start[k])
1326 case 'h':
1327 for (j = (sign_val ? 1 : 0); j < k; j++)
1328 val += temp[j] * pwr (16, k - j - 1);
1329 break;
1331 default:
1332 for (j = (sign_val ? 1 : 0); j < k; j++)
1334 if (temp[j] > 9)
1336 as_bad (_("Invalid Character in immediate value : %c"),
1337 imm_start[j]);
1338 return 0;
1340 val += temp[j] * pwr (10, k - j - 1);
1344 if (!sign_val)
1345 sign_val = 1;
1347 return val * sign_val;
1350 static char
1351 check_for_parse (const char *line)
1353 int val;
1355 if (*(line + 1) == '[')
1359 line++;
1360 if ((*line == '-') || (*line == '+'))
1361 break;
1363 while (!is_space_char (*line));
1365 if ((*line == '-') || (*line == '+'))
1366 val = extract_int_val (line);
1367 else
1368 val = extract_int_val (line + 1);
1370 INSERT_BUFFER[0] = 0x3E;
1371 INSERT_BUFFER[1] = val;
1373 return 1;
1376 return 0;
1379 static mem_access *
1380 maxq20_mem_access (char *mem_string, char **end_op)
1382 char *s = mem_string;
1383 char *p;
1384 char mem_name_given[MAX_MEM_NAME_SIZE + 1];
1385 mem_access *m;
1387 m = NULL;
1389 /* Skip possible whitespace. */
1390 if (is_space_char (*s))
1391 ++s;
1393 p = mem_name_given;
1394 while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1396 if (p >= mem_name_given + MAX_MEM_NAME_SIZE)
1397 return (mem_access *) NULL;
1398 s++;
1401 *end_op = s;
1403 m = (mem_access *) hash_find (mem_hash, mem_name_given);
1405 return m;
1408 /* This function checks whether the operand is a variable in the data segment
1409 and if so, it returns its symbol entry from the symbol table. */
1411 static symbolS *
1412 maxq20_data (char *op_string)
1414 symbolS *symbolP;
1415 symbolP = symbol_find (op_string);
1417 if (symbolP != NULL
1418 && S_GET_SEGMENT (symbolP) != now_seg
1419 && S_GET_SEGMENT (symbolP) != bfd_und_section_ptr)
1421 /* In case we do not want to always include the prefix instruction and
1422 let the loader handle the job or in case of a 8 bit addressing mode,
1423 we will just check for val_pfx to be equal to zero and then load the
1424 prefix instruction. Otherwise no prefix instruction needs to be
1425 loaded. */
1426 /* The prefix register will have to be loaded automatically as we have
1427 a 16 bit addressing field. */
1428 pfx_for_imm_val (0);
1429 return symbolP;
1432 return NULL;
1435 static int
1436 maxq20_displacement (char *disp_start, char *disp_end)
1438 expressionS *exp;
1439 segT exp_seg = 0;
1440 char *save_input_line_pointer;
1441 #ifndef LEX_AT
1442 char *gotfree_input_line;
1443 #endif
1445 gotfree_input_line = NULL;
1446 exp = &disp_expressions;
1447 i.maxq20_op[this_operand].disps = exp;
1448 i.disp_operands++;
1449 save_input_line_pointer = input_line_pointer;
1450 input_line_pointer = disp_start;
1452 END_STRING_AND_SAVE (disp_end);
1454 #ifndef LEX_AT
1455 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1456 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1457 #endif
1458 exp_seg = expression (exp);
1460 SKIP_WHITESPACE ();
1461 if (*input_line_pointer)
1462 as_bad (_("junk `%s' after expression"), input_line_pointer);
1463 #if GCC_ASM_O_HACK
1464 RESTORE_END_STRING (disp_end + 1);
1465 #endif
1466 RESTORE_END_STRING (disp_end);
1467 input_line_pointer = save_input_line_pointer;
1468 #ifndef LEX_AT
1469 if (gotfree_input_line)
1470 free (gotfree_input_line);
1471 #endif
1472 if (exp->X_op == O_absent || exp->X_op == O_big)
1474 /* Missing or bad expr becomes absolute 0. */
1475 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1476 disp_start);
1477 exp->X_op = O_constant;
1478 exp->X_add_number = 0;
1479 exp->X_add_symbol = (symbolS *) 0;
1480 exp->X_op_symbol = (symbolS *) 0;
1482 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1484 if (exp->X_op != O_constant
1485 && OUTPUT_FLAVOR == bfd_target_aout_flavour
1486 && exp_seg != absolute_section
1487 && exp_seg != text_section
1488 && exp_seg != data_section
1489 && exp_seg != bss_section && exp_seg != undefined_section
1490 && !bfd_is_com_section (exp_seg))
1492 as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
1493 return 0;
1495 #endif
1496 i.maxq20_op[this_operand].disps = exp;
1497 return 1;
1500 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1501 Returns non-zero on error. */
1503 static int
1504 maxq20_operand (char *operand_string)
1506 reg_entry *r = NULL;
1507 reg_bit *rb = NULL;
1508 mem_access *m = NULL;
1509 char *end_op = NULL;
1510 symbolS *sym = NULL;
1511 char *base_string = NULL;
1512 int ii = 0;
1513 /* Start and end of displacement string expression (if found). */
1514 char *displacement_string_start = NULL;
1515 char *displacement_string_end = NULL;
1516 /* This maintains the case sentivness. */
1517 char case_str_op_string[MAX_OPERAND_SIZE + 1];
1518 char str_op_string[MAX_OPERAND_SIZE + 1];
1519 char *org_case_op_string = case_str_op_string;
1520 char *op_string = str_op_string;
1523 memset (op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1524 memset (org_case_op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1526 memcpy (op_string, operand_string, strlen (operand_string) + 1);
1527 memcpy (org_case_op_string, operand_string, strlen (operand_string) + 1);
1529 ii = strlen (operand_string) + 1;
1531 if (ii > MAX_OPERAND_SIZE)
1533 as_bad (_("Size of Operand '%s' greater than %d"), op_string,
1534 MAX_OPERAND_SIZE);
1535 return 0;
1538 while (ii)
1540 op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1541 ii--;
1544 if (is_space_char (*op_string))
1545 ++op_string;
1547 if (isxdigit (operand_string[0]))
1549 /* Now the operands can start with an Integer. */
1550 r = parse_reg_by_index (op_string);
1551 if (r != NULL)
1553 if (is_space_char (*op_string))
1554 ++op_string;
1555 i.types[this_operand] = REG; /* Set the type. */
1556 i.maxq20_op[this_operand].reg = r; /* Set the Register value. */
1557 i.reg_operands++;
1558 return 1;
1561 /* Get the original string. */
1562 memcpy (op_string, operand_string, strlen (operand_string) + 1);
1563 ii = strlen (operand_string) + 1;
1565 while (ii)
1567 op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1568 ii--;
1572 /* Check for flags. */
1573 if (!strcmp (op_string, "Z"))
1575 if (is_space_char (*op_string))
1576 ++op_string;
1578 i.types[this_operand] = FLAG; /* Set the type. */
1579 i.maxq20_op[this_operand].flag = FLAG_Z; /* Set the Register value. */
1581 i.flag_operands++;
1583 return 1;
1586 else if (!strcmp (op_string, "NZ"))
1588 if (is_space_char (*op_string))
1589 ++op_string;
1591 i.types[this_operand] = FLAG; /* Set the type. */
1592 i.maxq20_op[this_operand].flag = FLAG_NZ; /* Set the Register value. */
1593 i.flag_operands++;
1594 return 1;
1597 else if (!strcmp (op_string, "NC"))
1599 if (is_space_char (*op_string))
1600 ++op_string;
1602 i.types[this_operand] = FLAG; /* Set the type. */
1603 i.maxq20_op[this_operand].flag = FLAG_NC; /* Set the Register value. */
1604 i.flag_operands++;
1605 return 1;
1608 else if (!strcmp (op_string, "E"))
1610 if (is_space_char (*op_string))
1611 ++op_string;
1613 i.types[this_operand] = FLAG; /* Set the type. */
1614 i.maxq20_op[this_operand].flag = FLAG_E; /* Set the Register value. */
1616 i.flag_operands++;
1618 return 1;
1621 else if (!strcmp (op_string, "S"))
1623 if (is_space_char (*op_string))
1624 ++op_string;
1626 i.types[this_operand] = FLAG; /* Set the type. */
1627 i.maxq20_op[this_operand].flag = FLAG_S; /* Set the Register value. */
1629 i.flag_operands++;
1631 return 1;
1634 else if (!strcmp (op_string, "C"))
1636 if (is_space_char (*op_string))
1637 ++op_string;
1639 i.types[this_operand] = FLAG; /* Set the type. */
1640 i.maxq20_op[this_operand].flag = FLAG_C; /* Set the Register value. */
1642 i.flag_operands++;
1644 return 1;
1647 else if (!strcmp (op_string, "NE"))
1650 if (is_space_char (*op_string))
1651 ++op_string;
1653 i.types[this_operand] = FLAG; /* Set the type. */
1655 i.maxq20_op[this_operand].flag = FLAG_NE; /* Set the Register value. */
1657 i.flag_operands++;
1659 return 1;
1662 /* CHECK FOR REGISTER BIT */
1663 else if ((rb = parse_register_bit (op_string, &end_op)) != NULL)
1665 op_string = end_op;
1667 if (is_space_char (*op_string))
1668 ++op_string;
1670 i.types[this_operand] = BIT;
1672 i.maxq20_op[this_operand].r_bit = rb;
1674 i.bit_operands++;
1676 return 1;
1679 else if (*op_string == IMMEDIATE_PREFIX) /* FOR IMMEDITE. */
1681 if (is_space_char (*op_string))
1682 ++op_string;
1684 i.types[this_operand] = IMM;
1686 if (!maxq20_immediate (op_string))
1688 as_bad (_("illegal immediate operand '%s'"), op_string);
1689 return 0;
1691 return 1;
1694 else if (*op_string == ABSOLUTE_PREFIX || !strcmp (op_string, "NUL"))
1696 if (is_space_char (*op_string))
1697 ++op_string;
1699 /* For new requiremnt of copiler of for, @(BP,cons). */
1700 if (check_for_parse (op_string))
1702 memset (op_string, '\0', strlen (op_string) + 1);
1703 memcpy (op_string, "@BP[OFFS]\0", 11);
1706 i.types[this_operand] = MEM;
1708 if ((m = maxq20_mem_access (op_string, &end_op)) == NULL)
1710 as_bad (_("Invalid operand for memory access '%s'"), op_string);
1711 return 0;
1713 i.maxq20_op[this_operand].mem = m;
1715 i.mem_operands++;
1717 return 1;
1720 else if ((r = parse_register (op_string, &end_op)) != NULL) /* Check for register. */
1722 op_string = end_op;
1724 if (is_space_char (*op_string))
1725 ++op_string;
1727 i.types[this_operand] = REG; /* Set the type. */
1728 i.maxq20_op[this_operand].reg = r; /* Set the Register value. */
1729 i.reg_operands++;
1730 return 1;
1733 if (this_operand == 1)
1735 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1736 /* The operand can either be a data reference or a symbol reference. */
1737 if ((sym = maxq20_data (org_case_op_string)) != NULL) /* Check for data memory. */
1739 while (is_space_char (*op_string))
1740 ++op_string;
1742 /* Set the type of the operand. */
1743 i.types[this_operand] = DATA;
1745 /* Set the value of the data. */
1746 i.maxq20_op[this_operand].data = sym;
1747 i.data_operands++;
1749 return 1;
1752 else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1754 /* This is a memory reference of some sort. char *base_string;
1755 Start and end of displacement string expression (if found). char
1756 *displacement_string_start; char *displacement_string_end. */
1757 base_string = org_case_op_string + strlen (org_case_op_string);
1759 --base_string;
1760 if (is_space_char (*base_string))
1761 --base_string;
1763 /* If we only have a displacement, set-up for it to be parsed
1764 later. */
1765 displacement_string_start = org_case_op_string;
1766 displacement_string_end = base_string + 1;
1767 if (displacement_string_start != displacement_string_end)
1769 if (!maxq20_displacement (displacement_string_start,
1770 displacement_string_end))
1772 as_bad (_("illegal displacement operand "));
1773 return 0;
1775 /* A displacement operand found. */
1776 i.types[this_operand] = DISP; /* Set the type. */
1777 return 1;
1782 /* Check for displacement. */
1783 else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1785 /* This is a memory reference of some sort. char *base_string;
1786 Start and end of displacement string expression (if found). char
1787 *displacement_string_start; char *displacement_string_end; */
1788 base_string = org_case_op_string + strlen (org_case_op_string);
1790 --base_string;
1791 if (is_space_char (*base_string))
1792 --base_string;
1794 /* If we only have a displacement, set-up for it to be parsed later. */
1795 displacement_string_start = org_case_op_string;
1796 displacement_string_end = base_string + 1;
1797 if (displacement_string_start != displacement_string_end)
1799 if (!maxq20_displacement (displacement_string_start,
1800 displacement_string_end))
1801 return 0;
1802 /* A displacement operand found. */
1803 i.types[this_operand] = DISP; /* Set the type. */
1806 return 1;
1809 /* Parse_operand takes as input instruction and operands and Parse operands
1810 and makes entry in the template. */
1812 static char *
1813 parse_operands (char *l, const char *mnemonic)
1815 char *token_start;
1817 /* 1 if operand is pending after ','. */
1818 short int expecting_operand = 0;
1820 /* Non-zero if operand parens not balanced. */
1821 short int paren_not_balanced;
1823 int operand_ok;
1825 /* For Overcoming Warning of unused variable. */
1826 if (mnemonic)
1827 operand_ok = 0;
1829 while (*l != END_OF_INSN)
1831 /* Skip optional white space before operand. */
1832 if (is_space_char (*l))
1833 ++l;
1835 if (!is_operand_char (*l) && *l != END_OF_INSN)
1837 as_bad (_("invalid character %c before operand %d"),
1838 (char) (*l), i.operands + 1);
1839 return NULL;
1841 token_start = l;
1843 paren_not_balanced = 0;
1844 while (paren_not_balanced || *l != ',')
1846 if (*l == END_OF_INSN)
1848 if (paren_not_balanced)
1850 as_bad (_("unbalanced brackets in operand %d."),
1851 i.operands + 1);
1852 return NULL;
1855 break;
1857 else if (!is_operand_char (*l) && !is_space_char (*l))
1859 as_bad (_("invalid character %c in operand %d"),
1860 (char) (*l), i.operands + 1);
1861 return NULL;
1863 if (*l == '[')
1864 ++paren_not_balanced;
1865 if (*l == ']')
1866 --paren_not_balanced;
1867 l++;
1870 if (l != token_start)
1872 /* Yes, we've read in another operand. */
1873 this_operand = i.operands++;
1874 if (i.operands > MAX_OPERANDS)
1876 as_bad (_("spurious operands; (%d operands/instruction max)"),
1877 MAX_OPERANDS);
1878 return NULL;
1881 /* Now parse operand adding info to 'i' as we go along. */
1882 END_STRING_AND_SAVE (l);
1884 operand_ok = maxq20_operand (token_start);
1886 RESTORE_END_STRING (l);
1888 if (!operand_ok)
1889 return NULL;
1891 else
1893 if (expecting_operand)
1895 expecting_operand_after_comma:
1896 as_bad (_("expecting operand after ','; got nothing"));
1897 return NULL;
1901 if (*l == ',')
1903 if (*(++l) == END_OF_INSN)
1904 /* Just skip it, if it's \n complain. */
1905 goto expecting_operand_after_comma;
1907 expecting_operand = 1;
1911 return l;
1914 static int
1915 match_operands (int type, MAX_ARG_TYPE flag_type, MAX_ARG_TYPE arg_type,
1916 int op_num)
1918 switch (type)
1920 case REG:
1921 if ((arg_type & A_REG) == A_REG)
1922 return 1;
1923 break;
1924 case IMM:
1925 if ((arg_type & A_IMM) == A_IMM)
1926 return 1;
1927 break;
1928 case IMMBIT:
1929 if ((arg_type & A_BIT_0) == A_BIT_0 && (i.maxq20_op[op_num].imms == 0))
1930 return 1;
1931 else if ((arg_type & A_BIT_1) == A_BIT_1
1932 && (i.maxq20_op[op_num].imms == 1))
1933 return 1;
1934 break;
1935 case MEM:
1936 if ((arg_type & A_MEM) == A_MEM)
1937 return 1;
1938 break;
1940 case FLAG:
1941 if ((arg_type & flag_type) == flag_type)
1942 return 1;
1944 break;
1946 case BIT:
1947 if ((arg_type & ACC_BIT) == ACC_BIT && !strcmp (i.maxq20_op[op_num].r_bit->reg->reg_name, "ACC"))
1948 return 1;
1949 else if ((arg_type & SRC_BIT) == SRC_BIT && (op_num == 1))
1950 return 1;
1951 else if ((op_num == 0) && (arg_type & DST_BIT) == DST_BIT)
1952 return 1;
1953 break;
1954 case DISP:
1955 if ((arg_type & A_DISP) == A_DISP)
1956 return 1;
1957 case DATA:
1958 if ((arg_type & A_DATA) == A_DATA)
1959 return 1;
1960 case BIT_BUCKET:
1961 if ((arg_type & A_BIT_BUCKET) == A_BIT_BUCKET)
1962 return 1;
1964 return 0;
1967 static int
1968 match_template (void)
1970 /* Points to template once we've found it. */
1971 const MAXQ20_OPCODE_INFO *t;
1972 char inv_oper;
1973 inv_oper = 0;
1975 for (t = current_templates->start; t < current_templates->end; t++)
1977 /* Must have right number of operands. */
1978 if (i.operands != t->op_number)
1979 continue;
1980 else if (!t->op_number)
1981 break;
1983 switch (i.operands)
1985 case 2:
1986 if (!match_operands (i.types[1], i.maxq20_op[1].flag, t->arg[1], 1))
1988 inv_oper = 1;
1989 continue;
1991 case 1:
1992 if (!match_operands (i.types[0], i.maxq20_op[0].flag, t->arg[0], 0))
1994 inv_oper = 2;
1995 continue;
1998 break;
2001 if (t == current_templates->end)
2003 /* We found no match. */
2004 as_bad (_("operand %d is invalid for `%s'"),
2005 inv_oper, current_templates->start->name);
2006 return 0;
2009 /* Copy the template we have found. */
2010 i.op = *t;
2011 return 1;
2014 /* This function filters out the various combinations of operands which are
2015 not allowed for a particular instruction. */
2017 static int
2018 match_filters (void)
2020 /* Now we have at our disposal the instruction i. We will be using the
2021 following fields i.op.name : This is the mnemonic name. i.types[2] :
2022 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2023 i.maxq20_op[2] : This contains the specific info of the operands. */
2025 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2026 SOURCE. */
2027 if (!strcmp (i.op.name, "AND") || !strcmp (i.op.name, "OR")
2028 || !strcmp (i.op.name, "XOR") || !strcmp (i.op.name, "ADD")
2029 || !strcmp (i.op.name, "ADDC") || !strcmp (i.op.name, "SUB")
2030 || !strcmp (i.op.name, "SUBB"))
2032 if (i.types[0] == REG)
2034 if (i.maxq20_op[0].reg->Mod_name == 0xa)
2036 as_bad (_
2037 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2038 return 0;
2043 if (!strcmp (i.op.name, "MOVE") && (i.types[0] == MEM || i.types[1] == MEM)
2044 && i.operands == 2)
2046 mem_access_syntax *mem_op = NULL;
2048 if (i.types[0] == MEM)
2050 mem_op =
2051 (mem_access_syntax *) hash_find (mem_syntax_hash,
2052 i.maxq20_op[0].mem->name);
2053 if ((mem_op->type == SRC) && mem_op)
2055 as_bad (_("'%s' operand cant be used as destination in %s"),
2056 mem_op->name, i.op.name);
2057 return 0;
2059 else if ((mem_op->invalid_op != NULL) && (i.types[1] == MEM)
2060 && mem_op)
2062 int k = 0;
2064 for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2066 if (mem_op->invalid_op[k] != NULL)
2067 if (!strcmp
2068 (mem_op->invalid_op[k], i.maxq20_op[1].mem->name))
2070 as_bad (_
2071 ("Invalid Instruction '%s' operand cant be used with %s"),
2072 mem_op->name, i.maxq20_op[1].mem->name);
2073 return 0;
2079 if (i.types[1] == MEM)
2081 mem_op = NULL;
2082 mem_op =
2083 (mem_access_syntax *) hash_find (mem_syntax_hash,
2084 i.maxq20_op[1].mem->name);
2085 if (mem_op->type == DST && mem_op)
2087 as_bad (_("'%s' operand cant be used as source in %s"),
2088 mem_op->name, i.op.name);
2089 return 0;
2091 else if (mem_op->invalid_op != NULL && i.types[0] == MEM && mem_op)
2093 int k = 0;
2095 for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2097 if (mem_op->invalid_op[k] != NULL)
2098 if (!strcmp
2099 (mem_op->invalid_op[k], i.maxq20_op[0].mem->name))
2101 as_bad (_
2102 ("Invalid Instruction '%s' operand cant be used with %s"),
2103 mem_op->name, i.maxq20_op[0].mem->name);
2104 return 0;
2108 else if (i.types[0] == REG
2109 && !strcmp (i.maxq20_op[0].reg->reg_name, "OFFS")
2110 && mem_op)
2112 if (!strcmp (mem_op->name, "@BP[OFFS--]")
2113 || !strcmp (mem_op->name, "@BP[OFFS++]"))
2115 as_bad (_
2116 ("Invalid Instruction '%s' operand cant be used with %s"),
2117 mem_op->name, i.maxq20_op[0].mem->name);
2118 return 0;
2124 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2125 on 10-March-2004. */
2126 if ((i.types[0] == MEM) && (i.operands == 1)
2127 && !(!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI")))
2129 mem_access_syntax *mem_op = NULL;
2131 if (i.types[0] == MEM)
2133 mem_op =
2134 (mem_access_syntax *) hash_find (mem_syntax_hash,
2135 i.maxq20_op[0].mem->name);
2136 if (mem_op->type == DST && mem_op)
2138 as_bad (_("'%s' operand cant be used as source in %s"),
2139 mem_op->name, i.op.name);
2140 return 0;
2145 if (i.operands == 2 && i.types[0] == IMM)
2147 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2148 i.op.name);
2149 return 0;
2152 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2153 if (!strcmp (i.op.name, "PUSH") || !strcmp (i.op.name, "POP")
2154 || !strcmp (i.op.name, "POPI"))
2156 if (i.types[0] == REG)
2158 if (!strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
2160 as_bad (_("SP cannot be used with %s\n"), i.op.name);
2161 return 0;
2164 else if (i.types[0] == MEM
2165 && !strcmp (i.maxq20_op[0].mem->name, "@SP--"))
2167 as_bad (_("@SP-- cannot be used with PUSH\n"));
2168 return 0;
2172 /* This filter checks that two memory references using DP's cannot be used
2173 together in an instruction */
2174 if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 2)
2176 if (strlen (i.maxq20_op[0].mem->name) != 6 ||
2177 strcmp (i.maxq20_op[0].mem->name, i.maxq20_op[1].mem->name))
2179 if (!strncmp (i.maxq20_op[0].mem->name, "@DP", 3)
2180 && !strncmp (i.maxq20_op[1].mem->name, "@DP", 3))
2182 as_bad (_
2183 ("Operands either contradictory or use the data bus in read/write state together"));
2184 return 0;
2187 if (!strncmp (i.maxq20_op[0].mem->name, "@SP", 3)
2188 && !strncmp (i.maxq20_op[1].mem->name, "@SP", 3))
2190 as_bad (_
2191 ("Operands either contradictory or use the data bus in read/write state together"));
2192 return 0;
2195 if ((i.maxq20_op[1].mem != NULL)
2196 && !strncmp (i.maxq20_op[1].mem->name, "NUL", 3))
2198 as_bad (_("MOVE Cant Use NUL as SRC"));
2199 return 0;
2203 /* This filter checks that contradictory movement between DP register and
2204 Memory access using DP followed by increment or decrement. */
2206 if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 1
2207 && i.reg_operands == 1)
2209 int memnum, regnum;
2211 memnum = (i.types[0] == MEM) ? 0 : 1;
2212 regnum = (memnum == 0) ? 1 : 0;
2213 if (!strncmp (i.maxq20_op[regnum].reg->reg_name, "DP", 2) &&
2214 !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2215 i.maxq20_op[regnum].reg->reg_name, 5)
2216 && strcmp ((i.maxq20_op[memnum].mem->name) + 1,
2217 i.maxq20_op[regnum].reg->reg_name))
2219 as_bad (_
2220 ("Contradictory movement between DP register and memory access using DP"));
2221 return 0;
2223 else if (!strcmp (i.maxq20_op[regnum].reg->reg_name, "SP") &&
2224 !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2225 i.maxq20_op[regnum].reg->reg_name, 2))
2227 as_bad (_
2228 ("SP and @SP-- cannot be used together in a move instruction"));
2229 return 0;
2233 /* This filter restricts the instructions containing source and destination
2234 bits to only CTRL module of the serial registers. Peripheral registers
2235 yet to be defined. */
2237 if (i.bit_operands == 1 && i.operands == 2)
2239 int bitnum = (i.types[0] == BIT) ? 0 : 1;
2241 if (strcmp (i.maxq20_op[bitnum].r_bit->reg->reg_name, "ACC"))
2243 if (i.maxq20_op[bitnum].r_bit->reg->Mod_name >= 0x7 &&
2244 i.maxq20_op[bitnum].r_bit->reg->Mod_name != CTRL)
2246 as_bad (_
2247 ("Only Module 8 system registers allowed in this operation"));
2248 return 0;
2253 /* This filter is for checking the register bits. */
2254 if (i.bit_operands == 1 || i.operands == 2)
2256 int bitnum = 0, size = 0;
2258 bitnum = (i.types[0] == BIT) ? 0 : 1;
2259 if (i.bit_operands == 1)
2261 switch (i.maxq20_op[bitnum].r_bit->reg->rtype)
2263 case Reg_8W:
2264 size = 7; /* 8 bit register, both read and write. */
2265 break;
2266 case Reg_16W:
2267 size = 15;
2268 break;
2269 case Reg_8R:
2270 size = 7;
2271 if (bitnum == 0)
2273 as_fatal (_("Read only Register used as destination"));
2274 return 0;
2276 break;
2278 case Reg_16R:
2279 size = 15;
2280 if (bitnum == 0)
2282 as_fatal (_("Read only Register used as destination"));
2283 return 0;
2285 break;
2288 if (size < (i.maxq20_op[bitnum].r_bit)->bit)
2290 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2291 (i.maxq20_op[bitnum].r_bit)->bit);
2292 return 0;
2296 if (i.bit_operands == 2)
2298 switch ((i.maxq20_op[0].r_bit)->reg->rtype)
2300 case Reg_8W:
2301 size = 7; /* 8 bit register, both read and write. */
2302 break;
2303 case Reg_16W:
2304 size = 15;
2305 break;
2306 case Reg_8R:
2307 case Reg_16R:
2308 as_fatal (_("Read only Register used as destination"));
2309 return 0;
2312 if (size < (i.maxq20_op[0].r_bit)->bit)
2314 as_bad (_
2315 ("Bit No '%d' exceeds register size in this operation"),
2316 (i.maxq20_op[0].r_bit)->bit);
2317 return 0;
2320 size = 0;
2321 switch ((i.maxq20_op[1].r_bit)->reg->rtype)
2323 case Reg_8R:
2324 case Reg_8W:
2325 size = 7; /* 8 bit register, both read and write. */
2326 break;
2327 case Reg_16R:
2328 case Reg_16W:
2329 size = 15;
2330 break;
2333 if (size < (i.maxq20_op[1].r_bit)->bit)
2335 as_bad (_
2336 ("Bit No '%d' exceeds register size in this operation"),
2337 (i.maxq20_op[1].r_bit)->bit);
2338 return 0;
2343 /* No branch operations should occur into the data memory. Hence any memory
2344 references have to be filtered out when used with instructions like
2345 jump, djnz[] and call. */
2347 if (!strcmp (i.op.name, "JUMP") || !strcmp (i.op.name, "CALL")
2348 || !strncmp (i.op.name, "DJNZ", 4))
2350 if (i.mem_operands)
2351 as_warn (_
2352 ("Memory References cannot be used with branching operations\n"));
2355 if (!strcmp (i.op.name, "DJNZ"))
2357 if (!
2358 (strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2359 || strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))
2361 as_bad (_("DJNZ uses only LC[n] register \n"));
2362 return 0;
2366 /* No destination register used should be read only! */
2367 if ((i.operands == 2 && i.types[0] == REG) || !strcmp (i.op.name, "POP")
2368 || !strcmp (i.op.name, "POPI"))
2369 { /* The destination is a register */
2370 int regnum = 0;
2372 if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2374 regnum = 0;
2376 if (i.types[regnum] == MEM)
2378 mem_access_syntax *mem_op = NULL;
2380 mem_op =
2381 (mem_access_syntax *) hash_find (mem_syntax_hash,
2382 i.maxq20_op[regnum].mem->
2383 name);
2384 if (mem_op->type == SRC && mem_op)
2386 as_bad (_
2387 ("'%s' operand cant be used as destination in %s"),
2388 mem_op->name, i.op.name);
2389 return 0;
2394 if (i.maxq20_op[regnum].reg->rtype == Reg_8R
2395 || i.maxq20_op[regnum].reg->rtype == Reg_16R)
2397 as_bad (_("Read only register used for writing purposes '%s'"),
2398 i.maxq20_op[regnum].reg->reg_name);
2399 return 0;
2403 /* While moving the address of a data in the data section, the destination
2404 should be either data pointers only. */
2405 if ((i.data_operands) && (i.operands == 2))
2407 if ((i.types[0] != REG) && (i.types[0] != MEM))
2409 as_bad (_("Invalid destination for this kind of source."));
2410 return 0;
2413 if (i.types[0] == REG && i.maxq20_op[0].reg->rtype == Reg_8W)
2415 as_bad (_
2416 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2417 return 0;
2420 return 1;
2423 static int
2424 decode_insn (void)
2426 /* Check for the format Bit if defined. */
2427 if (i.op.format == 0 || i.op.format == 1)
2428 i.instr[0] = i.op.format << 7;
2429 else
2431 /* Format bit not defined. We will have to be find it out ourselves. */
2432 if (i.imm_operands == 1 || i.data_operands == 1 || i.disp_operands == 1)
2433 i.op.format = 0;
2434 else
2435 i.op.format = 1;
2436 i.instr[0] = i.op.format << 7;
2439 /* Now for the destination register. */
2441 /* If destination register is already defined . The conditions are the
2442 following: (1) The second entry in the destination array should be 0 (2)
2443 If there are two operands then the first entry should not be a register,
2444 memory or a register bit (3) If there are less than two operands and the
2445 it is not a pop operation (4) The second argument is the carry
2446 flag(applicable to move Acc.<b>,C. */
2447 if (i.op.dst[1] == 0
2449 ((i.types[0] != REG && i.types[0] != MEM && i.types[0] != BIT
2450 && i.operands == 2) || (i.operands < 2 && strcmp (i.op.name, "POP")
2451 && strcmp (i.op.name, "POPI"))
2452 || (i.op.arg[1] == FLAG_C)))
2454 i.op.dst[0] &= 0x7f;
2455 i.instr[0] |= i.op.dst[0];
2457 else if (i.op.dst[1] == 0 && !strcmp (i.op.name, "DJNZ")
2459 (((i.types[0] == REG)
2460 && (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2461 || !strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))))
2463 i.op.dst[0] &= 0x7f;
2464 if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]"))
2465 i.instr[0] |= 0x4D;
2467 if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]"))
2468 i.instr[0] |= 0x5D;
2470 else
2472 unsigned char temp;
2474 /* Target register will have to be specified. */
2475 if (i.types[0] == REG
2476 && (i.op.dst[0] == REG || i.op.dst[0] == (REG | MEM)))
2478 temp = (i.maxq20_op[0].reg)->opcode;
2479 temp &= 0x7f;
2480 i.instr[0] |= temp;
2482 else if (i.types[0] == MEM && (i.op.dst[0] == (REG | MEM)))
2484 temp = (i.maxq20_op[0].mem)->opcode;
2485 temp &= 0x7f;
2486 i.instr[0] |= temp;
2488 else if (i.types[0] == BIT && (i.op.dst[0] == REG))
2490 temp = (i.maxq20_op[0].r_bit)->reg->opcode;
2491 temp &= 0x7f;
2492 i.instr[0] |= temp;
2494 else if (i.types[1] == BIT && (i.op.dst[0] == BIT))
2496 temp = (i.maxq20_op[1].r_bit)->bit;
2497 temp = temp << 4;
2498 temp |= i.op.dst[1];
2499 temp &= 0x7f;
2500 i.instr[0] |= temp;
2502 else
2504 as_bad (_("Invalid Instruction"));
2505 return 0;
2509 /* Now for the source register. */
2511 /* If Source register is already known. The following conditions are
2512 checked: (1) There are no operands (2) If there is only one operand and
2513 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2514 operation. */
2516 if (i.operands == 0 || (i.operands == 1 && i.types[0] == FLAG)
2517 || (i.types[0] == FLAG && i.types[1] == IMMBIT)
2518 || !strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2519 i.instr[1] = i.op.src[0];
2521 else if (i.imm_operands == 1 && ((i.op.src[0] & IMM) == IMM))
2522 i.instr[1] = i.maxq20_op[this_operand].imms;
2524 else if (i.types[this_operand] == REG && ((i.op.src[0] & REG) == REG))
2525 i.instr[1] = (char) ((i.maxq20_op[this_operand].reg)->opcode);
2527 else if (i.types[this_operand] == BIT && ((i.op.src[0] & REG) == REG))
2528 i.instr[1] = (char) (i.maxq20_op[this_operand].r_bit->reg->opcode);
2530 else if (i.types[this_operand] == MEM && ((i.op.src[0] & MEM) == MEM))
2531 i.instr[1] = (char) ((i.maxq20_op[this_operand].mem)->opcode);
2533 else if (i.types[this_operand] == DATA && ((i.op.src[0] & DATA) == DATA))
2534 /* This will copy only the lower order bytes into the instruction. The
2535 higher order bytes have already been copied into the prefix register. */
2536 i.instr[1] = 0;
2538 /* Decoding the source in the case when the second array entry is not 0.
2539 This means that the source register has been divided into two nibbles. */
2541 else if (i.op.src[1] != 0)
2543 /* If the first operand is a accumulator bit then
2544 the first 4 bits will be filled with the bit number. */
2545 if (i.types[0] == BIT && ((i.op.src[0] & BIT) == BIT))
2547 unsigned char temp = (i.maxq20_op[0].r_bit)->bit;
2549 temp = temp << 4;
2550 temp |= i.op.src[1];
2551 i.instr[1] = temp;
2553 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2554 has to start with a zero. This is called a ZEROBIT */
2555 else if (i.types[0] == BIT && ((i.op.src[0] & ZEROBIT) == ZEROBIT))
2557 char temp = (i.maxq20_op[0].r_bit)->bit;
2559 temp = temp << 4;
2560 temp |= i.op.src[1];
2561 temp &= 0x7f;
2562 i.instr[1] = temp;
2564 /* Similarly for a ONEBIT */
2565 else if (i.types[0] == BIT && ((i.op.src[0] & ONEBIT) == ONEBIT))
2567 char temp = (i.maxq20_op[0].r_bit)->bit;
2569 temp = temp << 4;
2570 temp |= i.op.src[1];
2571 temp |= 0x80;
2572 i.instr[1] = temp;
2574 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2575 C,src.<b> */
2576 else if (i.types[1] == BIT)
2578 if (i.op.src[1] == 0 && i.op.src[1] == REG)
2579 i.instr[1] = (i.maxq20_op[1].r_bit)->reg->opcode;
2581 else if (i.op.src[0] == BIT && i.op.src)
2583 char temp = (i.maxq20_op[1].r_bit)->bit;
2585 temp = temp << 4;
2586 temp |= i.op.src[1];
2587 i.instr[1] = temp;
2590 else
2592 as_bad (_("Invalid Instruction"));
2593 return 0;
2596 return 1;
2599 /* This is a function for outputting displacement operands. */
2601 static void
2602 output_disp (fragS *insn_start_frag, offsetT insn_start_off)
2604 char *p;
2605 relax_substateT subtype;
2606 symbolS *sym;
2607 offsetT off;
2608 int diff;
2610 diff = 0;
2611 insn_start_frag = frag_now;
2612 insn_start_off = frag_now_fix ();
2614 switch (i.Instr_Prefix)
2616 case LONG_PREFIX:
2617 subtype = EXPLICT_LONG_PREFIX;
2618 break;
2619 case SHORT_PREFIX:
2620 subtype = SHORT_PREFIX;
2621 break;
2622 default:
2623 subtype = NO_PREFIX;
2624 break;
2627 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2628 case there is no need for relaxation. But we do need support for a
2629 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2630 for prefix + 2 for the current instruction ) Hence if at a particular
2631 time we find out whether the prefix operator is reqd , we shift the
2632 current instruction two places ahead and insert the prefix instruction. */
2633 frag_grow (2 + 2);
2634 p = frag_more (2);
2636 sym = i.maxq20_op[this_operand].disps->X_add_symbol;
2637 off = i.maxq20_op[this_operand].disps->X_add_number;
2639 if (i.maxq20_op[this_operand].disps->X_add_symbol != NULL && sym && frag_now
2640 && (subtype != EXPLICT_LONG_PREFIX))
2642 /* If in the same frag. */
2643 if (frag_now == symbol_get_frag (sym))
2645 diff =
2646 ((((expressionS *) symbol_get_value_expression (sym))->
2647 X_add_number) - insn_start_off);
2649 /* PC points to the next instruction. */
2650 diff = (diff / MAXQ_OCTETS_PER_BYTE) - 1;
2652 if (diff >= -128 && diff <= 127)
2654 i.instr[1] = (char) diff;
2656 /* This will be overwritten later when the symbol is resolved. */
2657 *p = i.instr[1];
2658 *(p + 1) = i.instr[0];
2660 /* No Need to create a FIXUP. */
2661 return;
2666 /* This will be overwritten later when the symbol is resolved. */
2667 *p = i.instr[1];
2668 *(p + 1) = i.instr[0];
2670 if (i.maxq20_op[this_operand].disps->X_op != O_constant
2671 && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2673 /* Handle complex expressions. */
2674 sym = make_expr_symbol (i.maxq20_op[this_operand].disps);
2675 off = 0;
2678 /* Vineet : This has been added for md_estimate_size_before_relax to
2679 estimate the correct size. */
2680 if (subtype != SHORT_PREFIX)
2681 i.reloc[this_operand] = LONG_PREFIX;
2683 frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off, p);
2686 /* This is a function for outputting displacement operands. */
2688 static void
2689 output_data (fragS *insn_start_frag, offsetT insn_start_off)
2691 char *p;
2692 relax_substateT subtype;
2693 symbolS *sym;
2694 offsetT off;
2695 int diff;
2697 diff = 0;
2698 off = 0;
2699 insn_start_frag = frag_now;
2700 insn_start_off = frag_now_fix ();
2702 subtype = EXPLICT_LONG_PREFIX;
2704 frag_grow (2 + 2);
2705 p = frag_more (2);
2707 sym = i.maxq20_op[this_operand].data;
2708 off = 0;
2710 /* This will be overwritten later when the symbol is resolved. */
2711 *p = i.instr[1];
2712 *(p + 1) = i.instr[0];
2714 if (i.maxq20_op[this_operand].disps->X_op != O_constant
2715 && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2716 /* Handle complex expressions. */
2717 /* Because data is already in terms of symbol so no
2718 need to convert it from expression to symbol. */
2719 off = 0;
2721 frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off, p);
2724 static void
2725 output_insn (void)
2727 fragS *insn_start_frag;
2728 offsetT insn_start_off;
2729 char *p;
2731 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2732 do this after the insn has been output as the current frag may have been
2733 closed off. eg. by frag_var. */
2734 dwarf2_emit_insn (0);
2736 /* To ALign the text section on word. */
2738 frag_align (1, 0, 1);
2740 /* We initialise the frags for this particular instruction. */
2741 insn_start_frag = frag_now;
2742 insn_start_off = frag_now_fix ();
2744 /* If there are displacement operators(unresolved) present, then handle
2745 them separately. */
2746 if (i.disp_operands)
2748 output_disp (insn_start_frag, insn_start_off);
2749 return;
2752 if (i.data_operands)
2754 output_data (insn_start_frag, insn_start_off);
2755 return;
2758 /* Check whether the INSERT_BUFFER has to be written. */
2759 if (strcmp (INSERT_BUFFER, ""))
2761 p = frag_more (2);
2763 *p++ = INSERT_BUFFER[1];
2764 *p = INSERT_BUFFER[0];
2767 /* Check whether the prefix instruction has to be written. */
2768 if (strcmp (PFX_INSN, ""))
2770 p = frag_more (2);
2772 *p++ = PFX_INSN[1];
2773 *p = PFX_INSN[0];
2776 p = frag_more (2);
2777 /* For Little endian. */
2778 *p++ = i.instr[1];
2779 *p = i.instr[0];
2782 static void
2783 make_new_reg_table (void)
2785 unsigned long size_pm = sizeof (peripheral_reg_table);
2786 num_of_reg = ARRAY_SIZE (peripheral_reg_table);
2788 new_reg_table = xmalloc (size_pm);
2789 if (new_reg_table == NULL)
2790 as_bad (_("Cannot allocate memory"));
2792 memcpy (new_reg_table, peripheral_reg_table, size_pm);
2795 /* pmmain performs the initilizations for the pheripheral modules. */
2797 static void
2798 pmmain (void)
2800 make_new_reg_table ();
2801 return;
2804 void
2805 md_begin (void)
2807 const char *hash_err = NULL;
2808 int c = 0;
2809 char *p;
2810 const MAXQ20_OPCODE_INFO *optab;
2811 MAXQ20_OPCODES *core_optab; /* For opcodes of the same name. This will
2812 be inserted into the hash table. */
2813 struct reg *reg_tab;
2814 struct mem_access_syntax const *memsyntab;
2815 struct mem_access *memtab;
2816 struct bit_name *bittab;
2818 /* Initilize pherioipheral modules. */
2819 pmmain ();
2821 /* Initialise the opcode hash table. */
2822 op_hash = hash_new ();
2824 optab = op_table; /* Initialise it to the first entry of the
2825 maxq20 operand table. */
2827 /* Setup for loop. */
2828 core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2829 core_optab->start = optab;
2831 while (1)
2833 ++optab;
2834 if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0)
2836 /* different name --> ship out current template list; add to hash
2837 table; & begin anew. */
2839 core_optab->end = optab;
2840 #ifdef MAXQ10S
2841 if (max_version == bfd_mach_maxq10)
2843 if (((optab - 1)->arch == MAXQ10) || ((optab - 1)->arch == MAX))
2845 hash_err = hash_insert (op_hash,
2846 (optab - 1)->name,
2847 (void *) core_optab);
2850 else if (max_version == bfd_mach_maxq20)
2852 if (((optab - 1)->arch == MAXQ20) || ((optab - 1)->arch == MAX))
2854 #endif
2855 hash_err = hash_insert (op_hash,
2856 (optab - 1)->name,
2857 (void *) core_optab);
2858 #if MAXQ10S
2861 else
2862 as_fatal (_("Internal Error: Illegal Architecure specified"));
2863 #endif
2864 if (hash_err)
2865 as_fatal (_("Internal Error: Can't hash %s: %s"),
2866 (optab - 1)->name, hash_err);
2868 if (optab->name == NULL)
2869 break;
2870 core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2871 core_optab->start = optab;
2875 /* Initialise a new register table. */
2876 reg_hash = hash_new ();
2878 for (reg_tab = system_reg_table;
2879 reg_tab < (system_reg_table + ARRAY_SIZE (system_reg_table));
2880 reg_tab++)
2882 #if MAXQ10S
2883 switch (max_version)
2885 case bfd_mach_maxq10:
2886 if ((reg_tab->arch == MAXQ10) || (reg_tab->arch == MAX))
2887 hash_err = hash_insert (reg_hash, reg_tab->reg_name, (void *) reg_tab);
2888 break;
2890 case bfd_mach_maxq20:
2891 if ((reg_tab->arch == MAXQ20) || (reg_tab->arch == MAX))
2893 #endif
2894 hash_err =
2895 hash_insert (reg_hash, reg_tab->reg_name, (void *) reg_tab);
2896 #if MAXQ10S
2898 break;
2899 default:
2900 as_fatal (_("Invalid architecture type"));
2902 #endif
2904 if (hash_err)
2905 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2906 reg_tab->reg_name, hash_err);
2909 /* Pheripheral Registers Entry. */
2910 for (reg_tab = new_reg_table;
2911 reg_tab < (new_reg_table + num_of_reg - 1); reg_tab++)
2913 hash_err = hash_insert (reg_hash, reg_tab->reg_name, (void *) reg_tab);
2915 if (hash_err)
2916 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2917 reg_tab->reg_name, hash_err);
2920 /* Initialise a new memory operand table. */
2921 mem_hash = hash_new ();
2923 for (memtab = mem_table;
2924 memtab < mem_table + ARRAY_SIZE (mem_table);
2925 memtab++)
2927 hash_err = hash_insert (mem_hash, memtab->name, (void *) memtab);
2928 if (hash_err)
2929 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2930 memtab->name, hash_err);
2933 bit_hash = hash_new ();
2935 for (bittab = bit_table;
2936 bittab < bit_table + ARRAY_SIZE (bit_table);
2937 bittab++)
2939 hash_err = hash_insert (bit_hash, bittab->name, (void *) bittab);
2940 if (hash_err)
2941 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2942 bittab->name, hash_err);
2945 mem_syntax_hash = hash_new ();
2947 for (memsyntab = mem_access_syntax_table;
2948 memsyntab < mem_access_syntax_table + ARRAY_SIZE (mem_access_syntax_table);
2949 memsyntab++)
2951 hash_err =
2952 hash_insert (mem_syntax_hash, memsyntab->name, (void *) memsyntab);
2953 if (hash_err)
2954 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2955 memsyntab->name, hash_err);
2958 /* Initialise the lexical tables,mnemonic chars,operand chars. */
2959 for (c = 0; c < 256; c++)
2961 if (ISDIGIT (c))
2963 digit_chars[c] = c;
2964 mnemonic_chars[c] = c;
2965 operand_chars[c] = c;
2966 register_chars[c] = c;
2968 else if (ISLOWER (c))
2970 mnemonic_chars[c] = c;
2971 operand_chars[c] = c;
2972 register_chars[c] = c;
2974 else if (ISUPPER (c))
2976 mnemonic_chars[c] = TOLOWER (c);
2977 register_chars[c] = c;
2978 operand_chars[c] = c;
2981 if (ISALPHA (c) || ISDIGIT (c))
2983 identifier_chars[c] = c;
2985 else if (c > 128)
2987 identifier_chars[c] = c;
2988 operand_chars[c] = c;
2992 /* All the special characters. */
2993 register_chars['@'] = '@';
2994 register_chars['+'] = '+';
2995 register_chars['-'] = '-';
2996 digit_chars['-'] = '-';
2997 identifier_chars['_'] = '_';
2998 identifier_chars['.'] = '.';
2999 register_chars['['] = '[';
3000 register_chars[']'] = ']';
3001 operand_chars['_'] = '_';
3002 operand_chars['#'] = '#';
3003 mnemonic_chars['['] = '[';
3004 mnemonic_chars[']'] = ']';
3006 for (p = operand_special_chars; *p != '\0'; p++)
3007 operand_chars[(unsigned char) *p] = (unsigned char) *p;
3009 /* Set the maxq arch type. */
3010 maxq_target (max_version);
3013 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3014 menmunonic in the operand table - Parse operands and populate the
3015 structure/template - Match the operand with opcode and its validity -
3016 Output Instr. */
3018 void
3019 md_assemble (char *line)
3021 int j;
3023 char mnemonic[MAX_MNEM_SIZE];
3024 char temp4prev[256];
3025 static char prev_insn[256];
3027 /* Initialize globals. */
3028 memset (&i, '\0', sizeof (i));
3029 for (j = 0; j < MAX_OPERANDS; j++)
3030 i.reloc[j] = NO_RELOC;
3032 i.prefix = -1;
3033 PFX_INSN[0] = 0;
3034 PFX_INSN[1] = 0;
3035 INSERT_BUFFER[0] = 0;
3036 INSERT_BUFFER[1] = 0;
3038 memcpy (temp4prev, line, strlen (line) + 1);
3040 save_stack_p = save_stack;
3042 line = (char *) parse_insn (line, mnemonic);
3043 if (line == NULL)
3044 return;
3046 line = (char *) parse_operands (line, mnemonic);
3047 if (line == NULL)
3048 return;
3050 /* Next, we find a template that matches the given insn, making sure the
3051 overlap of the given operands types is consistent with the template
3052 operand types. */
3053 if (!match_template ())
3054 return;
3056 /* In the MAXQ20, there are certain register combinations, and other
3057 restrictions which are not allowed. We will try to resolve these right
3058 now. */
3059 if (!match_filters ())
3060 return;
3062 /* Check for the appropriate PFX register. */
3063 set_prefix ();
3064 pfx_for_imm_val (0);
3066 if (!decode_insn ()) /* decode insn. */
3067 need_pass_2 = 1;
3069 /* Check for Exlipct PFX instruction. */
3070 if (PFX_INSN[0] && (strstr (prev_insn, "PFX") || strstr (prev_insn, "pfx")))
3071 as_warn (_("Ineffective insntruction %s \n"), prev_insn);
3073 memcpy (prev_insn, temp4prev, strlen (temp4prev) + 1);
3075 /* We are ready to output the insn. */
3076 output_insn ();