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
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
30 #include "opcode/maxq.h"
42 #define DEFAULT_ARCH "MAXQ20"
46 #define MAX_OPERANDS 2
50 #define MAX_MNEM_SIZE 8
54 #define END_OF_INSN '\0'
57 #ifndef IMMEDIATE_PREFIX
58 #define IMMEDIATE_PREFIX '#'
61 #ifndef MAX_REG_NAME_SIZE
62 #define MAX_REG_NAME_SIZE 4
65 #ifndef MAX_MEM_NAME_SIZE
66 #define MAX_MEM_NAME_SIZE 9
69 /* opcode for PFX[0]. */
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. */
81 const reg_entry
* reg
;
82 char imms
; /* This is to store the immediate value operand. */
85 const mem_access
* mem
;
87 const reg_bit
* r_bit
;
90 typedef union _maxq20_op maxq20_opcode
;
92 /* For handling optional L/S in Maxq20. */
95 /* Exposed For Linker - maps indirectly to the liker relocations. */
96 #define LONG_PREFIX MAXQ_LONGJUMP /* BFD_RELOC_16 */
97 #define SHORT_PREFIX MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
98 #define ABSOLUTE_ADDR_FOR_DATA MAXQ_INTERSEGMENT
101 #define EXPLICT_LONG_PREFIX 14
105 #define EXPLICT_LONG_PREFIX 14
106 #define LONG_PREFIX 5
107 #define SHORT_PREFIX 1
108 #define ABSOLUTE_ADDR_FOR_DATA 0
113 /* The main instruction structure containing fields to describe instrn */
114 typedef struct _maxq20_insn
116 /* The opcode information for the MAXQ20 */
117 MAXQ20_OPCODE_INFO op
;
119 /* The number of operands */
120 unsigned int operands
;
122 /* Number of different types of operands - Comments can be removed if reqd.
124 unsigned int reg_operands
, mem_operands
, disp_operands
, data_operands
;
125 unsigned int imm_operands
, imm_bit_operands
, bit_operands
, flag_operands
;
127 /* Types of the individual operands */
128 UNKNOWN_OP types
[MAX_OPERANDS
];
130 /* Relocation type for operand : to be investigated into */
131 int reloc
[MAX_OPERANDS
];
133 /* Complete information of the Operands */
134 maxq20_opcode maxq20_op
[MAX_OPERANDS
];
136 /* Choice of prefix register whenever needed */
139 /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
140 unsigned char Instr_Prefix
;
142 /* 16 bit Instruction word */
143 unsigned char instr
[2];
147 /* Definitions of all possible characters that can start an operand. */
148 const char *extra_symbol_chars
= "@(#";
150 /* Special Character that would start a comment. */
151 const char comment_chars
[] = ";";
153 /* Starts a comment when it appears at the start of a line. */
154 const char line_comment_chars
[] = ";#";
156 const char line_separator_chars
[] = ""; /* originally may b by sudeep "\n". */
158 /* The following are used for option processing. */
160 /* This is added to the mach independent string passed to getopt. */
161 const char *md_shortopts
= "q";
163 /* Characters for exponent and floating point. */
164 const char EXP_CHARS
[] = "eE";
165 const char FLT_CHARS
[] = "";
167 /* This is for the machine dependent option handling. */
168 #define OPTION_EB (OPTION_MD_BASE + 0)
169 #define OPTION_EL (OPTION_MD_BASE + 1)
170 #define MAXQ_10 (OPTION_MD_BASE + 2)
171 #define MAXQ_20 (OPTION_MD_BASE + 3)
173 struct option md_longopts
[] =
175 {"MAXQ10", no_argument
, NULL
, MAXQ_10
},
176 {"MAXQ20", no_argument
, NULL
, MAXQ_20
},
177 {NULL
, no_argument
, NULL
, 0}
179 size_t md_longopts_size
= sizeof (md_longopts
);
181 /* md_undefined_symbol We have no need for this function. */
184 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
190 maxq_target (int target
)
192 max_version
= target
;
193 bfd_set_arch_mach (stdoutput
, bfd_arch_maxq
, max_version
);
197 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
199 /* Any options support will be added onto this switch case. */
203 max_version
= bfd_mach_maxq10
;
206 max_version
= bfd_mach_maxq20
;
216 /* When a usage message is printed, this function is called and
217 it prints a description of the machine specific options. */
220 md_show_usage (FILE * stream
)
222 /* Over here we will fill the description of the machine specific options. */
224 fprintf (stream
, _(" MAXQ-specific assembler options:\n"));
226 fprintf (stream
, _("\
227 -MAXQ20 generate obj for MAXQ20(default)\n\
228 -MAXQ10 generate obj for MAXQ10\n\
236 if (!(strcmp (default_arch
, "MAXQ20")))
239 as_fatal (_("Unknown architecture"));
244 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
247 bfd_reloc_code_real_type code
;
249 switch (fixp
->fx_r_type
)
251 case MAXQ_INTERSEGMENT
:
253 case BFD_RELOC_16_PCREL_S2
:
254 code
= fixp
->fx_r_type
;
259 switch (fixp
->fx_size
)
262 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
263 _("can not do %d byte relocation"), fixp
->fx_size
);
279 rel
= xmalloc (sizeof (arelent
));
280 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
281 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
283 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
284 rel
->addend
= fixp
->fx_addnumber
;
285 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
287 if (rel
->howto
== NULL
)
289 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
290 _("cannot represent relocation type %s"),
291 bfd_get_reloc_code_name (code
));
293 /* Set howto to a garbage value so that we can keep going. */
294 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
295 assert (rel
->howto
!= NULL
);
303 /* md_estimate_size_before_relax()
305 Called just before relax() for rs_machine_dependent frags. The MAXQ
306 assembler uses these frags to handle 16 bit absolute jumps which require a
307 prefix instruction to be inserted. Any symbol that is now undefined will
308 not become defined. Return the correct fr_subtype in the frag. Return the
309 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
310 caller. The guess is actually the growth beyond the fixed part. Whatever
311 we do to grow the fixed or variable part contributes to our returned
315 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
317 /* Check whether the symbol has been resolved or not.
318 Otherwise we will have to generate a fixup. */
319 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
)
320 || fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
322 RELOC_ENUM reloc_type
;
323 unsigned char *opcode
;
326 /* Now this symbol has not been defined in this file.
327 Hence we will have to create a fixup. */
330 /* This is for the prefix instruction. */
332 if (fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
333 fragP
->fr_subtype
= LONG_PREFIX
;
335 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
336 && ((!(fragP
->fr_subtype
) == EXPLICT_LONG_PREFIX
)))
337 fragP
->fr_subtype
= ABSOLUTE_ADDR_FOR_DATA
;
340 (fragP
->fr_subtype
? fragP
->fr_subtype
: ABSOLUTE_ADDR_FOR_DATA
);
342 fragP
->fr_subtype
= reloc_type
;
344 if (reloc_type
== SHORT_PREFIX
)
346 old_fr_fix
= fragP
->fr_fix
;
347 opcode
= (unsigned char *) fragP
->fr_opcode
;
349 fragP
->fr_fix
+= (size
);
351 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
352 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
354 return fragP
->fr_fix
- old_fr_fix
;
357 if (fragP
->fr_subtype
== SHORT_PREFIX
)
359 fragP
->fr_subtype
= SHORT_PREFIX
;
363 if (fragP
->fr_subtype
== NO_PREFIX
|| fragP
->fr_subtype
== LONG_PREFIX
)
366 unsigned long call_addr
;
370 call_addr
= call_addr
^ call_addr
;
374 /* segment_info_type *seginfo = seg_info (segment); */
375 instr
= fragP
->fr_address
+ fragP
->fr_fix
- 2;
377 /* This is the offset if it is a PC relative jump. */
378 call_addr
= S_GET_VALUE (fragP
->fr_symbol
) + fragP
->fr_offset
;
379 diff
= (call_addr
- instr
);
381 if (diff
>= (-128 * 2) && diff
<= (2 * 127))
383 /* Now as offset is an 8 bit value, we will pass
384 that to the jump instruction directly. */
385 fragP
->fr_subtype
= NO_PREFIX
;
389 fragP
->fr_subtype
= LONG_PREFIX
;
393 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
398 /* Equal to MAX_PRECISION in atof-ieee.c */
399 #define MAX_LITTLENUMS 6
401 /* Turn a string in input_line_pointer into a floating point constant of type
402 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
403 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
406 md_atof (int type
, char * litP
, int * sizeP
)
409 LITTLENUM_TYPE words
[4];
421 /* The size of Double has been changed to 2 words ie 32 bits. */
427 return _("bad call to md_atof");
430 t
= atof_ieee (input_line_pointer
, type
, words
);
432 input_line_pointer
= t
;
436 for (i
= prec
- 1; i
>= 0; i
--)
438 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
446 maxq20_cons_fix_new (fragS
* frag
, unsigned int off
, unsigned int len
,
454 r
= MAXQ_WORDDATA
; /* Word+n */
457 r
= MAXQ_LONGDATA
; /* Long+n */
461 fix_new_exp (frag
, off
, len
, exp
, 0, r
);
466 tc_coff_fix2rtype (fixS
* fixP
)
468 return fixP
->fx_r_type
;
472 tc_coff_sizemachdep (fragS
*fragP
)
475 return (fragP
->fr_next
->fr_address
- fragP
->fr_address
);
480 /* GAS will call this for every rs_machine_dependent fragment. The
481 instruction is compleated using the data from the relaxation pass. It may
482 also create any necessary relocations. */
485 md_convert_frag (bfd
* headers ATTRIBUTE_UNUSED
,
486 segT seg ATTRIBUTE_UNUSED
,
490 md_convert_frag (object_headers
* headers ATTRIBUTE_UNUSED
,
491 segT sec ATTRIBUTE_UNUSED
,
495 unsigned char *opcode
;
496 offsetT target_address
;
497 offsetT opcode_address
;
498 offsetT displacement_from_opcode_start
;
501 opcode
= fragP
->fr_opcode
;
503 target_address
= opcode_address
= displacement_from_opcode_start
= 0;
506 (S_GET_VALUE (fragP
->fr_symbol
) / MAXQ_OCTETS_PER_BYTE
) +
507 (fragP
->fr_offset
/ MAXQ_OCTETS_PER_BYTE
);
510 (fragP
->fr_address
/ MAXQ_OCTETS_PER_BYTE
) +
511 ((fragP
->fr_fix
- 2) / MAXQ_OCTETS_PER_BYTE
);
513 displacement_from_opcode_start
= (target_address
- opcode_address
);
515 if ((displacement_from_opcode_start
>= -128
516 && displacement_from_opcode_start
<= 127)
517 && (fragP
->fr_subtype
== SHORT_PREFIX
518 || fragP
->fr_subtype
== NO_PREFIX
))
520 /* Its a displacement. */
521 char *p
= (char *) &opcode
[0];
523 *p
= (char) displacement_from_opcode_start
;
527 /* Its an absolute 16 bit jump. Now we have to
528 load the prefix operator with the upper 8 bits. */
529 if (fragP
->fr_subtype
== SHORT_PREFIX
)
531 as_bad (_("Cant make long jump/call into short jump/call : %d"),
536 /* Check whether the symbol has been resolved or not.
537 Otherwise we will have to generate a fixup. */
539 if (fragP
->fr_subtype
!= SHORT_PREFIX
)
541 RELOC_ENUM reloc_type
;
542 unsigned char *opcode
;
546 /* Now this is a basolute jump/call.
547 Hence we will have to create a fixup. */
548 if (fragP
->fr_subtype
== NO_PREFIX
)
549 fragP
->fr_subtype
= LONG_PREFIX
;
552 (fragP
->fr_subtype
? fragP
->fr_subtype
: LONG_PREFIX
);
556 old_fr_fix
= fragP
->fr_fix
;
557 opcode
= (unsigned char *) fragP
->fr_opcode
;
559 fragP
->fr_fix
+= (size
);
561 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
562 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
569 md_pcrel_from (fixS
*fixP
)
571 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
574 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
577 maxq_number_to_chars (char *buf
, valueT val
, int n
)
579 if (target_big_endian
)
580 number_to_chars_bigendian (buf
, val
, n
);
582 number_to_chars_littleendian (buf
, val
, n
);
585 /* GAS will call this for each fixup. It's main objective is to store the
586 correct value in the object file. 'fixup_segment' performs the generic
587 overflow check on the 'valueT *val' argument after md_apply_fix3 returns.
588 If the overflow check is relevant for the target machine, then
589 'md_apply_fix3' should modify 'valueT *val', typically to the value stored
590 in the object file (not to be done in MAXQ). */
593 md_apply_fix3 (fixS
*fixP
, valueT
*valT
, segT seg ATTRIBUTE_UNUSED
)
595 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
596 char *frag_to_fix_at
=
597 fixP
->fx_frag
->fr_literal
+ fixP
->fx_frag
->fr_fix
- 2;
601 if (fixP
->fx_frag
&& valT
)
603 /* If the relaxation substate is not defined we make it equal
604 to the kind of relocation the fixup is generated for. */
605 if (!fixP
->fx_frag
->fr_subtype
)
606 fixP
->fx_frag
->fr_subtype
= fixP
->fx_r_type
;
608 /* For any instruction in which either we have specified an
609 absolute address or it is a long jump we need to add a PFX0
610 instruction to it. In this case as the instruction has already
611 being written at 'fx_where' in the frag we copy it at the end of
612 the frag(which is where the relocation was generated) as when
613 the relocation is generated the frag is grown by 2 type, this is
614 where we copy the contents of fx_where and add a pfx0 at
616 if ((fixP
->fx_frag
->fr_subtype
== ABSOLUTE_ADDR_FOR_DATA
)
617 || (fixP
->fx_frag
->fr_subtype
== LONG_PREFIX
))
619 *(frag_to_fix_at
+ 1) = *(p
+ 1);
620 maxq_number_to_chars (p
+ 1, PFX0
, 1);
624 /* Remember value for tc_gen_reloc. */
625 fixP
->fx_addnumber
= *valT
;
629 /* This prob can be fixed by defining tc_fix_adjustable. */
630 #ifndef BFD_ASSEMBLER
631 if (fixP
->fx_addsy
&& S_GET_SEGMENT (fixP
->fx_addsy
))
632 segment_info
[S_GET_SEGMENT (fixP
->fx_addsy
)].dot
= NULL
;
635 /* Some fixups generated by GAS which gets resovled before this this
636 func. is called need to be wriiten to the frag as here we are going
637 to go away with the relocations fx_done=1. */
638 if (fixP
->fx_addsy
== NULL
)
640 maxq_number_to_chars (p
, *valT
, fixP
->fx_size
);
641 fixP
->fx_addnumber
= *valT
;
647 /* Tables for lexical analysis. */
648 static char mnemonic_chars
[256];
649 static char register_chars
[256];
650 static char operand_chars
[256];
651 static char identifier_chars
[256];
652 static char digit_chars
[256];
654 /* Lexical Macros. */
655 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
656 #define is_register_char(x) (register_chars[(unsigned char)(x)])
657 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
658 #define is_space_char(x) (x==' ')
659 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
660 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
662 /* Special characters for operands. */
663 static char operand_special_chars
[] = "[]@.-+";
665 /* md_assemble() will always leave the instruction passed to it unaltered.
666 To do this we store the instruction in a special stack. */
667 static char save_stack
[32];
668 static char *save_stack_p
;
670 #define END_STRING_AND_SAVE(s) \
673 *save_stack_p++ = *(s); \
678 #define RESTORE_END_STRING(s) \
681 *(s) = *(--save_stack_p); \
685 /* The instruction we are assembling. */
686 static maxq20_insn i
;
688 /* The current template. */
689 static MAXQ20_OPCODES
*current_templates
;
691 /* The displacement operand if any. */
692 static expressionS disp_expressions
;
694 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
695 static int this_operand
;
697 /* The prefix instruction if used. */
698 static char PFX_INSN
[2];
699 static char INSERT_BUFFER
[2];
701 /* For interface with expression() ????? */
702 extern char *input_line_pointer
;
704 /* The HASH Tables: */
706 /* Operand Hash Table. */
707 static struct hash_control
*op_hash
;
709 /* Register Hash Table. */
710 static struct hash_control
*reg_hash
;
712 /* Memory reference Hash Table. */
713 static struct hash_control
*mem_hash
;
715 /* Bit hash table. */
716 static struct hash_control
*bit_hash
;
718 /* Memory Access syntax table. */
719 static struct hash_control
*mem_syntax_hash
;
721 /* This is a mapping from pseudo-op names to functions. */
723 const pseudo_typeS md_pseudo_table
[] =
725 {"int", cons
, 2}, /* size of 'int' has been changed to 1 word
727 {"maxq10", maxq_target
, bfd_mach_maxq10
},
728 {"maxq20", maxq_target
, bfd_mach_maxq20
},
732 #if defined(BFD_HEADERS)
734 const int md_reloc_size
= RELSZ
; /* Coff headers. */
736 const int md_reloc_size
= 12; /* Something else headers. */
739 const int md_reloc_size
= 12; /* Not bfdized. */
742 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
745 /* This function sets the PFX value coresponding to the specs. Source
746 Destination Index Selection ---------------------------------- Write To|
747 SourceRegRange | Dest Addr Range
748 ------------------------------------------------------ PFX[0] | 0h-Fh |
749 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
750 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
751 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
756 short int src_index
= 0, dst_index
= 0;
760 if (i
.operands
== 1) /* Only SRC is Present */
762 if (i
.types
[0] == REG
)
764 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
766 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
771 src_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
779 if (i
.types
[0] == REG
&& i
.types
[1] == REG
)
781 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
782 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
784 else if (i
.types
[0] != REG
&& i
.types
[1] == REG
) /* DST is Absent */
786 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
789 else if (i
.types
[0] == REG
&& i
.types
[1] != REG
) /* Id SRC is Absent */
791 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
794 else if (i
.types
[0] == BIT
&& i
.maxq20_op
[0].r_bit
)
796 dst_index
= i
.maxq20_op
[0].r_bit
->reg
->Mod_index
;
800 else if (i
.types
[1] == BIT
&& i
.maxq20_op
[1].r_bit
)
803 src_index
= i
.maxq20_op
[1].r_bit
->reg
->Mod_index
;
807 if (src_index
>= 0x00 && src_index
<= 0xF)
809 if (dst_index
>= 0x00 && dst_index
<= 0x07)
813 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
817 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
821 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
825 else if (src_index
>= 0x10 && src_index
<= 0x1F)
827 if (dst_index
>= 0x00 && dst_index
<= 0x07)
831 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
835 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
839 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
846 is_a_LSinstr (const char *ln_pointer
)
850 for (i
= 0; LSInstr
[i
] != NULL
; i
++)
851 if (!strcmp (LSInstr
[i
], ln_pointer
))
858 LS_processing (const char *line
)
860 if (is_a_LSinstr (line
))
862 if ((line
[0] == 'L') || (line
[0] == 'l'))
865 INSERT_BUFFER
[0] = PFX0
;
866 i
.Instr_Prefix
= LONG_PREFIX
;
868 else if ((line
[0] == 'S') || (line
[0] == 's'))
869 i
.Instr_Prefix
= SHORT_PREFIX
;
871 i
.Instr_Prefix
= NO_PREFIX
;
874 i
.Instr_Prefix
= LONG_PREFIX
;
877 /* Separate mnemonics and the operands. */
880 parse_insn (char *line
, char *mnemonic
)
883 char *token_start
= l
;
885 char temp
[MAX_MNEM_SIZE
];
888 memset (temp
, END_OF_INSN
, MAX_MNEM_SIZE
);
891 while ((*mnem_p
= mnemonic_chars
[(unsigned char) *l
]) != 0)
895 if (mnem_p
>= mnemonic
+ MAX_MNEM_SIZE
)
897 as_bad (_("no such instruction: `%s'"), token_start
);
903 if (!is_space_char (*l
) && *l
!= END_OF_INSN
)
905 as_bad (_("invalid character %s in mnemonic"), l
);
911 temp
[ii
- 1] = toupper ((char) mnemonic
[ii
- 1]);
915 LS_processing (temp
);
917 if (i
.Instr_Prefix
!= 0 && is_a_LSinstr (temp
))
918 /* Skip the optional L-S. */
919 memcpy (temp
, temp
+ 1, MAX_MNEM_SIZE
);
921 /* Look up instruction (or prefix) via hash table. */
922 current_templates
= (MAXQ20_OPCODES
*) hash_find (op_hash
, temp
);
924 if (current_templates
!= NULL
)
927 as_bad (_("no such instruction: `%s'"), token_start
);
931 /* Function to calculate x to the power of y.
932 Just to avoid including the math libraries. */
939 for (k
= 0; k
< y
; k
++)
946 parse_reg_by_index (char *imm_start
)
948 int k
= 0, mid
= 0, rid
= 0, val
= 0, j
= 0;
949 char temp
[4] = { 0 };
950 reg_entry
*reg
= NULL
;
954 if (isdigit (imm_start
[k
]))
955 temp
[k
] = imm_start
[k
] - '0';
957 else if (isalpha (imm_start
[k
])
958 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
959 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
961 else if (imm_start
[k
] == 'h')
964 else if (imm_start
[k
] == END_OF_INSN
)
971 return NULL
; /* not a hex digit */
975 while (imm_start
[k
] != '\n');
977 switch (imm_start
[k
])
980 for (j
= 0; j
< k
; j
++)
981 val
+= temp
[j
] * pwr (16, k
- j
- 1);
985 for (j
= 0; j
< k
; j
++)
988 return NULL
; /* not a number */
990 val
+= temp
[j
] * pwr (10, k
- j
- 1);
995 /* Get the module and register id's. */
997 rid
= (val
>> 4) & 0x0f;
1001 /* Search the pheripheral reg table. */
1002 for (j
= 0; j
< num_of_reg
; j
++)
1004 if (new_reg_table
[j
].opcode
== val
)
1006 reg
= (reg_entry
*) & new_reg_table
[j
];
1014 /* Search the system register table. */
1017 while (system_reg_table
[j
].reg_name
!= NULL
)
1019 if (system_reg_table
[j
].opcode
== val
)
1021 reg
= (reg_entry
*) & system_reg_table
[j
];
1030 as_bad (_("Invalid register value %s"), imm_start
);
1035 if (this_operand
== 0 && reg
!= NULL
)
1037 if (reg
->Mod_index
> 7)
1043 return (reg_entry
*) reg
;
1046 /* REG_STRING starts *before* REGISTER_PREFIX. */
1049 parse_register (char *reg_string
, char **end_op
)
1051 char *s
= reg_string
;
1053 char reg_name_given
[MAX_REG_NAME_SIZE
+ 1];
1054 reg_entry
*r
= NULL
;
1059 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1060 if (is_space_char (*s
))
1064 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1066 if (p
>= reg_name_given
+ MAX_REG_NAME_SIZE
)
1067 return (reg_entry
*) NULL
;
1073 r
= (reg_entry
*) hash_find (reg_hash
, reg_name_given
);
1076 if (this_operand
== 0 && r
!= NULL
)
1078 if (r
->Mod_index
> 7)
1088 parse_register_bit (char *reg_string
, char **end_op
)
1090 const char *s
= reg_string
;
1094 reg_entry
*r
= NULL
;
1096 char temp_bitname
[MAX_REG_NAME_SIZE
+ 2];
1097 char temp
[MAX_REG_NAME_SIZE
+ 1];
1099 memset (&temp
, '\0', (MAX_REG_NAME_SIZE
+ 1));
1100 memset (&temp_bitname
, '\0', (MAX_REG_NAME_SIZE
+ 2));
1105 rb
= xmalloc (sizeof (reg_bit
));
1106 rb
->reg
= xmalloc (sizeof (reg_entry
));
1109 /* For supporting bit names. */
1110 b
= (bit_name
*) hash_find (bit_hash
, reg_string
);
1114 *end_op
= reg_string
+ strlen (reg_string
);
1115 strcpy (temp_bitname
, b
->reg_bit
);
1119 if (strchr (s
, '.'))
1132 if ((r
= parse_register (temp
, end_op
)) == NULL
)
1140 if (isdigit ((char) *s
))
1142 else if (isalpha ((char) *s
))
1144 rb
->bit
= (char) *s
- 'a';
1148 as_bad (_("Invalid bit number : '%c'"), (char) *s
);
1154 diff
= strlen (temp_bitname
) - strlen (temp
) - 1;
1156 diff
= strlen (reg_string
) - strlen (temp
) - 1;
1158 if (*(s
+ diff
) != '\0')
1160 as_bad (_("Illegal character after operand '%s'"), reg_string
);
1168 pfx_for_imm_val (int arg
)
1173 if (i
.prefix
== 0 && arg
== 0 && PFX_INSN
[1] == 0 && !(i
.data_operands
))
1176 if (!(i
.prefix
< 0) && !(i
.prefix
> 7))
1177 PFX_INSN
[0] = (i
.prefix
<< 4) | PFX0
;
1185 maxq20_immediate (char *imm_start
)
1187 int val
= 0, val_pfx
= 0;
1190 int temp
[4] = { 0 };
1194 if (imm_start
[1] == '\0' && (imm_start
[0] == '0' || imm_start
[0] == '1')
1195 && (this_operand
== 1 && ((i
.types
[0] == BIT
|| i
.types
[0] == FLAG
))))
1197 val
= imm_start
[0] - '0';
1198 i
.imm_bit_operands
++;
1199 i
.types
[this_operand
] = IMMBIT
;
1200 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1203 pfx_for_imm_val (0);
1208 /* Check For Sign Charcater. */
1213 if (imm_start
[k
] == '-' && k
== 0)
1216 else if (imm_start
[k
] == '+' && k
== 0)
1219 else if (isdigit (imm_start
[k
]))
1220 temp
[k
] = imm_start
[k
] - '0';
1222 else if (isalpha (imm_start
[k
])
1223 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
1224 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
1226 else if (imm_start
[k
] == 'h')
1229 else if (imm_start
[k
] == '\0')
1236 as_bad (_("Invalid Character in immediate Value : %c"),
1242 while (imm_start
[k
] != '\n');
1244 switch (imm_start
[k
])
1247 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1248 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1252 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1256 as_bad (_("Invalid Character in immediate value : %c"),
1260 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1267 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1268 check if we are moving a 16 bit immediate value into an 8 bit register.
1269 In that case we will generate a warning and move only the lower 8 bits */
1272 as_bad (_("Immediate value greater than 16 bits"));
1276 val
= val
* sign_val
;
1278 /* If it is a stack pointer and the value is greater than the maximum
1280 if (this_operand
== 1)
1282 if ((val
* sign_val
) > MAX_STACK
&& i
.types
[0] == REG
1283 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
1286 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1287 val
= val
& MAX_STACK
;
1290 /* Check the range for 8 bit registers. */
1291 else if (((val
* sign_val
) > 0xFF) && (i
.types
[0] == REG
)
1292 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1295 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1299 else if (((sign_val
== -1) || (val
> 0xFF)) && (i
.types
[0] == REG
)
1300 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1303 val
= ((val
) & 0x00ff);
1304 SET_PFX_ARG (val_pfx
);
1305 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1308 else if ((val
<= 0xff) && (i
.types
[0] == REG
)
1309 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1310 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1313 /* Check for 16 bit registers. */
1314 else if (((sign_val
== -1) || val
> 0xFE) && i
.types
[0] == REG
1315 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1317 /* Add PFX for any negative value -> 16bit register. */
1319 val
= ((val
) & 0x00ff);
1320 SET_PFX_ARG (val_pfx
);
1321 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1324 else if (val
< 0xFF && i
.types
[0] == REG
1325 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1327 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1330 /* All the immediate memory access - no PFX. */
1331 else if (i
.types
[0] == MEM
)
1333 if ((sign_val
== -1) || val
> 0xFE)
1336 val
= ((val
) & 0x00ff);
1337 SET_PFX_ARG (val_pfx
);
1338 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1341 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1344 /* Special handling for immediate jumps like jump nz, #03h etc. */
1345 else if (val
< 0xFF && i
.types
[0] == FLAG
)
1346 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1348 else if ((((sign_val
== -1) || val
> 0xFE)) && i
.types
[0] == FLAG
)
1351 val
= ((val
) & 0x00ff);
1352 SET_PFX_ARG (val_pfx
);
1353 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1357 as_bad (_("Invalid immediate move operation"));
1363 /* All the instruction with operation on ACC: like ADD src, etc. */
1364 if ((sign_val
== -1) || val
> 0xFE)
1367 val
= ((val
) & 0x00ff);
1368 SET_PFX_ARG (val_pfx
);
1369 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1372 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1380 extract_int_val (const char *imm_start
)
1392 if (imm_start
[k
] == '-' && k
== 0)
1395 else if (imm_start
[k
] == '+' && k
== 0)
1398 else if (isdigit (imm_start
[k
]))
1399 temp
[k
] = imm_start
[k
] - '0';
1401 else if (isalpha (imm_start
[k
]) && (tolower (imm_start
[k
])) < 'g')
1402 temp
[k
] = 10 + (int) (tolower (imm_start
[k
]) - 'a');
1404 else if (tolower (imm_start
[k
]) == 'h')
1407 else if ((imm_start
[k
] == '\0') || (imm_start
[k
] == ']'))
1408 /* imm_start[k]='d'; */
1413 as_bad (_("Invalid Character in immediate Value : %c"),
1419 while (imm_start
[k
] != '\n');
1421 switch (imm_start
[k
])
1424 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1425 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1429 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1433 as_bad (_("Invalid Character in immediate value : %c"),
1437 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1444 return val
* sign_val
;
1448 check_for_parse (const char *line
)
1452 if (*(line
+ 1) == '[')
1457 if ((*line
== '-') || (*line
== '+'))
1460 while (!is_space_char (*line
));
1462 if ((*line
== '-') || (*line
== '+'))
1463 val
= extract_int_val (line
);
1465 val
= extract_int_val (line
+ 1);
1467 INSERT_BUFFER
[0] = 0x3E;
1468 INSERT_BUFFER
[1] = val
;
1477 maxq20_mem_access (char *mem_string
, char **end_op
)
1479 char *s
= mem_string
;
1481 char mem_name_given
[MAX_MEM_NAME_SIZE
+ 1];
1486 /* Skip possible whitespace. */
1487 if (is_space_char (*s
))
1491 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1493 if (p
>= mem_name_given
+ MAX_MEM_NAME_SIZE
)
1494 return (mem_access
*) NULL
;
1500 m
= (mem_access
*) hash_find (mem_hash
, mem_name_given
);
1505 /* This function checks whether the operand is a variable in the data segment
1506 and if so, it returns its symbol entry from the symbol table. */
1509 maxq20_data (char *op_string
)
1512 symbolP
= symbol_find (op_string
);
1515 && S_GET_SEGMENT (symbolP
) != now_seg
1516 && S_GET_SEGMENT (symbolP
) !=
1517 #ifdef BFD_ASSEMBLER
1526 #ifdef BFD_ASSEMBLER
1529 val_pfx
= (symbolP
->sy_value
.X_add_number
) >> 8;
1532 /* In case we do not want to always include the prefix instruction and
1533 let the loader handle the job or in case of a 8 bit addressing mode,
1534 we will just check for val_pfx to be equal to zero and then load the
1535 prefix instruction. Otherwise no prefix instruction needs to be
1537 /* The prefix register will have to be loaded automatically as we have
1538 a 16 bit addressing field. */
1539 pfx_for_imm_val (val_pfx
);
1547 maxq20_displacement (char *disp_start
, char *disp_end
)
1551 char *save_input_line_pointer
;
1553 char *gotfree_input_line
;
1556 gotfree_input_line
= NULL
;
1557 exp
= &disp_expressions
;
1558 i
.maxq20_op
[this_operand
].disps
= exp
;
1560 save_input_line_pointer
= input_line_pointer
;
1561 input_line_pointer
= disp_start
;
1563 END_STRING_AND_SAVE (disp_end
);
1566 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1567 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1569 exp_seg
= expression (exp
);
1572 if (*input_line_pointer
)
1573 as_bad (_("junk `%s' after expression"), input_line_pointer
);
1575 RESTORE_END_STRING (disp_end
+ 1);
1577 RESTORE_END_STRING (disp_end
);
1578 input_line_pointer
= save_input_line_pointer
;
1580 if (gotfree_input_line
)
1581 free (gotfree_input_line
);
1583 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1585 /* Missing or bad expr becomes absolute 0. */
1586 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1588 exp
->X_op
= O_constant
;
1589 exp
->X_add_number
= 0;
1590 exp
->X_add_symbol
= (symbolS
*) 0;
1591 exp
->X_op_symbol
= (symbolS
*) 0;
1593 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1595 if (exp
->X_op
!= O_constant
1596 #ifdef BFD_ASSEMBLER
1597 && OUTPUT_FLAVOR
== bfd_target_aout_flavour
1599 && exp_seg
!= absolute_section
1600 && exp_seg
!= text_section
1601 && exp_seg
!= data_section
1602 && exp_seg
!= bss_section
&& exp_seg
!= undefined_section
1603 #ifdef BFD_ASSEMBLER
1604 && !bfd_is_com_section (exp_seg
)
1608 #ifdef BFD_ASSEMBLER
1609 as_bad (_("unimplemented segment %s in operand"), exp_seg
->name
);
1611 as_bad (_("unimplemented segment type %d in operand"), exp_seg
);
1616 i
.maxq20_op
[this_operand
].disps
= exp
;
1620 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1621 Returns non-zero on error. */
1624 maxq20_operand (char *operand_string
)
1626 reg_entry
*r
= NULL
;
1628 mem_access
*m
= NULL
;
1629 char *end_op
= NULL
;
1630 symbolS
*sym
= NULL
;
1631 char *base_string
= NULL
;
1633 /* Start and end of displacement string expression (if found). */
1634 char *displacement_string_start
= NULL
;
1635 char *displacement_string_end
= NULL
;
1636 /* This maintains the case sentivness. */
1637 char case_str_op_string
[MAX_OPERAND_SIZE
+ 1];
1638 char str_op_string
[MAX_OPERAND_SIZE
+ 1];
1639 char *org_case_op_string
= case_str_op_string
;
1640 char *op_string
= str_op_string
;
1643 memset (op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1644 memset (org_case_op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1646 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1647 memcpy (org_case_op_string
, operand_string
, strlen (operand_string
) + 1);
1649 ii
= strlen (operand_string
) + 1;
1651 if (ii
> MAX_OPERAND_SIZE
)
1653 as_bad (_("Size of Operand '%s' greater than %d"), op_string
,
1660 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1664 if (is_space_char (*op_string
))
1667 if (isxdigit (operand_string
[0]))
1669 /* Now the operands can start with an Integer. */
1670 r
= parse_reg_by_index (op_string
);
1673 if (is_space_char (*op_string
))
1675 i
.types
[this_operand
] = REG
; /* Set the type. */
1676 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1681 /* Get the origanal string. */
1682 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1683 ii
= strlen (operand_string
) + 1;
1687 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1692 /* Check for flags. */
1693 if (!strcmp (op_string
, "Z"))
1695 if (is_space_char (*op_string
))
1698 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1699 i
.maxq20_op
[this_operand
].flag
= FLAG_Z
; /* Set the Register value. */
1706 else if (!strcmp (op_string
, "NZ"))
1708 if (is_space_char (*op_string
))
1711 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1712 i
.maxq20_op
[this_operand
].flag
= FLAG_NZ
; /* Set the Register value. */
1717 else if (!strcmp (op_string
, "NC"))
1719 if (is_space_char (*op_string
))
1722 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1723 i
.maxq20_op
[this_operand
].flag
= FLAG_NC
; /* Set the Register value. */
1728 else if (!strcmp (op_string
, "E"))
1730 if (is_space_char (*op_string
))
1733 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1734 i
.maxq20_op
[this_operand
].flag
= FLAG_E
; /* Set the Register value. */
1741 else if (!strcmp (op_string
, "S"))
1743 if (is_space_char (*op_string
))
1746 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1747 i
.maxq20_op
[this_operand
].flag
= FLAG_S
; /* Set the Register value. */
1754 else if (!strcmp (op_string
, "C"))
1756 if (is_space_char (*op_string
))
1759 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1760 i
.maxq20_op
[this_operand
].flag
= FLAG_C
; /* Set the Register value. */
1767 else if (!strcmp (op_string
, "NE"))
1770 if (is_space_char (*op_string
))
1773 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1775 i
.maxq20_op
[this_operand
].flag
= FLAG_NE
; /* Set the Register value. */
1782 /* CHECK FOR REGISTER BIT */
1783 else if ((rb
= parse_register_bit (op_string
, &end_op
)) != NULL
)
1787 if (is_space_char (*op_string
))
1790 i
.types
[this_operand
] = BIT
;
1792 i
.maxq20_op
[this_operand
].r_bit
= rb
;
1799 else if (*op_string
== IMMEDIATE_PREFIX
) /* FOR IMMEDITE. */
1801 if (is_space_char (*op_string
))
1804 i
.types
[this_operand
] = IMM
;
1806 if (!maxq20_immediate (op_string
))
1808 as_bad (_("illegal immediate operand '%s'"), op_string
);
1814 else if (*op_string
== ABSOLUTE_PREFIX
|| !strcmp (op_string
, "NUL"))
1816 if (is_space_char (*op_string
))
1819 /* For new requiremnt of copiler of for, @(BP,cons). */
1820 if (check_for_parse (op_string
))
1822 memset (op_string
, '\0', strlen (op_string
) + 1);
1823 memcpy (op_string
, "@BP[OFFS]\0", 11);
1826 i
.types
[this_operand
] = MEM
;
1828 if ((m
= maxq20_mem_access (op_string
, &end_op
)) == NULL
)
1830 as_bad (_("Invalid operand for memory access '%s'"), op_string
);
1833 i
.maxq20_op
[this_operand
].mem
= m
;
1840 else if ((r
= parse_register (op_string
, &end_op
)) != NULL
) /* Check for register. */
1844 if (is_space_char (*op_string
))
1847 i
.types
[this_operand
] = REG
; /* Set the type. */
1848 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1853 if (this_operand
== 1)
1855 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1856 /* The operand can either be a data reference or a symbol reference. */
1857 if ((sym
= maxq20_data (org_case_op_string
)) != NULL
) /* Check for data memory. */
1859 while (is_space_char (*op_string
))
1862 /* Set the type of the operand. */
1863 i
.types
[this_operand
] = DATA
;
1865 /* Set the value of the data. */
1866 i
.maxq20_op
[this_operand
].data
= sym
;
1872 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1874 /* This is a memory reference of some sort. char *base_string;
1875 Start and end of displacement string expression (if found). char
1876 *displacement_string_start; char *displacement_string_end. */
1877 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1880 if (is_space_char (*base_string
))
1883 /* If we only have a displacement, set-up for it to be parsed
1885 displacement_string_start
= org_case_op_string
;
1886 displacement_string_end
= base_string
+ 1;
1887 if (displacement_string_start
!= displacement_string_end
)
1889 if (!maxq20_displacement (displacement_string_start
,
1890 displacement_string_end
))
1892 as_bad (_("illegal displacement operand "));
1895 /* A displacement operand found. */
1896 i
.types
[this_operand
] = DISP
; /* Set the type. */
1902 /* Check for displacement. */
1903 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1905 /* This is a memory reference of some sort. char *base_string;
1906 Start and end of displacement string expression (if found). char
1907 *displacement_string_start; char *displacement_string_end; */
1908 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1911 if (is_space_char (*base_string
))
1914 /* If we only have a displacement, set-up for it to be parsed later. */
1915 displacement_string_start
= org_case_op_string
;
1916 displacement_string_end
= base_string
+ 1;
1917 if (displacement_string_start
!= displacement_string_end
)
1919 if (!maxq20_displacement (displacement_string_start
,
1920 displacement_string_end
))
1922 /* A displacement operand found. */
1923 i
.types
[this_operand
] = DISP
; /* Set the type. */
1929 /* Parse_operand takes as input instruction and operands and Parse operands
1930 and makes entry in the template. */
1933 parse_operands (char *l
, const char *mnemonic
)
1937 /* 1 if operand is pending after ','. */
1938 short int expecting_operand
= 0;
1940 /* Non-zero if operand parens not balanced. */
1941 short int paren_not_balanced
;
1945 /* For Overcoming Warning of unused variable. */
1949 while (*l
!= END_OF_INSN
)
1951 /* Skip optional white space before operand. */
1952 if (is_space_char (*l
))
1955 if (!is_operand_char (*l
) && *l
!= END_OF_INSN
)
1957 as_bad (_("invalid character %c before operand %d"),
1958 (char) (*l
), i
.operands
+ 1);
1963 paren_not_balanced
= 0;
1964 while (paren_not_balanced
|| *l
!= ',')
1966 if (*l
== END_OF_INSN
)
1968 if (paren_not_balanced
)
1970 as_bad (_("unbalanced brackets in operand %d."),
1977 else if (!is_operand_char (*l
) && !is_space_char (*l
))
1979 as_bad (_("invalid character %c in operand %d"),
1980 (char) (*l
), i
.operands
+ 1);
1984 ++paren_not_balanced
;
1986 --paren_not_balanced
;
1990 if (l
!= token_start
)
1992 /* Yes, we've read in another operand. */
1993 this_operand
= i
.operands
++;
1994 if (i
.operands
> MAX_OPERANDS
)
1996 as_bad (_("spurious operands; (%d operands/instruction max)"),
2001 /* Now parse operand adding info to 'i' as we go along. */
2002 END_STRING_AND_SAVE (l
);
2004 operand_ok
= maxq20_operand (token_start
);
2006 RESTORE_END_STRING (l
);
2013 if (expecting_operand
)
2015 expecting_operand_after_comma
:
2016 as_bad (_("expecting operand after ','; got nothing"));
2023 if (*(++l
) == END_OF_INSN
)
2024 /* Just skip it, if it's \n complain. */
2025 goto expecting_operand_after_comma
;
2027 expecting_operand
= 1;
2035 match_operands (int type
, MAX_ARG_TYPE flag_type
, MAX_ARG_TYPE arg_type
,
2041 if ((arg_type
& A_REG
) == A_REG
)
2045 if ((arg_type
& A_IMM
) == A_IMM
)
2049 if ((arg_type
& A_BIT_0
) == A_BIT_0
&& (i
.maxq20_op
[op_num
].imms
== 0))
2051 else if ((arg_type
& A_BIT_1
) == A_BIT_1
2052 && (i
.maxq20_op
[op_num
].imms
== 1))
2056 if ((arg_type
& A_MEM
) == A_MEM
)
2061 if ((arg_type
& flag_type
) == flag_type
)
2067 if ((arg_type
& ACC_BIT
) == ACC_BIT
&& !strcmp (i
.maxq20_op
[op_num
].r_bit
->reg
->reg_name
, "ACC"))
2069 else if ((arg_type
& SRC_BIT
) == SRC_BIT
&& (op_num
== 1))
2071 else if ((op_num
== 0) && (arg_type
& DST_BIT
) == DST_BIT
)
2075 if ((arg_type
& A_DISP
) == A_DISP
)
2078 if ((arg_type
& A_DATA
) == A_DATA
)
2081 if ((arg_type
& A_BIT_BUCKET
) == A_BIT_BUCKET
)
2088 match_template (void)
2090 /* Points to template once we've found it. */
2091 const MAXQ20_OPCODE_INFO
*t
;
2095 for (t
= current_templates
->start
; t
< current_templates
->end
; t
++)
2097 /* Must have right number of operands. */
2098 if (i
.operands
!= t
->op_number
)
2100 else if (!t
->op_number
)
2106 if (!match_operands (i
.types
[1], i
.maxq20_op
[1].flag
, t
->arg
[1], 1))
2112 if (!match_operands (i
.types
[0], i
.maxq20_op
[0].flag
, t
->arg
[0], 0))
2121 if (t
== current_templates
->end
)
2123 /* We found no match. */
2124 as_bad (_("operand %d is invalid for `%s'"),
2125 inv_oper
, current_templates
->start
->name
);
2129 /* Copy the template we have found. */
2134 /* This function filters out the various combinations of operands which are
2135 not allowed for a particular instruction. */
2138 match_filters (void)
2140 /* Now we have at our disposal the instruction i. We will be using the
2141 following fields i.op.name : This is the mnemonic name. i.types[2] :
2142 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2143 i.maxq20_op[2] : This contains the specific info of the operands. */
2145 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2147 if (!strcmp (i
.op
.name
, "AND") || !strcmp (i
.op
.name
, "OR")
2148 || !strcmp (i
.op
.name
, "XOR") || !strcmp (i
.op
.name
, "ADD")
2149 || !strcmp (i
.op
.name
, "ADDC") || !strcmp (i
.op
.name
, "SUB")
2150 || !strcmp (i
.op
.name
, "SUBB"))
2152 if (i
.types
[0] == REG
)
2154 if (i
.maxq20_op
[0].reg
->Mod_name
== 0xa)
2157 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2163 if (!strcmp (i
.op
.name
, "MOVE") && (i
.types
[0] == MEM
|| i
.types
[1] == MEM
)
2166 mem_access_syntax
*mem_op
= NULL
;
2168 if (i
.types
[0] == MEM
)
2171 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2172 i
.maxq20_op
[0].mem
->name
);
2173 if ((mem_op
->type
== SRC
) && mem_op
)
2175 as_bad (_("'%s' operand cant be used as destination in %s"),
2176 mem_op
->name
, i
.op
.name
);
2179 else if ((mem_op
->invalid_op
!= NULL
) && (i
.types
[1] == MEM
)
2184 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2186 if (mem_op
->invalid_op
[k
] != NULL
)
2188 (mem_op
->invalid_op
[k
], i
.maxq20_op
[1].mem
->name
))
2191 ("Invalid Instruction '%s' operand cant be used with %s"),
2192 mem_op
->name
, i
.maxq20_op
[1].mem
->name
);
2199 if (i
.types
[1] == MEM
)
2203 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2204 i
.maxq20_op
[1].mem
->name
);
2205 if (mem_op
->type
== DST
&& mem_op
)
2207 as_bad (_("'%s' operand cant be used as source in %s"),
2208 mem_op
->name
, i
.op
.name
);
2211 else if (mem_op
->invalid_op
!= NULL
&& i
.types
[0] == MEM
&& mem_op
)
2215 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2217 if (mem_op
->invalid_op
[k
] != NULL
)
2219 (mem_op
->invalid_op
[k
], i
.maxq20_op
[0].mem
->name
))
2222 ("Invalid Instruction '%s' operand cant be used with %s"),
2223 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2228 else if (i
.types
[0] == REG
2229 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "OFFS")
2232 if (!strcmp (mem_op
->name
, "@BP[OFFS--]")
2233 || !strcmp (mem_op
->name
, "@BP[OFFS++]"))
2236 ("Invalid Instruction '%s' operand cant be used with %s"),
2237 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2244 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2245 on 10-March-2004. */
2246 if ((i
.types
[0] == MEM
) && (i
.operands
== 1)
2247 && !(!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI")))
2249 mem_access_syntax
*mem_op
= NULL
;
2251 if (i
.types
[0] == MEM
)
2254 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2255 i
.maxq20_op
[0].mem
->name
);
2256 if (mem_op
->type
== DST
&& mem_op
)
2258 as_bad (_("'%s' operand cant be used as source in %s"),
2259 mem_op
->name
, i
.op
.name
);
2265 if (i
.operands
== 2 && i
.types
[0] == IMM
)
2267 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2272 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2273 if (!strcmp (i
.op
.name
, "PUSH") || !strcmp (i
.op
.name
, "POP")
2274 || !strcmp (i
.op
.name
, "POPI"))
2276 if (i
.types
[0] == REG
)
2278 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
2280 as_bad (_("SP cannot be used with %s\n"), i
.op
.name
);
2284 else if (i
.types
[0] == MEM
2285 && !strcmp (i
.maxq20_op
[0].mem
->name
, "@SP--"))
2287 as_bad (_("@SP-- cannot be used with PUSH\n"));
2292 /* This filter checks that two memory references using DP's cannot be used
2293 together in an instruction */
2294 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 2)
2296 if (strlen (i
.maxq20_op
[0].mem
->name
) != 6 ||
2297 strcmp (i
.maxq20_op
[0].mem
->name
, i
.maxq20_op
[1].mem
->name
))
2299 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@DP", 3)
2300 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@DP", 3))
2303 ("Operands either contradictory or use the data bus in read/write state together"));
2307 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@SP", 3)
2308 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@SP", 3))
2311 ("Operands either contradictory or use the data bus in read/write state together"));
2315 if ((i
.maxq20_op
[1].mem
!= NULL
)
2316 && !strncmp (i
.maxq20_op
[1].mem
->name
, "NUL", 3))
2318 as_bad (_("MOVE Cant Use NUL as SRC"));
2323 /* This filter checks that contradictory movement between DP register and
2324 Memory access using DP followed by increment or decrement. */
2326 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 1
2327 && i
.reg_operands
== 1)
2331 memnum
= (i
.types
[0] == MEM
) ? 0 : 1;
2332 regnum
= (memnum
== 0) ? 1 : 0;
2333 if (!strncmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "DP", 2) &&
2334 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2335 i
.maxq20_op
[regnum
].reg
->reg_name
, 5)
2336 && strcmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2337 i
.maxq20_op
[regnum
].reg
->reg_name
))
2340 ("Contradictory movement between DP register and memory access using DP"));
2343 else if (!strcmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "SP") &&
2344 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2345 i
.maxq20_op
[regnum
].reg
->reg_name
, 2))
2348 ("SP and @SP-- cannot be used together in a move instruction"));
2353 /* This filter restricts the instructions containing source and destination
2354 bits to only CTRL module of the serial registers. Peripheral registers
2355 yet to be defined. */
2357 if (i
.bit_operands
== 1 && i
.operands
== 2)
2359 int bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2361 if (strcmp (i
.maxq20_op
[bitnum
].r_bit
->reg
->reg_name
, "ACC"))
2363 if (i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
>= 0x7 &&
2364 i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
!= CTRL
)
2367 ("Only Module 8 system registers allowed in this operation"));
2373 /* This filter is for checking the register bits. */
2374 if (i
.bit_operands
== 1 || i
.operands
== 2)
2376 int bitnum
= 0, size
= 0;
2378 bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2379 if (i
.bit_operands
== 1)
2381 switch (i
.maxq20_op
[bitnum
].r_bit
->reg
->rtype
)
2384 size
= 7; /* 8 bit register, both read and write. */
2393 as_fatal (_("Read only Register used as destination"));
2402 as_fatal (_("Read only Register used as destination"));
2408 if (size
< (i
.maxq20_op
[bitnum
].r_bit
)->bit
)
2410 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2411 (i
.maxq20_op
[bitnum
].r_bit
)->bit
);
2416 if (i
.bit_operands
== 2)
2418 switch ((i
.maxq20_op
[0].r_bit
)->reg
->rtype
)
2421 size
= 7; /* 8 bit register, both read and write. */
2428 as_fatal (_("Read only Register used as destination"));
2432 if (size
< (i
.maxq20_op
[0].r_bit
)->bit
)
2435 ("Bit No '%d' exceeds register size in this operation"),
2436 (i
.maxq20_op
[0].r_bit
)->bit
);
2441 switch ((i
.maxq20_op
[1].r_bit
)->reg
->rtype
)
2445 size
= 7; /* 8 bit register, both read and write. */
2453 if (size
< (i
.maxq20_op
[1].r_bit
)->bit
)
2456 ("Bit No '%d' exceeds register size in this operation"),
2457 (i
.maxq20_op
[1].r_bit
)->bit
);
2463 /* No branch operations should occur into the data memory. Hence any memory
2464 references have to be filtered out when used with instructions like
2465 jump, djnz[] and call. */
2467 if (!strcmp (i
.op
.name
, "JUMP") || !strcmp (i
.op
.name
, "CALL")
2468 || !strncmp (i
.op
.name
, "DJNZ", 4))
2472 ("Memory References cannot be used with branching operations\n"));
2475 if (!strcmp (i
.op
.name
, "DJNZ"))
2478 (strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2479 || strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))
2481 as_bad (_("DJNZ uses only LC[n] register \n"));
2486 /* No destination register used should be read only! */
2487 if ((i
.operands
== 2 && i
.types
[0] == REG
) || !strcmp (i
.op
.name
, "POP")
2488 || !strcmp (i
.op
.name
, "POPI"))
2489 { /* The destination is a register */
2492 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2496 if (i
.types
[regnum
] == MEM
)
2498 mem_access_syntax
*mem_op
= NULL
;
2501 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2502 i
.maxq20_op
[regnum
].mem
->
2504 if (mem_op
->type
== SRC
&& mem_op
)
2507 ("'%s' operand cant be used as destination in %s"),
2508 mem_op
->name
, i
.op
.name
);
2514 if (i
.maxq20_op
[regnum
].reg
->rtype
== Reg_8R
2515 || i
.maxq20_op
[regnum
].reg
->rtype
== Reg_16R
)
2517 as_bad (_("Read only register used for writing purposes '%s'"),
2518 i
.maxq20_op
[regnum
].reg
->reg_name
);
2523 /* While moving the address of a data in the data section, the destination
2524 should be either data pointers only. */
2525 if ((i
.data_operands
) && (i
.operands
== 2))
2527 if ((i
.types
[0] != REG
) && (i
.types
[0] != MEM
))
2529 as_bad (_("Invalid destination for this kind of source."));
2533 if (i
.types
[0] == REG
&& i
.maxq20_op
[0].reg
->rtype
== Reg_8W
)
2536 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2546 /* Check for the format Bit if defined. */
2547 if (i
.op
.format
== 0 || i
.op
.format
== 1)
2548 i
.instr
[0] = i
.op
.format
<< 7;
2551 /* Format bit not defined. We will have to be find it out ourselves. */
2552 if (i
.imm_operands
== 1 || i
.data_operands
== 1 || i
.disp_operands
== 1)
2556 i
.instr
[0] = i
.op
.format
<< 7;
2559 /* Now for the destination register. */
2561 /* If destination register is already defined . The conditions are the
2562 following: (1) The second entry in the destination array should be 0 (2)
2563 If there are two operands then the first entry should not be a register,
2564 memory or a register bit (3) If there are less than two operands and the
2565 it is not a pop operation (4) The second argument is the carry
2566 flag(applicable to move Acc.<b>,C. */
2567 if (i
.op
.dst
[1] == 0
2569 ((i
.types
[0] != REG
&& i
.types
[0] != MEM
&& i
.types
[0] != BIT
2570 && i
.operands
== 2) || (i
.operands
< 2 && strcmp (i
.op
.name
, "POP")
2571 && strcmp (i
.op
.name
, "POPI"))
2572 || (i
.op
.arg
[1] == FLAG_C
)))
2574 i
.op
.dst
[0] &= 0x7f;
2575 i
.instr
[0] |= i
.op
.dst
[0];
2577 else if (i
.op
.dst
[1] == 0 && !strcmp (i
.op
.name
, "DJNZ")
2579 (((i
.types
[0] == REG
)
2580 && (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2581 || !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))))
2583 i
.op
.dst
[0] &= 0x7f;
2584 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]"))
2587 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]"))
2594 /* Target register will have to be specified. */
2595 if (i
.types
[0] == REG
2596 && (i
.op
.dst
[0] == REG
|| i
.op
.dst
[0] == (REG
| MEM
)))
2598 temp
= (i
.maxq20_op
[0].reg
)->opcode
;
2602 else if (i
.types
[0] == MEM
&& (i
.op
.dst
[0] == (REG
| MEM
)))
2604 temp
= (i
.maxq20_op
[0].mem
)->opcode
;
2608 else if (i
.types
[0] == BIT
&& (i
.op
.dst
[0] == REG
))
2610 temp
= (i
.maxq20_op
[0].r_bit
)->reg
->opcode
;
2614 else if (i
.types
[1] == BIT
&& (i
.op
.dst
[0] == BIT
))
2616 temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2618 temp
|= i
.op
.dst
[1];
2624 as_bad (_("Invalid Instruction"));
2629 /* Now for the source register. */
2631 /* If Source register is already known. The following conditions are
2632 checked: (1) There are no operands (2) If there is only one operand and
2633 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2636 if (i
.operands
== 0 || (i
.operands
== 1 && i
.types
[0] == FLAG
)
2637 || (i
.types
[0] == FLAG
&& i
.types
[1] == IMMBIT
)
2638 || !strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2639 i
.instr
[1] = i
.op
.src
[0];
2641 else if (i
.imm_operands
== 1 && ((i
.op
.src
[0] & IMM
) == IMM
))
2642 i
.instr
[1] = i
.maxq20_op
[this_operand
].imms
;
2644 else if (i
.types
[this_operand
] == REG
&& ((i
.op
.src
[0] & REG
) == REG
))
2645 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].reg
)->opcode
);
2647 else if (i
.types
[this_operand
] == BIT
&& ((i
.op
.src
[0] & REG
) == REG
))
2648 i
.instr
[1] = (char) (i
.maxq20_op
[this_operand
].r_bit
->reg
->opcode
);
2650 else if (i
.types
[this_operand
] == MEM
&& ((i
.op
.src
[0] & MEM
) == MEM
))
2651 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].mem
)->opcode
);
2653 else if (i
.types
[this_operand
] == DATA
&& ((i
.op
.src
[0] & DATA
) == DATA
))
2654 /* This will copy only the lower order bytes into the instruction. The
2655 higher order bytes have already been copied into the prefix register. */
2658 /* Decoding the source in the case when the second array entry is not 0.
2659 This means that the source register has been divided into two nibbles. */
2661 else if (i
.op
.src
[1] != 0)
2663 /* If the first operand is a accumulator bit then
2664 the first 4 bits will be filled with the bit number. */
2665 if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & BIT
) == BIT
))
2667 unsigned char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2670 temp
|= i
.op
.src
[1];
2673 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2674 has to start with a zero. This is called a ZEROBIT */
2675 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ZEROBIT
) == ZEROBIT
))
2677 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2680 temp
|= i
.op
.src
[1];
2684 /* Similarly for a ONEBIT */
2685 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ONEBIT
) == ONEBIT
))
2687 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2690 temp
|= i
.op
.src
[1];
2694 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2696 else if (i
.types
[1] == BIT
)
2698 if (i
.op
.src
[1] == 0 && i
.op
.src
[1] == REG
)
2699 i
.instr
[1] = (i
.maxq20_op
[1].r_bit
)->reg
->opcode
;
2701 else if (i
.op
.src
[0] == BIT
&& i
.op
.src
)
2703 char temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2706 temp
|= i
.op
.src
[1];
2712 as_bad (_("Invalid Instruction"));
2719 /* This is a function for outputting displacement operands. */
2722 output_disp (fragS
*insn_start_frag
, offsetT insn_start_off
)
2725 relax_substateT subtype
;
2731 insn_start_frag
= frag_now
;
2732 insn_start_off
= frag_now_fix ();
2734 switch (i
.Instr_Prefix
)
2737 subtype
= EXPLICT_LONG_PREFIX
;
2740 subtype
= SHORT_PREFIX
;
2743 subtype
= NO_PREFIX
;
2747 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2748 case there is no need for relaxation. But we do need support for a
2749 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2750 for prefix + 2 for the current instruction ) Hence if at a particular
2751 time we find out whether the prefix operator is reqd , we shift the
2752 current instruction two places ahead and insert the prefix instruction. */
2756 sym
= i
.maxq20_op
[this_operand
].disps
->X_add_symbol
;
2757 off
= i
.maxq20_op
[this_operand
].disps
->X_add_number
;
2759 if (i
.maxq20_op
[this_operand
].disps
->X_add_symbol
!= NULL
&& sym
&& frag_now
2760 && (subtype
!= EXPLICT_LONG_PREFIX
))
2762 /* If in the same frag. */
2763 if (frag_now
== symbol_get_frag (sym
))
2766 ((((expressionS
*) symbol_get_value_expression (sym
))->
2767 X_add_number
) - insn_start_off
);
2769 diff
= diff
/ MAXQ_OCTETS_PER_BYTE
;
2771 if (diff
>= -128 && diff
<= 127)
2773 i
.instr
[1] = (char) diff
;
2775 /* This will be overwritten later when the symbol is resolved. */
2777 *(p
+ 1) = i
.instr
[0];
2779 /* No Need to create a FIXUP. */
2785 /* This will be overwritten later when the symbol is resolved. */
2787 *(p
+ 1) = i
.instr
[0];
2789 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2790 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2792 /* Handle complex expressions. */
2793 sym
= make_expr_symbol (i
.maxq20_op
[this_operand
].disps
);
2797 /* Vineet : This has been added for md_estimate_size_before_relax to
2798 estimate the correct size. */
2799 if (subtype
!= SHORT_PREFIX
)
2800 i
.reloc
[this_operand
] = LONG_PREFIX
;
2802 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2805 /* This is a function for outputting displacement operands. */
2808 output_data (fragS
*insn_start_frag
, offsetT insn_start_off
)
2811 relax_substateT subtype
;
2818 insn_start_frag
= frag_now
;
2819 insn_start_off
= frag_now_fix ();
2821 subtype
= EXPLICT_LONG_PREFIX
;
2826 sym
= i
.maxq20_op
[this_operand
].data
;
2829 /* This will be overwritten later when the symbol is resolved. */
2831 *(p
+ 1) = i
.instr
[0];
2833 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2834 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2835 /* Handle complex expressions. */
2836 /* Because data is already in terms of symbol so no
2837 need to convert it from expression to symbol. */
2840 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2846 fragS
*insn_start_frag
;
2847 offsetT insn_start_off
;
2850 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2851 do this after the insn has been output as the current frag may have been
2852 closed off. eg. by frag_var. */
2853 dwarf2_emit_insn (0);
2855 /* To ALign the text section on word. */
2857 frag_align (1, 0, 1);
2859 /* We initialise the frags for this particular instruction. */
2860 insn_start_frag
= frag_now
;
2861 insn_start_off
= frag_now_fix ();
2863 /* If there are displacement operators(unresolved) present, then handle
2865 if (i
.disp_operands
)
2867 output_disp (insn_start_frag
, insn_start_off
);
2871 if (i
.data_operands
)
2873 output_data (insn_start_frag
, insn_start_off
);
2877 /* Check whether the INSERT_BUFFER has to be written. */
2878 if (strcmp (INSERT_BUFFER
, ""))
2882 *p
++ = INSERT_BUFFER
[1];
2883 *p
= INSERT_BUFFER
[0];
2886 /* Check whether the prefix instruction has to be written. */
2887 if (strcmp (PFX_INSN
, ""))
2896 /* For Little endian. */
2902 make_new_reg_table (void)
2904 unsigned long size_pm
= sizeof (peripheral_reg_table
);
2905 num_of_reg
= ARRAY_SIZE (peripheral_reg_table
);
2907 new_reg_table
= xmalloc (size_pm
);
2908 if (new_reg_table
== NULL
)
2909 as_bad (_("Cannot allocate memory"));
2911 memcpy (new_reg_table
, peripheral_reg_table
, size_pm
);
2914 /* pmmain performs the initilizations for the pheripheral modules. */
2919 make_new_reg_table ();
2926 const char *hash_err
= NULL
;
2929 const MAXQ20_OPCODE_INFO
*optab
;
2930 MAXQ20_OPCODES
*core_optab
; /* For opcodes of the same name. This will
2931 be inserted into the hash table. */
2932 struct reg
*reg_tab
;
2933 struct mem_access_syntax
const *memsyntab
;
2934 struct mem_access
*memtab
;
2935 struct bit_name
*bittab
;
2937 /* Initilize pherioipheral modules. */
2940 /* Initialise the opcode hash table. */
2941 op_hash
= hash_new ();
2943 optab
= op_table
; /* Initialise it to the first entry of the
2944 maxq20 operand table. */
2946 /* Setup for loop. */
2947 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2948 core_optab
->start
= optab
;
2953 if (optab
->name
== NULL
|| strcmp (optab
->name
, (optab
- 1)->name
) != 0)
2955 /* different name --> ship out current template list; add to hash
2956 table; & begin anew. */
2958 core_optab
->end
= optab
;
2960 if (max_version
== bfd_mach_maxq10
)
2962 if (((optab
- 1)->arch
== MAXQ10
) || ((optab
- 1)->arch
== MAX
))
2964 hash_err
= hash_insert (op_hash
,
2969 else if (max_version
== bfd_mach_maxq20
)
2971 if (((optab
- 1)->arch
== MAXQ20
) || ((optab
- 1)->arch
== MAX
))
2974 hash_err
= hash_insert (op_hash
,
2981 as_fatal (_("Internal Error: Illegal Architecure specified"));
2984 as_fatal (_("Internal Error: Can't hash %s: %s"),
2985 (optab
- 1)->name
, hash_err
);
2987 if (optab
->name
== NULL
)
2989 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2990 core_optab
->start
= optab
;
2994 /* Initialise a new register table. */
2995 reg_hash
= hash_new ();
2997 for (reg_tab
= system_reg_table
;
2998 reg_tab
< (system_reg_table
+ ARRAY_SIZE (system_reg_table
));
3002 switch (max_version
)
3004 case bfd_mach_maxq10
:
3005 if ((reg_tab
->arch
== MAXQ10
) || (reg_tab
->arch
== MAX
))
3006 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3009 case bfd_mach_maxq20
:
3010 if ((reg_tab
->arch
== MAXQ20
) || (reg_tab
->arch
== MAX
))
3014 hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3019 as_fatal (_("Invalid architecture type"));
3024 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3025 reg_tab
->reg_name
, hash_err
);
3028 /* Pheripheral Registers Entry. */
3029 for (reg_tab
= new_reg_table
;
3030 reg_tab
< (new_reg_table
+ num_of_reg
- 1); reg_tab
++)
3032 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3035 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3036 reg_tab
->reg_name
, hash_err
);
3039 /* Initialise a new memory operand table. */
3040 mem_hash
= hash_new ();
3042 for (memtab
= mem_table
;
3043 memtab
< mem_table
+ ARRAY_SIZE (mem_table
);
3046 hash_err
= hash_insert (mem_hash
, memtab
->name
, (PTR
) memtab
);
3048 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3049 memtab
->name
, hash_err
);
3052 bit_hash
= hash_new ();
3054 for (bittab
= bit_table
;
3055 bittab
< bit_table
+ ARRAY_SIZE (bit_table
);
3058 hash_err
= hash_insert (bit_hash
, bittab
->name
, (PTR
) bittab
);
3060 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3061 bittab
->name
, hash_err
);
3064 mem_syntax_hash
= hash_new ();
3066 for (memsyntab
= mem_access_syntax_table
;
3067 memsyntab
< mem_access_syntax_table
+ ARRAY_SIZE (mem_access_syntax_table
);
3071 hash_insert (mem_syntax_hash
, memsyntab
->name
, (PTR
) memsyntab
);
3073 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3074 memsyntab
->name
, hash_err
);
3077 /* Initialise the lexical tables,mnemonic chars,operand chars. */
3078 for (c
= 0; c
< 256; c
++)
3083 mnemonic_chars
[c
] = c
;
3084 operand_chars
[c
] = c
;
3085 register_chars
[c
] = c
;
3087 else if (ISLOWER (c
))
3089 mnemonic_chars
[c
] = c
;
3090 operand_chars
[c
] = c
;
3091 register_chars
[c
] = c
;
3093 else if (ISUPPER (c
))
3095 mnemonic_chars
[c
] = TOLOWER (c
);
3096 register_chars
[c
] = c
;
3097 operand_chars
[c
] = c
;
3100 if (ISALPHA (c
) || ISDIGIT (c
))
3102 identifier_chars
[c
] = c
;
3106 identifier_chars
[c
] = c
;
3107 operand_chars
[c
] = c
;
3111 /* All the special characters. */
3112 register_chars
['@'] = '@';
3113 register_chars
['+'] = '+';
3114 register_chars
['-'] = '-';
3115 digit_chars
['-'] = '-';
3116 identifier_chars
['_'] = '_';
3117 identifier_chars
['.'] = '.';
3118 register_chars
['['] = '[';
3119 register_chars
[']'] = ']';
3120 operand_chars
['_'] = '_';
3121 operand_chars
['#'] = '#';
3122 mnemonic_chars
['['] = '[';
3123 mnemonic_chars
[']'] = ']';
3125 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
3126 operand_chars
[(unsigned char) *p
] = (unsigned char) *p
;
3128 /* Set the maxq arch type. */
3129 maxq_target (max_version
);
3132 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3133 menmunonic in the operand table - Parse operands and populate the
3134 structure/template - Match the operand with opcode and its validity -
3138 md_assemble (char *line
)
3142 char mnemonic
[MAX_MNEM_SIZE
];
3143 char temp4prev
[256];
3144 static char prev_insn
[256];
3146 /* Initialize globals. */
3147 memset (&i
, '\0', sizeof (i
));
3148 for (j
= 0; j
< MAX_OPERANDS
; j
++)
3149 i
.reloc
[j
] = NO_RELOC
;
3154 INSERT_BUFFER
[0] = 0;
3155 INSERT_BUFFER
[1] = 0;
3157 memcpy (temp4prev
, line
, strlen (line
) + 1);
3159 save_stack_p
= save_stack
;
3161 line
= (char *) parse_insn (line
, mnemonic
);
3165 line
= (char *) parse_operands (line
, mnemonic
);
3169 /* Next, we find a template that matches the given insn, making sure the
3170 overlap of the given operands types is consistent with the template
3172 if (!match_template ())
3175 /* In the MAXQ20, there are certain register combinations, and other
3176 restrictions which are not allowed. We will try to resolve these right
3178 if (!match_filters ())
3181 /* Check for the approprate PFX register. */
3183 pfx_for_imm_val (0);
3185 if (!decode_insn ()) /* decode insn. */
3188 /* Check for Exlipct PFX instruction. */
3189 if (PFX_INSN
[0] && (strstr (prev_insn
, "PFX") || strstr (prev_insn
, "pfx")))
3190 as_warn (_("Ineffective insntruction %s \n"), prev_insn
);
3192 memcpy (prev_insn
, temp4prev
, strlen (temp4prev
) + 1);
3194 /* We are ready to output the insn. */