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, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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. */
94 /* Exposed For Linker - maps indirectly to the liker relocations. */
95 #define LONG_PREFIX MAXQ_LONGJUMP /* BFD_RELOC_16 */
96 #define SHORT_PREFIX MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
97 #define ABSOLUTE_ADDR_FOR_DATA MAXQ_INTERSEGMENT
100 #define EXPLICT_LONG_PREFIX 14
102 /* The main instruction structure containing fields to describe instrn */
103 typedef struct _maxq20_insn
105 /* The opcode information for the MAXQ20 */
106 MAXQ20_OPCODE_INFO op
;
108 /* The number of operands */
109 unsigned int operands
;
111 /* Number of different types of operands - Comments can be removed if reqd.
113 unsigned int reg_operands
, mem_operands
, disp_operands
, data_operands
;
114 unsigned int imm_operands
, imm_bit_operands
, bit_operands
, flag_operands
;
116 /* Types of the individual operands */
117 UNKNOWN_OP types
[MAX_OPERANDS
];
119 /* Relocation type for operand : to be investigated into */
120 int reloc
[MAX_OPERANDS
];
122 /* Complete information of the Operands */
123 maxq20_opcode maxq20_op
[MAX_OPERANDS
];
125 /* Choice of prefix register whenever needed */
128 /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
129 unsigned char Instr_Prefix
;
131 /* 16 bit Instruction word */
132 unsigned char instr
[2];
136 /* Definitions of all possible characters that can start an operand. */
137 const char *extra_symbol_chars
= "@(#";
139 /* Special Character that would start a comment. */
140 const char comment_chars
[] = ";";
142 /* Starts a comment when it appears at the start of a line. */
143 const char line_comment_chars
[] = ";#";
145 const char line_separator_chars
[] = ""; /* originally may b by sudeep "\n". */
147 /* The following are used for option processing. */
149 /* This is added to the mach independent string passed to getopt. */
150 const char *md_shortopts
= "q";
152 /* Characters for exponent and floating point. */
153 const char EXP_CHARS
[] = "eE";
154 const char FLT_CHARS
[] = "";
156 /* This is for the machine dependent option handling. */
157 #define OPTION_EB (OPTION_MD_BASE + 0)
158 #define OPTION_EL (OPTION_MD_BASE + 1)
159 #define MAXQ_10 (OPTION_MD_BASE + 2)
160 #define MAXQ_20 (OPTION_MD_BASE + 3)
162 struct option md_longopts
[] =
164 {"MAXQ10", no_argument
, NULL
, MAXQ_10
},
165 {"MAXQ20", no_argument
, NULL
, MAXQ_20
},
166 {NULL
, no_argument
, NULL
, 0}
168 size_t md_longopts_size
= sizeof (md_longopts
);
170 /* md_undefined_symbol We have no need for this function. */
173 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
179 maxq_target (int target
)
181 max_version
= target
;
182 bfd_set_arch_mach (stdoutput
, bfd_arch_maxq
, max_version
);
186 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
188 /* Any options support will be added onto this switch case. */
192 max_version
= bfd_mach_maxq10
;
195 max_version
= bfd_mach_maxq20
;
205 /* When a usage message is printed, this function is called and
206 it prints a description of the machine specific options. */
209 md_show_usage (FILE * stream
)
211 /* Over here we will fill the description of the machine specific options. */
213 fprintf (stream
, _(" MAXQ-specific assembler options:\n"));
215 fprintf (stream
, _("\
216 -MAXQ20 generate obj for MAXQ20(default)\n\
217 -MAXQ10 generate obj for MAXQ10\n\
224 if (!(strcmp (default_arch
, "MAXQ20")))
227 as_fatal (_("Unknown architecture"));
232 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
235 bfd_reloc_code_real_type code
;
237 switch (fixp
->fx_r_type
)
239 case MAXQ_INTERSEGMENT
:
241 case BFD_RELOC_16_PCREL_S2
:
242 code
= fixp
->fx_r_type
;
247 switch (fixp
->fx_size
)
250 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
251 _("can not do %d byte relocation"), fixp
->fx_size
);
267 rel
= xmalloc (sizeof (arelent
));
268 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
269 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
271 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
272 rel
->addend
= fixp
->fx_addnumber
;
273 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
275 if (rel
->howto
== NULL
)
277 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
278 _("cannot represent relocation type %s"),
279 bfd_get_reloc_code_name (code
));
281 /* Set howto to a garbage value so that we can keep going. */
282 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
283 assert (rel
->howto
!= NULL
);
289 /* md_estimate_size_before_relax()
291 Called just before relax() for rs_machine_dependent frags. The MAXQ
292 assembler uses these frags to handle 16 bit absolute jumps which require a
293 prefix instruction to be inserted. Any symbol that is now undefined will
294 not become defined. Return the correct fr_subtype in the frag. Return the
295 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
296 caller. The guess is actually the growth beyond the fixed part. Whatever
297 we do to grow the fixed or variable part contributes to our returned
301 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
303 /* Check whether the symbol has been resolved or not.
304 Otherwise we will have to generate a fixup. */
305 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
)
306 || fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
308 RELOC_ENUM reloc_type
;
309 unsigned char *opcode
;
312 /* Now this symbol has not been defined in this file.
313 Hence we will have to create a fixup. */
316 /* This is for the prefix instruction. */
318 if (fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
319 fragP
->fr_subtype
= LONG_PREFIX
;
321 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
322 && ((!(fragP
->fr_subtype
) == EXPLICT_LONG_PREFIX
)))
323 fragP
->fr_subtype
= ABSOLUTE_ADDR_FOR_DATA
;
326 (fragP
->fr_subtype
? fragP
->fr_subtype
: ABSOLUTE_ADDR_FOR_DATA
);
328 fragP
->fr_subtype
= reloc_type
;
330 if (reloc_type
== SHORT_PREFIX
)
332 old_fr_fix
= fragP
->fr_fix
;
333 opcode
= (unsigned char *) fragP
->fr_opcode
;
335 fragP
->fr_fix
+= (size
);
337 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
338 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
340 return fragP
->fr_fix
- old_fr_fix
;
343 if (fragP
->fr_subtype
== SHORT_PREFIX
)
345 fragP
->fr_subtype
= SHORT_PREFIX
;
349 if (fragP
->fr_subtype
== NO_PREFIX
|| fragP
->fr_subtype
== LONG_PREFIX
)
352 unsigned long call_addr
;
356 call_addr
= call_addr
^ call_addr
;
360 /* segment_info_type *seginfo = seg_info (segment); */
361 instr
= fragP
->fr_address
+ fragP
->fr_fix
- 2;
363 /* This is the offset if it is a PC relative jump. */
364 call_addr
= S_GET_VALUE (fragP
->fr_symbol
) + fragP
->fr_offset
;
366 /* PC stores the value of the next instruction. */
367 diff
= (call_addr
- instr
) - 1;
369 if (diff
>= (-128 * 2) && diff
<= (2 * 127))
371 /* Now as offset is an 8 bit value, we will pass
372 that to the jump instruction directly. */
373 fragP
->fr_subtype
= NO_PREFIX
;
377 fragP
->fr_subtype
= LONG_PREFIX
;
381 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
386 /* Equal to MAX_PRECISION in atof-ieee.c */
387 #define MAX_LITTLENUMS 6
389 /* Turn a string in input_line_pointer into a floating point constant of type
390 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
391 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
394 md_atof (int type
, char * litP
, int * sizeP
)
397 LITTLENUM_TYPE words
[4];
409 /* The size of Double has been changed to 2 words ie 32 bits. */
415 return _("bad call to md_atof");
418 t
= atof_ieee (input_line_pointer
, type
, words
);
420 input_line_pointer
= t
;
424 for (i
= prec
- 1; i
>= 0; i
--)
426 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
434 maxq20_cons_fix_new (fragS
* frag
, unsigned int off
, unsigned int len
,
442 r
= MAXQ_WORDDATA
; /* Word+n */
445 r
= MAXQ_LONGDATA
; /* Long+n */
449 fix_new_exp (frag
, off
, len
, exp
, 0, r
);
453 /* GAS will call this for every rs_machine_dependent fragment. The
454 instruction is compleated using the data from the relaxation pass. It may
455 also create any necessary relocations. */
457 md_convert_frag (bfd
* headers ATTRIBUTE_UNUSED
,
458 segT seg ATTRIBUTE_UNUSED
,
462 offsetT target_address
;
463 offsetT opcode_address
;
464 offsetT displacement_from_opcode_start
;
467 opcode
= fragP
->fr_opcode
;
469 target_address
= opcode_address
= displacement_from_opcode_start
= 0;
472 (S_GET_VALUE (fragP
->fr_symbol
) / MAXQ_OCTETS_PER_BYTE
) +
473 (fragP
->fr_offset
/ MAXQ_OCTETS_PER_BYTE
);
476 (fragP
->fr_address
/ MAXQ_OCTETS_PER_BYTE
) +
477 ((fragP
->fr_fix
- 2) / MAXQ_OCTETS_PER_BYTE
);
479 /* PC points to the next Instruction. */
480 displacement_from_opcode_start
= ((target_address
- opcode_address
) - 1);
482 if ((displacement_from_opcode_start
>= -128
483 && displacement_from_opcode_start
<= 127)
484 && (fragP
->fr_subtype
== SHORT_PREFIX
485 || fragP
->fr_subtype
== NO_PREFIX
))
487 /* Its a displacement. */
488 *opcode
= (char) displacement_from_opcode_start
;
492 /* Its an absolute 16 bit jump. Now we have to
493 load the prefix operator with the upper 8 bits. */
494 if (fragP
->fr_subtype
== SHORT_PREFIX
)
496 as_bad (_("Cant make long jump/call into short jump/call : %d"),
501 /* Check whether the symbol has been resolved or not.
502 Otherwise we will have to generate a fixup. */
504 if (fragP
->fr_subtype
!= SHORT_PREFIX
)
506 RELOC_ENUM reloc_type
;
510 /* Now this is a basolute jump/call.
511 Hence we will have to create a fixup. */
512 if (fragP
->fr_subtype
== NO_PREFIX
)
513 fragP
->fr_subtype
= LONG_PREFIX
;
516 (fragP
->fr_subtype
? fragP
->fr_subtype
: LONG_PREFIX
);
520 old_fr_fix
= fragP
->fr_fix
;
522 fragP
->fr_fix
+= (size
);
524 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
525 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
532 md_pcrel_from (fixS
*fixP
)
534 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
537 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
540 maxq_number_to_chars (char *buf
, valueT val
, int n
)
542 if (target_big_endian
)
543 number_to_chars_bigendian (buf
, val
, n
);
545 number_to_chars_littleendian (buf
, val
, n
);
548 /* GAS will call this for each fixup. It's main objective is to store the
549 correct value in the object file. 'fixup_segment' performs the generic
550 overflow check on the 'valueT *val' argument after md_apply_fix returns.
551 If the overflow check is relevant for the target machine, then
552 'md_apply_fix' should modify 'valueT *val', typically to the value stored
553 in the object file (not to be done in MAXQ). */
556 md_apply_fix (fixS
*fixP
, valueT
*valT
, segT seg ATTRIBUTE_UNUSED
)
558 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
559 char *frag_to_fix_at
=
560 fixP
->fx_frag
->fr_literal
+ fixP
->fx_frag
->fr_fix
- 2;
564 if (fixP
->fx_frag
&& valT
)
566 /* If the relaxation substate is not defined we make it equal
567 to the kind of relocation the fixup is generated for. */
568 if (!fixP
->fx_frag
->fr_subtype
)
569 fixP
->fx_frag
->fr_subtype
= fixP
->fx_r_type
;
571 /* For any instruction in which either we have specified an
572 absolute address or it is a long jump we need to add a PFX0
573 instruction to it. In this case as the instruction has already
574 being written at 'fx_where' in the frag we copy it at the end of
575 the frag(which is where the relocation was generated) as when
576 the relocation is generated the frag is grown by 2 type, this is
577 where we copy the contents of fx_where and add a pfx0 at
579 if ((fixP
->fx_frag
->fr_subtype
== ABSOLUTE_ADDR_FOR_DATA
)
580 || (fixP
->fx_frag
->fr_subtype
== LONG_PREFIX
))
582 *(frag_to_fix_at
+ 1) = *(p
+ 1);
583 maxq_number_to_chars (p
+ 1, PFX0
, 1);
586 /* Remember value for tc_gen_reloc. */
587 fixP
->fx_addnumber
= *valT
;
590 /* Some fixups generated by GAS which gets resovled before this this
591 func. is called need to be wriiten to the frag as here we are going
592 to go away with the relocations fx_done=1. */
593 if (fixP
->fx_addsy
== NULL
)
595 maxq_number_to_chars (p
, *valT
, fixP
->fx_size
);
596 fixP
->fx_addnumber
= *valT
;
602 /* Tables for lexical analysis. */
603 static char mnemonic_chars
[256];
604 static char register_chars
[256];
605 static char operand_chars
[256];
606 static char identifier_chars
[256];
607 static char digit_chars
[256];
609 /* Lexical Macros. */
610 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
611 #define is_register_char(x) (register_chars[(unsigned char)(x)])
612 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
613 #define is_space_char(x) (x==' ')
614 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
615 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
617 /* Special characters for operands. */
618 static char operand_special_chars
[] = "[]@.-+";
620 /* md_assemble() will always leave the instruction passed to it unaltered.
621 To do this we store the instruction in a special stack. */
622 static char save_stack
[32];
623 static char *save_stack_p
;
625 #define END_STRING_AND_SAVE(s) \
628 *save_stack_p++ = *(s); \
633 #define RESTORE_END_STRING(s) \
636 *(s) = *(--save_stack_p); \
640 /* The instruction we are assembling. */
641 static maxq20_insn i
;
643 /* The current template. */
644 static MAXQ20_OPCODES
*current_templates
;
646 /* The displacement operand if any. */
647 static expressionS disp_expressions
;
649 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
650 static int this_operand
;
652 /* The prefix instruction if used. */
653 static char PFX_INSN
[2];
654 static char INSERT_BUFFER
[2];
656 /* For interface with expression() ????? */
657 extern char *input_line_pointer
;
659 /* The HASH Tables: */
661 /* Operand Hash Table. */
662 static struct hash_control
*op_hash
;
664 /* Register Hash Table. */
665 static struct hash_control
*reg_hash
;
667 /* Memory reference Hash Table. */
668 static struct hash_control
*mem_hash
;
670 /* Bit hash table. */
671 static struct hash_control
*bit_hash
;
673 /* Memory Access syntax table. */
674 static struct hash_control
*mem_syntax_hash
;
676 /* This is a mapping from pseudo-op names to functions. */
678 const pseudo_typeS md_pseudo_table
[] =
680 {"int", cons
, 2}, /* size of 'int' has been changed to 1 word
682 {"maxq10", maxq_target
, bfd_mach_maxq10
},
683 {"maxq20", maxq_target
, bfd_mach_maxq20
},
687 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
690 /* This function sets the PFX value coresponding to the specs. Source
691 Destination Index Selection ---------------------------------- Write To|
692 SourceRegRange | Dest Addr Range
693 ------------------------------------------------------ PFX[0] | 0h-Fh |
694 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
695 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
696 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
701 short int src_index
= 0, dst_index
= 0;
705 if (i
.operands
== 1) /* Only SRC is Present */
707 if (i
.types
[0] == REG
)
709 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
711 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
716 src_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
724 if (i
.types
[0] == REG
&& i
.types
[1] == REG
)
726 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
727 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
729 else if (i
.types
[0] != REG
&& i
.types
[1] == REG
) /* DST is Absent */
731 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
734 else if (i
.types
[0] == REG
&& i
.types
[1] != REG
) /* Id SRC is Absent */
736 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
739 else if (i
.types
[0] == BIT
&& i
.maxq20_op
[0].r_bit
)
741 dst_index
= i
.maxq20_op
[0].r_bit
->reg
->Mod_index
;
745 else if (i
.types
[1] == BIT
&& i
.maxq20_op
[1].r_bit
)
748 src_index
= i
.maxq20_op
[1].r_bit
->reg
->Mod_index
;
752 if (src_index
>= 0x00 && src_index
<= 0xF)
754 if (dst_index
>= 0x00 && dst_index
<= 0x07)
758 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
762 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
766 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
770 else if (src_index
>= 0x10 && src_index
<= 0x1F)
772 if (dst_index
>= 0x00 && dst_index
<= 0x07)
776 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
780 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
784 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
791 is_a_LSinstr (const char *ln_pointer
)
795 for (i
= 0; LSInstr
[i
] != NULL
; i
++)
796 if (!strcmp (LSInstr
[i
], ln_pointer
))
803 LS_processing (const char *line
)
805 if (is_a_LSinstr (line
))
807 if ((line
[0] == 'L') || (line
[0] == 'l'))
810 INSERT_BUFFER
[0] = PFX0
;
811 i
.Instr_Prefix
= LONG_PREFIX
;
813 else if ((line
[0] == 'S') || (line
[0] == 's'))
814 i
.Instr_Prefix
= SHORT_PREFIX
;
816 i
.Instr_Prefix
= NO_PREFIX
;
819 i
.Instr_Prefix
= LONG_PREFIX
;
822 /* Separate mnemonics and the operands. */
825 parse_insn (char *line
, char *mnemonic
)
828 char *token_start
= l
;
830 char temp
[MAX_MNEM_SIZE
];
833 memset (temp
, END_OF_INSN
, MAX_MNEM_SIZE
);
836 while ((*mnem_p
= mnemonic_chars
[(unsigned char) *l
]) != 0)
840 if (mnem_p
>= mnemonic
+ MAX_MNEM_SIZE
)
842 as_bad (_("no such instruction: `%s'"), token_start
);
848 if (!is_space_char (*l
) && *l
!= END_OF_INSN
)
850 as_bad (_("invalid character %s in mnemonic"), l
);
856 temp
[ii
- 1] = toupper ((char) mnemonic
[ii
- 1]);
860 LS_processing (temp
);
862 if (i
.Instr_Prefix
!= 0 && is_a_LSinstr (temp
))
863 /* Skip the optional L-S. */
864 memcpy (temp
, temp
+ 1, MAX_MNEM_SIZE
);
866 /* Look up instruction (or prefix) via hash table. */
867 current_templates
= (MAXQ20_OPCODES
*) hash_find (op_hash
, temp
);
869 if (current_templates
!= NULL
)
872 as_bad (_("no such instruction: `%s'"), token_start
);
876 /* Function to calculate x to the power of y.
877 Just to avoid including the math libraries. */
884 for (k
= 0; k
< y
; k
++)
891 parse_reg_by_index (char *imm_start
)
893 int k
= 0, mid
= 0, rid
= 0, val
= 0, j
= 0;
894 char temp
[4] = { 0 };
895 reg_entry
*reg
= NULL
;
899 if (isdigit (imm_start
[k
]))
900 temp
[k
] = imm_start
[k
] - '0';
902 else if (isalpha (imm_start
[k
])
903 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
904 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
906 else if (imm_start
[k
] == 'h')
909 else if (imm_start
[k
] == END_OF_INSN
)
916 return NULL
; /* not a hex digit */
920 while (imm_start
[k
] != '\n');
922 switch (imm_start
[k
])
925 for (j
= 0; j
< k
; j
++)
926 val
+= temp
[j
] * pwr (16, k
- j
- 1);
930 for (j
= 0; j
< k
; j
++)
933 return NULL
; /* not a number */
935 val
+= temp
[j
] * pwr (10, k
- j
- 1);
940 /* Get the module and register id's. */
942 rid
= (val
>> 4) & 0x0f;
946 /* Search the pheripheral reg table. */
947 for (j
= 0; j
< num_of_reg
; j
++)
949 if (new_reg_table
[j
].opcode
== val
)
951 reg
= (reg_entry
*) & new_reg_table
[j
];
959 /* Search the system register table. */
962 while (system_reg_table
[j
].reg_name
!= NULL
)
964 if (system_reg_table
[j
].opcode
== val
)
966 reg
= (reg_entry
*) & system_reg_table
[j
];
975 as_bad (_("Invalid register value %s"), imm_start
);
980 if (this_operand
== 0 && reg
!= NULL
)
982 if (reg
->Mod_index
> 7)
988 return (reg_entry
*) reg
;
991 /* REG_STRING starts *before* REGISTER_PREFIX. */
994 parse_register (char *reg_string
, char **end_op
)
996 char *s
= reg_string
;
998 char reg_name_given
[MAX_REG_NAME_SIZE
+ 1];
1004 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1005 if (is_space_char (*s
))
1009 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1011 if (p
>= reg_name_given
+ MAX_REG_NAME_SIZE
)
1012 return (reg_entry
*) NULL
;
1018 r
= (reg_entry
*) hash_find (reg_hash
, reg_name_given
);
1021 if (this_operand
== 0 && r
!= NULL
)
1023 if (r
->Mod_index
> 7)
1033 parse_register_bit (char *reg_string
, char **end_op
)
1035 const char *s
= reg_string
;
1039 reg_entry
*r
= NULL
;
1041 char temp_bitname
[MAX_REG_NAME_SIZE
+ 2];
1042 char temp
[MAX_REG_NAME_SIZE
+ 1];
1044 memset (&temp
, '\0', (MAX_REG_NAME_SIZE
+ 1));
1045 memset (&temp_bitname
, '\0', (MAX_REG_NAME_SIZE
+ 2));
1050 rb
= xmalloc (sizeof (reg_bit
));
1051 rb
->reg
= xmalloc (sizeof (reg_entry
));
1054 /* For supporting bit names. */
1055 b
= (bit_name
*) hash_find (bit_hash
, reg_string
);
1059 *end_op
= reg_string
+ strlen (reg_string
);
1060 strcpy (temp_bitname
, b
->reg_bit
);
1064 if (strchr (s
, '.'))
1077 if ((r
= parse_register (temp
, end_op
)) == NULL
)
1085 if (isdigit ((char) *s
))
1087 else if (isalpha ((char) *s
))
1089 rb
->bit
= (char) *s
- 'a';
1093 as_bad (_("Invalid bit number : '%c'"), (char) *s
);
1099 diff
= strlen (temp_bitname
) - strlen (temp
) - 1;
1101 diff
= strlen (reg_string
) - strlen (temp
) - 1;
1103 if (*(s
+ diff
) != '\0')
1105 as_bad (_("Illegal character after operand '%s'"), reg_string
);
1113 pfx_for_imm_val (int arg
)
1118 if (i
.prefix
== 0 && arg
== 0 && PFX_INSN
[1] == 0 && !(i
.data_operands
))
1121 if (!(i
.prefix
< 0) && !(i
.prefix
> 7))
1122 PFX_INSN
[0] = (i
.prefix
<< 4) | PFX0
;
1130 maxq20_immediate (char *imm_start
)
1132 int val
= 0, val_pfx
= 0;
1135 int temp
[4] = { 0 };
1139 if (imm_start
[1] == '\0' && (imm_start
[0] == '0' || imm_start
[0] == '1')
1140 && (this_operand
== 1 && ((i
.types
[0] == BIT
|| i
.types
[0] == FLAG
))))
1142 val
= imm_start
[0] - '0';
1143 i
.imm_bit_operands
++;
1144 i
.types
[this_operand
] = IMMBIT
;
1145 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1148 pfx_for_imm_val (0);
1153 /* Check For Sign Charcater. */
1158 if (imm_start
[k
] == '-' && k
== 0)
1161 else if (imm_start
[k
] == '+' && k
== 0)
1164 else if (isdigit (imm_start
[k
]))
1165 temp
[k
] = imm_start
[k
] - '0';
1167 else if (isalpha (imm_start
[k
])
1168 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
1169 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
1171 else if (imm_start
[k
] == 'h')
1174 else if (imm_start
[k
] == '\0')
1181 as_bad (_("Invalid Character in immediate Value : %c"),
1187 while (imm_start
[k
] != '\n');
1189 switch (imm_start
[k
])
1192 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1193 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1197 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1201 as_bad (_("Invalid Character in immediate value : %c"),
1205 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1212 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1213 check if we are moving a 16 bit immediate value into an 8 bit register.
1214 In that case we will generate a warning and move only the lower 8 bits */
1217 as_bad (_("Immediate value greater than 16 bits"));
1221 val
= val
* sign_val
;
1223 /* If it is a stack pointer and the value is greater than the maximum
1225 if (this_operand
== 1)
1227 if ((val
* sign_val
) > MAX_STACK
&& i
.types
[0] == REG
1228 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
1231 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1232 val
= val
& MAX_STACK
;
1235 /* Check the range for 8 bit registers. */
1236 else if (((val
* sign_val
) > 0xFF) && (i
.types
[0] == REG
)
1237 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1240 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1244 else if (((sign_val
== -1) || (val
> 0xFF)) && (i
.types
[0] == REG
)
1245 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1248 val
= ((val
) & 0x00ff);
1249 SET_PFX_ARG (val_pfx
);
1250 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1253 else if ((val
<= 0xff) && (i
.types
[0] == REG
)
1254 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1255 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1258 /* Check for 16 bit registers. */
1259 else if (((sign_val
== -1) || val
> 0xFE) && i
.types
[0] == REG
1260 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1262 /* Add PFX for any negative value -> 16bit register. */
1264 val
= ((val
) & 0x00ff);
1265 SET_PFX_ARG (val_pfx
);
1266 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1269 else if (val
< 0xFF && i
.types
[0] == REG
1270 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1272 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1275 /* All the immediate memory access - no PFX. */
1276 else if (i
.types
[0] == MEM
)
1278 if ((sign_val
== -1) || val
> 0xFE)
1281 val
= ((val
) & 0x00ff);
1282 SET_PFX_ARG (val_pfx
);
1283 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1286 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1289 /* Special handling for immediate jumps like jump nz, #03h etc. */
1290 else if (val
< 0xFF && i
.types
[0] == FLAG
)
1291 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1293 else if ((((sign_val
== -1) || val
> 0xFE)) && i
.types
[0] == FLAG
)
1296 val
= ((val
) & 0x00ff);
1297 SET_PFX_ARG (val_pfx
);
1298 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1302 as_bad (_("Invalid immediate move operation"));
1308 /* All the instruction with operation on ACC: like ADD src, etc. */
1309 if ((sign_val
== -1) || val
> 0xFE)
1312 val
= ((val
) & 0x00ff);
1313 SET_PFX_ARG (val_pfx
);
1314 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1317 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1325 extract_int_val (const char *imm_start
)
1337 if (imm_start
[k
] == '-' && k
== 0)
1340 else if (imm_start
[k
] == '+' && k
== 0)
1343 else if (isdigit (imm_start
[k
]))
1344 temp
[k
] = imm_start
[k
] - '0';
1346 else if (isalpha (imm_start
[k
]) && (tolower (imm_start
[k
])) < 'g')
1347 temp
[k
] = 10 + (int) (tolower (imm_start
[k
]) - 'a');
1349 else if (tolower (imm_start
[k
]) == 'h')
1352 else if ((imm_start
[k
] == '\0') || (imm_start
[k
] == ']'))
1353 /* imm_start[k]='d'; */
1358 as_bad (_("Invalid Character in immediate Value : %c"),
1364 while (imm_start
[k
] != '\n');
1366 switch (imm_start
[k
])
1369 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1370 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1374 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1378 as_bad (_("Invalid Character in immediate value : %c"),
1382 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1389 return val
* sign_val
;
1393 check_for_parse (const char *line
)
1397 if (*(line
+ 1) == '[')
1402 if ((*line
== '-') || (*line
== '+'))
1405 while (!is_space_char (*line
));
1407 if ((*line
== '-') || (*line
== '+'))
1408 val
= extract_int_val (line
);
1410 val
= extract_int_val (line
+ 1);
1412 INSERT_BUFFER
[0] = 0x3E;
1413 INSERT_BUFFER
[1] = val
;
1422 maxq20_mem_access (char *mem_string
, char **end_op
)
1424 char *s
= mem_string
;
1426 char mem_name_given
[MAX_MEM_NAME_SIZE
+ 1];
1431 /* Skip possible whitespace. */
1432 if (is_space_char (*s
))
1436 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1438 if (p
>= mem_name_given
+ MAX_MEM_NAME_SIZE
)
1439 return (mem_access
*) NULL
;
1445 m
= (mem_access
*) hash_find (mem_hash
, mem_name_given
);
1450 /* This function checks whether the operand is a variable in the data segment
1451 and if so, it returns its symbol entry from the symbol table. */
1454 maxq20_data (char *op_string
)
1457 symbolP
= symbol_find (op_string
);
1460 && S_GET_SEGMENT (symbolP
) != now_seg
1461 && S_GET_SEGMENT (symbolP
) != bfd_und_section_ptr
)
1463 /* In case we do not want to always include the prefix instruction and
1464 let the loader handle the job or in case of a 8 bit addressing mode,
1465 we will just check for val_pfx to be equal to zero and then load the
1466 prefix instruction. Otherwise no prefix instruction needs to be
1468 /* The prefix register will have to be loaded automatically as we have
1469 a 16 bit addressing field. */
1470 pfx_for_imm_val (0);
1478 maxq20_displacement (char *disp_start
, char *disp_end
)
1482 char *save_input_line_pointer
;
1484 char *gotfree_input_line
;
1487 gotfree_input_line
= NULL
;
1488 exp
= &disp_expressions
;
1489 i
.maxq20_op
[this_operand
].disps
= exp
;
1491 save_input_line_pointer
= input_line_pointer
;
1492 input_line_pointer
= disp_start
;
1494 END_STRING_AND_SAVE (disp_end
);
1497 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1498 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1500 exp_seg
= expression (exp
);
1503 if (*input_line_pointer
)
1504 as_bad (_("junk `%s' after expression"), input_line_pointer
);
1506 RESTORE_END_STRING (disp_end
+ 1);
1508 RESTORE_END_STRING (disp_end
);
1509 input_line_pointer
= save_input_line_pointer
;
1511 if (gotfree_input_line
)
1512 free (gotfree_input_line
);
1514 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1516 /* Missing or bad expr becomes absolute 0. */
1517 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1519 exp
->X_op
= O_constant
;
1520 exp
->X_add_number
= 0;
1521 exp
->X_add_symbol
= (symbolS
*) 0;
1522 exp
->X_op_symbol
= (symbolS
*) 0;
1524 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1526 if (exp
->X_op
!= O_constant
1527 && OUTPUT_FLAVOR
== bfd_target_aout_flavour
1528 && exp_seg
!= absolute_section
1529 && exp_seg
!= text_section
1530 && exp_seg
!= data_section
1531 && exp_seg
!= bss_section
&& exp_seg
!= undefined_section
1532 && !bfd_is_com_section (exp_seg
))
1534 as_bad (_("unimplemented segment %s in operand"), exp_seg
->name
);
1538 i
.maxq20_op
[this_operand
].disps
= exp
;
1542 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1543 Returns non-zero on error. */
1546 maxq20_operand (char *operand_string
)
1548 reg_entry
*r
= NULL
;
1550 mem_access
*m
= NULL
;
1551 char *end_op
= NULL
;
1552 symbolS
*sym
= NULL
;
1553 char *base_string
= NULL
;
1555 /* Start and end of displacement string expression (if found). */
1556 char *displacement_string_start
= NULL
;
1557 char *displacement_string_end
= NULL
;
1558 /* This maintains the case sentivness. */
1559 char case_str_op_string
[MAX_OPERAND_SIZE
+ 1];
1560 char str_op_string
[MAX_OPERAND_SIZE
+ 1];
1561 char *org_case_op_string
= case_str_op_string
;
1562 char *op_string
= str_op_string
;
1565 memset (op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1566 memset (org_case_op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1568 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1569 memcpy (org_case_op_string
, operand_string
, strlen (operand_string
) + 1);
1571 ii
= strlen (operand_string
) + 1;
1573 if (ii
> MAX_OPERAND_SIZE
)
1575 as_bad (_("Size of Operand '%s' greater than %d"), op_string
,
1582 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1586 if (is_space_char (*op_string
))
1589 if (isxdigit (operand_string
[0]))
1591 /* Now the operands can start with an Integer. */
1592 r
= parse_reg_by_index (op_string
);
1595 if (is_space_char (*op_string
))
1597 i
.types
[this_operand
] = REG
; /* Set the type. */
1598 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1603 /* Get the origanal string. */
1604 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1605 ii
= strlen (operand_string
) + 1;
1609 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1614 /* Check for flags. */
1615 if (!strcmp (op_string
, "Z"))
1617 if (is_space_char (*op_string
))
1620 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1621 i
.maxq20_op
[this_operand
].flag
= FLAG_Z
; /* Set the Register value. */
1628 else if (!strcmp (op_string
, "NZ"))
1630 if (is_space_char (*op_string
))
1633 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1634 i
.maxq20_op
[this_operand
].flag
= FLAG_NZ
; /* Set the Register value. */
1639 else if (!strcmp (op_string
, "NC"))
1641 if (is_space_char (*op_string
))
1644 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1645 i
.maxq20_op
[this_operand
].flag
= FLAG_NC
; /* Set the Register value. */
1650 else if (!strcmp (op_string
, "E"))
1652 if (is_space_char (*op_string
))
1655 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1656 i
.maxq20_op
[this_operand
].flag
= FLAG_E
; /* Set the Register value. */
1663 else if (!strcmp (op_string
, "S"))
1665 if (is_space_char (*op_string
))
1668 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1669 i
.maxq20_op
[this_operand
].flag
= FLAG_S
; /* Set the Register value. */
1676 else if (!strcmp (op_string
, "C"))
1678 if (is_space_char (*op_string
))
1681 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1682 i
.maxq20_op
[this_operand
].flag
= FLAG_C
; /* Set the Register value. */
1689 else if (!strcmp (op_string
, "NE"))
1692 if (is_space_char (*op_string
))
1695 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1697 i
.maxq20_op
[this_operand
].flag
= FLAG_NE
; /* Set the Register value. */
1704 /* CHECK FOR REGISTER BIT */
1705 else if ((rb
= parse_register_bit (op_string
, &end_op
)) != NULL
)
1709 if (is_space_char (*op_string
))
1712 i
.types
[this_operand
] = BIT
;
1714 i
.maxq20_op
[this_operand
].r_bit
= rb
;
1721 else if (*op_string
== IMMEDIATE_PREFIX
) /* FOR IMMEDITE. */
1723 if (is_space_char (*op_string
))
1726 i
.types
[this_operand
] = IMM
;
1728 if (!maxq20_immediate (op_string
))
1730 as_bad (_("illegal immediate operand '%s'"), op_string
);
1736 else if (*op_string
== ABSOLUTE_PREFIX
|| !strcmp (op_string
, "NUL"))
1738 if (is_space_char (*op_string
))
1741 /* For new requiremnt of copiler of for, @(BP,cons). */
1742 if (check_for_parse (op_string
))
1744 memset (op_string
, '\0', strlen (op_string
) + 1);
1745 memcpy (op_string
, "@BP[OFFS]\0", 11);
1748 i
.types
[this_operand
] = MEM
;
1750 if ((m
= maxq20_mem_access (op_string
, &end_op
)) == NULL
)
1752 as_bad (_("Invalid operand for memory access '%s'"), op_string
);
1755 i
.maxq20_op
[this_operand
].mem
= m
;
1762 else if ((r
= parse_register (op_string
, &end_op
)) != NULL
) /* Check for register. */
1766 if (is_space_char (*op_string
))
1769 i
.types
[this_operand
] = REG
; /* Set the type. */
1770 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1775 if (this_operand
== 1)
1777 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1778 /* The operand can either be a data reference or a symbol reference. */
1779 if ((sym
= maxq20_data (org_case_op_string
)) != NULL
) /* Check for data memory. */
1781 while (is_space_char (*op_string
))
1784 /* Set the type of the operand. */
1785 i
.types
[this_operand
] = DATA
;
1787 /* Set the value of the data. */
1788 i
.maxq20_op
[this_operand
].data
= sym
;
1794 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1796 /* This is a memory reference of some sort. char *base_string;
1797 Start and end of displacement string expression (if found). char
1798 *displacement_string_start; char *displacement_string_end. */
1799 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1802 if (is_space_char (*base_string
))
1805 /* If we only have a displacement, set-up for it to be parsed
1807 displacement_string_start
= org_case_op_string
;
1808 displacement_string_end
= base_string
+ 1;
1809 if (displacement_string_start
!= displacement_string_end
)
1811 if (!maxq20_displacement (displacement_string_start
,
1812 displacement_string_end
))
1814 as_bad (_("illegal displacement operand "));
1817 /* A displacement operand found. */
1818 i
.types
[this_operand
] = DISP
; /* Set the type. */
1824 /* Check for displacement. */
1825 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1827 /* This is a memory reference of some sort. char *base_string;
1828 Start and end of displacement string expression (if found). char
1829 *displacement_string_start; char *displacement_string_end; */
1830 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1833 if (is_space_char (*base_string
))
1836 /* If we only have a displacement, set-up for it to be parsed later. */
1837 displacement_string_start
= org_case_op_string
;
1838 displacement_string_end
= base_string
+ 1;
1839 if (displacement_string_start
!= displacement_string_end
)
1841 if (!maxq20_displacement (displacement_string_start
,
1842 displacement_string_end
))
1844 /* A displacement operand found. */
1845 i
.types
[this_operand
] = DISP
; /* Set the type. */
1851 /* Parse_operand takes as input instruction and operands and Parse operands
1852 and makes entry in the template. */
1855 parse_operands (char *l
, const char *mnemonic
)
1859 /* 1 if operand is pending after ','. */
1860 short int expecting_operand
= 0;
1862 /* Non-zero if operand parens not balanced. */
1863 short int paren_not_balanced
;
1867 /* For Overcoming Warning of unused variable. */
1871 while (*l
!= END_OF_INSN
)
1873 /* Skip optional white space before operand. */
1874 if (is_space_char (*l
))
1877 if (!is_operand_char (*l
) && *l
!= END_OF_INSN
)
1879 as_bad (_("invalid character %c before operand %d"),
1880 (char) (*l
), i
.operands
+ 1);
1885 paren_not_balanced
= 0;
1886 while (paren_not_balanced
|| *l
!= ',')
1888 if (*l
== END_OF_INSN
)
1890 if (paren_not_balanced
)
1892 as_bad (_("unbalanced brackets in operand %d."),
1899 else if (!is_operand_char (*l
) && !is_space_char (*l
))
1901 as_bad (_("invalid character %c in operand %d"),
1902 (char) (*l
), i
.operands
+ 1);
1906 ++paren_not_balanced
;
1908 --paren_not_balanced
;
1912 if (l
!= token_start
)
1914 /* Yes, we've read in another operand. */
1915 this_operand
= i
.operands
++;
1916 if (i
.operands
> MAX_OPERANDS
)
1918 as_bad (_("spurious operands; (%d operands/instruction max)"),
1923 /* Now parse operand adding info to 'i' as we go along. */
1924 END_STRING_AND_SAVE (l
);
1926 operand_ok
= maxq20_operand (token_start
);
1928 RESTORE_END_STRING (l
);
1935 if (expecting_operand
)
1937 expecting_operand_after_comma
:
1938 as_bad (_("expecting operand after ','; got nothing"));
1945 if (*(++l
) == END_OF_INSN
)
1946 /* Just skip it, if it's \n complain. */
1947 goto expecting_operand_after_comma
;
1949 expecting_operand
= 1;
1957 match_operands (int type
, MAX_ARG_TYPE flag_type
, MAX_ARG_TYPE arg_type
,
1963 if ((arg_type
& A_REG
) == A_REG
)
1967 if ((arg_type
& A_IMM
) == A_IMM
)
1971 if ((arg_type
& A_BIT_0
) == A_BIT_0
&& (i
.maxq20_op
[op_num
].imms
== 0))
1973 else if ((arg_type
& A_BIT_1
) == A_BIT_1
1974 && (i
.maxq20_op
[op_num
].imms
== 1))
1978 if ((arg_type
& A_MEM
) == A_MEM
)
1983 if ((arg_type
& flag_type
) == flag_type
)
1989 if ((arg_type
& ACC_BIT
) == ACC_BIT
&& !strcmp (i
.maxq20_op
[op_num
].r_bit
->reg
->reg_name
, "ACC"))
1991 else if ((arg_type
& SRC_BIT
) == SRC_BIT
&& (op_num
== 1))
1993 else if ((op_num
== 0) && (arg_type
& DST_BIT
) == DST_BIT
)
1997 if ((arg_type
& A_DISP
) == A_DISP
)
2000 if ((arg_type
& A_DATA
) == A_DATA
)
2003 if ((arg_type
& A_BIT_BUCKET
) == A_BIT_BUCKET
)
2010 match_template (void)
2012 /* Points to template once we've found it. */
2013 const MAXQ20_OPCODE_INFO
*t
;
2017 for (t
= current_templates
->start
; t
< current_templates
->end
; t
++)
2019 /* Must have right number of operands. */
2020 if (i
.operands
!= t
->op_number
)
2022 else if (!t
->op_number
)
2028 if (!match_operands (i
.types
[1], i
.maxq20_op
[1].flag
, t
->arg
[1], 1))
2034 if (!match_operands (i
.types
[0], i
.maxq20_op
[0].flag
, t
->arg
[0], 0))
2043 if (t
== current_templates
->end
)
2045 /* We found no match. */
2046 as_bad (_("operand %d is invalid for `%s'"),
2047 inv_oper
, current_templates
->start
->name
);
2051 /* Copy the template we have found. */
2056 /* This function filters out the various combinations of operands which are
2057 not allowed for a particular instruction. */
2060 match_filters (void)
2062 /* Now we have at our disposal the instruction i. We will be using the
2063 following fields i.op.name : This is the mnemonic name. i.types[2] :
2064 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2065 i.maxq20_op[2] : This contains the specific info of the operands. */
2067 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2069 if (!strcmp (i
.op
.name
, "AND") || !strcmp (i
.op
.name
, "OR")
2070 || !strcmp (i
.op
.name
, "XOR") || !strcmp (i
.op
.name
, "ADD")
2071 || !strcmp (i
.op
.name
, "ADDC") || !strcmp (i
.op
.name
, "SUB")
2072 || !strcmp (i
.op
.name
, "SUBB"))
2074 if (i
.types
[0] == REG
)
2076 if (i
.maxq20_op
[0].reg
->Mod_name
== 0xa)
2079 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2085 if (!strcmp (i
.op
.name
, "MOVE") && (i
.types
[0] == MEM
|| i
.types
[1] == MEM
)
2088 mem_access_syntax
*mem_op
= NULL
;
2090 if (i
.types
[0] == MEM
)
2093 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2094 i
.maxq20_op
[0].mem
->name
);
2095 if ((mem_op
->type
== SRC
) && mem_op
)
2097 as_bad (_("'%s' operand cant be used as destination in %s"),
2098 mem_op
->name
, i
.op
.name
);
2101 else if ((mem_op
->invalid_op
!= NULL
) && (i
.types
[1] == MEM
)
2106 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2108 if (mem_op
->invalid_op
[k
] != NULL
)
2110 (mem_op
->invalid_op
[k
], i
.maxq20_op
[1].mem
->name
))
2113 ("Invalid Instruction '%s' operand cant be used with %s"),
2114 mem_op
->name
, i
.maxq20_op
[1].mem
->name
);
2121 if (i
.types
[1] == MEM
)
2125 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2126 i
.maxq20_op
[1].mem
->name
);
2127 if (mem_op
->type
== DST
&& mem_op
)
2129 as_bad (_("'%s' operand cant be used as source in %s"),
2130 mem_op
->name
, i
.op
.name
);
2133 else if (mem_op
->invalid_op
!= NULL
&& i
.types
[0] == MEM
&& mem_op
)
2137 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2139 if (mem_op
->invalid_op
[k
] != NULL
)
2141 (mem_op
->invalid_op
[k
], i
.maxq20_op
[0].mem
->name
))
2144 ("Invalid Instruction '%s' operand cant be used with %s"),
2145 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2150 else if (i
.types
[0] == REG
2151 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "OFFS")
2154 if (!strcmp (mem_op
->name
, "@BP[OFFS--]")
2155 || !strcmp (mem_op
->name
, "@BP[OFFS++]"))
2158 ("Invalid Instruction '%s' operand cant be used with %s"),
2159 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2166 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2167 on 10-March-2004. */
2168 if ((i
.types
[0] == MEM
) && (i
.operands
== 1)
2169 && !(!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI")))
2171 mem_access_syntax
*mem_op
= NULL
;
2173 if (i
.types
[0] == MEM
)
2176 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2177 i
.maxq20_op
[0].mem
->name
);
2178 if (mem_op
->type
== DST
&& mem_op
)
2180 as_bad (_("'%s' operand cant be used as source in %s"),
2181 mem_op
->name
, i
.op
.name
);
2187 if (i
.operands
== 2 && i
.types
[0] == IMM
)
2189 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2194 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2195 if (!strcmp (i
.op
.name
, "PUSH") || !strcmp (i
.op
.name
, "POP")
2196 || !strcmp (i
.op
.name
, "POPI"))
2198 if (i
.types
[0] == REG
)
2200 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
2202 as_bad (_("SP cannot be used with %s\n"), i
.op
.name
);
2206 else if (i
.types
[0] == MEM
2207 && !strcmp (i
.maxq20_op
[0].mem
->name
, "@SP--"))
2209 as_bad (_("@SP-- cannot be used with PUSH\n"));
2214 /* This filter checks that two memory references using DP's cannot be used
2215 together in an instruction */
2216 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 2)
2218 if (strlen (i
.maxq20_op
[0].mem
->name
) != 6 ||
2219 strcmp (i
.maxq20_op
[0].mem
->name
, i
.maxq20_op
[1].mem
->name
))
2221 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@DP", 3)
2222 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@DP", 3))
2225 ("Operands either contradictory or use the data bus in read/write state together"));
2229 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@SP", 3)
2230 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@SP", 3))
2233 ("Operands either contradictory or use the data bus in read/write state together"));
2237 if ((i
.maxq20_op
[1].mem
!= NULL
)
2238 && !strncmp (i
.maxq20_op
[1].mem
->name
, "NUL", 3))
2240 as_bad (_("MOVE Cant Use NUL as SRC"));
2245 /* This filter checks that contradictory movement between DP register and
2246 Memory access using DP followed by increment or decrement. */
2248 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 1
2249 && i
.reg_operands
== 1)
2253 memnum
= (i
.types
[0] == MEM
) ? 0 : 1;
2254 regnum
= (memnum
== 0) ? 1 : 0;
2255 if (!strncmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "DP", 2) &&
2256 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2257 i
.maxq20_op
[regnum
].reg
->reg_name
, 5)
2258 && strcmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2259 i
.maxq20_op
[regnum
].reg
->reg_name
))
2262 ("Contradictory movement between DP register and memory access using DP"));
2265 else if (!strcmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "SP") &&
2266 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2267 i
.maxq20_op
[regnum
].reg
->reg_name
, 2))
2270 ("SP and @SP-- cannot be used together in a move instruction"));
2275 /* This filter restricts the instructions containing source and destination
2276 bits to only CTRL module of the serial registers. Peripheral registers
2277 yet to be defined. */
2279 if (i
.bit_operands
== 1 && i
.operands
== 2)
2281 int bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2283 if (strcmp (i
.maxq20_op
[bitnum
].r_bit
->reg
->reg_name
, "ACC"))
2285 if (i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
>= 0x7 &&
2286 i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
!= CTRL
)
2289 ("Only Module 8 system registers allowed in this operation"));
2295 /* This filter is for checking the register bits. */
2296 if (i
.bit_operands
== 1 || i
.operands
== 2)
2298 int bitnum
= 0, size
= 0;
2300 bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2301 if (i
.bit_operands
== 1)
2303 switch (i
.maxq20_op
[bitnum
].r_bit
->reg
->rtype
)
2306 size
= 7; /* 8 bit register, both read and write. */
2315 as_fatal (_("Read only Register used as destination"));
2324 as_fatal (_("Read only Register used as destination"));
2330 if (size
< (i
.maxq20_op
[bitnum
].r_bit
)->bit
)
2332 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2333 (i
.maxq20_op
[bitnum
].r_bit
)->bit
);
2338 if (i
.bit_operands
== 2)
2340 switch ((i
.maxq20_op
[0].r_bit
)->reg
->rtype
)
2343 size
= 7; /* 8 bit register, both read and write. */
2350 as_fatal (_("Read only Register used as destination"));
2354 if (size
< (i
.maxq20_op
[0].r_bit
)->bit
)
2357 ("Bit No '%d' exceeds register size in this operation"),
2358 (i
.maxq20_op
[0].r_bit
)->bit
);
2363 switch ((i
.maxq20_op
[1].r_bit
)->reg
->rtype
)
2367 size
= 7; /* 8 bit register, both read and write. */
2375 if (size
< (i
.maxq20_op
[1].r_bit
)->bit
)
2378 ("Bit No '%d' exceeds register size in this operation"),
2379 (i
.maxq20_op
[1].r_bit
)->bit
);
2385 /* No branch operations should occur into the data memory. Hence any memory
2386 references have to be filtered out when used with instructions like
2387 jump, djnz[] and call. */
2389 if (!strcmp (i
.op
.name
, "JUMP") || !strcmp (i
.op
.name
, "CALL")
2390 || !strncmp (i
.op
.name
, "DJNZ", 4))
2394 ("Memory References cannot be used with branching operations\n"));
2397 if (!strcmp (i
.op
.name
, "DJNZ"))
2400 (strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2401 || strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))
2403 as_bad (_("DJNZ uses only LC[n] register \n"));
2408 /* No destination register used should be read only! */
2409 if ((i
.operands
== 2 && i
.types
[0] == REG
) || !strcmp (i
.op
.name
, "POP")
2410 || !strcmp (i
.op
.name
, "POPI"))
2411 { /* The destination is a register */
2414 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2418 if (i
.types
[regnum
] == MEM
)
2420 mem_access_syntax
*mem_op
= NULL
;
2423 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2424 i
.maxq20_op
[regnum
].mem
->
2426 if (mem_op
->type
== SRC
&& mem_op
)
2429 ("'%s' operand cant be used as destination in %s"),
2430 mem_op
->name
, i
.op
.name
);
2436 if (i
.maxq20_op
[regnum
].reg
->rtype
== Reg_8R
2437 || i
.maxq20_op
[regnum
].reg
->rtype
== Reg_16R
)
2439 as_bad (_("Read only register used for writing purposes '%s'"),
2440 i
.maxq20_op
[regnum
].reg
->reg_name
);
2445 /* While moving the address of a data in the data section, the destination
2446 should be either data pointers only. */
2447 if ((i
.data_operands
) && (i
.operands
== 2))
2449 if ((i
.types
[0] != REG
) && (i
.types
[0] != MEM
))
2451 as_bad (_("Invalid destination for this kind of source."));
2455 if (i
.types
[0] == REG
&& i
.maxq20_op
[0].reg
->rtype
== Reg_8W
)
2458 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2468 /* Check for the format Bit if defined. */
2469 if (i
.op
.format
== 0 || i
.op
.format
== 1)
2470 i
.instr
[0] = i
.op
.format
<< 7;
2473 /* Format bit not defined. We will have to be find it out ourselves. */
2474 if (i
.imm_operands
== 1 || i
.data_operands
== 1 || i
.disp_operands
== 1)
2478 i
.instr
[0] = i
.op
.format
<< 7;
2481 /* Now for the destination register. */
2483 /* If destination register is already defined . The conditions are the
2484 following: (1) The second entry in the destination array should be 0 (2)
2485 If there are two operands then the first entry should not be a register,
2486 memory or a register bit (3) If there are less than two operands and the
2487 it is not a pop operation (4) The second argument is the carry
2488 flag(applicable to move Acc.<b>,C. */
2489 if (i
.op
.dst
[1] == 0
2491 ((i
.types
[0] != REG
&& i
.types
[0] != MEM
&& i
.types
[0] != BIT
2492 && i
.operands
== 2) || (i
.operands
< 2 && strcmp (i
.op
.name
, "POP")
2493 && strcmp (i
.op
.name
, "POPI"))
2494 || (i
.op
.arg
[1] == FLAG_C
)))
2496 i
.op
.dst
[0] &= 0x7f;
2497 i
.instr
[0] |= i
.op
.dst
[0];
2499 else if (i
.op
.dst
[1] == 0 && !strcmp (i
.op
.name
, "DJNZ")
2501 (((i
.types
[0] == REG
)
2502 && (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2503 || !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))))
2505 i
.op
.dst
[0] &= 0x7f;
2506 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]"))
2509 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]"))
2516 /* Target register will have to be specified. */
2517 if (i
.types
[0] == REG
2518 && (i
.op
.dst
[0] == REG
|| i
.op
.dst
[0] == (REG
| MEM
)))
2520 temp
= (i
.maxq20_op
[0].reg
)->opcode
;
2524 else if (i
.types
[0] == MEM
&& (i
.op
.dst
[0] == (REG
| MEM
)))
2526 temp
= (i
.maxq20_op
[0].mem
)->opcode
;
2530 else if (i
.types
[0] == BIT
&& (i
.op
.dst
[0] == REG
))
2532 temp
= (i
.maxq20_op
[0].r_bit
)->reg
->opcode
;
2536 else if (i
.types
[1] == BIT
&& (i
.op
.dst
[0] == BIT
))
2538 temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2540 temp
|= i
.op
.dst
[1];
2546 as_bad (_("Invalid Instruction"));
2551 /* Now for the source register. */
2553 /* If Source register is already known. The following conditions are
2554 checked: (1) There are no operands (2) If there is only one operand and
2555 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2558 if (i
.operands
== 0 || (i
.operands
== 1 && i
.types
[0] == FLAG
)
2559 || (i
.types
[0] == FLAG
&& i
.types
[1] == IMMBIT
)
2560 || !strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2561 i
.instr
[1] = i
.op
.src
[0];
2563 else if (i
.imm_operands
== 1 && ((i
.op
.src
[0] & IMM
) == IMM
))
2564 i
.instr
[1] = i
.maxq20_op
[this_operand
].imms
;
2566 else if (i
.types
[this_operand
] == REG
&& ((i
.op
.src
[0] & REG
) == REG
))
2567 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].reg
)->opcode
);
2569 else if (i
.types
[this_operand
] == BIT
&& ((i
.op
.src
[0] & REG
) == REG
))
2570 i
.instr
[1] = (char) (i
.maxq20_op
[this_operand
].r_bit
->reg
->opcode
);
2572 else if (i
.types
[this_operand
] == MEM
&& ((i
.op
.src
[0] & MEM
) == MEM
))
2573 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].mem
)->opcode
);
2575 else if (i
.types
[this_operand
] == DATA
&& ((i
.op
.src
[0] & DATA
) == DATA
))
2576 /* This will copy only the lower order bytes into the instruction. The
2577 higher order bytes have already been copied into the prefix register. */
2580 /* Decoding the source in the case when the second array entry is not 0.
2581 This means that the source register has been divided into two nibbles. */
2583 else if (i
.op
.src
[1] != 0)
2585 /* If the first operand is a accumulator bit then
2586 the first 4 bits will be filled with the bit number. */
2587 if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & BIT
) == BIT
))
2589 unsigned char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2592 temp
|= i
.op
.src
[1];
2595 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2596 has to start with a zero. This is called a ZEROBIT */
2597 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ZEROBIT
) == ZEROBIT
))
2599 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2602 temp
|= i
.op
.src
[1];
2606 /* Similarly for a ONEBIT */
2607 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ONEBIT
) == ONEBIT
))
2609 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2612 temp
|= i
.op
.src
[1];
2616 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2618 else if (i
.types
[1] == BIT
)
2620 if (i
.op
.src
[1] == 0 && i
.op
.src
[1] == REG
)
2621 i
.instr
[1] = (i
.maxq20_op
[1].r_bit
)->reg
->opcode
;
2623 else if (i
.op
.src
[0] == BIT
&& i
.op
.src
)
2625 char temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2628 temp
|= i
.op
.src
[1];
2634 as_bad (_("Invalid Instruction"));
2641 /* This is a function for outputting displacement operands. */
2644 output_disp (fragS
*insn_start_frag
, offsetT insn_start_off
)
2647 relax_substateT subtype
;
2653 insn_start_frag
= frag_now
;
2654 insn_start_off
= frag_now_fix ();
2656 switch (i
.Instr_Prefix
)
2659 subtype
= EXPLICT_LONG_PREFIX
;
2662 subtype
= SHORT_PREFIX
;
2665 subtype
= NO_PREFIX
;
2669 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2670 case there is no need for relaxation. But we do need support for a
2671 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2672 for prefix + 2 for the current instruction ) Hence if at a particular
2673 time we find out whether the prefix operator is reqd , we shift the
2674 current instruction two places ahead and insert the prefix instruction. */
2678 sym
= i
.maxq20_op
[this_operand
].disps
->X_add_symbol
;
2679 off
= i
.maxq20_op
[this_operand
].disps
->X_add_number
;
2681 if (i
.maxq20_op
[this_operand
].disps
->X_add_symbol
!= NULL
&& sym
&& frag_now
2682 && (subtype
!= EXPLICT_LONG_PREFIX
))
2684 /* If in the same frag. */
2685 if (frag_now
== symbol_get_frag (sym
))
2688 ((((expressionS
*) symbol_get_value_expression (sym
))->
2689 X_add_number
) - insn_start_off
);
2691 /* PC points to the next instruction. */
2692 diff
= (diff
/ MAXQ_OCTETS_PER_BYTE
) - 1;
2694 if (diff
>= -128 && diff
<= 127)
2696 i
.instr
[1] = (char) diff
;
2698 /* This will be overwritten later when the symbol is resolved. */
2700 *(p
+ 1) = i
.instr
[0];
2702 /* No Need to create a FIXUP. */
2708 /* This will be overwritten later when the symbol is resolved. */
2710 *(p
+ 1) = i
.instr
[0];
2712 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2713 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2715 /* Handle complex expressions. */
2716 sym
= make_expr_symbol (i
.maxq20_op
[this_operand
].disps
);
2720 /* Vineet : This has been added for md_estimate_size_before_relax to
2721 estimate the correct size. */
2722 if (subtype
!= SHORT_PREFIX
)
2723 i
.reloc
[this_operand
] = LONG_PREFIX
;
2725 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2728 /* This is a function for outputting displacement operands. */
2731 output_data (fragS
*insn_start_frag
, offsetT insn_start_off
)
2734 relax_substateT subtype
;
2741 insn_start_frag
= frag_now
;
2742 insn_start_off
= frag_now_fix ();
2744 subtype
= EXPLICT_LONG_PREFIX
;
2749 sym
= i
.maxq20_op
[this_operand
].data
;
2752 /* This will be overwritten later when the symbol is resolved. */
2754 *(p
+ 1) = i
.instr
[0];
2756 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2757 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2758 /* Handle complex expressions. */
2759 /* Because data is already in terms of symbol so no
2760 need to convert it from expression to symbol. */
2763 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2769 fragS
*insn_start_frag
;
2770 offsetT insn_start_off
;
2773 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2774 do this after the insn has been output as the current frag may have been
2775 closed off. eg. by frag_var. */
2776 dwarf2_emit_insn (0);
2778 /* To ALign the text section on word. */
2780 frag_align (1, 0, 1);
2782 /* We initialise the frags for this particular instruction. */
2783 insn_start_frag
= frag_now
;
2784 insn_start_off
= frag_now_fix ();
2786 /* If there are displacement operators(unresolved) present, then handle
2788 if (i
.disp_operands
)
2790 output_disp (insn_start_frag
, insn_start_off
);
2794 if (i
.data_operands
)
2796 output_data (insn_start_frag
, insn_start_off
);
2800 /* Check whether the INSERT_BUFFER has to be written. */
2801 if (strcmp (INSERT_BUFFER
, ""))
2805 *p
++ = INSERT_BUFFER
[1];
2806 *p
= INSERT_BUFFER
[0];
2809 /* Check whether the prefix instruction has to be written. */
2810 if (strcmp (PFX_INSN
, ""))
2819 /* For Little endian. */
2825 make_new_reg_table (void)
2827 unsigned long size_pm
= sizeof (peripheral_reg_table
);
2828 num_of_reg
= ARRAY_SIZE (peripheral_reg_table
);
2830 new_reg_table
= xmalloc (size_pm
);
2831 if (new_reg_table
== NULL
)
2832 as_bad (_("Cannot allocate memory"));
2834 memcpy (new_reg_table
, peripheral_reg_table
, size_pm
);
2837 /* pmmain performs the initilizations for the pheripheral modules. */
2842 make_new_reg_table ();
2849 const char *hash_err
= NULL
;
2852 const MAXQ20_OPCODE_INFO
*optab
;
2853 MAXQ20_OPCODES
*core_optab
; /* For opcodes of the same name. This will
2854 be inserted into the hash table. */
2855 struct reg
*reg_tab
;
2856 struct mem_access_syntax
const *memsyntab
;
2857 struct mem_access
*memtab
;
2858 struct bit_name
*bittab
;
2860 /* Initilize pherioipheral modules. */
2863 /* Initialise the opcode hash table. */
2864 op_hash
= hash_new ();
2866 optab
= op_table
; /* Initialise it to the first entry of the
2867 maxq20 operand table. */
2869 /* Setup for loop. */
2870 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2871 core_optab
->start
= optab
;
2876 if (optab
->name
== NULL
|| strcmp (optab
->name
, (optab
- 1)->name
) != 0)
2878 /* different name --> ship out current template list; add to hash
2879 table; & begin anew. */
2881 core_optab
->end
= optab
;
2883 if (max_version
== bfd_mach_maxq10
)
2885 if (((optab
- 1)->arch
== MAXQ10
) || ((optab
- 1)->arch
== MAX
))
2887 hash_err
= hash_insert (op_hash
,
2892 else if (max_version
== bfd_mach_maxq20
)
2894 if (((optab
- 1)->arch
== MAXQ20
) || ((optab
- 1)->arch
== MAX
))
2897 hash_err
= hash_insert (op_hash
,
2904 as_fatal (_("Internal Error: Illegal Architecure specified"));
2907 as_fatal (_("Internal Error: Can't hash %s: %s"),
2908 (optab
- 1)->name
, hash_err
);
2910 if (optab
->name
== NULL
)
2912 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2913 core_optab
->start
= optab
;
2917 /* Initialise a new register table. */
2918 reg_hash
= hash_new ();
2920 for (reg_tab
= system_reg_table
;
2921 reg_tab
< (system_reg_table
+ ARRAY_SIZE (system_reg_table
));
2925 switch (max_version
)
2927 case bfd_mach_maxq10
:
2928 if ((reg_tab
->arch
== MAXQ10
) || (reg_tab
->arch
== MAX
))
2929 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
2932 case bfd_mach_maxq20
:
2933 if ((reg_tab
->arch
== MAXQ20
) || (reg_tab
->arch
== MAX
))
2937 hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
2942 as_fatal (_("Invalid architecture type"));
2947 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2948 reg_tab
->reg_name
, hash_err
);
2951 /* Pheripheral Registers Entry. */
2952 for (reg_tab
= new_reg_table
;
2953 reg_tab
< (new_reg_table
+ num_of_reg
- 1); reg_tab
++)
2955 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
2958 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2959 reg_tab
->reg_name
, hash_err
);
2962 /* Initialise a new memory operand table. */
2963 mem_hash
= hash_new ();
2965 for (memtab
= mem_table
;
2966 memtab
< mem_table
+ ARRAY_SIZE (mem_table
);
2969 hash_err
= hash_insert (mem_hash
, memtab
->name
, (PTR
) memtab
);
2971 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2972 memtab
->name
, hash_err
);
2975 bit_hash
= hash_new ();
2977 for (bittab
= bit_table
;
2978 bittab
< bit_table
+ ARRAY_SIZE (bit_table
);
2981 hash_err
= hash_insert (bit_hash
, bittab
->name
, (PTR
) bittab
);
2983 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2984 bittab
->name
, hash_err
);
2987 mem_syntax_hash
= hash_new ();
2989 for (memsyntab
= mem_access_syntax_table
;
2990 memsyntab
< mem_access_syntax_table
+ ARRAY_SIZE (mem_access_syntax_table
);
2994 hash_insert (mem_syntax_hash
, memsyntab
->name
, (PTR
) memsyntab
);
2996 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2997 memsyntab
->name
, hash_err
);
3000 /* Initialise the lexical tables,mnemonic chars,operand chars. */
3001 for (c
= 0; c
< 256; c
++)
3006 mnemonic_chars
[c
] = c
;
3007 operand_chars
[c
] = c
;
3008 register_chars
[c
] = c
;
3010 else if (ISLOWER (c
))
3012 mnemonic_chars
[c
] = c
;
3013 operand_chars
[c
] = c
;
3014 register_chars
[c
] = c
;
3016 else if (ISUPPER (c
))
3018 mnemonic_chars
[c
] = TOLOWER (c
);
3019 register_chars
[c
] = c
;
3020 operand_chars
[c
] = c
;
3023 if (ISALPHA (c
) || ISDIGIT (c
))
3025 identifier_chars
[c
] = c
;
3029 identifier_chars
[c
] = c
;
3030 operand_chars
[c
] = c
;
3034 /* All the special characters. */
3035 register_chars
['@'] = '@';
3036 register_chars
['+'] = '+';
3037 register_chars
['-'] = '-';
3038 digit_chars
['-'] = '-';
3039 identifier_chars
['_'] = '_';
3040 identifier_chars
['.'] = '.';
3041 register_chars
['['] = '[';
3042 register_chars
[']'] = ']';
3043 operand_chars
['_'] = '_';
3044 operand_chars
['#'] = '#';
3045 mnemonic_chars
['['] = '[';
3046 mnemonic_chars
[']'] = ']';
3048 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
3049 operand_chars
[(unsigned char) *p
] = (unsigned char) *p
;
3051 /* Set the maxq arch type. */
3052 maxq_target (max_version
);
3055 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3056 menmunonic in the operand table - Parse operands and populate the
3057 structure/template - Match the operand with opcode and its validity -
3061 md_assemble (char *line
)
3065 char mnemonic
[MAX_MNEM_SIZE
];
3066 char temp4prev
[256];
3067 static char prev_insn
[256];
3069 /* Initialize globals. */
3070 memset (&i
, '\0', sizeof (i
));
3071 for (j
= 0; j
< MAX_OPERANDS
; j
++)
3072 i
.reloc
[j
] = NO_RELOC
;
3077 INSERT_BUFFER
[0] = 0;
3078 INSERT_BUFFER
[1] = 0;
3080 memcpy (temp4prev
, line
, strlen (line
) + 1);
3082 save_stack_p
= save_stack
;
3084 line
= (char *) parse_insn (line
, mnemonic
);
3088 line
= (char *) parse_operands (line
, mnemonic
);
3092 /* Next, we find a template that matches the given insn, making sure the
3093 overlap of the given operands types is consistent with the template
3095 if (!match_template ())
3098 /* In the MAXQ20, there are certain register combinations, and other
3099 restrictions which are not allowed. We will try to resolve these right
3101 if (!match_filters ())
3104 /* Check for the approprate PFX register. */
3106 pfx_for_imm_val (0);
3108 if (!decode_insn ()) /* decode insn. */
3111 /* Check for Exlipct PFX instruction. */
3112 if (PFX_INSN
[0] && (strstr (prev_insn
, "PFX") || strstr (prev_insn
, "pfx")))
3113 as_warn (_("Ineffective insntruction %s \n"), prev_insn
);
3115 memcpy (prev_insn
, temp4prev
, strlen (temp4prev
) + 1);
3117 /* We are ready to output the insn. */