1 /* tc-maxq.c -- assembler code for a MAXQ chip.
3 Copyright 2004 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
= 20;
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 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
192 /* Any options support will be added onto this switch case. */
209 /* When a usage message is printed, this function is called and
210 it prints a description of the machine specific options. */
213 md_show_usage (FILE * stream
)
215 /* Over here we will fill the description of the machine specific options. */
217 fprintf (stream
, _(" MAXQ-specific assembler options:\n"));
219 fprintf (stream
, _("\
220 -MAXQ20 generate obj for MAXQ20(default)\n\
221 -MAXQ10 generate obj for MAXQ10\n\
229 if (!(strcmp (default_arch
, "MAXQ20")))
232 as_fatal (_("Unknown architecture"));
237 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
240 bfd_reloc_code_real_type code
;
242 switch (fixp
->fx_r_type
)
244 case MAXQ_INTERSEGMENT
:
246 case BFD_RELOC_16_PCREL_S2
:
247 code
= fixp
->fx_r_type
;
252 switch (fixp
->fx_size
)
255 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
256 _("can not do %d byte relocation"), fixp
->fx_size
);
272 rel
= xmalloc (sizeof (arelent
));
273 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
274 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
276 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
277 rel
->addend
= fixp
->fx_addnumber
;
278 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
280 if (rel
->howto
== NULL
)
282 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
283 _("cannot represent relocation type %s"),
284 bfd_get_reloc_code_name (code
));
286 /* Set howto to a garbage value so that we can keep going. */
287 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
288 assert (rel
->howto
!= NULL
);
296 /* md_estimate_size_before_relax()
298 Called just before relax() for rs_machine_dependent frags. The MAXQ
299 assembler uses these frags to handle 16 bit absolute jumps which require a
300 prefix instruction to be inserted. Any symbol that is now undefined will
301 not become defined. Return the correct fr_subtype in the frag. Return the
302 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
303 caller. The guess is actually the growth beyond the fixed part. Whatever
304 we do to grow the fixed or variable part contributes to our returned
308 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
310 /* Check whether the symbol has been resolved or not.
311 Otherwise we will have to generate a fixup. */
312 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
)
313 || fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
315 RELOC_ENUM reloc_type
;
316 unsigned char *opcode
;
319 /* Now this symbol has not been defined in this file.
320 Hence we will have to create a fixup. */
323 /* This is for the prefix instruction. */
325 if (fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
326 fragP
->fr_subtype
= LONG_PREFIX
;
328 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
329 && ((!(fragP
->fr_subtype
) == EXPLICT_LONG_PREFIX
)))
330 fragP
->fr_subtype
= ABSOLUTE_ADDR_FOR_DATA
;
333 (fragP
->fr_subtype
? fragP
->fr_subtype
: ABSOLUTE_ADDR_FOR_DATA
);
335 fragP
->fr_subtype
= reloc_type
;
337 if (reloc_type
== SHORT_PREFIX
)
339 old_fr_fix
= fragP
->fr_fix
;
340 opcode
= (unsigned char *) fragP
->fr_opcode
;
342 fragP
->fr_fix
+= (size
);
344 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
345 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
347 return fragP
->fr_fix
- old_fr_fix
;
350 if (fragP
->fr_subtype
== SHORT_PREFIX
)
352 fragP
->fr_subtype
= SHORT_PREFIX
;
356 if (fragP
->fr_subtype
== NO_PREFIX
|| fragP
->fr_subtype
== LONG_PREFIX
)
359 unsigned long call_addr
;
363 call_addr
= call_addr
^ call_addr
;
367 /* segment_info_type *seginfo = seg_info (segment); */
368 instr
= fragP
->fr_address
+ fragP
->fr_fix
- 2;
370 /* This is the offset if it is a PC relative jump. */
371 call_addr
= S_GET_VALUE (fragP
->fr_symbol
) + fragP
->fr_offset
;
372 diff
= (call_addr
- instr
);
374 if (diff
>= (-128 * 2) && diff
<= (2 * 127))
376 /* Now as offset is an 8 bit value, we will pass
377 that to the jump instruction directly. */
378 fragP
->fr_subtype
= NO_PREFIX
;
382 fragP
->fr_subtype
= LONG_PREFIX
;
386 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
391 /* Equal to MAX_PRECISION in atof-ieee.c */
392 #define MAX_LITTLENUMS 6
394 /* Turn a string in input_line_pointer into a floating point constant of type
395 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
396 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
399 md_atof (int type
, char * litP
, int * sizeP
)
402 LITTLENUM_TYPE words
[4];
414 /* The size of Double has been changed to 2 words ie 32 bits. */
420 return _("bad call to md_atof");
423 t
= atof_ieee (input_line_pointer
, type
, words
);
425 input_line_pointer
= t
;
429 for (i
= prec
- 1; i
>= 0; i
--)
431 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
439 maxq20_cons_fix_new (fragS
* frag
, unsigned int off
, unsigned int len
,
447 r
= MAXQ_WORDDATA
; /* Word+n */
450 r
= MAXQ_LONGDATA
; /* Long+n */
454 fix_new_exp (frag
, off
, len
, exp
, 0, r
);
459 tc_coff_fix2rtype (fixS
* fixP
)
461 return fixP
->fx_r_type
;
465 tc_coff_sizemachdep (fragS
*fragP
)
468 return (fragP
->fr_next
->fr_address
- fragP
->fr_address
);
473 /* GAS will call this for every rs_machine_dependent fragment. The
474 instruction is compleated using the data from the relaxation pass. It may
475 also create any necessary relocations. */
478 md_convert_frag (bfd
* headers ATTRIBUTE_UNUSED
,
479 segT seg ATTRIBUTE_UNUSED
,
483 md_convert_frag (object_headers
* headers ATTRIBUTE_UNUSED
,
484 segT sec ATTRIBUTE_UNUSED
,
488 unsigned char *opcode
;
489 offsetT target_address
;
490 offsetT opcode_address
;
491 offsetT displacement_from_opcode_start
;
494 opcode
= fragP
->fr_opcode
;
496 target_address
= opcode_address
= displacement_from_opcode_start
= 0;
499 (S_GET_VALUE (fragP
->fr_symbol
) / MAXQ_OCTETS_PER_BYTE
) +
500 (fragP
->fr_offset
/ MAXQ_OCTETS_PER_BYTE
);
503 (fragP
->fr_address
/ MAXQ_OCTETS_PER_BYTE
) +
504 ((fragP
->fr_fix
- 2) / MAXQ_OCTETS_PER_BYTE
);
506 displacement_from_opcode_start
= (target_address
- opcode_address
);
508 if ((displacement_from_opcode_start
>= -128
509 && displacement_from_opcode_start
<= 127)
510 && (fragP
->fr_subtype
== SHORT_PREFIX
511 || fragP
->fr_subtype
== NO_PREFIX
))
513 /* Its a displacement. */
514 char *p
= (char *) &opcode
[0];
516 *p
= (char) displacement_from_opcode_start
;
520 /* Its an absolute 16 bit jump. Now we have to
521 load the prefix operator with the upper 8 bits. */
522 if (fragP
->fr_subtype
== SHORT_PREFIX
)
524 as_bad (_("Cant make long jump/call into short jump/call : %d"),
529 /* Check whether the symbol has been resolved or not.
530 Otherwise we will have to generate a fixup. */
532 if (fragP
->fr_subtype
!= SHORT_PREFIX
)
534 RELOC_ENUM reloc_type
;
535 unsigned char *opcode
;
539 /* Now this is a basolute jump/call.
540 Hence we will have to create a fixup. */
541 if (fragP
->fr_subtype
== NO_PREFIX
)
542 fragP
->fr_subtype
= LONG_PREFIX
;
545 (fragP
->fr_subtype
? fragP
->fr_subtype
: LONG_PREFIX
);
549 old_fr_fix
= fragP
->fr_fix
;
550 opcode
= (unsigned char *) fragP
->fr_opcode
;
552 fragP
->fr_fix
+= (size
);
554 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
555 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
562 md_pcrel_from (fixS
*fixP
)
564 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
567 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
570 maxq_number_to_chars (char *buf
, valueT val
, int n
)
572 if (target_big_endian
)
573 number_to_chars_bigendian (buf
, val
, n
);
575 number_to_chars_littleendian (buf
, val
, n
);
578 /* GAS will call this for each fixup. It's main objective is to store the
579 correct value in the object file. 'fixup_segment' performs the generic
580 overflow check on the 'valueT *val' argument after md_apply_fix3 returns.
581 If the overflow check is relevant for the target machine, then
582 'md_apply_fix3' should modify 'valueT *val', typically to the value stored
583 in the object file (not to be done in MAXQ). */
586 md_apply_fix3 (fixS
*fixP
, valueT
*valT
, segT seg ATTRIBUTE_UNUSED
)
588 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
589 char *frag_to_fix_at
=
590 fixP
->fx_frag
->fr_literal
+ fixP
->fx_frag
->fr_fix
- 2;
594 if (fixP
->fx_frag
&& valT
)
596 /* If the relaxation substate is not defined we make it equal
597 to the kind of relocation the fixup is generated for. */
598 if (!fixP
->fx_frag
->fr_subtype
)
599 fixP
->fx_frag
->fr_subtype
= fixP
->fx_r_type
;
601 /* For any instruction in which either we have specified an
602 absolute address or it is a long jump we need to add a PFX0
603 instruction to it. In this case as the instruction has already
604 being written at 'fx_where' in the frag we copy it at the end of
605 the frag(which is where the relocation was generated) as when
606 the relocation is generated the frag is grown by 2 type, this is
607 where we copy the contents of fx_where and add a pfx0 at
609 if ((fixP
->fx_frag
->fr_subtype
== ABSOLUTE_ADDR_FOR_DATA
)
610 || (fixP
->fx_frag
->fr_subtype
== LONG_PREFIX
))
612 *(frag_to_fix_at
+ 1) = *(p
+ 1);
613 maxq_number_to_chars (p
+ 1, PFX0
, 1);
617 /* Remember value for tc_gen_reloc. */
618 fixP
->fx_addnumber
= *valT
;
622 /* This prob can be fixed by defining tc_fix_adjustable. */
623 #ifndef BFD_ASSEMBLER
624 if (fixP
->fx_addsy
&& S_GET_SEGMENT (fixP
->fx_addsy
))
625 segment_info
[S_GET_SEGMENT (fixP
->fx_addsy
)].dot
= NULL
;
628 /* Some fixups generated by GAS which gets resovled before this this
629 func. is called need to be wriiten to the frag as here we are going
630 to go away with the relocations fx_done=1. */
631 if (fixP
->fx_addsy
== NULL
)
633 maxq_number_to_chars (p
, *valT
, fixP
->fx_size
);
634 fixP
->fx_addnumber
= *valT
;
640 /* Tables for lexical analysis. */
641 static char mnemonic_chars
[256];
642 static char register_chars
[256];
643 static char operand_chars
[256];
644 static char identifier_chars
[256];
645 static char digit_chars
[256];
647 /* Lexical Macros. */
648 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
649 #define is_register_char(x) (register_chars[(unsigned char)(x)])
650 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
651 #define is_space_char(x) (x==' ')
652 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
653 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
655 /* Special characters for operands. */
656 static char operand_special_chars
[] = "[]@.-+";
658 /* md_assemble() will always leave the instruction passed to it unaltered.
659 To do this we store the instruction in a special stack. */
660 static char save_stack
[32];
661 static char *save_stack_p
;
663 #define END_STRING_AND_SAVE(s) \
666 *save_stack_p++ = *(s); \
671 #define RESTORE_END_STRING(s) \
674 *(s) = *(--save_stack_p); \
678 /* The instruction we are assembling. */
679 static maxq20_insn i
;
681 /* The current template. */
682 static MAXQ20_OPCODES
*current_templates
;
684 /* The displacement operand if any. */
685 static expressionS disp_expressions
;
687 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
688 static int this_operand
;
690 /* The prefix instruction if used. */
691 static char PFX_INSN
[2];
692 static char INSERT_BUFFER
[2];
694 /* For interface with expression() ????? */
695 extern char *input_line_pointer
;
697 /* The HASH Tables: */
699 /* Operand Hash Table. */
700 static struct hash_control
*op_hash
;
702 /* Register Hash Table. */
703 static struct hash_control
*reg_hash
;
705 /* Memory reference Hash Table. */
706 static struct hash_control
*mem_hash
;
708 /* Bit hash table. */
709 static struct hash_control
*bit_hash
;
711 /* Memory Access syntax table. */
712 static struct hash_control
*mem_syntax_hash
;
714 /* This is a mapping from pseudo-op names to functions. */
716 const pseudo_typeS md_pseudo_table
[] =
718 {"int", cons
, 2}, /* size of 'int' has been changed to 1 word
723 #if defined(BFD_HEADERS)
725 const int md_reloc_size
= RELSZ
; /* Coff headers. */
727 const int md_reloc_size
= 12; /* Something else headers. */
730 const int md_reloc_size
= 12; /* Not bfdized. */
733 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
736 /* This function sets the PFX value coresponding to the specs. Source
737 Destination Index Selection ---------------------------------- Write To|
738 SourceRegRange | Dest Addr Range
739 ------------------------------------------------------ PFX[0] | 0h-Fh |
740 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
741 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
742 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
747 short int src_index
= 0, dst_index
= 0;
751 if (i
.operands
== 1) /* Only SRC is Present */
753 if (i
.types
[0] == REG
)
755 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
757 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
762 src_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
770 if (i
.types
[0] == REG
&& i
.types
[1] == REG
)
772 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
773 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
775 else if (i
.types
[0] != REG
&& i
.types
[1] == REG
) /* DST is Absent */
777 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
780 else if (i
.types
[0] == REG
&& i
.types
[1] != REG
) /* Id SRC is Absent */
782 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
785 else if (i
.types
[0] == BIT
&& i
.maxq20_op
[0].r_bit
)
787 dst_index
= i
.maxq20_op
[0].r_bit
->reg
->Mod_index
;
791 else if (i
.types
[1] == BIT
&& i
.maxq20_op
[1].r_bit
)
794 src_index
= i
.maxq20_op
[1].r_bit
->reg
->Mod_index
;
798 if (src_index
>= 0x00 && src_index
<= 0xF)
800 if (dst_index
>= 0x00 && dst_index
<= 0x07)
804 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
808 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
812 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
816 else if (src_index
>= 0x10 && src_index
<= 0x1F)
818 if (dst_index
>= 0x00 && dst_index
<= 0x07)
822 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
826 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
830 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
837 is_a_LSinstr (const char *ln_pointer
)
841 for (i
= 0; LSInstr
[i
] != NULL
; i
++)
842 if (!strcmp (LSInstr
[i
], ln_pointer
))
849 LS_processing (const char *line
)
851 if (is_a_LSinstr (line
))
853 if ((line
[0] == 'L') || (line
[0] == 'l'))
856 INSERT_BUFFER
[0] = PFX0
;
857 i
.Instr_Prefix
= LONG_PREFIX
;
859 else if ((line
[0] == 'S') || (line
[0] == 's'))
860 i
.Instr_Prefix
= SHORT_PREFIX
;
862 i
.Instr_Prefix
= NO_PREFIX
;
865 i
.Instr_Prefix
= LONG_PREFIX
;
868 /* Separate mnemonics and the operands. */
871 parse_insn (char *line
, char *mnemonic
)
874 char *token_start
= l
;
876 char temp
[MAX_MNEM_SIZE
];
879 memset (temp
, END_OF_INSN
, MAX_MNEM_SIZE
);
882 while ((*mnem_p
= mnemonic_chars
[(unsigned char) *l
]) != 0)
886 if (mnem_p
>= mnemonic
+ MAX_MNEM_SIZE
)
888 as_bad (_("no such instruction: `%s'"), token_start
);
894 if (!is_space_char (*l
) && *l
!= END_OF_INSN
)
896 as_bad (_("invalid character %s in mnemonic"), l
);
902 temp
[ii
- 1] = toupper ((char) mnemonic
[ii
- 1]);
906 LS_processing (temp
);
908 if (i
.Instr_Prefix
!= 0 && is_a_LSinstr (temp
))
909 /* Skip the optional L-S. */
910 memcpy (temp
, temp
+ 1, MAX_MNEM_SIZE
);
912 /* Look up instruction (or prefix) via hash table. */
913 current_templates
= (MAXQ20_OPCODES
*) hash_find (op_hash
, temp
);
915 if (current_templates
!= NULL
)
918 as_bad (_("no such instruction: `%s'"), token_start
);
922 /* Function to calculate x to the power of y.
923 Just to avoid including the math libraries. */
930 for (k
= 0; k
< y
; k
++)
937 parse_reg_by_index (char *imm_start
)
939 int k
= 0, mid
= 0, rid
= 0, val
= 0, j
= 0;
940 char temp
[4] = { 0 };
941 reg_entry
*reg
= NULL
;
945 if (isdigit (imm_start
[k
]))
946 temp
[k
] = imm_start
[k
] - '0';
948 else if (isalpha (imm_start
[k
])
949 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
950 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
952 else if (imm_start
[k
] == 'h')
955 else if (imm_start
[k
] == END_OF_INSN
)
962 return NULL
; /* not a hex digit */
966 while (imm_start
[k
] != '\n');
968 switch (imm_start
[k
])
971 for (j
= 0; j
< k
; j
++)
972 val
+= temp
[j
] * pwr (16, k
- j
- 1);
976 for (j
= 0; j
< k
; j
++)
979 return NULL
; /* not a number */
981 val
+= temp
[j
] * pwr (10, k
- j
- 1);
986 /* Get the module and register id's. */
988 rid
= (val
>> 4) & 0x0f;
992 /* Search the pheripheral reg table. */
993 for (j
= 0; j
< num_of_reg
; j
++)
995 if (new_reg_table
[j
].opcode
== val
)
997 reg
= (reg_entry
*) & new_reg_table
[j
];
1005 /* Search the system register table. */
1008 while (system_reg_table
[j
].reg_name
!= NULL
)
1010 if (system_reg_table
[j
].opcode
== val
)
1012 reg
= (reg_entry
*) & system_reg_table
[j
];
1021 as_bad (_("Invalid register value %s"), imm_start
);
1026 if (this_operand
== 0 && reg
!= NULL
)
1028 if (reg
->Mod_index
> 7)
1034 return (reg_entry
*) reg
;
1037 /* REG_STRING starts *before* REGISTER_PREFIX. */
1040 parse_register (char *reg_string
, char **end_op
)
1042 char *s
= reg_string
;
1044 char reg_name_given
[MAX_REG_NAME_SIZE
+ 1];
1045 reg_entry
*r
= NULL
;
1050 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1051 if (is_space_char (*s
))
1055 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1057 if (p
>= reg_name_given
+ MAX_REG_NAME_SIZE
)
1058 return (reg_entry
*) NULL
;
1064 r
= (reg_entry
*) hash_find (reg_hash
, reg_name_given
);
1067 if (this_operand
== 0 && r
!= NULL
)
1069 if (r
->Mod_index
> 7)
1079 parse_register_bit (char *reg_string
, char **end_op
)
1081 const char *s
= reg_string
;
1085 reg_entry
*r
= NULL
;
1087 char temp_bitname
[MAX_REG_NAME_SIZE
+ 2];
1088 char temp
[MAX_REG_NAME_SIZE
+ 1];
1090 memset (&temp
, '\0', (MAX_REG_NAME_SIZE
+ 1));
1091 memset (&temp_bitname
, '\0', (MAX_REG_NAME_SIZE
+ 2));
1096 rb
= xmalloc (sizeof (reg_bit
));
1097 rb
->reg
= xmalloc (sizeof (reg_entry
));
1100 /* For supporting bit names. */
1101 b
= (bit_name
*) hash_find (bit_hash
, reg_string
);
1105 *end_op
= reg_string
+ strlen (reg_string
);
1106 strcpy (temp_bitname
, b
->reg_bit
);
1110 if (strchr (s
, '.'))
1123 if ((r
= parse_register (temp
, end_op
)) == NULL
)
1131 if (isdigit ((char) *s
))
1133 else if (isalpha ((char) *s
))
1135 rb
->bit
= (char) *s
- 'a';
1139 as_bad (_("Invalid bit number : '%c'"), (char) *s
);
1145 diff
= strlen (temp_bitname
) - strlen (temp
) - 1;
1147 diff
= strlen (reg_string
) - strlen (temp
) - 1;
1149 if (*(s
+ diff
) != '\0')
1151 as_bad (_("Illegal character after operand '%s'"), reg_string
);
1159 pfx_for_imm_val (int arg
)
1164 if (i
.prefix
== 0 && arg
== 0 && PFX_INSN
[1] == 0 && !(i
.data_operands
))
1167 if (!(i
.prefix
< 0) && !(i
.prefix
> 7))
1168 PFX_INSN
[0] = (i
.prefix
<< 4) | PFX0
;
1176 maxq20_immediate (char *imm_start
)
1178 int val
= 0, val_pfx
= 0;
1181 int temp
[4] = { 0 };
1185 if (imm_start
[1] == '\0' && (imm_start
[0] == '0' || imm_start
[0] == '1')
1186 && (this_operand
== 1 && ((i
.types
[0] == BIT
|| i
.types
[0] == FLAG
))))
1188 val
= imm_start
[0] - '0';
1189 i
.imm_bit_operands
++;
1190 i
.types
[this_operand
] = IMMBIT
;
1191 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1194 pfx_for_imm_val (0);
1199 /* Check For Sign Charcater. */
1204 if (imm_start
[k
] == '-' && k
== 0)
1207 else if (imm_start
[k
] == '+' && k
== 0)
1210 else if (isdigit (imm_start
[k
]))
1211 temp
[k
] = imm_start
[k
] - '0';
1213 else if (isalpha (imm_start
[k
])
1214 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
1215 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
1217 else if (imm_start
[k
] == 'h')
1220 else if (imm_start
[k
] == '\0')
1227 as_bad (_("Invalid Character in immediate Value : %c"),
1233 while (imm_start
[k
] != '\n');
1235 switch (imm_start
[k
])
1238 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1239 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1243 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1247 as_bad (_("Invalid Character in immediate value : %c"),
1251 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1258 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1259 check if we are moving a 16 bit immediate value into an 8 bit register.
1260 In that case we will generate a warning and move only the lower 8 bits */
1263 as_bad (_("Immediate value greater than 16 bits"));
1267 val
= val
* sign_val
;
1269 /* If it is a stack pointer and the value is greater than the maximum
1271 if (this_operand
== 1)
1273 if ((val
* sign_val
) > MAX_STACK
&& i
.types
[0] == REG
1274 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
1277 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1278 val
= val
& MAX_STACK
;
1281 /* Check the range for 8 bit registers. */
1282 else if (((val
* sign_val
) > 0xFF) && (i
.types
[0] == REG
)
1283 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1286 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1290 else if (((sign_val
== -1) || (val
> 0xFF)) && (i
.types
[0] == REG
)
1291 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1294 val
= ((val
) & 0x00ff);
1295 SET_PFX_ARG (val_pfx
);
1296 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1299 else if ((val
<= 0xff) && (i
.types
[0] == REG
)
1300 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1301 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1304 /* Check for 16 bit registers. */
1305 else if (((sign_val
== -1) || val
> 0xFE) && i
.types
[0] == REG
1306 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1308 /* Add PFX for any negative value -> 16bit register. */
1310 val
= ((val
) & 0x00ff);
1311 SET_PFX_ARG (val_pfx
);
1312 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1315 else if (val
< 0xFF && i
.types
[0] == REG
1316 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1318 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1321 /* All the immediate memory access - no PFX. */
1322 else if (i
.types
[0] == MEM
)
1324 if ((sign_val
== -1) || val
> 0xFE)
1327 val
= ((val
) & 0x00ff);
1328 SET_PFX_ARG (val_pfx
);
1329 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1332 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1335 /* Special handling for immediate jumps like jump nz, #03h etc. */
1336 else if (val
< 0xFF && i
.types
[0] == FLAG
)
1337 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1339 else if ((((sign_val
== -1) || val
> 0xFE)) && i
.types
[0] == FLAG
)
1342 val
= ((val
) & 0x00ff);
1343 SET_PFX_ARG (val_pfx
);
1344 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1348 as_bad (_("Invalid immediate move operation"));
1354 /* All the instruction with operation on ACC: like ADD src, etc. */
1355 if ((sign_val
== -1) || val
> 0xFE)
1358 val
= ((val
) & 0x00ff);
1359 SET_PFX_ARG (val_pfx
);
1360 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1363 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1371 extract_int_val (const char *imm_start
)
1383 if (imm_start
[k
] == '-' && k
== 0)
1386 else if (imm_start
[k
] == '+' && k
== 0)
1389 else if (isdigit (imm_start
[k
]))
1390 temp
[k
] = imm_start
[k
] - '0';
1392 else if (isalpha (imm_start
[k
]) && (tolower (imm_start
[k
])) < 'g')
1393 temp
[k
] = 10 + (int) (tolower (imm_start
[k
]) - 'a');
1395 else if (tolower (imm_start
[k
]) == 'h')
1398 else if ((imm_start
[k
] == '\0') || (imm_start
[k
] == ']'))
1399 /* imm_start[k]='d'; */
1404 as_bad (_("Invalid Character in immediate Value : %c"),
1410 while (imm_start
[k
] != '\n');
1412 switch (imm_start
[k
])
1415 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1416 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1420 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1424 as_bad (_("Invalid Character in immediate value : %c"),
1428 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1435 return val
* sign_val
;
1439 check_for_parse (const char *line
)
1443 if (*(line
+ 1) == '[')
1448 if ((*line
== '-') || (*line
== '+'))
1451 while (!is_space_char (*line
));
1453 if ((*line
== '-') || (*line
== '+'))
1454 val
= extract_int_val (line
);
1456 val
= extract_int_val (line
+ 1);
1458 INSERT_BUFFER
[0] = 0x3E;
1459 INSERT_BUFFER
[1] = val
;
1468 maxq20_mem_access (char *mem_string
, char **end_op
)
1470 char *s
= mem_string
;
1472 char mem_name_given
[MAX_MEM_NAME_SIZE
+ 1];
1477 /* Skip possible whitespace. */
1478 if (is_space_char (*s
))
1482 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1484 if (p
>= mem_name_given
+ MAX_MEM_NAME_SIZE
)
1485 return (mem_access
*) NULL
;
1491 m
= (mem_access
*) hash_find (mem_hash
, mem_name_given
);
1496 /* This function checks whether the operand is a variable in the data segment
1497 and if so, it returns its symbol entry from the symbol table. */
1500 maxq20_data (char *op_string
)
1503 symbolP
= symbol_find (op_string
);
1506 && S_GET_SEGMENT (symbolP
) != now_seg
1507 && S_GET_SEGMENT (symbolP
) !=
1508 #ifdef BFD_ASSEMBLER
1517 #ifdef BFD_ASSEMBLER
1520 val_pfx
= (symbolP
->sy_value
.X_add_number
) >> 8;
1523 /* In case we do not want to always include the prefix instruction and
1524 let the loader handle the job or in case of a 8 bit addressing mode,
1525 we will just check for val_pfx to be equal to zero and then load the
1526 prefix instruction. Otherwise no prefix instruction needs to be
1528 /* The prefix register will have to be loaded automatically as we have
1529 a 16 bit addressing field. */
1530 pfx_for_imm_val (val_pfx
);
1538 maxq20_displacement (char *disp_start
, char *disp_end
)
1542 char *save_input_line_pointer
;
1544 char *gotfree_input_line
;
1547 gotfree_input_line
= NULL
;
1548 exp
= &disp_expressions
;
1549 i
.maxq20_op
[this_operand
].disps
= exp
;
1551 save_input_line_pointer
= input_line_pointer
;
1552 input_line_pointer
= disp_start
;
1554 END_STRING_AND_SAVE (disp_end
);
1557 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1558 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1560 exp_seg
= expression (exp
);
1563 if (*input_line_pointer
)
1564 as_bad (_("junk `%s' after expression"), input_line_pointer
);
1566 RESTORE_END_STRING (disp_end
+ 1);
1568 RESTORE_END_STRING (disp_end
);
1569 input_line_pointer
= save_input_line_pointer
;
1571 if (gotfree_input_line
)
1572 free (gotfree_input_line
);
1574 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1576 /* Missing or bad expr becomes absolute 0. */
1577 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1579 exp
->X_op
= O_constant
;
1580 exp
->X_add_number
= 0;
1581 exp
->X_add_symbol
= (symbolS
*) 0;
1582 exp
->X_op_symbol
= (symbolS
*) 0;
1584 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1586 if (exp
->X_op
!= O_constant
1587 #ifdef BFD_ASSEMBLER
1588 && OUTPUT_FLAVOR
== bfd_target_aout_flavour
1590 && exp_seg
!= absolute_section
1591 && exp_seg
!= text_section
1592 && exp_seg
!= data_section
1593 && exp_seg
!= bss_section
&& exp_seg
!= undefined_section
1594 #ifdef BFD_ASSEMBLER
1595 && !bfd_is_com_section (exp_seg
)
1599 #ifdef BFD_ASSEMBLER
1600 as_bad (_("unimplemented segment %s in operand"), exp_seg
->name
);
1602 as_bad (_("unimplemented segment type %d in operand"), exp_seg
);
1607 i
.maxq20_op
[this_operand
].disps
= exp
;
1611 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1612 Returns non-zero on error. */
1615 maxq20_operand (char *operand_string
)
1617 reg_entry
*r
= NULL
;
1619 mem_access
*m
= NULL
;
1620 char *end_op
= NULL
;
1621 symbolS
*sym
= NULL
;
1622 char *base_string
= NULL
;
1624 /* Start and end of displacement string expression (if found). */
1625 char *displacement_string_start
= NULL
;
1626 char *displacement_string_end
= NULL
;
1627 /* This maintains the case sentivness. */
1628 char case_str_op_string
[MAX_OPERAND_SIZE
+ 1];
1629 char str_op_string
[MAX_OPERAND_SIZE
+ 1];
1630 char *org_case_op_string
= case_str_op_string
;
1631 char *op_string
= str_op_string
;
1634 memset (op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1635 memset (org_case_op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1637 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1638 memcpy (org_case_op_string
, operand_string
, strlen (operand_string
) + 1);
1640 ii
= strlen (operand_string
) + 1;
1642 if (ii
> MAX_OPERAND_SIZE
)
1644 as_bad (_("Size of Operand '%s' greater than %d"), op_string
,
1651 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1655 if (is_space_char (*op_string
))
1658 if (isxdigit (operand_string
[0]))
1660 /* Now the operands can start with an Integer. */
1661 r
= parse_reg_by_index (op_string
);
1664 if (is_space_char (*op_string
))
1666 i
.types
[this_operand
] = REG
; /* Set the type. */
1667 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1672 /* Get the origanal string. */
1673 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1674 ii
= strlen (operand_string
) + 1;
1678 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1683 /* Check for flags. */
1684 if (!strcmp (op_string
, "Z"))
1686 if (is_space_char (*op_string
))
1689 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1690 i
.maxq20_op
[this_operand
].flag
= FLAG_Z
; /* Set the Register value. */
1697 else if (!strcmp (op_string
, "NZ"))
1699 if (is_space_char (*op_string
))
1702 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1703 i
.maxq20_op
[this_operand
].flag
= FLAG_NZ
; /* Set the Register value. */
1708 else if (!strcmp (op_string
, "NC"))
1710 if (is_space_char (*op_string
))
1713 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1714 i
.maxq20_op
[this_operand
].flag
= FLAG_NC
; /* Set the Register value. */
1719 else if (!strcmp (op_string
, "E"))
1721 if (is_space_char (*op_string
))
1724 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1725 i
.maxq20_op
[this_operand
].flag
= FLAG_E
; /* Set the Register value. */
1732 else if (!strcmp (op_string
, "S"))
1734 if (is_space_char (*op_string
))
1737 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1738 i
.maxq20_op
[this_operand
].flag
= FLAG_S
; /* Set the Register value. */
1745 else if (!strcmp (op_string
, "C"))
1747 if (is_space_char (*op_string
))
1750 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1751 i
.maxq20_op
[this_operand
].flag
= FLAG_C
; /* Set the Register value. */
1758 else if (!strcmp (op_string
, "NE"))
1761 if (is_space_char (*op_string
))
1764 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1766 i
.maxq20_op
[this_operand
].flag
= FLAG_NE
; /* Set the Register value. */
1773 /* CHECK FOR REGISTER BIT */
1774 else if ((rb
= parse_register_bit (op_string
, &end_op
)) != NULL
)
1778 if (is_space_char (*op_string
))
1781 i
.types
[this_operand
] = BIT
;
1783 i
.maxq20_op
[this_operand
].r_bit
= rb
;
1790 else if (*op_string
== IMMEDIATE_PREFIX
) /* FOR IMMEDITE. */
1792 if (is_space_char (*op_string
))
1795 i
.types
[this_operand
] = IMM
;
1797 if (!maxq20_immediate (op_string
))
1799 as_bad (_("illegal immediate operand '%s'"), op_string
);
1805 else if (*op_string
== ABSOLUTE_PREFIX
|| !strcmp (op_string
, "NUL"))
1807 if (is_space_char (*op_string
))
1810 /* For new requiremnt of copiler of for, @(BP,cons). */
1811 if (check_for_parse (op_string
))
1813 memset (op_string
, '\0', strlen (op_string
) + 1);
1814 memcpy (op_string
, "@BP[OFFS]\0", 11);
1817 i
.types
[this_operand
] = MEM
;
1819 if ((m
= maxq20_mem_access (op_string
, &end_op
)) == NULL
)
1821 as_bad (_("Invalid operand for memory access '%s'"), op_string
);
1824 i
.maxq20_op
[this_operand
].mem
= m
;
1831 else if ((r
= parse_register (op_string
, &end_op
)) != NULL
) /* Check for register. */
1835 if (is_space_char (*op_string
))
1838 i
.types
[this_operand
] = REG
; /* Set the type. */
1839 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1844 if (this_operand
== 1)
1846 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1847 /* The operand can either be a data reference or a symbol reference. */
1848 if ((sym
= maxq20_data (org_case_op_string
)) != NULL
) /* Check for data memory. */
1850 while (is_space_char (*op_string
))
1853 /* Set the type of the operand. */
1854 i
.types
[this_operand
] = DATA
;
1856 /* Set the value of the data. */
1857 i
.maxq20_op
[this_operand
].data
= sym
;
1863 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1865 /* This is a memory reference of some sort. char *base_string;
1866 Start and end of displacement string expression (if found). char
1867 *displacement_string_start; char *displacement_string_end. */
1868 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1871 if (is_space_char (*base_string
))
1874 /* If we only have a displacement, set-up for it to be parsed
1876 displacement_string_start
= org_case_op_string
;
1877 displacement_string_end
= base_string
+ 1;
1878 if (displacement_string_start
!= displacement_string_end
)
1880 if (!maxq20_displacement (displacement_string_start
,
1881 displacement_string_end
))
1883 as_bad (_("illegal displacement operand "));
1886 /* A displacement operand found. */
1887 i
.types
[this_operand
] = DISP
; /* Set the type. */
1893 /* Check for displacement. */
1894 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1896 /* This is a memory reference of some sort. char *base_string;
1897 Start and end of displacement string expression (if found). char
1898 *displacement_string_start; char *displacement_string_end; */
1899 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1902 if (is_space_char (*base_string
))
1905 /* If we only have a displacement, set-up for it to be parsed later. */
1906 displacement_string_start
= org_case_op_string
;
1907 displacement_string_end
= base_string
+ 1;
1908 if (displacement_string_start
!= displacement_string_end
)
1910 if (!maxq20_displacement (displacement_string_start
,
1911 displacement_string_end
))
1913 /* A displacement operand found. */
1914 i
.types
[this_operand
] = DISP
; /* Set the type. */
1920 /* Parse_operand takes as input instruction and operands and Parse operands
1921 and makes entry in the template. */
1924 parse_operands (char *l
, const char *mnemonic
)
1928 /* 1 if operand is pending after ','. */
1929 short int expecting_operand
= 0;
1931 /* Non-zero if operand parens not balanced. */
1932 short int paren_not_balanced
;
1936 /* For Overcoming Warning of unused variable. */
1940 while (*l
!= END_OF_INSN
)
1942 /* Skip optional white space before operand. */
1943 if (is_space_char (*l
))
1946 if (!is_operand_char (*l
) && *l
!= END_OF_INSN
)
1948 as_bad (_("invalid character %c before operand %d"),
1949 (char) (*l
), i
.operands
+ 1);
1954 paren_not_balanced
= 0;
1955 while (paren_not_balanced
|| *l
!= ',')
1957 if (*l
== END_OF_INSN
)
1959 if (paren_not_balanced
)
1961 as_bad (_("unbalanced brackets in operand %d."),
1968 else if (!is_operand_char (*l
) && !is_space_char (*l
))
1970 as_bad (_("invalid character %c in operand %d"),
1971 (char) (*l
), i
.operands
+ 1);
1975 ++paren_not_balanced
;
1977 --paren_not_balanced
;
1981 if (l
!= token_start
)
1983 /* Yes, we've read in another operand. */
1984 this_operand
= i
.operands
++;
1985 if (i
.operands
> MAX_OPERANDS
)
1987 as_bad (_("spurious operands; (%d operands/instruction max)"),
1992 /* Now parse operand adding info to 'i' as we go along. */
1993 END_STRING_AND_SAVE (l
);
1995 operand_ok
= maxq20_operand (token_start
);
1997 RESTORE_END_STRING (l
);
2004 if (expecting_operand
)
2006 expecting_operand_after_comma
:
2007 as_bad (_("expecting operand after ','; got nothing"));
2014 if (*(++l
) == END_OF_INSN
)
2015 /* Just skip it, if it's \n complain. */
2016 goto expecting_operand_after_comma
;
2018 expecting_operand
= 1;
2026 match_operands (int type
, MAX_ARG_TYPE flag_type
, MAX_ARG_TYPE arg_type
,
2032 if ((arg_type
& A_REG
) == A_REG
)
2036 if ((arg_type
& A_IMM
) == A_IMM
)
2040 if ((arg_type
& A_BIT_0
) == A_BIT_0
&& (i
.maxq20_op
[op_num
].imms
== 0))
2042 else if ((arg_type
& A_BIT_1
) == A_BIT_1
2043 && (i
.maxq20_op
[op_num
].imms
== 1))
2047 if ((arg_type
& A_MEM
) == A_MEM
)
2052 if ((arg_type
& flag_type
) == flag_type
)
2058 if ((arg_type
& ACC_BIT
) == ACC_BIT
&& !strcmp (i
.maxq20_op
[op_num
].r_bit
->reg
->reg_name
, "ACC"))
2060 else if ((arg_type
& SRC_BIT
) == SRC_BIT
&& (op_num
== 1))
2062 else if ((op_num
== 0) && (arg_type
& DST_BIT
) == DST_BIT
)
2066 if ((arg_type
& A_DISP
) == A_DISP
)
2069 if ((arg_type
& A_DATA
) == A_DATA
)
2072 if ((arg_type
& A_BIT_BUCKET
) == A_BIT_BUCKET
)
2079 match_template (void)
2081 /* Points to template once we've found it. */
2082 const MAXQ20_OPCODE_INFO
*t
;
2086 for (t
= current_templates
->start
; t
< current_templates
->end
; t
++)
2088 /* Must have right number of operands. */
2089 if (i
.operands
!= t
->op_number
)
2091 else if (!t
->op_number
)
2097 if (!match_operands (i
.types
[1], i
.maxq20_op
[1].flag
, t
->arg
[1], 1))
2103 if (!match_operands (i
.types
[0], i
.maxq20_op
[0].flag
, t
->arg
[0], 0))
2112 if (t
== current_templates
->end
)
2114 /* We found no match. */
2115 as_bad (_("operand %d is invalid for `%s'"),
2116 inv_oper
, current_templates
->start
->name
);
2120 /* Copy the template we have found. */
2125 /* This function filters out the various combinations of operands which are
2126 not allowed for a particular instruction. */
2129 match_filters (void)
2131 /* Now we have at our disposal the instruction i. We will be using the
2132 following fields i.op.name : This is the mnemonic name. i.types[2] :
2133 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2134 i.maxq20_op[2] : This contains the specific info of the operands. */
2136 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2138 if (!strcmp (i
.op
.name
, "AND") || !strcmp (i
.op
.name
, "OR")
2139 || !strcmp (i
.op
.name
, "XOR") || !strcmp (i
.op
.name
, "ADD")
2140 || !strcmp (i
.op
.name
, "ADDC") || !strcmp (i
.op
.name
, "SUB")
2141 || !strcmp (i
.op
.name
, "SUBB"))
2143 if (i
.types
[0] == REG
)
2145 if (i
.maxq20_op
[0].reg
->Mod_name
== 0xa)
2148 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2154 if (!strcmp (i
.op
.name
, "MOVE") && (i
.types
[0] == MEM
|| i
.types
[1] == MEM
)
2157 mem_access_syntax
*mem_op
= NULL
;
2159 if (i
.types
[0] == MEM
)
2162 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2163 i
.maxq20_op
[0].mem
->name
);
2164 if ((mem_op
->type
== SRC
) && mem_op
)
2166 as_bad (_("'%s' operand cant be used as destination in %s"),
2167 mem_op
->name
, i
.op
.name
);
2170 else if ((mem_op
->invalid_op
!= NULL
) && (i
.types
[1] == MEM
)
2175 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2177 if (mem_op
->invalid_op
[k
] != NULL
)
2179 (mem_op
->invalid_op
[k
], i
.maxq20_op
[1].mem
->name
))
2182 ("Invalid Instruction '%s' operand cant be used with %s"),
2183 mem_op
->name
, i
.maxq20_op
[1].mem
->name
);
2190 if (i
.types
[1] == MEM
)
2194 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2195 i
.maxq20_op
[1].mem
->name
);
2196 if (mem_op
->type
== DST
&& mem_op
)
2198 as_bad (_("'%s' operand cant be used as source in %s"),
2199 mem_op
->name
, i
.op
.name
);
2202 else if (mem_op
->invalid_op
!= NULL
&& i
.types
[0] == MEM
&& mem_op
)
2206 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2208 if (mem_op
->invalid_op
[k
] != NULL
)
2210 (mem_op
->invalid_op
[k
], i
.maxq20_op
[0].mem
->name
))
2213 ("Invalid Instruction '%s' operand cant be used with %s"),
2214 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2219 else if (i
.types
[0] == REG
2220 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "OFFS")
2223 if (!strcmp (mem_op
->name
, "@BP[OFFS--]")
2224 || !strcmp (mem_op
->name
, "@BP[OFFS++]"))
2227 ("Invalid Instruction '%s' operand cant be used with %s"),
2228 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2235 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2236 on 10-March-2004. */
2237 if ((i
.types
[0] == MEM
) && (i
.operands
== 1)
2238 && !(!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI")))
2240 mem_access_syntax
*mem_op
= NULL
;
2242 if (i
.types
[0] == MEM
)
2245 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2246 i
.maxq20_op
[0].mem
->name
);
2247 if (mem_op
->type
== DST
&& mem_op
)
2249 as_bad (_("'%s' operand cant be used as source in %s"),
2250 mem_op
->name
, i
.op
.name
);
2256 if (i
.operands
== 2 && i
.types
[0] == IMM
)
2258 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2263 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2264 if (!strcmp (i
.op
.name
, "PUSH") || !strcmp (i
.op
.name
, "POP")
2265 || !strcmp (i
.op
.name
, "POPI"))
2267 if (i
.types
[0] == REG
)
2269 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
2271 as_bad (_("SP cannot be used with %s\n"), i
.op
.name
);
2275 else if (i
.types
[0] == MEM
2276 && !strcmp (i
.maxq20_op
[0].mem
->name
, "@SP--"))
2278 as_bad (_("@SP-- cannot be used with PUSH\n"));
2283 /* This filter checks that two memory references using DP's cannot be used
2284 together in an instruction */
2285 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 2)
2287 if (strlen (i
.maxq20_op
[0].mem
->name
) != 6 ||
2288 strcmp (i
.maxq20_op
[0].mem
->name
, i
.maxq20_op
[1].mem
->name
))
2290 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@DP", 3)
2291 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@DP", 3))
2294 ("Operands either contradictory or use the data bus in read/write state together"));
2298 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@SP", 3)
2299 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@SP", 3))
2302 ("Operands either contradictory or use the data bus in read/write state together"));
2306 if ((i
.maxq20_op
[1].mem
!= NULL
)
2307 && !strncmp (i
.maxq20_op
[1].mem
->name
, "NUL", 3))
2309 as_bad (_("MOVE Cant Use NUL as SRC"));
2314 /* This filter checks that contradictory movement between DP register and
2315 Memory access using DP followed by increment or decrement. */
2317 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 1
2318 && i
.reg_operands
== 1)
2322 memnum
= (i
.types
[0] == MEM
) ? 0 : 1;
2323 regnum
= (memnum
== 0) ? 1 : 0;
2324 if (!strncmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "DP", 2) &&
2325 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2326 i
.maxq20_op
[regnum
].reg
->reg_name
, 5)
2327 && strcmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2328 i
.maxq20_op
[regnum
].reg
->reg_name
))
2331 ("Contradictory movement between DP register and memory access using DP"));
2334 else if (!strcmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "SP") &&
2335 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2336 i
.maxq20_op
[regnum
].reg
->reg_name
, 2))
2339 ("SP and @SP-- cannot be used together in a move instruction"));
2344 /* This filter restricts the instructions containing source and destination
2345 bits to only CTRL module of the serial registers. Peripheral registers
2346 yet to be defined. */
2348 if (i
.bit_operands
== 1 && i
.operands
== 2)
2350 int bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2352 if (strcmp (i
.maxq20_op
[bitnum
].r_bit
->reg
->reg_name
, "ACC"))
2354 if (i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
>= 0x7 &&
2355 i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
!= CTRL
)
2358 ("Only Module 8 system registers allowed in this operation"));
2364 /* This filter is for checking the register bits. */
2365 if (i
.bit_operands
== 1 || i
.operands
== 2)
2367 int bitnum
= 0, size
= 0;
2369 bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2370 if (i
.bit_operands
== 1)
2372 switch (i
.maxq20_op
[bitnum
].r_bit
->reg
->rtype
)
2375 size
= 7; /* 8 bit register, both read and write. */
2384 as_fatal (_("Read only Register used as destination"));
2393 as_fatal (_("Read only Register used as destination"));
2399 if (size
< (i
.maxq20_op
[bitnum
].r_bit
)->bit
)
2401 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2402 (i
.maxq20_op
[bitnum
].r_bit
)->bit
);
2407 if (i
.bit_operands
== 2)
2409 switch ((i
.maxq20_op
[0].r_bit
)->reg
->rtype
)
2412 size
= 7; /* 8 bit register, both read and write. */
2419 as_fatal (_("Read only Register used as destination"));
2423 if (size
< (i
.maxq20_op
[0].r_bit
)->bit
)
2426 ("Bit No '%d' exceeds register size in this operation"),
2427 (i
.maxq20_op
[0].r_bit
)->bit
);
2432 switch ((i
.maxq20_op
[1].r_bit
)->reg
->rtype
)
2436 size
= 7; /* 8 bit register, both read and write. */
2444 if (size
< (i
.maxq20_op
[1].r_bit
)->bit
)
2447 ("Bit No '%d' exceeds register size in this operation"),
2448 (i
.maxq20_op
[1].r_bit
)->bit
);
2454 /* No branch operations should occur into the data memory. Hence any memory
2455 references have to be filtered out when used with instructions like
2456 jump, djnz[] and call. */
2458 if (!strcmp (i
.op
.name
, "JUMP") || !strcmp (i
.op
.name
, "CALL")
2459 || !strncmp (i
.op
.name
, "DJNZ", 4))
2463 ("Memory References cannot be used with branching operations\n"));
2466 if (!strcmp (i
.op
.name
, "DJNZ"))
2469 (strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2470 || strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))
2472 as_bad (_("DJNZ uses only LC[n] register \n"));
2477 /* No destination register used should be read only! */
2478 if ((i
.operands
== 2 && i
.types
[0] == REG
) || !strcmp (i
.op
.name
, "POP")
2479 || !strcmp (i
.op
.name
, "POPI"))
2480 { /* The destination is a register */
2483 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2487 if (i
.types
[regnum
] == MEM
)
2489 mem_access_syntax
*mem_op
= NULL
;
2492 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2493 i
.maxq20_op
[regnum
].mem
->
2495 if (mem_op
->type
== SRC
&& mem_op
)
2498 ("'%s' operand cant be used as destination in %s"),
2499 mem_op
->name
, i
.op
.name
);
2505 if (i
.maxq20_op
[regnum
].reg
->rtype
== Reg_8R
2506 || i
.maxq20_op
[regnum
].reg
->rtype
== Reg_16R
)
2508 as_bad (_("Read only register used for writing purposes '%s'"),
2509 i
.maxq20_op
[regnum
].reg
->reg_name
);
2514 /* While moving the address of a data in the data section, the destination
2515 should be either data pointers only. */
2516 if ((i
.data_operands
) && (i
.operands
== 2))
2518 if ((i
.types
[0] != REG
) && (i
.types
[0] != MEM
))
2520 as_bad (_("Invalid destination for this kind of source."));
2524 if (i
.types
[0] == REG
&& i
.maxq20_op
[0].reg
->rtype
== Reg_8W
)
2527 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2537 /* Check for the format Bit if defined. */
2538 if (i
.op
.format
== 0 || i
.op
.format
== 1)
2539 i
.instr
[0] = i
.op
.format
<< 7;
2542 /* Format bit not defined. We will have to be find it out ourselves. */
2543 if (i
.imm_operands
== 1 || i
.data_operands
== 1 || i
.disp_operands
== 1)
2547 i
.instr
[0] = i
.op
.format
<< 7;
2550 /* Now for the destination register. */
2552 /* If destination register is already defined . The conditions are the
2553 following: (1) The second entry in the destination array should be 0 (2)
2554 If there are two operands then the first entry should not be a register,
2555 memory or a register bit (3) If there are less than two operands and the
2556 it is not a pop operation (4) The second argument is the carry
2557 flag(applicable to move Acc.<b>,C. */
2558 if (i
.op
.dst
[1] == 0
2560 ((i
.types
[0] != REG
&& i
.types
[0] != MEM
&& i
.types
[0] != BIT
2561 && i
.operands
== 2) || (i
.operands
< 2 && strcmp (i
.op
.name
, "POP")
2562 && strcmp (i
.op
.name
, "POPI"))
2563 || (i
.op
.arg
[1] == FLAG_C
)))
2565 i
.op
.dst
[0] &= 0x7f;
2566 i
.instr
[0] |= i
.op
.dst
[0];
2568 else if (i
.op
.dst
[1] == 0 && !strcmp (i
.op
.name
, "DJNZ")
2570 (((i
.types
[0] == REG
)
2571 && (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2572 || !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))))
2574 i
.op
.dst
[0] &= 0x7f;
2575 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]"))
2578 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]"))
2585 /* Target register will have to be specified. */
2586 if (i
.types
[0] == REG
2587 && (i
.op
.dst
[0] == REG
|| i
.op
.dst
[0] == (REG
| MEM
)))
2589 temp
= (i
.maxq20_op
[0].reg
)->opcode
;
2593 else if (i
.types
[0] == MEM
&& (i
.op
.dst
[0] == (REG
| MEM
)))
2595 temp
= (i
.maxq20_op
[0].mem
)->opcode
;
2599 else if (i
.types
[0] == BIT
&& (i
.op
.dst
[0] == REG
))
2601 temp
= (i
.maxq20_op
[0].r_bit
)->reg
->opcode
;
2605 else if (i
.types
[1] == BIT
&& (i
.op
.dst
[0] == BIT
))
2607 temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2609 temp
|= i
.op
.dst
[1];
2615 as_bad (_("Invalid Instruction"));
2620 /* Now for the source register. */
2622 /* If Source register is already known. The following conditions are
2623 checked: (1) There are no operands (2) If there is only one operand and
2624 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2627 if (i
.operands
== 0 || (i
.operands
== 1 && i
.types
[0] == FLAG
)
2628 || (i
.types
[0] == FLAG
&& i
.types
[1] == IMMBIT
)
2629 || !strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2630 i
.instr
[1] = i
.op
.src
[0];
2632 else if (i
.imm_operands
== 1 && ((i
.op
.src
[0] & IMM
) == IMM
))
2633 i
.instr
[1] = i
.maxq20_op
[this_operand
].imms
;
2635 else if (i
.types
[this_operand
] == REG
&& ((i
.op
.src
[0] & REG
) == REG
))
2636 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].reg
)->opcode
);
2638 else if (i
.types
[this_operand
] == BIT
&& ((i
.op
.src
[0] & REG
) == REG
))
2639 i
.instr
[1] = (char) (i
.maxq20_op
[this_operand
].r_bit
->reg
->opcode
);
2641 else if (i
.types
[this_operand
] == MEM
&& ((i
.op
.src
[0] & MEM
) == MEM
))
2642 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].mem
)->opcode
);
2644 else if (i
.types
[this_operand
] == DATA
&& ((i
.op
.src
[0] & DATA
) == DATA
))
2645 /* This will copy only the lower order bytes into the instruction. The
2646 higher order bytes have already been copied into the prefix register. */
2649 /* Decoding the source in the case when the second array entry is not 0.
2650 This means that the source register has been divided into two nibbles. */
2652 else if (i
.op
.src
[1] != 0)
2654 /* If the first operand is a accumulator bit then
2655 the first 4 bits will be filled with the bit number. */
2656 if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & BIT
) == BIT
))
2658 unsigned char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2661 temp
|= i
.op
.src
[1];
2664 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2665 has to start with a zero. This is called a ZEROBIT */
2666 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ZEROBIT
) == ZEROBIT
))
2668 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2671 temp
|= i
.op
.src
[1];
2675 /* Similarly for a ONEBIT */
2676 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ONEBIT
) == ONEBIT
))
2678 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2681 temp
|= i
.op
.src
[1];
2685 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2687 else if (i
.types
[1] == BIT
)
2689 if (i
.op
.src
[1] == 0 && i
.op
.src
[1] == REG
)
2690 i
.instr
[1] = (i
.maxq20_op
[1].r_bit
)->reg
->opcode
;
2692 else if (i
.op
.src
[0] == BIT
&& i
.op
.src
)
2694 char temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2697 temp
|= i
.op
.src
[1];
2703 as_bad (_("Invalid Instruction"));
2710 /* This is a function for outputting displacement operands. */
2713 output_disp (fragS
*insn_start_frag
, offsetT insn_start_off
)
2716 relax_substateT subtype
;
2722 insn_start_frag
= frag_now
;
2723 insn_start_off
= frag_now_fix ();
2725 switch (i
.Instr_Prefix
)
2728 subtype
= EXPLICT_LONG_PREFIX
;
2731 subtype
= SHORT_PREFIX
;
2734 subtype
= NO_PREFIX
;
2738 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2739 case there is no need for relaxation. But we do need support for a
2740 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2741 for prefix + 2 for the current instruction ) Hence if at a particular
2742 time we find out whether the prefix operator is reqd , we shift the
2743 current instruction two places ahead and insert the prefix instruction. */
2747 sym
= i
.maxq20_op
[this_operand
].disps
->X_add_symbol
;
2748 off
= i
.maxq20_op
[this_operand
].disps
->X_add_number
;
2750 if (i
.maxq20_op
[this_operand
].disps
->X_add_symbol
!= NULL
&& sym
&& frag_now
2751 && (subtype
!= EXPLICT_LONG_PREFIX
))
2753 /* If in the same frag. */
2754 if (frag_now
== symbol_get_frag (sym
))
2757 ((((expressionS
*) symbol_get_value_expression (sym
))->
2758 X_add_number
) - insn_start_off
);
2760 diff
= diff
/ MAXQ_OCTETS_PER_BYTE
;
2762 if (diff
>= -128 && diff
<= 127)
2764 i
.instr
[1] = (char) diff
;
2766 /* This will be overwritten later when the symbol is resolved. */
2768 *(p
+ 1) = i
.instr
[0];
2770 /* No Need to create a FIXUP. */
2776 /* This will be overwritten later when the symbol is resolved. */
2778 *(p
+ 1) = i
.instr
[0];
2780 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2781 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2783 /* Handle complex expressions. */
2784 sym
= make_expr_symbol (i
.maxq20_op
[this_operand
].disps
);
2788 /* Vineet : This has been added for md_estimate_size_before_relax to
2789 estimate the correct size. */
2790 if (subtype
!= SHORT_PREFIX
)
2791 i
.reloc
[this_operand
] = LONG_PREFIX
;
2793 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2796 /* This is a function for outputting displacement operands. */
2799 output_data (fragS
*insn_start_frag
, offsetT insn_start_off
)
2802 relax_substateT subtype
;
2809 insn_start_frag
= frag_now
;
2810 insn_start_off
= frag_now_fix ();
2812 subtype
= EXPLICT_LONG_PREFIX
;
2817 sym
= i
.maxq20_op
[this_operand
].data
;
2820 /* This will be overwritten later when the symbol is resolved. */
2822 *(p
+ 1) = i
.instr
[0];
2824 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2825 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2826 /* Handle complex expressions. */
2827 /* Because data is already in terms of symbol so no
2828 need to convert it from expression to symbol. */
2831 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2837 fragS
*insn_start_frag
;
2838 offsetT insn_start_off
;
2841 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2842 do this after the insn has been output as the current frag may have been
2843 closed off. eg. by frag_var. */
2844 dwarf2_emit_insn (0);
2846 /* To ALign the text section on word. */
2848 frag_align (1, 0, 1);
2850 /* We initialise the frags for this particular instruction. */
2851 insn_start_frag
= frag_now
;
2852 insn_start_off
= frag_now_fix ();
2854 /* If there are displacement operators(unresolved) present, then handle
2856 if (i
.disp_operands
)
2858 output_disp (insn_start_frag
, insn_start_off
);
2862 if (i
.data_operands
)
2864 output_data (insn_start_frag
, insn_start_off
);
2868 /* Check whether the INSERT_BUFFER has to be written. */
2869 if (strcmp (INSERT_BUFFER
, ""))
2873 *p
++ = INSERT_BUFFER
[1];
2874 *p
= INSERT_BUFFER
[0];
2877 /* Check whether the prefix instruction has to be written. */
2878 if (strcmp (PFX_INSN
, ""))
2887 /* For Little endian. */
2893 make_new_reg_table (void)
2895 unsigned long size_pm
= sizeof (peripheral_reg_table
);
2896 num_of_reg
= ARRAY_SIZE (peripheral_reg_table
);
2898 new_reg_table
= xmalloc (size_pm
);
2899 if (new_reg_table
== NULL
)
2900 as_bad (_("Cannot allocate memory"));
2902 memcpy (new_reg_table
, peripheral_reg_table
, size_pm
);
2905 /* pmmain performs the initilizations for the pheripheral modules. */
2910 make_new_reg_table ();
2917 const char *hash_err
= NULL
;
2920 const MAXQ20_OPCODE_INFO
*optab
;
2921 MAXQ20_OPCODES
*core_optab
; /* For opcodes of the same name. This will
2922 be inserted into the hash table. */
2923 struct reg
*reg_tab
;
2924 struct mem_access_syntax
const *memsyntab
;
2925 struct mem_access
*memtab
;
2926 struct bit_name
*bittab
;
2928 /* Initilize pherioipheral modules. */
2931 /* Initialise the opcode hash table. */
2932 op_hash
= hash_new ();
2934 optab
= op_table
; /* Initialise it to the first entry of the
2935 maxq20 operand table. */
2937 /* Setup for loop. */
2938 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2939 core_optab
->start
= optab
;
2944 if (optab
->name
== NULL
|| strcmp (optab
->name
, (optab
- 1)->name
) != 0)
2946 /* different name --> ship out current template list; add to hash
2947 table; & begin anew. */
2949 core_optab
->end
= optab
;
2951 if (max_version
== 10)
2953 if (((optab
- 1)->arch
== MAXQ10
) || ((optab
- 1)->arch
== MAX
))
2955 hash_err
= hash_insert (op_hash
,
2960 else if (max_version
== 20)
2963 if (((optab
- 1)->arch
== MAXQ20
) || ((optab
- 1)->arch
== MAX
))
2966 hash_err
= hash_insert (op_hash
,
2973 as_fatal (_("Internal Error: Illegal Architecure specified"));
2976 as_fatal (_("Internal Error: Can't hash %s: %s"),
2977 (optab
- 1)->name
, hash_err
);
2979 if (optab
->name
== NULL
)
2981 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2982 core_optab
->start
= optab
;
2986 /* Initialise a new register table. */
2987 reg_hash
= hash_new ();
2989 for (reg_tab
= system_reg_table
;
2990 reg_tab
< (system_reg_table
+ ARRAY_SIZE (system_reg_table
));
2994 switch (max_version
)
2996 case 10: /* MAXQ10 */
2997 if ((reg_tab
->arch
== MAXQ10
) || (reg_tab
->arch
== MAX
))
2998 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3001 case 20: /* MAXQ20 */
3002 if ((reg_tab
->arch
== MAXQ20
) || (reg_tab
->arch
== MAX
))
3006 hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3011 as_fatal (_("Invalid architecture type"));
3016 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3017 reg_tab
->reg_name
, hash_err
);
3020 /* Pheripheral Registers Entry. */
3021 for (reg_tab
= new_reg_table
;
3022 reg_tab
< (new_reg_table
+ num_of_reg
- 1); reg_tab
++)
3024 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
3027 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3028 reg_tab
->reg_name
, hash_err
);
3031 /* Initialise a new memory operand table. */
3032 mem_hash
= hash_new ();
3034 for (memtab
= mem_table
;
3035 memtab
< mem_table
+ ARRAY_SIZE (mem_table
);
3038 hash_err
= hash_insert (mem_hash
, memtab
->name
, (PTR
) memtab
);
3040 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3041 memtab
->name
, hash_err
);
3044 bit_hash
= hash_new ();
3046 for (bittab
= bit_table
;
3047 bittab
< bit_table
+ ARRAY_SIZE (bit_table
);
3050 hash_err
= hash_insert (bit_hash
, bittab
->name
, (PTR
) bittab
);
3052 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3053 bittab
->name
, hash_err
);
3056 mem_syntax_hash
= hash_new ();
3058 for (memsyntab
= mem_access_syntax_table
;
3059 memsyntab
< mem_access_syntax_table
+ ARRAY_SIZE (mem_access_syntax_table
);
3063 hash_insert (mem_syntax_hash
, memsyntab
->name
, (PTR
) memsyntab
);
3065 as_fatal (_("Internal Error : Can't Hash %s : %s"),
3066 memsyntab
->name
, hash_err
);
3069 /* Initialise the lexical tables,mnemonic chars,operand chars. */
3070 for (c
= 0; c
< 256; c
++)
3075 mnemonic_chars
[c
] = c
;
3076 operand_chars
[c
] = c
;
3077 register_chars
[c
] = c
;
3079 else if (ISLOWER (c
))
3081 mnemonic_chars
[c
] = c
;
3082 operand_chars
[c
] = c
;
3083 register_chars
[c
] = c
;
3085 else if (ISUPPER (c
))
3087 mnemonic_chars
[c
] = TOLOWER (c
);
3088 register_chars
[c
] = c
;
3089 operand_chars
[c
] = c
;
3092 if (ISALPHA (c
) || ISDIGIT (c
))
3094 identifier_chars
[c
] = c
;
3098 identifier_chars
[c
] = c
;
3099 operand_chars
[c
] = c
;
3103 /* All the special characters. */
3104 register_chars
['@'] = '@';
3105 register_chars
['+'] = '+';
3106 register_chars
['-'] = '-';
3107 digit_chars
['-'] = '-';
3108 identifier_chars
['_'] = '_';
3109 identifier_chars
['.'] = '.';
3110 register_chars
['['] = '[';
3111 register_chars
[']'] = ']';
3112 operand_chars
['_'] = '_';
3113 operand_chars
['#'] = '#';
3114 mnemonic_chars
['['] = '[';
3115 mnemonic_chars
[']'] = ']';
3117 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
3118 operand_chars
[(unsigned char) *p
] = (unsigned char) *p
;
3121 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3122 menmunonic in the operand table - Parse operands and populate the
3123 structure/template - Match the operand with opcode and its validity -
3127 md_assemble (char *line
)
3131 char mnemonic
[MAX_MNEM_SIZE
];
3132 char temp4prev
[256];
3133 static char prev_insn
[256];
3135 /* Initialize globals. */
3136 memset (&i
, '\0', sizeof (i
));
3137 for (j
= 0; j
< MAX_OPERANDS
; j
++)
3138 i
.reloc
[j
] = NO_RELOC
;
3143 INSERT_BUFFER
[0] = 0;
3144 INSERT_BUFFER
[1] = 0;
3146 memcpy (temp4prev
, line
, strlen (line
) + 1);
3148 save_stack_p
= save_stack
;
3150 line
= (char *) parse_insn (line
, mnemonic
);
3154 line
= (char *) parse_operands (line
, mnemonic
);
3158 /* Next, we find a template that matches the given insn, making sure the
3159 overlap of the given operands types is consistent with the template
3161 if (!match_template ())
3164 /* In the MAXQ20, there are certain register combinations, and other
3165 restrictions which are not allowed. We will try to resolve these right
3167 if (!match_filters ())
3170 /* Check for the approprate PFX register. */
3172 pfx_for_imm_val (0);
3174 if (!decode_insn ()) /* decode insn. */
3177 /* Check for Exlipct PFX instruction. */
3178 if (PFX_INSN
[0] && (strstr (prev_insn
, "PFX") || strstr (prev_insn
, "pfx")))
3179 as_warn (_("Ineffective insntruction %s \n"), prev_insn
);
3181 memcpy (prev_insn
, temp4prev
, strlen (temp4prev
) + 1);
3183 /* We are ready to output the insn. */