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