1993-02-04 21:47:48 +01:00
|
|
|
|
/* 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"
|
1993-02-04 21:47:48 +01:00
|
|
|
|
#define DEFINE_TABLE
|
1993-03-29 23:45:50 +02:00
|
|
|
|
#define ASSEMBLER_TABLE
|
1993-02-04 21:47:48 +01:00
|
|
|
|
#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[] = ";";
|
1993-07-13 21:12:10 +02:00
|
|
|
|
const char line_comment_chars[] = "!#";
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
/* 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}
|
|
|
|
|
};
|
|
|
|
|
|
1993-05-27 21:42:23 +02:00
|
|
|
|
const int md_reloc_size;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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
|
1993-04-05 00:23:24 +02:00
|
|
|
|
#define BYTE_B -126
|
1993-02-04 21:47:48 +01:00
|
|
|
|
#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)];
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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;
|
1993-07-22 21:11:48 +02:00
|
|
|
|
register relax_typeS *table;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1993-07-22 21:11:48 +02:00
|
|
|
|
/* 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-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
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-02-04 21:47:48 +01:00
|
|
|
|
|
1993-03-29 23:45:50 +02:00
|
|
|
|
static expressionS displacement;/* displacement expression */
|
|
|
|
|
static int displacement_size; /* and size if given */
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
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-02-04 21:47:48 +01:00
|
|
|
|
|
1993-03-29 23:45:50 +02:00
|
|
|
|
static expressionS absolute; /* absolute expression */
|
|
|
|
|
static int absolute_size; /* and size if given */
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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
|
1993-02-04 21:47:48 +01:00
|
|
|
|
parse_reg (src, mode, reg)
|
|
|
|
|
char *src;
|
|
|
|
|
int *mode;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
int *reg;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
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;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
*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
|
1993-02-04 21:47:48 +01:00
|
|
|
|
char *
|
|
|
|
|
parse_exp (s, op, page)
|
|
|
|
|
char *s;
|
|
|
|
|
expressionS *op;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
int *page;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
1993-03-29 23:45:50 +02:00
|
|
|
|
char *save;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
char *new;
|
|
|
|
|
|
|
|
|
|
save = input_line_pointer;
|
|
|
|
|
|
1993-03-29 23:45:50 +02:00
|
|
|
|
*page = 0;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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';
|
|
|
|
|
}
|
1993-07-13 21:12:10 +02:00
|
|
|
|
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';
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input_line_pointer = s;
|
|
|
|
|
|
1993-07-23 21:17:12 +02:00
|
|
|
|
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");
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
1993-03-29 23:45:50 +02:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
exp_signed, exp_unsigned, exp_sandu
|
|
|
|
|
} sign_type;
|
|
|
|
|
|
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
static char *
|
1993-03-29 23:45:50 +02:00
|
|
|
|
skip_colonthing (sign, ptr, exp, def, size8, size16, size24)
|
|
|
|
|
sign_type sign;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
1993-03-29 23:45:50 +02:00
|
|
|
|
{
|
|
|
|
|
if (exp->page == 'p')
|
|
|
|
|
{
|
|
|
|
|
exp->type = IMM8;
|
|
|
|
|
}
|
1993-07-13 21:12:10 +02:00
|
|
|
|
else if (exp->page == 'h')
|
|
|
|
|
{
|
|
|
|
|
exp->type = IMM16;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
1993-03-29 23:45:50 +02:00
|
|
|
|
parse_reglist (src, op)
|
|
|
|
|
char *src;
|
|
|
|
|
h8500_operand_info *op;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
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-02-04 21:47:48 +01:00
|
|
|
|
{
|
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-02-04 21:47:48 +01:00
|
|
|
|
}
|
1993-03-29 23:45:50 +02:00
|
|
|
|
if (src[idx] == ',')
|
|
|
|
|
idx++;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
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;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
1993-10-06 18:31:31 +01:00
|
|
|
|
op->exp.X_unsigned = 1;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
op->type = IMM8;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
return idx;
|
|
|
|
|
|
|
|
|
|
}
|
1993-03-29 23:45:50 +02:00
|
|
|
|
|
1993-02-04 21:47:48 +01: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)
|
1993-02-04 21:47:48 +01:00
|
|
|
|
char **ptr;
|
|
|
|
|
h8500_operand_info *op;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
char ispage;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
char *src = *ptr;
|
|
|
|
|
int mode;
|
|
|
|
|
unsigned int num;
|
|
|
|
|
unsigned int len;
|
1993-04-05 00:23:24 +02:00
|
|
|
|
op->page = 0;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (*src == '#')
|
|
|
|
|
{
|
|
|
|
|
src++;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
*ptr = skip_colonthing (exp_sandu, src, op, IMM16, IMM8, IMM16, ABS24);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1993-03-29 23:45:50 +02:00
|
|
|
|
*ptr = skip_colonthing (exp_signed, src, op,
|
|
|
|
|
ispage ? ABS24 : PCREL8, PCREL8, PCREL16, ABS24);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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');
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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 */
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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)
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
case SPDEC:
|
|
|
|
|
if (user->type == RNDEC && user->reg == 7)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
1993-04-05 00:23:24 +02:00
|
|
|
|
case SPINC:
|
|
|
|
|
if (user->type == RNINC && user->reg == 7)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
case CRB:
|
1993-03-29 23:45:50 +02:00
|
|
|
|
if ((user->type == CRB || user->type == CR) && user->reg != 0)
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
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)
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
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
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|| user->type == IMM8)
|
|
|
|
|
{
|
|
|
|
|
immediate_inpage = user->page;
|
|
|
|
|
immediate = user->exp;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
case RLIST:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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
|
1993-02-04 21:47:48 +01:00
|
|
|
|
&&
|
|
|
|
|
(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:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
if (user->type == RNIND)
|
1993-03-29 23:45:50 +02:00
|
|
|
|
{
|
|
|
|
|
rd = user->reg;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|| 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)
|
1993-02-04 21:47:48 +01:00
|
|
|
|
char *output;
|
|
|
|
|
int index;
|
|
|
|
|
expressionS *exp;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
int reloc;
|
|
|
|
|
int pcrel;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
* 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 */
|
1993-07-22 21:11:48 +02:00
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
else if (opcode->bytes[0].contents == 0x06
|
|
|
|
|
|| opcode->bytes[0].contents == 0x07)
|
1993-03-29 23:45:50 +02:00
|
|
|
|
{
|
|
|
|
|
type = SCB_TST;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
else
|
1993-03-29 23:45:50 +02:00
|
|
|
|
{
|
|
|
|
|
type = BRANCH;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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:
|
1993-05-19 16:44:00 +02:00
|
|
|
|
case RDIND:
|
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
index++;
|
|
|
|
|
break;
|
|
|
|
|
case DISP8:
|
|
|
|
|
case FPIND_D8:
|
1993-03-29 23:45:50 +02:00
|
|
|
|
insert (output, index, &displacement, R_H8500_IMM8, 0);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
break;
|
1993-07-13 21:12:10 +02:00
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
case IMM16:
|
1993-07-13 21:12:10 +02:00
|
|
|
|
{
|
|
|
|
|
int p;
|
|
|
|
|
switch (immediate_inpage) {
|
|
|
|
|
case 'p':
|
1993-12-11 20:28:41 +01:00
|
|
|
|
p = R_H8500_HIGH16;
|
1993-07-13 21:12:10 +02:00
|
|
|
|
break;
|
|
|
|
|
case 'h':
|
|
|
|
|
p = R_H8500_HIGH16;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
p = R_H8500_IMM16;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
insert (output, index, &immediate,p, 0);
|
|
|
|
|
}
|
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
index++;
|
|
|
|
|
break;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
case RLIST:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
break;
|
|
|
|
|
case PCREL16:
|
1993-03-29 23:45:50 +02:00
|
|
|
|
insert (output, index, &displacement, R_H8500_PCREL16, 1);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
index++;
|
|
|
|
|
break;
|
|
|
|
|
case PCREL8:
|
1993-03-29 23:45:50 +02:00
|
|
|
|
insert (output, index, &displacement, R_H8500_PCREL8, 1);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
case CRB:
|
|
|
|
|
output[index] |= crb;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
output[0] &= ~0x8;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
break;
|
|
|
|
|
case CRW:
|
|
|
|
|
output[index] |= crw;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
output[0] |= 0x8;
|
|
|
|
|
break;
|
|
|
|
|
case ABS24:
|
1993-05-19 16:44:00 +02:00
|
|
|
|
insert (output, index, &absolute, R_H8500_IMM24, 0);
|
1993-03-29 23:45:50 +02:00
|
|
|
|
index += 2;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
break;
|
|
|
|
|
case ABS16:
|
1993-05-19 16:44:00 +02:00
|
|
|
|
insert (output, index, &absolute, R_H8500_IMM16, 0);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
index++;
|
|
|
|
|
break;
|
|
|
|
|
case ABS8:
|
1993-05-19 16:44:00 +02:00
|
|
|
|
insert (output, index, &absolute, R_H8500_IMM8, 0);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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 != ' ';
|
1993-02-04 21:47:48 +01:00
|
|
|
|
op_end++)
|
|
|
|
|
{
|
1993-03-29 23:45:50 +02:00
|
|
|
|
if ( /**op_end != '.'
|
1993-02-04 21:47:48 +01:00
|
|
|
|
&& *op_end != ':'
|
1993-03-29 23:45:50 +02:00
|
|
|
|
&& */ nlen < 10)
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
1993-12-11 20:28:41 +01:00
|
|
|
|
get_operands (opcode, op_end, operand);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
1994-06-03 19:42:27 +02:00
|
|
|
|
|
|
|
|
|
CONST char *md_shortopts = "";
|
|
|
|
|
struct option md_longopts[] = {
|
|
|
|
|
{NULL, no_argument, NULL, 0}
|
|
|
|
|
};
|
|
|
|
|
size_t md_longopts_size = sizeof(md_longopts);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
int
|
1994-06-03 19:42:27 +02:00
|
|
|
|
md_parse_option (c, arg)
|
|
|
|
|
int c;
|
|
|
|
|
char *arg;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1994-06-03 19:42:27 +02:00
|
|
|
|
void
|
|
|
|
|
md_show_usage (stream)
|
|
|
|
|
FILE *stream;
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
1993-07-12 21:42:32 +02:00
|
|
|
|
addressT from_addr;
|
|
|
|
|
addressT to_addr;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
1993-07-12 21:42:32 +02:00
|
|
|
|
addressT from_addr, to_addr;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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 */
|
1993-02-04 21:47:48 +01:00
|
|
|
|
case 0x20:
|
|
|
|
|
case 0x21:
|
|
|
|
|
case 0x22:
|
|
|
|
|
case 0x23:
|
1993-03-29 23:45:50 +02:00
|
|
|
|
case 0x24:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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
|
1993-12-11 20:28:41 +01:00
|
|
|
|
fix */
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1993-07-12 21:42:32 +02:00
|
|
|
|
valueT
|
1993-07-13 21:12:10 +02:00
|
|
|
|
md_section_align (seg, size)
|
|
|
|
|
segT seg ;
|
|
|
|
|
valueT size;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
{
|
1993-03-29 23:45:50 +02:00
|
|
|
|
return ((size + (1 << section_alignment[(int) seg]) - 1)
|
|
|
|
|
& (-1 << section_alignment[(int) seg]));
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-02-04 21:47:48 +01:00
|
|
|
|
{
|
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:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
*buf++ = val;
|
|
|
|
|
break;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
case R_H8500_IMM16:
|
|
|
|
|
case R_H8500_LOW16:
|
|
|
|
|
case R_H8500_PCREL16:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
*buf++ = (val >> 8);
|
|
|
|
|
*buf++ = val;
|
|
|
|
|
break;
|
1993-03-29 23:45:50 +02:00
|
|
|
|
case R_H8500_HIGH8:
|
|
|
|
|
*buf++ = val >> 16;
|
|
|
|
|
break;
|
1993-07-13 21:12:10 +02:00
|
|
|
|
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:
|
1993-02-04 21:47:48 +01:00
|
|
|
|
*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 ();
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
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-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
1993-03-29 23:45:50 +02:00
|
|
|
|
return fragP->fr_var;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Put number into target byte order */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
md_number_to_chars (ptr, use, nbytes)
|
|
|
|
|
char *ptr;
|
1993-07-12 21:42:32 +02:00
|
|
|
|
valueT use;
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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);
|
1993-02-04 21:47:48 +01:00
|
|
|
|
}
|
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
|
|
|
|
|
1993-02-04 21:47:48 +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;
|
|
|
|
|
}
|
|
|
|
|
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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. */
|
1993-02-04 21:47:48 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
else
|
1993-03-29 23:45:50 +02:00
|
|
|
|
{
|
|
|
|
|
intr->r_symndx = -1;
|
|
|
|
|
}
|
1993-02-04 21:47:48 +01:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
1993-05-19 16:44:00 +02:00
|
|
|
|
|
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;
|
|
|
|
|
}
|
1993-05-19 16:44:00 +02:00
|
|
|
|
|
1993-12-11 20:28:41 +01:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
tc_coff_sizemachdep (frag)
|
|
|
|
|
fragS *frag;
|
|
|
|
|
{
|
|
|
|
|
return md_relax_table[frag->fr_subtype].rlx_length;
|
|
|
|
|
}
|
|
|
|
|
|
1993-05-19 16:44:00 +02:00
|
|
|
|
/* end of tc-h8500.c */
|
1993-12-11 20:28:41 +01:00
|
|
|
|
|