1 /* tc-maxq.c -- assembler code for a MAXQ chip.
3 Copyright 2004, 2005, 2006, 2007, 2008, 2009 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 3, 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 gas_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"),
383 md_atof (int type
, char * litP
, int * sizeP
)
386 /* The size of Double has been changed to 2 words ie 32 bits. */
388 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
392 maxq20_cons_fix_new (fragS
* frag
, unsigned int off
, unsigned int len
,
400 r
= MAXQ_WORDDATA
; /* Word+n */
403 r
= MAXQ_LONGDATA
; /* Long+n */
407 fix_new_exp (frag
, off
, len
, exp
, 0, r
);
411 /* GAS will call this for every rs_machine_dependent fragment. The
412 instruction is completed using the data from the relaxation pass. It may
413 also create any necessary relocations. */
415 md_convert_frag (bfd
* headers ATTRIBUTE_UNUSED
,
416 segT seg ATTRIBUTE_UNUSED
,
420 offsetT target_address
;
421 offsetT opcode_address
;
422 offsetT displacement_from_opcode_start
;
425 opcode
= fragP
->fr_opcode
;
427 target_address
= opcode_address
= displacement_from_opcode_start
= 0;
430 (S_GET_VALUE (fragP
->fr_symbol
) / MAXQ_OCTETS_PER_BYTE
) +
431 (fragP
->fr_offset
/ MAXQ_OCTETS_PER_BYTE
);
434 (fragP
->fr_address
/ MAXQ_OCTETS_PER_BYTE
) +
435 ((fragP
->fr_fix
- 2) / MAXQ_OCTETS_PER_BYTE
);
437 /* PC points to the next Instruction. */
438 displacement_from_opcode_start
= ((target_address
- opcode_address
) - 1);
440 if ((displacement_from_opcode_start
>= -128
441 && displacement_from_opcode_start
<= 127)
442 && (fragP
->fr_subtype
== SHORT_PREFIX
443 || fragP
->fr_subtype
== NO_PREFIX
))
445 /* Its a displacement. */
446 *opcode
= (char) displacement_from_opcode_start
;
450 /* Its an absolute 16 bit jump. Now we have to
451 load the prefix operator with the upper 8 bits. */
452 if (fragP
->fr_subtype
== SHORT_PREFIX
)
454 as_bad (_("Cant make long jump/call into short jump/call : %d"),
459 /* Check whether the symbol has been resolved or not.
460 Otherwise we will have to generate a fixup. */
462 if (fragP
->fr_subtype
!= SHORT_PREFIX
)
464 RELOC_ENUM reloc_type
;
468 /* Now this is a basolute jump/call.
469 Hence we will have to create a fixup. */
470 if (fragP
->fr_subtype
== NO_PREFIX
)
471 fragP
->fr_subtype
= LONG_PREFIX
;
474 (fragP
->fr_subtype
? fragP
->fr_subtype
: LONG_PREFIX
);
478 old_fr_fix
= fragP
->fr_fix
;
480 fragP
->fr_fix
+= (size
);
482 fix_new (fragP
, old_fr_fix
- 2, size
+ 2,
483 fragP
->fr_symbol
, fragP
->fr_offset
, 0, reloc_type
);
490 md_pcrel_from (fixS
*fixP
)
492 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
495 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
498 maxq_number_to_chars (char *buf
, valueT val
, int n
)
500 if (target_big_endian
)
501 number_to_chars_bigendian (buf
, val
, n
);
503 number_to_chars_littleendian (buf
, val
, n
);
506 /* GAS will call this for each fixup. It's main objective is to store the
507 correct value in the object file. 'fixup_segment' performs the generic
508 overflow check on the 'valueT *val' argument after md_apply_fix returns.
509 If the overflow check is relevant for the target machine, then
510 'md_apply_fix' should modify 'valueT *val', typically to the value stored
511 in the object file (not to be done in MAXQ). */
514 md_apply_fix (fixS
*fixP
, valueT
*valT
, segT seg ATTRIBUTE_UNUSED
)
516 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
517 char *frag_to_fix_at
=
518 fixP
->fx_frag
->fr_literal
+ fixP
->fx_frag
->fr_fix
- 2;
522 if (fixP
->fx_frag
&& valT
)
524 /* If the relaxation substate is not defined we make it equal
525 to the kind of relocation the fixup is generated for. */
526 if (!fixP
->fx_frag
->fr_subtype
)
527 fixP
->fx_frag
->fr_subtype
= fixP
->fx_r_type
;
529 /* For any instruction in which either we have specified an
530 absolute address or it is a long jump we need to add a PFX0
531 instruction to it. In this case as the instruction has already
532 being written at 'fx_where' in the frag we copy it at the end of
533 the frag(which is where the relocation was generated) as when
534 the relocation is generated the frag is grown by 2 type, this is
535 where we copy the contents of fx_where and add a pfx0 at
537 if ((fixP
->fx_frag
->fr_subtype
== ABSOLUTE_ADDR_FOR_DATA
)
538 || (fixP
->fx_frag
->fr_subtype
== LONG_PREFIX
))
540 *(frag_to_fix_at
+ 1) = *(p
+ 1);
541 maxq_number_to_chars (p
+ 1, PFX0
, 1);
544 /* Remember value for tc_gen_reloc. */
545 fixP
->fx_addnumber
= *valT
;
548 /* Some fixups generated by GAS which gets resovled before this this
549 func. is called need to be wriiten to the frag as here we are going
550 to go away with the relocations fx_done=1. */
551 if (fixP
->fx_addsy
== NULL
)
553 maxq_number_to_chars (p
, *valT
, fixP
->fx_size
);
554 fixP
->fx_addnumber
= *valT
;
560 /* Tables for lexical analysis. */
561 static char mnemonic_chars
[256];
562 static char register_chars
[256];
563 static char operand_chars
[256];
564 static char identifier_chars
[256];
565 static char digit_chars
[256];
567 /* Lexical Macros. */
568 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
569 #define is_register_char(x) (register_chars[(unsigned char)(x)])
570 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
571 #define is_space_char(x) (x==' ')
572 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
573 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
575 /* Special characters for operands. */
576 static char operand_special_chars
[] = "[]@.-+";
578 /* md_assemble() will always leave the instruction passed to it unaltered.
579 To do this we store the instruction in a special stack. */
580 static char save_stack
[32];
581 static char *save_stack_p
;
583 #define END_STRING_AND_SAVE(s) \
586 *save_stack_p++ = *(s); \
591 #define RESTORE_END_STRING(s) \
594 *(s) = *(--save_stack_p); \
598 /* The instruction we are assembling. */
599 static maxq20_insn i
;
601 /* The current template. */
602 static MAXQ20_OPCODES
*current_templates
;
604 /* The displacement operand if any. */
605 static expressionS disp_expressions
;
607 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
608 static int this_operand
;
610 /* The prefix instruction if used. */
611 static char PFX_INSN
[2];
612 static char INSERT_BUFFER
[2];
614 /* For interface with expression() ????? */
615 extern char *input_line_pointer
;
617 /* The HASH Tables: */
619 /* Operand Hash Table. */
620 static struct hash_control
*op_hash
;
622 /* Register Hash Table. */
623 static struct hash_control
*reg_hash
;
625 /* Memory reference Hash Table. */
626 static struct hash_control
*mem_hash
;
628 /* Bit hash table. */
629 static struct hash_control
*bit_hash
;
631 /* Memory Access syntax table. */
632 static struct hash_control
*mem_syntax_hash
;
634 /* This is a mapping from pseudo-op names to functions. */
636 const pseudo_typeS md_pseudo_table
[] =
638 {"int", cons
, 2}, /* size of 'int' has been changed to 1 word
640 {"maxq10", maxq_target
, bfd_mach_maxq10
},
641 {"maxq20", maxq_target
, bfd_mach_maxq20
},
645 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
648 /* This function sets the PFX value corresponding to the specs. Source
649 Destination Index Selection ---------------------------------- Write To|
650 SourceRegRange | Dest Addr Range
651 ------------------------------------------------------ PFX[0] | 0h-Fh |
652 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
653 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
654 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
659 short int src_index
= 0, dst_index
= 0;
663 if (i
.operands
== 1) /* Only SRC is Present */
665 if (i
.types
[0] == REG
)
667 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
669 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
674 src_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
682 if (i
.types
[0] == REG
&& i
.types
[1] == REG
)
684 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
685 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
687 else if (i
.types
[0] != REG
&& i
.types
[1] == REG
) /* DST is Absent */
689 src_index
= i
.maxq20_op
[1].reg
[0].Mod_index
;
692 else if (i
.types
[0] == REG
&& i
.types
[1] != REG
) /* Id SRC is Absent */
694 dst_index
= i
.maxq20_op
[0].reg
[0].Mod_index
;
697 else if (i
.types
[0] == BIT
&& i
.maxq20_op
[0].r_bit
)
699 dst_index
= i
.maxq20_op
[0].r_bit
->reg
->Mod_index
;
703 else if (i
.types
[1] == BIT
&& i
.maxq20_op
[1].r_bit
)
706 src_index
= i
.maxq20_op
[1].r_bit
->reg
->Mod_index
;
710 if (src_index
>= 0x00 && src_index
<= 0xF)
712 if (dst_index
>= 0x00 && dst_index
<= 0x07)
716 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
720 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
724 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
728 else if (src_index
>= 0x10 && src_index
<= 0x1F)
730 if (dst_index
>= 0x00 && dst_index
<= 0x07)
734 else if (dst_index
>= 0x08 && dst_index
<= 0x0F)
738 else if (dst_index
>= 0x10 && dst_index
<= 0x17)
742 else if (dst_index
>= 0x18 && dst_index
<= 0x1F)
749 is_a_LSinstr (const char *ln_pointer
)
753 for (i
= 0; LSInstr
[i
] != NULL
; i
++)
754 if (!strcmp (LSInstr
[i
], ln_pointer
))
761 LS_processing (const char *line
)
763 if (is_a_LSinstr (line
))
765 if ((line
[0] == 'L') || (line
[0] == 'l'))
768 INSERT_BUFFER
[0] = PFX0
;
769 i
.Instr_Prefix
= LONG_PREFIX
;
771 else if ((line
[0] == 'S') || (line
[0] == 's'))
772 i
.Instr_Prefix
= SHORT_PREFIX
;
774 i
.Instr_Prefix
= NO_PREFIX
;
777 i
.Instr_Prefix
= LONG_PREFIX
;
780 /* Separate mnemonics and the operands. */
783 parse_insn (char *line
, char *mnemonic
)
786 char *token_start
= l
;
788 char temp
[MAX_MNEM_SIZE
];
791 memset (temp
, END_OF_INSN
, MAX_MNEM_SIZE
);
794 while ((*mnem_p
= mnemonic_chars
[(unsigned char) *l
]) != 0)
798 if (mnem_p
>= mnemonic
+ MAX_MNEM_SIZE
)
800 as_bad (_("no such instruction: `%s'"), token_start
);
806 if (!is_space_char (*l
) && *l
!= END_OF_INSN
)
808 as_bad (_("invalid character %s in mnemonic"), l
);
814 temp
[ii
- 1] = toupper ((char) mnemonic
[ii
- 1]);
818 LS_processing (temp
);
820 if (i
.Instr_Prefix
!= 0 && is_a_LSinstr (temp
))
821 /* Skip the optional L-S. */
822 memcpy (temp
, temp
+ 1, MAX_MNEM_SIZE
);
824 /* Look up instruction (or prefix) via hash table. */
825 current_templates
= (MAXQ20_OPCODES
*) hash_find (op_hash
, temp
);
827 if (current_templates
!= NULL
)
830 as_bad (_("no such instruction: `%s'"), token_start
);
834 /* Function to calculate x to the power of y.
835 Just to avoid including the math libraries. */
842 for (k
= 0; k
< y
; k
++)
849 parse_reg_by_index (char *imm_start
)
851 int k
= 0, mid
= 0, rid
= 0, val
= 0, j
= 0;
852 char temp
[4] = { 0 };
853 reg_entry
*reg
= NULL
;
857 if (isdigit (imm_start
[k
]))
858 temp
[k
] = imm_start
[k
] - '0';
860 else if (isalpha (imm_start
[k
])
861 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
862 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
864 else if (imm_start
[k
] == 'h')
867 else if (imm_start
[k
] == END_OF_INSN
)
874 return NULL
; /* not a hex digit */
878 while (imm_start
[k
] != '\n');
880 switch (imm_start
[k
])
883 for (j
= 0; j
< k
; j
++)
884 val
+= temp
[j
] * pwr (16, k
- j
- 1);
888 for (j
= 0; j
< k
; j
++)
891 return NULL
; /* not a number */
893 val
+= temp
[j
] * pwr (10, k
- j
- 1);
898 /* Get the module and register id's. */
900 rid
= (val
>> 4) & 0x0f;
904 /* Search the pheripheral reg table. */
905 for (j
= 0; j
< num_of_reg
; j
++)
907 if (new_reg_table
[j
].opcode
== val
)
909 reg
= (reg_entry
*) & new_reg_table
[j
];
917 /* Search the system register table. */
920 while (system_reg_table
[j
].reg_name
!= NULL
)
922 if (system_reg_table
[j
].opcode
== val
)
924 reg
= (reg_entry
*) & system_reg_table
[j
];
933 as_bad (_("Invalid register value %s"), imm_start
);
938 if (this_operand
== 0 && reg
!= NULL
)
940 if (reg
->Mod_index
> 7)
946 return (reg_entry
*) reg
;
949 /* REG_STRING starts *before* REGISTER_PREFIX. */
952 parse_register (char *reg_string
, char **end_op
)
954 char *s
= reg_string
;
956 char reg_name_given
[MAX_REG_NAME_SIZE
+ 1];
962 /* Skip possible REGISTER_PREFIX and possible whitespace. */
963 if (is_space_char (*s
))
967 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
969 if (p
>= reg_name_given
+ MAX_REG_NAME_SIZE
)
970 return (reg_entry
*) NULL
;
976 r
= (reg_entry
*) hash_find (reg_hash
, reg_name_given
);
979 if (this_operand
== 0 && r
!= NULL
)
981 if (r
->Mod_index
> 7)
991 parse_register_bit (char *reg_string
, char **end_op
)
993 const char *s
= reg_string
;
999 char temp_bitname
[MAX_REG_NAME_SIZE
+ 2];
1000 char temp
[MAX_REG_NAME_SIZE
+ 1];
1002 memset (&temp
, '\0', (MAX_REG_NAME_SIZE
+ 1));
1003 memset (&temp_bitname
, '\0', (MAX_REG_NAME_SIZE
+ 2));
1008 rb
= xmalloc (sizeof (reg_bit
));
1009 rb
->reg
= xmalloc (sizeof (reg_entry
));
1012 /* For supporting bit names. */
1013 b
= (bit_name
*) hash_find (bit_hash
, reg_string
);
1017 *end_op
= reg_string
+ strlen (reg_string
);
1018 strcpy (temp_bitname
, b
->reg_bit
);
1022 if (strchr (s
, '.'))
1035 if ((r
= parse_register (temp
, end_op
)) == NULL
)
1043 if (isdigit ((char) *s
))
1045 else if (isalpha ((char) *s
))
1047 rb
->bit
= (char) *s
- 'a';
1051 as_bad (_("Invalid bit number : '%c'"), (char) *s
);
1057 diff
= strlen (temp_bitname
) - strlen (temp
) - 1;
1059 diff
= strlen (reg_string
) - strlen (temp
) - 1;
1061 if (*(s
+ diff
) != '\0')
1063 as_bad (_("Illegal character after operand '%s'"), reg_string
);
1071 pfx_for_imm_val (int arg
)
1076 if (i
.prefix
== 0 && arg
== 0 && PFX_INSN
[1] == 0 && !(i
.data_operands
))
1079 if (!(i
.prefix
< 0) && !(i
.prefix
> 7))
1080 PFX_INSN
[0] = (i
.prefix
<< 4) | PFX0
;
1088 maxq20_immediate (char *imm_start
)
1090 int val
= 0, val_pfx
= 0;
1093 int temp
[4] = { 0 };
1097 if (imm_start
[1] == '\0' && (imm_start
[0] == '0' || imm_start
[0] == '1')
1098 && (this_operand
== 1 && ((i
.types
[0] == BIT
|| i
.types
[0] == FLAG
))))
1100 val
= imm_start
[0] - '0';
1101 i
.imm_bit_operands
++;
1102 i
.types
[this_operand
] = IMMBIT
;
1103 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1106 pfx_for_imm_val (0);
1111 /* Check For Sign Character. */
1116 if (imm_start
[k
] == '-' && k
== 0)
1119 else if (imm_start
[k
] == '+' && k
== 0)
1122 else if (isdigit (imm_start
[k
]))
1123 temp
[k
] = imm_start
[k
] - '0';
1125 else if (isalpha (imm_start
[k
])
1126 && (imm_start
[k
] = tolower (imm_start
[k
])) < 'g')
1127 temp
[k
] = 10 + (int) (imm_start
[k
] - 'a');
1129 else if (imm_start
[k
] == 'h')
1132 else if (imm_start
[k
] == '\0')
1139 as_bad (_("Invalid Character in immediate Value : %c"),
1145 while (imm_start
[k
] != '\n');
1147 switch (imm_start
[k
])
1150 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1151 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1155 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1159 as_bad (_("Invalid Character in immediate value : %c"),
1163 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1170 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1171 check if we are moving a 16 bit immediate value into an 8 bit register.
1172 In that case we will generate a warning and move only the lower 8 bits */
1175 as_bad (_("Immediate value greater than 16 bits"));
1179 val
= val
* sign_val
;
1181 /* If it is a stack pointer and the value is greater than the maximum
1183 if (this_operand
== 1)
1185 if ((val
* sign_val
) > MAX_STACK
&& i
.types
[0] == REG
1186 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
1189 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1190 val
= val
& MAX_STACK
;
1193 /* Check the range for 8 bit registers. */
1194 else if (((val
* sign_val
) > 0xFF) && (i
.types
[0] == REG
)
1195 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1198 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1202 else if (((sign_val
== -1) || (val
> 0xFF)) && (i
.types
[0] == REG
)
1203 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1206 val
= ((val
) & 0x00ff);
1207 SET_PFX_ARG (val_pfx
);
1208 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1211 else if ((val
<= 0xff) && (i
.types
[0] == REG
)
1212 && (i
.maxq20_op
[0].reg
->rtype
== Reg_8W
))
1213 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1216 /* Check for 16 bit registers. */
1217 else if (((sign_val
== -1) || val
> 0xFE) && i
.types
[0] == REG
1218 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1220 /* Add PFX for any negative value -> 16bit register. */
1222 val
= ((val
) & 0x00ff);
1223 SET_PFX_ARG (val_pfx
);
1224 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1227 else if (val
< 0xFF && i
.types
[0] == REG
1228 && i
.maxq20_op
[0].reg
->rtype
== Reg_16W
)
1230 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1233 /* All the immediate memory access - no PFX. */
1234 else if (i
.types
[0] == MEM
)
1236 if ((sign_val
== -1) || val
> 0xFE)
1239 val
= ((val
) & 0x00ff);
1240 SET_PFX_ARG (val_pfx
);
1241 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1244 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1247 /* Special handling for immediate jumps like jump nz, #03h etc. */
1248 else if (val
< 0xFF && i
.types
[0] == FLAG
)
1249 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1251 else if ((((sign_val
== -1) || val
> 0xFE)) && i
.types
[0] == FLAG
)
1254 val
= ((val
) & 0x00ff);
1255 SET_PFX_ARG (val_pfx
);
1256 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1260 as_bad (_("Invalid immediate move operation"));
1266 /* All the instruction with operation on ACC: like ADD src, etc. */
1267 if ((sign_val
== -1) || val
> 0xFE)
1270 val
= ((val
) & 0x00ff);
1271 SET_PFX_ARG (val_pfx
);
1272 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1275 i
.maxq20_op
[this_operand
].imms
= (char) val
;
1283 extract_int_val (const char *imm_start
)
1295 if (imm_start
[k
] == '-' && k
== 0)
1298 else if (imm_start
[k
] == '+' && k
== 0)
1301 else if (isdigit (imm_start
[k
]))
1302 temp
[k
] = imm_start
[k
] - '0';
1304 else if (isalpha (imm_start
[k
]) && (tolower (imm_start
[k
])) < 'g')
1305 temp
[k
] = 10 + (int) (tolower (imm_start
[k
]) - 'a');
1307 else if (tolower (imm_start
[k
]) == 'h')
1310 else if ((imm_start
[k
] == '\0') || (imm_start
[k
] == ']'))
1311 /* imm_start[k]='d'; */
1316 as_bad (_("Invalid Character in immediate Value : %c"),
1322 while (imm_start
[k
] != '\n');
1324 switch (imm_start
[k
])
1327 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1328 val
+= temp
[j
] * pwr (16, k
- j
- 1);
1332 for (j
= (sign_val
? 1 : 0); j
< k
; j
++)
1336 as_bad (_("Invalid Character in immediate value : %c"),
1340 val
+= temp
[j
] * pwr (10, k
- j
- 1);
1347 return val
* sign_val
;
1351 check_for_parse (const char *line
)
1355 if (*(line
+ 1) == '[')
1360 if ((*line
== '-') || (*line
== '+'))
1363 while (!is_space_char (*line
));
1365 if ((*line
== '-') || (*line
== '+'))
1366 val
= extract_int_val (line
);
1368 val
= extract_int_val (line
+ 1);
1370 INSERT_BUFFER
[0] = 0x3E;
1371 INSERT_BUFFER
[1] = val
;
1380 maxq20_mem_access (char *mem_string
, char **end_op
)
1382 char *s
= mem_string
;
1384 char mem_name_given
[MAX_MEM_NAME_SIZE
+ 1];
1389 /* Skip possible whitespace. */
1390 if (is_space_char (*s
))
1394 while ((*p
++ = register_chars
[(unsigned char) *s
]) != '\0')
1396 if (p
>= mem_name_given
+ MAX_MEM_NAME_SIZE
)
1397 return (mem_access
*) NULL
;
1403 m
= (mem_access
*) hash_find (mem_hash
, mem_name_given
);
1408 /* This function checks whether the operand is a variable in the data segment
1409 and if so, it returns its symbol entry from the symbol table. */
1412 maxq20_data (char *op_string
)
1415 symbolP
= symbol_find (op_string
);
1418 && S_GET_SEGMENT (symbolP
) != now_seg
1419 && S_GET_SEGMENT (symbolP
) != bfd_und_section_ptr
)
1421 /* In case we do not want to always include the prefix instruction and
1422 let the loader handle the job or in case of a 8 bit addressing mode,
1423 we will just check for val_pfx to be equal to zero and then load the
1424 prefix instruction. Otherwise no prefix instruction needs to be
1426 /* The prefix register will have to be loaded automatically as we have
1427 a 16 bit addressing field. */
1428 pfx_for_imm_val (0);
1436 maxq20_displacement (char *disp_start
, char *disp_end
)
1440 char *save_input_line_pointer
;
1442 char *gotfree_input_line
;
1445 gotfree_input_line
= NULL
;
1446 exp
= &disp_expressions
;
1447 i
.maxq20_op
[this_operand
].disps
= exp
;
1449 save_input_line_pointer
= input_line_pointer
;
1450 input_line_pointer
= disp_start
;
1452 END_STRING_AND_SAVE (disp_end
);
1455 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1456 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1458 exp_seg
= expression (exp
);
1461 if (*input_line_pointer
)
1462 as_bad (_("junk `%s' after expression"), input_line_pointer
);
1464 RESTORE_END_STRING (disp_end
+ 1);
1466 RESTORE_END_STRING (disp_end
);
1467 input_line_pointer
= save_input_line_pointer
;
1469 if (gotfree_input_line
)
1470 free (gotfree_input_line
);
1472 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1474 /* Missing or bad expr becomes absolute 0. */
1475 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1477 exp
->X_op
= O_constant
;
1478 exp
->X_add_number
= 0;
1479 exp
->X_add_symbol
= (symbolS
*) 0;
1480 exp
->X_op_symbol
= (symbolS
*) 0;
1482 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1484 if (exp
->X_op
!= O_constant
1485 && OUTPUT_FLAVOR
== bfd_target_aout_flavour
1486 && exp_seg
!= absolute_section
1487 && exp_seg
!= text_section
1488 && exp_seg
!= data_section
1489 && exp_seg
!= bss_section
&& exp_seg
!= undefined_section
1490 && !bfd_is_com_section (exp_seg
))
1492 as_bad (_("unimplemented segment %s in operand"), exp_seg
->name
);
1496 i
.maxq20_op
[this_operand
].disps
= exp
;
1500 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1501 Returns non-zero on error. */
1504 maxq20_operand (char *operand_string
)
1506 reg_entry
*r
= NULL
;
1508 mem_access
*m
= NULL
;
1509 char *end_op
= NULL
;
1510 symbolS
*sym
= NULL
;
1511 char *base_string
= NULL
;
1513 /* Start and end of displacement string expression (if found). */
1514 char *displacement_string_start
= NULL
;
1515 char *displacement_string_end
= NULL
;
1516 /* This maintains the case sentivness. */
1517 char case_str_op_string
[MAX_OPERAND_SIZE
+ 1];
1518 char str_op_string
[MAX_OPERAND_SIZE
+ 1];
1519 char *org_case_op_string
= case_str_op_string
;
1520 char *op_string
= str_op_string
;
1523 memset (op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1524 memset (org_case_op_string
, END_OF_INSN
, (MAX_OPERAND_SIZE
+ 1));
1526 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1527 memcpy (org_case_op_string
, operand_string
, strlen (operand_string
) + 1);
1529 ii
= strlen (operand_string
) + 1;
1531 if (ii
> MAX_OPERAND_SIZE
)
1533 as_bad (_("Size of Operand '%s' greater than %d"), op_string
,
1540 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1544 if (is_space_char (*op_string
))
1547 if (isxdigit (operand_string
[0]))
1549 /* Now the operands can start with an Integer. */
1550 r
= parse_reg_by_index (op_string
);
1553 if (is_space_char (*op_string
))
1555 i
.types
[this_operand
] = REG
; /* Set the type. */
1556 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1561 /* Get the original string. */
1562 memcpy (op_string
, operand_string
, strlen (operand_string
) + 1);
1563 ii
= strlen (operand_string
) + 1;
1567 op_string
[ii
- 1] = toupper ((char) op_string
[ii
- 1]);
1572 /* Check for flags. */
1573 if (!strcmp (op_string
, "Z"))
1575 if (is_space_char (*op_string
))
1578 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1579 i
.maxq20_op
[this_operand
].flag
= FLAG_Z
; /* Set the Register value. */
1586 else if (!strcmp (op_string
, "NZ"))
1588 if (is_space_char (*op_string
))
1591 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1592 i
.maxq20_op
[this_operand
].flag
= FLAG_NZ
; /* Set the Register value. */
1597 else if (!strcmp (op_string
, "NC"))
1599 if (is_space_char (*op_string
))
1602 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1603 i
.maxq20_op
[this_operand
].flag
= FLAG_NC
; /* Set the Register value. */
1608 else if (!strcmp (op_string
, "E"))
1610 if (is_space_char (*op_string
))
1613 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1614 i
.maxq20_op
[this_operand
].flag
= FLAG_E
; /* Set the Register value. */
1621 else if (!strcmp (op_string
, "S"))
1623 if (is_space_char (*op_string
))
1626 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1627 i
.maxq20_op
[this_operand
].flag
= FLAG_S
; /* Set the Register value. */
1634 else if (!strcmp (op_string
, "C"))
1636 if (is_space_char (*op_string
))
1639 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1640 i
.maxq20_op
[this_operand
].flag
= FLAG_C
; /* Set the Register value. */
1647 else if (!strcmp (op_string
, "NE"))
1650 if (is_space_char (*op_string
))
1653 i
.types
[this_operand
] = FLAG
; /* Set the type. */
1655 i
.maxq20_op
[this_operand
].flag
= FLAG_NE
; /* Set the Register value. */
1662 /* CHECK FOR REGISTER BIT */
1663 else if ((rb
= parse_register_bit (op_string
, &end_op
)) != NULL
)
1667 if (is_space_char (*op_string
))
1670 i
.types
[this_operand
] = BIT
;
1672 i
.maxq20_op
[this_operand
].r_bit
= rb
;
1679 else if (*op_string
== IMMEDIATE_PREFIX
) /* FOR IMMEDITE. */
1681 if (is_space_char (*op_string
))
1684 i
.types
[this_operand
] = IMM
;
1686 if (!maxq20_immediate (op_string
))
1688 as_bad (_("illegal immediate operand '%s'"), op_string
);
1694 else if (*op_string
== ABSOLUTE_PREFIX
|| !strcmp (op_string
, "NUL"))
1696 if (is_space_char (*op_string
))
1699 /* For new requiremnt of copiler of for, @(BP,cons). */
1700 if (check_for_parse (op_string
))
1702 memset (op_string
, '\0', strlen (op_string
) + 1);
1703 memcpy (op_string
, "@BP[OFFS]\0", 11);
1706 i
.types
[this_operand
] = MEM
;
1708 if ((m
= maxq20_mem_access (op_string
, &end_op
)) == NULL
)
1710 as_bad (_("Invalid operand for memory access '%s'"), op_string
);
1713 i
.maxq20_op
[this_operand
].mem
= m
;
1720 else if ((r
= parse_register (op_string
, &end_op
)) != NULL
) /* Check for register. */
1724 if (is_space_char (*op_string
))
1727 i
.types
[this_operand
] = REG
; /* Set the type. */
1728 i
.maxq20_op
[this_operand
].reg
= r
; /* Set the Register value. */
1733 if (this_operand
== 1)
1735 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1736 /* The operand can either be a data reference or a symbol reference. */
1737 if ((sym
= maxq20_data (org_case_op_string
)) != NULL
) /* Check for data memory. */
1739 while (is_space_char (*op_string
))
1742 /* Set the type of the operand. */
1743 i
.types
[this_operand
] = DATA
;
1745 /* Set the value of the data. */
1746 i
.maxq20_op
[this_operand
].data
= sym
;
1752 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1754 /* This is a memory reference of some sort. char *base_string;
1755 Start and end of displacement string expression (if found). char
1756 *displacement_string_start; char *displacement_string_end. */
1757 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1760 if (is_space_char (*base_string
))
1763 /* If we only have a displacement, set-up for it to be parsed
1765 displacement_string_start
= org_case_op_string
;
1766 displacement_string_end
= base_string
+ 1;
1767 if (displacement_string_start
!= displacement_string_end
)
1769 if (!maxq20_displacement (displacement_string_start
,
1770 displacement_string_end
))
1772 as_bad (_("illegal displacement operand "));
1775 /* A displacement operand found. */
1776 i
.types
[this_operand
] = DISP
; /* Set the type. */
1782 /* Check for displacement. */
1783 else if (is_digit_char (*op_string
) || is_identifier_char (*op_string
))
1785 /* This is a memory reference of some sort. char *base_string;
1786 Start and end of displacement string expression (if found). char
1787 *displacement_string_start; char *displacement_string_end; */
1788 base_string
= org_case_op_string
+ strlen (org_case_op_string
);
1791 if (is_space_char (*base_string
))
1794 /* If we only have a displacement, set-up for it to be parsed later. */
1795 displacement_string_start
= org_case_op_string
;
1796 displacement_string_end
= base_string
+ 1;
1797 if (displacement_string_start
!= displacement_string_end
)
1799 if (!maxq20_displacement (displacement_string_start
,
1800 displacement_string_end
))
1802 /* A displacement operand found. */
1803 i
.types
[this_operand
] = DISP
; /* Set the type. */
1809 /* Parse_operand takes as input instruction and operands and Parse operands
1810 and makes entry in the template. */
1813 parse_operands (char *l
, const char *mnemonic
)
1817 /* 1 if operand is pending after ','. */
1818 short int expecting_operand
= 0;
1820 /* Non-zero if operand parens not balanced. */
1821 short int paren_not_balanced
;
1825 /* For Overcoming Warning of unused variable. */
1829 while (*l
!= END_OF_INSN
)
1831 /* Skip optional white space before operand. */
1832 if (is_space_char (*l
))
1835 if (!is_operand_char (*l
) && *l
!= END_OF_INSN
)
1837 as_bad (_("invalid character %c before operand %d"),
1838 (char) (*l
), i
.operands
+ 1);
1843 paren_not_balanced
= 0;
1844 while (paren_not_balanced
|| *l
!= ',')
1846 if (*l
== END_OF_INSN
)
1848 if (paren_not_balanced
)
1850 as_bad (_("unbalanced brackets in operand %d."),
1857 else if (!is_operand_char (*l
) && !is_space_char (*l
))
1859 as_bad (_("invalid character %c in operand %d"),
1860 (char) (*l
), i
.operands
+ 1);
1864 ++paren_not_balanced
;
1866 --paren_not_balanced
;
1870 if (l
!= token_start
)
1872 /* Yes, we've read in another operand. */
1873 this_operand
= i
.operands
++;
1874 if (i
.operands
> MAX_OPERANDS
)
1876 as_bad (_("spurious operands; (%d operands/instruction max)"),
1881 /* Now parse operand adding info to 'i' as we go along. */
1882 END_STRING_AND_SAVE (l
);
1884 operand_ok
= maxq20_operand (token_start
);
1886 RESTORE_END_STRING (l
);
1893 if (expecting_operand
)
1895 expecting_operand_after_comma
:
1896 as_bad (_("expecting operand after ','; got nothing"));
1903 if (*(++l
) == END_OF_INSN
)
1904 /* Just skip it, if it's \n complain. */
1905 goto expecting_operand_after_comma
;
1907 expecting_operand
= 1;
1915 match_operands (int type
, MAX_ARG_TYPE flag_type
, MAX_ARG_TYPE arg_type
,
1921 if ((arg_type
& A_REG
) == A_REG
)
1925 if ((arg_type
& A_IMM
) == A_IMM
)
1929 if ((arg_type
& A_BIT_0
) == A_BIT_0
&& (i
.maxq20_op
[op_num
].imms
== 0))
1931 else if ((arg_type
& A_BIT_1
) == A_BIT_1
1932 && (i
.maxq20_op
[op_num
].imms
== 1))
1936 if ((arg_type
& A_MEM
) == A_MEM
)
1941 if ((arg_type
& flag_type
) == flag_type
)
1947 if ((arg_type
& ACC_BIT
) == ACC_BIT
&& !strcmp (i
.maxq20_op
[op_num
].r_bit
->reg
->reg_name
, "ACC"))
1949 else if ((arg_type
& SRC_BIT
) == SRC_BIT
&& (op_num
== 1))
1951 else if ((op_num
== 0) && (arg_type
& DST_BIT
) == DST_BIT
)
1955 if ((arg_type
& A_DISP
) == A_DISP
)
1958 if ((arg_type
& A_DATA
) == A_DATA
)
1961 if ((arg_type
& A_BIT_BUCKET
) == A_BIT_BUCKET
)
1968 match_template (void)
1970 /* Points to template once we've found it. */
1971 const MAXQ20_OPCODE_INFO
*t
;
1975 for (t
= current_templates
->start
; t
< current_templates
->end
; t
++)
1977 /* Must have right number of operands. */
1978 if (i
.operands
!= t
->op_number
)
1980 else if (!t
->op_number
)
1986 if (!match_operands (i
.types
[1], i
.maxq20_op
[1].flag
, t
->arg
[1], 1))
1992 if (!match_operands (i
.types
[0], i
.maxq20_op
[0].flag
, t
->arg
[0], 0))
2001 if (t
== current_templates
->end
)
2003 /* We found no match. */
2004 as_bad (_("operand %d is invalid for `%s'"),
2005 inv_oper
, current_templates
->start
->name
);
2009 /* Copy the template we have found. */
2014 /* This function filters out the various combinations of operands which are
2015 not allowed for a particular instruction. */
2018 match_filters (void)
2020 /* Now we have at our disposal the instruction i. We will be using the
2021 following fields i.op.name : This is the mnemonic name. i.types[2] :
2022 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2023 i.maxq20_op[2] : This contains the specific info of the operands. */
2025 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2027 if (!strcmp (i
.op
.name
, "AND") || !strcmp (i
.op
.name
, "OR")
2028 || !strcmp (i
.op
.name
, "XOR") || !strcmp (i
.op
.name
, "ADD")
2029 || !strcmp (i
.op
.name
, "ADDC") || !strcmp (i
.op
.name
, "SUB")
2030 || !strcmp (i
.op
.name
, "SUBB"))
2032 if (i
.types
[0] == REG
)
2034 if (i
.maxq20_op
[0].reg
->Mod_name
== 0xa)
2037 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2043 if (!strcmp (i
.op
.name
, "MOVE") && (i
.types
[0] == MEM
|| i
.types
[1] == MEM
)
2046 mem_access_syntax
*mem_op
= NULL
;
2048 if (i
.types
[0] == MEM
)
2051 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2052 i
.maxq20_op
[0].mem
->name
);
2053 if ((mem_op
->type
== SRC
) && mem_op
)
2055 as_bad (_("'%s' operand cant be used as destination in %s"),
2056 mem_op
->name
, i
.op
.name
);
2059 else if ((mem_op
->invalid_op
!= NULL
) && (i
.types
[1] == MEM
)
2064 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2066 if (mem_op
->invalid_op
[k
] != NULL
)
2068 (mem_op
->invalid_op
[k
], i
.maxq20_op
[1].mem
->name
))
2071 ("Invalid Instruction '%s' operand cant be used with %s"),
2072 mem_op
->name
, i
.maxq20_op
[1].mem
->name
);
2079 if (i
.types
[1] == MEM
)
2083 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2084 i
.maxq20_op
[1].mem
->name
);
2085 if (mem_op
->type
== DST
&& mem_op
)
2087 as_bad (_("'%s' operand cant be used as source in %s"),
2088 mem_op
->name
, i
.op
.name
);
2091 else if (mem_op
->invalid_op
!= NULL
&& i
.types
[0] == MEM
&& mem_op
)
2095 for (k
= 0; k
< 5 || !mem_op
->invalid_op
[k
]; k
++)
2097 if (mem_op
->invalid_op
[k
] != NULL
)
2099 (mem_op
->invalid_op
[k
], i
.maxq20_op
[0].mem
->name
))
2102 ("Invalid Instruction '%s' operand cant be used with %s"),
2103 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2108 else if (i
.types
[0] == REG
2109 && !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "OFFS")
2112 if (!strcmp (mem_op
->name
, "@BP[OFFS--]")
2113 || !strcmp (mem_op
->name
, "@BP[OFFS++]"))
2116 ("Invalid Instruction '%s' operand cant be used with %s"),
2117 mem_op
->name
, i
.maxq20_op
[0].mem
->name
);
2124 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2125 on 10-March-2004. */
2126 if ((i
.types
[0] == MEM
) && (i
.operands
== 1)
2127 && !(!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI")))
2129 mem_access_syntax
*mem_op
= NULL
;
2131 if (i
.types
[0] == MEM
)
2134 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2135 i
.maxq20_op
[0].mem
->name
);
2136 if (mem_op
->type
== DST
&& mem_op
)
2138 as_bad (_("'%s' operand cant be used as source in %s"),
2139 mem_op
->name
, i
.op
.name
);
2145 if (i
.operands
== 2 && i
.types
[0] == IMM
)
2147 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2152 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2153 if (!strcmp (i
.op
.name
, "PUSH") || !strcmp (i
.op
.name
, "POP")
2154 || !strcmp (i
.op
.name
, "POPI"))
2156 if (i
.types
[0] == REG
)
2158 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "SP"))
2160 as_bad (_("SP cannot be used with %s\n"), i
.op
.name
);
2164 else if (i
.types
[0] == MEM
2165 && !strcmp (i
.maxq20_op
[0].mem
->name
, "@SP--"))
2167 as_bad (_("@SP-- cannot be used with PUSH\n"));
2172 /* This filter checks that two memory references using DP's cannot be used
2173 together in an instruction */
2174 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 2)
2176 if (strlen (i
.maxq20_op
[0].mem
->name
) != 6 ||
2177 strcmp (i
.maxq20_op
[0].mem
->name
, i
.maxq20_op
[1].mem
->name
))
2179 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@DP", 3)
2180 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@DP", 3))
2183 ("Operands either contradictory or use the data bus in read/write state together"));
2187 if (!strncmp (i
.maxq20_op
[0].mem
->name
, "@SP", 3)
2188 && !strncmp (i
.maxq20_op
[1].mem
->name
, "@SP", 3))
2191 ("Operands either contradictory or use the data bus in read/write state together"));
2195 if ((i
.maxq20_op
[1].mem
!= NULL
)
2196 && !strncmp (i
.maxq20_op
[1].mem
->name
, "NUL", 3))
2198 as_bad (_("MOVE Cant Use NUL as SRC"));
2203 /* This filter checks that contradictory movement between DP register and
2204 Memory access using DP followed by increment or decrement. */
2206 if (!strcmp (i
.op
.name
, "MOVE") && i
.mem_operands
== 1
2207 && i
.reg_operands
== 1)
2211 memnum
= (i
.types
[0] == MEM
) ? 0 : 1;
2212 regnum
= (memnum
== 0) ? 1 : 0;
2213 if (!strncmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "DP", 2) &&
2214 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2215 i
.maxq20_op
[regnum
].reg
->reg_name
, 5)
2216 && strcmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2217 i
.maxq20_op
[regnum
].reg
->reg_name
))
2220 ("Contradictory movement between DP register and memory access using DP"));
2223 else if (!strcmp (i
.maxq20_op
[regnum
].reg
->reg_name
, "SP") &&
2224 !strncmp ((i
.maxq20_op
[memnum
].mem
->name
) + 1,
2225 i
.maxq20_op
[regnum
].reg
->reg_name
, 2))
2228 ("SP and @SP-- cannot be used together in a move instruction"));
2233 /* This filter restricts the instructions containing source and destination
2234 bits to only CTRL module of the serial registers. Peripheral registers
2235 yet to be defined. */
2237 if (i
.bit_operands
== 1 && i
.operands
== 2)
2239 int bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2241 if (strcmp (i
.maxq20_op
[bitnum
].r_bit
->reg
->reg_name
, "ACC"))
2243 if (i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
>= 0x7 &&
2244 i
.maxq20_op
[bitnum
].r_bit
->reg
->Mod_name
!= CTRL
)
2247 ("Only Module 8 system registers allowed in this operation"));
2253 /* This filter is for checking the register bits. */
2254 if (i
.bit_operands
== 1 || i
.operands
== 2)
2256 int bitnum
= 0, size
= 0;
2258 bitnum
= (i
.types
[0] == BIT
) ? 0 : 1;
2259 if (i
.bit_operands
== 1)
2261 switch (i
.maxq20_op
[bitnum
].r_bit
->reg
->rtype
)
2264 size
= 7; /* 8 bit register, both read and write. */
2273 as_fatal (_("Read only Register used as destination"));
2282 as_fatal (_("Read only Register used as destination"));
2288 if (size
< (i
.maxq20_op
[bitnum
].r_bit
)->bit
)
2290 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2291 (i
.maxq20_op
[bitnum
].r_bit
)->bit
);
2296 if (i
.bit_operands
== 2)
2298 switch ((i
.maxq20_op
[0].r_bit
)->reg
->rtype
)
2301 size
= 7; /* 8 bit register, both read and write. */
2308 as_fatal (_("Read only Register used as destination"));
2312 if (size
< (i
.maxq20_op
[0].r_bit
)->bit
)
2315 ("Bit No '%d' exceeds register size in this operation"),
2316 (i
.maxq20_op
[0].r_bit
)->bit
);
2321 switch ((i
.maxq20_op
[1].r_bit
)->reg
->rtype
)
2325 size
= 7; /* 8 bit register, both read and write. */
2333 if (size
< (i
.maxq20_op
[1].r_bit
)->bit
)
2336 ("Bit No '%d' exceeds register size in this operation"),
2337 (i
.maxq20_op
[1].r_bit
)->bit
);
2343 /* No branch operations should occur into the data memory. Hence any memory
2344 references have to be filtered out when used with instructions like
2345 jump, djnz[] and call. */
2347 if (!strcmp (i
.op
.name
, "JUMP") || !strcmp (i
.op
.name
, "CALL")
2348 || !strncmp (i
.op
.name
, "DJNZ", 4))
2352 ("Memory References cannot be used with branching operations\n"));
2355 if (!strcmp (i
.op
.name
, "DJNZ"))
2358 (strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2359 || strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))
2361 as_bad (_("DJNZ uses only LC[n] register \n"));
2366 /* No destination register used should be read only! */
2367 if ((i
.operands
== 2 && i
.types
[0] == REG
) || !strcmp (i
.op
.name
, "POP")
2368 || !strcmp (i
.op
.name
, "POPI"))
2369 { /* The destination is a register */
2372 if (!strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2376 if (i
.types
[regnum
] == MEM
)
2378 mem_access_syntax
*mem_op
= NULL
;
2381 (mem_access_syntax
*) hash_find (mem_syntax_hash
,
2382 i
.maxq20_op
[regnum
].mem
->
2384 if (mem_op
->type
== SRC
&& mem_op
)
2387 ("'%s' operand cant be used as destination in %s"),
2388 mem_op
->name
, i
.op
.name
);
2394 if (i
.maxq20_op
[regnum
].reg
->rtype
== Reg_8R
2395 || i
.maxq20_op
[regnum
].reg
->rtype
== Reg_16R
)
2397 as_bad (_("Read only register used for writing purposes '%s'"),
2398 i
.maxq20_op
[regnum
].reg
->reg_name
);
2403 /* While moving the address of a data in the data section, the destination
2404 should be either data pointers only. */
2405 if ((i
.data_operands
) && (i
.operands
== 2))
2407 if ((i
.types
[0] != REG
) && (i
.types
[0] != MEM
))
2409 as_bad (_("Invalid destination for this kind of source."));
2413 if (i
.types
[0] == REG
&& i
.maxq20_op
[0].reg
->rtype
== Reg_8W
)
2416 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2426 /* Check for the format Bit if defined. */
2427 if (i
.op
.format
== 0 || i
.op
.format
== 1)
2428 i
.instr
[0] = i
.op
.format
<< 7;
2431 /* Format bit not defined. We will have to be find it out ourselves. */
2432 if (i
.imm_operands
== 1 || i
.data_operands
== 1 || i
.disp_operands
== 1)
2436 i
.instr
[0] = i
.op
.format
<< 7;
2439 /* Now for the destination register. */
2441 /* If destination register is already defined . The conditions are the
2442 following: (1) The second entry in the destination array should be 0 (2)
2443 If there are two operands then the first entry should not be a register,
2444 memory or a register bit (3) If there are less than two operands and the
2445 it is not a pop operation (4) The second argument is the carry
2446 flag(applicable to move Acc.<b>,C. */
2447 if (i
.op
.dst
[1] == 0
2449 ((i
.types
[0] != REG
&& i
.types
[0] != MEM
&& i
.types
[0] != BIT
2450 && i
.operands
== 2) || (i
.operands
< 2 && strcmp (i
.op
.name
, "POP")
2451 && strcmp (i
.op
.name
, "POPI"))
2452 || (i
.op
.arg
[1] == FLAG_C
)))
2454 i
.op
.dst
[0] &= 0x7f;
2455 i
.instr
[0] |= i
.op
.dst
[0];
2457 else if (i
.op
.dst
[1] == 0 && !strcmp (i
.op
.name
, "DJNZ")
2459 (((i
.types
[0] == REG
)
2460 && (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]")
2461 || !strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]")))))
2463 i
.op
.dst
[0] &= 0x7f;
2464 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[0]"))
2467 if (!strcmp (i
.maxq20_op
[0].reg
->reg_name
, "LC[1]"))
2474 /* Target register will have to be specified. */
2475 if (i
.types
[0] == REG
2476 && (i
.op
.dst
[0] == REG
|| i
.op
.dst
[0] == (REG
| MEM
)))
2478 temp
= (i
.maxq20_op
[0].reg
)->opcode
;
2482 else if (i
.types
[0] == MEM
&& (i
.op
.dst
[0] == (REG
| MEM
)))
2484 temp
= (i
.maxq20_op
[0].mem
)->opcode
;
2488 else if (i
.types
[0] == BIT
&& (i
.op
.dst
[0] == REG
))
2490 temp
= (i
.maxq20_op
[0].r_bit
)->reg
->opcode
;
2494 else if (i
.types
[1] == BIT
&& (i
.op
.dst
[0] == BIT
))
2496 temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2498 temp
|= i
.op
.dst
[1];
2504 as_bad (_("Invalid Instruction"));
2509 /* Now for the source register. */
2511 /* If Source register is already known. The following conditions are
2512 checked: (1) There are no operands (2) If there is only one operand and
2513 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2516 if (i
.operands
== 0 || (i
.operands
== 1 && i
.types
[0] == FLAG
)
2517 || (i
.types
[0] == FLAG
&& i
.types
[1] == IMMBIT
)
2518 || !strcmp (i
.op
.name
, "POP") || !strcmp (i
.op
.name
, "POPI"))
2519 i
.instr
[1] = i
.op
.src
[0];
2521 else if (i
.imm_operands
== 1 && ((i
.op
.src
[0] & IMM
) == IMM
))
2522 i
.instr
[1] = i
.maxq20_op
[this_operand
].imms
;
2524 else if (i
.types
[this_operand
] == REG
&& ((i
.op
.src
[0] & REG
) == REG
))
2525 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].reg
)->opcode
);
2527 else if (i
.types
[this_operand
] == BIT
&& ((i
.op
.src
[0] & REG
) == REG
))
2528 i
.instr
[1] = (char) (i
.maxq20_op
[this_operand
].r_bit
->reg
->opcode
);
2530 else if (i
.types
[this_operand
] == MEM
&& ((i
.op
.src
[0] & MEM
) == MEM
))
2531 i
.instr
[1] = (char) ((i
.maxq20_op
[this_operand
].mem
)->opcode
);
2533 else if (i
.types
[this_operand
] == DATA
&& ((i
.op
.src
[0] & DATA
) == DATA
))
2534 /* This will copy only the lower order bytes into the instruction. The
2535 higher order bytes have already been copied into the prefix register. */
2538 /* Decoding the source in the case when the second array entry is not 0.
2539 This means that the source register has been divided into two nibbles. */
2541 else if (i
.op
.src
[1] != 0)
2543 /* If the first operand is a accumulator bit then
2544 the first 4 bits will be filled with the bit number. */
2545 if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & BIT
) == BIT
))
2547 unsigned char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2550 temp
|= i
.op
.src
[1];
2553 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2554 has to start with a zero. This is called a ZEROBIT */
2555 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ZEROBIT
) == ZEROBIT
))
2557 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2560 temp
|= i
.op
.src
[1];
2564 /* Similarly for a ONEBIT */
2565 else if (i
.types
[0] == BIT
&& ((i
.op
.src
[0] & ONEBIT
) == ONEBIT
))
2567 char temp
= (i
.maxq20_op
[0].r_bit
)->bit
;
2570 temp
|= i
.op
.src
[1];
2574 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2576 else if (i
.types
[1] == BIT
)
2578 if (i
.op
.src
[1] == 0 && i
.op
.src
[1] == REG
)
2579 i
.instr
[1] = (i
.maxq20_op
[1].r_bit
)->reg
->opcode
;
2581 else if (i
.op
.src
[0] == BIT
&& i
.op
.src
)
2583 char temp
= (i
.maxq20_op
[1].r_bit
)->bit
;
2586 temp
|= i
.op
.src
[1];
2592 as_bad (_("Invalid Instruction"));
2599 /* This is a function for outputting displacement operands. */
2602 output_disp (fragS
*insn_start_frag
, offsetT insn_start_off
)
2605 relax_substateT subtype
;
2611 insn_start_frag
= frag_now
;
2612 insn_start_off
= frag_now_fix ();
2614 switch (i
.Instr_Prefix
)
2617 subtype
= EXPLICT_LONG_PREFIX
;
2620 subtype
= SHORT_PREFIX
;
2623 subtype
= NO_PREFIX
;
2627 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2628 case there is no need for relaxation. But we do need support for a
2629 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2630 for prefix + 2 for the current instruction ) Hence if at a particular
2631 time we find out whether the prefix operator is reqd , we shift the
2632 current instruction two places ahead and insert the prefix instruction. */
2636 sym
= i
.maxq20_op
[this_operand
].disps
->X_add_symbol
;
2637 off
= i
.maxq20_op
[this_operand
].disps
->X_add_number
;
2639 if (i
.maxq20_op
[this_operand
].disps
->X_add_symbol
!= NULL
&& sym
&& frag_now
2640 && (subtype
!= EXPLICT_LONG_PREFIX
))
2642 /* If in the same frag. */
2643 if (frag_now
== symbol_get_frag (sym
))
2646 ((((expressionS
*) symbol_get_value_expression (sym
))->
2647 X_add_number
) - insn_start_off
);
2649 /* PC points to the next instruction. */
2650 diff
= (diff
/ MAXQ_OCTETS_PER_BYTE
) - 1;
2652 if (diff
>= -128 && diff
<= 127)
2654 i
.instr
[1] = (char) diff
;
2656 /* This will be overwritten later when the symbol is resolved. */
2658 *(p
+ 1) = i
.instr
[0];
2660 /* No Need to create a FIXUP. */
2666 /* This will be overwritten later when the symbol is resolved. */
2668 *(p
+ 1) = i
.instr
[0];
2670 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2671 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2673 /* Handle complex expressions. */
2674 sym
= make_expr_symbol (i
.maxq20_op
[this_operand
].disps
);
2678 /* Vineet : This has been added for md_estimate_size_before_relax to
2679 estimate the correct size. */
2680 if (subtype
!= SHORT_PREFIX
)
2681 i
.reloc
[this_operand
] = LONG_PREFIX
;
2683 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2686 /* This is a function for outputting displacement operands. */
2689 output_data (fragS
*insn_start_frag
, offsetT insn_start_off
)
2692 relax_substateT subtype
;
2699 insn_start_frag
= frag_now
;
2700 insn_start_off
= frag_now_fix ();
2702 subtype
= EXPLICT_LONG_PREFIX
;
2707 sym
= i
.maxq20_op
[this_operand
].data
;
2710 /* This will be overwritten later when the symbol is resolved. */
2712 *(p
+ 1) = i
.instr
[0];
2714 if (i
.maxq20_op
[this_operand
].disps
->X_op
!= O_constant
2715 && i
.maxq20_op
[this_operand
].disps
->X_op
!= O_symbol
)
2716 /* Handle complex expressions. */
2717 /* Because data is already in terms of symbol so no
2718 need to convert it from expression to symbol. */
2721 frag_var (rs_machine_dependent
, 2, i
.reloc
[this_operand
], subtype
, sym
, off
, p
);
2727 fragS
*insn_start_frag
;
2728 offsetT insn_start_off
;
2731 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2732 do this after the insn has been output as the current frag may have been
2733 closed off. eg. by frag_var. */
2734 dwarf2_emit_insn (0);
2736 /* To ALign the text section on word. */
2738 frag_align (1, 0, 1);
2740 /* We initialise the frags for this particular instruction. */
2741 insn_start_frag
= frag_now
;
2742 insn_start_off
= frag_now_fix ();
2744 /* If there are displacement operators(unresolved) present, then handle
2746 if (i
.disp_operands
)
2748 output_disp (insn_start_frag
, insn_start_off
);
2752 if (i
.data_operands
)
2754 output_data (insn_start_frag
, insn_start_off
);
2758 /* Check whether the INSERT_BUFFER has to be written. */
2759 if (strcmp (INSERT_BUFFER
, ""))
2763 *p
++ = INSERT_BUFFER
[1];
2764 *p
= INSERT_BUFFER
[0];
2767 /* Check whether the prefix instruction has to be written. */
2768 if (strcmp (PFX_INSN
, ""))
2777 /* For Little endian. */
2783 make_new_reg_table (void)
2785 unsigned long size_pm
= sizeof (peripheral_reg_table
);
2786 num_of_reg
= ARRAY_SIZE (peripheral_reg_table
);
2788 new_reg_table
= xmalloc (size_pm
);
2789 if (new_reg_table
== NULL
)
2790 as_bad (_("Cannot allocate memory"));
2792 memcpy (new_reg_table
, peripheral_reg_table
, size_pm
);
2795 /* pmmain performs the initilizations for the pheripheral modules. */
2800 make_new_reg_table ();
2807 const char *hash_err
= NULL
;
2810 const MAXQ20_OPCODE_INFO
*optab
;
2811 MAXQ20_OPCODES
*core_optab
; /* For opcodes of the same name. This will
2812 be inserted into the hash table. */
2813 struct reg
*reg_tab
;
2814 struct mem_access_syntax
const *memsyntab
;
2815 struct mem_access
*memtab
;
2816 struct bit_name
*bittab
;
2818 /* Initilize pherioipheral modules. */
2821 /* Initialise the opcode hash table. */
2822 op_hash
= hash_new ();
2824 optab
= op_table
; /* Initialise it to the first entry of the
2825 maxq20 operand table. */
2827 /* Setup for loop. */
2828 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2829 core_optab
->start
= optab
;
2834 if (optab
->name
== NULL
|| strcmp (optab
->name
, (optab
- 1)->name
) != 0)
2836 /* different name --> ship out current template list; add to hash
2837 table; & begin anew. */
2839 core_optab
->end
= optab
;
2841 if (max_version
== bfd_mach_maxq10
)
2843 if (((optab
- 1)->arch
== MAXQ10
) || ((optab
- 1)->arch
== MAX
))
2845 hash_err
= hash_insert (op_hash
,
2847 (void *) core_optab
);
2850 else if (max_version
== bfd_mach_maxq20
)
2852 if (((optab
- 1)->arch
== MAXQ20
) || ((optab
- 1)->arch
== MAX
))
2855 hash_err
= hash_insert (op_hash
,
2857 (void *) core_optab
);
2862 as_fatal (_("Internal Error: Illegal Architecure specified"));
2865 as_fatal (_("Internal Error: Can't hash %s: %s"),
2866 (optab
- 1)->name
, hash_err
);
2868 if (optab
->name
== NULL
)
2870 core_optab
= xmalloc (sizeof (MAXQ20_OPCODES
));
2871 core_optab
->start
= optab
;
2875 /* Initialise a new register table. */
2876 reg_hash
= hash_new ();
2878 for (reg_tab
= system_reg_table
;
2879 reg_tab
< (system_reg_table
+ ARRAY_SIZE (system_reg_table
));
2883 switch (max_version
)
2885 case bfd_mach_maxq10
:
2886 if ((reg_tab
->arch
== MAXQ10
) || (reg_tab
->arch
== MAX
))
2887 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (void *) reg_tab
);
2890 case bfd_mach_maxq20
:
2891 if ((reg_tab
->arch
== MAXQ20
) || (reg_tab
->arch
== MAX
))
2895 hash_insert (reg_hash
, reg_tab
->reg_name
, (void *) reg_tab
);
2900 as_fatal (_("Invalid architecture type"));
2905 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2906 reg_tab
->reg_name
, hash_err
);
2909 /* Pheripheral Registers Entry. */
2910 for (reg_tab
= new_reg_table
;
2911 reg_tab
< (new_reg_table
+ num_of_reg
- 1); reg_tab
++)
2913 hash_err
= hash_insert (reg_hash
, reg_tab
->reg_name
, (void *) reg_tab
);
2916 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2917 reg_tab
->reg_name
, hash_err
);
2920 /* Initialise a new memory operand table. */
2921 mem_hash
= hash_new ();
2923 for (memtab
= mem_table
;
2924 memtab
< mem_table
+ ARRAY_SIZE (mem_table
);
2927 hash_err
= hash_insert (mem_hash
, memtab
->name
, (void *) memtab
);
2929 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2930 memtab
->name
, hash_err
);
2933 bit_hash
= hash_new ();
2935 for (bittab
= bit_table
;
2936 bittab
< bit_table
+ ARRAY_SIZE (bit_table
);
2939 hash_err
= hash_insert (bit_hash
, bittab
->name
, (void *) bittab
);
2941 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2942 bittab
->name
, hash_err
);
2945 mem_syntax_hash
= hash_new ();
2947 for (memsyntab
= mem_access_syntax_table
;
2948 memsyntab
< mem_access_syntax_table
+ ARRAY_SIZE (mem_access_syntax_table
);
2952 hash_insert (mem_syntax_hash
, memsyntab
->name
, (void *) memsyntab
);
2954 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2955 memsyntab
->name
, hash_err
);
2958 /* Initialise the lexical tables,mnemonic chars,operand chars. */
2959 for (c
= 0; c
< 256; c
++)
2964 mnemonic_chars
[c
] = c
;
2965 operand_chars
[c
] = c
;
2966 register_chars
[c
] = c
;
2968 else if (ISLOWER (c
))
2970 mnemonic_chars
[c
] = c
;
2971 operand_chars
[c
] = c
;
2972 register_chars
[c
] = c
;
2974 else if (ISUPPER (c
))
2976 mnemonic_chars
[c
] = TOLOWER (c
);
2977 register_chars
[c
] = c
;
2978 operand_chars
[c
] = c
;
2981 if (ISALPHA (c
) || ISDIGIT (c
))
2983 identifier_chars
[c
] = c
;
2987 identifier_chars
[c
] = c
;
2988 operand_chars
[c
] = c
;
2992 /* All the special characters. */
2993 register_chars
['@'] = '@';
2994 register_chars
['+'] = '+';
2995 register_chars
['-'] = '-';
2996 digit_chars
['-'] = '-';
2997 identifier_chars
['_'] = '_';
2998 identifier_chars
['.'] = '.';
2999 register_chars
['['] = '[';
3000 register_chars
[']'] = ']';
3001 operand_chars
['_'] = '_';
3002 operand_chars
['#'] = '#';
3003 mnemonic_chars
['['] = '[';
3004 mnemonic_chars
[']'] = ']';
3006 for (p
= operand_special_chars
; *p
!= '\0'; p
++)
3007 operand_chars
[(unsigned char) *p
] = (unsigned char) *p
;
3009 /* Set the maxq arch type. */
3010 maxq_target (max_version
);
3013 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3014 menmunonic in the operand table - Parse operands and populate the
3015 structure/template - Match the operand with opcode and its validity -
3019 md_assemble (char *line
)
3023 char mnemonic
[MAX_MNEM_SIZE
];
3024 char temp4prev
[256];
3025 static char prev_insn
[256];
3027 /* Initialize globals. */
3028 memset (&i
, '\0', sizeof (i
));
3029 for (j
= 0; j
< MAX_OPERANDS
; j
++)
3030 i
.reloc
[j
] = NO_RELOC
;
3035 INSERT_BUFFER
[0] = 0;
3036 INSERT_BUFFER
[1] = 0;
3038 memcpy (temp4prev
, line
, strlen (line
) + 1);
3040 save_stack_p
= save_stack
;
3042 line
= (char *) parse_insn (line
, mnemonic
);
3046 line
= (char *) parse_operands (line
, mnemonic
);
3050 /* Next, we find a template that matches the given insn, making sure the
3051 overlap of the given operands types is consistent with the template
3053 if (!match_template ())
3056 /* In the MAXQ20, there are certain register combinations, and other
3057 restrictions which are not allowed. We will try to resolve these right
3059 if (!match_filters ())
3062 /* Check for the appropriate PFX register. */
3064 pfx_for_imm_val (0);
3066 if (!decode_insn ()) /* decode insn. */
3069 /* Check for Exlipct PFX instruction. */
3070 if (PFX_INSN
[0] && (strstr (prev_insn
, "PFX") || strstr (prev_insn
, "pfx")))
3071 as_warn (_("Ineffective insntruction %s \n"), prev_insn
);
3073 memcpy (prev_insn
, temp4prev
, strlen (temp4prev
) + 1);
3075 /* We are ready to output the insn. */