mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-11 16:46:14 +08:00
Kazu Hirata's formatting fixes.
This commit is contained in:
@ -1,3 +1,13 @@
|
|||||||
|
2000-07-27 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* config/tc-d10v.c (find_opcode): Remove extraneous `='.
|
||||||
|
|
||||||
|
2000-07-27 Kazu Hirata <kazu@hxi.com>
|
||||||
|
|
||||||
|
* config/tc-d10v.c: Fix formatting.
|
||||||
|
* config/tc-z8k.c: Likewise.
|
||||||
|
* config/tc-sparc.c: Likewise.
|
||||||
|
|
||||||
2000-07-26 Dave Brolley <brolley@redhat.com>
|
2000-07-26 Dave Brolley <brolley@redhat.com>
|
||||||
|
|
||||||
* cgen.c (queue_fixup): Declare opinfo.
|
* cgen.c (queue_fixup): Declare opinfo.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
|
/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
|
||||||
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation.
|
Copyright (C) 1996, 97, 98, 99, 2000 Free Software Foundation.
|
||||||
|
|
||||||
This file is part of GAS, the GNU Assembler.
|
This file is part of GAS, the GNU Assembler.
|
||||||
|
|
||||||
@ -40,8 +40,7 @@ int Optimizing = 0;
|
|||||||
&& S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT)
|
&& S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT)
|
||||||
#define AT_WORD_RIGHT_SHIFT 2
|
#define AT_WORD_RIGHT_SHIFT 2
|
||||||
|
|
||||||
|
/* Fixups. */
|
||||||
/* fixups */
|
|
||||||
#define MAX_INSN_FIXUPS (5)
|
#define MAX_INSN_FIXUPS (5)
|
||||||
struct d10v_fixup
|
struct d10v_fixup
|
||||||
{
|
{
|
||||||
@ -65,16 +64,16 @@ static Fixups *fixups;
|
|||||||
static int do_not_ignore_hash = 0;
|
static int do_not_ignore_hash = 0;
|
||||||
|
|
||||||
typedef int packing_type;
|
typedef int packing_type;
|
||||||
#define PACK_UNSPEC (0) /* packing order not specified */
|
#define PACK_UNSPEC (0) /* Packing order not specified. */
|
||||||
#define PACK_PARALLEL (1) /* "||" */
|
#define PACK_PARALLEL (1) /* "||" */
|
||||||
#define PACK_LEFT_RIGHT (2) /* "->" */
|
#define PACK_LEFT_RIGHT (2) /* "->" */
|
||||||
#define PACK_RIGHT_LEFT (3) /* "<-" */
|
#define PACK_RIGHT_LEFT (3) /* "<-" */
|
||||||
static packing_type etype = PACK_UNSPEC; /* used by d10v_cleanup */
|
static packing_type etype = PACK_UNSPEC; /* Used by d10v_cleanup. */
|
||||||
|
|
||||||
/* True if instruction swapping warnings should be inhibited. */
|
/* True if instruction swapping warnings should be inhibited. */
|
||||||
static unsigned char flag_warn_suppress_instructionswap; /* --nowarnswap */
|
static unsigned char flag_warn_suppress_instructionswap; /* --nowarnswap */
|
||||||
|
|
||||||
/* local functions */
|
/* Local functions. */
|
||||||
static int reg_name_search PARAMS ((char *name));
|
static int reg_name_search PARAMS ((char *name));
|
||||||
static int register_name PARAMS ((expressionS *expressionP));
|
static int register_name PARAMS ((expressionS *expressionP));
|
||||||
static int check_range PARAMS ((unsigned long num, int bits, int flags));
|
static int check_range PARAMS ((unsigned long num, int bits, int flags));
|
||||||
@ -115,9 +114,9 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
/* Opcode hash table. */
|
/* Opcode hash table. */
|
||||||
static struct hash_control *d10v_hash;
|
static struct hash_control *d10v_hash;
|
||||||
|
|
||||||
/* reg_name_search does a binary search of the d10v_predefined_registers
|
/* Do a binary search of the d10v_predefined_registers array to see if
|
||||||
array to see if "name" is a valid regiter name. Returns the register
|
NAME is a valid regiter name. Return the register number from the
|
||||||
number from the array on success, or -1 on failure. */
|
array on success, or -1 on failure. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
reg_name_search (name)
|
reg_name_search (name)
|
||||||
@ -144,8 +143,8 @@ reg_name_search (name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register_name() checks the string at input_line_pointer
|
/* Check the string at input_line_pointer
|
||||||
to see if it is a valid register name */
|
to see if it is a valid register name. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
register_name (expressionP)
|
register_name (expressionP)
|
||||||
@ -154,19 +153,20 @@ register_name (expressionP)
|
|||||||
int reg_number;
|
int reg_number;
|
||||||
char c, *p = input_line_pointer;
|
char c, *p = input_line_pointer;
|
||||||
|
|
||||||
while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
|
while (*p
|
||||||
|
&& *p != '\n' && *p != '\r' && *p != ',' && *p != ' ' && *p != ')')
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
c = *p;
|
c = *p;
|
||||||
if (c)
|
if (c)
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
|
|
||||||
/* look to see if it's in the register table */
|
/* Look to see if it's in the register table. */
|
||||||
reg_number = reg_name_search (input_line_pointer);
|
reg_number = reg_name_search (input_line_pointer);
|
||||||
if (reg_number >= 0)
|
if (reg_number >= 0)
|
||||||
{
|
{
|
||||||
expressionP->X_op = O_register;
|
expressionP->X_op = O_register;
|
||||||
/* temporarily store a pointer to the string here */
|
/* Temporarily store a pointer to the string here. */
|
||||||
expressionP->X_op_symbol = (symbolS *) input_line_pointer;
|
expressionP->X_op_symbol = (symbolS *) input_line_pointer;
|
||||||
expressionP->X_add_number = reg_number;
|
expressionP->X_add_number = reg_number;
|
||||||
input_line_pointer = p;
|
input_line_pointer = p;
|
||||||
@ -177,7 +177,6 @@ register_name (expressionP)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_range (num, bits, flags)
|
check_range (num, bits, flags)
|
||||||
unsigned long num;
|
unsigned long num;
|
||||||
@ -187,14 +186,14 @@ check_range (num, bits, flags)
|
|||||||
long min, max, bit1;
|
long min, max, bit1;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
/* don't bother checking 16-bit values */
|
/* Don't bother checking 16-bit values. */
|
||||||
if (bits == 16)
|
if (bits == 16)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (flags & OPERAND_SHIFT)
|
if (flags & OPERAND_SHIFT)
|
||||||
{
|
{
|
||||||
/* all special shift operands are unsigned */
|
/* All special shift operands are unsigned and <= 16.
|
||||||
/* and <= 16. We allow 0 for now. */
|
We allow 0 for now. */
|
||||||
if (num > 16)
|
if (num > 16)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
@ -203,7 +202,7 @@ check_range (num, bits, flags)
|
|||||||
|
|
||||||
if (flags & OPERAND_SIGNED)
|
if (flags & OPERAND_SIGNED)
|
||||||
{
|
{
|
||||||
/* Signed 3-bit integers are restricted to the (-2, 3) range */
|
/* Signed 3-bit integers are restricted to the (-2, 3) range. */
|
||||||
if (flags & RESTRICTED_NUM3)
|
if (flags & RESTRICTED_NUM3)
|
||||||
{
|
{
|
||||||
if ((long) num < -2 || (long) num > 3)
|
if ((long) num < -2 || (long) num > 3)
|
||||||
@ -227,7 +226,6 @@ check_range (num, bits, flags)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
md_show_usage (stream)
|
md_show_usage (stream)
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
@ -244,7 +242,7 @@ md_parse_option (c, arg)
|
|||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'O':
|
case 'O':
|
||||||
/* Optimize. Will attempt to parallelize operations */
|
/* Optimize. Will attempt to parallelize operations. */
|
||||||
Optimizing = 1;
|
Optimizing = 1;
|
||||||
break;
|
break;
|
||||||
case OPTION_NOWARNSWAP:
|
case OPTION_NOWARNSWAP:
|
||||||
@ -263,10 +261,11 @@ md_undefined_symbol (name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn a string in input_line_pointer into a floating point constant of type
|
/* Turn a string in input_line_pointer into a floating point constant
|
||||||
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
|
of type TYPE, and store the appropriate bytes in *LITP. The number
|
||||||
emitted is stored in *sizeP . An error message is returned, or NULL on OK.
|
of LITTLENUMS emitted is stored in *SIZEP. An error message is
|
||||||
*/
|
returned, or NULL on OK. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
md_atof (type, litP, sizeP)
|
md_atof (type, litP, sizeP)
|
||||||
int type;
|
int type;
|
||||||
@ -323,7 +322,6 @@ md_section_align (seg, addr)
|
|||||||
return ((addr + (1 << align) - 1) & (-1 << align));
|
return ((addr + (1 << align) - 1) & (-1 << align));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
md_begin ()
|
md_begin ()
|
||||||
{
|
{
|
||||||
@ -350,11 +348,11 @@ md_begin ()
|
|||||||
FixUps[1].next = &FixUps[0];
|
FixUps[1].next = &FixUps[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove the postincrement or postdecrement operator ( '+' or '-' )
|
||||||
|
from an expression. */
|
||||||
|
|
||||||
/* this function removes the postincrement or postdecrement
|
static int
|
||||||
operator ( '+' or '-' ) from an expression */
|
postfix (p)
|
||||||
|
|
||||||
static int postfix (p)
|
|
||||||
char *p;
|
char *p;
|
||||||
{
|
{
|
||||||
while (*p != '-' && *p != '+')
|
while (*p != '-' && *p != '+')
|
||||||
@ -378,7 +376,6 @@ static int postfix (p)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bfd_reloc_code_real_type
|
static bfd_reloc_code_real_type
|
||||||
get_reloc (op)
|
get_reloc (op)
|
||||||
struct d10v_operand *op;
|
struct d10v_operand *op;
|
||||||
@ -399,9 +396,7 @@ get_reloc (op)
|
|||||||
return (BFD_RELOC_16);
|
return (BFD_RELOC_16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse a string of operands. Return an array of expressions. */
|
||||||
/* get_operands parses a string of operands and returns
|
|
||||||
an array of expressions */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_operands (exp)
|
get_operands (exp)
|
||||||
@ -446,17 +441,17 @@ get_operands (exp)
|
|||||||
|
|
||||||
if (*p == ')')
|
if (*p == ')')
|
||||||
{
|
{
|
||||||
/* just skip the trailing paren */
|
/* Just skip the trailing paren. */
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
input_line_pointer = p;
|
input_line_pointer = p;
|
||||||
|
|
||||||
/* check to see if it might be a register name */
|
/* Check to see if it might be a register name. */
|
||||||
if (!register_name (&exp[numops]))
|
if (!register_name (&exp[numops]))
|
||||||
{
|
{
|
||||||
/* parse as an expression */
|
/* Parse as an expression. */
|
||||||
if (uses_at)
|
if (uses_at)
|
||||||
{
|
{
|
||||||
/* Any expression that involves the indirect addressing
|
/* Any expression that involves the indirect addressing
|
||||||
@ -478,14 +473,15 @@ get_operands (exp)
|
|||||||
input_line_pointer += 5;
|
input_line_pointer += 5;
|
||||||
if (exp[numops].X_op == O_register)
|
if (exp[numops].X_op == O_register)
|
||||||
{
|
{
|
||||||
/* if it looked like a register name but was followed by
|
/* If it looked like a register name but was followed by
|
||||||
"@word" then it was really a symbol, so change it to
|
"@word" then it was really a symbol, so change it to
|
||||||
one */
|
one. */
|
||||||
exp[numops].X_op = O_symbol;
|
exp[numops].X_op = O_symbol;
|
||||||
exp[numops].X_add_symbol = symbol_find_or_make ((char *)exp[numops].X_op_symbol);
|
exp[numops].X_add_symbol =
|
||||||
|
symbol_find_or_make ((char *) exp[numops].X_op_symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for identifier@word+constant */
|
/* Check for identifier@word+constant. */
|
||||||
if (*input_line_pointer == '-' || *input_line_pointer == '+')
|
if (*input_line_pointer == '-' || *input_line_pointer == '+')
|
||||||
{
|
{
|
||||||
char *orig_line = input_line_pointer;
|
char *orig_line = input_line_pointer;
|
||||||
@ -494,7 +490,7 @@ get_operands (exp)
|
|||||||
exp[numops].X_add_number = new_exp.X_add_number;
|
exp[numops].X_add_number = new_exp.X_add_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert expr into a right shift by AT_WORD_RIGHT_SHIFT */
|
/* Convert expr into a right shift by AT_WORD_RIGHT_SHIFT. */
|
||||||
{
|
{
|
||||||
expressionS new_exp;
|
expressionS new_exp;
|
||||||
memset (&new_exp, 0, sizeof new_exp);
|
memset (&new_exp, 0, sizeof new_exp);
|
||||||
@ -519,11 +515,11 @@ get_operands (exp)
|
|||||||
|
|
||||||
switch (post)
|
switch (post)
|
||||||
{
|
{
|
||||||
case -1: /* postdecrement mode */
|
case -1: /* Postdecrement mode. */
|
||||||
exp[numops].X_op = O_absent;
|
exp[numops].X_op = O_absent;
|
||||||
exp[numops++].X_add_number = OPERAND_MINUS;
|
exp[numops++].X_add_number = OPERAND_MINUS;
|
||||||
break;
|
break;
|
||||||
case 1: /* postincrement mode */
|
case 1: /* Postincrement mode. */
|
||||||
exp[numops].X_op = O_absent;
|
exp[numops].X_op = O_absent;
|
||||||
exp[numops++].X_add_number = OPERAND_PLUS;
|
exp[numops++].X_add_number = OPERAND_PLUS;
|
||||||
break;
|
break;
|
||||||
@ -549,7 +545,7 @@ d10v_insert_operand (insn, op_type, value, left, fix)
|
|||||||
|
|
||||||
bits = d10v_operands[op_type].bits;
|
bits = d10v_operands[op_type].bits;
|
||||||
|
|
||||||
/* truncate to the proper number of bits */
|
/* Truncate to the proper number of bits. */
|
||||||
if (check_range (value, bits, d10v_operands[op_type].flags))
|
if (check_range (value, bits, d10v_operands[op_type].flags))
|
||||||
as_bad_where (fix->fx_file, fix->fx_line, _("operand out of range: %d"), value);
|
as_bad_where (fix->fx_file, fix->fx_line, _("operand out of range: %d"), value);
|
||||||
|
|
||||||
@ -559,9 +555,8 @@ d10v_insert_operand (insn, op_type, value, left, fix)
|
|||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Take a pointer to the opcode entry in the opcode table and the
|
||||||
/* build_insn takes a pointer to the opcode entry in the opcode table
|
array of operand expressions. Return the instruction. */
|
||||||
and the array of operand expressions and returns the instruction */
|
|
||||||
|
|
||||||
static unsigned long
|
static unsigned long
|
||||||
build_insn (opcode, opers, insn)
|
build_insn (opcode, opers, insn)
|
||||||
@ -572,7 +567,7 @@ build_insn (opcode, opers, insn)
|
|||||||
int i, bits, shift, flags, format;
|
int i, bits, shift, flags, format;
|
||||||
unsigned long number;
|
unsigned long number;
|
||||||
|
|
||||||
/* the insn argument is only used for the DIVS kludge */
|
/* The insn argument is only used for the DIVS kludge. */
|
||||||
if (insn)
|
if (insn)
|
||||||
format = LONG_R;
|
format = LONG_R;
|
||||||
else
|
else
|
||||||
@ -597,17 +592,17 @@ build_insn (opcode, opers, insn)
|
|||||||
|
|
||||||
if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
|
if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
|
||||||
{
|
{
|
||||||
/* now create a fixup */
|
/* Now create a fixup. */
|
||||||
|
|
||||||
if (fixups->fc >= MAX_INSN_FIXUPS)
|
if (fixups->fc >= MAX_INSN_FIXUPS)
|
||||||
as_fatal (_("too many fixups"));
|
as_fatal (_("too many fixups"));
|
||||||
|
|
||||||
if (AT_WORD_P (&opers[i]))
|
if (AT_WORD_P (&opers[i]))
|
||||||
{
|
{
|
||||||
/* Reconize XXX>>1+N aka XXX@word+N as special (AT_WORD) */
|
/* Reconize XXX>>1+N aka XXX@word+N as special (AT_WORD). */
|
||||||
fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
|
fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
|
||||||
opers[i].X_op = O_symbol;
|
opers[i].X_op = O_symbol;
|
||||||
opers[i].X_op_symbol = NULL; /* Should free it */
|
opers[i].X_op_symbol = NULL; /* Should free it. */
|
||||||
/* number is left shifted by AT_WORD_RIGHT_SHIFT so
|
/* number is left shifted by AT_WORD_RIGHT_SHIFT so
|
||||||
that, it is aligned with the symbol's value. Later,
|
that, it is aligned with the symbol's value. Later,
|
||||||
BFD_RELOC_D10V_18 will right shift (symbol_value +
|
BFD_RELOC_D10V_18 will right shift (symbol_value +
|
||||||
@ -627,11 +622,12 @@ build_insn (opcode, opers, insn)
|
|||||||
|
|
||||||
fixups->fix[fixups->fc].exp = opers[i];
|
fixups->fix[fixups->fc].exp = opers[i];
|
||||||
fixups->fix[fixups->fc].operand = opcode->operands[i];
|
fixups->fix[fixups->fc].operand = opcode->operands[i];
|
||||||
fixups->fix[fixups->fc].pcrel = (flags & OPERAND_ADDR) ? true : false;
|
fixups->fix[fixups->fc].pcrel =
|
||||||
|
(flags & OPERAND_ADDR) ? true : false;
|
||||||
(fixups->fc)++;
|
(fixups->fc)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* truncate to the proper number of bits */
|
/* Truncate to the proper number of bits. */
|
||||||
if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
|
if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
|
||||||
as_bad (_("operand out of range: %d"), number);
|
as_bad (_("operand out of range: %d"), number);
|
||||||
number &= 0x7FFFFFFF >> (31 - bits);
|
number &= 0x7FFFFFFF >> (31 - bits);
|
||||||
@ -639,15 +635,16 @@ build_insn (opcode, opers, insn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* kludge: for DIVS, we need to put the operands in twice */
|
/* kludge: for DIVS, we need to put the operands in twice */
|
||||||
/* on the second pass, format is changed to LONG_R to force */
|
/* on the second pass, format is changed to LONG_R to force
|
||||||
/* the second set of operands to not be shifted over 15 */
|
the second set of operands to not be shifted over 15. */
|
||||||
if ((opcode->opcode == OPCODE_DIVS) && (format == LONG_L))
|
if ((opcode->opcode == OPCODE_DIVS) && (format == LONG_L))
|
||||||
insn = build_insn (opcode, opers, insn);
|
insn = build_insn (opcode, opers, insn);
|
||||||
|
|
||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write out a long form instruction */
|
/* Write out a long form instruction. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_long (opcode, insn, fx)
|
write_long (opcode, insn, fx)
|
||||||
struct d10v_opcode *opcode;
|
struct d10v_opcode *opcode;
|
||||||
@ -682,8 +679,8 @@ write_long (opcode, insn, fx)
|
|||||||
fx->fc = 0;
|
fx->fc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write out a short form instruction by itself. */
|
||||||
|
|
||||||
/* write out a short form instruction by itself */
|
|
||||||
static void
|
static void
|
||||||
write_1_short (opcode, insn, fx)
|
write_1_short (opcode, insn, fx)
|
||||||
struct d10v_opcode *opcode;
|
struct d10v_opcode *opcode;
|
||||||
@ -696,13 +693,13 @@ write_1_short (opcode, insn, fx)
|
|||||||
if (opcode->exec_type & PARONLY)
|
if (opcode->exec_type & PARONLY)
|
||||||
as_fatal (_("Instruction must be executed in parallel with another instruction."));
|
as_fatal (_("Instruction must be executed in parallel with another instruction."));
|
||||||
|
|
||||||
/* the other container needs to be NOP */
|
/* The other container needs to be NOP. */
|
||||||
/* according to 4.3.1: for FM=00, sub-instructions performed only
|
/* According to 4.3.1: for FM=00, sub-instructions performed only
|
||||||
by IU cannot be encoded in L-container. */
|
by IU cannot be encoded in L-container. */
|
||||||
if (opcode->unit == IU)
|
if (opcode->unit == IU)
|
||||||
insn |= FM00 | (NOP << 15); /* right container */
|
insn |= FM00 | (NOP << 15); /* Right container. */
|
||||||
else
|
else
|
||||||
insn = FM00 | (insn << 15) | NOP; /* left container */
|
insn = FM00 | (insn << 15) | NOP; /* Left container. */
|
||||||
|
|
||||||
number_to_chars_bigendian (f, insn, 4);
|
number_to_chars_bigendian (f, insn, 4);
|
||||||
for (i = 0; i < fx->fc; i++)
|
for (i = 0; i < fx->fc; i++)
|
||||||
@ -716,8 +713,9 @@ write_1_short (opcode, insn, fx)
|
|||||||
if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
|
if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
|
||||||
fx->fix[i].operand |= 4096;
|
fx->fix[i].operand |= 4096;
|
||||||
|
|
||||||
/* if it's an R reloc, we may have to switch it to L */
|
/* If it's an R reloc, we may have to switch it to L. */
|
||||||
if ( (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) )
|
if ((fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R)
|
||||||
|
&& (opcode->unit != IU))
|
||||||
fx->fix[i].operand |= 1024;
|
fx->fix[i].operand |= 1024;
|
||||||
|
|
||||||
fix_new_exp (frag_now,
|
fix_new_exp (frag_now,
|
||||||
@ -747,26 +745,27 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
|||||||
char *f;
|
char *f;
|
||||||
int i, j, where;
|
int i, j, where;
|
||||||
|
|
||||||
if ( (exec_type != PACK_PARALLEL) && ((opcode1->exec_type & PARONLY)
|
if ((exec_type != PACK_PARALLEL)
|
||||||
|| (opcode2->exec_type & PARONLY)))
|
&& ((opcode1->exec_type & PARONLY) || (opcode2->exec_type & PARONLY)))
|
||||||
as_fatal (_("Instruction must be executed in parallel"));
|
as_fatal (_("Instruction must be executed in parallel"));
|
||||||
|
|
||||||
if ((opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
|
if ((opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
|
||||||
as_fatal (_("Long instructions may not be combined."));
|
as_fatal (_("Long instructions may not be combined."));
|
||||||
|
|
||||||
|
|
||||||
switch (exec_type)
|
switch (exec_type)
|
||||||
{
|
{
|
||||||
case PACK_UNSPEC: /* order not specified */
|
case PACK_UNSPEC: /* Order not specified. */
|
||||||
if (opcode1->exec_type & ALONE)
|
if (opcode1->exec_type & ALONE)
|
||||||
{
|
{
|
||||||
/* Case of a short branch on a separate GAS line. Pack with NOP. */
|
/* Case of a short branch on a separate GAS line.
|
||||||
|
Pack with NOP. */
|
||||||
write_1_short (opcode1, insn1, fx->next);
|
write_1_short (opcode1, insn1, fx->next);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
|
if (Optimizing
|
||||||
|
&& parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
|
||||||
{
|
{
|
||||||
/* parallel */
|
/* Parallel. */
|
||||||
if (opcode1->unit == IU)
|
if (opcode1->unit == IU)
|
||||||
insn = FM00 | (insn2 << 15) | insn1;
|
insn = FM00 | (insn2 << 15) | insn1;
|
||||||
else if (opcode2->unit == MU)
|
else if (opcode2->unit == MU)
|
||||||
@ -774,23 +773,22 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
insn = FM00 | (insn1 << 15) | insn2;
|
insn = FM00 | (insn1 << 15) | insn2;
|
||||||
/* Advance over dummy fixup since packed insn1 in L */
|
/* Advance over dummy fixup since packed insn1 in L. */
|
||||||
fx = fx->next;
|
fx = fx->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (opcode1->unit == IU)
|
else if (opcode1->unit == IU)
|
||||||
/* reverse sequential with IU opcode1 on right and done first */
|
/* Reverse sequential with IU opcode1 on right and done first. */
|
||||||
insn = FM10 | (insn2 << 15) | insn1;
|
insn = FM10 | (insn2 << 15) | insn1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* sequential with non-IU opcode1 on left and done first */
|
/* Sequential with non-IU opcode1 on left and done first. */
|
||||||
insn = FM01 | (insn1 << 15) | insn2;
|
insn = FM01 | (insn1 << 15) | insn2;
|
||||||
/* Advance over dummy fixup since packed insn1 in L */
|
/* Advance over dummy fixup since packed insn1 in L. */
|
||||||
fx = fx->next;
|
fx = fx->next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case PACK_PARALLEL:
|
case PACK_PARALLEL:
|
||||||
if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
|
if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
|
||||||
as_fatal
|
as_fatal
|
||||||
@ -814,12 +812,11 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
insn = FM00 | (insn1 << 15) | insn2;
|
insn = FM00 | (insn1 << 15) | insn2;
|
||||||
/* Advance over dummy fixup since packed insn1 in L */
|
/* Advance over dummy fixup since packed insn1 in L. */
|
||||||
fx = fx->next;
|
fx = fx->next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case PACK_LEFT_RIGHT:
|
case PACK_LEFT_RIGHT:
|
||||||
if (opcode1->unit != IU)
|
if (opcode1->unit != IU)
|
||||||
insn = FM01 | (insn1 << 15) | insn2;
|
insn = FM01 | (insn1 << 15) | insn2;
|
||||||
@ -833,11 +830,10 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
|||||||
as_fatal (_("IU instruction may not be in the left container"));
|
as_fatal (_("IU instruction may not be in the left container"));
|
||||||
if (opcode1->exec_type & ALONE)
|
if (opcode1->exec_type & ALONE)
|
||||||
as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
|
as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
|
||||||
/* Advance over dummy fixup */
|
/* Advance over dummy fixup. */
|
||||||
fx = fx->next;
|
fx = fx->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case PACK_RIGHT_LEFT:
|
case PACK_RIGHT_LEFT:
|
||||||
if (opcode2->unit != MU)
|
if (opcode2->unit != MU)
|
||||||
insn = FM10 | (insn1 << 15) | insn2;
|
insn = FM10 | (insn1 << 15) | insn2;
|
||||||
@ -851,16 +847,14 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
|||||||
as_fatal (_("MU instruction may not be in the right container"));
|
as_fatal (_("MU instruction may not be in the right container"));
|
||||||
if (opcode2->exec_type & ALONE)
|
if (opcode2->exec_type & ALONE)
|
||||||
as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
|
as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
|
||||||
/* Advance over dummy fixup */
|
/* Advance over dummy fixup. */
|
||||||
fx = fx->next;
|
fx = fx->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
as_fatal (_("unknown execution type passed to write_2_short()"));
|
as_fatal (_("unknown execution type passed to write_2_short()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
f = frag_more (4);
|
f = frag_more (4);
|
||||||
number_to_chars_bigendian (f, insn, 4);
|
number_to_chars_bigendian (f, insn, 4);
|
||||||
|
|
||||||
@ -902,9 +896,9 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check 2 instructions and determine if they can be safely
|
||||||
|
executed in parallel. Return 1 if they can be. */
|
||||||
|
|
||||||
/* Check 2 instructions and determine if they can be safely */
|
|
||||||
/* executed in parallel. Returns 1 if they can be. */
|
|
||||||
static int
|
static int
|
||||||
parallel_ok (op1, insn1, op2, insn2, exec_type)
|
parallel_ok (op1, insn1, op2, insn2, exec_type)
|
||||||
struct d10v_opcode *op1, *op2;
|
struct d10v_opcode *op1, *op2;
|
||||||
@ -943,7 +937,7 @@ parallel_ok (op1, insn1, op2, insn2, exec_type)
|
|||||||
and the second reads the PSW (which includes C, F0, and F1), then
|
and the second reads the PSW (which includes C, F0, and F1), then
|
||||||
they cannot operate safely in parallel. */
|
they cannot operate safely in parallel. */
|
||||||
|
|
||||||
/* the bitmasks (mod and used) look like this (bit 31 = MSB) */
|
/* The bitmasks (mod and used) look like this (bit 31 = MSB). */
|
||||||
/* r0-r15 0-15 */
|
/* r0-r15 0-15 */
|
||||||
/* a0-a1 16-17 */
|
/* a0-a1 16-17 */
|
||||||
/* cr (not psw) 18 */
|
/* cr (not psw) 18 */
|
||||||
@ -976,7 +970,7 @@ parallel_ok (op1, insn1, op2, insn2, exec_type)
|
|||||||
regno = (ins >> shift) & mask;
|
regno = (ins >> shift) & mask;
|
||||||
if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
|
if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
|
||||||
regno += 16;
|
regno += 16;
|
||||||
else if (flags & OPERAND_CONTROL) /* mvtc or mvfc */
|
else if (flags & OPERAND_CONTROL) /* mvtc or mvfc. */
|
||||||
{
|
{
|
||||||
if (regno == 0)
|
if (regno == 0)
|
||||||
regno = 19;
|
regno = 19;
|
||||||
@ -1007,7 +1001,7 @@ parallel_ok (op1, insn1, op2, insn2, exec_type)
|
|||||||
}
|
}
|
||||||
else if (flags & OPERAND_ATMINUS)
|
else if (flags & OPERAND_ATMINUS)
|
||||||
{
|
{
|
||||||
/* SP implicitly used/modified */
|
/* SP implicitly used/modified. */
|
||||||
mod[j] |= 1 << 15;
|
mod[j] |= 1 << 15;
|
||||||
used[j] |= 1 << 15;
|
used[j] |= 1 << 15;
|
||||||
}
|
}
|
||||||
@ -1028,12 +1022,11 @@ parallel_ok (op1, insn1, op2, insn2, exec_type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is the main entry point for the machine-dependent assembler.
|
||||||
/* This is the main entry point for the machine-dependent assembler. str points to a
|
STR points to a machine-dependent instruction. This function is
|
||||||
machine-dependent instruction. This function is supposed to emit the frags/bytes
|
supposed to emit the frags/bytes it assembles to. For the D10V, it
|
||||||
it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing
|
mostly handles the special VLIW parsing and packing and leaves the
|
||||||
and leaves the difficult stuff to do_assemble().
|
difficult stuff to do_assemble(). */
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned long prev_insn;
|
static unsigned long prev_insn;
|
||||||
static struct d10v_opcode *prev_opcode = 0;
|
static struct d10v_opcode *prev_opcode = 0;
|
||||||
@ -1044,9 +1037,9 @@ void
|
|||||||
md_assemble (str)
|
md_assemble (str)
|
||||||
char *str;
|
char *str;
|
||||||
{
|
{
|
||||||
/* etype is saved extype. for multiline instructions */
|
/* etype is saved extype. For multi-line instructions. */
|
||||||
|
|
||||||
packing_type extype = PACK_UNSPEC; /* parallel, etc */
|
packing_type extype = PACK_UNSPEC; /* Parallel, etc. */
|
||||||
|
|
||||||
struct d10v_opcode *opcode;
|
struct d10v_opcode *opcode;
|
||||||
unsigned long insn;
|
unsigned long insn;
|
||||||
@ -1054,7 +1047,7 @@ md_assemble (str)
|
|||||||
|
|
||||||
if (etype == PACK_UNSPEC)
|
if (etype == PACK_UNSPEC)
|
||||||
{
|
{
|
||||||
/* look for the special multiple instruction separators */
|
/* Look for the special multiple instruction separators. */
|
||||||
str2 = strstr (str, "||");
|
str2 = strstr (str, "||");
|
||||||
if (str2)
|
if (str2)
|
||||||
extype = PACK_PARALLEL;
|
extype = PACK_PARALLEL;
|
||||||
@ -1070,16 +1063,16 @@ md_assemble (str)
|
|||||||
extype = PACK_RIGHT_LEFT;
|
extype = PACK_RIGHT_LEFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* str2 points to the separator, if one */
|
/* STR2 points to the separator, if there is one. */
|
||||||
if (str2)
|
if (str2)
|
||||||
{
|
{
|
||||||
*str2 = 0;
|
*str2 = 0;
|
||||||
|
|
||||||
/* if two instructions are present and we already have one saved
|
/* If two instructions are present and we already have one saved,
|
||||||
then first write out the save one */
|
then first write out the saved one. */
|
||||||
d10v_cleanup ();
|
d10v_cleanup ();
|
||||||
|
|
||||||
/* assemble first instruction and save it */
|
/* Assemble first instruction and save it. */
|
||||||
prev_insn = do_assemble (str, &prev_opcode);
|
prev_insn = do_assemble (str, &prev_opcode);
|
||||||
if (prev_insn == -1)
|
if (prev_insn == -1)
|
||||||
as_fatal (_("can't find opcode "));
|
as_fatal (_("can't find opcode "));
|
||||||
@ -1105,7 +1098,8 @@ md_assemble (str)
|
|||||||
etype = PACK_UNSPEC;
|
etype = PACK_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if this is a long instruction, write it and any previous short instruction */
|
/* If this is a long instruction, write it and any previous short
|
||||||
|
instruction. */
|
||||||
if (opcode->format & LONG_OPCODE)
|
if (opcode->format & LONG_OPCODE)
|
||||||
{
|
{
|
||||||
if (extype != PACK_UNSPEC)
|
if (extype != PACK_UNSPEC)
|
||||||
@ -1116,19 +1110,22 @@ md_assemble (str)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_opcode && prev_seg && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
|
if (prev_opcode
|
||||||
|
&& prev_seg
|
||||||
|
&& ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
|
||||||
d10v_cleanup ();
|
d10v_cleanup ();
|
||||||
|
|
||||||
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
|
if (prev_opcode
|
||||||
|
&& (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
|
||||||
{
|
{
|
||||||
/* no instructions saved */
|
/* No instructions saved. */
|
||||||
prev_opcode = NULL;
|
prev_opcode = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (extype != PACK_UNSPEC)
|
if (extype != PACK_UNSPEC)
|
||||||
as_fatal (_("Unable to mix instructions as specified"));
|
as_fatal (_("Unable to mix instructions as specified"));
|
||||||
/* save off last instruction so it may be packed on next pass */
|
/* Save last instruction so it may be packed on next pass. */
|
||||||
prev_opcode = opcode;
|
prev_opcode = opcode;
|
||||||
prev_insn = insn;
|
prev_insn = insn;
|
||||||
prev_seg = now_seg;
|
prev_seg = now_seg;
|
||||||
@ -1137,9 +1134,8 @@ md_assemble (str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assemble a single instruction.
|
||||||
/* do_assemble assembles a single instruction and returns an opcode */
|
Return an opcode, or -1 (an invalid opcode) on error. */
|
||||||
/* it returns -1 (an invalid opcode) on error */
|
|
||||||
|
|
||||||
static unsigned long
|
static unsigned long
|
||||||
do_assemble (str, opcode)
|
do_assemble (str, opcode)
|
||||||
@ -1188,7 +1184,8 @@ do_assemble (str, opcode)
|
|||||||
return (insn);
|
return (insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the symbol which has the same name as the register in the given expression. */
|
/* Find the symbol which has the same name as the register in EXP. */
|
||||||
|
|
||||||
static symbolS *
|
static symbolS *
|
||||||
find_symbol_matching_register (exp)
|
find_symbol_matching_register (exp)
|
||||||
expressionS *exp;
|
expressionS *exp;
|
||||||
@ -1210,10 +1207,9 @@ find_symbol_matching_register (exp)
|
|||||||
return symbol_find (d10v_predefined_registers[i].name);
|
return symbol_find (d10v_predefined_registers[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a pointer to an entry in the opcode table.
|
||||||
/* find_opcode() gets a pointer to an entry in the opcode table. */
|
The function must look at all opcodes with the same name and use
|
||||||
/* It must look at all opcodes with the same name and use the operands */
|
the operands to choose the correct opcode. */
|
||||||
/* to choose the correct opcode. */
|
|
||||||
|
|
||||||
static struct d10v_opcode *
|
static struct d10v_opcode *
|
||||||
find_opcode (opcode, myops)
|
find_opcode (opcode, myops)
|
||||||
@ -1223,11 +1219,11 @@ find_opcode (opcode, myops)
|
|||||||
int i, match, done;
|
int i, match, done;
|
||||||
struct d10v_opcode *next_opcode;
|
struct d10v_opcode *next_opcode;
|
||||||
|
|
||||||
/* get all the operands and save them as expressions */
|
/* Get all the operands and save them as expressions. */
|
||||||
get_operands (myops);
|
get_operands (myops);
|
||||||
|
|
||||||
/* now see if the operand is a fake. If so, find the correct size */
|
/* Now see if the operand is a fake. If so, find the correct size
|
||||||
/* instruction, if possible */
|
instruction, if possible. */
|
||||||
if (opcode->format == OPCODE_FAKE)
|
if (opcode->format == OPCODE_FAKE)
|
||||||
{
|
{
|
||||||
int opnum = opcode->operands[0];
|
int opnum = opcode->operands[0];
|
||||||
@ -1236,7 +1232,8 @@ find_opcode (opcode, myops)
|
|||||||
if (myops[opnum].X_op == O_register)
|
if (myops[opnum].X_op == O_register)
|
||||||
{
|
{
|
||||||
myops[opnum].X_op = O_symbol;
|
myops[opnum].X_op = O_symbol;
|
||||||
myops[opnum].X_add_symbol = symbol_find_or_make ((char *)myops[opnum].X_op_symbol);
|
myops[opnum].X_add_symbol =
|
||||||
|
symbol_find_or_make ((char *) myops[opnum].X_op_symbol);
|
||||||
myops[opnum].X_add_number = 0;
|
myops[opnum].X_add_number = 0;
|
||||||
myops[opnum].X_op_symbol = NULL;
|
myops[opnum].X_op_symbol = NULL;
|
||||||
}
|
}
|
||||||
@ -1261,9 +1258,10 @@ find_opcode (opcode, myops)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myops[opnum].X_op == O_constant || (myops[opnum].X_op == O_symbol &&
|
if (myops[opnum].X_op == O_constant
|
||||||
S_IS_DEFINED(myops[opnum].X_add_symbol) &&
|
|| (myops[opnum].X_op == O_symbol
|
||||||
(S_GET_SEGMENT(myops[opnum].X_add_symbol) == now_seg)))
|
&& S_IS_DEFINED (myops[opnum].X_add_symbol)
|
||||||
|
&& (S_GET_SEGMENT (myops[opnum].X_add_symbol) == now_seg)))
|
||||||
{
|
{
|
||||||
for (i = 0; opcode->operands[i + 1]; i++)
|
for (i = 0; opcode->operands[i + 1]; i++)
|
||||||
{
|
{
|
||||||
@ -1293,7 +1291,9 @@ find_opcode (opcode, myops)
|
|||||||
sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
|
sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
|
||||||
found_symbol = false;
|
found_symbol = false;
|
||||||
|
|
||||||
current_position = obstack_next_free (&frchain_now->frch_obstack) - frag_now->fr_literal;
|
current_position =
|
||||||
|
obstack_next_free (&frchain_now->frch_obstack)
|
||||||
|
- frag_now->fr_literal;
|
||||||
symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);
|
symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);
|
||||||
|
|
||||||
for (f = frchain_now->frch_root; f; f = f->fr_next)
|
for (f = frchain_now->frch_root; f; f = f->fr_next)
|
||||||
@ -1330,15 +1330,15 @@ find_opcode (opcode, myops)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* not a constant, so use a long instruction */
|
/* Not a constant, so use a long instruction. */
|
||||||
return opcode + 2;
|
return opcode + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
match = 0;
|
match = 0;
|
||||||
/* now search the opcode table table for one with operands */
|
/* Now search the opcode table table for one with operands
|
||||||
/* that matches what we've got */
|
that matches what we've got. */
|
||||||
while (!match)
|
while (!match)
|
||||||
{
|
{
|
||||||
match = 1;
|
match = 1;
|
||||||
@ -1377,23 +1377,24 @@ find_opcode (opcode, myops)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unfortunatly, for the indirect operand in instructions such as
|
/* Unfortunatly, for the indirect operand in
|
||||||
``ldb r1, @(c,r14)'' this function can be passed X_op == O_register
|
instructions such as ``ldb r1, @(c,r14)'' this
|
||||||
(because 'c' is a valid register name). However we cannot just
|
function can be passed X_op == O_register (because
|
||||||
ignore the case when X_op == O_register but flags & OPERAND_REG is
|
'c' is a valid register name). However we cannot
|
||||||
null, so we check to see if a symbol of the same name as the register
|
just ignore the case when X_op == O_register but
|
||||||
exists. If the symbol does exist, then the parser was unable to
|
flags & OPERAND_REG is null, so we check to see if a
|
||||||
distinguish the two cases and we fix things here. (Ref: PR14826) */
|
symbol of the same name as the register exists. If
|
||||||
|
the symbol does exist, then the parser was unable to
|
||||||
|
distinguish the two cases and we fix things here.
|
||||||
|
(Ref: PR14826) */
|
||||||
|
|
||||||
if (!(flags & OPERAND_REG) && (X_op == O_register))
|
if (!(flags & OPERAND_REG) && (X_op == O_register))
|
||||||
{
|
{
|
||||||
symbolS * sym;
|
symbolS *sym = find_symbol_matching_register (&myops[i]);
|
||||||
|
|
||||||
sym = find_symbol_matching_register (& myops[i]);
|
|
||||||
|
|
||||||
if (sym != NULL)
|
if (sym != NULL)
|
||||||
{
|
{
|
||||||
myops [i].X_op == X_op == O_symbol;
|
myops[i].X_op = X_op = O_symbol;
|
||||||
myops[i].X_add_symbol = sym;
|
myops[i].X_add_symbol = sym;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1427,9 +1428,9 @@ find_opcode (opcode, myops)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that all registers that are required to be even are. */
|
/* Check that all registers that are required to be even are.
|
||||||
/* Also, if any operands were marked as registers, but were really symbols */
|
Also, if any operands were marked as registers, but were really symbols,
|
||||||
/* fix that here. */
|
fix that here. */
|
||||||
for (i = 0; opcode->operands[i]; i++)
|
for (i = 0; opcode->operands[i]; i++)
|
||||||
{
|
{
|
||||||
if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
|
if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
|
||||||
@ -1440,7 +1441,8 @@ find_opcode (opcode, myops)
|
|||||||
if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
|
if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
|
||||||
{
|
{
|
||||||
myops[i].X_op = O_symbol;
|
myops[i].X_op = O_symbol;
|
||||||
myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
|
myops[i].X_add_symbol =
|
||||||
|
symbol_find_or_make ((char *) myops[i].X_op_symbol);
|
||||||
myops[i].X_add_number = 0;
|
myops[i].X_add_number = 0;
|
||||||
myops[i].X_op_symbol = NULL;
|
myops[i].X_op_symbol = NULL;
|
||||||
}
|
}
|
||||||
@ -1449,8 +1451,8 @@ find_opcode (opcode, myops)
|
|||||||
return opcode;
|
return opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if while processing a fixup, a reloc really needs to be created */
|
/* If while processing a fixup, a reloc really needs to be created.
|
||||||
/* then it is done here */
|
Then it is done here. */
|
||||||
|
|
||||||
arelent *
|
arelent *
|
||||||
tc_gen_reloc (seg, fixp)
|
tc_gen_reloc (seg, fixp)
|
||||||
@ -1466,7 +1468,8 @@ tc_gen_reloc (seg, fixp)
|
|||||||
if (reloc->howto == (reloc_howto_type *) NULL)
|
if (reloc->howto == (reloc_howto_type *) NULL)
|
||||||
{
|
{
|
||||||
as_bad_where (fixp->fx_file, fixp->fx_line,
|
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||||
_("reloc %d not supported by object file format"), (int)fixp->fx_r_type);
|
_("reloc %d not supported by object file format"),
|
||||||
|
(int) fixp->fx_r_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1493,8 +1496,9 @@ md_pcrel_from_section (fixp, sec)
|
|||||||
fixS *fixp;
|
fixS *fixp;
|
||||||
segT sec;
|
segT sec;
|
||||||
{
|
{
|
||||||
if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) ||
|
if (fixp->fx_addsy != (symbolS *) NULL
|
||||||
(S_GET_SEGMENT (fixp->fx_addsy) != sec)))
|
&& (!S_IS_DEFINED (fixp->fx_addsy)
|
||||||
|
|| (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
|
||||||
return 0;
|
return 0;
|
||||||
return fixp->fx_frag->fr_address + fixp->fx_where;
|
return fixp->fx_frag->fr_address + fixp->fx_where;
|
||||||
}
|
}
|
||||||
@ -1550,7 +1554,8 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
fixp->fx_r_type = BFD_RELOC_D10V_18;
|
fixp->fx_r_type = BFD_RELOC_D10V_18;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
|
fixp->fx_r_type =
|
||||||
|
get_reloc ((struct d10v_operand *) &d10v_operands[op_type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch the instruction, insert the fully resolved operand
|
/* Fetch the instruction, insert the fully resolved operand
|
||||||
@ -1564,7 +1569,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
case BFD_RELOC_D10V_10_PCREL_R:
|
case BFD_RELOC_D10V_10_PCREL_R:
|
||||||
case BFD_RELOC_D10V_18_PCREL:
|
case BFD_RELOC_D10V_18_PCREL:
|
||||||
case BFD_RELOC_D10V_18:
|
case BFD_RELOC_D10V_18:
|
||||||
/* instruction addresses are always right-shifted by 2 */
|
/* Instruction addresses are always right-shifted by 2. */
|
||||||
value >>= AT_WORD_RIGHT_SHIFT;
|
value >>= AT_WORD_RIGHT_SHIFT;
|
||||||
if (fixp->fx_size == 2)
|
if (fixp->fx_size == 2)
|
||||||
bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
|
bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
|
||||||
@ -1581,7 +1586,8 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
as_fatal
|
as_fatal
|
||||||
(_("line %d: rep or repi must include at least 4 instructions"),
|
(_("line %d: rep or repi must include at least 4 instructions"),
|
||||||
fixp->fx_line);
|
fixp->fx_line);
|
||||||
insn = d10v_insert_operand (insn, op_type, (offsetT)value, left, fixp);
|
insn =
|
||||||
|
d10v_insert_operand (insn, op_type, (offsetT) value, left, fixp);
|
||||||
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
|
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1598,17 +1604,21 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
as_fatal (_("line %d: unknown relocation type: 0x%x"),fixp->fx_line,fixp->fx_r_type);
|
as_fatal (_("line %d: unknown relocation type: 0x%x"),
|
||||||
|
fixp->fx_line, fixp->fx_r_type);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* d10v_cleanup() is called after the assembler has finished parsing the input
|
/* Called after the assembler has finished parsing the input file or
|
||||||
file or after a label is defined. Because the D10V assembler sometimes saves short
|
after a label is defined. Because the D10V assembler sometimes
|
||||||
instructions to see if it can package them with the next instruction, there may
|
saves short instructions to see if it can package them with the
|
||||||
be a short instruction that still needs written.
|
next instruction, there may be a short instruction that still needs
|
||||||
|
to be written.
|
||||||
|
|
||||||
NOTE: accesses a global, etype.
|
NOTE: accesses a global, etype.
|
||||||
NOTE: invoked by various macros such as md_cleanup: see. */
|
NOTE: invoked by various macros such as md_cleanup: see. */
|
||||||
|
|
||||||
int
|
int
|
||||||
d10v_cleanup ()
|
d10v_cleanup ()
|
||||||
{
|
{
|
||||||
@ -1628,8 +1638,9 @@ d10v_cleanup ()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like normal .word, except support @word */
|
/* Like normal .word, except support @word. */
|
||||||
/* clobbers input_line_pointer, checks end-of-line. */
|
/* Clobbers input_line_pointer, checks end-of-line. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
d10v_dot_word (nbytes)
|
d10v_dot_word (nbytes)
|
||||||
register int nbytes; /* 1=.byte, 2=.word, 4=.long */
|
register int nbytes; /* 1=.byte, 2=.word, 4=.long */
|
||||||
@ -1666,16 +1677,15 @@ d10v_dot_word (nbytes)
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mitsubishi asked that we support some old syntax that apparently
|
||||||
|
had immediate operands starting with '#'. This is in some of their
|
||||||
|
sample code but is not documented (although it appears in some
|
||||||
|
examples in their assembler manual). For now, we'll solve this
|
||||||
|
compatibility problem by simply ignoring any '#' at the beginning
|
||||||
|
of an operand. */
|
||||||
|
|
||||||
/* Mitsubishi asked that we support some old syntax that apparently */
|
/* Operands that begin with '#' should fall through to here. */
|
||||||
/* had immediate operands starting with '#'. This is in some of their */
|
/* From expr.c. */
|
||||||
/* sample code but is not documented (although it appears in some */
|
|
||||||
/* examples in their assembler manual). For now, we'll solve this */
|
|
||||||
/* compatibility problem by simply ignoring any '#' at the beginning */
|
|
||||||
/* of an operand. */
|
|
||||||
|
|
||||||
/* operands that begin with '#' should fall through to here */
|
|
||||||
/* from expr.c */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
md_operand (expressionP)
|
md_operand (expressionP)
|
||||||
@ -1692,7 +1702,6 @@ boolean
|
|||||||
d10v_fix_adjustable (fixP)
|
d10v_fix_adjustable (fixP)
|
||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
{
|
{
|
||||||
|
|
||||||
if (fixP->fx_addsy == NULL)
|
if (fixP->fx_addsy == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -1702,7 +1711,7 @@ d10v_fix_adjustable (fixP)
|
|||||||
if (S_IS_WEAK (fixP->fx_addsy))
|
if (S_IS_WEAK (fixP->fx_addsy))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* We need the symbol name for the VTABLE entries */
|
/* We need the symbol name for the VTABLE entries. */
|
||||||
if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
||||||
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* tc-sparc.c -- Assemble for the SPARC
|
/* tc-sparc.c -- Assemble for the SPARC
|
||||||
Copyright (C) 1989, 90-96, 97, 98, 99, 2000 Free Software Foundation, Inc.
|
Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
|
||||||
|
Free Software Foundation, Inc.
|
||||||
This file is part of GAS, the GNU Assembler.
|
This file is part of GAS, the GNU Assembler.
|
||||||
|
|
||||||
GAS is free software; you can redistribute it and/or modify
|
GAS is free software; you can redistribute it and/or modify
|
||||||
@ -117,7 +118,7 @@ static symbolS *globals[8];
|
|||||||
|| SPARC_OPCODE_ARCH_V9_P (max_architecture))
|
|| SPARC_OPCODE_ARCH_V9_P (max_architecture))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* handle of the OPCODE hash table */
|
/* Handle of the OPCODE hash table. */
|
||||||
static struct hash_control *op_hash;
|
static struct hash_control *op_hash;
|
||||||
|
|
||||||
static int log2 PARAMS ((int));
|
static int log2 PARAMS ((int));
|
||||||
@ -133,7 +134,7 @@ static void s_register PARAMS ((int));
|
|||||||
|
|
||||||
const pseudo_typeS md_pseudo_table[] =
|
const pseudo_typeS md_pseudo_table[] =
|
||||||
{
|
{
|
||||||
{"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
|
{"align", s_align_bytes, 0}, /* Defaulting is invalid (0). */
|
||||||
{"common", s_common, 0},
|
{"common", s_common, 0},
|
||||||
{"empty", s_empty, 0},
|
{"empty", s_empty, 0},
|
||||||
{"global", s_globl, 0},
|
{"global", s_globl, 0},
|
||||||
@ -150,7 +151,7 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{"uaword", s_uacons, 4},
|
{"uaword", s_uacons, 4},
|
||||||
{"uaxword", s_uacons, 8},
|
{"uaxword", s_uacons, 8},
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
/* these are specific to sparc/svr4 */
|
/* These are specific to sparc/svr4. */
|
||||||
{"2byte", s_uacons, 2},
|
{"2byte", s_uacons, 2},
|
||||||
{"4byte", s_uacons, 4},
|
{"4byte", s_uacons, 4},
|
||||||
{"8byte", s_uacons, 8},
|
{"8byte", s_uacons, 8},
|
||||||
@ -159,15 +160,17 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{NULL, 0, 0},
|
{NULL, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
const int md_reloc_size = 12; /* Size of relocation record */
|
/* Size of relocation record. */
|
||||||
|
const int md_reloc_size = 12;
|
||||||
|
|
||||||
/* This array holds the chars that always start a comment. If the
|
/* This array holds the chars that always start a comment. If the
|
||||||
pre-processor is disabled, these aren't very useful */
|
pre-processor is disabled, these aren't very useful. */
|
||||||
const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
|
const char comment_chars[] = "!"; /* JF removed '|' from
|
||||||
|
comment_chars. */
|
||||||
|
|
||||||
/* This array holds the chars that only start a comment at the beginning of
|
/* This array holds the chars that only start a comment at the beginning of
|
||||||
a line. If the line seems to have the form '# 123 filename'
|
a line. If the line seems to have the form '# 123 filename'
|
||||||
.line and .file directives will appear in the pre-processed output */
|
.line and .file directives will appear in the pre-processed output. */
|
||||||
/* Note that input_file.c hand checks for '#' at the beginning of the
|
/* Note that input_file.c hand checks for '#' at the beginning of the
|
||||||
first line of the input file. This is because the compiler outputs
|
first line of the input file. This is because the compiler outputs
|
||||||
#NO_APP at the beginning of its output. */
|
#NO_APP at the beginning of its output. */
|
||||||
@ -177,12 +180,13 @@ const char line_comment_chars[] = "#";
|
|||||||
|
|
||||||
const char line_separator_chars[] = ";";
|
const char line_separator_chars[] = ";";
|
||||||
|
|
||||||
/* Chars that can be used to separate mant from exp in floating point nums */
|
/* Chars that can be used to separate mant from exp in floating point
|
||||||
|
nums. */
|
||||||
const char EXP_CHARS[] = "eE";
|
const char EXP_CHARS[] = "eE";
|
||||||
|
|
||||||
/* Chars that mean this number is a floating point constant */
|
/* Chars that mean this number is a floating point constant.
|
||||||
/* As in 0f12.456 */
|
As in 0f12.456
|
||||||
/* or 0d1.2345e12 */
|
or 0d1.2345e12 */
|
||||||
const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
||||||
|
|
||||||
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
|
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
|
||||||
@ -323,8 +327,7 @@ sparc_target_format ()
|
|||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* md_parse_option
|
||||||
* md_parse_option
|
|
||||||
* Invocation line includes a switch not recognized by the base assembler.
|
* Invocation line includes a switch not recognized by the base assembler.
|
||||||
* See if it's a processor-specific option. These are:
|
* See if it's a processor-specific option. These are:
|
||||||
*
|
*
|
||||||
@ -424,6 +427,7 @@ struct option md_longopts[] = {
|
|||||||
{"no-relax", no_argument, NULL, OPTION_NO_RELAX},
|
{"no-relax", no_argument, NULL, OPTION_NO_RELAX},
|
||||||
{NULL, no_argument, NULL, 0}
|
{NULL, no_argument, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t md_longopts_size = sizeof (md_longopts);
|
size_t md_longopts_size = sizeof (md_longopts);
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -451,8 +455,7 @@ md_parse_option (c, arg)
|
|||||||
as_bad (_("invalid architecture -xarch=%s"), arg);
|
as_bad (_("invalid architecture -xarch=%s"), arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* Fall through. */
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
{
|
{
|
||||||
@ -554,15 +557,15 @@ md_parse_option (c, arg)
|
|||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
/* Qy - do emit .comment
|
/* Qy - do emit .comment
|
||||||
Qn - do not emit .comment */
|
Qn - do not emit .comment. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
/* use .stab instead of .stab.excl */
|
/* Use .stab instead of .stab.excl. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
/* quick -- native assembler does fewer checks */
|
/* quick -- Native assembler does fewer checks. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'K':
|
case 'K':
|
||||||
@ -659,7 +662,7 @@ md_show_usage (stream)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* native operand size opcode translation */
|
/* Native operand size opcode translation. */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
@ -680,7 +683,7 @@ struct
|
|||||||
{NULL, NULL, NULL},
|
{NULL, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* sparc64 priviledged registers */
|
/* sparc64 priviledged registers. */
|
||||||
|
|
||||||
struct priv_reg_entry
|
struct priv_reg_entry
|
||||||
{
|
{
|
||||||
@ -707,10 +710,10 @@ struct priv_reg_entry priv_reg_table[] =
|
|||||||
{"wstate", 14},
|
{"wstate", 14},
|
||||||
{"fq", 15},
|
{"fq", 15},
|
||||||
{"ver", 31},
|
{"ver", 31},
|
||||||
{"", -1}, /* end marker */
|
{"", -1}, /* End marker. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* v9a specific asrs */
|
/* v9a specific asrs. */
|
||||||
|
|
||||||
struct priv_reg_entry v9a_asr_table[] =
|
struct priv_reg_entry v9a_asr_table[] =
|
||||||
{
|
{
|
||||||
@ -722,7 +725,7 @@ struct priv_reg_entry v9a_asr_table[] =
|
|||||||
{"gsr", 19},
|
{"gsr", 19},
|
||||||
{"dcr", 18},
|
{"dcr", 18},
|
||||||
{"clear_softint", 21},
|
{"clear_softint", 21},
|
||||||
{"", -1}, /* end marker */
|
{"", -1}, /* End marker. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -737,7 +740,8 @@ cmp_reg_entry (parg, qarg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called once, at assembler startup time. It should
|
/* This function is called once, at assembler startup time. It should
|
||||||
set up all the tables, etc. that the MD part of the assembler will need. */
|
set up all the tables, etc. that the MD part of the assembler will
|
||||||
|
need. */
|
||||||
|
|
||||||
void
|
void
|
||||||
md_begin ()
|
md_begin ()
|
||||||
@ -857,9 +861,9 @@ sparc_md_end ()
|
|||||||
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_sparclite_le);
|
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_sparclite_le);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The sparclite is treated like a normal sparc. Perhaps it shouldn't
|
/* The sparclite is treated like a normal sparc. Perhaps it
|
||||||
be but for now it is (since that's the way it's always been
|
shouldn't be but for now it is (since that's the way it's
|
||||||
treated). */
|
always been treated). */
|
||||||
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc);
|
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -967,6 +971,7 @@ static const struct sparc_opcode *last_insn;
|
|||||||
static unsigned long last_opcode;
|
static unsigned long last_opcode;
|
||||||
|
|
||||||
/* Handle the set and setuw synthetic instructions. */
|
/* Handle the set and setuw synthetic instructions. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
synthetize_setuw (insn)
|
synthetize_setuw (insn)
|
||||||
const struct sparc_opcode *insn;
|
const struct sparc_opcode *insn;
|
||||||
@ -1026,6 +1031,7 @@ synthetize_setuw (insn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the setsw synthetic instruction. */
|
/* Handle the setsw synthetic instruction. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
synthetize_setsw (insn)
|
synthetize_setsw (insn)
|
||||||
const struct sparc_opcode *insn;
|
const struct sparc_opcode *insn;
|
||||||
@ -1077,6 +1083,7 @@ synthetize_setsw (insn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the setsw synthetic instruction. */
|
/* Handle the setsw synthetic instruction. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
synthetize_setx (insn)
|
synthetize_setx (insn)
|
||||||
const struct sparc_opcode *insn;
|
const struct sparc_opcode *insn;
|
||||||
@ -1285,7 +1292,7 @@ md_assemble (str)
|
|||||||
switch (special_case)
|
switch (special_case)
|
||||||
{
|
{
|
||||||
case SPECIAL_CASE_NONE:
|
case SPECIAL_CASE_NONE:
|
||||||
/* normal insn */
|
/* Normal insn. */
|
||||||
output_insn (insn, &the_insn);
|
output_insn (insn, &the_insn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1358,8 +1365,7 @@ sparc_ip (str, pinsn)
|
|||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
comma = 1;
|
comma = 1;
|
||||||
|
/* Fall through. */
|
||||||
/*FALLTHROUGH */
|
|
||||||
|
|
||||||
case ' ':
|
case ' ':
|
||||||
*s++ = '\0';
|
*s++ = '\0';
|
||||||
@ -1388,10 +1394,8 @@ sparc_ip (str, pinsn)
|
|||||||
the_insn.reloc = BFD_RELOC_NONE;
|
the_insn.reloc = BFD_RELOC_NONE;
|
||||||
v9_arg_p = 0;
|
v9_arg_p = 0;
|
||||||
|
|
||||||
/*
|
/* Build the opcode, checking as we go to make sure that the
|
||||||
* Build the opcode, checking as we go to make
|
operands match. */
|
||||||
* sure that the operands match
|
|
||||||
*/
|
|
||||||
for (args = insn->args;; ++args)
|
for (args = insn->args;; ++args)
|
||||||
{
|
{
|
||||||
switch (*args)
|
switch (*args)
|
||||||
@ -1474,7 +1478,7 @@ sparc_ip (str, pinsn)
|
|||||||
if (*s == '%')
|
if (*s == '%')
|
||||||
{
|
{
|
||||||
struct priv_reg_entry *p = priv_reg_table;
|
struct priv_reg_entry *p = priv_reg_table;
|
||||||
unsigned int len = 9999999; /* init to make gcc happy */
|
unsigned int len = 9999999; /* Init to make gcc happy. */
|
||||||
|
|
||||||
s += 1;
|
s += 1;
|
||||||
while (p->name[0] > s[0])
|
while (p->name[0] > s[0])
|
||||||
@ -1510,7 +1514,7 @@ sparc_ip (str, pinsn)
|
|||||||
if (*s == '%')
|
if (*s == '%')
|
||||||
{
|
{
|
||||||
struct priv_reg_entry *p = v9a_asr_table;
|
struct priv_reg_entry *p = v9a_asr_table;
|
||||||
unsigned int len = 9999999; /* init to make gcc happy */
|
unsigned int len = 9999999; /* Init to make gcc happy. */
|
||||||
|
|
||||||
s += 1;
|
s += 1;
|
||||||
while (p->name[0] > s[0])
|
while (p->name[0] > s[0])
|
||||||
@ -1731,7 +1735,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\0': /* end of args */
|
case '\0': /* End of args. */
|
||||||
if (*s == '\0')
|
if (*s == '\0')
|
||||||
{
|
{
|
||||||
match = 1;
|
match = 1;
|
||||||
@ -1750,7 +1754,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[': /* these must match exactly */
|
case '[': /* These must match exactly. */
|
||||||
case ']':
|
case ']':
|
||||||
case ',':
|
case ',':
|
||||||
case ' ':
|
case ' ':
|
||||||
@ -1758,7 +1762,7 @@ sparc_ip (str, pinsn)
|
|||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '#': /* must be at least one digit */
|
case '#': /* Must be at least one digit. */
|
||||||
if (isdigit ((unsigned char) *s++))
|
if (isdigit ((unsigned char) *s++))
|
||||||
{
|
{
|
||||||
while (isdigit ((unsigned char) *s))
|
while (isdigit ((unsigned char) *s))
|
||||||
@ -1769,7 +1773,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C': /* coprocessor state register */
|
case 'C': /* Coprocessor state register. */
|
||||||
if (strncmp (s, "%csr", 4) == 0)
|
if (strncmp (s, "%csr", 4) == 0)
|
||||||
{
|
{
|
||||||
s += 4;
|
s += 4;
|
||||||
@ -1777,7 +1781,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b': /* next operand is a coprocessor register */
|
case 'b': /* Next operand is a coprocessor register. */
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'D':
|
case 'D':
|
||||||
if (*s++ == '%' && *s++ == 'c' && isdigit ((unsigned char) *s))
|
if (*s++ == '%' && *s++ == 'c' && isdigit ((unsigned char) *s))
|
||||||
@ -2014,7 +2018,6 @@ sparc_ip (str, pinsn)
|
|||||||
opcode |= RS1 (mask);
|
opcode |= RS1 (mask);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'R':
|
case 'R':
|
||||||
@ -2172,7 +2175,8 @@ sparc_ip (str, pinsn)
|
|||||||
memset (&the_insn.exp, 0, sizeof (the_insn.exp));
|
memset (&the_insn.exp, 0, sizeof (the_insn.exp));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;
|
for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++)
|
||||||
|
;
|
||||||
|
|
||||||
if (s1 != s && isdigit ((unsigned char) s1[-1]))
|
if (s1 != s && isdigit ((unsigned char) s1[-1]))
|
||||||
{
|
{
|
||||||
@ -2227,7 +2231,7 @@ sparc_ip (str, pinsn)
|
|||||||
|
|
||||||
case BFD_RELOC_SPARC_HH22:
|
case BFD_RELOC_SPARC_HH22:
|
||||||
val = BSR (val, 32);
|
val = BSR (val, 32);
|
||||||
/* intentional fallthrough */
|
/* Fall through. */
|
||||||
|
|
||||||
case BFD_RELOC_SPARC_LM22:
|
case BFD_RELOC_SPARC_LM22:
|
||||||
case BFD_RELOC_HI22:
|
case BFD_RELOC_HI22:
|
||||||
@ -2236,7 +2240,7 @@ sparc_ip (str, pinsn)
|
|||||||
|
|
||||||
case BFD_RELOC_SPARC_HM10:
|
case BFD_RELOC_SPARC_HM10:
|
||||||
val = BSR (val, 32);
|
val = BSR (val, 32);
|
||||||
/* intentional fallthrough */
|
/* Fall through. */
|
||||||
|
|
||||||
case BFD_RELOC_LO10:
|
case BFD_RELOC_LO10:
|
||||||
val &= 0x3ff;
|
val &= 0x3ff;
|
||||||
@ -2352,7 +2356,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
opcode |= ASI (asi);
|
opcode |= ASI (asi);
|
||||||
continue;
|
continue;
|
||||||
} /* alternate space */
|
} /* Alternate space. */
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
if (strncmp (s, "%psr", 4) == 0)
|
if (strncmp (s, "%psr", 4) == 0)
|
||||||
@ -2362,7 +2366,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q': /* floating point queue */
|
case 'q': /* Floating point queue. */
|
||||||
if (strncmp (s, "%fq", 3) == 0)
|
if (strncmp (s, "%fq", 3) == 0)
|
||||||
{
|
{
|
||||||
s += 3;
|
s += 3;
|
||||||
@ -2370,7 +2374,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Q': /* coprocessor queue */
|
case 'Q': /* Coprocessor queue. */
|
||||||
if (strncmp (s, "%cq", 3) == 0)
|
if (strncmp (s, "%cq", 3) == 0)
|
||||||
{
|
{
|
||||||
s += 3;
|
s += 3;
|
||||||
@ -2476,11 +2480,11 @@ sparc_ip (str, pinsn)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
as_fatal (_("failed sanity check."));
|
as_fatal (_("failed sanity check."));
|
||||||
} /* switch on arg code */
|
} /* switch on arg code. */
|
||||||
|
|
||||||
/* Break out of for() loop. */
|
/* Break out of for() loop. */
|
||||||
break;
|
break;
|
||||||
} /* for each arg that we expect */
|
} /* For each arg that we expect. */
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (match == 0)
|
if (match == 0)
|
||||||
@ -2502,7 +2506,7 @@ sparc_ip (str, pinsn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We have a match. Now see if the architecture is ok. */
|
/* We have a match. Now see if the architecture is OK. */
|
||||||
int needed_arch_mask = insn->architecture;
|
int needed_arch_mask = insn->architecture;
|
||||||
|
|
||||||
if (v9_arg_p)
|
if (v9_arg_p)
|
||||||
@ -2512,10 +2516,13 @@ sparc_ip (str, pinsn)
|
|||||||
needed_arch_mask |= (1 << SPARC_OPCODE_ARCH_V9);
|
needed_arch_mask |= (1 << SPARC_OPCODE_ARCH_V9);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needed_arch_mask & SPARC_OPCODE_SUPPORTED (current_architecture))
|
if (needed_arch_mask
|
||||||
; /* ok */
|
& SPARC_OPCODE_SUPPORTED (current_architecture))
|
||||||
|
/* OK. */
|
||||||
|
;
|
||||||
/* Can we bump up the architecture? */
|
/* Can we bump up the architecture? */
|
||||||
else if (needed_arch_mask & SPARC_OPCODE_SUPPORTED (max_architecture))
|
else if (needed_arch_mask
|
||||||
|
& SPARC_OPCODE_SUPPORTED (max_architecture))
|
||||||
{
|
{
|
||||||
enum sparc_opcode_arch_val needed_architecture =
|
enum sparc_opcode_arch_val needed_architecture =
|
||||||
sparc_ffs (SPARC_OPCODE_SUPPORTED (max_architecture)
|
sparc_ffs (SPARC_OPCODE_SUPPORTED (max_architecture)
|
||||||
@ -2567,10 +2574,10 @@ sparc_ip (str, pinsn)
|
|||||||
sparc_opcode_archs[max_architecture].name);
|
sparc_opcode_archs[max_architecture].name);
|
||||||
return special_case;
|
return special_case;
|
||||||
}
|
}
|
||||||
} /* if no match */
|
} /* If no match. */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} /* forever looking for a match */
|
} /* Forever looking for a match. */
|
||||||
|
|
||||||
the_insn.opcode = opcode;
|
the_insn.opcode = opcode;
|
||||||
return special_case;
|
return special_case;
|
||||||
@ -2676,18 +2683,18 @@ output_insn (insn, the_insn)
|
|||||||
{
|
{
|
||||||
char *toP = frag_more (4);
|
char *toP = frag_more (4);
|
||||||
|
|
||||||
/* put out the opcode */
|
/* Put out the opcode. */
|
||||||
if (INSN_BIG_ENDIAN)
|
if (INSN_BIG_ENDIAN)
|
||||||
number_to_chars_bigendian (toP, (valueT) the_insn->opcode, 4);
|
number_to_chars_bigendian (toP, (valueT) the_insn->opcode, 4);
|
||||||
else
|
else
|
||||||
number_to_chars_littleendian (toP, (valueT) the_insn->opcode, 4);
|
number_to_chars_littleendian (toP, (valueT) the_insn->opcode, 4);
|
||||||
|
|
||||||
/* put out the symbol-dependent stuff */
|
/* Put out the symbol-dependent stuff. */
|
||||||
if (the_insn->reloc != BFD_RELOC_NONE)
|
if (the_insn->reloc != BFD_RELOC_NONE)
|
||||||
{
|
{
|
||||||
fixS *fixP = fix_new_exp (frag_now, /* which frag */
|
fixS *fixP = fix_new_exp (frag_now, /* Which frag. */
|
||||||
(toP - frag_now->fr_literal), /* where */
|
(toP - frag_now->fr_literal), /* Where. */
|
||||||
4, /* size */
|
4, /* Size. */
|
||||||
&the_insn->exp,
|
&the_insn->exp,
|
||||||
the_insn->pcrel,
|
the_insn->pcrel,
|
||||||
the_insn->reloc);
|
the_insn->reloc);
|
||||||
@ -2704,16 +2711,15 @@ output_insn (insn, the_insn)
|
|||||||
last_opcode = the_insn->opcode;
|
last_opcode = the_insn->opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* This is identical to the md_atof in m68k.c. I think this is right,
|
||||||
This is identical to the md_atof in m68k.c. I think this is right,
|
|
||||||
but I'm not sure.
|
but I'm not sure.
|
||||||
|
|
||||||
Turn a string in input_line_pointer into a floating point constant of type
|
Turn a string in input_line_pointer into a floating point constant
|
||||||
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
|
of type TYPE, and store the appropriate bytes in *LITP. The number
|
||||||
emitted is stored in *sizeP . An error message is returned, or NULL on OK.
|
of LITTLENUMS emitted is stored in *SIZEP. An error message is
|
||||||
*/
|
returned, or NULL on OK. */
|
||||||
|
|
||||||
/* Equal to MAX_PRECISION in atof-ieee.c */
|
/* Equal to MAX_PRECISION in atof-ieee.c. */
|
||||||
#define MAX_LITTLENUMS 6
|
#define MAX_LITTLENUMS 6
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -2795,7 +2801,8 @@ md_number_to_chars (buf, val, n)
|
|||||||
number_to_chars_bigendian (buf, val, n);
|
number_to_chars_bigendian (buf, val, n);
|
||||||
else if (target_little_endian_data
|
else if (target_little_endian_data
|
||||||
&& ((n == 4 || n == 2) && ~now_seg->flags & SEC_ALLOC))
|
&& ((n == 4 || n == 2) && ~now_seg->flags & SEC_ALLOC))
|
||||||
/* Output debug words, which are not in allocated sections, as big endian */
|
/* Output debug words, which are not in allocated sections, as big
|
||||||
|
endian. */
|
||||||
number_to_chars_bigendian (buf, val, n);
|
number_to_chars_bigendian (buf, val, n);
|
||||||
else if (target_little_endian_data || ! target_big_endian)
|
else if (target_little_endian_data || ! target_big_endian)
|
||||||
number_to_chars_littleendian (buf, val, n);
|
number_to_chars_littleendian (buf, val, n);
|
||||||
@ -2818,7 +2825,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
|
|
||||||
assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
|
assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
|
||||||
|
|
||||||
fixP->fx_addnumber = val; /* Remember value for emit_reloc */
|
fixP->fx_addnumber = val; /* Remember value for emit_reloc. */
|
||||||
|
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
/* FIXME: SPARC ELF relocations don't use an addend in the data
|
/* FIXME: SPARC ELF relocations don't use an addend in the data
|
||||||
@ -2935,7 +2942,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
|
|
||||||
insn |= val & 0x3fffffff;
|
insn |= val & 0x3fffffff;
|
||||||
|
|
||||||
/* See if we have a delay slot */
|
/* See if we have a delay slot. */
|
||||||
if (sparc_relax && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
|
if (sparc_relax && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
|
||||||
{
|
{
|
||||||
#define G0 0
|
#define G0 0
|
||||||
@ -2962,8 +2969,8 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
delay = bfd_getl32 ((unsigned char *) buf + 4);
|
delay = bfd_getl32 ((unsigned char *) buf + 4);
|
||||||
if ((insn & OP (~0)) != OP (1) || (delay & OP (~0)) != OP (2))
|
if ((insn & OP (~0)) != OP (1) || (delay & OP (~0)) != OP (2))
|
||||||
break;
|
break;
|
||||||
if ((delay & OP3(~0)) != OP3(0x3d) /* restore */
|
if ((delay & OP3 (~0)) != OP3 (0x3d) /* Restore. */
|
||||||
&& ((delay & OP3(0x28)) != 0 /* arithmetic */
|
&& ((delay & OP3 (0x28)) != 0 /* Arithmetic. */
|
||||||
|| ((delay & RD (~0)) != RD (O7))))
|
|| ((delay & RD (~0)) != RD (O7))))
|
||||||
break;
|
break;
|
||||||
if ((delay & RS1 (~0)) == RS1 (O7)
|
if ((delay & RS1 (~0)) == RS1 (O7)
|
||||||
@ -3055,7 +3062,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_SPARC_WDISP16:
|
case BFD_RELOC_SPARC_WDISP16:
|
||||||
/* FIXME: simplify */
|
/* FIXME: simplify. */
|
||||||
if (((val > 0) && (val & ~0x3fffc))
|
if (((val > 0) && (val & ~0x3fffc))
|
||||||
|| ((val < 0) && (~(val - 1) & ~0x3fffc)))
|
|| ((val < 0) && (~(val - 1) & ~0x3fffc)))
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
@ -3066,7 +3073,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_SPARC_WDISP19:
|
case BFD_RELOC_SPARC_WDISP19:
|
||||||
/* FIXME: simplify */
|
/* FIXME: simplify. */
|
||||||
if (((val > 0) && (val & ~0x1ffffc))
|
if (((val > 0) && (val & ~0x1ffffc))
|
||||||
|| ((val < 0) && (~(val - 1) & ~0x1ffffc)))
|
|| ((val < 0) && (~(val - 1) & ~0x1ffffc)))
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
@ -3078,7 +3085,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
|
|
||||||
case BFD_RELOC_SPARC_HH22:
|
case BFD_RELOC_SPARC_HH22:
|
||||||
val = BSR (val, 32);
|
val = BSR (val, 32);
|
||||||
/* intentional fallthrough */
|
/* Fall through. */
|
||||||
|
|
||||||
case BFD_RELOC_SPARC_LM22:
|
case BFD_RELOC_SPARC_LM22:
|
||||||
case BFD_RELOC_HI22:
|
case BFD_RELOC_HI22:
|
||||||
@ -3102,7 +3109,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
|
|
||||||
case BFD_RELOC_SPARC_HM10:
|
case BFD_RELOC_SPARC_HM10:
|
||||||
val = BSR (val, 32);
|
val = BSR (val, 32);
|
||||||
/* intentional fallthrough */
|
/* Fall through. */
|
||||||
|
|
||||||
case BFD_RELOC_LO10:
|
case BFD_RELOC_LO10:
|
||||||
if (!fixP->fx_addsy)
|
if (!fixP->fx_addsy)
|
||||||
@ -3119,7 +3126,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
case BFD_RELOC_SPARC_OLO10:
|
case BFD_RELOC_SPARC_OLO10:
|
||||||
val &= 0x3ff;
|
val &= 0x3ff;
|
||||||
val += fixP->tc_fix_data;
|
val += fixP->tc_fix_data;
|
||||||
/* intentional fallthrough */
|
/* Fall through. */
|
||||||
|
|
||||||
case BFD_RELOC_SPARC13:
|
case BFD_RELOC_SPARC13:
|
||||||
if (! in_signed_range (val, 0x1fff))
|
if (! in_signed_range (val, 0x1fff))
|
||||||
@ -3130,7 +3137,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
|
|
||||||
case BFD_RELOC_SPARC_WDISP22:
|
case BFD_RELOC_SPARC_WDISP22:
|
||||||
val = (val >> 2) + 1;
|
val = (val >> 2) + 1;
|
||||||
/* FALLTHROUGH */
|
/* Fall through. */
|
||||||
case BFD_RELOC_SPARC_BASE22:
|
case BFD_RELOC_SPARC_BASE22:
|
||||||
insn |= val & 0x3fffff;
|
insn |= val & 0x3fffff;
|
||||||
break;
|
break;
|
||||||
@ -3190,6 +3197,7 @@ md_apply_fix3 (fixP, value, segment)
|
|||||||
|
|
||||||
/* Translate internal representation of relocation info to BFD target
|
/* Translate internal representation of relocation info to BFD target
|
||||||
format. */
|
format. */
|
||||||
|
|
||||||
arelent **
|
arelent **
|
||||||
tc_gen_reloc (section, fixp)
|
tc_gen_reloc (section, fixp)
|
||||||
asection *section;
|
asection *section;
|
||||||
@ -3358,15 +3366,15 @@ tc_gen_reloc (section, fixp)
|
|||||||
|
|
||||||
/* We have no need to default values of symbols. */
|
/* We have no need to default values of symbols. */
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
symbolS *
|
symbolS *
|
||||||
md_undefined_symbol (name)
|
md_undefined_symbol (name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
} /* md_undefined_symbol() */
|
}
|
||||||
|
|
||||||
/* Round up a section size to the appropriate boundary. */
|
/* Round up a section size to the appropriate boundary. */
|
||||||
|
|
||||||
valueT
|
valueT
|
||||||
md_section_align (segment, size)
|
md_section_align (segment, size)
|
||||||
segT segment;
|
segT segment;
|
||||||
@ -3378,7 +3386,8 @@ md_section_align (segment, size)
|
|||||||
valueT align = ((valueT) 1
|
valueT align = ((valueT) 1
|
||||||
<< (valueT) bfd_get_section_alignment (stdoutput, segment));
|
<< (valueT) bfd_get_section_alignment (stdoutput, segment));
|
||||||
valueT newsize;
|
valueT newsize;
|
||||||
/* turn alignment value into a mask */
|
|
||||||
|
/* Turn alignment value into a mask. */
|
||||||
align--;
|
align--;
|
||||||
newsize = (size + align) & ~align;
|
newsize = (size + align) & ~align;
|
||||||
return newsize;
|
return newsize;
|
||||||
@ -3423,9 +3432,7 @@ log2 (value)
|
|||||||
return (value == 1) ? shift : -1;
|
return (value == 1) ? shift : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Sort of like s_lcomm. */
|
||||||
* sort of like s_lcomm
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef OBJ_ELF
|
#ifndef OBJ_ELF
|
||||||
static int max_alignment = 15;
|
static int max_alignment = 15;
|
||||||
@ -3463,7 +3470,7 @@ s_reserve (ignore)
|
|||||||
as_bad (_("BSS length (%d.) <0! Ignored."), size);
|
as_bad (_("BSS length (%d.) <0! Ignored."), size);
|
||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
return;
|
return;
|
||||||
} /* bad length */
|
} /* Bad length. */
|
||||||
|
|
||||||
*p = 0;
|
*p = 0;
|
||||||
symbolP = symbol_find_or_make (name);
|
symbolP = symbol_find_or_make (name);
|
||||||
@ -3542,12 +3549,14 @@ s_reserve (ignore)
|
|||||||
segT current_seg = now_seg;
|
segT current_seg = now_seg;
|
||||||
subsegT current_subseg = now_subseg;
|
subsegT current_subseg = now_subseg;
|
||||||
|
|
||||||
subseg_set (bss_section, 1); /* switch to bss */
|
/* Switch to bss. */
|
||||||
|
subseg_set (bss_section, 1);
|
||||||
|
|
||||||
if (align)
|
if (align)
|
||||||
frag_align (align, 0, 0); /* do alignment */
|
/* Do alignment. */
|
||||||
|
frag_align (align, 0, 0);
|
||||||
|
|
||||||
/* detach from old frag */
|
/* Detach from old frag. */
|
||||||
if (S_GET_SEGMENT(symbolP) == bss_section)
|
if (S_GET_SEGMENT(symbolP) == bss_section)
|
||||||
symbol_get_frag (symbolP)->fr_symbol = NULL;
|
symbol_get_frag (symbolP)->fr_symbol = NULL;
|
||||||
|
|
||||||
@ -3569,7 +3578,7 @@ s_reserve (ignore)
|
|||||||
{
|
{
|
||||||
as_warn("Ignoring attempt to re-define symbol %s",
|
as_warn("Ignoring attempt to re-define symbol %s",
|
||||||
S_GET_NAME (symbolP));
|
S_GET_NAME (symbolP));
|
||||||
} /* if not redefining */
|
} /* if not redefining. */
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
@ -3586,7 +3595,7 @@ s_common (ignore)
|
|||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
c = get_symbol_end ();
|
c = get_symbol_end ();
|
||||||
/* just after name is now '\0' */
|
/* Just after name is now '\0'. */
|
||||||
p = input_line_pointer;
|
p = input_line_pointer;
|
||||||
*p = c;
|
*p = c;
|
||||||
SKIP_WHITESPACE ();
|
SKIP_WHITESPACE ();
|
||||||
@ -3596,7 +3605,10 @@ s_common (ignore)
|
|||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
input_line_pointer++; /* skip ',' */
|
|
||||||
|
/* Skip ','. */
|
||||||
|
input_line_pointer++;
|
||||||
|
|
||||||
if ((temp = get_absolute_expression ()) < 0)
|
if ((temp = get_absolute_expression ()) < 0)
|
||||||
{
|
{
|
||||||
as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
|
as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
|
||||||
@ -3790,7 +3802,7 @@ s_seg (ignore)
|
|||||||
/* We only support 2 segments -- text and data -- for now, so
|
/* We only support 2 segments -- text and data -- for now, so
|
||||||
things in the "bss segment" will have to go into data for now.
|
things in the "bss segment" will have to go into data for now.
|
||||||
You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
|
You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
|
||||||
subseg_set (data_section, 255); /* FIXME-SOMEDAY */
|
subseg_set (data_section, 255); /* FIXME-SOMEDAY. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
as_bad (_("Unknown segment type"));
|
as_bad (_("Unknown segment type"));
|
||||||
@ -4033,7 +4045,8 @@ sparc_handle_align (fragp)
|
|||||||
|
|
||||||
for (i = 0; i < count; i += 4, p++)
|
for (i = 0; i < count; i += 4, p++)
|
||||||
if (INSN_BIG_ENDIAN)
|
if (INSN_BIG_ENDIAN)
|
||||||
number_to_chars_bigendian ((char *)p, 0x01000000, 4); /* emit nops */
|
/* Emit nops. */
|
||||||
|
number_to_chars_bigendian ((char *) p, 0x01000000, 4);
|
||||||
else
|
else
|
||||||
number_to_chars_littleendian ((char *) p, 0x10000000, 4);
|
number_to_chars_littleendian ((char *) p, 0x10000000, 4);
|
||||||
|
|
||||||
@ -4115,4 +4128,3 @@ elf32_sparc_force_relocation (fixp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -19,10 +19,8 @@
|
|||||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||||
02111-1307, USA. */
|
02111-1307, USA. */
|
||||||
|
|
||||||
/*
|
/* Written By Steve Chamberlain <sac@cygnus.com>. */
|
||||||
Written By Steve Chamberlain
|
|
||||||
sac@cygnus.com
|
|
||||||
*/
|
|
||||||
#define DEFINE_TABLE
|
#define DEFINE_TABLE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -41,13 +39,6 @@ extern int coff_flags;
|
|||||||
int segmented_mode;
|
int segmented_mode;
|
||||||
const int md_reloc_size;
|
const int md_reloc_size;
|
||||||
|
|
||||||
/* 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 ();
|
void cons ();
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -66,8 +57,7 @@ s_unseg ()
|
|||||||
coff_flags = F_Z8002;
|
coff_flags = F_Z8002;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
even ()
|
even ()
|
||||||
{
|
{
|
||||||
frag_align (1, 0, 0);
|
frag_align (1, 0, 0);
|
||||||
@ -90,7 +80,6 @@ tohex (c)
|
|||||||
void
|
void
|
||||||
sval ()
|
sval ()
|
||||||
{
|
{
|
||||||
|
|
||||||
SKIP_WHITESPACE ();
|
SKIP_WHITESPACE ();
|
||||||
if (*input_line_pointer == '\'')
|
if (*input_line_pointer == '\'')
|
||||||
{
|
{
|
||||||
@ -110,10 +99,16 @@ sval ()
|
|||||||
}
|
}
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
const pseudo_typeS md_pseudo_table[] =
|
|
||||||
{
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
const pseudo_typeS md_pseudo_table[] = {
|
||||||
{"int" , cons , 2},
|
{"int" , cons , 2},
|
||||||
{"data.b" , cons , 1},
|
{"data.b" , cons , 1},
|
||||||
{"data.w" , cons , 2},
|
{"data.w" , cons , 2},
|
||||||
@ -126,7 +121,6 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{"z8001" , s_segm , 0},
|
{"z8001" , s_segm , 0},
|
||||||
{"z8002" , s_unseg , 0},
|
{"z8002" , s_unseg , 0},
|
||||||
|
|
||||||
|
|
||||||
{"segm" , s_segm , 0},
|
{"segm" , s_segm , 0},
|
||||||
{"unsegm" , s_unseg , 0},
|
{"unsegm" , s_unseg , 0},
|
||||||
{"unseg" , s_unseg , 0},
|
{"unseg" , s_unseg , 0},
|
||||||
@ -145,12 +139,13 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
|
|
||||||
const char EXP_CHARS[] = "eE";
|
const char EXP_CHARS[] = "eE";
|
||||||
|
|
||||||
/* Chars that mean this number is a floating point constant */
|
/* Chars that mean this number is a floating point constant.
|
||||||
/* As in 0f12.456 */
|
As in 0f12.456
|
||||||
/* or 0d1.2345e12 */
|
or 0d1.2345e12 */
|
||||||
const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
||||||
|
|
||||||
static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
|
/* Opcode mnemonics. */
|
||||||
|
static struct hash_control *opcode_hash_control;
|
||||||
|
|
||||||
void
|
void
|
||||||
md_begin ()
|
md_begin ()
|
||||||
@ -163,7 +158,7 @@ md_begin ()
|
|||||||
|
|
||||||
for (opcode = z8k_table; opcode->name; opcode++)
|
for (opcode = z8k_table; opcode->name; opcode++)
|
||||||
{
|
{
|
||||||
/* Only enter unique codes into the table */
|
/* Only enter unique codes into the table. */
|
||||||
char *src = opcode->name;
|
char *src = opcode->name;
|
||||||
|
|
||||||
if (strcmp (opcode->name, prev_name))
|
if (strcmp (opcode->name, prev_name))
|
||||||
@ -175,10 +170,10 @@ md_begin ()
|
|||||||
prev_name = opcode->name;
|
prev_name = opcode->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* default to z8002 */
|
/* Default to z8002. */
|
||||||
s_unseg ();
|
s_unseg ();
|
||||||
|
|
||||||
/* insert the pseudo ops too */
|
/* Insert the pseudo ops, too. */
|
||||||
for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
|
for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
|
||||||
{
|
{
|
||||||
opcode_entry_type *fake_opcode;
|
opcode_entry_type *fake_opcode;
|
||||||
@ -198,15 +193,22 @@ struct z8k_exp
|
|||||||
char *e_end;
|
char *e_end;
|
||||||
expressionS e_exp;
|
expressionS e_exp;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct z8k_op
|
typedef struct z8k_op
|
||||||
{
|
{
|
||||||
char regsize; /* 'b','w','r','q' */
|
/* 'b','w','r','q'. */
|
||||||
unsigned int reg; /* 0..15 */
|
char regsize;
|
||||||
|
|
||||||
|
/* 0 .. 15. */
|
||||||
|
unsigned int reg;
|
||||||
|
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
unsigned int x_reg; /* any other register associated with the mode */
|
/* Any other register associated with the mode. */
|
||||||
expressionS exp; /* any expression */
|
unsigned int x_reg;
|
||||||
|
|
||||||
|
/* Any expression. */
|
||||||
|
expressionS exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
op_type;
|
op_type;
|
||||||
@ -237,8 +239,7 @@ whatreg (reg, src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Parse operands
|
||||||
parse operands
|
|
||||||
|
|
||||||
rh0-rh7, rl0-rl7
|
rh0-rh7, rl0-rl7
|
||||||
r0-r15
|
r0-r15
|
||||||
@ -250,7 +251,6 @@ whatreg (reg, src)
|
|||||||
@WREG+
|
@WREG+
|
||||||
@-WREG
|
@-WREG
|
||||||
#const
|
#const
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Try to parse a reg name. Return a pointer to the first character
|
/* Try to parse a reg name. Return a pointer to the first character
|
||||||
@ -324,7 +324,6 @@ parse_reg (src, mode, reg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -356,13 +355,9 @@ parse_exp (s, op)
|
|||||||
exp(r)
|
exp(r)
|
||||||
r(#exp)
|
r(#exp)
|
||||||
r(r)
|
r(r)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
static char *
|
||||||
char *
|
|
||||||
checkfor (ptr, what)
|
checkfor (ptr, what)
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char what;
|
char what;
|
||||||
@ -370,13 +365,13 @@ checkfor (ptr, what)
|
|||||||
if (*ptr == what)
|
if (*ptr == what)
|
||||||
ptr++;
|
ptr++;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
as_bad (_("expected %c"), what);
|
as_bad (_("expected %c"), what);
|
||||||
}
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the mode supplied is the size of a word */
|
/* Make sure the mode supplied is the size of a word. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
regword (mode, string)
|
regword (mode, string)
|
||||||
int mode;
|
int mode;
|
||||||
@ -391,7 +386,8 @@ regword (mode, string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the mode supplied is the size of an address */
|
/* Make sure the mode supplied is the size of an address. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
regaddr (mode, string)
|
regaddr (mode, string)
|
||||||
int mode;
|
int mode;
|
||||||
@ -412,8 +408,7 @@ struct ctrl_names
|
|||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ctrl_names ctrl_table[] =
|
struct ctrl_names ctrl_table[] = {
|
||||||
{
|
|
||||||
0x2, "fcw",
|
0x2, "fcw",
|
||||||
0X3, "refresh",
|
0X3, "refresh",
|
||||||
0x4, "psapseg",
|
0x4, "psapseg",
|
||||||
@ -451,7 +446,8 @@ get_ctrl_operand (ptr, mode, dst)
|
|||||||
the_ctrl = ctrl_table[i].value;
|
the_ctrl = ctrl_table[i].value;
|
||||||
*ptr = src + j;
|
*ptr = src + j;
|
||||||
return;
|
return;
|
||||||
fail:;
|
fail:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
the_ctrl = 0;
|
the_ctrl = 0;
|
||||||
return;
|
return;
|
||||||
@ -464,8 +460,7 @@ struct flag_names
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct flag_names flag_table[] =
|
struct flag_names flag_table[] = {
|
||||||
{
|
|
||||||
0x1, "p",
|
0x1, "p",
|
||||||
0x1, "v",
|
0x1, "v",
|
||||||
0x2, "s",
|
0x2, "s",
|
||||||
@ -512,7 +507,6 @@ get_flags_operand (ptr, mode, dst)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct interrupt_names
|
struct interrupt_names
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
@ -555,7 +549,8 @@ get_interrupt_operand (ptr, mode, dst)
|
|||||||
the_interrupt = intr_table[i].value;
|
the_interrupt = intr_table[i].value;
|
||||||
*ptr = src + j;
|
*ptr = src + j;
|
||||||
return;
|
return;
|
||||||
fail:;
|
fail:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
the_interrupt = 0x0;
|
the_interrupt = 0x0;
|
||||||
return;
|
return;
|
||||||
@ -568,8 +563,7 @@ struct cc_names
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cc_names table[] =
|
struct cc_names table[] = {
|
||||||
{
|
|
||||||
0x0, "f",
|
0x0, "f",
|
||||||
0x1, "lt",
|
0x1, "lt",
|
||||||
0x2, "le",
|
0x2, "le",
|
||||||
@ -621,7 +615,8 @@ get_cc_operand (ptr, mode, dst)
|
|||||||
the_cc = table[i].value;
|
the_cc = table[i].value;
|
||||||
*ptr = src + j;
|
*ptr = src + j;
|
||||||
return;
|
return;
|
||||||
fail:;
|
fail:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
the_cc = 0x8;
|
the_cc = 0x8;
|
||||||
}
|
}
|
||||||
@ -672,20 +667,18 @@ get_operand (ptr, mode, dst)
|
|||||||
end = parse_reg (src, &nw, &nr);
|
end = parse_reg (src, &nw, &nr);
|
||||||
if (end)
|
if (end)
|
||||||
{
|
{
|
||||||
/* Got Ra(Rb) */
|
/* Got Ra(Rb). */
|
||||||
src = end;
|
src = end;
|
||||||
|
|
||||||
if (*src != ')')
|
if (*src != ')')
|
||||||
{
|
|
||||||
as_bad (_("Missing ) in ra(rb)"));
|
as_bad (_("Missing ) in ra(rb)"));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
src++;
|
src++;
|
||||||
}
|
|
||||||
|
|
||||||
regaddr (mode->mode, "ra(rb) ra");
|
regaddr (mode->mode, "ra(rb) ra");
|
||||||
/* regword (mode->mode, "ra(rb) rb");*/
|
#if 0
|
||||||
|
regword (mode->mode, "ra(rb) rb");
|
||||||
|
#endif
|
||||||
mode->mode = CLASS_BX;
|
mode->mode = CLASS_BX;
|
||||||
mode->reg = regn;
|
mode->reg = regn;
|
||||||
mode->x_reg = nr;
|
mode->x_reg = nr;
|
||||||
@ -693,7 +686,7 @@ get_operand (ptr, mode, dst)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Got Ra(disp) */
|
/* Got Ra(disp). */
|
||||||
if (*src == '#')
|
if (*src == '#')
|
||||||
src++;
|
src++;
|
||||||
src = parse_exp (src, &(mode->exp));
|
src = parse_exp (src, &(mode->exp));
|
||||||
@ -712,7 +705,7 @@ get_operand (ptr, mode, dst)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No initial reg */
|
/* No initial reg. */
|
||||||
src = parse_exp (src, &(mode->exp));
|
src = parse_exp (src, &(mode->exp));
|
||||||
if (*src == '(')
|
if (*src == '(')
|
||||||
{
|
{
|
||||||
@ -727,7 +720,7 @@ get_operand (ptr, mode, dst)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Just an address */
|
/* Just an address. */
|
||||||
mode->mode = CLASS_DA;
|
mode->mode = CLASS_DA;
|
||||||
mode->reg = 0;
|
mode->reg = 0;
|
||||||
mode->x_reg = 0;
|
mode->x_reg = 0;
|
||||||
@ -738,8 +731,7 @@ get_operand (ptr, mode, dst)
|
|||||||
*ptr = src;
|
*ptr = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static char *
|
||||||
char *
|
|
||||||
get_operands (opcode, op_end, operand)
|
get_operands (opcode, op_end, operand)
|
||||||
opcode_entry_type *opcode;
|
opcode_entry_type *opcode;
|
||||||
char *op_end;
|
char *op_end;
|
||||||
@ -747,6 +739,7 @@ get_operands (opcode, op_end, operand)
|
|||||||
{
|
{
|
||||||
char *ptr = op_end;
|
char *ptr = op_end;
|
||||||
char *savptr;
|
char *savptr;
|
||||||
|
|
||||||
switch (opcode->noperands)
|
switch (opcode->noperands)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -832,6 +825,7 @@ char *savptr;
|
|||||||
ptr++;
|
ptr++;
|
||||||
get_cc_operand (&ptr, operand + 3, 3);
|
get_cc_operand (&ptr, operand + 3, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
@ -840,12 +834,10 @@ char *savptr;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Passed a pointer to a list of opcodes which use different
|
/* Passed a pointer to a list of opcodes which use different
|
||||||
addressing modes, return the opcode which matches the opcodes
|
addressing modes. Return the opcode which matches the opcodes
|
||||||
provided
|
provided. */
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
static opcode_entry_type *
|
||||||
opcode_entry_type *
|
|
||||||
get_specific (opcode, operands)
|
get_specific (opcode, operands)
|
||||||
opcode_entry_type *opcode;
|
opcode_entry_type *opcode;
|
||||||
op_type *operands;
|
op_type *operands;
|
||||||
@ -869,29 +861,29 @@ get_specific (opcode, operands)
|
|||||||
|
|
||||||
if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
|
if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
|
||||||
{
|
{
|
||||||
/* it could be an pc rel operand, if this is a da mode and
|
/* It could be an pc rel operand, if this is a da mode
|
||||||
we like disps, then insert it */
|
and we like disps, then insert it. */
|
||||||
|
|
||||||
if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
|
if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
|
||||||
{
|
{
|
||||||
/* This is the case */
|
/* This is the case. */
|
||||||
operands[i].mode = CLASS_DISP;
|
operands[i].mode = CLASS_DISP;
|
||||||
}
|
}
|
||||||
else if (mode == CLASS_BA && this_try->arg_info[i])
|
else if (mode == CLASS_BA && this_try->arg_info[i])
|
||||||
{
|
{
|
||||||
/* Can't think of a way to turn what we've been given into
|
/* Can't think of a way to turn what we've been
|
||||||
something that's ok */
|
given into something that's OK. */
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else if (this_try->arg_info[i] & CLASS_PR)
|
else if (this_try->arg_info[i] & CLASS_PR)
|
||||||
{
|
{
|
||||||
if (mode == CLASS_REG_LONG && segmented_mode)
|
if (mode == CLASS_REG_LONG && segmented_mode)
|
||||||
{
|
{
|
||||||
/* ok */
|
/* OK. */
|
||||||
}
|
}
|
||||||
else if (mode == CLASS_REG_WORD && !segmented_mode)
|
else if (mode == CLASS_REG_WORD && !segmented_mode)
|
||||||
{
|
{
|
||||||
/* ok */
|
/* OK. */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -920,7 +912,8 @@ get_specific (opcode, operands)
|
|||||||
}
|
}
|
||||||
|
|
||||||
found = 1;
|
found = 1;
|
||||||
fail:;
|
fail:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
return this_try;
|
return this_try;
|
||||||
@ -938,13 +931,15 @@ check_operand (operand, width, string)
|
|||||||
&& operand->exp.X_op_symbol == 0)
|
&& operand->exp.X_op_symbol == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* No symbol involved, let's look at offset, it's dangerous if any of
|
/* No symbol involved, let's look at offset, it's dangerous if
|
||||||
the high bits are not 0 or ff's, find out by oring or anding with
|
any of the high bits are not 0 or ff's, find out by oring or
|
||||||
the width and seeing if the answer is 0 or all fs*/
|
anding with the width and seeing if the answer is 0 or all
|
||||||
|
fs. */
|
||||||
if ((operand->exp.X_add_number & ~width) != 0 &&
|
if ((operand->exp.X_add_number & ~width) != 0 &&
|
||||||
(operand->exp.X_add_number | width) != (~0))
|
(operand->exp.X_add_number | width) != (~0))
|
||||||
{
|
{
|
||||||
as_warn (_("operand %s0x%x out of range."), string, operand->exp.X_add_number);
|
as_warn (_("operand %s0x%x out of range."),
|
||||||
|
string, operand->exp.X_add_number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,8 +999,8 @@ apply_fix (ptr, type, operand, size)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we know what sort of opcodes it is, lets build the bytes -
|
/* Now we know what sort of opcodes it is. Let's build the bytes. */
|
||||||
*/
|
|
||||||
#define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
|
#define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
|
||||||
static void
|
static void
|
||||||
build_bytes (this_try, operand)
|
build_bytes (this_try, operand)
|
||||||
@ -1029,18 +1024,18 @@ build_bytes (this_try, operand)
|
|||||||
|
|
||||||
memset (buffer, 20, 0);
|
memset (buffer, 20, 0);
|
||||||
class_ptr = this_try->byte_info;
|
class_ptr = this_try->byte_info;
|
||||||
top:;
|
|
||||||
|
|
||||||
|
top:
|
||||||
for (nibble = 0; c = *class_ptr++; nibble++)
|
for (nibble = 0; c = *class_ptr++; nibble++)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (c & CLASS_MASK)
|
switch (c & CLASS_MASK)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
case CLASS_ADDRESS:
|
case CLASS_ADDRESS:
|
||||||
/* Direct address, we don't cope with the SS mode right now */
|
/* Direct address, we don't cope with the SS mode right now. */
|
||||||
if (segmented_mode)
|
if (segmented_mode)
|
||||||
{
|
{
|
||||||
da_operand->X_add_number |= 0x80000000;
|
da_operand->X_add_number |= 0x80000000;
|
||||||
@ -1078,18 +1073,12 @@ top:;
|
|||||||
if (imm_operand)
|
if (imm_operand)
|
||||||
{
|
{
|
||||||
if (imm_operand->X_add_number == 2)
|
if (imm_operand->X_add_number == 2)
|
||||||
{
|
|
||||||
*output_ptr |= 2;
|
*output_ptr |= 2;
|
||||||
}
|
|
||||||
else if (imm_operand->X_add_number != 1)
|
else if (imm_operand->X_add_number != 1)
|
||||||
{
|
|
||||||
as_bad (_("immediate must be 1 or 2"));
|
as_bad (_("immediate must be 1 or 2"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
as_bad (_("immediate 1 or 2 expected"));
|
as_bad (_("immediate 1 or 2 expected"));
|
||||||
}
|
|
||||||
output_ptr++;
|
output_ptr++;
|
||||||
break;
|
break;
|
||||||
case CLASS_CC:
|
case CLASS_CC:
|
||||||
@ -1115,16 +1104,14 @@ top:;
|
|||||||
break;
|
break;
|
||||||
case CLASS_REGN0:
|
case CLASS_REGN0:
|
||||||
if (reg[c & 0xf] == 0)
|
if (reg[c & 0xf] == 0)
|
||||||
{
|
|
||||||
as_bad (_("can't use R0 here"));
|
as_bad (_("can't use R0 here"));
|
||||||
}
|
/* Fall through. */
|
||||||
case CLASS_REG:
|
case CLASS_REG:
|
||||||
case CLASS_REG_BYTE:
|
case CLASS_REG_BYTE:
|
||||||
case CLASS_REG_WORD:
|
case CLASS_REG_WORD:
|
||||||
case CLASS_REG_LONG:
|
case CLASS_REG_LONG:
|
||||||
case CLASS_REG_QUAD:
|
case CLASS_REG_QUAD:
|
||||||
/* Insert bit mattern of
|
/* Insert bit mattern of right reg. */
|
||||||
right reg */
|
|
||||||
*output_ptr++ = reg[c & 0xf];
|
*output_ptr++ = reg[c & 0xf];
|
||||||
break;
|
break;
|
||||||
case CLASS_DISP:
|
case CLASS_DISP:
|
||||||
@ -1168,8 +1155,7 @@ top:;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy from the nibble buffer into the frag */
|
/* Copy from the nibble buffer into the frag. */
|
||||||
|
|
||||||
{
|
{
|
||||||
int length = (output_ptr - buffer) / 2;
|
int length = (output_ptr - buffer) / 2;
|
||||||
char *src = buffer;
|
char *src = buffer;
|
||||||
@ -1181,9 +1167,7 @@ top:;
|
|||||||
src += 2;
|
src += 2;
|
||||||
fragp++;
|
fragp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the guts of the machine-dependent assembler. STR points to a
|
/* This is the guts of the machine-dependent assembler. STR points to a
|
||||||
@ -1204,17 +1188,14 @@ md_assemble (str)
|
|||||||
char *dot = 0;
|
char *dot = 0;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
/* Drop leading whitespace */
|
/* Drop leading whitespace. */
|
||||||
while (*str == ' ')
|
while (*str == ' ')
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
/* find the op code end */
|
/* Find the op code end. */
|
||||||
for (op_start = op_end = str;
|
for (op_start = op_end = str;
|
||||||
*op_end != 0 && *op_end != ' ';
|
*op_end != 0 && *op_end != ' ';
|
||||||
op_end++)
|
op_end++)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
if (op_end == op_start)
|
if (op_end == op_start)
|
||||||
@ -1225,9 +1206,7 @@ md_assemble (str)
|
|||||||
|
|
||||||
*op_end = 0;
|
*op_end = 0;
|
||||||
|
|
||||||
opcode = (opcode_entry_type *) hash_find (opcode_hash_control,
|
opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
|
||||||
op_start);
|
|
||||||
|
|
||||||
|
|
||||||
if (opcode == NULL)
|
if (opcode == NULL)
|
||||||
{
|
{
|
||||||
@ -1237,7 +1216,7 @@ md_assemble (str)
|
|||||||
|
|
||||||
if (opcode->opcode == 250)
|
if (opcode->opcode == 250)
|
||||||
{
|
{
|
||||||
/* was really a pseudo op */
|
/* Was really a pseudo op. */
|
||||||
|
|
||||||
pseudo_typeS *p;
|
pseudo_typeS *p;
|
||||||
char oc;
|
char oc;
|
||||||
@ -1245,7 +1224,6 @@ md_assemble (str)
|
|||||||
char *old = input_line_pointer;
|
char *old = input_line_pointer;
|
||||||
*op_end = c;
|
*op_end = c;
|
||||||
|
|
||||||
|
|
||||||
input_line_pointer = op_end;
|
input_line_pointer = op_end;
|
||||||
|
|
||||||
oc = *old;
|
oc = *old;
|
||||||
@ -1260,15 +1238,14 @@ md_assemble (str)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
input_line_pointer = get_operands (opcode, op_end,
|
input_line_pointer = get_operands (opcode, op_end, operand);
|
||||||
operand);
|
|
||||||
prev_opcode = opcode;
|
prev_opcode = opcode;
|
||||||
|
|
||||||
opcode = get_specific (opcode, operand);
|
opcode = get_specific (opcode, operand);
|
||||||
|
|
||||||
if (opcode == 0)
|
if (opcode == 0)
|
||||||
{
|
{
|
||||||
/* Couldn't find an opcode which matched the operands */
|
/* Couldn't find an opcode which matched the operands. */
|
||||||
char *where = frag_more (2);
|
char *where = frag_more (2);
|
||||||
|
|
||||||
where[0] = 0x0;
|
where[0] = 0x0;
|
||||||
@ -1303,14 +1280,15 @@ tc_headers_hook (headers)
|
|||||||
printf (_("call to tc_headers_hook \n"));
|
printf (_("call to tc_headers_hook \n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Various routines to kill one day */
|
/* Various routines to kill one day. */
|
||||||
/* Equal to MAX_PRECISION in atof-ieee.c */
|
/* Equal to MAX_PRECISION in atof-ieee.c. */
|
||||||
#define MAX_LITTLENUMS 6
|
#define MAX_LITTLENUMS 6
|
||||||
|
|
||||||
/* Turn a string in input_line_pointer into a floating point constant of type
|
/* Turn a string in input_line_pointer into a floating point constant
|
||||||
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
|
of type TYPE, and store the appropriate bytes in *LITP. The number
|
||||||
emitted is stored in *sizeP . An error message is returned, or NULL on OK.
|
of LITTLENUMS emitted is stored in *SIZEP. An error message is
|
||||||
*/
|
returned, or NULL on OK. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
md_atof (type, litP, sizeP)
|
md_atof (type, litP, sizeP)
|
||||||
char type;
|
char type;
|
||||||
@ -1367,9 +1345,11 @@ md_atof (type, litP, sizeP)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CONST char *md_shortopts = "z:";
|
CONST char *md_shortopts = "z:";
|
||||||
|
|
||||||
struct option md_longopts[] = {
|
struct option md_longopts[] = {
|
||||||
{NULL, no_argument, NULL, 0}
|
{NULL, no_argument, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t md_longopts_size = sizeof (md_longopts);
|
size_t md_longopts_size = sizeof (md_longopts);
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1430,7 +1410,8 @@ md_section_align (seg, size)
|
|||||||
segT seg;
|
segT seg;
|
||||||
valueT size;
|
valueT size;
|
||||||
{
|
{
|
||||||
return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
|
return ((size + (1 << section_alignment[(int) seg]) - 1)
|
||||||
|
& (-1 << section_alignment[(int) seg]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,13 +1431,19 @@ md_apply_fix (fixP, val)
|
|||||||
case R_JR:
|
case R_JR:
|
||||||
|
|
||||||
*buf++ = val;
|
*buf++ = val;
|
||||||
/* if (val != 0) abort();*/
|
#if 0
|
||||||
|
if (val != 0)
|
||||||
|
abort ();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_DISP7:
|
case R_DISP7:
|
||||||
|
|
||||||
*buf++ += val;
|
*buf++ += val;
|
||||||
/* if (val != 0) abort();*/
|
#if 0
|
||||||
|
if (val != 0)
|
||||||
|
abort ();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_IMM8:
|
case R_IMM8:
|
||||||
@ -1487,7 +1474,6 @@ md_apply_fix (fixP, val)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,7 +1486,7 @@ md_estimate_size_before_relax (fragP, segment_type)
|
|||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put number into target byte order */
|
/* Put number into target byte order. */
|
||||||
|
|
||||||
void
|
void
|
||||||
md_number_to_chars (ptr, use, nbytes)
|
md_number_to_chars (ptr, use, nbytes)
|
||||||
@ -1510,6 +1496,7 @@ md_number_to_chars (ptr, use, nbytes)
|
|||||||
{
|
{
|
||||||
number_to_chars_bigendian (ptr, use, nbytes);
|
number_to_chars_bigendian (ptr, use, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
long
|
long
|
||||||
md_pcrel_from (fixP)
|
md_pcrel_from (fixP)
|
||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
@ -1532,18 +1519,19 @@ tc_reloc_mangle (fix_ptr, intr, base)
|
|||||||
{
|
{
|
||||||
symbolS *symbol_ptr;
|
symbolS *symbol_ptr;
|
||||||
|
|
||||||
if (fix_ptr->fx_addsy &&
|
if (fix_ptr->fx_addsy
|
||||||
fix_ptr->fx_subsy)
|
&& fix_ptr->fx_subsy)
|
||||||
{
|
{
|
||||||
symbolS *add = fix_ptr->fx_addsy;
|
symbolS *add = fix_ptr->fx_addsy;
|
||||||
symbolS *sub = fix_ptr->fx_subsy;
|
symbolS *sub = fix_ptr->fx_subsy;
|
||||||
|
|
||||||
if (S_GET_SEGMENT (add) != S_GET_SEGMENT (sub))
|
if (S_GET_SEGMENT (add) != S_GET_SEGMENT (sub))
|
||||||
{
|
|
||||||
as_bad (_("Can't subtract symbols in different sections %s %s"),
|
as_bad (_("Can't subtract symbols in different sections %s %s"),
|
||||||
S_GET_NAME (add), S_GET_NAME (sub));
|
S_GET_NAME (add), S_GET_NAME (sub));
|
||||||
}
|
else
|
||||||
else {
|
{
|
||||||
int diff = S_GET_VALUE (add) - S_GET_VALUE (sub);
|
int diff = S_GET_VALUE (add) - S_GET_VALUE (sub);
|
||||||
|
|
||||||
fix_ptr->fx_addsy = 0;
|
fix_ptr->fx_addsy = 0;
|
||||||
fix_ptr->fx_subsy = 0;
|
fix_ptr->fx_subsy = 0;
|
||||||
fix_ptr->fx_offset += diff;
|
fix_ptr->fx_offset += diff;
|
||||||
@ -1552,10 +1540,10 @@ tc_reloc_mangle (fix_ptr, intr, base)
|
|||||||
symbol_ptr = fix_ptr->fx_addsy;
|
symbol_ptr = fix_ptr->fx_addsy;
|
||||||
|
|
||||||
/* If this relocation is attached to a symbol then it's ok
|
/* If this relocation is attached to a symbol then it's ok
|
||||||
to output it */
|
to output it. */
|
||||||
if (fix_ptr->fx_r_type == 0)
|
if (fix_ptr->fx_r_type == 0)
|
||||||
{
|
{
|
||||||
/* cons likes to create reloc32's whatever the size of the reloc.. */
|
/* cons likes to create reloc32's whatever the size of the reloc. */
|
||||||
switch (fix_ptr->fx_size)
|
switch (fix_ptr->fx_size)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
@ -1570,12 +1558,9 @@ tc_reloc_mangle (fix_ptr, intr, base)
|
|||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
intr->r_type = fix_ptr->fx_r_type;
|
intr->r_type = fix_ptr->fx_r_type;
|
||||||
}
|
|
||||||
|
|
||||||
intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
|
intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
|
||||||
intr->r_offset = fix_ptr->fx_offset;
|
intr->r_offset = fix_ptr->fx_offset;
|
||||||
@ -1585,4 +1570,3 @@ tc_reloc_mangle (fix_ptr, intr, base)
|
|||||||
else
|
else
|
||||||
intr->r_symndx = -1;
|
intr->r_symndx = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user