1 /* tc-maxq.c -- assembler code for a MAXQ chip.
3 Copyright 2004, 2005, 2006 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"
38 #define DEFAULT_ARCH "MAXQ20"
42 #define MAX_OPERANDS 2
46 #define MAX_MNEM_SIZE 8
50 #define END_OF_INSN '\0'
53 #ifndef IMMEDIATE_PREFIX
54 #define IMMEDIATE_PREFIX '#'
57 #ifndef MAX_REG_NAME_SIZE
58 #define MAX_REG_NAME_SIZE 4
61 #ifndef MAX_MEM_NAME_SIZE
62 #define MAX_MEM_NAME_SIZE 9
65 /* opcode for PFX[0]. */
68 /* Set default to MAXQ20. */
69 unsigned int max_version
= bfd_mach_maxq20
;
71 const char *default_arch
= DEFAULT_ARCH
;
73 /* Type of the operand: Register,Immediate,Memory access,flag or bit. */
77 const reg_entry
* reg
;
78 char imms
; /* This is to store the immediate value operand. */
81 const mem_access
* mem
;
83 const reg_bit
* r_bit
;
86 typedef union _maxq20_op maxq20_opcode
;
88 /* For handling optional L/S in Maxq20. */
90 /* Exposed For Linker - maps indirectly to the liker relocations. */
91 #define LONG_PREFIX MAXQ_LONGJUMP /* BFD_RELOC_16 */
92 #define SHORT_PREFIX MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
93 #define ABSOLUTE_ADDR_FOR_DATA MAXQ_INTERSEGMENT
96 #define EXPLICT_LONG_PREFIX 14
98 /* The main instruction structure containing fields to describe instrn */
99 typedef struct _maxq20_insn
101 /* The opcode information for the MAXQ20 */
102 MAXQ20_OPCODE_INFO op
;
104 /* The number of operands */
105 unsigned int operands
;
107 /* Number of different types of operands - Comments can be removed if reqd.
109 unsigned int reg_operands
, mem_operands
, disp_operands
, data_operands
;
110 unsigned int imm_operands
, imm_bit_operands
, bit_operands
, flag_operands
;
112 /* Types of the individual operands */
113 UNKNOWN_OP types
[MAX_OPERANDS
];
115 /* Relocation type for operand : to be investigated into */
116 int reloc
[MAX_OPERANDS
];
118 /* Complete information of the Operands */
119 maxq20_opcode maxq20_op
[MAX_OPERANDS
];
121 /* Choice of prefix register whenever needed */
124 /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
125 unsigned char Instr_Prefix
;
127 /* 16 bit Instruction word */
128 unsigned char instr
[2];
132 /* Definitions of all possible characters that can start an operand. */
133 const char *extra_symbol_chars
= "@(#";
135 /* Special Character that would start a comment. */
136 const char comment_chars
[] = ";";
138 /* Starts a comment when it appears at the start of a line. */
139 const char line_comment_chars
[] = ";#";
141 const char line_separator_chars
[] = ""; /* originally may b by sudeep "\n". */
143 /* The following are used for option processing. */
145 /* This is added to the mach independent string passed to getopt. */
146 const char *md_shortopts
= "q";
148 /* Characters for exponent and floating point. */
149 const char EXP_CHARS
[] = "eE";
150 const char FLT_CHARS
[] = "";
152 /* This is for the machine dependent option handling. */
153 #define OPTION_EB (OPTION_MD_BASE + 0)
154 #define OPTION_EL (OPTION_MD_BASE + 1)
155 #define MAXQ_10 (OPTION_MD_BASE + 2)
156 #define MAXQ_20 (OPTION_MD_BASE + 3)
158 struct option md_longopts
[] =
160 {"MAXQ10", no_argument
, NULL
, MAXQ_10
},
161 {"MAXQ20", no_argument
, NULL
, MAXQ_20
},
162 {NULL
, no_argument
, NULL
, 0}
164 size_t md_longopts_size
= sizeof (md_longopts
);
166 /* md_undefined_symbol We have no need for this function. */
169 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
175 maxq_target (int target
)
177 max_version
= target
;
178 bfd_set_arch_mach (stdoutput
, bfd_arch_maxq
, max_version
);
182 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
184 /* Any options support will be added onto this switch case. */
188 max_version
= bfd_mach_maxq10
;
191 max_version
= bfd_mach_maxq20
;
201 /* When a usage message is printed, this function is called and
202 it prints a description of the machine specific options. */
205 md_show_usage (FILE * stream
)
207 /* Over here we will fill the description of the machine specific options. */
209 fprintf (stream
, _(" MAXQ-specific assembler options:\n"));
211 fprintf (stream
, _("\
212 -MAXQ20 generate obj for MAXQ20(default)\n\
213 -MAXQ10 generate obj for MAXQ10\n\
220 if (!(strcmp (default_arch
, "MAXQ20")))
223 as_fatal (_("Unknown architecture"));
228 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
231 bfd_reloc_code_real_type code
;
233 switch (fixp
->fx_r_type
)
235 case MAXQ_INTERSEGMENT
:
237 case BFD_RELOC_16_PCREL_S2
:
238 code
= fixp
->fx_r_type
;
243 switch (fixp
->fx_size
)
246 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
247 _("can not do %d byte relocation"), fixp
->fx_size
);
263 rel
= xmalloc (sizeof (arelent
));
264 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
265 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
267 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
268 rel
->addend
= fixp
->fx_addnumber
;
269 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
271 if (rel
->howto
== NULL
)
273 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
274 _("cannot represent relocation type %s"),
275 bfd_get_reloc_code_name (code
));
277 /* Set howto to a garbage value so that we can keep going. */
278 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
279 assert (rel
->howto
!= NULL
);
285 /* md_estimate_size_before_relax()
287 Called just before relax() for rs_machine_dependent frags. The MAXQ
288 assembler uses these frags to handle 16 bit absolute jumps which require a
289 prefix instruction to be inserted. Any symbol that is now undefined will
290 not become defined. Return the correct fr_subtype in the frag. Return the
291 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
292 caller. The guess is actually the growth beyond the fixed part. Whatever
293 we do to grow the fixed or variable part contributes to our returned
297 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
299 /* Check whether the symbol has been resolved or not.
300 Otherwise we will have to generate a fixup. */
301 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
)
302 || fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
304 RELOC_ENUM reloc_type
;
305 unsigned char *opcode
;
308 /* Now this symbol has not been defined in this file.
309 Hence we will have to create a fixup. */
312 /* This is for the prefix instruction. */
314 if (fragP
->fr_subtype
== EXPLICT_LONG_PREFIX
)
315 fragP
->fr_subtype
= LONG_PREFIX
;
317 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
318 && ((!(fragP
->fr_subtype
) == EXPLICT_LONG_PREFIX
)))
319 fragP
->fr_subtype
= ABSOLUTE_ADDR_FOR_DATA
;
322 (fragP
->fr_subtype
? fragP
->fr_subtype
: ABSOLUTE_ADDR_FOR_DATA
);
324 fragP
->fr_subtype
= reloc_type
;
326 if (reloc_type
== SHORT_PREFIX
)
328 old_fr_fix
= fragP
->fr_fix
;
329 opcode
= (unsigned char *) fragP
->fr_opcode
;
331 fragP
->fr_fix
+= (size
);
333 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
334 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
336 return fragP
->fr_fix
- old_fr_fix
;
339 if (fragP
->fr_subtype
== SHORT_PREFIX
)
341 fragP
->fr_subtype
= SHORT_PREFIX
;
345 if (fragP
->fr_subtype
== NO_PREFIX
|| fragP
->fr_subtype
== LONG_PREFIX
)
348 unsigned long call_addr
;
352 call_addr
= call_addr
^ call_addr
;
356 /* segment_info_type *seginfo = seg_info (segment); */
357 instr
= fragP
->fr_address
+ fragP
->fr_fix
- 2;
359 /* This is the offset if it is a PC relative jump. */
360 call_addr
= S_GET_VALUE (fragP
->fr_symbol
) + fragP
->fr_offset
;
362 /* PC stores the value of the next instruction. */
363 diff
= (call_addr
- instr
) - 1;
365 if (diff
>= (-128 * 2) && diff
<= (2 * 127))
367 /* Now as offset is an 8 bit value, we will pass
368 that to the jump instruction directly. */
369 fragP
->fr_subtype
= NO_PREFIX
;
373 fragP
->fr_subtype
= LONG_PREFIX
;
377 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
382 /* Equal to MAX_PRECISION in atof-ieee.c */
383 #define MAX_LITTLENUMS 6
385 /* Turn a string in input_line_pointer into a floating point constant of type
386 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
387 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
390 md_atof (int type
, char * litP
, int * sizeP
)
393 LITTLENUM_TYPE words
[4];
405 /* The size of Double has been changed to 2 words ie 32 bits. */
411 return _("bad call to md_atof");
414 t
= atof_ieee (input_line_pointer
, type
, words
);
416 input_line_pointer
= t
;
420 for (i
= prec
- 1; i
>= 0; i
--)
422 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
430 maxq20_cons_fix_new (fragS
* frag
, unsigned int off
, unsigned int len
,
438 r
= MAXQ_WORDDATA
; /* Word+n */
441 r
= MAXQ_LONGDATA
; /* Long+n */
445 fix_new_exp (frag
, off
, len
, exp
, 0, r
);
449 /* GAS will call this for every rs_machine_dependent fragment. The
450 instruction is completed using the data from the relaxation pass. It may
451 also create any necessary relocations. */
453 md_convert_frag (bfd
* headers ATTRIBUTE_UNUSED
,
454 segT seg ATTRIBUTE_UNUSED
,
458 offsetT target_address
;
459 offsetT opcode_address
;
460 offsetT displacement_from_opcode_start
;
463 opcode
= fragP
->fr_opcode
;
465 target_address
= opcode_address
= displacement_from_opcode_start
= 0;
468 (S_GET_VALUE (fragP
->fr_symbol
) / MAXQ_OCTETS_PER_BYTE
) +
469 (fragP
->fr_offset
/ MAXQ_OCTETS_PER_BYTE
);
472 (fragP
->fr_address
/ MAXQ_OCTETS_PER_BYTE
) +
473 ((fragP
->fr_fix
- 2) / MAXQ_OCTETS_PER_BYTE
);
475 /* PC points to the next Instruction. */
476 displacement_from_opcode_start
= ((target_address
- opcode_address
) - 1);
478 if ((displacement_from_opcode_start
>= -128
479 && displacement_from_opcode_start
<= 127)
480 && (fragP
->fr_subtype
== SHORT_PREFIX
481 || fragP
->fr_subtype
== NO_PREFIX
))
483 /* Its a displacement. */
484 *opcode
= (char) displacement_from_opcode_start
;
488 /* Its an absolute 16 bit jump. Now we have to
489 load the prefix operator with the upper 8 bits. */
490 if (fragP
->fr_subtype
== SHORT_PREFIX
)
492 as_bad (_("Cant make long jump/call into short jump/call : %d"),
497 /* Check whether the symbol has been resolved or not.
498 Otherwise we will have to generate a fixup. */
500 if (fragP
->fr_subtype
!= SHORT_PREFIX
)
502 RELOC_ENUM reloc_type
;
506 /* Now this is a basolute jump/call.
507 Hence we will have to create a fixup. */
508 if (fragP
->fr_subtype
== NO_PREFIX
)
509 fragP
->fr_subtype
= LONG_PREFIX
;
512 (fragP
->fr_subtype
? fragP
->fr_subtype
: LONG_PREFIX
);
516 old_fr_fix
= fragP
->fr_fix
;
518 fragP
->fr_fix
+= (size
);
520 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
521 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
528 md_pcrel_from (fixS
*fixP
)
530 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
533 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
536 maxq_number_to_chars (char *buf
, valueT val
, int n
)
538 if (target_big_endian
)
539 number_to_chars_bigendian (buf
, val
, n
);
541 number_to_chars_littleendian (buf
, val
, n
);
544 /* GAS will call this for each fixup. It's main objective is to store the
545 correct value in the object file. 'fixup_segment' performs the generic
546 overflow check on the 'valueT *val' argument after md_apply_fix returns.
547 If the overflow check is relevant for the target machine, then
548 'md_apply_fix' should modify 'valueT *val', typically to the value stored
549 in the object file (not to be done in MAXQ). */
552 md_apply_fix (fixS
*fixP
, valueT
*valT
, segT seg ATTRIBUTE_UNUSED
)
554 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
555 char *frag_to_fix_at
=
556 fixP
->fx_frag
->fr_literal
+ fixP
->fx_frag
->fr_fix
- 2;
560 if (fixP
->fx_frag
&& valT
)
562 /* If the relaxation substate is not defined we make it equal
563 to the kind of relocation the fixup is generated for. */
564 if (!fixP
->fx_frag
->fr_subtype
)
565 fixP
->fx_frag
->fr_subtype
= fixP
->fx_r_type
;
567 /* For any instruction in which either we have specified an
568 absolute address or it is a long jump we need to add a PFX0
569 instruction to it. In this case as the instruction has already
570 being written at 'fx_where' in the frag we copy it at the end of
571 the frag(which is where the relocation was generated) as when
572 the relocation is generated the frag is grown by 2 type, this is
573 where we copy the contents of fx_where and add a pfx0 at
575 if ((fixP
->fx_frag
->fr_subtype
== ABSOLUTE_ADDR_FOR_DATA
)
576 || (fixP
->fx_frag
->fr_subtype
== LONG_PREFIX
))
578 *(frag_to_fix_at
+ 1) = *(p
+ 1);
579 maxq_number_to_chars (p
+ 1, PFX0
, 1);
582 /* Remember value for tc_gen_reloc. */
583 fixP
->fx_addnumber
= *valT
;
586 /* Some fixups generated by GAS which gets resovled before this this
587 func. is called need to be wriiten to the frag as here we are going
588 to go away with the relocations fx_done=1. */
589 if (fixP
->fx_addsy
== NULL
)
591 maxq_number_to_chars (p
, *valT
, fixP
->fx_size
);
592 fixP
->fx_addnumber
= *valT
;
598 /* Tables for lexical analysis. */
599 static char mnemonic_chars
[256];
600 static char register_chars
[256];
601 static char operand_chars
[256];
602 static char identifier_chars
[256];
603 static char digit_chars
[256];
605 /* Lexical Macros. */
606 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
607 #define is_register_char(x) (register_chars[(unsigned char)(x)])
608 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
609 #define is_space_char(x) (x==' ')
610 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
611 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
613 /* Special characters for operands. */
614 static char operand_special_chars
[] = "[]@.-+";
616 /* md_assemble() will always leave the instruction passed to it unaltered.
617 To do this we store the instruction in a special stack. */
618 static char save_stack
[32];
619 static char *save_stack_p
;
621 #define END_STRING_AND_SAVE(s) \
624 *save_stack_p++ = *(s); \
629 #define RESTORE_END_STRING(s) \
632 *(s) = *(--save_stack_p); \
636 /* The instruction we are assembling. */
637 static maxq20_insn i
;
639 /* The current template. */
640 static MAXQ20_OPCODES
*current_templates
;
642 /* The displacement operand if any. */
643 static expressionS disp_expressions
;
645 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
646 static int this_operand
;
648 /* The prefix instruction if used. */
649 static char PFX_INSN
[2];
650 static char INSERT_BUFFER
[2];
652 /* For interface with expression() ????? */
653 extern char *input_line_pointer
;
655 /* The HASH Tables: */
657 /* Operand Hash Table. */
658 static struct hash_control
*op_hash
;
660 /* Register Hash Table. */
661 static struct hash_control
*reg_hash
;
663 /* Memory reference Hash Table. */
664 static struct hash_control
*mem_hash
;
666 /* Bit hash table. */
667 static struct hash_control
*bit_hash
;
669 /* Memory Access syntax table. */
670 static struct hash_control
*mem_syntax_hash
;
672 /* This is a mapping from pseudo-op names to functions. */
674 const pseudo_typeS md_pseudo_table
[] =
676 {"int", cons
, 2}, /* size of 'int' has been changed to 1 word
678 {"maxq10", maxq_target
, bfd_mach_maxq10
},
679 {"maxq20", maxq_target
, bfd_mach_maxq20
},
683 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
686 /* This function sets the PFX value corresponding to the specs. Source
687 Destination Index Selection ---------------------------------- Write To|
688 SourceRegRange | Dest Addr Range
689 ------------------------------------------------------ PFX[0] | 0h-Fh |
690 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
691 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
692 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
697 short int src_index
= 0, dst_index
= 0;
701 if (i
.operands
== 1) /* Only SRC is Present */
703 if (i
.types
[0] == REG
)
705 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
707 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
712 src_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
720 if (i
.types
[0] == REG
&& i
.types
[1] == REG
)
722 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
723 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
725 else if (i
.types
[0] != REG
&& i
.types
[1] == REG
) /* DST is Absent */
727 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
730 else if (i
.types
[0] == REG
&& i
.types
[1] != REG
) /* Id SRC is Absent */
732 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
735 else if (i
.types
[0] == BIT
&& i
.maxq20_op
[0].r_bit
)
737 dst_index
= i
.maxq20_op
[0].r_bit
->reg
->Mod_index
;
741 else if (i
.types
[1] == BIT
&& i
.maxq20_op
[1].r_bit
)
744 src_index
= i
.maxq20_op
[1].r_bit
->reg
->Mod_index
;
748 if (src_index
>= 0x00 && src_index
<= 0xF)
750 if (dst_index
>= 0x00 && dst_index
<= 0x07)
754 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
758 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
762 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
766 else if (src_index
>= 0x10 && src_index
<= 0x1F)
768 if (dst_index
>= 0x00 && dst_index
<= 0x07)
772 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
776 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
780 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
787 is_a_LSinstr (const char *ln_pointer
)
791 for (i
= 0; LSInstr
[i
] != NULL
; i
++)
792 if (!strcmp (LSInstr
[i
], ln_pointer
))
799 LS_processing (const char *line
)
801 if (is_a_LSinstr (line
))
803 if ((line
[0] == 'L') || (line
[0] == 'l'))
806 INSERT_BUFFER
[0] = PFX0
;
807 i
.Instr_Prefix
= LONG_PREFIX
;
809 else if ((line
[0] == 'S') || (line
[0] == 's'))
810 i
.Instr_Prefix
= SHORT_PREFIX
;
812 i
.Instr_Prefix
= NO_PREFIX
;
815 i
.Instr_Prefix
= LONG_PREFIX
;
818 /* Separate mnemonics and the operands. */
821 parse_insn (char *line
, char *mnemonic
)
824 char *token_start
= l
;
826 char temp
[MAX_MNEM_SIZE
];
829 memset (temp
, END_OF_INSN
, MAX_MNEM_SIZE
);
832 while ((*mnem_p
= mnemonic_chars
[(unsigned char) *l
]) != 0)
836 if (mnem_p
>= mnemonic
+ MAX_MNEM_SIZE
)
838 as_bad (_("no such instruction: `%s'"), token_start
);
844 if (!is_space_char (*l
) && *l
!= END_OF_INSN
)
846 as_bad (_("invalid character %s in mnemonic"), l
);
852 temp
[ii
- 1] = toupper ((char) mnemonic
[ii
- 1]);
856 LS_processing (temp
);
858 if (i
.Instr_Prefix
!= 0 && is_a_LSinstr (temp
))
859 /* Skip the optional L-S. */
860 memcpy (temp
, temp
+ 1, MAX_MNEM_SIZE
);
862 /* Look up instruction (or prefix) via hash table. */
863 current_templates
= (MAXQ20_OPCODES
*) hash_find (op_hash
, temp
);
865 if (current_templates
!= NULL
)
868 as_bad (_("no such instruction: `%s'"), token_start
);
872 /* Function to calculate x to the power of y.
873 Just to avoid including the math libraries. */
880 for (k
= 0; k
< y
; k
++)
887 parse_reg_by_index (char *imm_start
)
889 int k
= 0, mid
= 0, rid
= 0, val
= 0, j
= 0;
890 char temp
[4] = { 0 };
891 reg_entry
*reg
= NULL
;
895 if (isdigit (imm_start
[k
]))
896 temp
[k
] = imm_start
[k
] - '0';
898 else if (isalpha (imm_start
[k
])
899 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
900 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
902 else if (imm_start
[k
] == 'h')
905 else if (imm_start
[k
] == END_OF_INSN
)
912 return NULL
; /* not a hex digit */
916 while (imm_start
[k
] != '\n');
918 switch (imm_start
[k
])
921 for (j
= 0; j
< k
; j
++)
922 val
+= temp
[j
] * pwr (16, k
- j
- 1);
926 for (j
= 0; j
< k
; j
++)
929 return NULL
; /* not a number */
931 val
+= temp
[j
] * pwr (10, k
- j
- 1);
936 /* Get the module and register id's. */
938 rid
= (val
>> 4) & 0x0f;
942 /* Search the pheripheral reg table. */
943 for (j
= 0; j
< num_of_reg
; j
++)
945 if (new_reg_table
[j
].opcode
== val
)
947 reg
= (reg_entry
*) & new_reg_table
[j
];
955 /* Search the system register table. */
958 while (system_reg_table
[j
].reg_name
!= NULL
)
960 if (system_reg_table
[j
].opcode
== val
)
962 reg
= (reg_entry
*) & system_reg_table
[j
];
971 as_bad (_("Invalid register value %s"), imm_start
);
976 if (this_operand
== 0 && reg
!= NULL
)
978 if (reg
->Mod_index
> 7)
984 return (reg_entry
*) reg
;
987 /* REG_STRING starts *before* REGISTER_PREFIX. */
990 parse_register (char *reg_string
, char **end_op
)
992 char *s
= reg_string
;
994 char reg_name_given
[MAX_REG_NAME_SIZE
+ 1];
1000 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1001 if (is_space_char (*s
))
1005 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1007 if (p
>= reg_name_given
+ MAX_REG_NAME_SIZE
)
1008 return (reg_entry
*) NULL
;
1014 r
= (reg_entry
*) hash_find (reg_hash
, reg_name_given
);
1017 if (this_operand
== 0 && r
!= NULL
)
1019 if (r
->Mod_index
> 7)
1029 parse_register_bit (char *reg_string
, char **end_op
)
1031 const char *s
= reg_string
;
1035 reg_entry
*r
= NULL
;
1037 char temp_bitname
[MAX_REG_NAME_SIZE
+ 2];
1038 char temp
[MAX_REG_NAME_SIZE
+ 1];
1040 memset (&temp
, '\0', (MAX_REG_NAME_SIZE
+ 1));
1041 memset (&temp_bitname
, '\0', (MAX_REG_NAME_SIZE
+ 2));
1046 rb
= xmalloc (sizeof (reg_bit
));
1047 rb
->reg
= xmalloc (sizeof (reg_entry
));
1050 /* For supporting bit names. */
1051 b
= (bit_name
*) hash_find (bit_hash
, reg_string
);
1055 *end_op
= reg_string
+ strlen (reg_string
);
1056 strcpy (temp_bitname
, b
->reg_bit
);
1060 if (strchr (s
, '.'))
1073 if ((r
= parse_register (temp
, end_op
)) == NULL
)
1081 if (isdigit ((char) *s
))
1083 else if (isalpha ((char) *s
))
1085 rb
->bit
= (char) *s
- 'a';
1089 as_bad (_("Invalid bit number : '%c'"), (char) *s
);
1095 diff
= strlen (temp_bitname
) - strlen (temp
) - 1;
1097 diff
= strlen (reg_string
) - strlen (temp
) - 1;
1099 if (*(s
+ diff
) != '\0')
1101 as_bad (_("Illegal character after operand '%s'"), reg_string
);
1109 pfx_for_imm_val (int arg
)
1114 if (i
.prefix
== 0 && arg
== 0 && PFX_INSN
[1] == 0 && !(i
.data_operands
))
1117 if (!(i
.prefix
< 0) && !(i
.prefix
> 7))
1118 PFX_INSN
[0] = (i
.prefix
<< 4) | PFX0
;
1126 maxq20_immediate (char *imm_start
)
1128 int val
= 0, val_pfx
= 0;
1131 int temp
[4] = { 0 };
1135 if (imm_start
[1] == '\0' && (imm_start
[0] == '0' || imm_start
[0] == '1')
1136 && (this_operand
== 1 && ((i
.types
[0] == BIT
|| i
.types
[0] == FLAG
))))
1138 val
= imm_start
[0] - '0';
1139 i
.imm_bit_operands
++;
1140 i
.types
[this_operand
] = IMMBIT
;
1141 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1144 pfx_for_imm_val (0);
1149 /* Check For Sign Character. */
1154 if (imm_start
[k
] == '-' && k
== 0)
1157 else if (imm_start
[k
] == '+' && k
== 0)
1160 else if (isdigit (imm_start
[k
]))
1161 temp
[k
] = imm_start
[k
] - '0';
1163 else if (isalpha (imm_start
[k
])
1164 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
1165 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
1167 else if (imm_start
[k
] == 'h')
1170 else if (imm_start
[k
] == '\0')
1177 as_bad (_("Invalid Character in immediate Value : %c"),
1183 while (imm_start
[k
] != '\n');
1185 switch (imm_start
[k
])
1188 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1189 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1193 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1197 as_bad (_("Invalid Character in immediate value : %c"),
1201 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1208 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1209 check if we are moving a 16 bit immediate value into an 8 bit register.
1210 In that case we will generate a warning and move only the lower 8 bits */
1213 as_bad (_("Immediate value greater than 16 bits"));
1217 val
= val
* sign_val
;
1219 /* If it is a stack pointer and the value is greater than the maximum
1221 if (this_operand
== 1)
1223 if ((val
* sign_val
) > MAX_STACK
&& i
.types
[0] == REG
1224 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
1227 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1228 val
= val
& MAX_STACK
;
1231 /* Check the range for 8 bit registers. */
1232 else if (((val
* sign_val
) > 0xFF) && (i
.types
[0] == REG
)
1233 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1236 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1240 else if (((sign_val
== -1) || (val
> 0xFF)) && (i
.types
[0] == REG
)
1241 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1244 val
= ((val
) & 0x00ff);
1245 SET_PFX_ARG (val_pfx
);
1246 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1249 else if ((val
<= 0xff) && (i
.types
[0] == REG
)
1250 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1251 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1254 /* Check for 16 bit registers. */
1255 else if (((sign_val
== -1) || val
> 0xFE) && i
.types
[0] == REG
1256 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1258 /* Add PFX for any negative value -> 16bit register. */
1260 val
= ((val
) & 0x00ff);
1261 SET_PFX_ARG (val_pfx
);
1262 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1265 else if (val
< 0xFF && i
.types
[0] == REG
1266 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1268 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1271 /* All the immediate memory access - no PFX. */
1272 else if (i
.types
[0] == MEM
)
1274 if ((sign_val
== -1) || val
> 0xFE)
1277 val
= ((val
) & 0x00ff);
1278 SET_PFX_ARG (val_pfx
);
1279 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1282 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1285 /* Special handling for immediate jumps like jump nz, #03h etc. */
1286 else if (val
< 0xFF && i
.types
[0] == FLAG
)
1287 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1289 else if ((((sign_val
== -1) || val
> 0xFE)) && i
.types
[0] == FLAG
)
1292 val
= ((val
) & 0x00ff);
1293 SET_PFX_ARG (val_pfx
);
1294 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1298 as_bad (_("Invalid immediate move operation"));
1304 /* All the instruction with operation on ACC: like ADD src, etc. */
1305 if ((sign_val
== -1) || val
> 0xFE)
1308 val
= ((val
) & 0x00ff);
1309 SET_PFX_ARG (val_pfx
);
1310 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1313 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1321 extract_int_val (const char *imm_start
)
1333 if (imm_start
[k
] == '-' && k
== 0)
1336 else if (imm_start
[k
] == '+' && k
== 0)
1339 else if (isdigit (imm_start
[k
]))
1340 temp
[k
] = imm_start
[k
] - '0';
1342 else if (isalpha (imm_start
[k
]) && (tolower (imm_start
[k
])) < 'g')
1343 temp
[k
] = 10 + (int) (tolower (imm_start
[k
]) - 'a');
1345 else if (tolower (imm_start
[k
]) == 'h')
1348 else if ((imm_start
[k
] == '\0') || (imm_start
[k
] == ']'))
1349 /* imm_start[k]='d'; */
1354 as_bad (_("Invalid Character in immediate Value : %c"),
1360 while (imm_start
[k
] != '\n');
1362 switch (imm_start
[k
])
1365 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1366 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1370 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1374 as_bad (_("Invalid Character in immediate value : %c"),
1378 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1385 return val
* sign_val
;
1389 check_for_parse (const char *line
)
1393 if (*(line
+ 1) == '[')
1398 if ((*line
== '-') || (*line
== '+'))
1401 while (!is_space_char (*line
));
1403 if ((*line
== '-') || (*line
== '+'))
1404 val
= extract_int_val (line
);
1406 val
= extract_int_val (line
+ 1);
1408 INSERT_BUFFER
[0] = 0x3E;
1409 INSERT_BUFFER
[1] = val
;
1418 maxq20_mem_access (char *mem_string
, char **end_op
)
1420 char *s
= mem_string
;
1422 char mem_name_given
[MAX_MEM_NAME_SIZE
+ 1];
1427 /* Skip possible whitespace. */
1428 if (is_space_char (*s
))
1432 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1434 if (p
>= mem_name_given
+ MAX_MEM_NAME_SIZE
)
1435 return (mem_access
*) NULL
;
1441 m
= (mem_access
*) hash_find (mem_hash
, mem_name_given
);
1446 /* This function checks whether the operand is a variable in the data segment
1447 and if so, it returns its symbol entry from the symbol table. */
1450 maxq20_data (char *op_string
)
1453 symbolP
= symbol_find (op_string
);
1456 && S_GET_SEGMENT (symbolP
) != now_seg
1457 && S_GET_SEGMENT (symbolP
) != bfd_und_section_ptr
)
1459 /* In case we do not want to always include the prefix instruction and
1460 let the loader handle the job or in case of a 8 bit addressing mode,
1461 we will just check for val_pfx to be equal to zero and then load the
1462 prefix instruction. Otherwise no prefix instruction needs to be
1464 /* The prefix register will have to be loaded automatically as we have
1465 a 16 bit addressing field. */
1466 pfx_for_imm_val (0);
1474 maxq20_displacement (char *disp_start
, char *disp_end
)
1478 char *save_input_line_pointer
;
1480 char *gotfree_input_line
;
1483 gotfree_input_line
= NULL
;
1484 exp
= &disp_expressions
;
1485 i
.maxq20_op
[this_operand
].disps
= exp
;
1487 save_input_line_pointer
= input_line_pointer
;
1488 input_line_pointer
= disp_start
;
1490 END_STRING_AND_SAVE (disp_end
);
1493 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1494 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1496 exp_seg
= expression (exp
);
1499 if (*input_line_pointer
)
1500 as_bad (_("junk `%s' after expression"), input_line_pointer
);
1502 RESTORE_END_STRING (disp_end
+ 1);
1504 RESTORE_END_STRING (disp_end
);
1505 input_line_pointer
= save_input_line_pointer
;
1507 if (gotfree_input_line
)
1508 free (gotfree_input_line
);
1510 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1512 /* Missing or bad expr becomes absolute 0. */
1513 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1515 exp
->X_op
= O_constant
;
1516 exp
->X_add_number
= 0;
1517 exp
->X_add_symbol
= (symbolS
*) 0;
1518 exp
->X_op_symbol
= (symbolS
*) 0;
1520 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1522 if (exp
->X_op
!= O_constant
1523 && OUTPUT_FLAVOR
== bfd_target_aout_flavour
1524 && exp_seg
!= absolute_section
1525 && exp_seg
!= text_section
1526 && exp_seg
!= data_section
1527 && exp_seg
!= bss_section
&& exp_seg
!= undefined_section
1528 && !bfd_is_com_section (exp_seg
))
1530 as_bad (_("unimplemented segment %s in operand"), exp_seg
->name
);
1534 i
.maxq20_op
[this_operand
].disps
= exp
;
1538 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1539 Returns non-zero on error. */
1542 maxq20_operand (char *operand_string
)
1544 reg_entry
*r
= NULL
;
1546 mem_access
*m
= NULL
;
1547 char *end_op
= NULL
;
1548 symbolS
*sym
= NULL
;
1549 char *base_string
= NULL
;
1551 /* Start and end of displacement string expression (if found). */
1552 char *displacement_string_start
= NULL
;
1553 char *displacement_string_end
= NULL
;
1554 /* This maintains the case sentivness. */
1555 char case_str_op_string
[MAX_OPERAND_SIZE
+ 1];
1556 char str_op_string
[MAX_OPERAND_SIZE
+ 1];
1557 char *org_case_op_string
= case_str_op_string
;
1558 char *op_string
= str_op_string
;
1561 memset (op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1562 memset (org_case_op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1564 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1565 memcpy (org_case_op_string
, operand_string
, strlen (operand_string
) + 1);
1567 ii
= strlen (operand_string
) + 1;
1569 if (ii
> MAX_OPERAND_SIZE
)
1571 as_bad (_("Size of Operand '%s' greater than %d"), op_string
,
1578 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1582 if (is_space_char (*op_string
))
1585 if (isxdigit (operand_string
[0]))
1587 /* Now the operands can start with an Integer. */
1588 r
= parse_reg_by_index (op_string
);
1591 if (is_space_char (*op_string
))
1593 i
.types
[this_operand
] = REG
; /* Set the type. */
1594 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1599 /* Get the original string. */
1600 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1601 ii
= strlen (operand_string
) + 1;
1605 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1610 /* Check for flags. */
1611 if (!strcmp (op_string
, "Z"))
1613 if (is_space_char (*op_string
))
1616 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1617 i
.maxq20_op
[this_operand
].flag
= FLAG_Z
; /* Set the Register value. */
1624 else if (!strcmp (op_string
, "NZ"))
1626 if (is_space_char (*op_string
))
1629 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1630 i
.maxq20_op
[this_operand
].flag
= FLAG_NZ
; /* Set the Register value. */
1635 else if (!strcmp (op_string
, "NC"))
1637 if (is_space_char (*op_string
))
1640 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1641 i
.maxq20_op
[this_operand
].flag
= FLAG_NC
; /* Set the Register value. */
1646 else if (!strcmp (op_string
, "E"))
1648 if (is_space_char (*op_string
))
1651 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1652 i
.maxq20_op
[this_operand
].flag
= FLAG_E
; /* Set the Register value. */
1659 else if (!strcmp (op_string
, "S"))
1661 if (is_space_char (*op_string
))
1664 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1665 i
.maxq20_op
[this_operand
].flag
= FLAG_S
; /* Set the Register value. */
1672 else if (!strcmp (op_string
, "C"))
1674 if (is_space_char (*op_string
))
1677 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1678 i
.maxq20_op
[this_operand
].flag
= FLAG_C
; /* Set the Register value. */
1685 else if (!strcmp (op_string
, "NE"))
1688 if (is_space_char (*op_string
))
1691 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1693 i
.maxq20_op
[this_operand
].flag
= FLAG_NE
; /* Set the Register value. */
1700 /* CHECK FOR REGISTER BIT */
1701 else if ((rb
= parse_register_bit (op_string
, &end_op
)) != NULL
)
1705 if (is_space_char (*op_string
))
1708 i
.types
[this_operand
] = BIT
;
1710 i
.maxq20_op
[this_operand
].r_bit
= rb
;
1717 else if (*op_string
== IMMEDIATE_PREFIX
) /* FOR IMMEDITE. */
1719 if (is_space_char (*op_string
))
1722 i
.types
[this_operand
] = IMM
;
1724 if (!maxq20_immediate (op_string
))
1726 as_bad (_("illegal immediate operand '%s'"), op_string
);
1732 else if (*op_string
== ABSOLUTE_PREFIX
|| !strcmp (op_string
, "NUL"))
1734 if (is_space_char (*op_string
))
1737 /* For new requiremnt of copiler of for, @(BP,cons). */
1738 if (check_for_parse (op_string
))
1740 memset (op_string
, '\0', strlen (op_string
) + 1);
1741 memcpy (op_string
, "@BP[OFFS]\0", 11);
1744 i
.types
[this_operand
] = MEM
;
1746 if ((m
= maxq20_mem_access (op_string
, &end_op
)) == NULL
)
1748 as_bad (_("Invalid operand for memory access '%s'"), op_string
);
1751 i
.maxq20_op
[this_operand
].mem
= m
;
1758 else if ((r
= parse_register (op_string
, &end_op
)) != NULL
) /* Check for register. */
1762 if (is_space_char (*op_string
))
1765 i
.types
[this_operand
] = REG
; /* Set the type. */
1766 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1771 if (this_operand
== 1)
1773 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1774 /* The operand can either be a data reference or a symbol reference. */
1775 if ((sym
= maxq20_data (org_case_op_string
)) != NULL
) /* Check for data memory. */
1777 while (is_space_char (*op_string
))
1780 /* Set the type of the operand. */
1781 i
.types
[this_operand
] = DATA
;
1783 /* Set the value of the data. */
1784 i
.maxq20_op
[this_operand
].data
= sym
;
1790 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1792 /* This is a memory reference of some sort. char *base_string;
1793 Start and end of displacement string expression (if found). char
1794 *displacement_string_start; char *displacement_string_end. */
1795 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1798 if (is_space_char (*base_string
))
1801 /* If we only have a displacement, set-up for it to be parsed
1803 displacement_string_start
= org_case_op_string
;
1804 displacement_string_end
= base_string
+ 1;
1805 if (displacement_string_start
!= displacement_string_end
)
1807 if (!maxq20_displacement (displacement_string_start
,
1808 displacement_string_end
))
1810 as_bad (_("illegal displacement operand "));
1813 /* A displacement operand found. */
1814 i
.types
[this_operand
] = DISP
; /* Set the type. */
1820 /* Check for displacement. */
1821 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1823 /* This is a memory reference of some sort. char *base_string;
1824 Start and end of displacement string expression (if found). char
1825 *displacement_string_start; char *displacement_string_end; */
1826 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1829 if (is_space_char (*base_string
))
1832 /* If we only have a displacement, set-up for it to be parsed later. */
1833 displacement_string_start
= org_case_op_string
;
1834 displacement_string_end
= base_string
+ 1;
1835 if (displacement_string_start
!= displacement_string_end
)
1837 if (!maxq20_displacement (displacement_string_start
,
1838 displacement_string_end
))
1840 /* A displacement operand found. */
1841 i
.types
[this_operand
] = DISP
; /* Set the type. */
1847 /* Parse_operand takes as input instruction and operands and Parse operands
1848 and makes entry in the template. */
1851 parse_operands (char *l
, const char *mnemonic
)
1855 /* 1 if operand is pending after ','. */
1856 short int expecting_operand
= 0;
1858 /* Non-zero if operand parens not balanced. */
1859 short int paren_not_balanced
;
1863 /* For Overcoming Warning of unused variable. */
1867 while (*l
!= END_OF_INSN
)
1869 /* Skip optional white space before operand. */
1870 if (is_space_char (*l
))
1873 if (!is_operand_char (*l
) && *l
!= END_OF_INSN
)
1875 as_bad (_("invalid character %c before operand %d"),
1876 (char) (*l
), i
.operands
+ 1);
1881 paren_not_balanced
= 0;
1882 while (paren_not_balanced
|| *l
!= ',')
1884 if (*l
== END_OF_INSN
)
1886 if (paren_not_balanced
)
1888 as_bad (_("unbalanced brackets in operand %d."),
1895 else if (!is_operand_char (*l
) && !is_space_char (*l
))
1897 as_bad (_("invalid character %c in operand %d"),
1898 (char) (*l
), i
.operands
+ 1);
1902 ++paren_not_balanced
;
1904 --paren_not_balanced
;
1908 if (l
!= token_start
)
1910 /* Yes, we've read in another operand. */
1911 this_operand
= i
.operands
++;
1912 if (i
.operands
> MAX_OPERANDS
)
1914 as_bad (_("spurious operands; (%d operands/instruction max)"),
1919 /* Now parse operand adding info to 'i' as we go along. */
1920 END_STRING_AND_SAVE (l
);
1922 operand_ok
= maxq20_operand (token_start
);
1924 RESTORE_END_STRING (l
);
1931 if (expecting_operand
)
1933 expecting_operand_after_comma
:
1934 as_bad (_("expecting operand after ','; got nothing"));
1941 if (*(++l
) == END_OF_INSN
)
1942 /* Just skip it, if it's \n complain. */
1943 goto expecting_operand_after_comma
;
1945 expecting_operand
= 1;
1953 match_operands (int type
, MAX_ARG_TYPE flag_type
, MAX_ARG_TYPE arg_type
,
1959 if ((arg_type
& A_REG
) == A_REG
)
1963 if ((arg_type
& A_IMM
) == A_IMM
)
1967 if ((arg_type
& A_BIT_0
) == A_BIT_0
&& (i
.maxq20_op
[op_num
].imms
== 0))
1969 else if ((arg_type
& A_BIT_1
) == A_BIT_1
1970 && (i
.maxq20_op
[op_num
].imms
== 1))
1974 if ((arg_type
& A_MEM
) == A_MEM
)
1979 if ((arg_type
& flag_type
) == flag_type
)
1985 if ((arg_type
& ACC_BIT
) == ACC_BIT
&& !strcmp (i
.maxq20_op
[op_num
].r_bit
->reg
->reg_name
, "ACC"))
1987 else if ((arg_type
& SRC_BIT
) == SRC_BIT
&& (op_num
== 1))
1989 else if ((op_num
== 0) && (arg_type
& DST_BIT
) == DST_BIT
)
1993 if ((arg_type
& A_DISP
) == A_DISP
)
1996 if ((arg_type
& A_DATA
) == A_DATA
)
1999 if ((arg_type
& A_BIT_BUCKET
) == A_BIT_BUCKET
)
2006 match_template (void)
2008 /* Points to template once we've found it. */
2009 const MAXQ20_OPCODE_INFO
*t
;
2013 for (t
= current_templates
->start
; t
< current_templates
->end
; t
++)
2015 /* Must have right number of operands. */
2016 if (i
.operands
!= t
->op_number
)
2018 else if (!t
->op_number
)
2024 if (!match_operands (i
.types
[1], i
.maxq20_op
[1].flag
, t
->arg
[1], 1))
2030 if (!match_operands (i
.types
[0], i
.maxq20_op
[0].flag
, t
->arg
[0], 0))
2039 if (t
== current_templates
->end
)
2041 /* We found no match. */
2042 as_bad (_("operand %d is invalid for `%s'"),
2043 inv_oper
, current_templates
->start
->name
);
2047 /* Copy the template we have found. */
2052 /* This function filters out the various combinations of operands which are
2053 not allowed for a particular instruction. */
2056 match_filters (void)
2058 /* Now we have at our disposal the instruction i. We will be using the
2059 following fields i.op.name : This is the mnemonic name. i.types[2] :
2060 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2061 i.maxq20_op[2] : This contains the specific info of the operands. */
2063 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2065 if (!strcmp (i
.op
.name
, "AND") || !strcmp (i
.op
.name
, "OR")
2066 || !strcmp (i
.op
.name
, "XOR") || !strcmp (i
.op
.name
, "ADD")
2067 || !strcmp (i
.op
.name
, "ADDC") || !strcmp (i
.op
.name
, "SUB")
2068 || !strcmp (i
.op
.name
, "SUBB"))
2070 if (i
.types
[0] == REG
)
2072 if (i
.maxq20_op
[0].reg
->Mod_name
== 0xa)
2075 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2081 if (!strcmp (i
.op
.name
, "MOVE") && (i
.types
[0] == MEM
|| i
.types
[1] == MEM
)
2084 mem_access_syntax
*mem_op
= NULL
;
2086 if (i
.types
[0] == MEM
)
2089 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2090 i
.maxq20_op
[0].mem
->name
);
2091 if ((mem_op
->type
== SRC
) && mem_op
)
2093 as_bad (_("'%s' operand cant be used as destination in %s"),
2094 mem_op
->name
, i
.op
.name
);
2097 else if ((mem_op
->invalid_op
!= NULL
) && (i
.types
[1] == MEM
)
2102 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2104 if (mem_op
->invalid_op
[k
] != NULL
)
2106 (mem_op
->invalid_op
[k
], i
.maxq20_op
[1].mem
->name
))
2109 ("Invalid Instruction '%s' operand cant be used with %s"),
2110 mem_op
->name
, i
.maxq20_op
[1].mem
->name
);
2117 if (i
.types
[1] == MEM
)
2121 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2122 i
.maxq20_op
[1].mem
->name
);
2123 if (mem_op
->type
== DST
&& mem_op
)
2125 as_bad (_("'%s' operand cant be used as source in %s"),
2126 mem_op
->name
, i
.op
.name
);
2129 else if (mem_op
->invalid_op
!= NULL
&& i
.types
[0] == MEM
&& mem_op
)
2133 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2135 if (mem_op
->invalid_op
[k
] != NULL
)
2137 (mem_op
->invalid_op
[k
], i
.maxq20_op
[0].mem
->name
))
2140 ("Invalid Instruction '%s' operand cant be used with %s"),
2141 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2146 else if (i
.types
[0] == REG
2147 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "OFFS")
2150 if (!strcmp (mem_op
->name
, "@BP[OFFS--]")
2151 || !strcmp (mem_op
->name
, "@BP[OFFS++]"))
2154 ("Invalid Instruction '%s' operand cant be used with %s"),
2155 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2162 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2163 on 10-March-2004. */
2164 if ((i
.types
[0] == MEM
) && (i
.operands
== 1)
2165 && !(!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI")))
2167 mem_access_syntax
*mem_op
= NULL
;
2169 if (i
.types
[0] == MEM
)
2172 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2173 i
.maxq20_op
[0].mem
->name
);
2174 if (mem_op
->type
== DST
&& mem_op
)
2176 as_bad (_("'%s' operand cant be used as source in %s"),
2177 mem_op
->name
, i
.op
.name
);
2183 if (i
.operands
== 2 && i
.types
[0] == IMM
)
2185 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2190 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2191 if (!strcmp (i
.op
.name
, "PUSH") || !strcmp (i
.op
.name
, "POP")
2192 || !strcmp (i
.op
.name
, "POPI"))
2194 if (i
.types
[0] == REG
)
2196 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
2198 as_bad (_("SP cannot be used with %s\n"), i
.op
.name
);
2202 else if (i
.types
[0] == MEM
2203 && !strcmp (i
.maxq20_op
[0].mem
->name
, "@SP--"))
2205 as_bad (_("@SP-- cannot be used with PUSH\n"));
2210 /* This filter checks that two memory references using DP's cannot be used
2211 together in an instruction */
2212 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 2)
2214 if (strlen (i
.maxq20_op
[0].mem
->name
) != 6 ||
2215 strcmp (i
.maxq20_op
[0].mem
->name
, i
.maxq20_op
[1].mem
->name
))
2217 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@DP", 3)
2218 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@DP", 3))
2221 ("Operands either contradictory or use the data bus in read/write state together"));
2225 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@SP", 3)
2226 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@SP", 3))
2229 ("Operands either contradictory or use the data bus in read/write state together"));
2233 if ((i
.maxq20_op
[1].mem
!= NULL
)
2234 && !strncmp (i
.maxq20_op
[1].mem
->name
, "NUL", 3))
2236 as_bad (_("MOVE Cant Use NUL as SRC"));
2241 /* This filter checks that contradictory movement between DP register and
2242 Memory access using DP followed by increment or decrement. */
2244 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 1
2245 && i
.reg_operands
== 1)
2249 memnum
= (i
.types
[0] == MEM
) ? 0 : 1;
2250 regnum
= (memnum
== 0) ? 1 : 0;
2251 if (!strncmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "DP", 2) &&
2252 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2253 i
.maxq20_op
[regnum
].reg
->reg_name
, 5)
2254 && strcmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2255 i
.maxq20_op
[regnum
].reg
->reg_name
))
2258 ("Contradictory movement between DP register and memory access using DP"));
2261 else if (!strcmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "SP") &&
2262 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2263 i
.maxq20_op
[regnum
].reg
->reg_name
, 2))
2266 ("SP and @SP-- cannot be used together in a move instruction"));
2271 /* This filter restricts the instructions containing source and destination
2272 bits to only CTRL module of the serial registers. Peripheral registers
2273 yet to be defined. */
2275 if (i
.bit_operands
== 1 && i
.operands
== 2)
2277 int bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2279 if (strcmp (i
.maxq20_op
[bitnum
].r_bit
->reg
->reg_name
, "ACC"))
2281 if (i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
>= 0x7 &&
2282 i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
!= CTRL
)
2285 ("Only Module 8 system registers allowed in this operation"));
2291 /* This filter is for checking the register bits. */
2292 if (i
.bit_operands
== 1 || i
.operands
== 2)
2294 int bitnum
= 0, size
= 0;
2296 bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2297 if (i
.bit_operands
== 1)
2299 switch (i
.maxq20_op
[bitnum
].r_bit
->reg
->rtype
)
2302 size
= 7; /* 8 bit register, both read and write. */
2311 as_fatal (_("Read only Register used as destination"));
2320 as_fatal (_("Read only Register used as destination"));
2326 if (size
< (i
.maxq20_op
[bitnum
].r_bit
)->bit
)
2328 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2329 (i
.maxq20_op
[bitnum
].r_bit
)->bit
);
2334 if (i
.bit_operands
== 2)
2336 switch ((i
.maxq20_op
[0].r_bit
)->reg
->rtype
)
2339 size
= 7; /* 8 bit register, both read and write. */
2346 as_fatal (_("Read only Register used as destination"));
2350 if (size
< (i
.maxq20_op
[0].r_bit
)->bit
)
2353 ("Bit No '%d' exceeds register size in this operation"),
2354 (i
.maxq20_op
[0].r_bit
)->bit
);
2359 switch ((i
.maxq20_op
[1].r_bit
)->reg
->rtype
)
2363 size
= 7; /* 8 bit register, both read and write. */
2371 if (size
< (i
.maxq20_op
[1].r_bit
)->bit
)
2374 ("Bit No '%d' exceeds register size in this operation"),
2375 (i
.maxq20_op
[1].r_bit
)->bit
);
2381 /* No branch operations should occur into the data memory. Hence any memory
2382 references have to be filtered out when used with instructions like
2383 jump, djnz[] and call. */
2385 if (!strcmp (i
.op
.name
, "JUMP") || !strcmp (i
.op
.name
, "CALL")
2386 || !strncmp (i
.op
.name
, "DJNZ", 4))
2390 ("Memory References cannot be used with branching operations\n"));
2393 if (!strcmp (i
.op
.name
, "DJNZ"))
2396 (strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2397 || strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))
2399 as_bad (_("DJNZ uses only LC[n] register \n"));
2404 /* No destination register used should be read only! */
2405 if ((i
.operands
== 2 && i
.types
[0] == REG
) || !strcmp (i
.op
.name
, "POP")
2406 || !strcmp (i
.op
.name
, "POPI"))
2407 { /* The destination is a register */
2410 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2414 if (i
.types
[regnum
] == MEM
)
2416 mem_access_syntax
*mem_op
= NULL
;
2419 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2420 i
.maxq20_op
[regnum
].mem
->
2422 if (mem_op
->type
== SRC
&& mem_op
)
2425 ("'%s' operand cant be used as destination in %s"),
2426 mem_op
->name
, i
.op
.name
);
2432 if (i
.maxq20_op
[regnum
].reg
->rtype
== Reg_8R
2433 || i
.maxq20_op
[regnum
].reg
->rtype
== Reg_16R
)
2435 as_bad (_("Read only register used for writing purposes '%s'"),
2436 i
.maxq20_op
[regnum
].reg
->reg_name
);
2441 /* While moving the address of a data in the data section, the destination
2442 should be either data pointers only. */
2443 if ((i
.data_operands
) && (i
.operands
== 2))
2445 if ((i
.types
[0] != REG
) && (i
.types
[0] != MEM
))
2447 as_bad (_("Invalid destination for this kind of source."));
2451 if (i
.types
[0] == REG
&& i
.maxq20_op
[0].reg
->rtype
== Reg_8W
)
2454 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2464 /* Check for the format Bit if defined. */
2465 if (i
.op
.format
== 0 || i
.op
.format
== 1)
2466 i
.instr
[0] = i
.op
.format
<< 7;
2469 /* Format bit not defined. We will have to be find it out ourselves. */
2470 if (i
.imm_operands
== 1 || i
.data_operands
== 1 || i
.disp_operands
== 1)
2474 i
.instr
[0] = i
.op
.format
<< 7;
2477 /* Now for the destination register. */
2479 /* If destination register is already defined . The conditions are the
2480 following: (1) The second entry in the destination array should be 0 (2)
2481 If there are two operands then the first entry should not be a register,
2482 memory or a register bit (3) If there are less than two operands and the
2483 it is not a pop operation (4) The second argument is the carry
2484 flag(applicable to move Acc.<b>,C. */
2485 if (i
.op
.dst
[1] == 0
2487 ((i
.types
[0] != REG
&& i
.types
[0] != MEM
&& i
.types
[0] != BIT
2488 && i
.operands
== 2) || (i
.operands
< 2 && strcmp (i
.op
.name
, "POP")
2489 && strcmp (i
.op
.name
, "POPI"))
2490 || (i
.op
.arg
[1] == FLAG_C
)))
2492 i
.op
.dst
[0] &= 0x7f;
2493 i
.instr
[0] |= i
.op
.dst
[0];
2495 else if (i
.op
.dst
[1] == 0 && !strcmp (i
.op
.name
, "DJNZ")
2497 (((i
.types
[0] == REG
)
2498 && (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2499 || !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))))
2501 i
.op
.dst
[0] &= 0x7f;
2502 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]"))
2505 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]"))
2512 /* Target register will have to be specified. */
2513 if (i
.types
[0] == REG
2514 && (i
.op
.dst
[0] == REG
|| i
.op
.dst
[0] == (REG
| MEM
)))
2516 temp
= (i
.maxq20_op
[0].reg
)->opcode
;
2520 else if (i
.types
[0] == MEM
&& (i
.op
.dst
[0] == (REG
| MEM
)))
2522 temp
= (i
.maxq20_op
[0].mem
)->opcode
;
2526 else if (i
.types
[0] == BIT
&& (i
.op
.dst
[0] == REG
))
2528 temp
= (i
.maxq20_op
[0].r_bit
)->reg
->opcode
;
2532 else if (i
.types
[1] == BIT
&& (i
.op
.dst
[0] == BIT
))
2534 temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2536 temp
|= i
.op
.dst
[1];
2542 as_bad (_("Invalid Instruction"));
2547 /* Now for the source register. */
2549 /* If Source register is already known. The following conditions are
2550 checked: (1) There are no operands (2) If there is only one operand and
2551 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2554 if (i
.operands
== 0 || (i
.operands
== 1 && i
.types
[0] == FLAG
)
2555 || (i
.types
[0] == FLAG
&& i
.types
[1] == IMMBIT
)
2556 || !strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2557 i
.instr
[1] = i
.op
.src
[0];
2559 else if (i
.imm_operands
== 1 && ((i
.op
.src
[0] & IMM
) == IMM
))
2560 i
.instr
[1] = i
.maxq20_op
[this_operand
].imms
;
2562 else if (i
.types
[this_operand
] == REG
&& ((i
.op
.src
[0] & REG
) == REG
))
2563 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].reg
)->opcode
);
2565 else if (i
.types
[this_operand
] == BIT
&& ((i
.op
.src
[0] & REG
) == REG
))
2566 i
.instr
[1] = (char) (i
.maxq20_op
[this_operand
].r_bit
->reg
->opcode
);
2568 else if (i
.types
[this_operand
] == MEM
&& ((i
.op
.src
[0] & MEM
) == MEM
))
2569 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].mem
)->opcode
);
2571 else if (i
.types
[this_operand
] == DATA
&& ((i
.op
.src
[0] & DATA
) == DATA
))
2572 /* This will copy only the lower order bytes into the instruction. The
2573 higher order bytes have already been copied into the prefix register. */
2576 /* Decoding the source in the case when the second array entry is not 0.
2577 This means that the source register has been divided into two nibbles. */
2579 else if (i
.op
.src
[1] != 0)
2581 /* If the first operand is a accumulator bit then
2582 the first 4 bits will be filled with the bit number. */
2583 if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & BIT
) == BIT
))
2585 unsigned char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2588 temp
|= i
.op
.src
[1];
2591 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2592 has to start with a zero. This is called a ZEROBIT */
2593 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ZEROBIT
) == ZEROBIT
))
2595 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2598 temp
|= i
.op
.src
[1];
2602 /* Similarly for a ONEBIT */
2603 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ONEBIT
) == ONEBIT
))
2605 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2608 temp
|= i
.op
.src
[1];
2612 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2614 else if (i
.types
[1] == BIT
)
2616 if (i
.op
.src
[1] == 0 && i
.op
.src
[1] == REG
)
2617 i
.instr
[1] = (i
.maxq20_op
[1].r_bit
)->reg
->opcode
;
2619 else if (i
.op
.src
[0] == BIT
&& i
.op
.src
)
2621 char temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2624 temp
|= i
.op
.src
[1];
2630 as_bad (_("Invalid Instruction"));
2637 /* This is a function for outputting displacement operands. */
2640 output_disp (fragS
*insn_start_frag
, offsetT insn_start_off
)
2643 relax_substateT subtype
;
2649 insn_start_frag
= frag_now
;
2650 insn_start_off
= frag_now_fix ();
2652 switch (i
.Instr_Prefix
)
2655 subtype
= EXPLICT_LONG_PREFIX
;
2658 subtype
= SHORT_PREFIX
;
2661 subtype
= NO_PREFIX
;
2665 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2666 case there is no need for relaxation. But we do need support for a
2667 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2668 for prefix + 2 for the current instruction ) Hence if at a particular
2669 time we find out whether the prefix operator is reqd , we shift the
2670 current instruction two places ahead and insert the prefix instruction. */
2674 sym
= i
.maxq20_op
[this_operand
].disps
->X_add_symbol
;
2675 off
= i
.maxq20_op
[this_operand
].disps
->X_add_number
;
2677 if (i
.maxq20_op
[this_operand
].disps
->X_add_symbol
!= NULL
&& sym
&& frag_now
2678 && (subtype
!= EXPLICT_LONG_PREFIX
))
2680 /* If in the same frag. */
2681 if (frag_now
== symbol_get_frag (sym
))
2684 ((((expressionS
*) symbol_get_value_expression (sym
))->
2685 X_add_number
) - insn_start_off
);
2687 /* PC points to the next instruction. */
2688 diff
= (diff
/ MAXQ_OCTETS_PER_BYTE
) - 1;
2690 if (diff
>= -128 && diff
<= 127)
2692 i
.instr
[1] = (char) diff
;
2694 /* This will be overwritten later when the symbol is resolved. */
2696 *(p
+ 1) = i
.instr
[0];
2698 /* No Need to create a FIXUP. */
2704 /* This will be overwritten later when the symbol is resolved. */
2706 *(p
+ 1) = i
.instr
[0];
2708 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2709 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2711 /* Handle complex expressions. */
2712 sym
= make_expr_symbol (i
.maxq20_op
[this_operand
].disps
);
2716 /* Vineet : This has been added for md_estimate_size_before_relax to
2717 estimate the correct size. */
2718 if (subtype
!= SHORT_PREFIX
)
2719 i
.reloc
[this_operand
] = LONG_PREFIX
;
2721 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2724 /* This is a function for outputting displacement operands. */
2727 output_data (fragS
*insn_start_frag
, offsetT insn_start_off
)
2730 relax_substateT subtype
;
2737 insn_start_frag
= frag_now
;
2738 insn_start_off
= frag_now_fix ();
2740 subtype
= EXPLICT_LONG_PREFIX
;
2745 sym
= i
.maxq20_op
[this_operand
].data
;
2748 /* This will be overwritten later when the symbol is resolved. */
2750 *(p
+ 1) = i
.instr
[0];
2752 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2753 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2754 /* Handle complex expressions. */
2755 /* Because data is already in terms of symbol so no
2756 need to convert it from expression to symbol. */
2759 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2765 fragS
*insn_start_frag
;
2766 offsetT insn_start_off
;
2769 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2770 do this after the insn has been output as the current frag may have been
2771 closed off. eg. by frag_var. */
2772 dwarf2_emit_insn (0);
2774 /* To ALign the text section on word. */
2776 frag_align (1, 0, 1);
2778 /* We initialise the frags for this particular instruction. */
2779 insn_start_frag
= frag_now
;
2780 insn_start_off
= frag_now_fix ();
2782 /* If there are displacement operators(unresolved) present, then handle
2784 if (i
.disp_operands
)
2786 output_disp (insn_start_frag
, insn_start_off
);
2790 if (i
.data_operands
)
2792 output_data (insn_start_frag
, insn_start_off
);
2796 /* Check whether the INSERT_BUFFER has to be written. */
2797 if (strcmp (INSERT_BUFFER
, ""))
2801 *p
++ = INSERT_BUFFER
[1];
2802 *p
= INSERT_BUFFER
[0];
2805 /* Check whether the prefix instruction has to be written. */
2806 if (strcmp (PFX_INSN
, ""))
2815 /* For Little endian. */
2821 make_new_reg_table (void)
2823 unsigned long size_pm
= sizeof (peripheral_reg_table
);
2824 num_of_reg
= ARRAY_SIZE (peripheral_reg_table
);
2826 new_reg_table
= xmalloc (size_pm
);
2827 if (new_reg_table
== NULL
)
2828 as_bad (_("Cannot allocate memory"));
2830 memcpy (new_reg_table
, peripheral_reg_table
, size_pm
);
2833 /* pmmain performs the initilizations for the pheripheral modules. */
2838 make_new_reg_table ();
2845 const char *hash_err
= NULL
;
2848 const MAXQ20_OPCODE_INFO
*optab
;
2849 MAXQ20_OPCODES
*core_optab
; /* For opcodes of the same name. This will
2850 be inserted into the hash table. */
2851 struct reg
*reg_tab
;
2852 struct mem_access_syntax
const *memsyntab
;
2853 struct mem_access
*memtab
;
2854 struct bit_name
*bittab
;
2856 /* Initilize pherioipheral modules. */
2859 /* Initialise the opcode hash table. */
2860 op_hash
= hash_new ();
2862 optab
= op_table
; /* Initialise it to the first entry of the
2863 maxq20 operand table. */
2865 /* Setup for loop. */
2866 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2867 core_optab
->start
= optab
;
2872 if (optab
->name
== NULL
|| strcmp (optab
->name
, (optab
- 1)->name
) != 0)
2874 /* different name --> ship out current template list; add to hash
2875 table; & begin anew. */
2877 core_optab
->end
= optab
;
2879 if (max_version
== bfd_mach_maxq10
)
2881 if (((optab
- 1)->arch
== MAXQ10
) || ((optab
- 1)->arch
== MAX
))
2883 hash_err
= hash_insert (op_hash
,
2888 else if (max_version
== bfd_mach_maxq20
)
2890 if (((optab
- 1)->arch
== MAXQ20
) || ((optab
- 1)->arch
== MAX
))
2893 hash_err
= hash_insert (op_hash
,
2900 as_fatal (_("Internal Error: Illegal Architecure specified"));
2903 as_fatal (_("Internal Error: Can't hash %s: %s"),
2904 (optab
- 1)->name
, hash_err
);
2906 if (optab
->name
== NULL
)
2908 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2909 core_optab
->start
= optab
;
2913 /* Initialise a new register table. */
2914 reg_hash
= hash_new ();
2916 for (reg_tab
= system_reg_table
;
2917 reg_tab
< (system_reg_table
+ ARRAY_SIZE (system_reg_table
));
2921 switch (max_version
)
2923 case bfd_mach_maxq10
:
2924 if ((reg_tab
->arch
== MAXQ10
) || (reg_tab
->arch
== MAX
))
2925 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
2928 case bfd_mach_maxq20
:
2929 if ((reg_tab
->arch
== MAXQ20
) || (reg_tab
->arch
== MAX
))
2933 hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
2938 as_fatal (_("Invalid architecture type"));
2943 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2944 reg_tab
->reg_name
, hash_err
);
2947 /* Pheripheral Registers Entry. */
2948 for (reg_tab
= new_reg_table
;
2949 reg_tab
< (new_reg_table
+ num_of_reg
- 1); reg_tab
++)
2951 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (PTR
) reg_tab
);
2954 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2955 reg_tab
->reg_name
, hash_err
);
2958 /* Initialise a new memory operand table. */
2959 mem_hash
= hash_new ();
2961 for (memtab
= mem_table
;
2962 memtab
< mem_table
+ ARRAY_SIZE (mem_table
);
2965 hash_err
= hash_insert (mem_hash
, memtab
->name
, (PTR
) memtab
);
2967 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2968 memtab
->name
, hash_err
);
2971 bit_hash
= hash_new ();
2973 for (bittab
= bit_table
;
2974 bittab
< bit_table
+ ARRAY_SIZE (bit_table
);
2977 hash_err
= hash_insert (bit_hash
, bittab
->name
, (PTR
) bittab
);
2979 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2980 bittab
->name
, hash_err
);
2983 mem_syntax_hash
= hash_new ();
2985 for (memsyntab
= mem_access_syntax_table
;
2986 memsyntab
< mem_access_syntax_table
+ ARRAY_SIZE (mem_access_syntax_table
);
2990 hash_insert (mem_syntax_hash
, memsyntab
->name
, (PTR
) memsyntab
);
2992 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2993 memsyntab
->name
, hash_err
);
2996 /* Initialise the lexical tables,mnemonic chars,operand chars. */
2997 for (c
= 0; c
< 256; c
++)
3002 mnemonic_chars
[c
] = c
;
3003 operand_chars
[c
] = c
;
3004 register_chars
[c
] = c
;
3006 else if (ISLOWER (c
))
3008 mnemonic_chars
[c
] = c
;
3009 operand_chars
[c
] = c
;
3010 register_chars
[c
] = c
;
3012 else if (ISUPPER (c
))
3014 mnemonic_chars
[c
] = TOLOWER (c
);
3015 register_chars
[c
] = c
;
3016 operand_chars
[c
] = c
;
3019 if (ISALPHA (c
) || ISDIGIT (c
))
3021 identifier_chars
[c
] = c
;
3025 identifier_chars
[c
] = c
;
3026 operand_chars
[c
] = c
;
3030 /* All the special characters. */
3031 register_chars
['@'] = '@';
3032 register_chars
['+'] = '+';
3033 register_chars
['-'] = '-';
3034 digit_chars
['-'] = '-';
3035 identifier_chars
['_'] = '_';
3036 identifier_chars
['.'] = '.';
3037 register_chars
['['] = '[';
3038 register_chars
[']'] = ']';
3039 operand_chars
['_'] = '_';
3040 operand_chars
['#'] = '#';
3041 mnemonic_chars
['['] = '[';
3042 mnemonic_chars
[']'] = ']';
3044 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
3045 operand_chars
[(unsigned char) *p
] = (unsigned char) *p
;
3047 /* Set the maxq arch type. */
3048 maxq_target (max_version
);
3051 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3052 menmunonic in the operand table - Parse operands and populate the
3053 structure/template - Match the operand with opcode and its validity -
3057 md_assemble (char *line
)
3061 char mnemonic
[MAX_MNEM_SIZE
];
3062 char temp4prev
[256];
3063 static char prev_insn
[256];
3065 /* Initialize globals. */
3066 memset (&i
, '\0', sizeof (i
));
3067 for (j
= 0; j
< MAX_OPERANDS
; j
++)
3068 i
.reloc
[j
] = NO_RELOC
;
3073 INSERT_BUFFER
[0] = 0;
3074 INSERT_BUFFER
[1] = 0;
3076 memcpy (temp4prev
, line
, strlen (line
) + 1);
3078 save_stack_p
= save_stack
;
3080 line
= (char *) parse_insn (line
, mnemonic
);
3084 line
= (char *) parse_operands (line
, mnemonic
);
3088 /* Next, we find a template that matches the given insn, making sure the
3089 overlap of the given operands types is consistent with the template
3091 if (!match_template ())
3094 /* In the MAXQ20, there are certain register combinations, and other
3095 restrictions which are not allowed. We will try to resolve these right
3097 if (!match_filters ())
3100 /* Check for the appropriate PFX register. */
3102 pfx_for_imm_val (0);
3104 if (!decode_insn ()) /* decode insn. */
3107 /* Check for Exlipct PFX instruction. */
3108 if (PFX_INSN
[0] && (strstr (prev_insn
, "PFX") || strstr (prev_insn
, "pfx")))
3109 as_warn (_("Ineffective insntruction %s \n"), prev_insn
);
3111 memcpy (prev_insn
, temp4prev
, strlen (temp4prev
) + 1);
3113 /* We are ready to output the insn. */