mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 21:19:54 +00: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:
parent
84dd1cffbf
commit
cd3cde8631
@ -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>
|
||||
|
||||
* config/obj-elf.c (special_section): Add .init_array,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 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.
|
||||
|
||||
@ -33,6 +33,9 @@ static int set_option PARAMS ((char *arg));
|
||||
static int set_cpu_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 FALSE 0
|
||||
|
||||
@ -85,7 +88,7 @@ CONST char EXP_CHARS[] = "eE";
|
||||
/* Chars that mean this number is a floating point constant */
|
||||
/* as in 0f123.456 */
|
||||
/* or 0H1.234E-12 (see exp chars above) */
|
||||
CONST char FLT_CHARS[] = "dDfFgGhH";
|
||||
CONST char FLT_CHARS[] = "dDfF";
|
||||
|
||||
void pseudo_even (int);
|
||||
void pseudo_bss (int);
|
||||
@ -298,7 +301,7 @@ parse_reg (char *str, struct pdp11_code *operand)
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_ac (char *str, struct pdp11_code *operand)
|
||||
parse_ac5 (char *str, struct pdp11_code *operand)
|
||||
{
|
||||
str = skip_whitespace (str);
|
||||
if (strncmp (str, "fr", 2) == 0 ||
|
||||
@ -310,6 +313,7 @@ parse_ac (char *str, struct pdp11_code *operand)
|
||||
switch (*str)
|
||||
{
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5':
|
||||
operand->code = *str - '0';
|
||||
str++;
|
||||
break;
|
||||
@ -327,6 +331,19 @@ parse_ac (char *str, struct pdp11_code *operand)
|
||||
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 *
|
||||
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;
|
||||
|
||||
#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 (*str == '.')
|
||||
@ -362,13 +388,15 @@ parse_expression (char *str, struct pdp11_code *operand)
|
||||
operand->reloc.exp.X_add_number = strtol (buf, &end, 8);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_op_no_deferred (char *str, struct pdp11_code *operand)
|
||||
{
|
||||
LITTLENUM_TYPE literal_float[2];
|
||||
|
||||
str = skip_whitespace (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.pc_rel = 0;
|
||||
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:
|
||||
operand->error = "Error in expression";
|
||||
break;
|
||||
@ -504,13 +545,9 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_op (char *str, struct pdp11_code *operand)
|
||||
parse_op_noreg (char *str, struct pdp11_code *operand)
|
||||
{
|
||||
str = skip_whitespace (str);
|
||||
|
||||
str = parse_reg (str, operand);
|
||||
if (!operand->error)
|
||||
return str;
|
||||
operand->error = NULL;
|
||||
|
||||
if (*str == '@' || *str == '*')
|
||||
@ -526,6 +563,46 @@ parse_op (char *str, struct pdp11_code *operand)
|
||||
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 *
|
||||
parse_separator (char *str, int *error)
|
||||
{
|
||||
@ -585,7 +662,7 @@ md_assemble (instruction_string)
|
||||
&insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
|
||||
}
|
||||
#else
|
||||
as_warn ("Unknown instruction");
|
||||
as_bad (_("Unknown instruction '%s'"), str);
|
||||
#endif
|
||||
|
||||
return;
|
||||
@ -627,31 +704,36 @@ md_assemble (instruction_string)
|
||||
str = parse_expression (str, &op1);
|
||||
if (op1.error)
|
||||
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)
|
||||
{
|
||||
case PDP11_OPCODE_IMM3:
|
||||
if (op1.code & ~7)
|
||||
if (op1.reloc.exp.X_add_number & ~7)
|
||||
{
|
||||
op1.error = "3-bit immediate out of range";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PDP11_OPCODE_IMM6:
|
||||
if (op1.code & ~0x3f)
|
||||
if (op1.reloc.exp.X_add_number & ~0x3f)
|
||||
{
|
||||
op1.error = "6-bit immediate out of range";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PDP11_OPCODE_IMM8:
|
||||
if (op1.code & ~0xff)
|
||||
if (op1.reloc.exp.X_add_number & ~0xff)
|
||||
{
|
||||
op1.error = "8-bit immediate out of range";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
insn.code |= op1.code;
|
||||
insn.code |= op1.reloc.exp.X_add_number;
|
||||
break;
|
||||
|
||||
case PDP11_OPCODE_DISPL:
|
||||
@ -693,6 +775,15 @@ md_assemble (instruction_string)
|
||||
size += 2;
|
||||
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:
|
||||
str = parse_reg (str, &op2);
|
||||
if (op2.error)
|
||||
@ -731,6 +822,44 @@ md_assemble (instruction_string)
|
||||
insn.code |= op2.code << 6;
|
||||
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:
|
||||
str = parse_ac (str, &op2);
|
||||
if (op2.error)
|
||||
@ -750,6 +879,25 @@ md_assemble (instruction_string)
|
||||
size += 2;
|
||||
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:
|
||||
str = parse_op (str, &op1);
|
||||
if (op1.error)
|
||||
|
Loading…
Reference in New Issue
Block a user