mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
* tc-pdp11.c: Use VAX float format support for PDP-11 target.
(parse_ac5): New function for parsing float regs in float operand. (parse_expression): Remove attempt to make literals be octal. (parse_op_no_deferred): Support float literals. (parse_op): Reject attempts to refer to float regs. (parse_fop): New function, like parse_op but for float operand. (md_assemble): Add cases to parse float operands. Also fix IMM3, IMM6, IMM8 cases to pick up the operand from the right spot.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2002-03-05 Paul Koning <pkoning@equallogic.com>
|
||||||
|
|
||||||
|
* tc-pdp11.c: Use VAX float format support for PDP-11 target.
|
||||||
|
(parse_ac5): New function for parsing float regs in float operand.
|
||||||
|
(parse_expression): Remove attempt to make literals be octal.
|
||||||
|
(parse_op_no_deferred): Support float literals.
|
||||||
|
(parse_op): Reject attempts to refer to float regs.
|
||||||
|
(parse_fop): New function, like parse_op but for float operand.
|
||||||
|
(md_assemble): Add cases to parse float operands. Also fix
|
||||||
|
IMM3, IMM6, IMM8 cases to pick up the operand from the right spot.
|
||||||
|
|
||||||
2002-03-04 H.J. Lu <hjl@gnu.org>
|
2002-03-04 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
* config/obj-elf.c (special_section): Add .init_array,
|
* config/obj-elf.c (special_section): Add .init_array,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* tc-pdp11.c - pdp11-specific -
|
/* tc-pdp11.c - pdp11-specific -
|
||||||
Copyright 2001 Free Software Foundation, Inc.
|
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GAS, the GNU Assembler.
|
This file is part of GAS, the GNU Assembler.
|
||||||
|
|
||||||
@ -33,6 +33,9 @@ static int set_option PARAMS ((char *arg));
|
|||||||
static int set_cpu_model PARAMS ((char *arg));
|
static int set_cpu_model PARAMS ((char *arg));
|
||||||
static int set_machine_model PARAMS ((char *arg));
|
static int set_machine_model PARAMS ((char *arg));
|
||||||
|
|
||||||
|
extern int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
|
||||||
|
LITTLENUM_TYPE * words));
|
||||||
|
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
@ -85,7 +88,7 @@ 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 0f123.456 */
|
/* as in 0f123.456 */
|
||||||
/* or 0H1.234E-12 (see exp chars above) */
|
/* or 0H1.234E-12 (see exp chars above) */
|
||||||
CONST char FLT_CHARS[] = "dDfFgGhH";
|
CONST char FLT_CHARS[] = "dDfF";
|
||||||
|
|
||||||
void pseudo_even (int);
|
void pseudo_even (int);
|
||||||
void pseudo_bss (int);
|
void pseudo_bss (int);
|
||||||
@ -298,7 +301,7 @@ parse_reg (char *str, struct pdp11_code *operand)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
parse_ac (char *str, struct pdp11_code *operand)
|
parse_ac5 (char *str, struct pdp11_code *operand)
|
||||||
{
|
{
|
||||||
str = skip_whitespace (str);
|
str = skip_whitespace (str);
|
||||||
if (strncmp (str, "fr", 2) == 0 ||
|
if (strncmp (str, "fr", 2) == 0 ||
|
||||||
@ -310,6 +313,7 @@ parse_ac (char *str, struct pdp11_code *operand)
|
|||||||
switch (*str)
|
switch (*str)
|
||||||
{
|
{
|
||||||
case '0': case '1': case '2': case '3':
|
case '0': case '1': case '2': case '3':
|
||||||
|
case '4': case '5':
|
||||||
operand->code = *str - '0';
|
operand->code = *str - '0';
|
||||||
str++;
|
str++;
|
||||||
break;
|
break;
|
||||||
@ -327,6 +331,19 @@ parse_ac (char *str, struct pdp11_code *operand)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
parse_ac (char *str, struct pdp11_code *operand)
|
||||||
|
{
|
||||||
|
str = parse_ac5 (str, operand);
|
||||||
|
if (!operand->error && operand->code > 3)
|
||||||
|
{
|
||||||
|
operand->error = "Bad register name";
|
||||||
|
return str - 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
parse_expression (char *str, struct pdp11_code *operand)
|
parse_expression (char *str, struct pdp11_code *operand)
|
||||||
{
|
{
|
||||||
@ -348,6 +365,15 @@ parse_expression (char *str, struct pdp11_code *operand)
|
|||||||
|
|
||||||
operand->reloc.pc_rel = 0;
|
operand->reloc.pc_rel = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* FIXME: what follows is broken badly. You can't deal with differences
|
||||||
|
in radix conventions this way, because of symbolic constants, constant
|
||||||
|
expressions made up of pieces of differing radix, etc. The only
|
||||||
|
choices are to change ../expr.c to know about pdp11 conventions, or
|
||||||
|
to accept the fact that gas will use consistent conventions that differ
|
||||||
|
from those of traditional pdp11 assemblers. For now, I've
|
||||||
|
chosen the latter. paul koning, 12/23/2001
|
||||||
|
*/
|
||||||
if (operand->reloc.exp.X_op == O_constant)
|
if (operand->reloc.exp.X_op == O_constant)
|
||||||
{
|
{
|
||||||
if (*str == '.')
|
if (*str == '.')
|
||||||
@ -362,13 +388,15 @@ parse_expression (char *str, struct pdp11_code *operand)
|
|||||||
operand->reloc.exp.X_add_number = strtol (buf, &end, 8);
|
operand->reloc.exp.X_add_number = strtol (buf, &end, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
parse_op_no_deferred (char *str, struct pdp11_code *operand)
|
parse_op_no_deferred (char *str, struct pdp11_code *operand)
|
||||||
{
|
{
|
||||||
|
LITTLENUM_TYPE literal_float[2];
|
||||||
|
|
||||||
str = skip_whitespace (str);
|
str = skip_whitespace (str);
|
||||||
|
|
||||||
switch (*str)
|
switch (*str)
|
||||||
@ -412,6 +440,19 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
|
|||||||
operand->reloc.type = BFD_RELOC_16;
|
operand->reloc.type = BFD_RELOC_16;
|
||||||
operand->reloc.pc_rel = 0;
|
operand->reloc.pc_rel = 0;
|
||||||
break;
|
break;
|
||||||
|
case O_big:
|
||||||
|
if (operand->reloc.exp.X_add_number > 0)
|
||||||
|
{
|
||||||
|
operand->error = "Error in expression";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* it's a floating literal... */
|
||||||
|
know (operand->reloc.exp.X_add_number < 0);
|
||||||
|
flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
|
||||||
|
operand->word = literal_float[0];
|
||||||
|
if (literal_float[1] != 0)
|
||||||
|
as_warn (_("Low order bits truncated in immediate float operand"));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
operand->error = "Error in expression";
|
operand->error = "Error in expression";
|
||||||
break;
|
break;
|
||||||
@ -504,13 +545,9 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
parse_op (char *str, struct pdp11_code *operand)
|
parse_op_noreg (char *str, struct pdp11_code *operand)
|
||||||
{
|
{
|
||||||
str = skip_whitespace (str);
|
str = skip_whitespace (str);
|
||||||
|
|
||||||
str = parse_reg (str, operand);
|
|
||||||
if (!operand->error)
|
|
||||||
return str;
|
|
||||||
operand->error = NULL;
|
operand->error = NULL;
|
||||||
|
|
||||||
if (*str == '@' || *str == '*')
|
if (*str == '@' || *str == '*')
|
||||||
@ -526,6 +563,46 @@ parse_op (char *str, struct pdp11_code *operand)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
parse_op (char *str, struct pdp11_code *operand)
|
||||||
|
{
|
||||||
|
str = skip_whitespace (str);
|
||||||
|
|
||||||
|
str = parse_reg (str, operand);
|
||||||
|
if (!operand->error)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
operand->error = NULL;
|
||||||
|
parse_ac5 (str, operand);
|
||||||
|
if (!operand->error)
|
||||||
|
{
|
||||||
|
operand->error = "Float AC not legal as integer operand";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parse_op_noreg (str, operand);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
parse_fop (char *str, struct pdp11_code *operand)
|
||||||
|
{
|
||||||
|
str = skip_whitespace (str);
|
||||||
|
|
||||||
|
str = parse_ac5 (str, operand);
|
||||||
|
if (!operand->error)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
operand->error = NULL;
|
||||||
|
parse_reg (str, operand);
|
||||||
|
if (!operand->error)
|
||||||
|
{
|
||||||
|
operand->error = "General register not legal as float operand";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parse_op_noreg (str, operand);
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
parse_separator (char *str, int *error)
|
parse_separator (char *str, int *error)
|
||||||
{
|
{
|
||||||
@ -585,7 +662,7 @@ md_assemble (instruction_string)
|
|||||||
&insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
|
&insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
as_warn ("Unknown instruction");
|
as_bad (_("Unknown instruction '%s'"), str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -627,31 +704,36 @@ md_assemble (instruction_string)
|
|||||||
str = parse_expression (str, &op1);
|
str = parse_expression (str, &op1);
|
||||||
if (op1.error)
|
if (op1.error)
|
||||||
break;
|
break;
|
||||||
|
if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE)
|
||||||
|
{
|
||||||
|
op1.error = "operand is not an absolute constant";
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch (op->type)
|
switch (op->type)
|
||||||
{
|
{
|
||||||
case PDP11_OPCODE_IMM3:
|
case PDP11_OPCODE_IMM3:
|
||||||
if (op1.code & ~7)
|
if (op1.reloc.exp.X_add_number & ~7)
|
||||||
{
|
{
|
||||||
op1.error = "3-bit immediate out of range";
|
op1.error = "3-bit immediate out of range";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PDP11_OPCODE_IMM6:
|
case PDP11_OPCODE_IMM6:
|
||||||
if (op1.code & ~0x3f)
|
if (op1.reloc.exp.X_add_number & ~0x3f)
|
||||||
{
|
{
|
||||||
op1.error = "6-bit immediate out of range";
|
op1.error = "6-bit immediate out of range";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PDP11_OPCODE_IMM8:
|
case PDP11_OPCODE_IMM8:
|
||||||
if (op1.code & ~0xff)
|
if (op1.reloc.exp.X_add_number & ~0xff)
|
||||||
{
|
{
|
||||||
op1.error = "8-bit immediate out of range";
|
op1.error = "8-bit immediate out of range";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
insn.code |= op1.code;
|
insn.code |= op1.reloc.exp.X_add_number;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDP11_OPCODE_DISPL:
|
case PDP11_OPCODE_DISPL:
|
||||||
@ -693,6 +775,15 @@ md_assemble (instruction_string)
|
|||||||
size += 2;
|
size += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PDP11_OPCODE_FOP:
|
||||||
|
str = parse_fop (str, &op1);
|
||||||
|
if (op1.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op1.code;
|
||||||
|
if (op1.additional)
|
||||||
|
size += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
case PDP11_OPCODE_REG_OP:
|
case PDP11_OPCODE_REG_OP:
|
||||||
str = parse_reg (str, &op2);
|
str = parse_reg (str, &op2);
|
||||||
if (op2.error)
|
if (op2.error)
|
||||||
@ -731,6 +822,44 @@ md_assemble (instruction_string)
|
|||||||
insn.code |= op2.code << 6;
|
insn.code |= op2.code << 6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PDP11_OPCODE_AC_FOP:
|
||||||
|
str = parse_ac (str, &op2);
|
||||||
|
if (op2.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op2.code << 6;
|
||||||
|
str = parse_separator (str, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
op1.error = "Missing ','";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str = parse_fop (str, &op1);
|
||||||
|
if (op1.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op1.code;
|
||||||
|
if (op1.additional)
|
||||||
|
size += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PDP11_OPCODE_FOP_AC:
|
||||||
|
str = parse_fop (str, &op1);
|
||||||
|
if (op1.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op1.code;
|
||||||
|
if (op1.additional)
|
||||||
|
size += 2;
|
||||||
|
str = parse_separator (str, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
op1.error = "Missing ','";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str = parse_ac (str, &op2);
|
||||||
|
if (op2.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op2.code << 6;
|
||||||
|
break;
|
||||||
|
|
||||||
case PDP11_OPCODE_AC_OP:
|
case PDP11_OPCODE_AC_OP:
|
||||||
str = parse_ac (str, &op2);
|
str = parse_ac (str, &op2);
|
||||||
if (op2.error)
|
if (op2.error)
|
||||||
@ -750,6 +879,25 @@ md_assemble (instruction_string)
|
|||||||
size += 2;
|
size += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PDP11_OPCODE_OP_AC:
|
||||||
|
str = parse_op (str, &op1);
|
||||||
|
if (op1.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op1.code;
|
||||||
|
if (op1.additional)
|
||||||
|
size += 2;
|
||||||
|
str = parse_separator (str, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
op1.error = "Missing ','";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str = parse_ac (str, &op2);
|
||||||
|
if (op2.error)
|
||||||
|
break;
|
||||||
|
insn.code |= op2.code << 6;
|
||||||
|
break;
|
||||||
|
|
||||||
case PDP11_OPCODE_OP_OP:
|
case PDP11_OPCODE_OP_OP:
|
||||||
str = parse_op (str, &op1);
|
str = parse_op (str, &op1);
|
||||||
if (op1.error)
|
if (op1.error)
|
||||||
|
Reference in New Issue
Block a user