start-sanitize-d10v

Wed Jul 17 14:25:13 1996  Martin M. Hunt  <hunt@pizza.cygnus.com>
        * config/tc-d10v.c: New file.
        * config/tc-d10v.h: New file.
        * configure (d10v-*-elf): New target.
        * configure.in (d10v-*-elf): New target.
end-sanitize-d10v
This commit is contained in:
Martin Hunt 1996-07-18 00:39:03 +00:00
parent 2154656e3d
commit 7be9a3121d
7 changed files with 1131 additions and 57 deletions

View file

@ -160,6 +160,34 @@ else
fi
d10v_files="ChangeLog configure.in configure Makefile.in"
if ( echo $* | grep keep\-d10v > /dev/null ) ; then
for i in $d10v_files ; do
if test ! -d $i && (grep sanitize-d10v $i > /dev/null) ; then
if [ -n "${verbose}" ] ; then
echo Keeping d10v stuff in $i
fi
fi
done
else
for i in $d10v_files ; do
if test ! -d $i && (grep sanitize-d10v $i > /dev/null) ; then
if [ -n "${verbose}" ] ; then
echo Removing traces of \"d10v\" from $i...
fi
cp $i new
sed '/start\-sanitize\-d10v/,/end-\sanitize\-d10v/d' < $i > new
if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
if [ -n "${verbose}" ] ; then
echo Caching $i in .Recover...
fi
mv $i .Recover
fi
mv new $i
fi
done
fi
for i in * ; do
if test ! -d $i && (grep sanitize $i > /dev/null) ; then
echo '***' Some mentions of Sanitize are still left in $i! 1>&2

View file

@ -1,3 +1,12 @@
start-sanitize-d10v
Wed Jul 17 14:25:13 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* config/tc-d10v.c: New file.
* config/tc-d10v.h: New file.
* configure (d10v-*-elf): New target.
* configure.in (d10v-*-elf): New target.
end-sanitize-d10v
Fri Jul 12 20:54:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* config/tc-ppc.c (md_parse_option): Recognize -K PIC.

View file

@ -23,6 +23,14 @@ else
lose_these_too="${arc_files} ${lose_these_too}"
fi
d10v_files="tc-d10v.c tc-d10v.h"
if ( echo $* | grep keep\-d10v > /dev/null ) ; then
keep_these_too="${d10v_files} ${keep_these_too}"
else
lose_these_too="${d10v_files} ${lose_these_too}"
fi
# All files listed between the "Things-to-keep:" line and the
# "Files-to-sed:" line will be kept. All other files will be removed.
# Directories listed in this section will have their own Sanitize

928
gas/config/tc-d10v.c Normal file
View file

@ -0,0 +1,928 @@
/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
Copyright (C) 1996 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, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <ctype.h>
#include "as.h"
#include "subsegs.h"
#include "opcode/d10v.h"
#include "elf/ppc.h"
const char comment_chars[] = "#;";
const char line_comment_chars[] = "#";
const char line_separator_chars[] = "";
const char *md_shortopts = "";
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";
/* local functions */
static int reg_name_search PARAMS ((char *name));
static void register_name PARAMS ((expressionS *expressionP));
static int postfix PARAMS ((char *p));
static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
static int get_operands PARAMS ((expressionS exp[]));
static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers));
static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn));
static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn));
static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
struct d10v_opcode *opcode2, unsigned long insn2, int exec_type));
static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
/* fixups */
#define MAX_INSN_FIXUPS (5)
struct d10v_fixup
{
expressionS exp;
int opindex;
bfd_reloc_code_real_type reloc;
};
struct d10v_fixup fixups[MAX_INSN_FIXUPS];
static int fc;
struct option md_longopts[] = {
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
/* The target specific pseudo-ops which we support. */
const pseudo_typeS md_pseudo_table[] =
{
/*
{ "byte", ppc_byte, 0 },
{ "long", ppc_elf_cons, 4 },
{ "word", ppc_elf_cons, 2 },
{ "short", ppc_elf_cons, 2 },
{ "rdata", ppc_elf_rdata, 0 },
{ "rodata", ppc_elf_rdata, 0 },
{ "lcomm", ppc_elf_lcomm, 0 },
*/
{ NULL, NULL, 0 }
};
/* Opcode hash table. */
static struct hash_control *d10v_hash;
/* Structure to hold information about predefined registers. */
struct pd_reg
{
char *name;
int value;
};
/* an expressionS only has one register type, so we fake it */
/* by setting high bits to indicate type */
#define REGISTER_MASK 0xFF
/* The table is sorted. Suitable for searching by a binary search. */
static const struct pd_reg pre_defined_registers[] =
{
{ "a0", OPERAND_ACC+0 },
{ "a1", OPERAND_ACC+1 },
{ "bpc", OPERAND_CONTROL+3 },
{ "bpsw", OPERAND_CONTROL+1 },
{ "c", OPERAND_FLAG+3 },
{ "f0", OPERAND_FLAG+0 },
{ "f1", OPERAND_FLAG+1 },
{ "iba", OPERAND_CONTROL+14 },
{ "mod_e", OPERAND_CONTROL+11 },
{ "mod_s", OPERAND_CONTROL+10 },
{ "pc", OPERAND_CONTROL+2 },
{ "psw", OPERAND_CONTROL+0 },
{ "r0", 0 },
{ "r1", 1 },
{ "r10", 10 },
{ "r11", 11 },
{ "r12", 12 },
{ "r13", 13 },
{ "r14", 14 },
{ "r15", 15 },
{ "r2", 2 },
{ "r3", 3 },
{ "r4", 4 },
{ "r5", 5 },
{ "r6", 6 },
{ "r7", 7 },
{ "r8", 8 },
{ "r9", 9 },
{ "rpt_c", OPERAND_CONTROL+7 },
{ "rpt_e", OPERAND_CONTROL+9 },
{ "rpt_s", OPERAND_CONTROL+8 },
{ "sp", 15 },
};
#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
/* reg_name_search does a binary search of the pre_defined_registers
array to see if "name" is a valid regiter name. Returns the register
number from the array on success, or -1 on failure. */
static int
reg_name_search (name)
char *name;
{
int middle, low, high;
int cmp;
low = 0;
high = REG_NAME_CNT - 1;
do
{
middle = (low + high) / 2;
cmp = strcasecmp (name, pre_defined_registers[middle].name);
if (cmp < 0)
high = middle - 1;
else if (cmp > 0)
low = middle + 1;
else
return pre_defined_registers[middle].value;
}
while (low <= high);
return -1;
}
/* register_name check to see if an expression is a valid
register name. If it is, it marks the expression type
as O_register. */
static void
register_name (expressionP)
expressionS *expressionP;
{
int reg_number;
char *name;
if (expressionP->X_op == O_symbol)
{
name = (char *)S_GET_NAME (expressionP->X_add_symbol);
reg_number = reg_name_search (name);
/* look to see if it's in the register table */
if (reg_number >= 0)
{
expressionP->X_op = O_register;
expressionP->X_add_number = reg_number;
}
}
}
void
md_show_usage (stream)
FILE *stream;
{
fprintf(stream, "D10V options:\n\
none yet\n");
}
int
md_parse_option (c, arg)
int c;
char *arg;
{
return 0;
}
symbolS *
md_undefined_symbol (name)
char *name;
{
return 0;
}
char *
md_atof (type, litp, sizep)
int type;
char *litp;
int *sizep;
{
return "";
}
void
md_convert_frag (abfd, sec, fragP)
bfd *abfd;
asection *sec;
fragS *fragP;
{
/* printf ("call to md_convert_frag \n"); */
abort ();
}
valueT
md_section_align (seg, addr)
asection *seg;
valueT addr;
{
int align = bfd_get_section_alignment (stdoutput, seg);
return ((addr + (1 << align) - 1) & (-1 << align));
}
void
md_begin ()
{
char *prev_name = "";
struct d10v_opcode *opcode;
d10v_hash = hash_new();
/* Insert unique names into hash table. The D10v instruction set
has many identical opcode names that have different opcodes based
on the operands. This hash table then provides a quick index to
the first opcode with a particular name in the opcode table. */
for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++)
{
if (strcmp (prev_name, opcode->name))
{
prev_name = (char *)opcode->name;
hash_insert (d10v_hash, opcode->name, (char *) opcode);
}
}
}
/* this function removes the postincrement or postdecrement
operator ( '+' or '-' ) from an expression */
static int postfix (p)
char *p;
{
while (*p != '-' && *p != '+')
{
if (*p==0 || *p=='\n' || *p=='\r')
break;
p++;
}
if (*p == '-')
{
*p = ' ';
return (-1);
}
if (*p == '+')
{
*p = ' ';
return (1);
}
return (0);
}
static bfd_reloc_code_real_type
get_reloc (op)
struct d10v_operand *op;
{
int bits = op->bits;
/* printf("get_reloc: bits=%d address=%d\n",bits,op->flags & OPERAND_ADDR); */
if (bits <= 4)
return (0);
if (op->flags & OPERAND_ADDR)
{
if (bits == 8)
return (BFD_RELOC_D10V_10_PCREL_R);
else
return (BFD_RELOC_D10V_18_PCREL);
}
return (BFD_RELOC_16);
}
/* get_operands parses a string of operands and returns
an array of expressions */
static int
get_operands (exp)
expressionS exp[];
{
char *p = input_line_pointer;
int numops = 0;
int post = 0;
while (*p)
{
while (*p == ' ' || *p == '\t' || *p == ',')
p++;
if (*p==0 || *p=='\n' || *p=='\r')
break;
if (*p == '@')
{
p++;
exp[numops].X_op = O_absent;
if (*p == '(')
{
p++;
exp[numops].X_add_number = OPERAND_ATPAR;
}
else if (*p == '-')
{
p++;
exp[numops].X_add_number = OPERAND_ATMINUS;
}
else
{
exp[numops].X_add_number = OPERAND_ATSIGN;
post = postfix (p);
}
numops++;
continue;
}
if (*p == ')')
{
/* just skip the trailing paren */
p++;
continue;
}
input_line_pointer = p;
/* create an expression */
expression (&exp[numops]);
/* check to see if it might be a register name */
register_name (&exp[numops]);
if (exp[numops].X_op == O_illegal)
as_bad ("illegal operand");
else if (exp[numops].X_op == O_absent)
as_bad ("missing operand");
numops++;
p = input_line_pointer;
}
switch (post)
{
case -1: /* postdecrement mode */
exp[numops].X_op = O_absent;
exp[numops++].X_add_number = OPERAND_MINUS;
break;
case 1: /* postincrement mode */
exp[numops].X_op = O_absent;
exp[numops++].X_add_number = OPERAND_PLUS;
break;
}
exp[numops].X_op = 0;
return (numops);
}
static unsigned long
d10v_insert_operand (insn, op_type, value)
unsigned long insn;
int op_type;
offsetT value;
{
int shift, bits;
shift = d10v_operands[op_type].shift;
bits = d10v_operands[op_type].bits;
/* truncate to the proper number of bits */
/* FIXME: overflow checking here? */
value &= 0x7FFFFFFF >> (31 - bits);
insn |= (value << shift);
return insn;
}
/* build_insn takes a pointer to the opcode entry in the opcode table
and the array of operand expressions and returns the instruction */
static unsigned long
build_insn (opcode, opers)
struct d10v_opcode *opcode;
expressionS *opers;
{
int i, bits, shift, flags;
unsigned long insn;
unsigned int number;
insn = opcode->opcode;
for (i=0;opcode->operands[i];i++)
{
flags = d10v_operands[opcode->operands[i]].flags;
bits = d10v_operands[opcode->operands[i]].bits;
shift = d10v_operands[opcode->operands[i]].shift;
number = opers[i].X_add_number;
if (flags & OPERAND_REG)
{
number &= REGISTER_MASK;
if (opcode->format == LONG_L)
shift += 15;
}
if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
{
/* now create a fixup */
/*
printf("need a fixup: ");
print_expr_1(stdout,&opers[i]);
printf("\n");
*/
if (fc >= MAX_INSN_FIXUPS)
as_fatal ("too many fixups");
fixups[fc].exp = opers[i];
/* put the operand number here for now. We can look up
the reloc type and/or fixup the instruction in md_apply_fix() */
fixups[fc].reloc = opcode->operands[i];
fc++;
}
/* truncate to the proper number of bits */
/* FIXME: overflow checking here? */
number &= 0x7FFFFFFF >> (31 - bits);
insn = insn | (number << shift);
}
return insn;
}
/* write out a long form instruction */
static void
write_long (opcode, insn)
struct d10v_opcode *opcode;
unsigned long insn;
{
int i;
char *f = frag_more(4);
insn |= FM11;
/* printf("INSN: %08x\n",insn); */
number_to_chars_bigendian (f, insn, 4);
for (i=0; i<fc; i++)
{
if (get_reloc((struct d10v_operand *)&d10v_operands[fixups[i].reloc]))
{
/*
printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
print_expr_1(stdout,&fixups[i].exp);
printf("\n");
*/
fix_new_exp (frag_now,
f - frag_now->fr_literal,
4,
&fixups[i].exp,
1,
fixups[i].reloc);
}
}
}
/* write out a short form instruction by itself */
static void
write_1_short (opcode, insn)
struct d10v_opcode *opcode;
unsigned long insn;
{
char *f = frag_more(4);
int i;
insn |= FM00 | (NOP << 15);
/* printf("INSN: %08x\n",insn); */
number_to_chars_bigendian (f, insn, 4);
for (i=0; i<fc; i++)
{
if (get_reloc((struct d10v_operand *)&d10v_operands[fixups[i].reloc]))
{
/*
printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
print_expr_1(stdout,&fixups[i].exp);
printf("\n");
*/
fix_new_exp (frag_now,
f - frag_now->fr_literal,
4,
&fixups[i].exp,
1,
fixups[i].reloc);
}
}
}
/* write out a short form instruction if possible */
/* return number of instructions not written out */
static int
write_2_short (opcode1, insn1, opcode2, insn2, exec_type)
struct d10v_opcode *opcode1, *opcode2;
unsigned long insn1, insn2;
int exec_type;
{
unsigned long insn;
if(opcode1->exec_type == BRANCH_LINK)
{
/* subroutines must be called from 32-bit boundaries */
/* so the return address will be correct */
write_1_short (opcode1, insn1);
return (1);
}
switch (exec_type)
{
case 0:
if (opcode1->unit == IU)
{
insn = FM10 | (insn2 << 15) | insn1;
}
else
{
insn = FM01 | (insn1 << 15) | insn2;
}
break;
case 1: /* parallel */
insn = FM00 | (insn1 << 15) | insn2;
break;
case 2: /* sequential */
insn = FM01 | (insn1 << 15) | insn2;
break;
case 3: /* reverse sequential */
insn = FM10 | (insn1 << 15) | insn2;
break;
default:
as_fatal("unknown execution type passed to write_2_short()");
}
/* printf("INSN: %08x\n",insn); */
number_to_chars_bigendian (frag_more(4), insn, 4);
return (0);
}
/* This is the main entry point for the machine-dependent assembler. str points to a
machine-dependent instruction. This function is supposed to emit the frags/bytes
it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing
and leaves the difficult stuff to do_assemble().
*/
static unsigned long prev_insn;
static struct d10v_opcode *prev_opcode = 0;
void
md_assemble (str)
char *str;
{
struct d10v_opcode *opcode;
unsigned long insn;
int t=0;
char *str2;
/* printf("md_assemble: str=%s\n",str); */
fc = 0;
/* look for the special multiple instruction seperators */
str2 = strstr (str, "||");
if (str2)
t = 1;
else
{
str2 = strstr (str, "->");
if (str2)
t = 2;
else
{
str2 = strstr (str, "<-");
if (str2)
t = 3;
}
}
/* str2 points to the seperator, if one */
if (str2)
{
*str2 = 0;
/* if two instructions are present and we already have one saved
then first write it out */
if (prev_opcode)
write_1_short (prev_opcode, prev_insn);
/* assemble first instruction and save it */
prev_insn = do_assemble (str, &prev_opcode);
str = str2 + 2;
}
insn = do_assemble (str, &opcode);
/* if this is a long instruction, write it and any previous short instruction */
if (opcode->format & LONG_OPCODE)
{
if (t)
as_fatal("Unable to mix instructions as specified");
if (prev_opcode)
{
write_1_short (prev_opcode, prev_insn);
prev_opcode = NULL;
}
write_long (opcode, insn);
prev_opcode = NULL;
return;
}
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, t) == 0))
{
/* no instructions saved */
prev_opcode = NULL;
}
else
{
if (t)
as_fatal("Unable to mix instructions as specified");
/* save off last instruction so it may be packed on next pass */
prev_opcode = opcode;
prev_insn = insn;
}
}
static unsigned long
do_assemble (str, opcode)
char *str;
struct d10v_opcode **opcode;
{
struct d10v_opcode *next_opcode;
unsigned char *op_start, *save;
unsigned char *op_end;
char name[20];
int nlen = 0, i, match, numops;
expressionS myops[6];
unsigned long insn;
/* printf("do_assemble: str=%s\n",str);*/
/* Drop leading whitespace */
while (*str == ' ')
str++;
/* find the opcode end */
for (op_start = op_end = (unsigned char *) (str);
*op_end
&& nlen < 20
&& !is_end_of_line[*op_end] && *op_end != ' ';
op_end++)
{
name[nlen] = op_start[nlen];
nlen++;
}
name[nlen] = 0;
if (nlen == 0)
as_bad ("can't find opcode ");
/* find the first opcode with the proper name */
*opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
if (*opcode == NULL)
{
as_bad ("unknown opcode");
return;
}
save = input_line_pointer;
input_line_pointer = op_end;
/* get all the operands and save them as expressions */
numops = get_operands (myops);
/* now search the opcode table table for one with operands */
/* that match what we've got */
do
{
match = 1;
for (i = 0; (*opcode)->operands[i]; i++)
{
int flags = d10v_operands[(*opcode)->operands[i]].flags;
if (myops[i].X_op==0)
{
match=0;
break;
}
if (flags & OPERAND_REG)
{
if ((myops[i].X_op != O_register) ||
((flags & OPERAND_ACC) != (myops[i].X_add_number & OPERAND_ACC)) ||
((flags & OPERAND_FLAG) != (myops[i].X_add_number & OPERAND_FLAG)) ||
((flags & OPERAND_CONTROL) != (myops[i].X_add_number & OPERAND_CONTROL)))
{
match=0;
break;
}
}
if (((flags & OPERAND_MINUS) && ((myops[i].X_op != O_absent) || (myops[i].X_add_number != OPERAND_MINUS))) ||
((flags & OPERAND_PLUS) && ((myops[i].X_op != O_absent) || (myops[i].X_add_number != OPERAND_PLUS))) ||
((flags & OPERAND_ATMINUS) && ((myops[i].X_op != O_absent) || (myops[i].X_add_number != OPERAND_ATMINUS))) ||
((flags & OPERAND_ATPAR) && ((myops[i].X_op != O_absent) || (myops[i].X_add_number != OPERAND_ATPAR))) ||
((flags & OPERAND_ATSIGN) && ((myops[i].X_op != O_absent) || (myops[i].X_add_number != OPERAND_ATSIGN))))
{
match=0;
break;
}
}
/* we're only done if the operands matched AND there
are no more to check */
if (match && myops[i].X_op==0)
break;
next_opcode = (*opcode)+1;
if (next_opcode->opcode == 0)
break;
if (strcmp(next_opcode->name, (*opcode)->name))
break;
(*opcode) = next_opcode;
} while (!match);
if (!match)
{
as_bad ("bad opcode or operands");
return (0);
}
/* Check that all registers that are required to be even are. */
/* Also, if any operands were marked as registers, but were really symbols */
/* fix that here. */
for (i=0; (*opcode)->operands[i]; i++)
{
if ((d10v_operands[(*opcode)->operands[i]].flags & OPERAND_EVEN) &&
(myops[i].X_add_number & 1))
as_fatal("Register number must be EVEN");
if (myops[i].X_op == O_register)
{
if (!(d10v_operands[(*opcode)->operands[i]].flags & OPERAND_REG))
{
myops[i].X_op = O_symbol;
myops[i].X_add_number = 0;
/* FIXME create a fixup */
}
}
}
input_line_pointer = save;
/* at this point, we have "opcode" pointing to the opcode entry in the
d10v opcode table, with myops filled out with the operands. */
insn = build_insn ((*opcode), myops);
/* printf("sub-insn = %lx\n",insn); */
return (insn);
}
/* if while processing a fixup, a reloc really needs to be created */
/* then it is done here */
arelent *
tc_gen_reloc (seg, fixp)
asection *seg;
fixS *fixp;
{
arelent *reloc;
reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
"reloc %d not supported by object file format", (int)fixp->fx_r_type);
return NULL;
}
reloc->addend = fixp->fx_addnumber;
/* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
return reloc;
}
int
md_estimate_size_before_relax (fragp, seg)
fragS *fragp;
asection *seg;
{
abort ();
return 0;
}
long
md_pcrel_from_section (fixp, sec)
fixS *fixp;
segT sec;
{
return 0;
/* return fixp->fx_frag->fr_address + fixp->fx_where; */
}
int
md_apply_fix3 (fixp, valuep, seg)
fixS *fixp;
valueT *valuep;
segT seg;
{
valueT value;
char *where;
unsigned long insn;
int op_type;
if (fixp->fx_addsy == (symbolS *) NULL)
{
value = *valuep;
fixp->fx_done = 1;
}
else if (fixp->fx_pcrel)
value = *valuep;
else
{
value = fixp->fx_offset;
if (fixp->fx_subsy != (symbolS *) NULL)
{
if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
value -= S_GET_VALUE (fixp->fx_subsy);
else
{
/* We don't actually support subtracting a symbol. */
as_bad_where (fixp->fx_file, fixp->fx_line,
"expression too complex");
}
}
}
/* printf("md_apply_fix: value=0x%x type=%d\n", value, fixp->fx_r_type); */
op_type = fixp->fx_r_type;
fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
/* printf("reloc=%d\n",fixp->fx_r_type); */
/* Fetch the instruction, insert the fully resolved operand
value, and stuff the instruction back again. */
where = fixp->fx_frag->fr_literal + fixp->fx_where;
insn = bfd_getb32 ((unsigned char *) where);
/* printf(" insn=%x value=%x\n",insn,value); */
insn = d10v_insert_operand (insn, op_type, (offsetT) value);
/* printf(" new insn=%x\n",insn); */
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
if (fixp->fx_done)
return 1;
fixp->fx_addnumber = value;
return 1;
}
/* This is called after the assembler has finished parsing the input
file. Because the D10V assembler sometimes saves short instructions
to see if it can package them with the next instruction, there may
be a short instruction that still needs written. */
int md_after_pass()
{
if (prev_opcode)
{
write_1_short (prev_opcode, prev_insn);
prev_opcode = NULL;
}
}
/* there is a label to be defined. Any saved instruction must
be written out. */
int
start_label()
{
if (prev_opcode)
{
write_1_short (prev_opcode, prev_insn);
prev_opcode = NULL;
}
return 1;
}

57
gas/config/tc-d10v.h Normal file
View file

@ -0,0 +1,57 @@
/* tc-d10v.h -- Header file for tc-d10v.c.
Copyright (C) 1996 Free Software Foundation, Inc.
Written by Martin Hunt, Cygnus Support.
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define TC_D10V
#ifndef BFD_ASSEMBLER
#error D10V support requires BFD_ASSEMBLER
#endif
/* The target BFD architecture. */
#define TARGET_ARCH bfd_arch_d10v
#define TARGET_FORMAT "elf32-d10v"
#define MD_APPLY_FIX3
#define md_operand(x)
/* call md_pcrel_from_section, not md_pcrel_from */
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
/* Permit temporary numeric labels. */
#define LOCAL_LABELS_FB 1
#define LOCAL_LABEL(name) (name[0] == '.' \
&& (name[1] == 'L' || name[1] == '.'))
#define FAKE_LABEL_NAME ".L0\001"
#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
/* We don't need to handle .word strangely. */
#define WORKING_DOT_WORD
#define md_number_to_chars number_to_chars_bigendian
#define md_after_pass_hook md_after_pass
extern int start_label PARAMS ((void));
#define TC_START_LABEL(ch, ptr) (ch == ':' && start_label())

151
gas/configure vendored
View file

@ -762,7 +762,7 @@ for this_target in $target $canon_targets ; do
arc-*-elf*) fmt=elf bfd_gas=yes ;;
# end-sanitize-arc
arm-*-riscix*) fmt=aout targ=arm-lit ;;
arm-*-riscix*) fmt=aout targ=arm-lit em=riscix ;;
arm-*-aout) fmt=aout
case "$endian" in
big) targ=arm-big ;;
@ -773,6 +773,10 @@ for this_target in $target $canon_targets ; do
arm-*-riscix*) fmt=aout ;;
arm-*-pe) fmt=coff targ=armcoff em=pe ;;
# start-sanitize-d10v
d10v-*-elf) fmt=elf bfd_gas=yes ;;
# end-sanitize-d10v
hppa-*-*elf*) fmt=elf em=hppa ;;
hppa-*-lites*) fmt=elf em=hppa ;;
hppa-*-osf*) fmt=som em=hppa ;;
@ -800,6 +804,7 @@ for this_target in $target $canon_targets ; do
fmt=coff targ=i386coff ;;
i386-*-vsta) fmt=aout ;;
i386-*-go32) fmt=coff targ=i386coff ;;
i386-*-rtems*) fmt=coff targ=i386coff ;;
i386-*-gnu*) fmt=elf ;;
i386-*-mach*)
fmt=aout em=mach bfd_gas=yes ;;
@ -810,6 +815,7 @@ for this_target in $target $canon_targets ; do
i386-*-*nt) fmt=coff targ=i386coff em=pe ;;
i960-*-bout) fmt=bout ;;
i960-*-coff) fmt=coff em=ic960 targ=ic960coff ;;
i960-*-rtems*) fmt=coff em=ic960 targ=ic960coff ;;
i960-*-nindy*) fmt=bout ;;
i960-*-vxworks4*) fmt=bout ;;
i960-*-vxworks5.0) fmt=bout ;;
@ -823,7 +829,7 @@ for this_target in $target $canon_targets ; do
m68k-apollo-*) fmt=coff targ=apollo em=apollo ;;
m68k-*-sysv4 | m68k-*-elf) # must be before -sysv*
fmt=elf ;;
m68k-*-coff | m68k-*-sysv*)
m68k-*-coff | m68k-*-sysv* | m68k-*-rtems*)
fmt=coff targ=m68kcoff ;;
m68k-*-hpux*) fmt=hp300 em=hp300 ;;
m68k-*-linux*aout*) fmt=aout em=linux ;;
@ -843,6 +849,7 @@ for this_target in $target $canon_targets ; do
mips-sony-bsd*) fmt=ecoff targ=mips-big ;;
mips-*-bsd*) { echo "configure: error: Unknown vendor for mips-bsd configuration." 1>&2; exit 1; } ;;
mips-*-ultrix*) fmt=ecoff targ=mips-lit endian=little ;;
mips-*-osf*) fmt=ecoff targ=mips-lit endian=little ;;
mips-*-ecoff*) fmt=ecoff
case "$endian" in
big) targ=mips-big ;;
@ -893,6 +900,13 @@ for this_target in $target $canon_targets ; do
*) targ=ppc-sol ;;
esac
;;
ppc-*-rtems*)
fmt=elf
case "$endian" in
big) targ=ppc-big ;;
*) targ=ppc-lit ;;
esac
;;
ppc-*-macos* | ppc-*-mpw*)
fmt=coff em=macos ;;
ppc-*-netware*) fmt=elf em=ppcnw ;;
@ -902,6 +916,7 @@ for this_target in $target $canon_targets ; do
ns32k-pc532-mach* | ns32k-pc532-ux*) fmt=aout em=pc532mach ;;
ns32k-pc532-netbsd* | ns32k-pc532-lites*) fmt=aout em=nbsd532 ;;
sparc-*-rtems*) fmt=aout ;;
sparc-*-sunos4*) fmt=aout em=sun3 ;;
sparc-*-aout | sparc*-*-vxworks*)
fmt=aout ;;
@ -1266,42 +1281,66 @@ esac
# do we need the opcodes library?
case "${need_opcodes}" in
yes)
OPCODES_DEP=../opcodes/libopcodes.a
OPCODES_LIB='-L../opcodes -lopcodes'
yes)
OPCODES_DEP=../opcodes/libopcodes.a
OPCODES_LIB='-L../opcodes -lopcodes'
# We need to handle some special cases if opcodes was built shared.
# We need to handle some special cases for shared libraries.
case "${host}" in
*-*-sunos*)
# On SunOS, we must link against the name we are going to install,
# not -lbfd, since SunOS does not support SONAME.
if test "${shared_opcodes}" = "true"; then
case "${host}" in
*-*-sunos*)
# On SunOS, we must link against the name we are going to install,
# not -lbfd, since SunOS does not support SONAME.
OPCODES_LIB='-L../opcodes -l`echo opcodes | sed '"'"'$(program_transform_name)'"'"'`'
;;
esac
fi
;;
alpha*-*-osf*)
# On Alpha OSF/1, the native linker searches all the -L
# directories for any LIB.so files, and only then searches for any
# LIB.a files. That means that if there is an installed
# libbfd.so, but this build is not done with --enable-shared, the
# link will wind up being against the install libbfd.so rather
# than the newly built libbfd. To avoid this, we must explicitly
# link against libbfd.a when --enable-shared is not used.
if test "${shared_opcodes}" != "true"; then
OPCODES_LIB='../opcodes/libopcodes.a'
fi
;;
esac
;;
esac
case "${need_bfd}" in
yes)
BFDDEP=../bfd/libbfd.a
BFDLIB='-L../bfd -lbfd'
ALL_OBJ_DEPS="$ALL_OBJ_DEPS ../bfd/bfd.h"
yes)
BFDDEP=../bfd/libbfd.a
BFDLIB='-L../bfd -lbfd'
ALL_OBJ_DEPS="$ALL_OBJ_DEPS ../bfd/bfd.h"
# We need to handle some special cases if BFD was built shared.
# We need to handle some special cases for shared libraries
case "${host}" in
*-*-sunos*)
# On SunOS, we must link against the name we are going to install,
# not -lbfd, since SunOS does not support SONAME.
if test "${shared_bfd}" = "true"; then
case "${host}" in
*-*-sunos*)
# On SunOS, we must link against the name we are going to install,
# not -lbfd, since SunOS does not support SONAME.
BFDLIB='-L../bfd -l`echo bfd | sed '"'"'$(program_transform_name)'"'"'`'
;;
esac
BFDLIB='-L../bfd -l`echo bfd | sed '"'"'$(program_transform_name)'"'"'`'
fi
;;
alpha*-*-osf*)
# On Alpha OSF/1, the native linker searches all the -L
# directories for any LIB.so files, and only then searches for any
# LIB.a files. That means that if there is an installed
# libbfd.so, but this build is not done with --enable-shared, the
# link will wind up being against the install libbfd.so rather
# than the newly built libbfd. To avoid this, we must explicitly
# link against libbfd.a when --enable-shared is not used.
if test "${shared_bfd}" != "true"; then
BFDLIB='../bfd/libbfd.a'
fi
;;
esac
;;
esac
@ -1414,7 +1453,7 @@ else
yes;
#endif
EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1418: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1453: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@ -1526,13 +1565,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1530 "configure"
#line 1565 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1536: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1571: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@ -1541,13 +1580,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1545 "configure"
#line 1580 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1551: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@ -1575,12 +1614,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1579 "configure"
#line 1614 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1584: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1619: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@ -1628,11 +1667,11 @@ else
ac_cv_c_cross=yes
else
cat > conftest.$ac_ext <<EOF
#line 1632 "configure"
#line 1667 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
{ (eval echo configure:1636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
{ (eval echo configure:1671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_c_cross=no
else
@ -1652,7 +1691,7 @@ if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1656 "configure"
#line 1691 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() { return 0; }
@ -1660,7 +1699,7 @@ int t() {
char *p = alloca(2 * sizeof(int));
; return 0; }
EOF
if { (eval echo configure:1664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:1699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
ac_cv_header_alloca_h=yes
else
@ -1684,7 +1723,7 @@ if eval "test \"`echo '$''{'ac_cv_func_alloca'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1688 "configure"
#line 1723 "configure"
#include "confdefs.h"
#ifdef __GNUC__
@ -1708,7 +1747,7 @@ int t() {
char *p = (char *) alloca(1);
; return 0; }
EOF
if { (eval echo configure:1712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:1747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
ac_cv_func_alloca=yes
else
@ -1743,7 +1782,7 @@ if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1747 "configure"
#line 1782 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
@ -1772,7 +1811,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1776 "configure"
#line 1811 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -1796,7 +1835,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:1800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:1835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -1828,7 +1867,7 @@ else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
#line 1832 "configure"
#line 1867 "configure"
#include "confdefs.h"
find_stack_direction ()
{
@ -1847,7 +1886,7 @@ main ()
exit (find_stack_direction() < 0);
}
EOF
{ (eval echo configure:1851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
{ (eval echo configure:1886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_c_stack_direction=1
else
@ -1871,7 +1910,7 @@ else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
#line 1875 "configure"
#line 1910 "configure"
#include "confdefs.h"
int main() { return 0; }
@ -1879,7 +1918,7 @@ int t() {
} $ac_kw foo() {
; return 0; }
EOF
if { (eval echo configure:1883: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1918: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
fi
@ -1911,7 +1950,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1915 "configure"
#line 1950 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -1935,7 +1974,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:1939: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:1974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -1966,7 +2005,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1970 "configure"
#line 2005 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -1990,7 +2029,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:1994: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -2021,7 +2060,7 @@ if eval "test \"`echo '$''{'gas_cv_assert_ok'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2025 "configure"
#line 2060 "configure"
#include "confdefs.h"
#include <assert.h>
#include <stdio.h>
@ -2038,7 +2077,7 @@ assert (a == b
; return 0; }
EOF
if { (eval echo configure:2042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
gas_cv_assert_ok=yes
else
@ -2078,7 +2117,7 @@ if eval "test \"`echo '$''{'gas_cv_decl_needed_malloc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2082 "configure"
#line 2117 "configure"
#include "confdefs.h"
$gas_test_headers
int main() { return 0; }
@ -2090,7 +2129,7 @@ x = (f) malloc;
; return 0; }
EOF
if { (eval echo configure:2094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
gas_cv_decl_needed_malloc=no
else
@ -2114,7 +2153,7 @@ if eval "test \"`echo '$''{'gas_cv_decl_needed_free'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2118 "configure"
#line 2153 "configure"
#include "confdefs.h"
$gas_test_headers
int main() { return 0; }
@ -2126,7 +2165,7 @@ x = (f) free;
; return 0; }
EOF
if { (eval echo configure:2130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
gas_cv_decl_needed_free=no
else
@ -2153,7 +2192,7 @@ if eval "test \"`echo '$''{'gas_cv_decl_needed_errno'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2157 "configure"
#line 2192 "configure"
#include "confdefs.h"
#ifdef HAVE_ERRNO_H
@ -2169,7 +2208,7 @@ x = (f) errno;
; return 0; }
EOF
if { (eval echo configure:2173: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
gas_cv_decl_needed_errno=no
else

View file

@ -116,7 +116,7 @@ changequote([,])dnl
arc-*-elf*) fmt=elf bfd_gas=yes ;;
# end-sanitize-arc
arm-*-riscix*) fmt=aout targ=arm-lit ;;
arm-*-riscix*) fmt=aout targ=arm-lit em=riscix ;;
arm-*-aout) fmt=aout
case "$endian" in
big) targ=arm-big ;;
@ -127,6 +127,10 @@ changequote([,])dnl
arm-*-riscix*) fmt=aout ;;
arm-*-pe) fmt=coff targ=armcoff em=pe ;;
# start-sanitize-d10v
d10v-*-elf*) fmt=elf bfd_gas=yes ;;
# end-sanitize-d10v
hppa-*-*elf*) fmt=elf em=hppa ;;
hppa-*-lites*) fmt=elf em=hppa ;;
hppa-*-osf*) fmt=som em=hppa ;;
@ -199,6 +203,7 @@ changequote([,])dnl
mips-sony-bsd*) fmt=ecoff targ=mips-big ;;
mips-*-bsd*) AC_MSG_ERROR(Unknown vendor for mips-bsd configuration.) ;;
mips-*-ultrix*) fmt=ecoff targ=mips-lit endian=little ;;
mips-*-osf*) fmt=ecoff targ=mips-lit endian=little ;;
mips-*-ecoff*) fmt=ecoff
case "$endian" in
big) targ=mips-big ;;