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
;
380 /* PC stores the value of the next instruction. */
381 diff
= (call_addr
- instr
) - 1;
383 if (diff
>= (-128 * 2) && diff
<= (2 * 127))
385 /* Now as offset is an 8 bit value, we will pass
386 that to the jump instruction directly. */
387 fragP
->fr_subtype
= NO_PREFIX
;
391 fragP
->fr_subtype
= LONG_PREFIX
;
395 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
400 /* Equal to MAX_PRECISION in atof-ieee.c */
401 #define MAX_LITTLENUMS 6
403 /* Turn a string in input_line_pointer into a floating point constant of type
404 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
405 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
408 md_atof (int type
, char * litP
, int * sizeP
)
411 LITTLENUM_TYPE words
[4];
423 /* The size of Double has been changed to 2 words ie 32 bits. */
429 return _("bad call to md_atof");
432 t
= atof_ieee (input_line_pointer
, type
, words
);
434 input_line_pointer
= t
;
438 for (i
= prec
- 1; i
>= 0; i
--)
440 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
448 maxq20_cons_fix_new (fragS
* frag
, unsigned int off
, unsigned int len
,
456 r
= MAXQ_WORDDATA
; /* Word+n */
459 r
= MAXQ_LONGDATA
; /* Long+n */
463 fix_new_exp (frag
, off
, len
, exp
, 0, r
);
468 tc_coff_fix2rtype (fixS
* fixP
)
470 return fixP
->fx_r_type
;
474 tc_coff_sizemachdep (fragS
*fragP
)
477 return (fragP
->fr_next
->fr_address
- fragP
->fr_address
);
482 /* GAS will call this for every rs_machine_dependent fragment. The
483 instruction is compleated using the data from the relaxation pass. It may
484 also create any necessary relocations. */
487 md_convert_frag (bfd
* headers ATTRIBUTE_UNUSED
,
488 segT seg ATTRIBUTE_UNUSED
,
492 md_convert_frag (object_headers
* headers ATTRIBUTE_UNUSED
,
493 segT sec ATTRIBUTE_UNUSED
,
497 unsigned char *opcode
;
498 offsetT target_address
;
499 offsetT opcode_address
;
500 offsetT displacement_from_opcode_start
;
503 opcode
= fragP
->fr_opcode
;
505 target_address
= opcode_address
= displacement_from_opcode_start
= 0;
508 (S_GET_VALUE (fragP
->fr_symbol
) / MAXQ_OCTETS_PER_BYTE
) +
509 (fragP
->fr_offset
/ MAXQ_OCTETS_PER_BYTE
);
512 (fragP
->fr_address
/ MAXQ_OCTETS_PER_BYTE
) +
513 ((fragP
->fr_fix
- 2) / MAXQ_OCTETS_PER_BYTE
);
515 /* PC points to the next Instruction. */
516 displacement_from_opcode_start
= ((target_address
- opcode_address
) - 1);
518 if ((displacement_from_opcode_start
>= -128
519 && displacement_from_opcode_start
<= 127)
520 && (fragP
->fr_subtype
== SHORT_PREFIX
521 || fragP
->fr_subtype
== NO_PREFIX
))
523 /* Its a displacement. */
524 char *p
= (char *) &opcode
[0];
526 *p
= (char) displacement_from_opcode_start
;
530 /* Its an absolute 16 bit jump. Now we have to
531 load the prefix operator with the upper 8 bits. */
532 if (fragP
->fr_subtype
== SHORT_PREFIX
)
534 as_bad (_("Cant make long jump/call into short jump/call : %d"),
539 /* Check whether the symbol has been resolved or not.
540 Otherwise we will have to generate a fixup. */
542 if (fragP
->fr_subtype
!= SHORT_PREFIX
)
544 RELOC_ENUM reloc_type
;
545 unsigned char *opcode
;
549 /* Now this is a basolute jump/call.
550 Hence we will have to create a fixup. */
551 if (fragP
->fr_subtype
== NO_PREFIX
)
552 fragP
->fr_subtype
= LONG_PREFIX
;
555 (fragP
->fr_subtype
? fragP
->fr_subtype
: LONG_PREFIX
);
559 old_fr_fix
= fragP
->fr_fix
;
560 opcode
= (unsigned char *) fragP
->fr_opcode
;
562 fragP
->fr_fix
+= (size
);
564 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
565 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
572 md_pcrel_from (fixS
*fixP
)
574 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
577 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
580 maxq_number_to_chars (char *buf
, valueT val
, int n
)
582 if (target_big_endian
)
583 number_to_chars_bigendian (buf
, val
, n
);
585 number_to_chars_littleendian (buf
, val
, n
);
588 /* GAS will call this for each fixup. It's main objective is to store the
589 correct value in the object file. 'fixup_segment' performs the generic
590 overflow check on the 'valueT *val' argument after md_apply_fix3 returns.
591 If the overflow check is relevant for the target machine, then
592 'md_apply_fix3' should modify 'valueT *val', typically to the value stored
593 in the object file (not to be done in MAXQ). */
596 md_apply_fix3 (fixS
*fixP
, valueT
*valT
, segT seg ATTRIBUTE_UNUSED
)
598 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
599 char *frag_to_fix_at
=
600 fixP
->fx_frag
->fr_literal
+ fixP
->fx_frag
->fr_fix
- 2;
604 if (fixP
->fx_frag
&& valT
)
606 /* If the relaxation substate is not defined we make it equal
607 to the kind of relocation the fixup is generated for. */
608 if (!fixP
->fx_frag
->fr_subtype
)
609 fixP
->fx_frag
->fr_subtype
= fixP
->fx_r_type
;
611 /* For any instruction in which either we have specified an
612 absolute address or it is a long jump we need to add a PFX0
613 instruction to it. In this case as the instruction has already
614 being written at 'fx_where' in the frag we copy it at the end of
615 the frag(which is where the relocation was generated) as when
616 the relocation is generated the frag is grown by 2 type, this is
617 where we copy the contents of fx_where and add a pfx0 at
619 if ((fixP
->fx_frag
->fr_subtype
== ABSOLUTE_ADDR_FOR_DATA
)
620 || (fixP
->fx_frag
->fr_subtype
== LONG_PREFIX
))
622 *(frag_to_fix_at
+ 1) = *(p
+ 1);
623 maxq_number_to_chars (p
+ 1, PFX0
, 1);
627 /* Remember value for tc_gen_reloc. */
628 fixP
->fx_addnumber
= *valT
;
632 /* This prob can be fixed by defining tc_fix_adjustable. */
633 #ifndef BFD_ASSEMBLER
634 if (fixP
->fx_addsy
&& S_GET_SEGMENT (fixP
->fx_addsy
))
635 segment_info
[S_GET_SEGMENT (fixP
->fx_addsy
)].dot
= NULL
;
638 /* Some fixups generated by GAS which gets resovled before this this
639 func. is called need to be wriiten to the frag as here we are going
640 to go away with the relocations fx_done=1. */
641 if (fixP
->fx_addsy
== NULL
)
643 maxq_number_to_chars (p
, *valT
, fixP
->fx_size
);
644 fixP
->fx_addnumber
= *valT
;
650 /* Tables for lexical analysis. */
651 static char mnemonic_chars
[256];
652 static char register_chars
[256];
653 static char operand_chars
[256];
654 static char identifier_chars
[256];
655 static char digit_chars
[256];
657 /* Lexical Macros. */
658 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
659 #define is_register_char(x) (register_chars[(unsigned char)(x)])
660 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
661 #define is_space_char(x) (x==' ')
662 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
663 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
665 /* Special characters for operands. */
666 static char operand_special_chars
[] = "[]@.-+";
668 /* md_assemble() will always leave the instruction passed to it unaltered.
669 To do this we store the instruction in a special stack. */
670 static char save_stack
[32];
671 static char *save_stack_p
;
673 #define END_STRING_AND_SAVE(s) \
676 *save_stack_p++ = *(s); \
681 #define RESTORE_END_STRING(s) \
684 *(s) = *(--save_stack_p); \
688 /* The instruction we are assembling. */
689 static maxq20_insn i
;
691 /* The current template. */
692 static MAXQ20_OPCODES
*current_templates
;
694 /* The displacement operand if any. */
695 static expressionS disp_expressions
;
697 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
698 static int this_operand
;
700 /* The prefix instruction if used. */
701 static char PFX_INSN
[2];
702 static char INSERT_BUFFER
[2];
704 /* For interface with expression() ????? */
705 extern char *input_line_pointer
;
707 /* The HASH Tables: */
709 /* Operand Hash Table. */
710 static struct hash_control
*op_hash
;
712 /* Register Hash Table. */
713 static struct hash_control
*reg_hash
;
715 /* Memory reference Hash Table. */
716 static struct hash_control
*mem_hash
;
718 /* Bit hash table. */
719 static struct hash_control
*bit_hash
;
721 /* Memory Access syntax table. */
722 static struct hash_control
*mem_syntax_hash
;
724 /* This is a mapping from pseudo-op names to functions. */
726 const pseudo_typeS md_pseudo_table
[] =
728 {"int", cons
, 2}, /* size of 'int' has been changed to 1 word
730 {"maxq10", maxq_target
, bfd_mach_maxq10
},
731 {"maxq20", maxq_target
, bfd_mach_maxq20
},
735 #if defined(BFD_HEADERS)
737 const int md_reloc_size
= RELSZ
; /* Coff headers. */
739 const int md_reloc_size
= 12; /* Something else headers. */
742 const int md_reloc_size
= 12; /* Not bfdized. */
745 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
748 /* This function sets the PFX value coresponding to the specs. Source
749 Destination Index Selection ---------------------------------- Write To|
750 SourceRegRange | Dest Addr Range
751 ------------------------------------------------------ PFX[0] | 0h-Fh |
752 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
753 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
754 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
759 short int src_index
= 0, dst_index
= 0;
763 if (i
.operands
== 1) /* Only SRC is Present */
765 if (i
.types
[0] == REG
)
767 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
769 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
774 src_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
782 if (i
.types
[0] == REG
&& i
.types
[1] == REG
)
784 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
785 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
787 else if (i
.types
[0] != REG
&& i
.types
[1] == REG
) /* DST is Absent */
789 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
792 else if (i
.types
[0] == REG
&& i
.types
[1] != REG
) /* Id SRC is Absent */
794 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
797 else if (i
.types
[0] == BIT
&& i
.maxq20_op
[0].r_bit
)
799 dst_index
= i
.maxq20_op
[0].r_bit
->reg
->Mod_index
;
803 else if (i
.types
[1] == BIT
&& i
.maxq20_op
[1].r_bit
)
806 src_index
= i
.maxq20_op
[1].r_bit
->reg
->Mod_index
;
810 if (src_index
>= 0x00 && src_index
<= 0xF)
812 if (dst_index
>= 0x00 && dst_index
<= 0x07)
816 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
820 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
824 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
828 else if (src_index
>= 0x10 && src_index
<= 0x1F)
830 if (dst_index
>= 0x00 && dst_index
<= 0x07)
834 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
838 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
842 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
849 is_a_LSinstr (const char *ln_pointer
)
853 for (i
= 0; LSInstr
[i
] != NULL
; i
++)
854 if (!strcmp (LSInstr
[i
], ln_pointer
))
861 LS_processing (const char *line
)
863 if (is_a_LSinstr (line
))
865 if ((line
[0] == 'L') || (line
[0] == 'l'))
868 INSERT_BUFFER
[0] = PFX0
;
869 i
.Instr_Prefix
= LONG_PREFIX
;
871 else if ((line
[0] == 'S') || (line
[0] == 's'))
872 i
.Instr_Prefix
= SHORT_PREFIX
;
874 i
.Instr_Prefix
= NO_PREFIX
;
877 i
.Instr_Prefix
= LONG_PREFIX
;
880 /* Separate mnemonics and the operands. */
883 parse_insn (char *line
, char *mnemonic
)
886 char *token_start
= l
;
888 char temp
[MAX_MNEM_SIZE
];
891 memset (temp
, END_OF_INSN
, MAX_MNEM_SIZE
);
894 while ((*mnem_p
= mnemonic_chars
[(unsigned char) *l
]) != 0)
898 if (mnem_p
>= mnemonic
+ MAX_MNEM_SIZE
)
900 as_bad (_("no such instruction: `%s'"), token_start
);
906 if (!is_space_char (*l
) && *l
!= END_OF_INSN
)
908 as_bad (_("invalid character %s in mnemonic"), l
);
914 temp
[ii
- 1] = toupper ((char) mnemonic
[ii
- 1]);
918 LS_processing (temp
);
920 if (i
.Instr_Prefix
!= 0 && is_a_LSinstr (temp
))
921 /* Skip the optional L-S. */
922 memcpy (temp
, temp
+ 1, MAX_MNEM_SIZE
);
924 /* Look up instruction (or prefix) via hash table. */
925 current_templates
= (MAXQ20_OPCODES
*) hash_find (op_hash
, temp
);
927 if (current_templates
!= NULL
)
930 as_bad (_("no such instruction: `%s'"), token_start
);
934 /* Function to calculate x to the power of y.
935 Just to avoid including the math libraries. */
942 for (k
= 0; k
< y
; k
++)
949 parse_reg_by_index (char *imm_start
)
951 int k
= 0, mid
= 0, rid
= 0, val
= 0, j
= 0;
952 char temp
[4] = { 0 };
953 reg_entry
*reg
= NULL
;
957 if (isdigit (imm_start
[k
]))
958 temp
[k
] = imm_start
[k
] - '0';
960 else if (isalpha (imm_start
[k
])
961 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
962 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
964 else if (imm_start
[k
] == 'h')
967 else if (imm_start
[k
] == END_OF_INSN
)
974 return NULL
; /* not a hex digit */
978 while (imm_start
[k
] != '\n');
980 switch (imm_start
[k
])
983 for (j
= 0; j
< k
; j
++)
984 val
+= temp
[j
] * pwr (16, k
- j
- 1);
988 for (j
= 0; j
< k
; j
++)
991 return NULL
; /* not a number */
993 val
+= temp
[j
] * pwr (10, k
- j
- 1);
998 /* Get the module and register id's. */
1000 rid
= (val
>> 4) & 0x0f;
1004 /* Search the pheripheral reg table. */
1005 for (j
= 0; j
< num_of_reg
; j
++)
1007 if (new_reg_table
[j
].opcode
== val
)
1009 reg
= (reg_entry
*) & new_reg_table
[j
];
1017 /* Search the system register table. */
1020 while (system_reg_table
[j
].reg_name
!= NULL
)
1022 if (system_reg_table
[j
].opcode
== val
)
1024 reg
= (reg_entry
*) & system_reg_table
[j
];
1033 as_bad (_("Invalid register value %s"), imm_start
);
1038 if (this_operand
== 0 && reg
!= NULL
)
1040 if (reg
->Mod_index
> 7)
1046 return (reg_entry
*) reg
;
1049 /* REG_STRING starts *before* REGISTER_PREFIX. */
1052 parse_register (char *reg_string
, char **end_op
)
1054 char *s
= reg_string
;
1056 char reg_name_given
[MAX_REG_NAME_SIZE
+ 1];
1057 reg_entry
*r
= NULL
;
1062 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1063 if (is_space_char (*s
))
1067 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1069 if (p
>= reg_name_given
+ MAX_REG_NAME_SIZE
)
1070 return (reg_entry
*) NULL
;
1076 r
= (reg_entry
*) hash_find (reg_hash
, reg_name_given
);
1079 if (this_operand
== 0 && r
!= NULL
)
1081 if (r
->Mod_index
> 7)
1091 parse_register_bit (char *reg_string
, char **end_op
)
1093 const char *s
= reg_string
;
1097 reg_entry
*r
= NULL
;
1099 char temp_bitname
[MAX_REG_NAME_SIZE
+ 2];
1100 char temp
[MAX_REG_NAME_SIZE
+ 1];
1102 memset (&temp
, '\0', (MAX_REG_NAME_SIZE
+ 1));
1103 memset (&temp_bitname
, '\0', (MAX_REG_NAME_SIZE
+ 2));
1108 rb
= xmalloc (sizeof (reg_bit
));
1109 rb
->reg
= xmalloc (sizeof (reg_entry
));
1112 /* For supporting bit names. */
1113 b
= (bit_name
*) hash_find (bit_hash
, reg_string
);
1117 *end_op
= reg_string
+ strlen (reg_string
);
1118 strcpy (temp_bitname
, b
->reg_bit
);
1122 if (strchr (s
, '.'))
1135 if ((r
= parse_register (temp
, end_op
)) == NULL
)
1143 if (isdigit ((char) *s
))
1145 else if (isalpha ((char) *s
))
1147 rb
->bit
= (char) *s
- 'a';
1151 as_bad (_("Invalid bit number : '%c'"), (char) *s
);
1157 diff
= strlen (temp_bitname
) - strlen (temp
) - 1;
1159 diff
= strlen (reg_string
) - strlen (temp
) - 1;
1161 if (*(s
+ diff
) != '\0')
1163 as_bad (_("Illegal character after operand '%s'"), reg_string
);
1171 pfx_for_imm_val (int arg
)
1176 if (i
.prefix
== 0 && arg
== 0 && PFX_INSN
[1] == 0 && !(i
.data_operands
))
1179 if (!(i
.prefix
< 0) && !(i
.prefix
> 7))
1180 PFX_INSN
[0] = (i
.prefix
<< 4) | PFX0
;
1188 maxq20_immediate (char *imm_start
)
1190 int val
= 0, val_pfx
= 0;
1193 int temp
[4] = { 0 };
1197 if (imm_start
[1] == '\0' && (imm_start
[0] == '0' || imm_start
[0] == '1')
1198 && (this_operand
== 1 && ((i
.types
[0] == BIT
|| i
.types
[0] == FLAG
))))
1200 val
= imm_start
[0] - '0';
1201 i
.imm_bit_operands
++;
1202 i
.types
[this_operand
] = IMMBIT
;
1203 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1206 pfx_for_imm_val (0);
1211 /* Check For Sign Charcater. */
1216 if (imm_start
[k
] == '-' && k
== 0)
1219 else if (imm_start
[k
] == '+' && k
== 0)
1222 else if (isdigit (imm_start
[k
]))
1223 temp
[k
] = imm_start
[k
] - '0';
1225 else if (isalpha (imm_start
[k
])
1226 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
1227 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
1229 else if (imm_start
[k
] == 'h')
1232 else if (imm_start
[k
] == '\0')
1239 as_bad (_("Invalid Character in immediate Value : %c"),
1245 while (imm_start
[k
] != '\n');
1247 switch (imm_start
[k
])
1250 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1251 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1255 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1259 as_bad (_("Invalid Character in immediate value : %c"),
1263 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1270 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1271 check if we are moving a 16 bit immediate value into an 8 bit register.
1272 In that case we will generate a warning and move only the lower 8 bits */
1275 as_bad (_("Immediate value greater than 16 bits"));
1279 val
= val
* sign_val
;
1281 /* If it is a stack pointer and the value is greater than the maximum
1283 if (this_operand
== 1)
1285 if ((val
* sign_val
) > MAX_STACK
&& i
.types
[0] == REG
1286 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
1289 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1290 val
= val
& MAX_STACK
;
1293 /* Check the range for 8 bit registers. */
1294 else if (((val
* sign_val
) > 0xFF) && (i
.types
[0] == REG
)
1295 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1298 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1302 else if (((sign_val
== -1) || (val
> 0xFF)) && (i
.types
[0] == REG
)
1303 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1306 val
= ((val
) & 0x00ff);
1307 SET_PFX_ARG (val_pfx
);
1308 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1311 else if ((val
<= 0xff) && (i
.types
[0] == REG
)
1312 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1313 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1316 /* Check for 16 bit registers. */
1317 else if (((sign_val
== -1) || val
> 0xFE) && i
.types
[0] == REG
1318 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1320 /* Add PFX for any negative value -> 16bit register. */
1322 val
= ((val
) & 0x00ff);
1323 SET_PFX_ARG (val_pfx
);
1324 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1327 else if (val
< 0xFF && i
.types
[0] == REG
1328 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1330 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1333 /* All the immediate memory access - no PFX. */
1334 else if (i
.types
[0] == MEM
)
1336 if ((sign_val
== -1) || val
> 0xFE)
1339 val
= ((val
) & 0x00ff);
1340 SET_PFX_ARG (val_pfx
);
1341 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1344 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1347 /* Special handling for immediate jumps like jump nz, #03h etc. */
1348 else if (val
< 0xFF && i
.types
[0] == FLAG
)
1349 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1351 else if ((((sign_val
== -1) || val
> 0xFE)) && i
.types
[0] == FLAG
)
1354 val
= ((val
) & 0x00ff);
1355 SET_PFX_ARG (val_pfx
);
1356 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1360 as_bad (_("Invalid immediate move operation"));
1366 /* All the instruction with operation on ACC: like ADD src, etc. */
1367 if ((sign_val
== -1) || val
> 0xFE)
1370 val
= ((val
) & 0x00ff);
1371 SET_PFX_ARG (val_pfx
);
1372 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1375 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1383 extract_int_val (const char *imm_start
)
1395 if (imm_start
[k
] == '-' && k
== 0)
1398 else if (imm_start
[k
] == '+' && k
== 0)
1401 else if (isdigit (imm_start
[k
]))
1402 temp
[k
] = imm_start
[k
] - '0';
1404 else if (isalpha (imm_start
[k
]) && (tolower (imm_start
[k
])) < 'g')
1405 temp
[k
] = 10 + (int) (tolower (imm_start
[k
]) - 'a');
1407 else if (tolower (imm_start
[k
]) == 'h')
1410 else if ((imm_start
[k
] == '\0') || (imm_start
[k
] == ']'))
1411 /* imm_start[k]='d'; */
1416 as_bad (_("Invalid Character in immediate Value : %c"),
1422 while (imm_start
[k
] != '\n');
1424 switch (imm_start
[k
])
1427 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1428 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1432 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1436 as_bad (_("Invalid Character in immediate value : %c"),
1440 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1447 return val
* sign_val
;
1451 check_for_parse (const char *line
)
1455 if (*(line
+ 1) == '[')
1460 if ((*line
== '-') || (*line
== '+'))
1463 while (!is_space_char (*line
));
1465 if ((*line
== '-') || (*line
== '+'))
1466 val
= extract_int_val (line
);
1468 val
= extract_int_val (line
+ 1);
1470 INSERT_BUFFER
[0] = 0x3E;
1471 INSERT_BUFFER
[1] = val
;
1480 maxq20_mem_access (char *mem_string
, char **end_op
)
1482 char *s
= mem_string
;
1484 char mem_name_given
[MAX_MEM_NAME_SIZE
+ 1];
1489 /* Skip possible whitespace. */
1490 if (is_space_char (*s
))
1494 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1496 if (p
>= mem_name_given
+ MAX_MEM_NAME_SIZE
)
1497 return (mem_access
*) NULL
;
1503 m
= (mem_access
*) hash_find (mem_hash
, mem_name_given
);
1508 /* This function checks whether the operand is a variable in the data segment
1509 and if so, it returns its symbol entry from the symbol table. */
1512 maxq20_data (char *op_string
)
1515 symbolP
= symbol_find (op_string
);
1518 && S_GET_SEGMENT (symbolP
) != now_seg
1519 && S_GET_SEGMENT (symbolP
) !=
1520 #ifdef BFD_ASSEMBLER
1529 #ifdef BFD_ASSEMBLER
1532 val_pfx
= (symbolP
->sy_value
.X_add_number
) >> 8;
1535 /* In case we do not want to always include the prefix instruction and
1536 let the loader handle the job or in case of a 8 bit addressing mode,
1537 we will just check for val_pfx to be equal to zero and then load the
1538 prefix instruction. Otherwise no prefix instruction needs to be
1540 /* The prefix register will have to be loaded automatically as we have
1541 a 16 bit addressing field. */
1542 pfx_for_imm_val (val_pfx
);
1550 maxq20_displacement (char *disp_start
, char *disp_end
)
1554 char *save_input_line_pointer
;
1556 char *gotfree_input_line
;
1559 gotfree_input_line
= NULL
;
1560 exp
= &disp_expressions
;
1561 i
.maxq20_op
[this_operand
].disps
= exp
;
1563 save_input_line_pointer
= input_line_pointer
;
1564 input_line_pointer
= disp_start
;
1566 END_STRING_AND_SAVE (disp_end
);
1569 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1570 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1572 exp_seg
= expression (exp
);
1575 if (*input_line_pointer
)
1576 as_bad (_("junk `%s' after expression"), input_line_pointer
);
1578 RESTORE_END_STRING (disp_end
+ 1);
1580 RESTORE_END_STRING (disp_end
);
1581 input_line_pointer
= save_input_line_pointer
;
1583 if (gotfree_input_line
)
1584 free (gotfree_input_line
);
1586 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1588 /* Missing or bad expr becomes absolute 0. */
1589 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1591 exp
->X_op
= O_constant
;
1592 exp
->X_add_number
= 0;
1593 exp
->X_add_symbol
= (symbolS
*) 0;
1594 exp
->X_op_symbol
= (symbolS
*) 0;
1596 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1598 if (exp
->X_op
!= O_constant
1599 #ifdef BFD_ASSEMBLER
1600 && OUTPUT_FLAVOR
== bfd_target_aout_flavour
1602 && exp_seg
!= absolute_section
1603 && exp_seg
!= text_section
1604 && exp_seg
!= data_section
1605 && exp_seg
!= bss_section
&& exp_seg
!= undefined_section
1606 #ifdef BFD_ASSEMBLER
1607 && !bfd_is_com_section (exp_seg
)
1611 #ifdef BFD_ASSEMBLER
1612 as_bad (_("unimplemented segment %s in operand"), exp_seg
->name
);
1614 as_bad (_("unimplemented segment type %d in operand"), exp_seg
);
1619 i
.maxq20_op
[this_operand
].disps
= exp
;
1623 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1624 Returns non-zero on error. */
1627 maxq20_operand (char *operand_string
)
1629 reg_entry
*r
= NULL
;
1631 mem_access
*m
= NULL
;
1632 char *end_op
= NULL
;
1633 symbolS
*sym
= NULL
;
1634 char *base_string
= NULL
;
1636 /* Start and end of displacement string expression (if found). */
1637 char *displacement_string_start
= NULL
;
1638 char *displacement_string_end
= NULL
;
1639 /* This maintains the case sentivness. */
1640 char case_str_op_string
[MAX_OPERAND_SIZE
+ 1];
1641 char str_op_string
[MAX_OPERAND_SIZE
+ 1];
1642 char *org_case_op_string
= case_str_op_string
;
1643 char *op_string
= str_op_string
;
1646 memset (op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1647 memset (org_case_op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1649 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1650 memcpy (org_case_op_string
, operand_string
, strlen (operand_string
) + 1);
1652 ii
= strlen (operand_string
) + 1;
1654 if (ii
> MAX_OPERAND_SIZE
)
1656 as_bad (_("Size of Operand '%s' greater than %d"), op_string
,
1663 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1667 if (is_space_char (*op_string
))
1670 if (isxdigit (operand_string
[0]))
1672 /* Now the operands can start with an Integer. */
1673 r
= parse_reg_by_index (op_string
);
1676 if (is_space_char (*op_string
))
1678 i
.types
[this_operand
] = REG
; /* Set the type. */
1679 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1684 /* Get the origanal string. */
1685 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1686 ii
= strlen (operand_string
) + 1;
1690 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1695 /* Check for flags. */
1696 if (!strcmp (op_string
, "Z"))
1698 if (is_space_char (*op_string
))
1701 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1702 i
.maxq20_op
[this_operand
].flag
= FLAG_Z
; /* Set the Register value. */
1709 else if (!strcmp (op_string
, "NZ"))
1711 if (is_space_char (*op_string
))
1714 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1715 i
.maxq20_op
[this_operand
].flag
= FLAG_NZ
; /* Set the Register value. */
1720 else if (!strcmp (op_string
, "NC"))
1722 if (is_space_char (*op_string
))
1725 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1726 i
.maxq20_op
[this_operand
].flag
= FLAG_NC
; /* Set the Register value. */
1731 else if (!strcmp (op_string
, "E"))
1733 if (is_space_char (*op_string
))
1736 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1737 i
.maxq20_op
[this_operand
].flag
= FLAG_E
; /* Set the Register value. */
1744 else if (!strcmp (op_string
, "S"))
1746 if (is_space_char (*op_string
))
1749 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1750 i
.maxq20_op
[this_operand
].flag
= FLAG_S
; /* Set the Register value. */
1757 else if (!strcmp (op_string
, "C"))
1759 if (is_space_char (*op_string
))
1762 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1763 i
.maxq20_op
[this_operand
].flag
= FLAG_C
; /* Set the Register value. */
1770 else if (!strcmp (op_string
, "NE"))
1773 if (is_space_char (*op_string
))
1776 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1778 i
.maxq20_op
[this_operand
].flag
= FLAG_NE
; /* Set the Register value. */
1785 /* CHECK FOR REGISTER BIT */
1786 else if ((rb
= parse_register_bit (op_string
, &end_op
)) != NULL
)
1790 if (is_space_char (*op_string
))
1793 i
.types
[this_operand
] = BIT
;
1795 i
.maxq20_op
[this_operand
].r_bit
= rb
;
1802 else if (*op_string
== IMMEDIATE_PREFIX
) /* FOR IMMEDITE. */
1804 if (is_space_char (*op_string
))
1807 i
.types
[this_operand
] = IMM
;
1809 if (!maxq20_immediate (op_string
))
1811 as_bad (_("illegal immediate operand '%s'"), op_string
);
1817 else if (*op_string
== ABSOLUTE_PREFIX
|| !strcmp (op_string
, "NUL"))
1819 if (is_space_char (*op_string
))
1822 /* For new requiremnt of copiler of for, @(BP,cons). */
1823 if (check_for_parse (op_string
))
1825 memset (op_string
, '\0', strlen (op_string
) + 1);
1826 memcpy (op_string
, "@BP[OFFS]\0", 11);
1829 i
.types
[this_operand
] = MEM
;
1831 if ((m
= maxq20_mem_access (op_string
, &end_op
)) == NULL
)
1833 as_bad (_("Invalid operand for memory access '%s'"), op_string
);
1836 i
.maxq20_op
[this_operand
].mem
= m
;
1843 else if ((r
= parse_register (op_string
, &end_op
)) != NULL
) /* Check for register. */
1847 if (is_space_char (*op_string
))
1850 i
.types
[this_operand
] = REG
; /* Set the type. */
1851 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1856 if (this_operand
== 1)
1858 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1859 /* The operand can either be a data reference or a symbol reference. */
1860 if ((sym
= maxq20_data (org_case_op_string
)) != NULL
) /* Check for data memory. */
1862 while (is_space_char (*op_string
))
1865 /* Set the type of the operand. */
1866 i
.types
[this_operand
] = DATA
;
1868 /* Set the value of the data. */
1869 i
.maxq20_op
[this_operand
].data
= sym
;
1875 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1877 /* This is a memory reference of some sort. char *base_string;
1878 Start and end of displacement string expression (if found). char
1879 *displacement_string_start; char *displacement_string_end. */
1880 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1883 if (is_space_char (*base_string
))
1886 /* If we only have a displacement, set-up for it to be parsed
1888 displacement_string_start
= org_case_op_string
;
1889 displacement_string_end
= base_string
+ 1;
1890 if (displacement_string_start
!= displacement_string_end
)
1892 if (!maxq20_displacement (displacement_string_start
,
1893 displacement_string_end
))
1895 as_bad (_("illegal displacement operand "));
1898 /* A displacement operand found. */
1899 i
.types
[this_operand
] = DISP
; /* Set the type. */
1905 /* Check for displacement. */
1906 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1908 /* This is a memory reference of some sort. char *base_string;
1909 Start and end of displacement string expression (if found). char
1910 *displacement_string_start; char *displacement_string_end; */
1911 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1914 if (is_space_char (*base_string
))
1917 /* If we only have a displacement, set-up for it to be parsed later. */
1918 displacement_string_start
= org_case_op_string
;
1919 displacement_string_end
= base_string
+ 1;
1920 if (displacement_string_start
!= displacement_string_end
)
1922 if (!maxq20_displacement (displacement_string_start
,
1923 displacement_string_end
))
1925 /* A displacement operand found. */
1926 i
.types
[this_operand
] = DISP
; /* Set the type. */
1932 /* Parse_operand takes as input instruction and operands and Parse operands
1933 and makes entry in the template. */
1936 parse_operands (char *l
, const char *mnemonic
)
1940 /* 1 if operand is pending after ','. */
1941 short int expecting_operand
= 0;
1943 /* Non-zero if operand parens not balanced. */
1944 short int paren_not_balanced
;
1948 /* For Overcoming Warning of unused variable. */
1952 while (*l
!= END_OF_INSN
)
1954 /* Skip optional white space before operand. */
1955 if (is_space_char (*l
))
1958 if (!is_operand_char (*l
) && *l
!= END_OF_INSN
)
1960 as_bad (_("invalid character %c before operand %d"),
1961 (char) (*l
), i
.operands
+ 1);
1966 paren_not_balanced
= 0;
1967 while (paren_not_balanced
|| *l
!= ',')
1969 if (*l
== END_OF_INSN
)
1971 if (paren_not_balanced
)
1973 as_bad (_("unbalanced brackets in operand %d."),
1980 else if (!is_operand_char (*l
) && !is_space_char (*l
))
1982 as_bad (_("invalid character %c in operand %d"),
1983 (char) (*l
), i
.operands
+ 1);
1987 ++paren_not_balanced
;
1989 --paren_not_balanced
;
1993 if (l
!= token_start
)
1995 /* Yes, we've read in another operand. */
1996 this_operand
= i
.operands
++;
1997 if (i
.operands
> MAX_OPERANDS
)
1999 as_bad (_("spurious operands; (%d operands/instruction max)"),
2004 /* Now parse operand adding info to 'i' as we go along. */
2005 END_STRING_AND_SAVE (l
);
2007 operand_ok
= maxq20_operand (token_start
);
2009 RESTORE_END_STRING (l
);
2016 if (expecting_operand
)
2018 expecting_operand_after_comma
:
2019 as_bad (_("expecting operand after ','; got nothing"));
2026 if (*(++l
) == END_OF_INSN
)
2027 /* Just skip it, if it's \n complain. */
2028 goto expecting_operand_after_comma
;
2030 expecting_operand
= 1;
2038 match_operands (int type
, MAX_ARG_TYPE flag_type
, MAX_ARG_TYPE arg_type
,
2044 if ((arg_type
& A_REG
) == A_REG
)
2048 if ((arg_type
& A_IMM
) == A_IMM
)
2052 if ((arg_type
& A_BIT_0
) == A_BIT_0
&& (i
.maxq20_op
[op_num
].imms
== 0))
2054 else if ((arg_type
& A_BIT_1
) == A_BIT_1
2055 && (i
.maxq20_op
[op_num
].imms
== 1))
2059 if ((arg_type
& A_MEM
) == A_MEM
)
2064 if ((arg_type
& flag_type
) == flag_type
)
2070 if ((arg_type
& ACC_BIT
) == ACC_BIT
&& !strcmp (i
.maxq20_op
[op_num
].r_bit
->reg
->reg_name
, "ACC"))
2072 else if ((arg_type
& SRC_BIT
) == SRC_BIT
&& (op_num
== 1))
2074 else if ((op_num
== 0) && (arg_type
& DST_BIT
) == DST_BIT
)
2078 if ((arg_type
& A_DISP
) == A_DISP
)
2081 if ((arg_type
& A_DATA
) == A_DATA
)
2084 if ((arg_type
& A_BIT_BUCKET
) == A_BIT_BUCKET
)
2091 match_template (void)
2093 /* Points to template once we've found it. */
2094 const MAXQ20_OPCODE_INFO
*t
;
2098 for (t
= current_templates
->start
; t
< current_templates
->end
; t
++)
2100 /* Must have right number of operands. */
2101 if (i
.operands
!= t
->op_number
)
2103 else if (!t
->op_number
)
2109 if (!match_operands (i
.types
[1], i
.maxq20_op
[1].flag
, t
->arg
[1], 1))
2115 if (!match_operands (i
.types
[0], i
.maxq20_op
[0].flag
, t
->arg
[0], 0))
2124 if (t
== current_templates
->end
)
2126 /* We found no match. */
2127 as_bad (_("operand %d is invalid for `%s'"),
2128 inv_oper
, current_templates
->start
->name
);
2132 /* Copy the template we have found. */
2137 /* This function filters out the various combinations of operands which are
2138 not allowed for a particular instruction. */
2141 match_filters (void)
2143 /* Now we have at our disposal the instruction i. We will be using the
2144 following fields i.op.name : This is the mnemonic name. i.types[2] :
2145 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2146 i.maxq20_op[2] : This contains the specific info of the operands. */
2148 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2150 if (!strcmp (i
.op
.name
, "AND") || !strcmp (i
.op
.name
, "OR")
2151 || !strcmp (i
.op
.name
, "XOR") || !strcmp (i
.op
.name
, "ADD")
2152 || !strcmp (i
.op
.name
, "ADDC") || !strcmp (i
.op
.name
, "SUB")
2153 || !strcmp (i
.op
.name
, "SUBB"))
2155 if (i
.types
[0] == REG
)
2157 if (i
.maxq20_op
[0].reg
->Mod_name
== 0xa)
2160 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2166 if (!strcmp (i
.op
.name
, "MOVE") && (i
.types
[0] == MEM
|| i
.types
[1] == MEM
)
2169 mem_access_syntax
*mem_op
= NULL
;
2171 if (i
.types
[0] == MEM
)
2174 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2175 i
.maxq20_op
[0].mem
->name
);
2176 if ((mem_op
->type
== SRC
) && mem_op
)
2178 as_bad (_("'%s' operand cant be used as destination in %s"),
2179 mem_op
->name
, i
.op
.name
);
2182 else if ((mem_op
->invalid_op
!= NULL
) && (i
.types
[1] == MEM
)
2187 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2189 if (mem_op
->invalid_op
[k
] != NULL
)
2191 (mem_op
->invalid_op
[k
], i
.maxq20_op
[1].mem
->name
))
2194 ("Invalid Instruction '%s' operand cant be used with %s"),
2195 mem_op
->name
, i
.maxq20_op
[1].mem
->name
);
2202 if (i
.types
[1] == MEM
)
2206 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2207 i
.maxq20_op
[1].mem
->name
);
2208 if (mem_op
->type
== DST
&& mem_op
)
2210 as_bad (_("'%s' operand cant be used as source in %s"),
2211 mem_op
->name
, i
.op
.name
);
2214 else if (mem_op
->invalid_op
!= NULL
&& i
.types
[0] == MEM
&& mem_op
)
2218 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2220 if (mem_op
->invalid_op
[k
] != NULL
)
2222 (mem_op
->invalid_op
[k
], i
.maxq20_op
[0].mem
->name
))
2225 ("Invalid Instruction '%s' operand cant be used with %s"),
2226 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2231 else if (i
.types
[0] == REG
2232 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "OFFS")
2235 if (!strcmp (mem_op
->name
, "@BP[OFFS--]")
2236 || !strcmp (mem_op
->name
, "@BP[OFFS++]"))
2239 ("Invalid Instruction '%s' operand cant be used with %s"),
2240 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2247 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2248 on 10-March-2004. */
2249 if ((i
.types
[0] == MEM
) && (i
.operands
== 1)
2250 && !(!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI")))
2252 mem_access_syntax
*mem_op
= NULL
;
2254 if (i
.types
[0] == MEM
)
2257 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2258 i
.maxq20_op
[0].mem
->name
);
2259 if (mem_op
->type
== DST
&& mem_op
)
2261 as_bad (_("'%s' operand cant be used as source in %s"),
2262 mem_op
->name
, i
.op
.name
);
2268 if (i
.operands
== 2 && i
.types
[0] == IMM
)
2270 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2275 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2276 if (!strcmp (i
.op
.name
, "PUSH") || !strcmp (i
.op
.name
, "POP")
2277 || !strcmp (i
.op
.name
, "POPI"))
2279 if (i
.types
[0] == REG
)
2281 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
2283 as_bad (_("SP cannot be used with %s\n"), i
.op
.name
);
2287 else if (i
.types
[0] == MEM
2288 && !strcmp (i
.maxq20_op
[0].mem
->name
, "@SP--"))
2290 as_bad (_("@SP-- cannot be used with PUSH\n"));
2295 /* This filter checks that two memory references using DP's cannot be used
2296 together in an instruction */
2297 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 2)
2299 if (strlen (i
.maxq20_op
[0].mem
->name
) != 6 ||
2300 strcmp (i
.maxq20_op
[0].mem
->name
, i
.maxq20_op
[1].mem
->name
))
2302 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@DP", 3)
2303 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@DP", 3))
2306 ("Operands either contradictory or use the data bus in read/write state together"));
2310 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@SP", 3)
2311 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@SP", 3))
2314 ("Operands either contradictory or use the data bus in read/write state together"));
2318 if ((i
.maxq20_op
[1].mem
!= NULL
)
2319 && !strncmp (i
.maxq20_op
[1].mem
->name
, "NUL", 3))
2321 as_bad (_("MOVE Cant Use NUL as SRC"));
2326 /* This filter checks that contradictory movement between DP register and
2327 Memory access using DP followed by increment or decrement. */
2329 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 1
2330 && i
.reg_operands
== 1)
2334 memnum
= (i
.types
[0] == MEM
) ? 0 : 1;
2335 regnum
= (memnum
== 0) ? 1 : 0;
2336 if (!strncmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "DP", 2) &&
2337 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2338 i
.maxq20_op
[regnum
].reg
->reg_name
, 5)
2339 && strcmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2340 i
.maxq20_op
[regnum
].reg
->reg_name
))
2343 ("Contradictory movement between DP register and memory access using DP"));
2346 else if (!strcmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "SP") &&
2347 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2348 i
.maxq20_op
[regnum
].reg
->reg_name
, 2))
2351 ("SP and @SP-- cannot be used together in a move instruction"));
2356 /* This filter restricts the instructions containing source and destination
2357 bits to only CTRL module of the serial registers. Peripheral registers
2358 yet to be defined. */
2360 if (i
.bit_operands
== 1 && i
.operands
== 2)
2362 int bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2364 if (strcmp (i
.maxq20_op
[bitnum
].r_bit
->reg
->reg_name
, "ACC"))
2366 if (i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
>= 0x7 &&
2367 i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
!= CTRL
)
2370 ("Only Module 8 system registers allowed in this operation"));
2376 /* This filter is for checking the register bits. */
2377 if (i
.bit_operands
== 1 || i
.operands
== 2)
2379 int bitnum
= 0, size
= 0;
2381 bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2382 if (i
.bit_operands
== 1)
2384 switch (i
.maxq20_op
[bitnum
].r_bit
->reg
->rtype
)
2387 size
= 7; /* 8 bit register, both read and write. */
2396 as_fatal (_("Read only Register used as destination"));
2405 as_fatal (_("Read only Register used as destination"));
2411 if (size
< (i
.maxq20_op
[bitnum
].r_bit
)->bit
)
2413 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2414 (i
.maxq20_op
[bitnum
].r_bit
)->bit
);
2419 if (i
.bit_operands
== 2)
2421 switch ((i
.maxq20_op
[0].r_bit
)->reg
->rtype
)
2424 size
= 7; /* 8 bit register, both read and write. */
2431 as_fatal (_("Read only Register used as destination"));
2435 if (size
< (i
.maxq20_op
[0].r_bit
)->bit
)
2438 ("Bit No '%d' exceeds register size in this operation"),
2439 (i
.maxq20_op
[0].r_bit
)->bit
);
2444 switch ((i
.maxq20_op
[1].r_bit
)->reg
->rtype
)
2448 size
= 7; /* 8 bit register, both read and write. */
2456 if (size
< (i
.maxq20_op
[1].r_bit
)->bit
)
2459 ("Bit No '%d' exceeds register size in this operation"),
2460 (i
.maxq20_op
[1].r_bit
)->bit
);
2466 /* No branch operations should occur into the data memory. Hence any memory
2467 references have to be filtered out when used with instructions like
2468 jump, djnz[] and call. */
2470 if (!strcmp (i
.op
.name
, "JUMP") || !strcmp (i
.op
.name
, "CALL")
2471 || !strncmp (i
.op
.name
, "DJNZ", 4))
2475 ("Memory References cannot be used with branching operations\n"));
2478 if (!strcmp (i
.op
.name
, "DJNZ"))
2481 (strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2482 || strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))
2484 as_bad (_("DJNZ uses only LC[n] register \n"));
2489 /* No destination register used should be read only! */
2490 if ((i
.operands
== 2 && i
.types
[0] == REG
) || !strcmp (i
.op
.name
, "POP")
2491 || !strcmp (i
.op
.name
, "POPI"))
2492 { /* The destination is a register */
2495 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2499 if (i
.types
[regnum
] == MEM
)
2501 mem_access_syntax
*mem_op
= NULL
;
2504 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2505 i
.maxq20_op
[regnum
].mem
->
2507 if (mem_op
->type
== SRC
&& mem_op
)
2510 ("'%s' operand cant be used as destination in %s"),
2511 mem_op
->name
, i
.op
.name
);
2517 if (i
.maxq20_op
[regnum
].reg
->rtype
== Reg_8R
2518 || i
.maxq20_op
[regnum
].reg
->rtype
== Reg_16R
)
2520 as_bad (_("Read only register used for writing purposes '%s'"),
2521 i
.maxq20_op
[regnum
].reg
->reg_name
);
2526 /* While moving the address of a data in the data section, the destination
2527 should be either data pointers only. */
2528 if ((i
.data_operands
) && (i
.operands
== 2))
2530 if ((i
.types
[0] != REG
) && (i
.types
[0] != MEM
))
2532 as_bad (_("Invalid destination for this kind of source."));
2536 if (i
.types
[0] == REG
&& i
.maxq20_op
[0].reg
->rtype
== Reg_8W
)
2539 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2549 /* Check for the format Bit if defined. */
2550 if (i
.op
.format
== 0 || i
.op
.format
== 1)
2551 i
.instr
[0] = i
.op
.format
<< 7;
2554 /* Format bit not defined. We will have to be find it out ourselves. */
2555 if (i
.imm_operands
== 1 || i
.data_operands
== 1 || i
.disp_operands
== 1)
2559 i
.instr
[0] = i
.op
.format
<< 7;
2562 /* Now for the destination register. */
2564 /* If destination register is already defined . The conditions are the
2565 following: (1) The second entry in the destination array should be 0 (2)
2566 If there are two operands then the first entry should not be a register,
2567 memory or a register bit (3) If there are less than two operands and the
2568 it is not a pop operation (4) The second argument is the carry
2569 flag(applicable to move Acc.<b>,C. */
2570 if (i
.op
.dst
[1] == 0
2572 ((i
.types
[0] != REG
&& i
.types
[0] != MEM
&& i
.types
[0] != BIT
2573 && i
.operands
== 2) || (i
.operands
< 2 && strcmp (i
.op
.name
, "POP")
2574 && strcmp (i
.op
.name
, "POPI"))
2575 || (i
.op
.arg
[1] == FLAG_C
)))
2577 i
.op
.dst
[0] &= 0x7f;
2578 i
.instr
[0] |= i
.op
.dst
[0];
2580 else if (i
.op
.dst
[1] == 0 && !strcmp (i
.op
.name
, "DJNZ")
2582 (((i
.types
[0] == REG
)
2583 && (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2584 || !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))))
2586 i
.op
.dst
[0] &= 0x7f;
2587 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]"))
2590 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]"))
2597 /* Target register will have to be specified. */
2598 if (i
.types
[0] == REG
2599 && (i
.op
.dst
[0] == REG
|| i
.op
.dst
[0] == (REG
| MEM
)))
2601 temp
= (i
.maxq20_op
[0].reg
)->opcode
;
2605 else if (i
.types
[0] == MEM
&& (i
.op
.dst
[0] == (REG
| MEM
)))
2607 temp
= (i
.maxq20_op
[0].mem
)->opcode
;
2611 else if (i
.types
[0] == BIT
&& (i
.op
.dst
[0] == REG
))
2613 temp
= (i
.maxq20_op
[0].r_bit
)->reg
->opcode
;
2617 else if (i
.types
[1] == BIT
&& (i
.op
.dst
[0] == BIT
))
2619 temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2621 temp
|= i
.op
.dst
[1];
2627 as_bad (_("Invalid Instruction"));
2632 /* Now for the source register. */
2634 /* If Source register is already known. The following conditions are
2635 checked: (1) There are no operands (2) If there is only one operand and
2636 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2639 if (i
.operands
== 0 || (i
.operands
== 1 && i
.types
[0] == FLAG
)
2640 || (i
.types
[0] == FLAG
&& i
.types
[1] == IMMBIT
)
2641 || !strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2642 i
.instr
[1] = i
.op
.src
[0];
2644 else if (i
.imm_operands
== 1 && ((i
.op
.src
[0] & IMM
) == IMM
))
2645 i
.instr
[1] = i
.maxq20_op
[this_operand
].imms
;
2647 else if (i
.types
[this_operand
] == REG
&& ((i
.op
.src
[0] & REG
) == REG
))
2648 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].reg
)->opcode
);
2650 else if (i
.types
[this_operand
] == BIT
&& ((i
.op
.src
[0] & REG
) == REG
))
2651 i
.instr
[1] = (char) (i
.maxq20_op
[this_operand
].r_bit
->reg
->opcode
);
2653 else if (i
.types
[this_operand
] == MEM
&& ((i
.op
.src
[0] & MEM
) == MEM
))
2654 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].mem
)->opcode
);
2656 else if (i
.types
[this_operand
] == DATA
&& ((i
.op
.src
[0] & DATA
) == DATA
))
2657 /* This will copy only the lower order bytes into the instruction. The
2658 higher order bytes have already been copied into the prefix register. */
2661 /* Decoding the source in the case when the second array entry is not 0.
2662 This means that the source register has been divided into two nibbles. */
2664 else if (i
.op
.src
[1] != 0)
2666 /* If the first operand is a accumulator bit then
2667 the first 4 bits will be filled with the bit number. */
2668 if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & BIT
) == BIT
))
2670 unsigned char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2673 temp
|= i
.op
.src
[1];
2676 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2677 has to start with a zero. This is called a ZEROBIT */
2678 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ZEROBIT
) == ZEROBIT
))
2680 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2683 temp
|= i
.op
.src
[1];
2687 /* Similarly for a ONEBIT */
2688 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ONEBIT
) == ONEBIT
))
2690 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2693 temp
|= i
.op
.src
[1];
2697 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2699 else if (i
.types
[1] == BIT
)
2701 if (i
.op
.src
[1] == 0 && i
.op
.src
[1] == REG
)
2702 i
.instr
[1] = (i
.maxq20_op
[1].r_bit
)->reg
->opcode
;
2704 else if (i
.op
.src
[0] == BIT
&& i
.op
.src
)
2706 char temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2709 temp
|= i
.op
.src
[1];
2715 as_bad (_("Invalid Instruction"));
2722 /* This is a function for outputting displacement operands. */
2725 output_disp (fragS
*insn_start_frag
, offsetT insn_start_off
)
2728 relax_substateT subtype
;
2734 insn_start_frag
= frag_now
;
2735 insn_start_off
= frag_now_fix ();
2737 switch (i
.Instr_Prefix
)
2740 subtype
= EXPLICT_LONG_PREFIX
;
2743 subtype
= SHORT_PREFIX
;
2746 subtype
= NO_PREFIX
;
2750 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2751 case there is no need for relaxation. But we do need support for a
2752 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2753 for prefix + 2 for the current instruction ) Hence if at a particular
2754 time we find out whether the prefix operator is reqd , we shift the
2755 current instruction two places ahead and insert the prefix instruction. */
2759 sym
= i
.maxq20_op
[this_operand
].disps
->X_add_symbol
;
2760 off
= i
.maxq20_op
[this_operand
].disps
->X_add_number
;
2762 if (i
.maxq20_op
[this_operand
].disps
->X_add_symbol
!= NULL
&& sym
&& frag_now
2763 && (subtype
!= EXPLICT_LONG_PREFIX
))
2765 /* If in the same frag. */
2766 if (frag_now
== symbol_get_frag (sym
))
2769 ((((expressionS
*) symbol_get_value_expression (sym
))->
2770 X_add_number
) - insn_start_off
);
2772 /* PC points to the next instruction. */
2773 diff
= (diff
/ MAXQ_OCTETS_PER_BYTE
) - 1;
2775 if (diff
>= -128 && diff
<= 127)
2777 i
.instr
[1] = (char) diff
;
2779 /* This will be overwritten later when the symbol is resolved. */
2781 *(p
+ 1) = i
.instr
[0];
2783 /* No Need to create a FIXUP. */
2789 /* This will be overwritten later when the symbol is resolved. */
2791 *(p
+ 1) = i
.instr
[0];
2793 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2794 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2796 /* Handle complex expressions. */
2797 sym
= make_expr_symbol (i
.maxq20_op
[this_operand
].disps
);
2801 /* Vineet : This has been added for md_estimate_size_before_relax to
2802 estimate the correct size. */
2803 if (subtype
!= SHORT_PREFIX
)
2804 i
.reloc
[this_operand
] = LONG_PREFIX
;
2806 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2809 /* This is a function for outputting displacement operands. */
2812 output_data (fragS
*insn_start_frag
, offsetT insn_start_off
)
2815 relax_substateT subtype
;
2822 insn_start_frag
= frag_now
;
2823 insn_start_off
= frag_now_fix ();
2825 subtype
= EXPLICT_LONG_PREFIX
;
2830 sym
= i
.maxq20_op
[this_operand
].data
;
2833 /* This will be overwritten later when the symbol is resolved. */
2835 *(p
+ 1) = i
.instr
[0];
2837 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2838 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2839 /* Handle complex expressions. */
2840 /* Because data is already in terms of symbol so no
2841 need to convert it from expression to symbol. */
2844 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2850 fragS
*insn_start_frag
;
2851 offsetT insn_start_off
;
2854 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2855 do this after the insn has been output as the current frag may have been
2856 closed off. eg. by frag_var. */
2857 dwarf2_emit_insn (0);
2859 /* To ALign the text section on word. */
2861 frag_align (1, 0, 1);
2863 /* We initialise the frags for this particular instruction. */
2864 insn_start_frag
= frag_now
;
2865 insn_start_off
= frag_now_fix ();
2867 /* If there are displacement operators(unresolved) present, then handle
2869 if (i
.disp_operands
)
2871 output_disp (insn_start_frag
, insn_start_off
);
2875 if (i
.data_operands
)
2877 output_data (insn_start_frag
, insn_start_off
);
2881 /* Check whether the INSERT_BUFFER has to be written. */
2882 if (strcmp (INSERT_BUFFER
, ""))
2886 *p
++ = INSERT_BUFFER
[1];
2887 *p
= INSERT_BUFFER
[0];
2890 /* Check whether the prefix instruction has to be written. */
2891 if (strcmp (PFX_INSN
, ""))
2900 /* For Little endian. */
2906 make_new_reg_table (void)
2908 unsigned long size_pm
= sizeof (peripheral_reg_table
);
2909 num_of_reg
= ARRAY_SIZE (peripheral_reg_table
);
2911 new_reg_table
= xmalloc (size_pm
);
2912 if (new_reg_table
== NULL
)
2913 as_bad (_("Cannot allocate memory"));
2915 memcpy (new_reg_table
, peripheral_reg_table
, size_pm
);
2918 /* pmmain performs the initilizations for the pheripheral modules. */
2923 make_new_reg_table ();
2930 const char *hash_err
= NULL
;
2933 const MAXQ20_OPCODE_INFO
*optab
;
2934 MAXQ20_OPCODES
*core_optab
; /* For opcodes of the same name. This will
2935 be inserted into the hash table. */
2936 struct reg
*reg_tab
;
2937 struct mem_access_syntax
const *memsyntab
;
2938 struct mem_access
*memtab
;
2939 struct bit_name
*bittab
;
2941 /* Initilize pherioipheral modules. */
2944 /* Initialise the opcode hash table. */
2945 op_hash
= hash_new ();
2947 optab
= op_table
; /* Initialise it to the first entry of the
2948 maxq20 operand table. */
2950 /* Setup for loop. */
2951 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2952 core_optab
->start
= optab
;
2957 if (optab
->name
== NULL
|| strcmp (optab
->name
, (optab
- 1)->name
) != 0)
2959 /* different name --> ship out current template list; add to hash
2960 table; & begin anew. */
2962 core_optab
->end
= optab
;
2964 if (max_version
== bfd_mach_maxq10
)
2966 if (((optab
- 1)->arch
== MAXQ10
) || ((optab
- 1)->arch
== MAX
))
2968 hash_err
= hash_insert (op_hash
,
2973 else if (max_version
== bfd_mach_maxq20
)
2975 if (((optab
- 1)->arch
== MAXQ20
) || ((optab
- 1)->arch
== MAX
))
2978 hash_err
= hash_insert (op_hash
,
2985 as_fatal (_("Internal Error: Illegal Architecure specified"));
2988 as_fatal (_("Internal Error: Can't hash %s: %s"),
2989 (optab
- 1)->name
, hash_err
);
2991 if (optab
->name
== NULL
)
2993 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2994 core_optab
->start
= optab
;
2998 /* Initialise a new register table. */
2999 reg_hash
= hash_new ();
3001 for (reg_tab
= system_reg_table
;
3002 reg_tab
< (system_reg_table
+ ARRAY_SIZE (system_reg_table
));
3006 switch (max_version
)
3008 case bfd_mach_maxq10
:
3009 if ((reg_tab
->arch
== MAXQ10
) || (reg_tab
->arch
== MAX
))
3010 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3013 case bfd_mach_maxq20
:
3014 if ((reg_tab
->arch
== MAXQ20
) || (reg_tab
->arch
== MAX
))
3018 hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3023 as_fatal (_("Invalid architecture type"));
3028 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3029 reg_tab
->reg_name
, hash_err
);
3032 /* Pheripheral Registers Entry. */
3033 for (reg_tab
= new_reg_table
;
3034 reg_tab
< (new_reg_table
+ num_of_reg
- 1); reg_tab
++)
3036 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3039 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3040 reg_tab
->reg_name
, hash_err
);
3043 /* Initialise a new memory operand table. */
3044 mem_hash
= hash_new ();
3046 for (memtab
= mem_table
;
3047 memtab
< mem_table
+ ARRAY_SIZE (mem_table
);
3050 hash_err
= hash_insert (mem_hash
, memtab
->name
, (PTR
) memtab
);
3052 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3053 memtab
->name
, hash_err
);
3056 bit_hash
= hash_new ();
3058 for (bittab
= bit_table
;
3059 bittab
< bit_table
+ ARRAY_SIZE (bit_table
);
3062 hash_err
= hash_insert (bit_hash
, bittab
->name
, (PTR
) bittab
);
3064 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3065 bittab
->name
, hash_err
);
3068 mem_syntax_hash
= hash_new ();
3070 for (memsyntab
= mem_access_syntax_table
;
3071 memsyntab
< mem_access_syntax_table
+ ARRAY_SIZE (mem_access_syntax_table
);
3075 hash_insert (mem_syntax_hash
, memsyntab
->name
, (PTR
) memsyntab
);
3077 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3078 memsyntab
->name
, hash_err
);
3081 /* Initialise the lexical tables,mnemonic chars,operand chars. */
3082 for (c
= 0; c
< 256; c
++)
3087 mnemonic_chars
[c
] = c
;
3088 operand_chars
[c
] = c
;
3089 register_chars
[c
] = c
;
3091 else if (ISLOWER (c
))
3093 mnemonic_chars
[c
] = c
;
3094 operand_chars
[c
] = c
;
3095 register_chars
[c
] = c
;
3097 else if (ISUPPER (c
))
3099 mnemonic_chars
[c
] = TOLOWER (c
);
3100 register_chars
[c
] = c
;
3101 operand_chars
[c
] = c
;
3104 if (ISALPHA (c
) || ISDIGIT (c
))
3106 identifier_chars
[c
] = c
;
3110 identifier_chars
[c
] = c
;
3111 operand_chars
[c
] = c
;
3115 /* All the special characters. */
3116 register_chars
['@'] = '@';
3117 register_chars
['+'] = '+';
3118 register_chars
['-'] = '-';
3119 digit_chars
['-'] = '-';
3120 identifier_chars
['_'] = '_';
3121 identifier_chars
['.'] = '.';
3122 register_chars
['['] = '[';
3123 register_chars
[']'] = ']';
3124 operand_chars
['_'] = '_';
3125 operand_chars
['#'] = '#';
3126 mnemonic_chars
['['] = '[';
3127 mnemonic_chars
[']'] = ']';
3129 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
3130 operand_chars
[(unsigned char) *p
] = (unsigned char) *p
;
3132 /* Set the maxq arch type. */
3133 maxq_target (max_version
);
3136 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3137 menmunonic in the operand table - Parse operands and populate the
3138 structure/template - Match the operand with opcode and its validity -
3142 md_assemble (char *line
)
3146 char mnemonic
[MAX_MNEM_SIZE
];
3147 char temp4prev
[256];
3148 static char prev_insn
[256];
3150 /* Initialize globals. */
3151 memset (&i
, '\0', sizeof (i
));
3152 for (j
= 0; j
< MAX_OPERANDS
; j
++)
3153 i
.reloc
[j
] = NO_RELOC
;
3158 INSERT_BUFFER
[0] = 0;
3159 INSERT_BUFFER
[1] = 0;
3161 memcpy (temp4prev
, line
, strlen (line
) + 1);
3163 save_stack_p
= save_stack
;
3165 line
= (char *) parse_insn (line
, mnemonic
);
3169 line
= (char *) parse_operands (line
, mnemonic
);
3173 /* Next, we find a template that matches the given insn, making sure the
3174 overlap of the given operands types is consistent with the template
3176 if (!match_template ())
3179 /* In the MAXQ20, there are certain register combinations, and other
3180 restrictions which are not allowed. We will try to resolve these right
3182 if (!match_filters ())
3185 /* Check for the approprate PFX register. */
3187 pfx_for_imm_val (0);
3189 if (!decode_insn ()) /* decode insn. */
3192 /* Check for Exlipct PFX instruction. */
3193 if (PFX_INSN
[0] && (strstr (prev_insn
, "PFX") || strstr (prev_insn
, "pfx")))
3194 as_warn (_("Ineffective insntruction %s \n"), prev_insn
);
3196 memcpy (prev_insn
, temp4prev
, strlen (temp4prev
) + 1);
3198 /* We are ready to output the insn. */