pdp11-modes.def: Add RESET_FLOAT_FORMAT calls.

* config/pdp11/pdp11-modes.def: Add RESET_FLOAT_FORMAT calls.
* config/pdp11/pdp11-protos.h (legitimate_const_double_p): Add.
* config/pdp11/pdp11.c (encode_pdp11_f, decode_pdp11_f,
encode_pdp11_d, decode_pdp11_d): New functions to handle PDP11
floating point format.
(pdp11_f_format, pdp11_d_format): New real_format descriptors for
the above functions.
(output_move_quad): Output float values in correct target format.
(legitimate_const_double_p): New function.
* config/pdp11/pdp11.h: Fix typos.
(FLOAT_WORDS_BIG_ENDIAN): Add definition.
(TARGET_FLOAT_FORMAT): Ditto.
(pdp11_f_format, pdp11_d_format): Add external declarations.
(MAX_REGS_PER_ADDRESS): Corrected.
(LEGITIMATE_CONSTANT_P): Use legitimate_const_double_p().
(PRINT_OPERAND): Output float literals in target format.

From-SVN: r77180
This commit is contained in:
Paul Koning 2004-02-03 17:36:02 +00:00 committed by Paul Koning
parent b6d3cb37ef
commit e621b5885a
5 changed files with 153 additions and 26 deletions

View File

@ -1,3 +1,22 @@
2004-02-03 Paul Koning <pkoning@equallogic.com>
* config/pdp11/pdp11-modes.def: Add RESET_FLOAT_FORMAT calls.
* config/pdp11/pdp11-protos.h (legitimate_const_double_p): Add.
* config/pdp11/pdp11.c (encode_pdp11_f, decode_pdp11_f,
encode_pdp11_d, decode_pdp11_d): New functions to handle PDP11
floating point format.
(pdp11_f_format, pdp11_d_format): New real_format descriptors for
the above functions.
(output_move_quad): Output float values in correct target format.
(legitimate_const_double_p): New function.
* config/pdp11/pdp11.h: Fix typos.
(FLOAT_WORDS_BIG_ENDIAN): Add definition.
(TARGET_FLOAT_FORMAT): Ditto.
(pdp11_f_format, pdp11_d_format): Add external declarations.
(MAX_REGS_PER_ADDRESS): Corrected.
(LEGITIMATE_CONSTANT_P): Use legitimate_const_double_p().
(PRINT_OPERAND): Output float literals in target format.
2004-02-03 Mark Mitchell <mark@codesourcery.com>
PR c++/13975

View File

@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for the pdp-11
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
This file is part of GCC.
@ -23,3 +23,5 @@ Boston, MA 02111-1307, USA. */
CCFPmode is used for FPU, but should we use a separate reg? */
CC_MODE (CCFP);
RESET_FLOAT_FORMAT (SF, pdp11_f_format);
RESET_FLOAT_FORMAT (DF, pdp11_d_format);

View File

@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for the pdp-11
Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
This file is part of GCC.
@ -29,6 +29,7 @@ extern int simple_memory_operand (rtx, enum machine_mode);
extern int comp_operator (rtx, enum machine_mode);
extern int legitimate_address_p (enum machine_mode, rtx);
extern int legitimate_const_double_p (rtx);
extern void notice_update_cc_on_set (rtx, rtx);
extern void output_addr_const_pdp11 (FILE *, rtx);
extern const char *output_move_double (rtx *);

View File

@ -51,6 +51,90 @@ Boston, MA 02111-1307, USA. */
defined in tm.h */
int current_first_parm_offset;
/* Routines to encode/decode pdp11 floats */
static void encode_pdp11_f (const struct real_format *fmt,
long *, const REAL_VALUE_TYPE *);
static void decode_pdp11_f (const struct real_format *,
REAL_VALUE_TYPE *, const long *);
static void encode_pdp11_d (const struct real_format *fmt,
long *, const REAL_VALUE_TYPE *);
static void decode_pdp11_d (const struct real_format *,
REAL_VALUE_TYPE *, const long *);
/* These two are taken from the corresponding vax descriptors
in real.c, changing only the encode/decode routine pointers. */
const struct real_format pdp11_f_format =
{
encode_pdp11_f,
decode_pdp11_f,
2,
1,
24,
24,
-127,
127,
15,
false,
false,
false,
false,
false
};
const struct real_format pdp11_d_format =
{
encode_pdp11_d,
decode_pdp11_d,
2,
1,
56,
56,
-127,
127,
15,
false,
false,
false,
false,
false
};
static void
encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
const REAL_VALUE_TYPE *r)
{
(*vax_f_format.encode) (fmt, buf, r);
buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
}
static void
decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
REAL_VALUE_TYPE *r, const long *buf)
{
long tbuf;
tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
(*vax_f_format.decode) (fmt, r, &tbuf);
}
static void
encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
const REAL_VALUE_TYPE *r)
{
(*vax_d_format.encode) (fmt, buf, r);
buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
}
static void
decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
REAL_VALUE_TYPE *r, const long *buf)
{
long tbuf[2];
tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
(*vax_d_format.decode) (fmt, r, tbuf);
}
/* This is where the condition code register lives. */
/* rtx cc0_reg_rtx; - no longer needed? */
@ -683,22 +767,12 @@ output_move_quad (rtx *operands)
{
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
/* floats only. not yet supported!
-- compute it into PDP float format, - internally,
just use IEEE and ignore possible problems ;-)
we might get away with it !!!! */
abort();
#ifndef HOST_WORDS_BIG_ENDIAN
latehalf[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
#else /* HOST_WORDS_BIG_ENDIAN */
latehalf[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
#endif /* HOST_WORDS_BIG_ENDIAN */
REAL_VALUE_TYPE r;
long dval[2];
REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
latehalf[1] = GEN_INT (dval[1]);
operands[1] = GEN_INT (dval[0]);
}
else if (GET_CODE(operands[1]) == CONST_INT)
{
@ -1591,6 +1665,21 @@ legitimate_address_p (enum machine_mode mode, rtx address)
/* #undef REG_OK_STRICT */
}
/* This function checks whether a real value can be encoded as
a literal, i.e., addressing mode 27. In that mode, real values
are one word values, so the remaining 48 bits have to be zero. */
int
legitimate_const_double_p (rtx address)
{
REAL_VALUE_TYPE r;
long sval[2];
REAL_VALUE_FROM_CONST_DOUBLE (r, address);
REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
return 1;
return 0;
}
/* A copy of output_addr_const modified for pdp11 expression syntax.
output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
use, and for debugging output, which we don't support with this port either.

View File

@ -167,14 +167,27 @@ extern int target_flags;
/* Define this if most significant byte of a word is the lowest numbered. */
#define BYTES_BIG_ENDIAN 0
/* Define this if most significant word of a multiword number is numbered. */
/* Define this if most significant word of a multiword number is first. */
#define WORDS_BIG_ENDIAN 1
/* Define that floats are in VAX order, not high word first as for ints. */
#define FLOAT_WORDS_BIG_ENDIAN 0
/* Width of a word, in units (bytes).
UNITS OR BYTES - seems like units */
#define UNITS_PER_WORD 2
/* This machine doesn't use IEEE floats. */
/* Because the pdp11 (at least Unix) convention for 32 bit ints is
big endian, opposite for what you need for float, the vax float
conversion routines aren't actually used directly. But the underlying
format is indeed the vax/pdp11 float format. */
#define TARGET_FLOAT_FORMAT VAX_FLOAT_FORMAT
extern const struct real_format pdp11_f_format;
extern const struct real_format pdp11_d_format;
/* Maximum sized of reasonable data type
DImode or Dfmode ...*/
#define MAX_FIXED_MODE_SIZE 64
@ -446,8 +459,8 @@ enum reg_class { NO_REGS, MUL_REGS, GENERAL_REGS, LOAD_FPU_REGS, NO_LOAD_FPU_REG
operand as its first argument and the constraint letter as its
second operand.
`Q' is for memory references using take more than 1 instruction.
`R' is for memory references which take 1 word for the instruction. */
`Q' is for memory references that require an extra word after the opcode.
`R' is for memory references which are encoded within the opcode. */
#define EXTRA_CONSTRAINT(OP,CODE) \
((GET_CODE (OP) != MEM) ? 0 \
@ -678,7 +691,7 @@ extern int may_call_alloca;
/* Maximum number of registers that can appear in a valid memory address. */
#define MAX_REGS_PER_ADDRESS 2
#define MAX_REGS_PER_ADDRESS 1
/* Recognize any constant value that is a valid address. */
@ -687,7 +700,8 @@ extern int may_call_alloca;
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
#define LEGITIMATE_CONSTANT_P(X) (TARGET_FPU? 1: !(GET_CODE(X) == CONST_DOUBLE))
#define LEGITIMATE_CONSTANT_P(X) \
(GET_CODE (X) != CONST_DOUBLE || legitimate_const_double_p (X))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@ -1078,9 +1092,11 @@ extern struct rtx_def *cc0_reg_rtx;
else if (GET_CODE (X) == MEM) \
output_address (XEXP (X, 0)); \
else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != SImode) \
{ char buf[30]; \
real_to_decimal (buf, CONST_DOUBLE_REAL_VALUE (X), sizeof (buf), 0, 1); \
fprintf (FILE, "$0F%s", buf); } \
{ REAL_VALUE_TYPE r; \
long sval[2]; \
REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
REAL_VALUE_TO_TARGET_DOUBLE (r, sval); \
fprintf (FILE, "$%#o", sval[0] >> 16); } \
else { putc ('$', FILE); output_addr_const_pdp11 (FILE, X); }}
/* Print a memory address as an operand to reference that memory location. */