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:
parent
b6d3cb37ef
commit
e621b5885a
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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.
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user