binutils-gdb/gas/config/tc-h8500.c

1656 lines
32 KiB
C
Raw Normal View History

/* tc-h8500.c -- Assemble code for the Hitachi H8/500
Copyright (C) 1993 Free Software Foundation.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
Written By Steve Chamberlain
sac@cygnus.com
*/
#include <stdio.h>
#include "as.h"
#include "bfd.h"
1993-03-29 23:45:50 +02:00
#include "subsegs.h"
#define DEFINE_TABLE
1993-03-29 23:45:50 +02:00
#define ASSEMBLER_TABLE
#include "../opcodes/h8500-opc.h"
#include <ctype.h>
1993-03-29 23:45:50 +02:00
const char comment_chars[] = "!";
const char line_separator_chars[] = ";";
const char line_comment_chars[] = "!#";
/* This table describes all the machine specific pseudo-ops the assembler
has to support. The fields are:
pseudo-op name without dot
function to call to execute this pseudo-op
Integer arg to pass to the function
*/
void cons ();
const pseudo_typeS md_pseudo_table[] =
{
{"int", cons, 2},
{"data.b", cons, 1},
{"data.w", cons, 2},
{"data.l", cons, 4},
{"form", listing_psize, 0},
{"heading", listing_title, 0},
{"import", s_ignore, 0},
{"page", listing_eject, 0},
{"program", s_ignore, 0},
{0, 0, 0}
};
const int md_reloc_size;
const char EXP_CHARS[] = "eE";
/* Chars that mean this number is a floating point constant */
/* As in 0f12.456 */
/* or 0d1.2345e12 */
const char FLT_CHARS[] = "rRsSfFdDxXpP";
#define C(a,b) ENCODE_RELAX(a,b)
#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
#define GET_WHAT(x) ((x>>2))
#define BYTE_DISP 1
#define WORD_DISP 2
#define UNDEF_BYTE_DISP 0
#define UNDEF_WORD_DISP 3
#define BRANCH 1
#define SCB_F 2
#define SCB_TST 3
#define END 4
#define BYTE_F 127
#define BYTE_B -126
#define WORD_F 32767
#define WORD_B 32768
1993-07-02 03:33:33 +02:00
const relax_typeS md_relax_table[C (END, 0)];
static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
/*
This function is called once, at assembler startup time. This should
set up all the tables, etc that the MD part of the assembler needs
*/
void
md_begin ()
{
h8500_opcode_info *opcode;
char prev_buffer[100];
int idx = 0;
register relax_typeS *table;
opcode_hash_control = hash_new ();
prev_buffer[0] = 0;
/* Insert unique names into hash table */
for (opcode = h8500_table; opcode->name; opcode++)
{
if (idx != opcode->idx)
{
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
idx++;
}
}
/* Initialize the relax table. We use a local variable to avoid
warnings about modifying a supposedly const data structure. */
table = (relax_typeS *) md_relax_table;
table[C (BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
table[C (BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
table[C (BRANCH, BYTE_DISP)].rlx_length = 2;
table[C (BRANCH, BYTE_DISP)].rlx_more = C (BRANCH, WORD_DISP);
table[C (BRANCH, WORD_DISP)].rlx_forward = WORD_F;
table[C (BRANCH, WORD_DISP)].rlx_backward = WORD_B;
table[C (BRANCH, WORD_DISP)].rlx_length = 3;
table[C (BRANCH, WORD_DISP)].rlx_more = 0;
table[C (SCB_F, BYTE_DISP)].rlx_forward = BYTE_F;
table[C (SCB_F, BYTE_DISP)].rlx_backward = BYTE_B;
table[C (SCB_F, BYTE_DISP)].rlx_length = 3;
table[C (SCB_F, BYTE_DISP)].rlx_more = C (SCB_F, WORD_DISP);
table[C (SCB_F, WORD_DISP)].rlx_forward = WORD_F;
table[C (SCB_F, WORD_DISP)].rlx_backward = WORD_B;
table[C (SCB_F, WORD_DISP)].rlx_length = 8;
table[C (SCB_F, WORD_DISP)].rlx_more = 0;
table[C (SCB_TST, BYTE_DISP)].rlx_forward = BYTE_F;
table[C (SCB_TST, BYTE_DISP)].rlx_backward = BYTE_B;
table[C (SCB_TST, BYTE_DISP)].rlx_length = 3;
table[C (SCB_TST, BYTE_DISP)].rlx_more = C (SCB_TST, WORD_DISP);
table[C (SCB_TST, WORD_DISP)].rlx_forward = WORD_F;
table[C (SCB_TST, WORD_DISP)].rlx_backward = WORD_B;
table[C (SCB_TST, WORD_DISP)].rlx_length = 10;
table[C (SCB_TST, WORD_DISP)].rlx_more = 0;
}
1993-03-29 23:45:50 +02:00
static int rn; /* register number used by RN */
static int rs; /* register number used by RS */
static int rd; /* register number used by RD */
static int crb; /* byte size cr */
static int crw; /* word sized cr */
static int cr; /* unknown size cr */
1993-03-29 23:45:50 +02:00
static expressionS displacement;/* displacement expression */
static int displacement_size; /* and size if given */
1993-03-29 23:45:50 +02:00
static int immediate_inpage;
static expressionS immediate; /* immediate expression */
static int immediate_size; /* and size if given */
1993-03-29 23:45:50 +02:00
static expressionS absolute; /* absolute expression */
static int absolute_size; /* and size if given */
typedef struct
{
int type;
int reg;
expressionS exp;
int page;
}
h8500_operand_info;
/* try and parse a reg name, returns number of chars consumed */
1993-03-29 23:45:50 +02:00
static int
parse_reg (src, mode, reg)
char *src;
int *mode;
1993-03-29 23:45:50 +02:00
int *reg;
{
if (src[0] == 'r')
{
if (src[1] >= '0' && src[1] <= '7')
{
*mode = RN;
*reg = (src[1] - '0');
return 2;
}
}
if (src[0] == 's' && src[1] == 'p')
{
*mode = RN;
*reg = 7;
return 2;
}
if (src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
{
*mode = CRB;
*reg = 1;
return 3;
}
if (src[0] == 's' && src[1] == 'r')
{
*mode = CRW;
*reg = 0;
return 2;
}
if (src[0] == 'b' && src[1] == 'r')
{
*mode = CRB;
*reg = 3;
return 2;
}
if (src[0] == 'e' && src[1] == 'p')
{
*mode = CRB;
*reg = 4;
return 2;
}
if (src[0] == 'd' && src[1] == 'p')
{
*mode = CRB;
*reg = 5;
return 2;
}
if (src[0] == 't' && src[1] == 'p')
{
1993-03-29 23:45:50 +02:00
*mode = CRB;
*reg = 7;
return 2;
}
if (src[0] == 'f' && src[1] == 'p')
{
*mode = RN;
*reg = 6;
return 2;
}
return 0;
}
1993-03-29 23:45:50 +02:00
static
char *
parse_exp (s, op, page)
char *s;
expressionS *op;
1993-03-29 23:45:50 +02:00
int *page;
{
1993-03-29 23:45:50 +02:00
char *save;
char *new;
save = input_line_pointer;
1993-03-29 23:45:50 +02:00
*page = 0;
if (s[0] == '%')
1993-03-29 23:45:50 +02:00
{
if (s[1] == 'p' && s[2] == 'a' && s[3] == 'g' && s[4] == 'e')
{
s += 5;
*page = 'p';
}
if (s[1] == 'h' && s[2] == 'i' && s[3] == '1' && s[4] == '6')
{
s += 5;
*page = 'h';
}
1993-03-29 23:45:50 +02:00
else if (s[1] == 'o' && s[2] == 'f' && s[3] == 'f')
{
s += 4;
*page = 'o';
}
}
input_line_pointer = s;
expression (op);
if (op->X_op == O_absent)
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
as_bad ("missing operand");
new = input_line_pointer;
input_line_pointer = save;
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
return new;
}
1993-03-29 23:45:50 +02:00
typedef enum
{
exp_signed, exp_unsigned, exp_sandu
} sign_type;
static char *
1993-03-29 23:45:50 +02:00
skip_colonthing (sign, ptr, exp, def, size8, size16, size24)
sign_type sign;
char *ptr;
h8500_operand_info *exp;
int def;
int size8;
int size16;
int size24;
{
ptr = parse_exp (ptr, &exp->exp, &exp->page);
if (*ptr == ':')
{
ptr++;
1993-03-29 23:45:50 +02:00
if (*ptr == '8')
{
ptr++;
exp->type = size8;
}
else if (ptr[0] == '1' & ptr[1] == '6')
{
ptr += 2;
exp->type = size16;
}
else if (ptr[0] == '2' & ptr[1] == '4')
{
if (!size24)
{
as_bad (":24 not valid for this opcode");
}
ptr += 2;
exp->type = size24;
}
else
{
as_bad ("expect :8,:16 or :24");
exp->type = size16;
}
}
else
1993-03-29 23:45:50 +02:00
{
if (exp->page == 'p')
{
exp->type = IMM8;
}
else if (exp->page == 'h')
{
exp->type = IMM16;
}
else
1993-03-29 23:45:50 +02:00
{
/* Let's work out the size from the context */
int n = exp->exp.X_add_number;
if (size8
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
&& exp->exp.X_op == O_constant
1993-03-29 23:45:50 +02:00
&& ((sign == exp_signed && (n >= -128 && n <= 127))
|| (sign == exp_unsigned && (n >= 0 && (n <= 255)))
|| (sign == exp_sandu && (n >= -128 && (n <= 255)))))
{
exp->type = size8;
}
else
{
exp->type = def;
}
}
}
return ptr;
}
static int
1993-03-29 23:45:50 +02:00
parse_reglist (src, op)
char *src;
h8500_operand_info *op;
{
int mode;
int rn;
int mask = 0;
int rm;
int idx = 1; /* skip ( */
1993-03-29 23:45:50 +02:00
while (src[idx] && src[idx] != ')')
{
1993-03-29 23:45:50 +02:00
int done = parse_reg (src + idx, &mode, &rn);
if (done)
{
idx += done;
mask |= 1 << rn;
}
else
{
as_bad ("syntax error in reg list");
return 0;
}
if (src[idx] == '-')
{
idx++;
done = parse_reg (src + idx, &mode, &rm);
if (done)
{
idx += done;
while (rn <= rm)
{
mask |= 1 << rn;
rn++;
}
}
else
{
as_bad ("missing final register in range");
}
}
1993-03-29 23:45:50 +02:00
if (src[idx] == ',')
idx++;
}
idx++;
op->exp.X_add_symbol = 0;
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
op->exp.X_op_symbol = 0;
op->exp.X_add_number = mask;
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
op->exp.X_op = O_constant;
op->exp.X_unsigned = 1;
1993-03-29 23:45:50 +02:00
op->type = IMM8;
return idx;
}
1993-03-29 23:45:50 +02:00
/* The many forms of operand:
Rn Register direct
@Rn Register indirect
@(disp[:size], Rn) Register indirect with displacement
@Rn+
@-Rn
@aa[:size] absolute
#xx[:size] immediate data
*/
static void
1993-03-29 23:45:50 +02:00
get_operand (ptr, op, ispage)
char **ptr;
h8500_operand_info *op;
1993-03-29 23:45:50 +02:00
char ispage;
{
char *src = *ptr;
int mode;
unsigned int num;
unsigned int len;
op->page = 0;
if (src[0] == '(' && src[1] == 'r')
1993-03-29 23:45:50 +02:00
{
/* This is a register list */
*ptr = src + parse_reglist (src, op);
return;
}
len = parse_reg (src, &op->type, &op->reg);
if (len)
{
*ptr = src + len;
return;
}
if (*src == '@')
{
src++;
if (*src == '-')
{
src++;
len = parse_reg (src, &mode, &num);
if (len == 0)
{
/* Oops, not a reg after all, must be ordinary exp */
src--;
/* must be a symbol */
1993-03-29 23:45:50 +02:00
*ptr = skip_colonthing (exp_unsigned, src,
op, ABS16, ABS8, ABS16, ABS24);
return;
}
op->type = RNDEC;
op->reg = num;
*ptr = src + len;
return;
}
if (*src == '(')
{
/* Disp */
src++;
1993-03-29 23:45:50 +02:00
src = skip_colonthing (exp_signed, src,
op, RNIND_D16, RNIND_D8, RNIND_D16, 0);
if (*src != ',')
{
as_bad ("expected @(exp, Rn)");
return;
}
src++;
len = parse_reg (src, &mode, &op->reg);
if (len == 0 || mode != RN)
{
as_bad ("expected @(exp, Rn)");
return;
}
src += len;
if (*src != ')')
{
as_bad ("expected @(exp, Rn)");
return;
}
*ptr = src + 1;
return;
}
len = parse_reg (src, &mode, &num);
if (len)
{
src += len;
if (*src == '+')
{
src++;
if (mode != RN)
{
as_bad ("@Rn+ needs word register");
return;
}
op->type = RNINC;
op->reg = num;
*ptr = src;
return;
}
if (mode != RN)
{
as_bad ("@Rn needs word register");
return;
}
op->type = RNIND;
op->reg = num;
*ptr = src;
return;
}
else
{
/* must be a symbol */
1993-03-29 23:45:50 +02:00
*ptr =
skip_colonthing (exp_unsigned, src, op,
ispage ? ABS24 : ABS16, ABS8, ABS16, ABS24);
return;
}
}
if (*src == '#')
{
src++;
1993-03-29 23:45:50 +02:00
*ptr = skip_colonthing (exp_sandu, src, op, IMM16, IMM8, IMM16, ABS24);
return;
}
else
{
1993-03-29 23:45:50 +02:00
*ptr = skip_colonthing (exp_signed, src, op,
ispage ? ABS24 : PCREL8, PCREL8, PCREL16, ABS24);
}
}
static
char *
get_operands (info, args, operand)
h8500_opcode_info *info;
char *args;
h8500_operand_info *operand;
{
char *ptr = args;
switch (info->nargs)
{
case 0:
operand[0].type = 0;
operand[1].type = 0;
break;
case 1:
ptr++;
1993-03-29 23:45:50 +02:00
get_operand (&ptr, operand + 0, info->name[0] == 'p');
operand[1].type = 0;
break;
case 2:
ptr++;
get_operand (&ptr, operand + 0, 0);
if (*ptr == ',')
ptr++;
1993-03-29 23:45:50 +02:00
get_operand (&ptr, operand + 1, 0);
break;
default:
abort ();
}
return ptr;
}
/* Passed a pointer to a list of opcodes which use different
addressing modes, return the opcode which matches the opcodes
provided
*/
1993-03-29 23:45:50 +02:00
int pcrel8; /* Set when we've seen a pcrel operand */
static
h8500_opcode_info *
get_specific (opcode, operands)
h8500_opcode_info *opcode;
h8500_operand_info *operands;
{
h8500_opcode_info *this_try = opcode;
int found = 0;
unsigned int noperands = opcode->nargs;
unsigned int this_index = opcode->idx;
while (this_index == opcode->idx && !found)
{
unsigned int i;
this_try = opcode++;
/* look at both operands needed by the opcodes and provided by
the user*/
for (i = 0; i < noperands; i++)
{
h8500_operand_info *user = operands + i;
switch (this_try->arg_type[i])
{
case FPIND_D8:
/* Opcode needs (disp:8,fp) */
1993-03-29 23:45:50 +02:00
if (user->type == RNIND_D8 && user->reg == 6)
{
displacement = user->exp;
continue;
}
break;
case RDIND_D16:
if (user->type == RNIND_D16)
{
displacement = user->exp;
rd = user->reg;
continue;
}
break;
case RDIND_D8:
if (user->type == RNIND_D8)
{
displacement = user->exp;
rd = user->reg;
continue;
}
break;
case RNIND_D16:
case RNIND_D8:
if (user->type == this_try->arg_type[i])
{
displacement = user->exp;
rn = user->reg;
continue;
}
break;
1993-03-29 23:45:50 +02:00
case SPDEC:
if (user->type == RNDEC && user->reg == 7)
{
continue;
}
break;
case SPINC:
if (user->type == RNINC && user->reg == 7)
{
continue;
}
break;
case ABS16:
if (user->type == ABS16)
{
absolute = user->exp;
continue;
}
break;
case ABS8:
if (user->type == ABS8)
{
absolute = user->exp;
continue;
}
break;
case ABS24:
if (user->type == ABS24)
{
absolute = user->exp;
continue;
}
break;
1993-03-29 23:45:50 +02:00
case CRB:
1993-03-29 23:45:50 +02:00
if ((user->type == CRB || user->type == CR) && user->reg != 0)
{
crb = user->reg;
continue;
}
break;
case CRW:
1993-03-29 23:45:50 +02:00
if ((user->type == CRW || user->type == CR) && user->reg == 0)
{
crw = user->reg;
continue;
}
break;
case DISP16:
if (user->type == DISP16)
{
displacement = user->exp;
continue;
}
break;
case DISP8:
if (user->type == DISP8)
{
displacement = user->exp;
continue;
}
break;
case FP:
if (user->type == RN && user->reg == 6)
{
continue;
}
break;
case PCREL16:
if (user->type == PCREL16)
{
displacement = user->exp;
continue;
}
break;
case PCREL8:
if (user->type == PCREL8)
{
displacement = user->exp;
pcrel8 = 1;
continue;
}
break;
case IMM16:
1993-03-29 23:45:50 +02:00
if (user->type == IMM16
|| user->type == IMM8)
{
immediate_inpage = user->page;
immediate = user->exp;
continue;
}
break;
1993-03-29 23:45:50 +02:00
case RLIST:
case IMM8:
if (user->type == IMM8)
{
immediate_inpage = user->page;
immediate = user->exp;
continue;
}
break;
case IMM4:
if (user->type == IMM8)
{
immediate_inpage = user->page;
immediate = user->exp;
continue;
}
break;
case QIM:
if (user->type == IMM8
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
&& user->exp.X_op == O_constant
&&
(user->exp.X_add_number == -2
|| user->exp.X_add_number == -1
|| user->exp.X_add_number == 1
|| user->exp.X_add_number == 2))
{
immediate_inpage = user->page;
immediate = user->exp;
continue;
}
break;
case RD:
if (user->type == RN)
{
rd = user->reg;
continue;
}
break;
case RS:
if (user->type == RN)
{
rs = user->reg;
continue;
}
break;
1993-03-29 23:45:50 +02:00
case RDIND:
if (user->type == RNIND)
1993-03-29 23:45:50 +02:00
{
rd = user->reg;
continue;
}
break;
case RNINC:
case RNIND:
case RNDEC:
case RN:
if (user->type == this_try->arg_type[i])
{
rn = user->reg;
continue;
}
break;
case SP:
if (user->type == RN && user->reg == 7)
{
continue;
}
break;
default:
printf ("unhandled %d\n", this_try->arg_type[i]);
break;
}
/* If we get here this didn't work out */
goto fail;
}
found = 1;
fail:;
}
if (found)
return this_try;
else
return 0;
}
int
check (operand, low, high)
expressionS *operand;
int low;
int high;
{
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
if (operand->X_op != O_constant
|| operand->X_add_number < low
|| operand->X_add_number > high)
{
as_bad ("operand must be absolute in range %d..%d", low, high);
}
return operand->X_add_number;
}
1993-03-29 23:45:50 +02:00
static
void
insert (output, index, exp, reloc, pcrel)
char *output;
int index;
expressionS *exp;
1993-03-29 23:45:50 +02:00
int reloc;
int pcrel;
{
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
fix_new_exp (frag_now,
output - frag_now->fr_literal + index,
4, /* always say size is 4, but we know better */
exp,
* Extensive changes to permit symbols to contain any expression type and to delay the computation of the expression until the value is actually needed. This permits setting symbols to values calculated based on object code size. Expressions were changed to no longer be in a section, to stop the overloading of segment and expression type that previously occurred. * as.c (big_section, pass1_section, diff_section, absent_section): Removed. (expr_section): Added (used for dummy symbols which hold intermediate expression values). (perform_an_assembly_pass): Create expr_section, do not create the sections now removed. * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and SEG_DIFFERENCE. Added SEG_EXPR. (SEG_NORMAL): Corresponding changes. * subsegs.c (seg_name, subsegs_begin): Changed accordingly. * write.c (write_object_file): Ditto. * config/obj-aout.c (seg_N_TYPE): Ditto. * config/obj-bout.c (seg_N_TYPE): Ditto. * config/obj-coff.c (seg_N_TYPE): Ditto. * config/obj-coffbfd.c (seg_N_TYPE): Ditto. * config/obj-vms.c (seg_N_TYPE): Ditto. * expr.h (operatorT): Moved in from expr.c, added some values. (expressionS): Added X_op field, removed X_seg field; renamed X_subtract_symbol to X_op_symbol. * expr.c: Extensive changes to assign expression types rather than sections and to simplify the parsing. * write.c (fix_new_internal): New static function. (fix_new): Removed sub_symbol argument. (fix_new_exp): New function, takes expression argument. * write.h: Prototype changes for fix_new and fix_new_exp. * cond.c (s_if): Changed accordingly. * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons, parse_repeat_cons, get_segmented_expression, get_known_segmented_expression, get_absolute_expression): Ditto. * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE): Ditto. * write.c (write_object_file): Ditto. * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto. * config/obj-coffbfd.c (obj_coff_def, obj_coff_val, obj_coff_endef, yank_symbols): Ditto. * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto. * config/tc-a29k.c (md_assemble, parse_operand, machine_ip, print_insn, md_operand): Ditto. * config/tc-h8300.c (parse_exp, colonmod24, check_operand, do_a_fix_imm, build_bytes): Ditto. * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist, get_specific, check, insert, md_convert_frag): Ditto. * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa, md_assemble, pa_ip, getExpression, getAbsoluteExpression, evaluateAbsolute, pa_build_unwind_subspace, pa_entry, process_exit): Ditto. * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative, is_complex): Ditto. * config/tc-i386.c (pe, md_assemble, i386_operand, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-i860.c (md_assemble, getExpression, print_insn): Ditto. * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag, get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc, i960_handle_align): Ditto. * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op, subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1, md_estimate_size_before_relax, md_create_long_jump, get_num): Ditto. * config/tc-m88k.c (md_assemble, get_imm16, get_pcr, md_create_short_jump, md_create_long_jump): Ditto. * config/tc-mips.c (md_assemble, append_insn, gp_reference, macro_build, macro, my_getExpression): Ditto. Also removed get_optional_absolute_expression; just use get_absolute_expression instead. * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif, fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto. * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto. * config/tc-sh.c (parse_exp, check, insert, md_convert_frag): Ditto. * config/tc-sparc.c (md_assemble, sparc_ip, getExpression, print_insn): Ditto. * config/tc-tahoe.c (struct top, md_estimate_size_before_relax, tip_op, md_assemble): Ditto. * config/tc-vax.c (seg_of_operand, md_assemble, md_estimate_size_before_relax, md_create_long_jump): Ditto. * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
1993-07-21 02:41:42 +02:00
pcrel,
reloc);
}
void
build_relaxable_instruction (opcode, operand)
h8500_opcode_info *opcode;
h8500_operand_info *operand;
{
/* All relaxable instructions start life as two bytes but can become
three bytes long if a lonely branch and up to 9 bytes if long scb
*/
char *p;
int len;
int type;
if (opcode->bytes[0].contents == 0x01)
1993-03-29 23:45:50 +02:00
{
type = SCB_F;
}
else if (opcode->bytes[0].contents == 0x06
|| opcode->bytes[0].contents == 0x07)
1993-03-29 23:45:50 +02:00
{
type = SCB_TST;
}
else
1993-03-29 23:45:50 +02:00
{
type = BRANCH;
}
p = frag_var (rs_machine_dependent,
md_relax_table[C (type, WORD_DISP)].rlx_length,
len = md_relax_table[C (type, BYTE_DISP)].rlx_length,
C (type, UNDEF_BYTE_DISP),
displacement.X_add_symbol,
displacement.X_add_number,
0);
p[0] = opcode->bytes[0].contents;
1993-03-29 23:45:50 +02:00
if (type != BRANCH)
{
p[1] = opcode->bytes[1].contents | rs;
}
}
/* Now we know what sort of opcodes it is, lets build the bytes -
*/
static void
build_bytes (opcode, operand)
h8500_opcode_info *opcode;
h8500_operand_info *operand;
{
int index;
if (pcrel8)
{
pcrel8 = 0;
build_relaxable_instruction (opcode, operand);
}
else
{
char *output = frag_more (opcode->length);
memset (output, 0, opcode->length);
for (index = 0; index < opcode->length; index++)
{
output[index] = opcode->bytes[index].contents;
switch (opcode->bytes[index].insert)
{
default:
printf ("failed for %d\n", opcode->bytes[index].insert);
break;
case 0:
break;
case RN:
output[index] |= rn;
break;
case RD:
case RDIND:
output[index] |= rd;
break;
case RS:
output[index] |= rs;
break;
case DISP16:
1993-03-29 23:45:50 +02:00
insert (output, index, &displacement, R_H8500_IMM16, 0);
index++;
break;
case DISP8:
case FPIND_D8:
1993-03-29 23:45:50 +02:00
insert (output, index, &displacement, R_H8500_IMM8, 0);
break;
case IMM16:
{
int p;
switch (immediate_inpage) {
case 'p':
p = R_H8500_HIGH16;
break;
case 'h':
p = R_H8500_HIGH16;
break;
default:
p = R_H8500_IMM16;
break;
}
insert (output, index, &immediate,p, 0);
}
index++;
break;
1993-03-29 23:45:50 +02:00
case RLIST:
case IMM8:
1993-03-29 23:45:50 +02:00
if (immediate_inpage)
{
insert (output, index, &immediate, R_H8500_HIGH8, 0);
}
else
{
insert (output, index, &immediate, R_H8500_IMM8, 0);
}
break;
case PCREL16:
1993-03-29 23:45:50 +02:00
insert (output, index, &displacement, R_H8500_PCREL16, 1);
index++;
break;
case PCREL8:
1993-03-29 23:45:50 +02:00
insert (output, index, &displacement, R_H8500_PCREL8, 1);
break;
case IMM4:
output[index] |= check (&immediate, 0, 15);
break;
1993-03-29 23:45:50 +02:00
case CR:
output[index] |= cr;
if (cr == 0)
{
output[0] |= 0x8;
}
else
{
output[0] &= ~0x8;
}
break;
case CRB:
output[index] |= crb;
1993-03-29 23:45:50 +02:00
output[0] &= ~0x8;
break;
case CRW:
output[index] |= crw;
1993-03-29 23:45:50 +02:00
output[0] |= 0x8;
break;
case ABS24:
insert (output, index, &absolute, R_H8500_IMM24, 0);
1993-03-29 23:45:50 +02:00
index += 2;
break;
case ABS16:
insert (output, index, &absolute, R_H8500_IMM16, 0);
index++;
break;
case ABS8:
insert (output, index, &absolute, R_H8500_IMM8, 0);
break;
case QIM:
switch (immediate.X_add_number)
{
case -2:
output[index] |= 0x5;
break;
case -1:
output[index] |= 0x4;
break;
case 1:
output[index] |= 0;
break;
case 2:
output[index] |= 1;
break;
}
break;
}
}
}
}
/* This is the guts of the machine-dependent assembler. STR points to a
machine dependent instruction. This funciton is supposed to emit
the frags/bytes it assembles to.
*/
void
DEFUN (md_assemble, (str),
char *str)
{
char *op_start;
char *op_end;
h8500_operand_info operand[2];
h8500_opcode_info *opcode;
h8500_opcode_info *prev_opcode;
char name[11];
int nlen = 0;
/* Drop leading whitespace */
while (*str == ' ')
str++;
/* find the op code end */
for (op_start = op_end = str;
1993-03-29 23:45:50 +02:00
*op_end &&
!is_end_of_line[*op_end] && *op_end != ' ';
op_end++)
{
1993-03-29 23:45:50 +02:00
if ( /**op_end != '.'
&& *op_end != ':'
1993-03-29 23:45:50 +02:00
&& */ nlen < 10)
{
name[nlen++] = *op_end;
}
}
name[nlen] = 0;
if (op_end == op_start)
{
as_bad ("can't find opcode ");
}
opcode = (h8500_opcode_info *) hash_find (opcode_hash_control, name);
if (opcode == NULL)
{
as_bad ("unknown opcode");
return;
}
get_operands (opcode, op_end, operand);
prev_opcode = opcode;
opcode = get_specific (opcode, operand);
if (opcode == 0)
{
/* Couldn't find an opcode which matched the operands */
char *where = frag_more (2);
where[0] = 0x0;
where[1] = 0x0;
as_bad ("invalid operands for opcode");
return;
}
build_bytes (opcode, operand);
}
void
DEFUN (tc_crawl_symbol_chain, (headers),
object_headers * headers)
{
printf ("call to tc_crawl_symbol_chain \n");
}
symbolS *
DEFUN (md_undefined_symbol, (name),
char *name)
{
return 0;
}
void
DEFUN (tc_headers_hook, (headers),
object_headers * headers)
{
printf ("call to tc_headers_hook \n");
}
/* Various routines to kill one day */
/* Equal to MAX_PRECISION in atof-ieee.c */
#define MAX_LITTLENUMS 6
/* Turn a string in input_line_pointer into a floating point constant of type
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
emitted is stored in *sizeP . An error message is returned, or NULL on OK.
*/
char *
md_atof (type, litP, sizeP)
char type;
char *litP;
int *sizeP;
{
int prec;
LITTLENUM_TYPE words[MAX_LITTLENUMS];
LITTLENUM_TYPE *wordP;
char *t;
char *atof_ieee ();
switch (type)
{
case 'f':
case 'F':
case 's':
case 'S':
prec = 2;
break;
case 'd':
case 'D':
case 'r':
case 'R':
prec = 4;
break;
case 'x':
case 'X':
prec = 6;
break;
case 'p':
case 'P':
prec = 6;
break;
default:
*sizeP = 0;
return "Bad call to MD_ATOF()";
}
t = atof_ieee (input_line_pointer, type, words);
if (t)
input_line_pointer = t;
*sizeP = prec * sizeof (LITTLENUM_TYPE);
for (wordP = words; prec--;)
{
md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
litP += sizeof (LITTLENUM_TYPE);
}
1993-10-12 09:45:49 +01:00
return 0;
}
CONST char *md_shortopts = "";
struct option md_longopts[] = {
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
int
md_parse_option (c, arg)
int c;
char *arg;
{
return 0;
}
void
md_show_usage (stream)
FILE *stream;
{
}
int md_short_jump_size;
void
tc_aout_fix_to_chars ()
{
printf ("call to tc_aout_fix_to_chars \n");
abort ();
}
void
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr;
addressT to_addr;
fragS *frag;
symbolS *to_symbol;
{
as_fatal ("failed sanity check.");
}
void
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr, to_addr;
fragS *frag;
symbolS *to_symbol;
{
as_fatal ("failed sanity check.");
}
static
void
wordify_scb (buffer, disp_size, inst_size)
char *buffer;
int *disp_size;
int *inst_size;
{
int rn = buffer[1] & 0x7;
switch (buffer[0])
{
1993-03-29 23:45:50 +02:00
case 0x0e: /* BSR */
case 0x20:
case 0x21:
case 0x22:
case 0x23:
1993-03-29 23:45:50 +02:00
case 0x24:
case 0x25:
case 0x26:
case 0x27:
case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
buffer[0] |= 0x10;
buffer[1] = 0;
buffer[2] = 0;
*disp_size = 2;
*inst_size = 1;
return;
default:
abort ();
case 0x01:
*inst_size = 6;
*disp_size = 2;
break;
case 0x06:
*inst_size = 8;
*disp_size = 2;
*buffer++ = 0x26; /* bne + 8 */
*buffer++ = 0x08;
break;
case 0x07:
*inst_size = 8;
*disp_size = 2;
*buffer++ = 0x27; /* bne + 8 */
*buffer++ = 0x08;
break;
}
*buffer++ = 0xa8 | rn; /* addq -1,rn */
*buffer++ = 0x0c;
*buffer++ = 0x04; /* cmp #0xff:8, rn */
*buffer++ = 0xff;
*buffer++ = 0x70 | rn;
*buffer++ = 0x36; /* bne ... */
*buffer++ = 0;
*buffer++ = 0;
}
/*
called after relaxing, change the frags so they know how big they are
*/
void
md_convert_frag (headers, fragP)
object_headers *headers;
fragS *fragP;
{
int disp_size = 0;
int inst_size = 0;
char *buffer = fragP->fr_fix + fragP->fr_literal;
switch (fragP->fr_subtype)
{
case C (BRANCH, BYTE_DISP):
disp_size = 1;
inst_size = 1;
break;
case C (SCB_F, BYTE_DISP):
case C (SCB_TST, BYTE_DISP):
disp_size = 1;
inst_size = 2;
break;
/* Branches to a known 16 bit displacement */
/* Turn on the 16bit bit */
case C (BRANCH, WORD_DISP):
case C (SCB_F, WORD_DISP):
case C (SCB_TST, WORD_DISP):
wordify_scb (buffer, &disp_size, &inst_size);
break;
case C (BRANCH, UNDEF_WORD_DISP):
case C (SCB_F, UNDEF_WORD_DISP):
case C (SCB_TST, UNDEF_WORD_DISP):
/* This tried to be relaxed, but didn't manage it, it now needs a
fix */
wordify_scb (buffer, &disp_size, &inst_size);
/* Make a reloc */
1993-03-29 23:45:50 +02:00
fix_new (fragP,
fragP->fr_fix + inst_size,
4,
fragP->fr_symbol,
fragP->fr_offset,
0,
R_H8500_PCREL16);
fragP->fr_fix += disp_size + inst_size;
fragP->fr_var = 0;
return;
break;
default:
abort ();
}
if (inst_size)
{
/* Get the address of the end of the instruction */
int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size;
int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
fragP->fr_offset);
int disp = targ_addr - next_inst;
md_number_to_chars (buffer + inst_size, disp, disp_size);
fragP->fr_fix += disp_size + inst_size;
fragP->fr_var = 0;
}
}
valueT
md_section_align (seg, size)
segT seg ;
valueT size;
{
1993-03-29 23:45:50 +02:00
return ((size + (1 << section_alignment[(int) seg]) - 1)
& (-1 << section_alignment[(int) seg]));
}
void
md_apply_fix (fixP, val)
fixS *fixP;
long val;
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1993-03-29 23:45:50 +02:00
if (fixP->fx_r_type == 0)
{
1993-03-29 23:45:50 +02:00
fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16;
}
switch (fixP->fx_r_type)
{
case R_H8500_IMM8:
case R_H8500_PCREL8:
*buf++ = val;
break;
1993-03-29 23:45:50 +02:00
case R_H8500_IMM16:
case R_H8500_LOW16:
case R_H8500_PCREL16:
*buf++ = (val >> 8);
*buf++ = val;
break;
1993-03-29 23:45:50 +02:00
case R_H8500_HIGH8:
*buf++ = val >> 16;
break;
case R_H8500_HIGH16:
*buf++ = val >> 24;
*buf++ = val >> 16;
break;
1993-03-29 23:45:50 +02:00
case R_H8500_IMM24:
*buf++ = (val >> 16);
*buf++ = (val >> 8);
*buf++ = val;
break;
case R_H8500_IMM32:
*buf++ = (val >> 24);
*buf++ = (val >> 16);
*buf++ = (val >> 8);
*buf++ = val;
break;
default:
abort ();
}
}
void
DEFUN (md_operand, (expressionP), expressionS * expressionP)
{
}
int md_long_jump_size;
/*
called just before address relaxation, return the length
by which a fragment must grow to reach it's destination
*/
int
md_estimate_size_before_relax (fragP, segment_type)
register fragS *fragP;
register segT segment_type;
{
int what = GET_WHAT (fragP->fr_subtype);
switch (fragP->fr_subtype)
{
1993-03-29 23:45:50 +02:00
default:
abort ();
case C (BRANCH, UNDEF_BYTE_DISP):
case C (SCB_F, UNDEF_BYTE_DISP):
case C (SCB_TST, UNDEF_BYTE_DISP):
/* used to be a branch to somewhere which was unknown */
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
{
/* Got a symbol and it's defined in this segment, become byte
sized - maybe it will fix up */
fragP->fr_subtype = C (what, BYTE_DISP);
1993-03-29 23:45:50 +02:00
fragP->fr_var = md_relax_table[C (what, BYTE_DISP)].rlx_length;
}
else
{
/* Its got a segment, but its not ours, so it will always be long */
fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
1993-03-29 23:45:50 +02:00
fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
return md_relax_table[C (what, WORD_DISP)].rlx_length;
}
}
1993-03-29 23:45:50 +02:00
return fragP->fr_var;
}
/* Put number into target byte order */
void
md_number_to_chars (ptr, use, nbytes)
char *ptr;
valueT use;
int nbytes;
{
Lots of changes for: - sparc[lite]-coff as well as sparc-lynx - producing coff (including debug info) under BFD_ASSEMBLER option - cleanup of cpu-specific code in non-cpu-specific files (especially write.c) - providing common code to avoid duplication in cpu-specific files (specifically, md_number_to_chars) - stylistic changes & misc cleanup ================ * config/tc-sparc.c (tc_gen_reloc): Make adjustment to addend be dependent on howto fields, not on format flavour. * struc-symbol.h (struct symbol): New fields sy_obj and sy_tc, defined as types OBJ_SYMFIELD_TYPE and TC_SYMFIELD_TYPE, if those macros are defined. * config/obj-coff.h (TC_SYMFIELD_TYPE, OBJ_SYMFIELD_TYPE): Define. (TARGET_SYMBOL_FIELDS, I960_SYM_FIELDS): Don't define. (sy_tc, sy_obj): Define so that the fields look like they used to, until all references get changed. * write.c (fixup_segment): Lots of variables no longer register. Reordered some code for easier reading. * config/obj-coff.c (obj_coff_dim): dim_index no longer register. Deleted superfluous return statement. (obj_coff_line, obj_coff_size, obj_coff_scl, obj_coff_type, obj_coff_val, tag_init, tag_insert): Deleted superfluous return statement. (align, obj_coff_section): Deleted debugging printfs. * config/tc-i386.c (md_assemble): Discard some register decls. Use assignment rather than memcpy to copy template. (op_hash, reg_hash, prefix_hash): Default C initialization of statics is sufficient. * config/tc-sparc.c (print_insn): Array Reloc is now const, and points to const. * config/obj-coff.h (TARGET_FORMAT): Only use coff-sparc-lynx if TE_LYNX; use coff-sparc otherwise. [USE_NATIVE_HEADERS]: Delete this code; it isn't used. * write.c (fixup_segment): Call TC_VALIDATE_FIX, if defined, before processing a fixup. Call TC_ADJUST_RELOC_COUNT just before returning. Remove some i960-coff-specific code. (TC_ADJUST_RELOC_COUNT): Default to doing nothing. * config/tc-i960.h (TC_ADJUST_RELOC_COUNT) [OBJ_COFF]: Define. (i960_validate_fix): Declare. (TC_VALIDATE_FIX): Define. * config/tc-i960.c (i960_validate_fix): New function. * write.c (number_to_chars_littleendian): New function. Write out bytes in little endian order, doing size and range checking. (number_to_chars_bigendian): New function, similar. * write.h: Declare them. * config/tc-*.c (md_number_to_chars): Use them. * config/tc-vax.c (md_apply_fix): Ditto. * config/tc-i386.c (md_apply_fix): Ditto. * config/obj-coff.c: Rearranged code for handling line number data. (line_fsym): Renamed from function_lineoff in BFD_ASSEMBLER case, since the usage is different from non-BFD_ASSEMBLER case. (in_function, clear_function, set_function): New macros, to combine some of the functionality implemented in differnet ways in BFD_ASSEMBLER and non-... code. Used in other functions that used to check function_lineoff &c. (obj_emit_lineno): Split into two copies, one for BFD_ASSEMBLER, one for not. Non-BFD_ASSEMBLER version now has temporary variable to contain char* pointer pointed to by char** argument. Always follow CROSS_COMPILE code; easier to read that way. (obj_coff_ln): Don't call add_lineno or c_line_new if appline is set. (obj_coff_endef) [BFD_ASSEMBLER]: Don't do anything special for ".bf", it's been done elsewhere. (coff_frob_symbol): If ilne number data is pending, call add_linesym to flush it. (coff_frob_file): Don't do that here. * config/obj-coff.h (coff_frob_file): Declare. (obj_frob_file): Define, to call it. * config/tc-sparc.h (md_create_short_jump, md_create_long_jump, md_estimate_size_before_relax: Define them as macros calling as_fatal. * config/tc-sparc.c: Don't define them as functions.
1993-12-03 04:10:08 +01:00
number_to_chars_bigendian (ptr, use, nbytes);
}
Lots of changes for: - sparc[lite]-coff as well as sparc-lynx - producing coff (including debug info) under BFD_ASSEMBLER option - cleanup of cpu-specific code in non-cpu-specific files (especially write.c) - providing common code to avoid duplication in cpu-specific files (specifically, md_number_to_chars) - stylistic changes & misc cleanup ================ * config/tc-sparc.c (tc_gen_reloc): Make adjustment to addend be dependent on howto fields, not on format flavour. * struc-symbol.h (struct symbol): New fields sy_obj and sy_tc, defined as types OBJ_SYMFIELD_TYPE and TC_SYMFIELD_TYPE, if those macros are defined. * config/obj-coff.h (TC_SYMFIELD_TYPE, OBJ_SYMFIELD_TYPE): Define. (TARGET_SYMBOL_FIELDS, I960_SYM_FIELDS): Don't define. (sy_tc, sy_obj): Define so that the fields look like they used to, until all references get changed. * write.c (fixup_segment): Lots of variables no longer register. Reordered some code for easier reading. * config/obj-coff.c (obj_coff_dim): dim_index no longer register. Deleted superfluous return statement. (obj_coff_line, obj_coff_size, obj_coff_scl, obj_coff_type, obj_coff_val, tag_init, tag_insert): Deleted superfluous return statement. (align, obj_coff_section): Deleted debugging printfs. * config/tc-i386.c (md_assemble): Discard some register decls. Use assignment rather than memcpy to copy template. (op_hash, reg_hash, prefix_hash): Default C initialization of statics is sufficient. * config/tc-sparc.c (print_insn): Array Reloc is now const, and points to const. * config/obj-coff.h (TARGET_FORMAT): Only use coff-sparc-lynx if TE_LYNX; use coff-sparc otherwise. [USE_NATIVE_HEADERS]: Delete this code; it isn't used. * write.c (fixup_segment): Call TC_VALIDATE_FIX, if defined, before processing a fixup. Call TC_ADJUST_RELOC_COUNT just before returning. Remove some i960-coff-specific code. (TC_ADJUST_RELOC_COUNT): Default to doing nothing. * config/tc-i960.h (TC_ADJUST_RELOC_COUNT) [OBJ_COFF]: Define. (i960_validate_fix): Declare. (TC_VALIDATE_FIX): Define. * config/tc-i960.c (i960_validate_fix): New function. * write.c (number_to_chars_littleendian): New function. Write out bytes in little endian order, doing size and range checking. (number_to_chars_bigendian): New function, similar. * write.h: Declare them. * config/tc-*.c (md_number_to_chars): Use them. * config/tc-vax.c (md_apply_fix): Ditto. * config/tc-i386.c (md_apply_fix): Ditto. * config/obj-coff.c: Rearranged code for handling line number data. (line_fsym): Renamed from function_lineoff in BFD_ASSEMBLER case, since the usage is different from non-BFD_ASSEMBLER case. (in_function, clear_function, set_function): New macros, to combine some of the functionality implemented in differnet ways in BFD_ASSEMBLER and non-... code. Used in other functions that used to check function_lineoff &c. (obj_emit_lineno): Split into two copies, one for BFD_ASSEMBLER, one for not. Non-BFD_ASSEMBLER version now has temporary variable to contain char* pointer pointed to by char** argument. Always follow CROSS_COMPILE code; easier to read that way. (obj_coff_ln): Don't call add_lineno or c_line_new if appline is set. (obj_coff_endef) [BFD_ASSEMBLER]: Don't do anything special for ".bf", it's been done elsewhere. (coff_frob_symbol): If ilne number data is pending, call add_linesym to flush it. (coff_frob_file): Don't do that here. * config/obj-coff.h (coff_frob_file): Declare. (obj_frob_file): Define, to call it. * config/tc-sparc.h (md_create_short_jump, md_create_long_jump, md_estimate_size_before_relax: Define them as macros calling as_fatal. * config/tc-sparc.c: Don't define them as functions.
1993-12-03 04:10:08 +01:00
long
md_pcrel_from (fixP)
fixS *fixP;
{
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
void
tc_coff_symbol_emit_hook ()
{
}
1993-03-29 23:45:50 +02:00
short
tc_coff_fix2rtype (fix_ptr)
fixS *fix_ptr;
{
if (fix_ptr->fx_r_type == RELOC_32)
{
/* cons likes to create reloc32's whatever the size of the reloc..
*/
switch (fix_ptr->fx_size)
{
case 2:
return R_H8500_IMM16;
break;
case 1:
return R_H8500_IMM8;
break;
default:
abort ();
}
}
return fix_ptr->fx_r_type;
}
void
tc_reloc_mangle (fix_ptr, intr, base)
fixS *fix_ptr;
struct internal_reloc *intr;
bfd_vma base;
{
symbolS *symbol_ptr;
symbol_ptr = fix_ptr->fx_addsy;
/* If this relocation is attached to a symbol then it's ok
to output it */
if (fix_ptr->fx_r_type == RELOC_32)
{
/* cons likes to create reloc32's whatever the size of the reloc..
*/
switch (fix_ptr->fx_size)
{
case 2:
intr->r_type = R_IMM16;
break;
case 1:
intr->r_type = R_IMM8;
break;
default:
abort ();
}
}
else
{
intr->r_type = fix_ptr->fx_r_type;
}
intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
intr->r_offset = fix_ptr->fx_offset;
1993-03-29 23:45:50 +02:00
/* Turn the segment of the symbol into an offset. */
if (symbol_ptr)
1993-03-29 23:45:50 +02:00
{
symbolS *dot;
dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
if (dot)
{
/* intr->r_offset -=
segment_info[S_GET_SEGMENT(symbol_ptr)].scnhdr.s_paddr;*/
intr->r_offset += S_GET_VALUE (symbol_ptr);
intr->r_symndx = dot->sy_number;
}
else
{
intr->r_symndx = symbol_ptr->sy_number;
}
}
else
1993-03-29 23:45:50 +02:00
{
intr->r_symndx = -1;
}
}
1993-03-29 23:45:50 +02:00
int
start_label (ptr)
char *ptr;
{
/* Check for :s.w */
if (isalpha (ptr[1]) && ptr[2] == '.')
return 0;
/* Check for :s */
if (isalpha (ptr[1]) && !isalpha (ptr[2]))
return 0;
return 1;
}
int
tc_coff_sizemachdep (frag)
fragS *frag;
{
return md_relax_table[frag->fr_subtype].rlx_length;
}
/* end of tc-h8500.c */