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