* Makefile.am: Bfin support.
[deliverable/binutils-gdb.git] / gas / config / tc-maxq.c
1 /* tc-maxq.c -- assembler code for a MAXQ chip.
2
3 Copyright 2004, 2005 Free Software Foundation, Inc.
4
5 Contributed by HCL Technologies Pvt. Ltd.
6
7 Author: Vineet Sharma(vineets@noida.hcltech.com) Inderpreet
8 S.(inderpreetb@noida.hcltech.com)
9
10 This file is part of GAS.
11
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.
15
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
19 details.
20
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. */
24
25 #include "as.h"
26 #include "safe-ctype.h"
27 #include "subsegs.h"
28 #include "dwarf2dbg.h"
29 #include "tc-maxq.h"
30 #include "opcode/maxq.h"
31 #include "ctype.h"
32
33 #ifndef MAXQ10S
34 #define MAXQ10S 1
35 #endif
36
37 #ifndef _STRING_H
38 #include "string.h"
39 #endif
40
41 #ifndef DEFAULT_ARCH
42 #define DEFAULT_ARCH "MAXQ20"
43 #endif
44
45 #ifndef MAX_OPERANDS
46 #define MAX_OPERANDS 2
47 #endif
48
49 #ifndef MAX_MNEM_SIZE
50 #define MAX_MNEM_SIZE 8
51 #endif
52
53 #ifndef END_OF_INSN
54 #define END_OF_INSN '\0'
55 #endif
56
57 #ifndef IMMEDIATE_PREFIX
58 #define IMMEDIATE_PREFIX '#'
59 #endif
60
61 #ifndef MAX_REG_NAME_SIZE
62 #define MAX_REG_NAME_SIZE 4
63 #endif
64
65 #ifndef MAX_MEM_NAME_SIZE
66 #define MAX_MEM_NAME_SIZE 9
67 #endif
68
69 /* opcode for PFX[0]. */
70 #define PFX0 0x0b
71
72 /* Set default to MAXQ20. */
73 unsigned int max_version = bfd_mach_maxq20;
74
75 const char *default_arch = DEFAULT_ARCH;
76
77 /* Type of the operand: Register,Immediate,Memory access,flag or bit. */
78
79 union _maxq20_op
80 {
81 const reg_entry * reg;
82 char imms; /* This is to store the immediate value operand. */
83 expressionS * disps;
84 symbolS * data;
85 const mem_access * mem;
86 int flag;
87 const reg_bit * r_bit;
88 };
89
90 typedef union _maxq20_op maxq20_opcode;
91
92 /* For handling optional L/S in Maxq20. */
93
94 /* Exposed For Linker - maps indirectly to the liker relocations. */
95 #define LONG_PREFIX MAXQ_LONGJUMP /* BFD_RELOC_16 */
96 #define SHORT_PREFIX MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
97 #define ABSOLUTE_ADDR_FOR_DATA MAXQ_INTERSEGMENT
98
99 #define NO_PREFIX 0
100 #define EXPLICT_LONG_PREFIX 14
101
102 /* The main instruction structure containing fields to describe instrn */
103 typedef struct _maxq20_insn
104 {
105 /* The opcode information for the MAXQ20 */
106 MAXQ20_OPCODE_INFO op;
107
108 /* The number of operands */
109 unsigned int operands;
110
111 /* Number of different types of operands - Comments can be removed if reqd.
112 */
113 unsigned int reg_operands, mem_operands, disp_operands, data_operands;
114 unsigned int imm_operands, imm_bit_operands, bit_operands, flag_operands;
115
116 /* Types of the individual operands */
117 UNKNOWN_OP types[MAX_OPERANDS];
118
119 /* Relocation type for operand : to be investigated into */
120 int reloc[MAX_OPERANDS];
121
122 /* Complete information of the Operands */
123 maxq20_opcode maxq20_op[MAX_OPERANDS];
124
125 /* Choice of prefix register whenever needed */
126 int prefix;
127
128 /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
129 unsigned char Instr_Prefix;
130
131 /* 16 bit Instruction word */
132 unsigned char instr[2];
133 }
134 maxq20_insn;
135
136 /* Definitions of all possible characters that can start an operand. */
137 const char *extra_symbol_chars = "@(#";
138
139 /* Special Character that would start a comment. */
140 const char comment_chars[] = ";";
141
142 /* Starts a comment when it appears at the start of a line. */
143 const char line_comment_chars[] = ";#";
144
145 const char line_separator_chars[] = ""; /* originally may b by sudeep "\n". */
146
147 /* The following are used for option processing. */
148
149 /* This is added to the mach independent string passed to getopt. */
150 const char *md_shortopts = "q";
151
152 /* Characters for exponent and floating point. */
153 const char EXP_CHARS[] = "eE";
154 const char FLT_CHARS[] = "";
155
156 /* This is for the machine dependent option handling. */
157 #define OPTION_EB (OPTION_MD_BASE + 0)
158 #define OPTION_EL (OPTION_MD_BASE + 1)
159 #define MAXQ_10 (OPTION_MD_BASE + 2)
160 #define MAXQ_20 (OPTION_MD_BASE + 3)
161
162 struct option md_longopts[] =
163 {
164 {"MAXQ10", no_argument, NULL, MAXQ_10},
165 {"MAXQ20", no_argument, NULL, MAXQ_20},
166 {NULL, no_argument, NULL, 0}
167 };
168 size_t md_longopts_size = sizeof (md_longopts);
169
170 /* md_undefined_symbol We have no need for this function. */
171
172 symbolS *
173 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
174 {
175 return NULL;
176 }
177
178 static void
179 maxq_target (int target)
180 {
181 max_version = target;
182 bfd_set_arch_mach (stdoutput, bfd_arch_maxq, max_version);
183 }
184
185 int
186 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
187 {
188 /* Any options support will be added onto this switch case. */
189 switch (c)
190 {
191 case MAXQ_10:
192 max_version = bfd_mach_maxq10;
193 break;
194 case MAXQ_20:
195 max_version = bfd_mach_maxq20;
196 break;
197
198 default:
199 return 0;
200 }
201
202 return 1;
203 }
204
205 /* When a usage message is printed, this function is called and
206 it prints a description of the machine specific options. */
207
208 void
209 md_show_usage (FILE * stream)
210 {
211 /* Over here we will fill the description of the machine specific options. */
212
213 fprintf (stream, _(" MAXQ-specific assembler options:\n"));
214
215 fprintf (stream, _("\
216 -MAXQ20 generate obj for MAXQ20(default)\n\
217 -MAXQ10 generate obj for MAXQ10\n\
218 "));
219 }
220
221 unsigned long
222 maxq20_mach (void)
223 {
224 if (!(strcmp (default_arch, "MAXQ20")))
225 return 0;
226
227 as_fatal (_("Unknown architecture"));
228 return 1;
229 }
230
231 arelent *
232 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
233 {
234 arelent *rel;
235 bfd_reloc_code_real_type code;
236
237 switch (fixp->fx_r_type)
238 {
239 case MAXQ_INTERSEGMENT:
240 case MAXQ_LONGJUMP:
241 case BFD_RELOC_16_PCREL_S2:
242 code = fixp->fx_r_type;
243 break;
244
245 case 0:
246 default:
247 switch (fixp->fx_size)
248 {
249 default:
250 as_bad_where (fixp->fx_file, fixp->fx_line,
251 _("can not do %d byte relocation"), fixp->fx_size);
252 code = BFD_RELOC_32;
253 break;
254
255 case 1:
256 code = BFD_RELOC_8;
257 break;
258 case 2:
259 code = BFD_RELOC_16;
260 break;
261 case 4:
262 code = BFD_RELOC_32;
263 break;
264 }
265 }
266
267 rel = xmalloc (sizeof (arelent));
268 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
269 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
270
271 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
272 rel->addend = fixp->fx_addnumber;
273 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
274
275 if (rel->howto == NULL)
276 {
277 as_bad_where (fixp->fx_file, fixp->fx_line,
278 _("cannot represent relocation type %s"),
279 bfd_get_reloc_code_name (code));
280
281 /* Set howto to a garbage value so that we can keep going. */
282 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
283 assert (rel->howto != NULL);
284 }
285
286 return rel;
287 }
288
289 /* md_estimate_size_before_relax()
290
291 Called just before relax() for rs_machine_dependent frags. The MAXQ
292 assembler uses these frags to handle 16 bit absolute jumps which require a
293 prefix instruction to be inserted. Any symbol that is now undefined will
294 not become defined. Return the correct fr_subtype in the frag. Return the
295 initial "guess for variable size of frag"(This will be eiter 2 or 0) to
296 caller. The guess is actually the growth beyond the fixed part. Whatever
297 we do to grow the fixed or variable part contributes to our returned
298 value. */
299
300 int
301 md_estimate_size_before_relax (fragS *fragP, segT segment)
302 {
303 /* Check whether the symbol has been resolved or not.
304 Otherwise we will have to generate a fixup. */
305 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment)
306 || fragP->fr_subtype == EXPLICT_LONG_PREFIX)
307 {
308 RELOC_ENUM reloc_type;
309 unsigned char *opcode;
310 int old_fr_fix;
311
312 /* Now this symbol has not been defined in this file.
313 Hence we will have to create a fixup. */
314 int size = 2;
315
316 /* This is for the prefix instruction. */
317
318 if (fragP->fr_subtype == EXPLICT_LONG_PREFIX)
319 fragP->fr_subtype = LONG_PREFIX;
320
321 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
322 && ((!(fragP->fr_subtype) == EXPLICT_LONG_PREFIX)))
323 fragP->fr_subtype = ABSOLUTE_ADDR_FOR_DATA;
324
325 reloc_type =
326 (fragP->fr_subtype ? fragP->fr_subtype : ABSOLUTE_ADDR_FOR_DATA);
327
328 fragP->fr_subtype = reloc_type;
329
330 if (reloc_type == SHORT_PREFIX)
331 size = 0;
332 old_fr_fix = fragP->fr_fix;
333 opcode = (unsigned char *) fragP->fr_opcode;
334
335 fragP->fr_fix += (size);
336
337 fix_new (fragP, old_fr_fix - 2, size + 2,
338 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
339 frag_wane (fragP);
340 return fragP->fr_fix - old_fr_fix;
341 }
342
343 if (fragP->fr_subtype == SHORT_PREFIX)
344 {
345 fragP->fr_subtype = SHORT_PREFIX;
346 return 0;
347 }
348
349 if (fragP->fr_subtype == NO_PREFIX || fragP->fr_subtype == LONG_PREFIX)
350 {
351 unsigned long instr;
352 unsigned long call_addr;
353 long diff;
354 fragS *f;
355 diff = diff ^ diff;;
356 call_addr = call_addr ^ call_addr;
357 instr = 0;
358 f = NULL;
359
360 /* segment_info_type *seginfo = seg_info (segment); */
361 instr = fragP->fr_address + fragP->fr_fix - 2;
362
363 /* This is the offset if it is a PC relative jump. */
364 call_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
365
366 /* PC stores the value of the next instruction. */
367 diff = (call_addr - instr) - 1;
368
369 if (diff >= (-128 * 2) && diff <= (2 * 127))
370 {
371 /* Now as offset is an 8 bit value, we will pass
372 that to the jump instruction directly. */
373 fragP->fr_subtype = NO_PREFIX;
374 return 0;
375 }
376
377 fragP->fr_subtype = LONG_PREFIX;
378 return 2;
379 }
380
381 as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
382 frag_now->fr_line);
383 return 0;
384 }
385
386 /* Equal to MAX_PRECISION in atof-ieee.c */
387 #define MAX_LITTLENUMS 6
388
389 /* Turn a string in input_line_pointer into a floating point constant of type
390 TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS
391 emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */
392
393 char *
394 md_atof (int type, char * litP, int * sizeP)
395 {
396 int prec;
397 LITTLENUM_TYPE words[4];
398 char *t;
399 int i;
400
401 switch (type)
402 {
403 case 'f':
404 prec = 2;
405 break;
406
407 case 'd':
408 prec = 2;
409 /* The size of Double has been changed to 2 words ie 32 bits. */
410 /* prec = 4; */
411 break;
412
413 default:
414 *sizeP = 0;
415 return _("bad call to md_atof");
416 }
417
418 t = atof_ieee (input_line_pointer, type, words);
419 if (t)
420 input_line_pointer = t;
421
422 *sizeP = prec * 2;
423
424 for (i = prec - 1; i >= 0; i--)
425 {
426 md_number_to_chars (litP, (valueT) words[i], 2);
427 litP += 2;
428 }
429
430 return NULL;
431 }
432
433 void
434 maxq20_cons_fix_new (fragS * frag, unsigned int off, unsigned int len,
435 expressionS * exp)
436 {
437 int r = 0;
438
439 switch (len)
440 {
441 case 2:
442 r = MAXQ_WORDDATA; /* Word+n */
443 break;
444 case 4:
445 r = MAXQ_LONGDATA; /* Long+n */
446 break;
447 }
448
449 fix_new_exp (frag, off, len, exp, 0, r);
450 return;
451 }
452
453 /* GAS will call this for every rs_machine_dependent fragment. The
454 instruction is compleated using the data from the relaxation pass. It may
455 also create any necessary relocations. */
456 void
457 md_convert_frag (bfd * headers ATTRIBUTE_UNUSED,
458 segT seg ATTRIBUTE_UNUSED,
459 fragS * fragP)
460 {
461 char *opcode;
462 offsetT target_address;
463 offsetT opcode_address;
464 offsetT displacement_from_opcode_start;
465 int address;
466
467 opcode = fragP->fr_opcode;
468 address = 0;
469 target_address = opcode_address = displacement_from_opcode_start = 0;
470
471 target_address =
472 (S_GET_VALUE (fragP->fr_symbol) / MAXQ_OCTETS_PER_BYTE) +
473 (fragP->fr_offset / MAXQ_OCTETS_PER_BYTE);
474
475 opcode_address =
476 (fragP->fr_address / MAXQ_OCTETS_PER_BYTE) +
477 ((fragP->fr_fix - 2) / MAXQ_OCTETS_PER_BYTE);
478
479 /* PC points to the next Instruction. */
480 displacement_from_opcode_start = ((target_address - opcode_address) - 1);
481
482 if ((displacement_from_opcode_start >= -128
483 && displacement_from_opcode_start <= 127)
484 && (fragP->fr_subtype == SHORT_PREFIX
485 || fragP->fr_subtype == NO_PREFIX))
486 {
487 /* Its a displacement. */
488 *opcode = (char) displacement_from_opcode_start;
489 }
490 else
491 {
492 /* Its an absolute 16 bit jump. Now we have to
493 load the prefix operator with the upper 8 bits. */
494 if (fragP->fr_subtype == SHORT_PREFIX)
495 {
496 as_bad (_("Cant make long jump/call into short jump/call : %d"),
497 fragP->fr_line);
498 return;
499 }
500
501 /* Check whether the symbol has been resolved or not.
502 Otherwise we will have to generate a fixup. */
503
504 if (fragP->fr_subtype != SHORT_PREFIX)
505 {
506 RELOC_ENUM reloc_type;
507 int old_fr_fix;
508 int size = 2;
509
510 /* Now this is a basolute jump/call.
511 Hence we will have to create a fixup. */
512 if (fragP->fr_subtype == NO_PREFIX)
513 fragP->fr_subtype = LONG_PREFIX;
514
515 reloc_type =
516 (fragP->fr_subtype ? fragP->fr_subtype : LONG_PREFIX);
517
518 if (reloc_type == 1)
519 size = 0;
520 old_fr_fix = fragP->fr_fix;
521
522 fragP->fr_fix += (size);
523
524 fix_new (fragP, old_fr_fix - 2, size + 2,
525 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
526 frag_wane (fragP);
527 }
528 }
529 }
530
531 long
532 md_pcrel_from (fixS *fixP)
533 {
534 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
535 }
536
537 /* Writes the val to the buf, where n is the nuumber of bytes to write. */
538
539 void
540 maxq_number_to_chars (char *buf, valueT val, int n)
541 {
542 if (target_big_endian)
543 number_to_chars_bigendian (buf, val, n);
544 else
545 number_to_chars_littleendian (buf, val, n);
546 }
547
548 /* GAS will call this for each fixup. It's main objective is to store the
549 correct value in the object file. 'fixup_segment' performs the generic
550 overflow check on the 'valueT *val' argument after md_apply_fix returns.
551 If the overflow check is relevant for the target machine, then
552 'md_apply_fix' should modify 'valueT *val', typically to the value stored
553 in the object file (not to be done in MAXQ). */
554
555 void
556 md_apply_fix (fixS *fixP, valueT *valT, segT seg ATTRIBUTE_UNUSED)
557 {
558 char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
559 char *frag_to_fix_at =
560 fixP->fx_frag->fr_literal + fixP->fx_frag->fr_fix - 2;
561
562 if (fixP)
563 {
564 if (fixP->fx_frag && valT)
565 {
566 /* If the relaxation substate is not defined we make it equal
567 to the kind of relocation the fixup is generated for. */
568 if (!fixP->fx_frag->fr_subtype)
569 fixP->fx_frag->fr_subtype = fixP->fx_r_type;
570
571 /* For any instruction in which either we have specified an
572 absolute address or it is a long jump we need to add a PFX0
573 instruction to it. In this case as the instruction has already
574 being written at 'fx_where' in the frag we copy it at the end of
575 the frag(which is where the relocation was generated) as when
576 the relocation is generated the frag is grown by 2 type, this is
577 where we copy the contents of fx_where and add a pfx0 at
578 fx_where. */
579 if ((fixP->fx_frag->fr_subtype == ABSOLUTE_ADDR_FOR_DATA)
580 || (fixP->fx_frag->fr_subtype == LONG_PREFIX))
581 {
582 *(frag_to_fix_at + 1) = *(p + 1);
583 maxq_number_to_chars (p + 1, PFX0, 1);
584 }
585
586 /* Remember value for tc_gen_reloc. */
587 fixP->fx_addnumber = *valT;
588 }
589
590 /* Some fixups generated by GAS which gets resovled before this this
591 func. is called need to be wriiten to the frag as here we are going
592 to go away with the relocations fx_done=1. */
593 if (fixP->fx_addsy == NULL)
594 {
595 maxq_number_to_chars (p, *valT, fixP->fx_size);
596 fixP->fx_addnumber = *valT;
597 fixP->fx_done = 1;
598 }
599 }
600 }
601
602 /* Tables for lexical analysis. */
603 static char mnemonic_chars[256];
604 static char register_chars[256];
605 static char operand_chars[256];
606 static char identifier_chars[256];
607 static char digit_chars[256];
608
609 /* Lexical Macros. */
610 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char)(x)])
611 #define is_register_char(x) (register_chars[(unsigned char)(x)])
612 #define is_operand_char(x) (operand_chars[(unsigned char)(x)])
613 #define is_space_char(x) (x==' ')
614 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
615 #define is_digit_char(x) (identifier_chars[(unsigned char)(x)])
616
617 /* Special characters for operands. */
618 static char operand_special_chars[] = "[]@.-+";
619
620 /* md_assemble() will always leave the instruction passed to it unaltered.
621 To do this we store the instruction in a special stack. */
622 static char save_stack[32];
623 static char *save_stack_p;
624
625 #define END_STRING_AND_SAVE(s) \
626 do \
627 { \
628 *save_stack_p++ = *(s); \
629 *s = '\0'; \
630 } \
631 while (0)
632
633 #define RESTORE_END_STRING(s) \
634 do \
635 { \
636 *(s) = *(--save_stack_p); \
637 } \
638 while (0)
639
640 /* The instruction we are assembling. */
641 static maxq20_insn i;
642
643 /* The current template. */
644 static MAXQ20_OPCODES *current_templates;
645
646 /* The displacement operand if any. */
647 static expressionS disp_expressions;
648
649 /* Current Operand we are working on (0:1st operand,1:2nd operand). */
650 static int this_operand;
651
652 /* The prefix instruction if used. */
653 static char PFX_INSN[2];
654 static char INSERT_BUFFER[2];
655
656 /* For interface with expression() ????? */
657 extern char *input_line_pointer;
658
659 /* The HASH Tables: */
660
661 /* Operand Hash Table. */
662 static struct hash_control *op_hash;
663
664 /* Register Hash Table. */
665 static struct hash_control *reg_hash;
666
667 /* Memory reference Hash Table. */
668 static struct hash_control *mem_hash;
669
670 /* Bit hash table. */
671 static struct hash_control *bit_hash;
672
673 /* Memory Access syntax table. */
674 static struct hash_control *mem_syntax_hash;
675
676 /* This is a mapping from pseudo-op names to functions. */
677
678 const pseudo_typeS md_pseudo_table[] =
679 {
680 {"int", cons, 2}, /* size of 'int' has been changed to 1 word
681 (i.e) 16 bits. */
682 {"maxq10", maxq_target, bfd_mach_maxq10},
683 {"maxq20", maxq_target, bfd_mach_maxq20},
684 {NULL, 0, 0},
685 };
686
687 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
688
689
690 /* This function sets the PFX value coresponding to the specs. Source
691 Destination Index Selection ---------------------------------- Write To|
692 SourceRegRange | Dest Addr Range
693 ------------------------------------------------------ PFX[0] | 0h-Fh |
694 0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
695 8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
696 18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
697
698 static void
699 set_prefix (void)
700 {
701 short int src_index = 0, dst_index = 0;
702
703 if (i.operands == 0)
704 return;
705 if (i.operands == 1) /* Only SRC is Present */
706 {
707 if (i.types[0] == REG)
708 {
709 if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
710 {
711 dst_index = i.maxq20_op[0].reg[0].Mod_index;
712 src_index = 0x00;
713 }
714 else
715 {
716 src_index = i.maxq20_op[0].reg[0].Mod_index;
717 dst_index = 0x00;
718 }
719 }
720 }
721
722 if (i.operands == 2)
723 {
724 if (i.types[0] == REG && i.types[1] == REG)
725 {
726 dst_index = i.maxq20_op[0].reg[0].Mod_index;
727 src_index = i.maxq20_op[1].reg[0].Mod_index;
728 }
729 else if (i.types[0] != REG && i.types[1] == REG) /* DST is Absent */
730 {
731 src_index = i.maxq20_op[1].reg[0].Mod_index;
732 dst_index = 0x00;
733 }
734 else if (i.types[0] == REG && i.types[1] != REG) /* Id SRC is Absent */
735 {
736 dst_index = i.maxq20_op[0].reg[0].Mod_index;
737 src_index = 0x00;
738 }
739 else if (i.types[0] == BIT && i.maxq20_op[0].r_bit)
740 {
741 dst_index = i.maxq20_op[0].r_bit->reg->Mod_index;
742 src_index = 0x00;
743 }
744
745 else if (i.types[1] == BIT && i.maxq20_op[1].r_bit)
746 {
747 dst_index = 0x00;
748 src_index = i.maxq20_op[1].r_bit->reg->Mod_index;
749 }
750 }
751
752 if (src_index >= 0x00 && src_index <= 0xF)
753 {
754 if (dst_index >= 0x00 && dst_index <= 0x07)
755 /* Set PFX[0] */
756 i.prefix = 0;
757
758 else if (dst_index >= 0x08 && dst_index <= 0x0F)
759 /* Set PFX[2] */
760 i.prefix = 2;
761
762 else if (dst_index >= 0x10 && dst_index <= 0x17)
763 /* Set PFX[4] */
764 i.prefix = 4;
765
766 else if (dst_index >= 0x18 && dst_index <= 0x1F)
767 /* Set PFX[6] */
768 i.prefix = 6;
769 }
770 else if (src_index >= 0x10 && src_index <= 0x1F)
771 {
772 if (dst_index >= 0x00 && dst_index <= 0x07)
773 /* Set PFX[1] */
774 i.prefix = 1;
775
776 else if (dst_index >= 0x08 && dst_index <= 0x0F)
777 /* Set PFX[3] */
778 i.prefix = 3;
779
780 else if (dst_index >= 0x10 && dst_index <= 0x17)
781 /* Set PFX[5] */
782 i.prefix = 5;
783
784 else if (dst_index >= 0x18 && dst_index <= 0x1F)
785 /* Set PFX[7] */
786 i.prefix = 7;
787 }
788 }
789
790 static unsigned char
791 is_a_LSinstr (const char *ln_pointer)
792 {
793 int i = 0;
794
795 for (i = 0; LSInstr[i] != NULL; i++)
796 if (!strcmp (LSInstr[i], ln_pointer))
797 return 1;
798
799 return 0;
800 }
801
802 static void
803 LS_processing (const char *line)
804 {
805 if (is_a_LSinstr (line))
806 {
807 if ((line[0] == 'L') || (line[0] == 'l'))
808 {
809 i.prefix = 0;
810 INSERT_BUFFER[0] = PFX0;
811 i.Instr_Prefix = LONG_PREFIX;
812 }
813 else if ((line[0] == 'S') || (line[0] == 's'))
814 i.Instr_Prefix = SHORT_PREFIX;
815 else
816 i.Instr_Prefix = NO_PREFIX;
817 }
818 else
819 i.Instr_Prefix = LONG_PREFIX;
820 }
821
822 /* Separate mnemonics and the operands. */
823
824 static char *
825 parse_insn (char *line, char *mnemonic)
826 {
827 char *l = line;
828 char *token_start = l;
829 char *mnem_p;
830 char temp[MAX_MNEM_SIZE];
831 int ii = 0;
832
833 memset (temp, END_OF_INSN, MAX_MNEM_SIZE);
834 mnem_p = mnemonic;
835
836 while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
837 {
838 ii++;
839 mnem_p++;
840 if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
841 {
842 as_bad (_("no such instruction: `%s'"), token_start);
843 return NULL;
844 }
845 l++;
846 }
847
848 if (!is_space_char (*l) && *l != END_OF_INSN)
849 {
850 as_bad (_("invalid character %s in mnemonic"), l);
851 return NULL;
852 }
853
854 while (ii)
855 {
856 temp[ii - 1] = toupper ((char) mnemonic[ii - 1]);
857 ii--;
858 }
859
860 LS_processing (temp);
861
862 if (i.Instr_Prefix != 0 && is_a_LSinstr (temp))
863 /* Skip the optional L-S. */
864 memcpy (temp, temp + 1, MAX_MNEM_SIZE);
865
866 /* Look up instruction (or prefix) via hash table. */
867 current_templates = (MAXQ20_OPCODES *) hash_find (op_hash, temp);
868
869 if (current_templates != NULL)
870 return l;
871
872 as_bad (_("no such instruction: `%s'"), token_start);
873 return NULL;
874 }
875
876 /* Function to calculate x to the power of y.
877 Just to avoid including the math libraries. */
878
879 static int
880 pwr (int x, int y)
881 {
882 int k, ans = 1;
883
884 for (k = 0; k < y; k++)
885 ans *= x;
886
887 return ans;
888 }
889
890 static reg_entry *
891 parse_reg_by_index (char *imm_start)
892 {
893 int k = 0, mid = 0, rid = 0, val = 0, j = 0;
894 char temp[4] = { 0 };
895 reg_entry *reg = NULL;
896
897 do
898 {
899 if (isdigit (imm_start[k]))
900 temp[k] = imm_start[k] - '0';
901
902 else if (isalpha (imm_start[k])
903 && (imm_start[k] = tolower (imm_start[k])) < 'g')
904 temp[k] = 10 + (int) (imm_start[k] - 'a');
905
906 else if (imm_start[k] == 'h')
907 break;
908
909 else if (imm_start[k] == END_OF_INSN)
910 {
911 imm_start[k] = 'd';
912 break;
913 }
914
915 else
916 return NULL; /* not a hex digit */
917
918 k++;
919 }
920 while (imm_start[k] != '\n');
921
922 switch (imm_start[k])
923 {
924 case 'h':
925 for (j = 0; j < k; j++)
926 val += temp[j] * pwr (16, k - j - 1);
927 break;
928
929 case 'd':
930 for (j = 0; j < k; j++)
931 {
932 if (temp[j] > 9)
933 return NULL; /* not a number */
934
935 val += temp[j] * pwr (10, k - j - 1);
936 break;
937 }
938 }
939
940 /* Get the module and register id's. */
941 mid = val & 0x0f;
942 rid = (val >> 4) & 0x0f;
943
944 if (mid < 6)
945 {
946 /* Search the pheripheral reg table. */
947 for (j = 0; j < num_of_reg; j++)
948 {
949 if (new_reg_table[j].opcode == val)
950 {
951 reg = (reg_entry *) & new_reg_table[j];
952 break;
953 }
954 }
955 }
956
957 else
958 {
959 /* Search the system register table. */
960 j = 0;
961
962 while (system_reg_table[j].reg_name != NULL)
963 {
964 if (system_reg_table[j].opcode == val)
965 {
966 reg = (reg_entry *) & system_reg_table[j];
967 break;
968 }
969 j++;
970 }
971 }
972
973 if (reg == NULL)
974 {
975 as_bad (_("Invalid register value %s"), imm_start);
976 return reg;
977 }
978
979 #if CHANGE_PFX
980 if (this_operand == 0 && reg != NULL)
981 {
982 if (reg->Mod_index > 7)
983 i.prefix = 2;
984 else
985 i.prefix = 0;
986 }
987 #endif
988 return (reg_entry *) reg;
989 }
990
991 /* REG_STRING starts *before* REGISTER_PREFIX. */
992
993 static reg_entry *
994 parse_register (char *reg_string, char **end_op)
995 {
996 char *s = reg_string;
997 char *p = NULL;
998 char reg_name_given[MAX_REG_NAME_SIZE + 1];
999 reg_entry *r = NULL;
1000
1001 r = NULL;
1002 p = NULL;
1003
1004 /* Skip possible REGISTER_PREFIX and possible whitespace. */
1005 if (is_space_char (*s))
1006 ++s;
1007
1008 p = reg_name_given;
1009 while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1010 {
1011 if (p >= reg_name_given + MAX_REG_NAME_SIZE)
1012 return (reg_entry *) NULL;
1013 s++;
1014 }
1015
1016 *end_op = s;
1017
1018 r = (reg_entry *) hash_find (reg_hash, reg_name_given);
1019
1020 #if CHANGE_PFX
1021 if (this_operand == 0 && r != NULL)
1022 {
1023 if (r->Mod_index > 7)
1024 i.prefix = 2;
1025 else
1026 i.prefix = 0;
1027 }
1028 #endif
1029 return r;
1030 }
1031
1032 static reg_bit *
1033 parse_register_bit (char *reg_string, char **end_op)
1034 {
1035 const char *s = reg_string;
1036 short k = 0;
1037 char diff = 0;
1038 reg_bit *rb = NULL;
1039 reg_entry *r = NULL;
1040 bit_name *b = NULL;
1041 char temp_bitname[MAX_REG_NAME_SIZE + 2];
1042 char temp[MAX_REG_NAME_SIZE + 1];
1043
1044 memset (&temp, '\0', (MAX_REG_NAME_SIZE + 1));
1045 memset (&temp_bitname, '\0', (MAX_REG_NAME_SIZE + 2));
1046
1047 diff = 0;
1048 r = NULL;
1049 rb = NULL;
1050 rb = xmalloc (sizeof (reg_bit));
1051 rb->reg = xmalloc (sizeof (reg_entry));
1052 k = 0;
1053
1054 /* For supporting bit names. */
1055 b = (bit_name *) hash_find (bit_hash, reg_string);
1056
1057 if (b != NULL)
1058 {
1059 *end_op = reg_string + strlen (reg_string);
1060 strcpy (temp_bitname, b->reg_bit);
1061 s = temp_bitname;
1062 }
1063
1064 if (strchr (s, '.'))
1065 {
1066 while (*s != '.')
1067 {
1068 if (*s == '\0')
1069 return NULL;
1070 temp[k] = *s++;
1071
1072 k++;
1073 }
1074 temp[k] = '\0';
1075 }
1076
1077 if ((r = parse_register (temp, end_op)) == NULL)
1078 return NULL;
1079
1080 rb->reg = r;
1081
1082 /* Skip the "." */
1083 s++;
1084
1085 if (isdigit ((char) *s))
1086 rb->bit = atoi (s);
1087 else if (isalpha ((char) *s))
1088 {
1089 rb->bit = (char) *s - 'a';
1090 rb->bit += 10;
1091 if (rb->bit > 15)
1092 {
1093 as_bad (_("Invalid bit number : '%c'"), (char) *s);
1094 return NULL;
1095 }
1096 }
1097
1098 if (b != NULL)
1099 diff = strlen (temp_bitname) - strlen (temp) - 1;
1100 else
1101 diff = strlen (reg_string) - strlen (temp) - 1;
1102
1103 if (*(s + diff) != '\0')
1104 {
1105 as_bad (_("Illegal character after operand '%s'"), reg_string);
1106 return NULL;
1107 }
1108
1109 return rb;
1110 }
1111
1112 static void
1113 pfx_for_imm_val (int arg)
1114 {
1115 if (i.prefix == -1)
1116 return;
1117
1118 if (i.prefix == 0 && arg == 0 && PFX_INSN[1] == 0 && !(i.data_operands))
1119 return;
1120
1121 if (!(i.prefix < 0) && !(i.prefix > 7))
1122 PFX_INSN[0] = (i.prefix << 4) | PFX0;
1123
1124 if (!PFX_INSN[1])
1125 PFX_INSN[1] = arg;
1126
1127 }
1128
1129 static int
1130 maxq20_immediate (char *imm_start)
1131 {
1132 int val = 0, val_pfx = 0;
1133 char sign_val = 0;
1134 int k = 0, j;
1135 int temp[4] = { 0 };
1136
1137 imm_start++;
1138
1139 if (imm_start[1] == '\0' && (imm_start[0] == '0' || imm_start[0] == '1')
1140 && (this_operand == 1 && ((i.types[0] == BIT || i.types[0] == FLAG))))
1141 {
1142 val = imm_start[0] - '0';
1143 i.imm_bit_operands++;
1144 i.types[this_operand] = IMMBIT;
1145 i.maxq20_op[this_operand].imms = (char) val;
1146 #if CHANGE_PFX
1147 if (i.prefix == 2)
1148 pfx_for_imm_val (0);
1149 #endif
1150 return 1;
1151 }
1152
1153 /* Check For Sign Charcater. */
1154 sign_val = 0;
1155
1156 do
1157 {
1158 if (imm_start[k] == '-' && k == 0)
1159 sign_val = -1;
1160
1161 else if (imm_start[k] == '+' && k == 0)
1162 sign_val = 1;
1163
1164 else if (isdigit (imm_start[k]))
1165 temp[k] = imm_start[k] - '0';
1166
1167 else if (isalpha (imm_start[k])
1168 && (imm_start[k] = tolower (imm_start[k])) < 'g')
1169 temp[k] = 10 + (int) (imm_start[k] - 'a');
1170
1171 else if (imm_start[k] == 'h')
1172 break;
1173
1174 else if (imm_start[k] == '\0')
1175 {
1176 imm_start[k] = 'd';
1177 break;
1178 }
1179 else
1180 {
1181 as_bad (_("Invalid Character in immediate Value : %c"),
1182 imm_start[k]);
1183 return 0;
1184 }
1185 k++;
1186 }
1187 while (imm_start[k] != '\n');
1188
1189 switch (imm_start[k])
1190 {
1191 case 'h':
1192 for (j = (sign_val ? 1 : 0); j < k; j++)
1193 val += temp[j] * pwr (16, k - j - 1);
1194 break;
1195
1196 case 'd':
1197 for (j = (sign_val ? 1 : 0); j < k; j++)
1198 {
1199 if (temp[j] > 9)
1200 {
1201 as_bad (_("Invalid Character in immediate value : %c"),
1202 imm_start[j]);
1203 return 0;
1204 }
1205 val += temp[j] * pwr (10, k - j - 1);
1206 }
1207 }
1208
1209 if (!sign_val)
1210 sign_val = 1;
1211
1212 /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1213 check if we are moving a 16 bit immediate value into an 8 bit register.
1214 In that case we will generate a warning and move only the lower 8 bits */
1215 if (val > 65535)
1216 {
1217 as_bad (_("Immediate value greater than 16 bits"));
1218 return 0;
1219 }
1220
1221 val = val * sign_val;
1222
1223 /* If it is a stack pointer and the value is greater than the maximum
1224 permissible size */
1225 if (this_operand == 1)
1226 {
1227 if ((val * sign_val) > MAX_STACK && i.types[0] == REG
1228 && !strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
1229 {
1230 as_warn (_
1231 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1232 val = val & MAX_STACK;
1233 }
1234
1235 /* Check the range for 8 bit registers. */
1236 else if (((val * sign_val) > 0xFF) && (i.types[0] == REG)
1237 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1238 {
1239 as_warn (_
1240 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1241 val = val & 0xfe;
1242 }
1243
1244 else if (((sign_val == -1) || (val > 0xFF)) && (i.types[0] == REG)
1245 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1246 {
1247 val_pfx = val >> 8;
1248 val = ((val) & 0x00ff);
1249 SET_PFX_ARG (val_pfx);
1250 i.maxq20_op[this_operand].imms = (char) val;
1251 }
1252
1253 else if ((val <= 0xff) && (i.types[0] == REG)
1254 && (i.maxq20_op[0].reg->rtype == Reg_8W))
1255 i.maxq20_op[this_operand].imms = (char) val;
1256
1257
1258 /* Check for 16 bit registers. */
1259 else if (((sign_val == -1) || val > 0xFE) && i.types[0] == REG
1260 && i.maxq20_op[0].reg->rtype == Reg_16W)
1261 {
1262 /* Add PFX for any negative value -> 16bit register. */
1263 val_pfx = val >> 8;
1264 val = ((val) & 0x00ff);
1265 SET_PFX_ARG (val_pfx);
1266 i.maxq20_op[this_operand].imms = (char) val;
1267 }
1268
1269 else if (val < 0xFF && i.types[0] == REG
1270 && i.maxq20_op[0].reg->rtype == Reg_16W)
1271 {
1272 i.maxq20_op[this_operand].imms = (char) val;
1273 }
1274
1275 /* All the immediate memory access - no PFX. */
1276 else if (i.types[0] == MEM)
1277 {
1278 if ((sign_val == -1) || val > 0xFE)
1279 {
1280 val_pfx = val >> 8;
1281 val = ((val) & 0x00ff);
1282 SET_PFX_ARG (val_pfx);
1283 i.maxq20_op[this_operand].imms = (char) val;
1284 }
1285 else
1286 i.maxq20_op[this_operand].imms = (char) val;
1287 }
1288
1289 /* Special handling for immediate jumps like jump nz, #03h etc. */
1290 else if (val < 0xFF && i.types[0] == FLAG)
1291 i.maxq20_op[this_operand].imms = (char) val;
1292
1293 else if ((((sign_val == -1) || val > 0xFE)) && i.types[0] == FLAG)
1294 {
1295 val_pfx = val >> 8;
1296 val = ((val) & 0x00ff);
1297 SET_PFX_ARG (val_pfx);
1298 i.maxq20_op[this_operand].imms = (char) val;
1299 }
1300 else
1301 {
1302 as_bad (_("Invalid immediate move operation"));
1303 return 0;
1304 }
1305 }
1306 else
1307 {
1308 /* All the instruction with operation on ACC: like ADD src, etc. */
1309 if ((sign_val == -1) || val > 0xFE)
1310 {
1311 val_pfx = val >> 8;
1312 val = ((val) & 0x00ff);
1313 SET_PFX_ARG (val_pfx);
1314 i.maxq20_op[this_operand].imms = (char) val;
1315 }
1316 else
1317 i.maxq20_op[this_operand].imms = (char) val;
1318 }
1319
1320 i.imm_operands++;
1321 return 1;
1322 }
1323
1324 static int
1325 extract_int_val (const char *imm_start)
1326 {
1327 int k, j, val;
1328 char sign_val;
1329 int temp[4];
1330
1331 k = 0;
1332 j = 0;
1333 val = 0;
1334 sign_val = 0;
1335 do
1336 {
1337 if (imm_start[k] == '-' && k == 0)
1338 sign_val = -1;
1339
1340 else if (imm_start[k] == '+' && k == 0)
1341 sign_val = 1;
1342
1343 else if (isdigit (imm_start[k]))
1344 temp[k] = imm_start[k] - '0';
1345
1346 else if (isalpha (imm_start[k]) && (tolower (imm_start[k])) < 'g')
1347 temp[k] = 10 + (int) (tolower (imm_start[k]) - 'a');
1348
1349 else if (tolower (imm_start[k]) == 'h')
1350 break;
1351
1352 else if ((imm_start[k] == '\0') || (imm_start[k] == ']'))
1353 /* imm_start[k]='d'; */
1354 break;
1355
1356 else
1357 {
1358 as_bad (_("Invalid Character in immediate Value : %c"),
1359 imm_start[k]);
1360 return 0;
1361 }
1362 k++;
1363 }
1364 while (imm_start[k] != '\n');
1365
1366 switch (imm_start[k])
1367 {
1368 case 'h':
1369 for (j = (sign_val ? 1 : 0); j < k; j++)
1370 val += temp[j] * pwr (16, k - j - 1);
1371 break;
1372
1373 default:
1374 for (j = (sign_val ? 1 : 0); j < k; j++)
1375 {
1376 if (temp[j] > 9)
1377 {
1378 as_bad (_("Invalid Character in immediate value : %c"),
1379 imm_start[j]);
1380 return 0;
1381 }
1382 val += temp[j] * pwr (10, k - j - 1);
1383 }
1384 }
1385
1386 if (!sign_val)
1387 sign_val = 1;
1388
1389 return val * sign_val;
1390 }
1391
1392 static char
1393 check_for_parse (const char *line)
1394 {
1395 int val;
1396
1397 if (*(line + 1) == '[')
1398 {
1399 do
1400 {
1401 line++;
1402 if ((*line == '-') || (*line == '+'))
1403 break;
1404 }
1405 while (!is_space_char (*line));
1406
1407 if ((*line == '-') || (*line == '+'))
1408 val = extract_int_val (line);
1409 else
1410 val = extract_int_val (line + 1);
1411
1412 INSERT_BUFFER[0] = 0x3E;
1413 INSERT_BUFFER[1] = val;
1414
1415 return 1;
1416 }
1417
1418 return 0;
1419 }
1420
1421 static mem_access *
1422 maxq20_mem_access (char *mem_string, char **end_op)
1423 {
1424 char *s = mem_string;
1425 char *p;
1426 char mem_name_given[MAX_MEM_NAME_SIZE + 1];
1427 mem_access *m;
1428
1429 m = NULL;
1430
1431 /* Skip possible whitespace. */
1432 if (is_space_char (*s))
1433 ++s;
1434
1435 p = mem_name_given;
1436 while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1437 {
1438 if (p >= mem_name_given + MAX_MEM_NAME_SIZE)
1439 return (mem_access *) NULL;
1440 s++;
1441 }
1442
1443 *end_op = s;
1444
1445 m = (mem_access *) hash_find (mem_hash, mem_name_given);
1446
1447 return m;
1448 }
1449
1450 /* This function checks whether the operand is a variable in the data segment
1451 and if so, it returns its symbol entry from the symbol table. */
1452
1453 static symbolS *
1454 maxq20_data (char *op_string)
1455 {
1456 symbolS *symbolP;
1457 symbolP = symbol_find (op_string);
1458
1459 if (symbolP != NULL
1460 && S_GET_SEGMENT (symbolP) != now_seg
1461 && S_GET_SEGMENT (symbolP) != bfd_und_section_ptr)
1462 {
1463 /* In case we do not want to always include the prefix instruction and
1464 let the loader handle the job or in case of a 8 bit addressing mode,
1465 we will just check for val_pfx to be equal to zero and then load the
1466 prefix instruction. Otherwise no prefix instruction needs to be
1467 loaded. */
1468 /* The prefix register will have to be loaded automatically as we have
1469 a 16 bit addressing field. */
1470 pfx_for_imm_val (0);
1471 return symbolP;
1472 }
1473
1474 return NULL;
1475 }
1476
1477 static int
1478 maxq20_displacement (char *disp_start, char *disp_end)
1479 {
1480 expressionS *exp;
1481 segT exp_seg = 0;
1482 char *save_input_line_pointer;
1483 #ifndef LEX_AT
1484 char *gotfree_input_line;
1485 #endif
1486
1487 gotfree_input_line = NULL;
1488 exp = &disp_expressions;
1489 i.maxq20_op[this_operand].disps = exp;
1490 i.disp_operands++;
1491 save_input_line_pointer = input_line_pointer;
1492 input_line_pointer = disp_start;
1493
1494 END_STRING_AND_SAVE (disp_end);
1495
1496 #ifndef LEX_AT
1497 /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1498 (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1499 #endif
1500 exp_seg = expression (exp);
1501
1502 SKIP_WHITESPACE ();
1503 if (*input_line_pointer)
1504 as_bad (_("junk `%s' after expression"), input_line_pointer);
1505 #if GCC_ASM_O_HACK
1506 RESTORE_END_STRING (disp_end + 1);
1507 #endif
1508 RESTORE_END_STRING (disp_end);
1509 input_line_pointer = save_input_line_pointer;
1510 #ifndef LEX_AT
1511 if (gotfree_input_line)
1512 free (gotfree_input_line);
1513 #endif
1514 if (exp->X_op == O_absent || exp->X_op == O_big)
1515 {
1516 /* Missing or bad expr becomes absolute 0. */
1517 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1518 disp_start);
1519 exp->X_op = O_constant;
1520 exp->X_add_number = 0;
1521 exp->X_add_symbol = (symbolS *) 0;
1522 exp->X_op_symbol = (symbolS *) 0;
1523 }
1524 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1525
1526 if (exp->X_op != O_constant
1527 && OUTPUT_FLAVOR == bfd_target_aout_flavour
1528 && exp_seg != absolute_section
1529 && exp_seg != text_section
1530 && exp_seg != data_section
1531 && exp_seg != bss_section && exp_seg != undefined_section
1532 && !bfd_is_com_section (exp_seg))
1533 {
1534 as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
1535 return 0;
1536 }
1537 #endif
1538 i.maxq20_op[this_operand].disps = exp;
1539 return 1;
1540 }
1541
1542 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1543 Returns non-zero on error. */
1544
1545 static int
1546 maxq20_operand (char *operand_string)
1547 {
1548 reg_entry *r = NULL;
1549 reg_bit *rb = NULL;
1550 mem_access *m = NULL;
1551 char *end_op = NULL;
1552 symbolS *sym = NULL;
1553 char *base_string = NULL;
1554 int ii = 0;
1555 /* Start and end of displacement string expression (if found). */
1556 char *displacement_string_start = NULL;
1557 char *displacement_string_end = NULL;
1558 /* This maintains the case sentivness. */
1559 char case_str_op_string[MAX_OPERAND_SIZE + 1];
1560 char str_op_string[MAX_OPERAND_SIZE + 1];
1561 char *org_case_op_string = case_str_op_string;
1562 char *op_string = str_op_string;
1563
1564
1565 memset (op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1566 memset (org_case_op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1567
1568 memcpy (op_string, operand_string, strlen (operand_string) + 1);
1569 memcpy (org_case_op_string, operand_string, strlen (operand_string) + 1);
1570
1571 ii = strlen (operand_string) + 1;
1572
1573 if (ii > MAX_OPERAND_SIZE)
1574 {
1575 as_bad (_("Size of Operand '%s' greater than %d"), op_string,
1576 MAX_OPERAND_SIZE);
1577 return 0;
1578 }
1579
1580 while (ii)
1581 {
1582 op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1583 ii--;
1584 }
1585
1586 if (is_space_char (*op_string))
1587 ++op_string;
1588
1589 if (isxdigit (operand_string[0]))
1590 {
1591 /* Now the operands can start with an Integer. */
1592 r = parse_reg_by_index (op_string);
1593 if (r != NULL)
1594 {
1595 if (is_space_char (*op_string))
1596 ++op_string;
1597 i.types[this_operand] = REG; /* Set the type. */
1598 i.maxq20_op[this_operand].reg = r; /* Set the Register value. */
1599 i.reg_operands++;
1600 return 1;
1601 }
1602
1603 /* Get the origanal string. */
1604 memcpy (op_string, operand_string, strlen (operand_string) + 1);
1605 ii = strlen (operand_string) + 1;
1606
1607 while (ii)
1608 {
1609 op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1610 ii--;
1611 }
1612 }
1613
1614 /* Check for flags. */
1615 if (!strcmp (op_string, "Z"))
1616 {
1617 if (is_space_char (*op_string))
1618 ++op_string;
1619
1620 i.types[this_operand] = FLAG; /* Set the type. */
1621 i.maxq20_op[this_operand].flag = FLAG_Z; /* Set the Register value. */
1622
1623 i.flag_operands++;
1624
1625 return 1;
1626 }
1627
1628 else if (!strcmp (op_string, "NZ"))
1629 {
1630 if (is_space_char (*op_string))
1631 ++op_string;
1632
1633 i.types[this_operand] = FLAG; /* Set the type. */
1634 i.maxq20_op[this_operand].flag = FLAG_NZ; /* Set the Register value. */
1635 i.flag_operands++;
1636 return 1;
1637 }
1638
1639 else if (!strcmp (op_string, "NC"))
1640 {
1641 if (is_space_char (*op_string))
1642 ++op_string;
1643
1644 i.types[this_operand] = FLAG; /* Set the type. */
1645 i.maxq20_op[this_operand].flag = FLAG_NC; /* Set the Register value. */
1646 i.flag_operands++;
1647 return 1;
1648 }
1649
1650 else if (!strcmp (op_string, "E"))
1651 {
1652 if (is_space_char (*op_string))
1653 ++op_string;
1654
1655 i.types[this_operand] = FLAG; /* Set the type. */
1656 i.maxq20_op[this_operand].flag = FLAG_E; /* Set the Register value. */
1657
1658 i.flag_operands++;
1659
1660 return 1;
1661 }
1662
1663 else if (!strcmp (op_string, "S"))
1664 {
1665 if (is_space_char (*op_string))
1666 ++op_string;
1667
1668 i.types[this_operand] = FLAG; /* Set the type. */
1669 i.maxq20_op[this_operand].flag = FLAG_S; /* Set the Register value. */
1670
1671 i.flag_operands++;
1672
1673 return 1;
1674 }
1675
1676 else if (!strcmp (op_string, "C"))
1677 {
1678 if (is_space_char (*op_string))
1679 ++op_string;
1680
1681 i.types[this_operand] = FLAG; /* Set the type. */
1682 i.maxq20_op[this_operand].flag = FLAG_C; /* Set the Register value. */
1683
1684 i.flag_operands++;
1685
1686 return 1;
1687 }
1688
1689 else if (!strcmp (op_string, "NE"))
1690 {
1691
1692 if (is_space_char (*op_string))
1693 ++op_string;
1694
1695 i.types[this_operand] = FLAG; /* Set the type. */
1696
1697 i.maxq20_op[this_operand].flag = FLAG_NE; /* Set the Register value. */
1698
1699 i.flag_operands++;
1700
1701 return 1;
1702 }
1703
1704 /* CHECK FOR REGISTER BIT */
1705 else if ((rb = parse_register_bit (op_string, &end_op)) != NULL)
1706 {
1707 op_string = end_op;
1708
1709 if (is_space_char (*op_string))
1710 ++op_string;
1711
1712 i.types[this_operand] = BIT;
1713
1714 i.maxq20_op[this_operand].r_bit = rb;
1715
1716 i.bit_operands++;
1717
1718 return 1;
1719 }
1720
1721 else if (*op_string == IMMEDIATE_PREFIX) /* FOR IMMEDITE. */
1722 {
1723 if (is_space_char (*op_string))
1724 ++op_string;
1725
1726 i.types[this_operand] = IMM;
1727
1728 if (!maxq20_immediate (op_string))
1729 {
1730 as_bad (_("illegal immediate operand '%s'"), op_string);
1731 return 0;
1732 }
1733 return 1;
1734 }
1735
1736 else if (*op_string == ABSOLUTE_PREFIX || !strcmp (op_string, "NUL"))
1737 {
1738 if (is_space_char (*op_string))
1739 ++op_string;
1740
1741 /* For new requiremnt of copiler of for, @(BP,cons). */
1742 if (check_for_parse (op_string))
1743 {
1744 memset (op_string, '\0', strlen (op_string) + 1);
1745 memcpy (op_string, "@BP[OFFS]\0", 11);
1746 }
1747
1748 i.types[this_operand] = MEM;
1749
1750 if ((m = maxq20_mem_access (op_string, &end_op)) == NULL)
1751 {
1752 as_bad (_("Invalid operand for memory access '%s'"), op_string);
1753 return 0;
1754 }
1755 i.maxq20_op[this_operand].mem = m;
1756
1757 i.mem_operands++;
1758
1759 return 1;
1760 }
1761
1762 else if ((r = parse_register (op_string, &end_op)) != NULL) /* Check for register. */
1763 {
1764 op_string = end_op;
1765
1766 if (is_space_char (*op_string))
1767 ++op_string;
1768
1769 i.types[this_operand] = REG; /* Set the type. */
1770 i.maxq20_op[this_operand].reg = r; /* Set the Register value. */
1771 i.reg_operands++;
1772 return 1;
1773 }
1774
1775 if (this_operand == 1)
1776 {
1777 /* Changed for orginal case of data refrence on 30 Nov 2003. */
1778 /* The operand can either be a data reference or a symbol reference. */
1779 if ((sym = maxq20_data (org_case_op_string)) != NULL) /* Check for data memory. */
1780 {
1781 while (is_space_char (*op_string))
1782 ++op_string;
1783
1784 /* Set the type of the operand. */
1785 i.types[this_operand] = DATA;
1786
1787 /* Set the value of the data. */
1788 i.maxq20_op[this_operand].data = sym;
1789 i.data_operands++;
1790
1791 return 1;
1792 }
1793
1794 else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1795 {
1796 /* This is a memory reference of some sort. char *base_string;
1797 Start and end of displacement string expression (if found). char
1798 *displacement_string_start; char *displacement_string_end. */
1799 base_string = org_case_op_string + strlen (org_case_op_string);
1800
1801 --base_string;
1802 if (is_space_char (*base_string))
1803 --base_string;
1804
1805 /* If we only have a displacement, set-up for it to be parsed
1806 later. */
1807 displacement_string_start = org_case_op_string;
1808 displacement_string_end = base_string + 1;
1809 if (displacement_string_start != displacement_string_end)
1810 {
1811 if (!maxq20_displacement (displacement_string_start,
1812 displacement_string_end))
1813 {
1814 as_bad (_("illegal displacement operand "));
1815 return 0;
1816 }
1817 /* A displacement operand found. */
1818 i.types[this_operand] = DISP; /* Set the type. */
1819 return 1;
1820 }
1821 }
1822 }
1823
1824 /* Check for displacement. */
1825 else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1826 {
1827 /* This is a memory reference of some sort. char *base_string;
1828 Start and end of displacement string expression (if found). char
1829 *displacement_string_start; char *displacement_string_end; */
1830 base_string = org_case_op_string + strlen (org_case_op_string);
1831
1832 --base_string;
1833 if (is_space_char (*base_string))
1834 --base_string;
1835
1836 /* If we only have a displacement, set-up for it to be parsed later. */
1837 displacement_string_start = org_case_op_string;
1838 displacement_string_end = base_string + 1;
1839 if (displacement_string_start != displacement_string_end)
1840 {
1841 if (!maxq20_displacement (displacement_string_start,
1842 displacement_string_end))
1843 return 0;
1844 /* A displacement operand found. */
1845 i.types[this_operand] = DISP; /* Set the type. */
1846 }
1847 }
1848 return 1;
1849 }
1850
1851 /* Parse_operand takes as input instruction and operands and Parse operands
1852 and makes entry in the template. */
1853
1854 static char *
1855 parse_operands (char *l, const char *mnemonic)
1856 {
1857 char *token_start;
1858
1859 /* 1 if operand is pending after ','. */
1860 short int expecting_operand = 0;
1861
1862 /* Non-zero if operand parens not balanced. */
1863 short int paren_not_balanced;
1864
1865 int operand_ok;
1866
1867 /* For Overcoming Warning of unused variable. */
1868 if (mnemonic)
1869 operand_ok = 0;
1870
1871 while (*l != END_OF_INSN)
1872 {
1873 /* Skip optional white space before operand. */
1874 if (is_space_char (*l))
1875 ++l;
1876
1877 if (!is_operand_char (*l) && *l != END_OF_INSN)
1878 {
1879 as_bad (_("invalid character %c before operand %d"),
1880 (char) (*l), i.operands + 1);
1881 return NULL;
1882 }
1883 token_start = l;
1884
1885 paren_not_balanced = 0;
1886 while (paren_not_balanced || *l != ',')
1887 {
1888 if (*l == END_OF_INSN)
1889 {
1890 if (paren_not_balanced)
1891 {
1892 as_bad (_("unbalanced brackets in operand %d."),
1893 i.operands + 1);
1894 return NULL;
1895 }
1896
1897 break;
1898 }
1899 else if (!is_operand_char (*l) && !is_space_char (*l))
1900 {
1901 as_bad (_("invalid character %c in operand %d"),
1902 (char) (*l), i.operands + 1);
1903 return NULL;
1904 }
1905 if (*l == '[')
1906 ++paren_not_balanced;
1907 if (*l == ']')
1908 --paren_not_balanced;
1909 l++;
1910 }
1911
1912 if (l != token_start)
1913 {
1914 /* Yes, we've read in another operand. */
1915 this_operand = i.operands++;
1916 if (i.operands > MAX_OPERANDS)
1917 {
1918 as_bad (_("spurious operands; (%d operands/instruction max)"),
1919 MAX_OPERANDS);
1920 return NULL;
1921 }
1922
1923 /* Now parse operand adding info to 'i' as we go along. */
1924 END_STRING_AND_SAVE (l);
1925
1926 operand_ok = maxq20_operand (token_start);
1927
1928 RESTORE_END_STRING (l);
1929
1930 if (!operand_ok)
1931 return NULL;
1932 }
1933 else
1934 {
1935 if (expecting_operand)
1936 {
1937 expecting_operand_after_comma:
1938 as_bad (_("expecting operand after ','; got nothing"));
1939 return NULL;
1940 }
1941 }
1942
1943 if (*l == ',')
1944 {
1945 if (*(++l) == END_OF_INSN)
1946 /* Just skip it, if it's \n complain. */
1947 goto expecting_operand_after_comma;
1948
1949 expecting_operand = 1;
1950 }
1951 }
1952
1953 return l;
1954 }
1955
1956 static int
1957 match_operands (int type, MAX_ARG_TYPE flag_type, MAX_ARG_TYPE arg_type,
1958 int op_num)
1959 {
1960 switch (type)
1961 {
1962 case REG:
1963 if ((arg_type & A_REG) == A_REG)
1964 return 1;
1965 break;
1966 case IMM:
1967 if ((arg_type & A_IMM) == A_IMM)
1968 return 1;
1969 break;
1970 case IMMBIT:
1971 if ((arg_type & A_BIT_0) == A_BIT_0 && (i.maxq20_op[op_num].imms == 0))
1972 return 1;
1973 else if ((arg_type & A_BIT_1) == A_BIT_1
1974 && (i.maxq20_op[op_num].imms == 1))
1975 return 1;
1976 break;
1977 case MEM:
1978 if ((arg_type & A_MEM) == A_MEM)
1979 return 1;
1980 break;
1981
1982 case FLAG:
1983 if ((arg_type & flag_type) == flag_type)
1984 return 1;
1985
1986 break;
1987
1988 case BIT:
1989 if ((arg_type & ACC_BIT) == ACC_BIT && !strcmp (i.maxq20_op[op_num].r_bit->reg->reg_name, "ACC"))
1990 return 1;
1991 else if ((arg_type & SRC_BIT) == SRC_BIT && (op_num == 1))
1992 return 1;
1993 else if ((op_num == 0) && (arg_type & DST_BIT) == DST_BIT)
1994 return 1;
1995 break;
1996 case DISP:
1997 if ((arg_type & A_DISP) == A_DISP)
1998 return 1;
1999 case DATA:
2000 if ((arg_type & A_DATA) == A_DATA)
2001 return 1;
2002 case BIT_BUCKET:
2003 if ((arg_type & A_BIT_BUCKET) == A_BIT_BUCKET)
2004 return 1;
2005 }
2006 return 0;
2007 }
2008
2009 static int
2010 match_template (void)
2011 {
2012 /* Points to template once we've found it. */
2013 const MAXQ20_OPCODE_INFO *t;
2014 char inv_oper;
2015 inv_oper = 0;
2016
2017 for (t = current_templates->start; t < current_templates->end; t++)
2018 {
2019 /* Must have right number of operands. */
2020 if (i.operands != t->op_number)
2021 continue;
2022 else if (!t->op_number)
2023 break;
2024
2025 switch (i.operands)
2026 {
2027 case 2:
2028 if (!match_operands (i.types[1], i.maxq20_op[1].flag, t->arg[1], 1))
2029 {
2030 inv_oper = 1;
2031 continue;
2032 }
2033 case 1:
2034 if (!match_operands (i.types[0], i.maxq20_op[0].flag, t->arg[0], 0))
2035 {
2036 inv_oper = 2;
2037 continue;
2038 }
2039 }
2040 break;
2041 }
2042
2043 if (t == current_templates->end)
2044 {
2045 /* We found no match. */
2046 as_bad (_("operand %d is invalid for `%s'"),
2047 inv_oper, current_templates->start->name);
2048 return 0;
2049 }
2050
2051 /* Copy the template we have found. */
2052 i.op = *t;
2053 return 1;
2054 }
2055
2056 /* This function filters out the various combinations of operands which are
2057 not allowed for a particular instruction. */
2058
2059 static int
2060 match_filters (void)
2061 {
2062 /* Now we have at our disposal the instruction i. We will be using the
2063 following fields i.op.name : This is the mnemonic name. i.types[2] :
2064 These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2065 i.maxq20_op[2] : This contains the specific info of the operands. */
2066
2067 /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2068 SOURCE. */
2069 if (!strcmp (i.op.name, "AND") || !strcmp (i.op.name, "OR")
2070 || !strcmp (i.op.name, "XOR") || !strcmp (i.op.name, "ADD")
2071 || !strcmp (i.op.name, "ADDC") || !strcmp (i.op.name, "SUB")
2072 || !strcmp (i.op.name, "SUBB"))
2073 {
2074 if (i.types[0] == REG)
2075 {
2076 if (i.maxq20_op[0].reg->Mod_name == 0xa)
2077 {
2078 as_bad (_
2079 ("The Accumulator cannot be used as a source in ALU instructions\n"));
2080 return 0;
2081 }
2082 }
2083 }
2084
2085 if (!strcmp (i.op.name, "MOVE") && (i.types[0] == MEM || i.types[1] == MEM)
2086 && i.operands == 2)
2087 {
2088 mem_access_syntax *mem_op = NULL;
2089
2090 if (i.types[0] == MEM)
2091 {
2092 mem_op =
2093 (mem_access_syntax *) hash_find (mem_syntax_hash,
2094 i.maxq20_op[0].mem->name);
2095 if ((mem_op->type == SRC) && mem_op)
2096 {
2097 as_bad (_("'%s' operand cant be used as destination in %s"),
2098 mem_op->name, i.op.name);
2099 return 0;
2100 }
2101 else if ((mem_op->invalid_op != NULL) && (i.types[1] == MEM)
2102 && mem_op)
2103 {
2104 int k = 0;
2105
2106 for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2107 {
2108 if (mem_op->invalid_op[k] != NULL)
2109 if (!strcmp
2110 (mem_op->invalid_op[k], i.maxq20_op[1].mem->name))
2111 {
2112 as_bad (_
2113 ("Invalid Instruction '%s' operand cant be used with %s"),
2114 mem_op->name, i.maxq20_op[1].mem->name);
2115 return 0;
2116 }
2117 }
2118 }
2119 }
2120
2121 if (i.types[1] == MEM)
2122 {
2123 mem_op = NULL;
2124 mem_op =
2125 (mem_access_syntax *) hash_find (mem_syntax_hash,
2126 i.maxq20_op[1].mem->name);
2127 if (mem_op->type == DST && mem_op)
2128 {
2129 as_bad (_("'%s' operand cant be used as source in %s"),
2130 mem_op->name, i.op.name);
2131 return 0;
2132 }
2133 else if (mem_op->invalid_op != NULL && i.types[0] == MEM && mem_op)
2134 {
2135 int k = 0;
2136
2137 for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2138 {
2139 if (mem_op->invalid_op[k] != NULL)
2140 if (!strcmp
2141 (mem_op->invalid_op[k], i.maxq20_op[0].mem->name))
2142 {
2143 as_bad (_
2144 ("Invalid Instruction '%s' operand cant be used with %s"),
2145 mem_op->name, i.maxq20_op[0].mem->name);
2146 return 0;
2147 }
2148 }
2149 }
2150 else if (i.types[0] == REG
2151 && !strcmp (i.maxq20_op[0].reg->reg_name, "OFFS")
2152 && mem_op)
2153 {
2154 if (!strcmp (mem_op->name, "@BP[OFFS--]")
2155 || !strcmp (mem_op->name, "@BP[OFFS++]"))
2156 {
2157 as_bad (_
2158 ("Invalid Instruction '%s' operand cant be used with %s"),
2159 mem_op->name, i.maxq20_op[0].mem->name);
2160 return 0;
2161 }
2162 }
2163 }
2164 }
2165
2166 /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2167 on 10-March-2004. */
2168 if ((i.types[0] == MEM) && (i.operands == 1)
2169 && !(!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI")))
2170 {
2171 mem_access_syntax *mem_op = NULL;
2172
2173 if (i.types[0] == MEM)
2174 {
2175 mem_op =
2176 (mem_access_syntax *) hash_find (mem_syntax_hash,
2177 i.maxq20_op[0].mem->name);
2178 if (mem_op->type == DST && mem_op)
2179 {
2180 as_bad (_("'%s' operand cant be used as source in %s"),
2181 mem_op->name, i.op.name);
2182 return 0;
2183 }
2184 }
2185 }
2186
2187 if (i.operands == 2 && i.types[0] == IMM)
2188 {
2189 as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2190 i.op.name);
2191 return 0;
2192 }
2193
2194 /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2195 if (!strcmp (i.op.name, "PUSH") || !strcmp (i.op.name, "POP")
2196 || !strcmp (i.op.name, "POPI"))
2197 {
2198 if (i.types[0] == REG)
2199 {
2200 if (!strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
2201 {
2202 as_bad (_("SP cannot be used with %s\n"), i.op.name);
2203 return 0;
2204 }
2205 }
2206 else if (i.types[0] == MEM
2207 && !strcmp (i.maxq20_op[0].mem->name, "@SP--"))
2208 {
2209 as_bad (_("@SP-- cannot be used with PUSH\n"));
2210 return 0;
2211 }
2212 }
2213
2214 /* This filter checks that two memory references using DP's cannot be used
2215 together in an instruction */
2216 if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 2)
2217 {
2218 if (strlen (i.maxq20_op[0].mem->name) != 6 ||
2219 strcmp (i.maxq20_op[0].mem->name, i.maxq20_op[1].mem->name))
2220 {
2221 if (!strncmp (i.maxq20_op[0].mem->name, "@DP", 3)
2222 && !strncmp (i.maxq20_op[1].mem->name, "@DP", 3))
2223 {
2224 as_bad (_
2225 ("Operands either contradictory or use the data bus in read/write state together"));
2226 return 0;
2227 }
2228
2229 if (!strncmp (i.maxq20_op[0].mem->name, "@SP", 3)
2230 && !strncmp (i.maxq20_op[1].mem->name, "@SP", 3))
2231 {
2232 as_bad (_
2233 ("Operands either contradictory or use the data bus in read/write state together"));
2234 return 0;
2235 }
2236 }
2237 if ((i.maxq20_op[1].mem != NULL)
2238 && !strncmp (i.maxq20_op[1].mem->name, "NUL", 3))
2239 {
2240 as_bad (_("MOVE Cant Use NUL as SRC"));
2241 return 0;
2242 }
2243 }
2244
2245 /* This filter checks that contradictory movement between DP register and
2246 Memory access using DP followed by increment or decrement. */
2247
2248 if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 1
2249 && i.reg_operands == 1)
2250 {
2251 int memnum, regnum;
2252
2253 memnum = (i.types[0] == MEM) ? 0 : 1;
2254 regnum = (memnum == 0) ? 1 : 0;
2255 if (!strncmp (i.maxq20_op[regnum].reg->reg_name, "DP", 2) &&
2256 !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2257 i.maxq20_op[regnum].reg->reg_name, 5)
2258 && strcmp ((i.maxq20_op[memnum].mem->name) + 1,
2259 i.maxq20_op[regnum].reg->reg_name))
2260 {
2261 as_bad (_
2262 ("Contradictory movement between DP register and memory access using DP"));
2263 return 0;
2264 }
2265 else if (!strcmp (i.maxq20_op[regnum].reg->reg_name, "SP") &&
2266 !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2267 i.maxq20_op[regnum].reg->reg_name, 2))
2268 {
2269 as_bad (_
2270 ("SP and @SP-- cannot be used together in a move instruction"));
2271 return 0;
2272 }
2273 }
2274
2275 /* This filter restricts the instructions containing source and destination
2276 bits to only CTRL module of the serial registers. Peripheral registers
2277 yet to be defined. */
2278
2279 if (i.bit_operands == 1 && i.operands == 2)
2280 {
2281 int bitnum = (i.types[0] == BIT) ? 0 : 1;
2282
2283 if (strcmp (i.maxq20_op[bitnum].r_bit->reg->reg_name, "ACC"))
2284 {
2285 if (i.maxq20_op[bitnum].r_bit->reg->Mod_name >= 0x7 &&
2286 i.maxq20_op[bitnum].r_bit->reg->Mod_name != CTRL)
2287 {
2288 as_bad (_
2289 ("Only Module 8 system registers allowed in this operation"));
2290 return 0;
2291 }
2292 }
2293 }
2294
2295 /* This filter is for checking the register bits. */
2296 if (i.bit_operands == 1 || i.operands == 2)
2297 {
2298 int bitnum = 0, size = 0;
2299
2300 bitnum = (i.types[0] == BIT) ? 0 : 1;
2301 if (i.bit_operands == 1)
2302 {
2303 switch (i.maxq20_op[bitnum].r_bit->reg->rtype)
2304 {
2305 case Reg_8W:
2306 size = 7; /* 8 bit register, both read and write. */
2307 break;
2308 case Reg_16W:
2309 size = 15;
2310 break;
2311 case Reg_8R:
2312 size = 7;
2313 if (bitnum == 0)
2314 {
2315 as_fatal (_("Read only Register used as destination"));
2316 return 0;
2317 }
2318 break;
2319
2320 case Reg_16R:
2321 size = 15;
2322 if (bitnum == 0)
2323 {
2324 as_fatal (_("Read only Register used as destination"));
2325 return 0;
2326 }
2327 break;
2328 }
2329
2330 if (size < (i.maxq20_op[bitnum].r_bit)->bit)
2331 {
2332 as_bad (_("Bit No '%d'exceeds register size in this operation"),
2333 (i.maxq20_op[bitnum].r_bit)->bit);
2334 return 0;
2335 }
2336 }
2337
2338 if (i.bit_operands == 2)
2339 {
2340 switch ((i.maxq20_op[0].r_bit)->reg->rtype)
2341 {
2342 case Reg_8W:
2343 size = 7; /* 8 bit register, both read and write. */
2344 break;
2345 case Reg_16W:
2346 size = 15;
2347 break;
2348 case Reg_8R:
2349 case Reg_16R:
2350 as_fatal (_("Read only Register used as destination"));
2351 return 0;
2352 }
2353
2354 if (size < (i.maxq20_op[0].r_bit)->bit)
2355 {
2356 as_bad (_
2357 ("Bit No '%d' exceeds register size in this operation"),
2358 (i.maxq20_op[0].r_bit)->bit);
2359 return 0;
2360 }
2361
2362 size = 0;
2363 switch ((i.maxq20_op[1].r_bit)->reg->rtype)
2364 {
2365 case Reg_8R:
2366 case Reg_8W:
2367 size = 7; /* 8 bit register, both read and write. */
2368 break;
2369 case Reg_16R:
2370 case Reg_16W:
2371 size = 15;
2372 break;
2373 }
2374
2375 if (size < (i.maxq20_op[1].r_bit)->bit)
2376 {
2377 as_bad (_
2378 ("Bit No '%d' exceeds register size in this operation"),
2379 (i.maxq20_op[1].r_bit)->bit);
2380 return 0;
2381 }
2382 }
2383 }
2384
2385 /* No branch operations should occur into the data memory. Hence any memory
2386 references have to be filtered out when used with instructions like
2387 jump, djnz[] and call. */
2388
2389 if (!strcmp (i.op.name, "JUMP") || !strcmp (i.op.name, "CALL")
2390 || !strncmp (i.op.name, "DJNZ", 4))
2391 {
2392 if (i.mem_operands)
2393 as_warn (_
2394 ("Memory References cannot be used with branching operations\n"));
2395 }
2396
2397 if (!strcmp (i.op.name, "DJNZ"))
2398 {
2399 if (!
2400 (strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2401 || strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))
2402 {
2403 as_bad (_("DJNZ uses only LC[n] register \n"));
2404 return 0;
2405 }
2406 }
2407
2408 /* No destination register used should be read only! */
2409 if ((i.operands == 2 && i.types[0] == REG) || !strcmp (i.op.name, "POP")
2410 || !strcmp (i.op.name, "POPI"))
2411 { /* The destination is a register */
2412 int regnum = 0;
2413
2414 if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2415 {
2416 regnum = 0;
2417
2418 if (i.types[regnum] == MEM)
2419 {
2420 mem_access_syntax *mem_op = NULL;
2421
2422 mem_op =
2423 (mem_access_syntax *) hash_find (mem_syntax_hash,
2424 i.maxq20_op[regnum].mem->
2425 name);
2426 if (mem_op->type == SRC && mem_op)
2427 {
2428 as_bad (_
2429 ("'%s' operand cant be used as destination in %s"),
2430 mem_op->name, i.op.name);
2431 return 0;
2432 }
2433 }
2434 }
2435
2436 if (i.maxq20_op[regnum].reg->rtype == Reg_8R
2437 || i.maxq20_op[regnum].reg->rtype == Reg_16R)
2438 {
2439 as_bad (_("Read only register used for writing purposes '%s'"),
2440 i.maxq20_op[regnum].reg->reg_name);
2441 return 0;
2442 }
2443 }
2444
2445 /* While moving the address of a data in the data section, the destination
2446 should be either data pointers only. */
2447 if ((i.data_operands) && (i.operands == 2))
2448 {
2449 if ((i.types[0] != REG) && (i.types[0] != MEM))
2450 {
2451 as_bad (_("Invalid destination for this kind of source."));
2452 return 0;
2453 }
2454
2455 if (i.types[0] == REG && i.maxq20_op[0].reg->rtype == Reg_8W)
2456 {
2457 as_bad (_
2458 ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2459 return 0;
2460 }
2461 }
2462 return 1;
2463 }
2464
2465 static int
2466 decode_insn (void)
2467 {
2468 /* Check for the format Bit if defined. */
2469 if (i.op.format == 0 || i.op.format == 1)
2470 i.instr[0] = i.op.format << 7;
2471 else
2472 {
2473 /* Format bit not defined. We will have to be find it out ourselves. */
2474 if (i.imm_operands == 1 || i.data_operands == 1 || i.disp_operands == 1)
2475 i.op.format = 0;
2476 else
2477 i.op.format = 1;
2478 i.instr[0] = i.op.format << 7;
2479 }
2480
2481 /* Now for the destination register. */
2482
2483 /* If destination register is already defined . The conditions are the
2484 following: (1) The second entry in the destination array should be 0 (2)
2485 If there are two operands then the first entry should not be a register,
2486 memory or a register bit (3) If there are less than two operands and the
2487 it is not a pop operation (4) The second argument is the carry
2488 flag(applicable to move Acc.<b>,C. */
2489 if (i.op.dst[1] == 0
2490 &&
2491 ((i.types[0] != REG && i.types[0] != MEM && i.types[0] != BIT
2492 && i.operands == 2) || (i.operands < 2 && strcmp (i.op.name, "POP")
2493 && strcmp (i.op.name, "POPI"))
2494 || (i.op.arg[1] == FLAG_C)))
2495 {
2496 i.op.dst[0] &= 0x7f;
2497 i.instr[0] |= i.op.dst[0];
2498 }
2499 else if (i.op.dst[1] == 0 && !strcmp (i.op.name, "DJNZ")
2500 &&
2501 (((i.types[0] == REG)
2502 && (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2503 || !strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))))
2504 {
2505 i.op.dst[0] &= 0x7f;
2506 if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]"))
2507 i.instr[0] |= 0x4D;
2508
2509 if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]"))
2510 i.instr[0] |= 0x5D;
2511 }
2512 else
2513 {
2514 unsigned char temp;
2515
2516 /* Target register will have to be specified. */
2517 if (i.types[0] == REG
2518 && (i.op.dst[0] == REG || i.op.dst[0] == (REG | MEM)))
2519 {
2520 temp = (i.maxq20_op[0].reg)->opcode;
2521 temp &= 0x7f;
2522 i.instr[0] |= temp;
2523 }
2524 else if (i.types[0] == MEM && (i.op.dst[0] == (REG | MEM)))
2525 {
2526 temp = (i.maxq20_op[0].mem)->opcode;
2527 temp &= 0x7f;
2528 i.instr[0] |= temp;
2529 }
2530 else if (i.types[0] == BIT && (i.op.dst[0] == REG))
2531 {
2532 temp = (i.maxq20_op[0].r_bit)->reg->opcode;
2533 temp &= 0x7f;
2534 i.instr[0] |= temp;
2535 }
2536 else if (i.types[1] == BIT && (i.op.dst[0] == BIT))
2537 {
2538 temp = (i.maxq20_op[1].r_bit)->bit;
2539 temp = temp << 4;
2540 temp |= i.op.dst[1];
2541 temp &= 0x7f;
2542 i.instr[0] |= temp;
2543 }
2544 else
2545 {
2546 as_bad (_("Invalid Instruction"));
2547 return 0;
2548 }
2549 }
2550
2551 /* Now for the source register. */
2552
2553 /* If Source register is already known. The following conditions are
2554 checked: (1) There are no operands (2) If there is only one operand and
2555 it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2556 operation. */
2557
2558 if (i.operands == 0 || (i.operands == 1 && i.types[0] == FLAG)
2559 || (i.types[0] == FLAG && i.types[1] == IMMBIT)
2560 || !strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2561 i.instr[1] = i.op.src[0];
2562
2563 else if (i.imm_operands == 1 && ((i.op.src[0] & IMM) == IMM))
2564 i.instr[1] = i.maxq20_op[this_operand].imms;
2565
2566 else if (i.types[this_operand] == REG && ((i.op.src[0] & REG) == REG))
2567 i.instr[1] = (char) ((i.maxq20_op[this_operand].reg)->opcode);
2568
2569 else if (i.types[this_operand] == BIT && ((i.op.src[0] & REG) == REG))
2570 i.instr[1] = (char) (i.maxq20_op[this_operand].r_bit->reg->opcode);
2571
2572 else if (i.types[this_operand] == MEM && ((i.op.src[0] & MEM) == MEM))
2573 i.instr[1] = (char) ((i.maxq20_op[this_operand].mem)->opcode);
2574
2575 else if (i.types[this_operand] == DATA && ((i.op.src[0] & DATA) == DATA))
2576 /* This will copy only the lower order bytes into the instruction. The
2577 higher order bytes have already been copied into the prefix register. */
2578 i.instr[1] = 0;
2579
2580 /* Decoding the source in the case when the second array entry is not 0.
2581 This means that the source register has been divided into two nibbles. */
2582
2583 else if (i.op.src[1] != 0)
2584 {
2585 /* If the first operand is a accumulator bit then
2586 the first 4 bits will be filled with the bit number. */
2587 if (i.types[0] == BIT && ((i.op.src[0] & BIT) == BIT))
2588 {
2589 unsigned char temp = (i.maxq20_op[0].r_bit)->bit;
2590
2591 temp = temp << 4;
2592 temp |= i.op.src[1];
2593 i.instr[1] = temp;
2594 }
2595 /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2596 has to start with a zero. This is called a ZEROBIT */
2597 else if (i.types[0] == BIT && ((i.op.src[0] & ZEROBIT) == ZEROBIT))
2598 {
2599 char temp = (i.maxq20_op[0].r_bit)->bit;
2600
2601 temp = temp << 4;
2602 temp |= i.op.src[1];
2603 temp &= 0x7f;
2604 i.instr[1] = temp;
2605 }
2606 /* Similarly for a ONEBIT */
2607 else if (i.types[0] == BIT && ((i.op.src[0] & ONEBIT) == ONEBIT))
2608 {
2609 char temp = (i.maxq20_op[0].r_bit)->bit;
2610
2611 temp = temp << 4;
2612 temp |= i.op.src[1];
2613 temp |= 0x80;
2614 i.instr[1] = temp;
2615 }
2616 /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2617 C,src.<b> */
2618 else if (i.types[1] == BIT)
2619 {
2620 if (i.op.src[1] == 0 && i.op.src[1] == REG)
2621 i.instr[1] = (i.maxq20_op[1].r_bit)->reg->opcode;
2622
2623 else if (i.op.src[0] == BIT && i.op.src)
2624 {
2625 char temp = (i.maxq20_op[1].r_bit)->bit;
2626
2627 temp = temp << 4;
2628 temp |= i.op.src[1];
2629 i.instr[1] = temp;
2630 }
2631 }
2632 else
2633 {
2634 as_bad (_("Invalid Instruction"));
2635 return 0;
2636 }
2637 }
2638 return 1;
2639 }
2640
2641 /* This is a function for outputting displacement operands. */
2642
2643 static void
2644 output_disp (fragS *insn_start_frag, offsetT insn_start_off)
2645 {
2646 char *p;
2647 relax_substateT subtype;
2648 symbolS *sym;
2649 offsetT off;
2650 int diff;
2651
2652 diff = 0;
2653 insn_start_frag = frag_now;
2654 insn_start_off = frag_now_fix ();
2655
2656 switch (i.Instr_Prefix)
2657 {
2658 case LONG_PREFIX:
2659 subtype = EXPLICT_LONG_PREFIX;
2660 break;
2661 case SHORT_PREFIX:
2662 subtype = SHORT_PREFIX;
2663 break;
2664 default:
2665 subtype = NO_PREFIX;
2666 break;
2667 }
2668
2669 /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2670 case there is no need for relaxation. But we do need support for a
2671 prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2672 for prefix + 2 for the current instruction ) Hence if at a particular
2673 time we find out whether the prefix operator is reqd , we shift the
2674 current instruction two places ahead and insert the prefix instruction. */
2675 frag_grow (2 + 2);
2676 p = frag_more (2);
2677
2678 sym = i.maxq20_op[this_operand].disps->X_add_symbol;
2679 off = i.maxq20_op[this_operand].disps->X_add_number;
2680
2681 if (i.maxq20_op[this_operand].disps->X_add_symbol != NULL && sym && frag_now
2682 && (subtype != EXPLICT_LONG_PREFIX))
2683 {
2684 /* If in the same frag. */
2685 if (frag_now == symbol_get_frag (sym))
2686 {
2687 diff =
2688 ((((expressionS *) symbol_get_value_expression (sym))->
2689 X_add_number) - insn_start_off);
2690
2691 /* PC points to the next instruction. */
2692 diff = (diff / MAXQ_OCTETS_PER_BYTE) - 1;
2693
2694 if (diff >= -128 && diff <= 127)
2695 {
2696 i.instr[1] = (char) diff;
2697
2698 /* This will be overwritten later when the symbol is resolved. */
2699 *p = i.instr[1];
2700 *(p + 1) = i.instr[0];
2701
2702 /* No Need to create a FIXUP. */
2703 return;
2704 }
2705 }
2706 }
2707
2708 /* This will be overwritten later when the symbol is resolved. */
2709 *p = i.instr[1];
2710 *(p + 1) = i.instr[0];
2711
2712 if (i.maxq20_op[this_operand].disps->X_op != O_constant
2713 && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2714 {
2715 /* Handle complex expressions. */
2716 sym = make_expr_symbol (i.maxq20_op[this_operand].disps);
2717 off = 0;
2718 }
2719
2720 /* Vineet : This has been added for md_estimate_size_before_relax to
2721 estimate the correct size. */
2722 if (subtype != SHORT_PREFIX)
2723 i.reloc[this_operand] = LONG_PREFIX;
2724
2725 frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off, p);
2726 }
2727
2728 /* This is a function for outputting displacement operands. */
2729
2730 static void
2731 output_data (fragS *insn_start_frag, offsetT insn_start_off)
2732 {
2733 char *p;
2734 relax_substateT subtype;
2735 symbolS *sym;
2736 offsetT off;
2737 int diff;
2738
2739 diff = 0;
2740 off = 0;
2741 insn_start_frag = frag_now;
2742 insn_start_off = frag_now_fix ();
2743
2744 subtype = EXPLICT_LONG_PREFIX;
2745
2746 frag_grow (2 + 2);
2747 p = frag_more (2);
2748
2749 sym = i.maxq20_op[this_operand].data;
2750 off = 0;
2751
2752 /* This will be overwritten later when the symbol is resolved. */
2753 *p = i.instr[1];
2754 *(p + 1) = i.instr[0];
2755
2756 if (i.maxq20_op[this_operand].disps->X_op != O_constant
2757 && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2758 /* Handle complex expressions. */
2759 /* Because data is already in terms of symbol so no
2760 need to convert it from expression to symbol. */
2761 off = 0;
2762
2763 frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off, p);
2764 }
2765
2766 static void
2767 output_insn (void)
2768 {
2769 fragS *insn_start_frag;
2770 offsetT insn_start_off;
2771 char *p;
2772
2773 /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2774 do this after the insn has been output as the current frag may have been
2775 closed off. eg. by frag_var. */
2776 dwarf2_emit_insn (0);
2777
2778 /* To ALign the text section on word. */
2779
2780 frag_align (1, 0, 1);
2781
2782 /* We initialise the frags for this particular instruction. */
2783 insn_start_frag = frag_now;
2784 insn_start_off = frag_now_fix ();
2785
2786 /* If there are displacement operators(unresolved) present, then handle
2787 them separately. */
2788 if (i.disp_operands)
2789 {
2790 output_disp (insn_start_frag, insn_start_off);
2791 return;
2792 }
2793
2794 if (i.data_operands)
2795 {
2796 output_data (insn_start_frag, insn_start_off);
2797 return;
2798 }
2799
2800 /* Check whether the INSERT_BUFFER has to be written. */
2801 if (strcmp (INSERT_BUFFER, ""))
2802 {
2803 p = frag_more (2);
2804
2805 *p++ = INSERT_BUFFER[1];
2806 *p = INSERT_BUFFER[0];
2807 }
2808
2809 /* Check whether the prefix instruction has to be written. */
2810 if (strcmp (PFX_INSN, ""))
2811 {
2812 p = frag_more (2);
2813
2814 *p++ = PFX_INSN[1];
2815 *p = PFX_INSN[0];
2816 }
2817
2818 p = frag_more (2);
2819 /* For Little endian. */
2820 *p++ = i.instr[1];
2821 *p = i.instr[0];
2822 }
2823
2824 static void
2825 make_new_reg_table (void)
2826 {
2827 unsigned long size_pm = sizeof (peripheral_reg_table);
2828 num_of_reg = ARRAY_SIZE (peripheral_reg_table);
2829
2830 new_reg_table = xmalloc (size_pm);
2831 if (new_reg_table == NULL)
2832 as_bad (_("Cannot allocate memory"));
2833
2834 memcpy (new_reg_table, peripheral_reg_table, size_pm);
2835 }
2836
2837 /* pmmain performs the initilizations for the pheripheral modules. */
2838
2839 static void
2840 pmmain (void)
2841 {
2842 make_new_reg_table ();
2843 return;
2844 }
2845
2846 void
2847 md_begin (void)
2848 {
2849 const char *hash_err = NULL;
2850 int c = 0;
2851 char *p;
2852 const MAXQ20_OPCODE_INFO *optab;
2853 MAXQ20_OPCODES *core_optab; /* For opcodes of the same name. This will
2854 be inserted into the hash table. */
2855 struct reg *reg_tab;
2856 struct mem_access_syntax const *memsyntab;
2857 struct mem_access *memtab;
2858 struct bit_name *bittab;
2859
2860 /* Initilize pherioipheral modules. */
2861 pmmain ();
2862
2863 /* Initialise the opcode hash table. */
2864 op_hash = hash_new ();
2865
2866 optab = op_table; /* Initialise it to the first entry of the
2867 maxq20 operand table. */
2868
2869 /* Setup for loop. */
2870 core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2871 core_optab->start = optab;
2872
2873 while (1)
2874 {
2875 ++optab;
2876 if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0)
2877 {
2878 /* different name --> ship out current template list; add to hash
2879 table; & begin anew. */
2880
2881 core_optab->end = optab;
2882 #ifdef MAXQ10S
2883 if (max_version == bfd_mach_maxq10)
2884 {
2885 if (((optab - 1)->arch == MAXQ10) || ((optab - 1)->arch == MAX))
2886 {
2887 hash_err = hash_insert (op_hash,
2888 (optab - 1)->name,
2889 (PTR) core_optab);
2890 }
2891 }
2892 else if (max_version == bfd_mach_maxq20)
2893 {
2894 if (((optab - 1)->arch == MAXQ20) || ((optab - 1)->arch == MAX))
2895 {
2896 #endif
2897 hash_err = hash_insert (op_hash,
2898 (optab - 1)->name,
2899 (PTR) core_optab);
2900 #if MAXQ10S
2901 }
2902 }
2903 else
2904 as_fatal (_("Internal Error: Illegal Architecure specified"));
2905 #endif
2906 if (hash_err)
2907 as_fatal (_("Internal Error: Can't hash %s: %s"),
2908 (optab - 1)->name, hash_err);
2909
2910 if (optab->name == NULL)
2911 break;
2912 core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2913 core_optab->start = optab;
2914 }
2915 }
2916
2917 /* Initialise a new register table. */
2918 reg_hash = hash_new ();
2919
2920 for (reg_tab = system_reg_table;
2921 reg_tab < (system_reg_table + ARRAY_SIZE (system_reg_table));
2922 reg_tab++)
2923 {
2924 #if MAXQ10S
2925 switch (max_version)
2926 {
2927 case bfd_mach_maxq10:
2928 if ((reg_tab->arch == MAXQ10) || (reg_tab->arch == MAX))
2929 hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2930 break;
2931
2932 case bfd_mach_maxq20:
2933 if ((reg_tab->arch == MAXQ20) || (reg_tab->arch == MAX))
2934 {
2935 #endif
2936 hash_err =
2937 hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2938 #if MAXQ10S
2939 }
2940 break;
2941 default:
2942 as_fatal (_("Invalid architecture type"));
2943 }
2944 #endif
2945
2946 if (hash_err)
2947 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2948 reg_tab->reg_name, hash_err);
2949 }
2950
2951 /* Pheripheral Registers Entry. */
2952 for (reg_tab = new_reg_table;
2953 reg_tab < (new_reg_table + num_of_reg - 1); reg_tab++)
2954 {
2955 hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2956
2957 if (hash_err)
2958 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2959 reg_tab->reg_name, hash_err);
2960 }
2961
2962 /* Initialise a new memory operand table. */
2963 mem_hash = hash_new ();
2964
2965 for (memtab = mem_table;
2966 memtab < mem_table + ARRAY_SIZE (mem_table);
2967 memtab++)
2968 {
2969 hash_err = hash_insert (mem_hash, memtab->name, (PTR) memtab);
2970 if (hash_err)
2971 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2972 memtab->name, hash_err);
2973 }
2974
2975 bit_hash = hash_new ();
2976
2977 for (bittab = bit_table;
2978 bittab < bit_table + ARRAY_SIZE (bit_table);
2979 bittab++)
2980 {
2981 hash_err = hash_insert (bit_hash, bittab->name, (PTR) bittab);
2982 if (hash_err)
2983 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2984 bittab->name, hash_err);
2985 }
2986
2987 mem_syntax_hash = hash_new ();
2988
2989 for (memsyntab = mem_access_syntax_table;
2990 memsyntab < mem_access_syntax_table + ARRAY_SIZE (mem_access_syntax_table);
2991 memsyntab++)
2992 {
2993 hash_err =
2994 hash_insert (mem_syntax_hash, memsyntab->name, (PTR) memsyntab);
2995 if (hash_err)
2996 as_fatal (_("Internal Error : Can't Hash %s : %s"),
2997 memsyntab->name, hash_err);
2998 }
2999
3000 /* Initialise the lexical tables,mnemonic chars,operand chars. */
3001 for (c = 0; c < 256; c++)
3002 {
3003 if (ISDIGIT (c))
3004 {
3005 digit_chars[c] = c;
3006 mnemonic_chars[c] = c;
3007 operand_chars[c] = c;
3008 register_chars[c] = c;
3009 }
3010 else if (ISLOWER (c))
3011 {
3012 mnemonic_chars[c] = c;
3013 operand_chars[c] = c;
3014 register_chars[c] = c;
3015 }
3016 else if (ISUPPER (c))
3017 {
3018 mnemonic_chars[c] = TOLOWER (c);
3019 register_chars[c] = c;
3020 operand_chars[c] = c;
3021 }
3022
3023 if (ISALPHA (c) || ISDIGIT (c))
3024 {
3025 identifier_chars[c] = c;
3026 }
3027 else if (c > 128)
3028 {
3029 identifier_chars[c] = c;
3030 operand_chars[c] = c;
3031 }
3032 }
3033
3034 /* All the special characters. */
3035 register_chars['@'] = '@';
3036 register_chars['+'] = '+';
3037 register_chars['-'] = '-';
3038 digit_chars['-'] = '-';
3039 identifier_chars['_'] = '_';
3040 identifier_chars['.'] = '.';
3041 register_chars['['] = '[';
3042 register_chars[']'] = ']';
3043 operand_chars['_'] = '_';
3044 operand_chars['#'] = '#';
3045 mnemonic_chars['['] = '[';
3046 mnemonic_chars[']'] = ']';
3047
3048 for (p = operand_special_chars; *p != '\0'; p++)
3049 operand_chars[(unsigned char) *p] = (unsigned char) *p;
3050
3051 /* Set the maxq arch type. */
3052 maxq_target (max_version);
3053 }
3054
3055 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3056 menmunonic in the operand table - Parse operands and populate the
3057 structure/template - Match the operand with opcode and its validity -
3058 Output Instr. */
3059
3060 void
3061 md_assemble (char *line)
3062 {
3063 int j;
3064
3065 char mnemonic[MAX_MNEM_SIZE];
3066 char temp4prev[256];
3067 static char prev_insn[256];
3068
3069 /* Initialize globals. */
3070 memset (&i, '\0', sizeof (i));
3071 for (j = 0; j < MAX_OPERANDS; j++)
3072 i.reloc[j] = NO_RELOC;
3073
3074 i.prefix = -1;
3075 PFX_INSN[0] = 0;
3076 PFX_INSN[1] = 0;
3077 INSERT_BUFFER[0] = 0;
3078 INSERT_BUFFER[1] = 0;
3079
3080 memcpy (temp4prev, line, strlen (line) + 1);
3081
3082 save_stack_p = save_stack;
3083
3084 line = (char *) parse_insn (line, mnemonic);
3085 if (line == NULL)
3086 return;
3087
3088 line = (char *) parse_operands (line, mnemonic);
3089 if (line == NULL)
3090 return;
3091
3092 /* Next, we find a template that matches the given insn, making sure the
3093 overlap of the given operands types is consistent with the template
3094 operand types. */
3095 if (!match_template ())
3096 return;
3097
3098 /* In the MAXQ20, there are certain register combinations, and other
3099 restrictions which are not allowed. We will try to resolve these right
3100 now. */
3101 if (!match_filters ())
3102 return;
3103
3104 /* Check for the approprate PFX register. */
3105 set_prefix ();
3106 pfx_for_imm_val (0);
3107
3108 if (!decode_insn ()) /* decode insn. */
3109 need_pass_2 = 1;
3110
3111 /* Check for Exlipct PFX instruction. */
3112 if (PFX_INSN[0] && (strstr (prev_insn, "PFX") || strstr (prev_insn, "pfx")))
3113 as_warn (_("Ineffective insntruction %s \n"), prev_insn);
3114
3115 memcpy (prev_insn, temp4prev, strlen (temp4prev) + 1);
3116
3117 /* We are ready to output the insn. */
3118 output_insn ();
3119 }
This page took 0.094633 seconds and 4 git commands to generate.