mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 21:41:47 +08:00
* config/tc-mn10300.h (pre_defined_registers) Remove.
(system_registers, cc_names): Likewise. (address_registers, data_registers, other_registers): New register arrays. (register_name, system_register_name, cc_name): Remove. (mn10300_reloc_prefix): Likewise. (data_register_name): New function. (address_register_name, other_register_name): Likewise. (md_assemble): Rough cut at parsing operands. Remove lots of unwanted code. (md_apply_fix3): Disable for now. Checkpointing today's Matsushita work.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
Mon Oct 7 16:53:23 1996 Jeffrey A Law (law@cygnus.com)
|
||||||
|
|
||||||
|
* config/tc-mn10300.h (pre_defined_registers) Remove.
|
||||||
|
(system_registers, cc_names): Likewise.
|
||||||
|
(address_registers, data_registers, other_registers): New register
|
||||||
|
arrays.
|
||||||
|
(register_name, system_register_name, cc_name): Remove.
|
||||||
|
(mn10300_reloc_prefix): Likewise.
|
||||||
|
(data_register_name): New function.
|
||||||
|
(address_register_name, other_register_name): Likewise.
|
||||||
|
(md_assemble): Rough cut at parsing operands. Remove lots of
|
||||||
|
unwanted code.
|
||||||
|
(md_apply_fix3): Disable for now.
|
||||||
|
|
||||||
Mon Oct 7 11:38:34 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
Mon Oct 7 11:38:34 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||||
|
|
||||||
* config/tc-m68k.c (select_control_regs): New function, extracted
|
* config/tc-m68k.c (select_control_regs): New function, extracted
|
||||||
|
@ -61,7 +61,6 @@ static int reg_name_search PARAMS ((const struct reg_name *, int, const char *))
|
|||||||
static boolean register_name PARAMS ((expressionS *expressionP));
|
static boolean register_name PARAMS ((expressionS *expressionP));
|
||||||
static boolean system_register_name PARAMS ((expressionS *expressionP));
|
static boolean system_register_name PARAMS ((expressionS *expressionP));
|
||||||
static boolean cc_name PARAMS ((expressionS *expressionP));
|
static boolean cc_name PARAMS ((expressionS *expressionP));
|
||||||
static bfd_reloc_code_real_type mn10300_reloc_prefix PARAMS ((void));
|
|
||||||
|
|
||||||
|
|
||||||
/* fixups */
|
/* fixups */
|
||||||
@ -91,85 +90,31 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
static struct hash_control *mn10300_hash;
|
static struct hash_control *mn10300_hash;
|
||||||
|
|
||||||
/* This table is sorted. Suitable for searching by a binary search. */
|
/* This table is sorted. Suitable for searching by a binary search. */
|
||||||
static const struct reg_name pre_defined_registers[] =
|
static const struct reg_name data_registers[] =
|
||||||
{
|
{
|
||||||
{ "ep", 30 }, /* ep - element ptr */
|
{ "d0", 0 },
|
||||||
{ "gp", 4 }, /* gp - global ptr */
|
{ "d1", 1 },
|
||||||
{ "lp", 31 }, /* lp - link ptr */
|
{ "d2", 2 },
|
||||||
{ "r0", 0 },
|
{ "d3", 3 },
|
||||||
{ "r1", 1 },
|
|
||||||
{ "r10", 10 },
|
|
||||||
{ "r11", 11 },
|
|
||||||
{ "r12", 12 },
|
|
||||||
{ "r13", 13 },
|
|
||||||
{ "r14", 14 },
|
|
||||||
{ "r15", 15 },
|
|
||||||
{ "r16", 16 },
|
|
||||||
{ "r17", 17 },
|
|
||||||
{ "r18", 18 },
|
|
||||||
{ "r19", 19 },
|
|
||||||
{ "r2", 2 },
|
|
||||||
{ "r20", 20 },
|
|
||||||
{ "r21", 21 },
|
|
||||||
{ "r22", 22 },
|
|
||||||
{ "r23", 23 },
|
|
||||||
{ "r24", 24 },
|
|
||||||
{ "r25", 25 },
|
|
||||||
{ "r26", 26 },
|
|
||||||
{ "r27", 27 },
|
|
||||||
{ "r28", 28 },
|
|
||||||
{ "r29", 29 },
|
|
||||||
{ "r3", 3 },
|
|
||||||
{ "r30", 30 },
|
|
||||||
{ "r31", 31 },
|
|
||||||
{ "r4", 4 },
|
|
||||||
{ "r5", 5 },
|
|
||||||
{ "r6", 6 },
|
|
||||||
{ "r7", 7 },
|
|
||||||
{ "r8", 8 },
|
|
||||||
{ "r9", 9 },
|
|
||||||
{ "sp", 3 }, /* sp - stack ptr */
|
|
||||||
{ "tp", 5 }, /* tp - text ptr */
|
|
||||||
{ "zero", 0 },
|
|
||||||
};
|
};
|
||||||
#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct reg_name))
|
#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
|
||||||
|
|
||||||
|
static const struct reg_name address_registers[] =
|
||||||
static const struct reg_name system_registers[] =
|
|
||||||
{
|
{
|
||||||
{ "eipc", 0 },
|
{ "a0", 0 },
|
||||||
{ "eipsw", 1 },
|
{ "a1", 1 },
|
||||||
{ "fepc", 2 },
|
{ "a2", 2 },
|
||||||
{ "fepsw", 3 },
|
{ "a3", 3 },
|
||||||
{ "ecr", 4 },
|
|
||||||
{ "psw", 5 },
|
|
||||||
};
|
};
|
||||||
#define SYSREG_NAME_CNT (sizeof(system_registers) / sizeof(struct reg_name))
|
#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
|
||||||
|
|
||||||
static const struct reg_name cc_names[] =
|
static const struct reg_name other_registers[] =
|
||||||
{
|
{
|
||||||
{ "c", 0x1 },
|
{ "mdr", 0 },
|
||||||
{ "ge", 0xe },
|
{ "psw", 0 },
|
||||||
{ "gt", 0xf },
|
{ "sp", 0 },
|
||||||
{ "h", 0xb },
|
|
||||||
{ "l", 0x1 },
|
|
||||||
{ "le", 0x7 },
|
|
||||||
{ "lt", 0x6 },
|
|
||||||
{ "n", 0x4 },
|
|
||||||
{ "nc", 0x9 },
|
|
||||||
{ "nh", 0x3 },
|
|
||||||
{ "nl", 0x9 },
|
|
||||||
{ "ns", 0xc },
|
|
||||||
{ "nv", 0x8 },
|
|
||||||
{ "nz", 0xa },
|
|
||||||
{ "p", 0xc },
|
|
||||||
{ "s", 0x4 },
|
|
||||||
{ "sa", 0xd },
|
|
||||||
{ "t", 0x5 },
|
|
||||||
{ "v", 0x0 },
|
|
||||||
{ "z", 0x2 },
|
|
||||||
};
|
};
|
||||||
#define CC_NAME_CNT (sizeof(cc_names) / sizeof(struct reg_name))
|
#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
|
||||||
|
|
||||||
/* reg_name_search does a binary search of the given register table
|
/* reg_name_search does a binary search of the given register table
|
||||||
to see if "name" is a valid regiter name. Returns the register
|
to see if "name" is a valid regiter name. Returns the register
|
||||||
@ -214,7 +159,7 @@ reg_name_search (regs, regcount, name)
|
|||||||
* its original state.
|
* its original state.
|
||||||
*/
|
*/
|
||||||
static boolean
|
static boolean
|
||||||
register_name (expressionP)
|
data_register_name (expressionP)
|
||||||
expressionS *expressionP;
|
expressionS *expressionP;
|
||||||
{
|
{
|
||||||
int reg_number;
|
int reg_number;
|
||||||
@ -226,7 +171,7 @@ register_name (expressionP)
|
|||||||
start = name = input_line_pointer;
|
start = name = input_line_pointer;
|
||||||
|
|
||||||
c = get_symbol_end ();
|
c = get_symbol_end ();
|
||||||
reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
|
reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
|
||||||
|
|
||||||
/* look to see if it's in the register table */
|
/* look to see if it's in the register table */
|
||||||
if (reg_number >= 0)
|
if (reg_number >= 0)
|
||||||
@ -249,7 +194,7 @@ register_name (expressionP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Summary of system_register_name().
|
/* Summary of register_name().
|
||||||
*
|
*
|
||||||
* in: Input_line_pointer points to 1st char of operand.
|
* in: Input_line_pointer points to 1st char of operand.
|
||||||
*
|
*
|
||||||
@ -260,7 +205,7 @@ register_name (expressionP)
|
|||||||
* its original state.
|
* its original state.
|
||||||
*/
|
*/
|
||||||
static boolean
|
static boolean
|
||||||
system_register_name (expressionP)
|
address_register_name (expressionP)
|
||||||
expressionS *expressionP;
|
expressionS *expressionP;
|
||||||
{
|
{
|
||||||
int reg_number;
|
int reg_number;
|
||||||
@ -272,7 +217,7 @@ system_register_name (expressionP)
|
|||||||
start = name = input_line_pointer;
|
start = name = input_line_pointer;
|
||||||
|
|
||||||
c = get_symbol_end ();
|
c = get_symbol_end ();
|
||||||
reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name);
|
reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
|
||||||
|
|
||||||
/* look to see if it's in the register table */
|
/* look to see if it's in the register table */
|
||||||
if (reg_number >= 0)
|
if (reg_number >= 0)
|
||||||
@ -295,7 +240,7 @@ system_register_name (expressionP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Summary of cc_name().
|
/* Summary of register_name().
|
||||||
*
|
*
|
||||||
* in: Input_line_pointer points to 1st char of operand.
|
* in: Input_line_pointer points to 1st char of operand.
|
||||||
*
|
*
|
||||||
@ -306,7 +251,7 @@ system_register_name (expressionP)
|
|||||||
* its original state.
|
* its original state.
|
||||||
*/
|
*/
|
||||||
static boolean
|
static boolean
|
||||||
cc_name (expressionP)
|
other_register_name (expressionP)
|
||||||
expressionS *expressionP;
|
expressionS *expressionP;
|
||||||
{
|
{
|
||||||
int reg_number;
|
int reg_number;
|
||||||
@ -318,12 +263,12 @@ cc_name (expressionP)
|
|||||||
start = name = input_line_pointer;
|
start = name = input_line_pointer;
|
||||||
|
|
||||||
c = get_symbol_end ();
|
c = get_symbol_end ();
|
||||||
reg_number = reg_name_search (cc_names, CC_NAME_CNT, name);
|
reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
|
||||||
|
|
||||||
/* look to see if it's in the register table */
|
/* look to see if it's in the register table */
|
||||||
if (reg_number >= 0)
|
if (reg_number >= 0)
|
||||||
{
|
{
|
||||||
expressionP->X_op = O_constant;
|
expressionP->X_op = O_register;
|
||||||
expressionP->X_add_number = reg_number;
|
expressionP->X_add_number = reg_number;
|
||||||
|
|
||||||
/* make the rest nice */
|
/* make the rest nice */
|
||||||
@ -450,30 +395,6 @@ md_begin ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_reloc_code_real_type
|
|
||||||
mn10300_reloc_prefix()
|
|
||||||
{
|
|
||||||
if (strncmp(input_line_pointer, "hi0(", 4) == 0)
|
|
||||||
{
|
|
||||||
input_line_pointer += 4;
|
|
||||||
return BFD_RELOC_HI16;
|
|
||||||
}
|
|
||||||
if (strncmp(input_line_pointer, "hi(", 3) == 0)
|
|
||||||
{
|
|
||||||
input_line_pointer += 3;
|
|
||||||
return BFD_RELOC_HI16_S;
|
|
||||||
}
|
|
||||||
if (strncmp (input_line_pointer, "lo(", 3) == 0)
|
|
||||||
{
|
|
||||||
input_line_pointer += 3;
|
|
||||||
return BFD_RELOC_LO16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: implement sda, tda, zda here */
|
|
||||||
|
|
||||||
return BFD_RELOC_UNUSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
md_assemble (str)
|
md_assemble (str)
|
||||||
char *str;
|
char *str;
|
||||||
@ -512,15 +433,19 @@ md_assemble (str)
|
|||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
const char *errmsg = NULL;
|
const char *errmsg = NULL;
|
||||||
|
int op_idx;
|
||||||
|
int parens = 0;
|
||||||
|
char *hold;
|
||||||
|
|
||||||
fc = 0;
|
fc = 0;
|
||||||
match = 0;
|
match = 0;
|
||||||
next_opindex = 0;
|
next_opindex = 0;
|
||||||
insn = opcode->opcode;
|
insn = opcode->opcode;
|
||||||
for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
|
for (op_idx = 1, opindex_ptr = opcode->operands;
|
||||||
|
*opindex_ptr != 0;
|
||||||
|
opindex_ptr++, op_idx++)
|
||||||
{
|
{
|
||||||
const struct mn10300_operand *operand;
|
const struct mn10300_operand *operand;
|
||||||
char *hold;
|
|
||||||
expressionS ex;
|
expressionS ex;
|
||||||
|
|
||||||
if (next_opindex == 0)
|
if (next_opindex == 0)
|
||||||
@ -542,55 +467,101 @@ md_assemble (str)
|
|||||||
hold = input_line_pointer;
|
hold = input_line_pointer;
|
||||||
input_line_pointer = str;
|
input_line_pointer = str;
|
||||||
|
|
||||||
|
#if 1
|
||||||
/* lo(), hi(), hi0(), etc... */
|
if (*str == '(')
|
||||||
if ((reloc = mn10300_reloc_prefix()) != BFD_RELOC_UNUSED)
|
|
||||||
{
|
{
|
||||||
expression(&ex);
|
str++;
|
||||||
|
input_line_pointer++;
|
||||||
if (*input_line_pointer++ != ')')
|
parens++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* See if we can match the operands. */
|
||||||
|
if (operand->flags & MN10300_OPERAND_DREG)
|
||||||
{
|
{
|
||||||
errmsg = "syntax error: expected `)'";
|
if (!data_register_name (&ex))
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex.X_op == O_constant)
|
|
||||||
{
|
|
||||||
switch (reloc)
|
|
||||||
{
|
|
||||||
case BFD_RELOC_LO16:
|
|
||||||
ex.X_add_number &= 0xffff;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BFD_RELOC_HI16:
|
|
||||||
ex.X_add_number = ((ex.X_add_number >> 16) & 0xffff);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BFD_RELOC_HI16_S:
|
|
||||||
ex.X_add_number = ((ex.X_add_number >> 16) & 0xffff)
|
|
||||||
+ ((ex.X_add_number >> 15) & 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else if (operand->flags & MN10300_OPERAND_AREG)
|
||||||
|
{
|
||||||
|
if (!address_register_name (&ex))
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (operand->flags & MN10300_OPERAND_SP)
|
||||||
|
{
|
||||||
|
char *start = input_line_pointer;
|
||||||
|
char c = get_symbol_end ();
|
||||||
|
|
||||||
insn = mn10300_insert_operand (insn, operand, ex.X_add_number,
|
if (strcmp (start, "sp") != 0)
|
||||||
(char *) NULL, 0);
|
{
|
||||||
|
*input_line_pointer = c;
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
*input_line_pointer = c;
|
||||||
|
goto keep_going;
|
||||||
|
}
|
||||||
|
else if (operand->flags & MN10300_OPERAND_PSW)
|
||||||
|
{
|
||||||
|
char *start = input_line_pointer;
|
||||||
|
char c = get_symbol_end ();
|
||||||
|
|
||||||
|
if (strcmp (start, "psw") != 0)
|
||||||
|
{
|
||||||
|
*input_line_pointer = c;
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
*input_line_pointer = c;
|
||||||
|
goto keep_going;
|
||||||
|
}
|
||||||
|
else if (operand->flags & MN10300_OPERAND_MDR)
|
||||||
|
{
|
||||||
|
char *start = input_line_pointer;
|
||||||
|
char c = get_symbol_end ();
|
||||||
|
|
||||||
|
if (strcmp (start, "mdr") != 0)
|
||||||
|
{
|
||||||
|
*input_line_pointer = c;
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
*input_line_pointer = c;
|
||||||
|
goto keep_going;
|
||||||
|
}
|
||||||
|
else if (data_register_name (&ex))
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else if (address_register_name (&ex))
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else if (other_register_name (&ex))
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fc > MAX_INSN_FIXUPS)
|
expression (&ex);
|
||||||
as_fatal ("too many fixups");
|
}
|
||||||
|
|
||||||
fixups[fc].exp = ex;
|
|
||||||
fixups[fc].opindex = *opindex_ptr;
|
|
||||||
fixups[fc].reloc = reloc;
|
|
||||||
fc++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (ex.X_op)
|
switch (ex.X_op)
|
||||||
{
|
{
|
||||||
case O_illegal:
|
case O_illegal:
|
||||||
@ -600,17 +571,44 @@ md_assemble (str)
|
|||||||
errmsg = "missing operand";
|
errmsg = "missing operand";
|
||||||
goto error;
|
goto error;
|
||||||
case O_register:
|
case O_register:
|
||||||
|
if (operand->flags & (MN10300_OPERAND_DREG
|
||||||
|
| MN10300_OPERAND_AREG) == 0)
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
insn = mn10300_insert_operand (insn, operand, ex.X_add_number,
|
insn = mn10300_insert_operand (insn, operand, ex.X_add_number,
|
||||||
(char *) NULL, 0);
|
(char *) NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_constant:
|
case O_constant:
|
||||||
|
/* If this operand can be promoted, and it doesn't
|
||||||
|
fit into the allocated bitfield for this insn,
|
||||||
|
then promote it (ie this opcode does not match). */
|
||||||
|
if (operand->flags & MN10300_OPERAND_PROMOTE
|
||||||
|
&& ! check_operand (insn, operand, ex.X_add_number))
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
insn = mn10300_insert_operand (insn, operand, ex.X_add_number,
|
insn = mn10300_insert_operand (insn, operand, ex.X_add_number,
|
||||||
(char *) NULL, 0);
|
(char *) NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
/* If this operand can be promoted, then this opcode didn't
|
||||||
|
match since we can't know if it needed promotion! */
|
||||||
|
if (operand->flags & MN10300_OPERAND_PROMOTE)
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to generate a fixup for this expression. */
|
/* We need to generate a fixup for this expression. */
|
||||||
if (fc >= MAX_INSN_FIXUPS)
|
if (fc >= MAX_INSN_FIXUPS)
|
||||||
as_fatal ("too many fixups");
|
as_fatal ("too many fixups");
|
||||||
@ -621,15 +619,26 @@ md_assemble (str)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
keep_going:
|
||||||
|
|
||||||
str = input_line_pointer;
|
str = input_line_pointer;
|
||||||
input_line_pointer = hold;
|
input_line_pointer = hold;
|
||||||
|
|
||||||
while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
|
while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
|
||||||
++str;
|
++str;
|
||||||
|
|
||||||
|
if (*str == ')')
|
||||||
|
{
|
||||||
|
str++;
|
||||||
|
parens--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (parens == 0 && *str != ',')
|
||||||
match = 1;
|
match = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input_line_pointer = hold;
|
||||||
|
str = hold;
|
||||||
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (match == 0)
|
if (match == 0)
|
||||||
@ -655,57 +664,38 @@ md_assemble (str)
|
|||||||
|
|
||||||
input_line_pointer = str;
|
input_line_pointer = str;
|
||||||
|
|
||||||
/* Write out the instruction.
|
/* XXX */
|
||||||
|
if (opcode->format == 1)
|
||||||
|
size = 1;
|
||||||
|
|
||||||
Four byte insns have an opcode with the two high bits on. */
|
if (opcode->format == 2 || opcode->format == 6)
|
||||||
if ((insn & 0x0600) == 0x0600)
|
|
||||||
size = 4;
|
|
||||||
else
|
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|
||||||
|
if (opcode->format == 3 || opcode->format == 7)
|
||||||
|
size = 3;
|
||||||
|
|
||||||
|
if (opcode->format == 4)
|
||||||
|
size = 5;
|
||||||
|
|
||||||
|
if (opcode->format == 5)
|
||||||
|
size = 7;
|
||||||
|
|
||||||
|
if (opcode->format == 8)
|
||||||
|
size = 4;
|
||||||
|
|
||||||
|
if (opcode->format == 9)
|
||||||
|
size = 6;
|
||||||
|
|
||||||
|
if (opcode->format == 10)
|
||||||
|
size = 8;
|
||||||
|
|
||||||
|
|
||||||
|
/* Write out the instruction. */
|
||||||
|
|
||||||
f = frag_more (size);
|
f = frag_more (size);
|
||||||
|
if (size > 4)
|
||||||
|
size = 4;
|
||||||
md_number_to_chars (f, insn, size);
|
md_number_to_chars (f, insn, size);
|
||||||
|
|
||||||
/* Create any fixups. At this point we do not use a
|
|
||||||
bfd_reloc_code_real_type, but instead just use the
|
|
||||||
BFD_RELOC_UNUSED plus the operand index. This lets us easily
|
|
||||||
handle fixups for any operand type, although that is admittedly
|
|
||||||
not a very exciting feature. We pick a BFD reloc type in
|
|
||||||
md_apply_fix. */
|
|
||||||
for (i = 0; i < fc; i++)
|
|
||||||
{
|
|
||||||
const struct mn10300_operand *operand;
|
|
||||||
|
|
||||||
operand = &mn10300_operands[fixups[i].opindex];
|
|
||||||
if (fixups[i].reloc != BFD_RELOC_UNUSED)
|
|
||||||
{
|
|
||||||
reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
|
|
||||||
int size;
|
|
||||||
int offset;
|
|
||||||
fixS *fixP;
|
|
||||||
|
|
||||||
if (!reloc_howto)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
size = bfd_get_reloc_size (reloc_howto);
|
|
||||||
offset = 4 - size;
|
|
||||||
|
|
||||||
if (size < 1 || size > 4)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size,
|
|
||||||
&fixups[i].exp,
|
|
||||||
reloc_howto->pc_relative,
|
|
||||||
fixups[i].reloc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
|
|
||||||
&fixups[i].exp,
|
|
||||||
1 /* FIXME: MN10300_OPERAND_RELATIVE ??? */,
|
|
||||||
((bfd_reloc_code_real_type)
|
|
||||||
(fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -762,6 +752,9 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
valueT value;
|
valueT value;
|
||||||
char *where;
|
char *where;
|
||||||
|
|
||||||
|
fixp->fx_done = 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (fixp->fx_addsy == (symbolS *) NULL)
|
if (fixp->fx_addsy == (symbolS *) NULL)
|
||||||
{
|
{
|
||||||
value = *valuep;
|
value = *valuep;
|
||||||
@ -841,7 +834,6 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Insert an operand value into an instruction. */
|
/* Insert an operand value into an instruction. */
|
||||||
|
|
||||||
static unsigned long
|
static unsigned long
|
||||||
@ -852,11 +844,17 @@ mn10300_insert_operand (insn, operand, val, file, line)
|
|||||||
char *file;
|
char *file;
|
||||||
unsigned int line;
|
unsigned int line;
|
||||||
{
|
{
|
||||||
if (operand->bits != 16)
|
if (operand->bits != 32)
|
||||||
{
|
{
|
||||||
long min, max;
|
long min, max;
|
||||||
offsetT test;
|
offsetT test;
|
||||||
|
|
||||||
|
if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
|
||||||
|
{
|
||||||
|
max = (1 << (operand->bits - 1)) - 1;
|
||||||
|
min = - (1 << (operand->bits - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
max = (1 << operand->bits) - 1;
|
max = (1 << operand->bits) - 1;
|
||||||
min = 0;
|
min = 0;
|
||||||
@ -882,3 +880,36 @@ mn10300_insert_operand (insn, operand, val, file, line)
|
|||||||
insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
|
insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
|
||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long
|
||||||
|
check_operand (insn, operand, val)
|
||||||
|
unsigned long insn;
|
||||||
|
const struct mn10300_operand *operand;
|
||||||
|
offsetT val;
|
||||||
|
{
|
||||||
|
if (operand->bits != 32)
|
||||||
|
{
|
||||||
|
long min, max;
|
||||||
|
offsetT test;
|
||||||
|
|
||||||
|
if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
|
||||||
|
{
|
||||||
|
max = (1 << (operand->bits - 1)) - 1;
|
||||||
|
min = - (1 << (operand->bits - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
max = (1 << operand->bits) - 1;
|
||||||
|
min = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
test = val;
|
||||||
|
|
||||||
|
|
||||||
|
if (test < (offsetT) min || test > (offsetT) max)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user