1 /* tc-h8300.c -- Assemble code for the Hitachi h8/300
2 Copyright (C) 1991 Free Software Foundation.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
22 Written By Steve Chamberlain
29 #include "h8300-opcode.h"
32 char comment_chars
[] = { ';',0 };
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
40 const pseudo_typeS md_pseudo_table
[] = {
46 const char EXP_CHARS
[] = "eE";
48 /* Chars that mean this number is a floating point constant */
51 char FLT_CHARS
[] = "rRsSfFdDxXpP";
54 const relax_typeS md_relax_table
[1];
57 static struct hash_control
*opcode_hash_control
; /* Opcode mnemonics */
58 static struct hash_control
*register_hash_control
; /* Register name hash table */
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
66 reloc_howto_type
*r16
;
68 reloc_howto_type
*r8ff
;
69 reloc_howto_type
*r8pcrel
;
73 bfd_arch_info_struct_type
*ai
;
74 const struct h8_opcode
*opcode
;
76 opcode_hash_control
= hash_new();
77 for (opcode
= h8_opcodes
; opcode
->name
; opcode
++) {
78 hash_insert(opcode_hash_control
, opcode
->name
, (char *)opcode
);
81 ai
= bfd_lookup_arch(bfd_arch_h8300
,0);
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
);
108 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
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
),
125 op_enum_type
*mode AND
126 unsigned int *reg AND
129 if (src
[0] == 's' && src
[1] == 'p') {
130 *mode
= r16_sord
[dst
];
134 if (src
[0] == 'c' && src
[1] == 'c' && src
[2] == 'r') {
139 if (src
[0] == 'f' && src
[1] == 'p') {
140 *mode
= r16_sord
[dst
];
145 if (src
[1] >= '0' && src
[1] <= '7') {
147 *mode
= r8_sord
[dst
];
148 *reg
= (src
[1] - '0') + 8;
152 *mode
= r8_sord
[dst
];
153 *reg
= (src
[1] - '0') ;
156 *mode
= r16_sord
[dst
];
157 *reg
= (src
[1] - '0');
165 DEFUN(parse_exp
,(s
, op
),
169 char *save
= input_line_pointer
;
172 input_line_pointer
= s
;
174 new = input_line_pointer
;
175 input_line_pointer
= save
;
186 as_bad("Missing operand");
189 as_bad("Don't understand operand of type %s", segment_name (seg
));
196 DEFUN(get_operand
,(ptr
, op
, dst
),
207 while (*src
== ' ') src
++;
208 len
= parse_reg(src
, &op
->mode
, &op
->reg
, dst
);
218 len
= parse_reg(src
, &mode
, &num
, dst
);
219 if (len
== 0 || mode
!= r16_sord
[dst
]) {
220 as_bad("@- needs word register");
227 if (*src
== '(' && ')') {
230 src
= parse_exp(src
, &op
->exp
);
234 op
->mode
= abs_sord
[dst
];
239 as_bad("expected @(exp, reg16)");
242 len
= parse_reg(src
, &mode
, &op
->reg
, dst
);
243 if (len
== 0 || mode
!= r16_sord
[dst
])
245 as_bad("expected @(exp, reg16)");
247 op
->mode
= disp_sord
[dst
];
249 if (*src
!= ')' && '(') {
250 as_bad("expected @(exp, reg16)");
257 len
= parse_reg(src
, &mode
, &num
, dst
);
264 as_bad("@Rn+ needs word register");
271 if (mode
!= r16_sord
[dst
]) {
272 as_bad("@Rn needs word register");
274 op
->mode
=rind_sord
[dst
];
280 /* must be a symbol */
281 op
->mode
= abs_sord
[dst
];
282 *ptr
= parse_exp(src
, &op
->exp
);
291 *ptr
= parse_exp(src
, &op
->exp
);
295 *ptr
= parse_exp(src
, &op
->exp
);
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.
307 DEFUN(md_assemble
,(str
),
312 struct h8_opcode
* opcode
;
313 /* Drop leading whitespace */
318 /* find the op code end */
319 for (op_start
= op_end
= str
;
320 *op_end
!= 0 && *op_end
!= ' ';
324 if (op_end
== op_start
) {
325 as_bad("can't find opcode ");
328 opcode
= (struct h8_opcode
*) hash_find(opcode_hash_control
,
331 if (opcode
== NULL
) {
332 as_bad("unknown opcode");
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);
350 else operand
[1].mode
= 0;
355 struct h8_opcode
*this_try
;
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
);
381 dispreg
= operand
[i
].reg
;
391 if (operand
[i
].mode
!= op
) goto fail
;
397 if (operand
[i
].mode
!= IMM16
) goto fail
;
401 if (operand
[i
].mode
!= ABS16SRC
) goto fail
;
405 if (operand
[i
].mode
!= ABS16DST
) goto fail
;
414 as_bad("illegal operands for opcode");
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
422 char *output
= frag_more(this_try
->length
);
423 char *output_ptr
= output
;
424 op_enum_type
*nibble_ptr
= this_try
->data
.nib
;
430 while (*nibble_ptr
!= E
) {
432 for (nibble
= 0; nibble
<2; nibble
++) {
433 c
= *nibble_ptr
& ~(B30
|B31
);
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:
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
);
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
);
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
);
477 else as_bad("can't have symbol for bit number");
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
);
517 nib
= operand
[1].reg
;
524 if (*nibble_ptr
& B31
) nib
|=0x8;
526 *output_ptr
= nib
<< 4;
537 /* output any fixes */
540 for (i
= 0; i
< 2; i
++) {
541 switch (operand
[i
].mode
) {
548 operand
[i
].exp
.X_add_symbol
,
549 operand
[i
].exp
.X_subtract_symbol
,
550 operand
[i
].exp
.X_add_number
,
562 operand
[i
].exp
.X_add_symbol
,
563 operand
[i
].exp
.X_subtract_symbol
,
564 operand
[i
].exp
.X_add_number
,
589 DEFUN(tc_crawl_symbol_chain
, (headers
),
590 object_headers
*headers
)
592 printf("call to tc_crawl_symbol_chain \n");
595 symbolS
*DEFUN(md_undefined_symbol
,(name
),
602 DEFUN(tc_headers_hook
,(headers
),
603 object_headers
*headers
)
605 printf("call to tc_headers_hook \n");
612 /* Various routines to kill one day */
614 char *md_atof () { printf("call to md_atof \n"); abort(); }
615 int md_parse_option () { printf("call to md_parse_option \n"); abort(); }
617 int md_short_jump_size
;
619 void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n");
621 void md_create_long_jump () { printf("call to md_create_long_jump \n");
623 void md_convert_frag () { printf("call to md_convert_frag \n"); abort(); }
626 DEFUN(md_section_align
,(seg
, size
),
630 return((size
+ (1 << section_alignment
[(int) seg
]) - 1) & (-1 << section_alignment
[(int) seg
]));
634 void md_apply_fix () { printf("call to md_apply_fix \n"); abort(); }
636 void DEFUN(md_operand
, (expressionP
),expressionS
*expressionP
)
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
),
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;
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");
662 void tc_coff_symbol_emit_hook() { }