Initial revision
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
1 /* tc-h8300.c -- Assemble code for the Hitachi h8/300
2 Copyright (C) 1991 Free Software Foundation.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 /*
22 Written By Steve Chamberlain
23 steve@cygnus.com
24 */
25
26 #include <stdio.h>
27 #include "as.h"
28 #include "bfd.h"
29 #include "h8300-opcode.h"
30 #include <ctype.h>
31
32 char comment_chars[] = { ';',0 };
33
34 /* This table describes all the machine specific pseudo-ops the assembler
35 has to support. The fields are:
36 pseudo-op name without dot
37 function to call to execute this pseudo-op
38 Integer arg to pass to the function
39 */
40 const pseudo_typeS md_pseudo_table[] = {
41 { 0, 0, 0 }
42 };
43
44 int md_reloc_size ;
45
46 const char EXP_CHARS[] = "eE";
47
48 /* Chars that mean this number is a floating point constant */
49 /* As in 0f12.456 */
50 /* or 0d1.2345e12 */
51 char FLT_CHARS[] = "rRsSfFdDxXpP";
52
53
54 const relax_typeS md_relax_table[1];
55
56
57 static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
58 static struct hash_control *register_hash_control; /* Register name hash table */
59
60
61 /*
62 This function is called once, at assembler startup time. This should
63 set up all the tables, etc that the MD part of the assembler needs
64 */
65
66 reloc_howto_type *r16;
67 reloc_howto_type *r8;
68 reloc_howto_type *r8ff;
69 reloc_howto_type *r8pcrel;
70
71 void md_begin ()
72 {
73 bfd_arch_info_struct_type *ai;
74 const struct h8_opcode *opcode;
75
76 opcode_hash_control = hash_new();
77 for (opcode = h8_opcodes; opcode->name; opcode++) {
78 hash_insert(opcode_hash_control, opcode->name, (char *)opcode);
79 }
80
81 ai = bfd_lookup_arch(bfd_arch_h8300,0);
82
83 r16 = ai->reloc_type_lookup(ai, BFD_RELOC_16);
84 r8 = ai->reloc_type_lookup(ai, BFD_RELOC_8);
85 r8ff = ai->reloc_type_lookup(ai, BFD_RELOC_8_FFnn);
86 r8pcrel = ai->reloc_type_lookup(ai, BFD_RELOC_8_PCREL);
87
88
89 }
90
91
92 struct h8_exp {
93 char *e_beg;
94 char *e_end;
95 expressionS e_exp;
96 };
97 struct h8_op
98 {
99 op_enum_type mode;
100 unsigned reg;
101 expressionS exp;
102 };
103
104
105
106 /*
107 parse operands
108 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
109 r0l,r0h,..r7l,r7h
110 @WREG
111 @WREG+
112 @-WREG
113 #const
114
115 */
116
117 op_enum_type r8_sord[] = {RS8, RD8};
118 op_enum_type r16_sord[] = {RS16, RD16};
119 op_enum_type rind_sord[] = {RSIND, RDIND};
120 op_enum_type abs_sord[2] = {ABS16SRC, ABS16DST};
121 op_enum_type disp_sord[] = {DISPSRC, DISPDST};
122 /* try and parse a reg name, returns number of chars consumed */
123 int DEFUN(parse_reg,(src, mode, reg, dst),
124 char *src AND
125 op_enum_type *mode AND
126 unsigned int *reg AND
127 int dst)
128 {
129 if (src[0] == 's' && src[1] == 'p') {
130 *mode = r16_sord[dst];
131 *reg = 7;
132 return 2;
133 }
134 if (src[0] == 'c' && src[1] == 'c' && src[2] == 'r') {
135 *mode = CCR;
136 *reg = 0;
137 return 3;
138 }
139 if (src[0] == 'f' && src[1] == 'p') {
140 *mode = r16_sord[dst];
141 *reg = 6;
142 return 2;
143 }
144 if (src[0] == 'r') {
145 if (src[1] >= '0' && src[1] <= '7') {
146 if(src[2] == 'l') {
147 *mode = r8_sord[dst];
148 *reg = (src[1] - '0') + 8;
149 return 3;
150 }
151 if(src[2] == 'h') {
152 *mode = r8_sord[dst];
153 *reg = (src[1] - '0') ;
154 return 3;
155 }
156 *mode = r16_sord[dst];
157 *reg = (src[1] - '0');
158 return 2;
159 }
160 }
161 return 0;
162 }
163
164 char *
165 DEFUN(parse_exp,(s, op),
166 char *s AND
167 expressionS *op)
168 {
169 char *save = input_line_pointer;
170 char *new;
171 segT seg;
172 input_line_pointer = s;
173 seg = expr(0,op);
174 new = input_line_pointer;
175 input_line_pointer = save;
176 if (SEG_NORMAL(seg))
177 return new;
178 switch (seg) {
179 case SEG_ABSOLUTE:
180 case SEG_UNKNOWN:
181 case SEG_DIFFERENCE:
182 case SEG_BIG:
183 case SEG_REGISTER:
184 return new;
185 case SEG_ABSENT:
186 as_bad("Missing operand");
187 return new;
188 default:
189 as_bad("Don't understand operand of type %s", segment_name (seg));
190 return new;
191 }
192 }
193
194
195 static void
196 DEFUN(get_operand,(ptr, op, dst),
197 char **ptr AND
198 struct h8_op *op AND
199 unsigned int dst)
200 {
201 char *src = *ptr;
202 op_enum_type mode;
203 unsigned int num;
204 unsigned int len;
205 op->mode = E;
206
207 while (*src == ' ') src++;
208 len = parse_reg(src, &op->mode, &op->reg, dst);
209 if (len) {
210 *ptr = src + len;
211 return ;
212 }
213
214 if (*src == '@') {
215 src++;
216 if (*src == '-') {
217 src++;
218 len = parse_reg(src, &mode, &num, dst);
219 if (len == 0 || mode != r16_sord[dst]) {
220 as_bad("@- needs word register");
221 }
222 op->mode = RDDEC;
223 op->reg = num;
224 *ptr = src + len;
225 return;
226 }
227 if (*src == '(' && ')') {
228 /* Disp */
229 src++;
230 src = parse_exp(src, &op->exp);
231
232 if (*src == ')') {
233 src++;
234 op->mode = abs_sord[dst];
235 *ptr = src;
236 return;
237 }
238 if (*src != ',') {
239 as_bad("expected @(exp, reg16)");
240 }
241 src++;
242 len = parse_reg(src, &mode, &op->reg, dst);
243 if (len == 0 || mode != r16_sord[dst])
244 {
245 as_bad("expected @(exp, reg16)");
246 }
247 op->mode = disp_sord[dst];
248 src += len;
249 if (*src != ')' && '(') {
250 as_bad("expected @(exp, reg16)");
251
252 }
253 *ptr = src +1;
254
255 return;
256 }
257 len = parse_reg(src, &mode, &num, dst);
258
259 if(len) {
260 src += len;
261 if (*src == '+') {
262 src++;
263 if (mode != RS16) {
264 as_bad("@Rn+ needs word register");
265 }
266 op->mode = RSINC;
267 op->reg = num;
268 *ptr = src;
269 return;
270 }
271 if (mode != r16_sord[dst]) {
272 as_bad("@Rn needs word register");
273 }
274 op->mode =rind_sord[dst];
275 op->reg = num;
276 *ptr = src;
277 return;
278 }
279 else {
280 /* must be a symbol */
281 op->mode = abs_sord[dst];
282 *ptr = parse_exp(src, &op->exp);
283 return;
284 }
285 }
286
287
288 if (*src == '#') {
289 src++;
290 op->mode = IMM16;
291 *ptr = parse_exp(src, &op->exp);
292 return;
293 }
294 else {
295 *ptr = parse_exp(src, &op->exp);
296 op->mode = DISP8;
297 }
298 }
299
300 /* This is the guts of the machine-dependent assembler. STR points to a
301 machine dependent instruction. This funciton is supposed to emit
302 the frags/bytes it assembles to.
303 */
304
305
306 void
307 DEFUN(md_assemble,(str),
308 char *str)
309 {
310 char *op_start;
311 char *op_end;
312 struct h8_opcode * opcode;
313 /* Drop leading whitespace */
314 while (*str == ' ')
315 str++;
316
317
318 /* find the op code end */
319 for (op_start = op_end = str;
320 *op_end != 0 && *op_end != ' ';
321 op_end ++)
322 ;
323
324 if (op_end == op_start) {
325 as_bad("can't find opcode ");
326 }
327 *op_end = 0;
328 opcode = (struct h8_opcode *) hash_find(opcode_hash_control,
329 op_start);
330
331 if (opcode == NULL) {
332 as_bad("unknown opcode");
333 return;
334 }
335
336
337 {
338 int ok = 1;
339 int j,i;
340 int dispreg = 0;
341 struct h8_op operand[2];
342 char *ptr = op_end+1;
343 if (opcode->noperands)
344 get_operand(& ptr, &operand[0],0);
345 else operand[0].mode = 0;
346 if (opcode->noperands==2) {
347 if (*ptr == ',') ptr++;
348 get_operand(& ptr, &operand[1], 1);
349 }
350 else operand[1].mode = 0;
351
352
353
354 {
355 struct h8_opcode *this_try ;
356 int found = 0;
357 for (j = 0; j < opcode->nopcodes && !found; j++) {
358 this_try = opcode + j;
359 for (i = 0; i < opcode->noperands; i++) {
360 op_enum_type op = (this_try->args.nib[i]) & ~(B30|B31);
361 switch (op) {
362 case Hex0:
363 case Hex1:
364 case Hex2:
365 case Hex3:
366 case Hex4:
367 case Hex5:
368 case Hex6:
369 case Hex7:
370 case Hex8:
371 case Hex9:
372 case HexA:
373 case HexB:
374 case HexC:
375 case HexD:
376 case HexE:
377 case HexF:
378 break;
379 case DISPSRC:
380 case DISPDST:
381 dispreg = operand[i].reg;
382 case RD8:
383 case RS8:
384 case RDIND:
385 case RSIND:
386 case RD16:
387 case RS16:
388 case CCR:
389 case RSINC:
390 case RDDEC:
391 if (operand[i].mode != op) goto fail;
392 break;
393 case KBIT:
394 case IMM8:
395 case IMM16:
396 case IMM3:
397 if (operand[i].mode != IMM16) goto fail;
398 break;
399 case ABS16SRC:
400 case ABS8SRC:
401 if (operand[i].mode != ABS16SRC) goto fail;
402 break;
403 case ABS16DST:
404 case ABS8DST:
405 if (operand[i].mode != ABS16DST) goto fail;
406
407 break;
408 }
409 }
410 found =1;
411 fail: ;
412 }
413 if (found == 0)
414 as_bad("illegal operands for opcode");
415
416
417 /* Now we know what sort of opcodes etc, lets build the bytes -
418 actually we know how big the instruction will be too. So we
419 can get
420 */
421 {
422 char *output = frag_more(this_try->length);
423 char *output_ptr = output;
424 op_enum_type *nibble_ptr = this_try->data.nib;
425 char part;
426 op_enum_type c;
427 char high;
428 int nib;
429 top: ;
430 while (*nibble_ptr != E) {
431 int nibble;
432 for (nibble = 0; nibble <2; nibble++) {
433 c = *nibble_ptr & ~(B30|B31);
434 switch (c) {
435 default:
436 abort();
437
438 case 0:
439 case 1:
440 case 2: case 3: case 4: case 5: case 6:
441 case 7: case 8: case 9: case 10: case 11:
442 case 12: case 13: case 14: case 15:
443 nib = c;
444 break;
445 case DISPREG:
446 nib = dispreg;
447 break;
448 case IMM8:
449 /* if no symbol then put value in place */
450 if (operand[0].exp.X_add_symbol == 0) {
451 operand[0].mode = 0; /* stop it making a fix */
452 *output_ptr++ = (operand[0].exp.X_add_number);
453 nibble_ptr += 2;
454 goto top;
455 }
456 nib = 0;
457 break;
458
459 case DISPDST:
460 /* if no symbol then put value in place */
461 if (operand[1].exp.X_add_symbol == 0) {
462 operand[1].mode = 0; /* stop it making a fix */
463 *output_ptr++ =(operand[1].exp.X_add_number)>>8;
464 *output_ptr++ = (operand[1].exp.X_add_number);
465 nibble_ptr += 4;
466 goto top;
467 }
468
469 nib = 0;
470 break;
471 case IMM3:
472
473 if (operand[0].exp.X_add_symbol == 0) {
474 operand[0].mode = 0; /* stop it making a fix */
475 nib = (operand[0].exp.X_add_number);
476 }
477 else as_bad("can't have symbol for bit number");
478 break;
479
480 case DISPSRC:
481 case IMM16:
482 /* if no symbol then put value in place */
483 if (operand[0].exp.X_add_symbol == 0) {
484 operand[0].mode = 0; /* stop it making a fix */
485 *output_ptr++ =(operand[0].exp.X_add_number)>>8;
486 *output_ptr++ = (operand[0].exp.X_add_number);
487 nibble_ptr += 4;
488 goto top;
489 }
490
491
492 case ABS16SRC:
493 case ABS16DST:
494
495 case ABS8DST:
496 case ABS8SRC:
497 case IGNORE:
498
499
500 nib = 0;
501 break;
502 case DISP8:
503 nib = 0;
504 break;
505
506
507 case RS8:
508 case RS16:
509 case RSIND:
510 case RSINC:
511 case RDIND:
512 nib= operand[0].reg;
513 break;
514 case RD8:
515 case RD16:
516 case RDDEC:
517 nib = operand[1].reg;
518
519 break;
520 case E:
521 abort();
522 break;
523 }
524 if (*nibble_ptr & B31) nib|=0x8;
525 if (nibble == 0) {
526 *output_ptr = nib << 4;
527 }
528 else {
529 *output_ptr |= nib;
530 output_ptr++;
531 }
532 nibble_ptr++;
533 }
534
535 }
536
537 /* output any fixes */
538 {
539 int i;
540 for (i = 0; i < 2; i++) {
541 switch (operand[i].mode) {
542 case 0:
543 break;
544 case DISP8:
545 fix_new(frag_now,
546 output+1,
547 1,
548 operand[i].exp.X_add_symbol,
549 operand[i].exp.X_subtract_symbol,
550 operand[i].exp.X_add_number,
551 0,
552 (int)r8pcrel);
553 break;
554 case ABS16SRC:
555 case ABS16DST:
556 case IMM16:
557 case DISPSRC:
558 case DISPDST:
559 fix_new(frag_now,
560 output+2,
561 2,
562 operand[i].exp.X_add_symbol,
563 operand[i].exp.X_subtract_symbol,
564 operand[i].exp.X_add_number,
565 0,
566 (int)r16);
567 break;
568 case RS8:
569 case RD8:
570 case RS16:
571 case RD16:
572 case RDDEC:
573 case RSINC:
574 case RDIND:
575 case RSIND:
576 break;
577 default:
578 abort();
579 }
580 }
581 }
582
583 }
584 }
585 }
586 }
587
588 void
589 DEFUN(tc_crawl_symbol_chain, (headers),
590 object_headers *headers)
591 {
592 printf("call to tc_crawl_symbol_chain \n");
593 }
594
595 symbolS *DEFUN(md_undefined_symbol,(name),
596 char *name)
597 {
598 return 0;
599 }
600
601 void
602 DEFUN(tc_headers_hook,(headers),
603 object_headers *headers)
604 {
605 printf("call to tc_headers_hook \n");
606 }
607 void
608 DEFUN_VOID(md_end)
609 {
610 }
611
612 /* Various routines to kill one day */
613
614 char *md_atof () { printf("call to md_atof \n"); abort(); }
615 int md_parse_option () { printf("call to md_parse_option \n"); abort(); }
616
617 int md_short_jump_size;
618
619 void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n");
620 abort(); }
621 void md_create_long_jump () { printf("call to md_create_long_jump \n");
622 abort(); }
623 void md_convert_frag () { printf("call to md_convert_frag \n"); abort(); }
624
625 long
626 DEFUN(md_section_align,(seg, size),
627 segT seg AND
628 long size)
629 {
630 return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
631
632 }
633
634 void md_apply_fix () { printf("call to md_apply_fix \n"); abort(); }
635
636 void DEFUN(md_operand, (expressionP),expressionS *expressionP)
637 { }
638
639 int md_long_jump_size;
640 int md_estimate_size_before_relax () { printf("call tomd_estimate_size_before_relax \n"); abort(); }
641 /* Put number into target byte order */
642 void DEFUN(md_number_to_chars,(ptr, use, nbytes),
643 char *ptr AND
644 int use AND
645 unsigned int nbytes)
646 {
647 switch (nbytes) {
648 case 4: *ptr++ = (use >> 24) & 0xff;
649 case 3: *ptr++ = (use >> 16) & 0xff;
650 case 2: *ptr++ = (use >> 8) & 0xff;
651 case 1: *ptr++ = (use >> 0) & 0xff;
652 break;
653 default:
654 abort();
655 }
656 }
657
658 long md_pcrel_from () { printf("call to md_pcrel_from \n"); abort(); }
659 void md_create_short_jump () { printf("call to md_create_short_jump \n");
660 abort(); }
661
662 void tc_coff_symbol_emit_hook() { }
This page took 0.042978 seconds and 5 git commands to generate.