Commit e621b588 by Paul Koning Committed by Paul Koning

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
parent b6d3cb37
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> 2004-02-03 Mark Mitchell <mark@codesourcery.com>
PR c++/13975 PR c++/13975
......
/* Definitions of target machine for GNU compiler, for the pdp-11 /* 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). Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
This file is part of GCC. This file is part of GCC.
...@@ -23,3 +23,5 @@ Boston, MA 02111-1307, USA. */ ...@@ -23,3 +23,5 @@ Boston, MA 02111-1307, USA. */
CCFPmode is used for FPU, but should we use a separate reg? */ CCFPmode is used for FPU, but should we use a separate reg? */
CC_MODE (CCFP); CC_MODE (CCFP);
RESET_FLOAT_FORMAT (SF, pdp11_f_format);
RESET_FLOAT_FORMAT (DF, pdp11_d_format);
/* Definitions of target machine for GNU compiler, for the pdp-11 /* 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). Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
This file is part of GCC. This file is part of GCC.
...@@ -29,6 +29,7 @@ extern int simple_memory_operand (rtx, enum machine_mode); ...@@ -29,6 +29,7 @@ extern int simple_memory_operand (rtx, enum machine_mode);
extern int comp_operator (rtx, enum machine_mode); extern int comp_operator (rtx, enum machine_mode);
extern int legitimate_address_p (enum machine_mode, rtx); 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 notice_update_cc_on_set (rtx, rtx);
extern void output_addr_const_pdp11 (FILE *, rtx); extern void output_addr_const_pdp11 (FILE *, rtx);
extern const char *output_move_double (rtx *); extern const char *output_move_double (rtx *);
......
...@@ -51,6 +51,90 @@ Boston, MA 02111-1307, USA. */ ...@@ -51,6 +51,90 @@ Boston, MA 02111-1307, USA. */
defined in tm.h */ defined in tm.h */
int current_first_parm_offset; 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. */ /* This is where the condition code register lives. */
/* rtx cc0_reg_rtx; - no longer needed? */ /* rtx cc0_reg_rtx; - no longer needed? */
...@@ -683,22 +767,12 @@ output_move_quad (rtx *operands) ...@@ -683,22 +767,12 @@ output_move_quad (rtx *operands)
{ {
if (GET_CODE (operands[1]) == CONST_DOUBLE) if (GET_CODE (operands[1]) == CONST_DOUBLE)
{ {
/* floats only. not yet supported! REAL_VALUE_TYPE r;
long dval[2];
-- compute it into PDP float format, - internally, REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
just use IEEE and ignore possible problems ;-) REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
latehalf[1] = GEN_INT (dval[1]);
we might get away with it !!!! */ operands[1] = GEN_INT (dval[0]);
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 */
} }
else if (GET_CODE(operands[1]) == CONST_INT) else if (GET_CODE(operands[1]) == CONST_INT)
{ {
...@@ -1591,6 +1665,21 @@ legitimate_address_p (enum machine_mode mode, rtx address) ...@@ -1591,6 +1665,21 @@ legitimate_address_p (enum machine_mode mode, rtx address)
/* #undef REG_OK_STRICT */ /* #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. /* 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 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. use, and for debugging output, which we don't support with this port either.
......
...@@ -167,14 +167,27 @@ extern int target_flags; ...@@ -167,14 +167,27 @@ extern int target_flags;
/* Define this if most significant byte of a word is the lowest numbered. */ /* Define this if most significant byte of a word is the lowest numbered. */
#define BYTES_BIG_ENDIAN 0 #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 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). /* Width of a word, in units (bytes).
UNITS OR BYTES - seems like units */ UNITS OR BYTES - seems like units */
#define UNITS_PER_WORD 2 #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 /* Maximum sized of reasonable data type
DImode or Dfmode ...*/ DImode or Dfmode ...*/
#define MAX_FIXED_MODE_SIZE 64 #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 ...@@ -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 operand as its first argument and the constraint letter as its
second operand. second operand.
`Q' is for memory references using take more than 1 instruction. `Q' is for memory references that require an extra word after the opcode.
`R' is for memory references which take 1 word for the instruction. */ `R' is for memory references which are encoded within the opcode. */
#define EXTRA_CONSTRAINT(OP,CODE) \ #define EXTRA_CONSTRAINT(OP,CODE) \
((GET_CODE (OP) != MEM) ? 0 \ ((GET_CODE (OP) != MEM) ? 0 \
...@@ -678,7 +691,7 @@ extern int may_call_alloca; ...@@ -678,7 +691,7 @@ extern int may_call_alloca;
/* Maximum number of registers that can appear in a valid memory address. */ /* 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. */ /* Recognize any constant value that is a valid address. */
...@@ -687,7 +700,8 @@ extern int may_call_alloca; ...@@ -687,7 +700,8 @@ extern int may_call_alloca;
/* Nonzero if the constant value X is a legitimate general operand. /* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ 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 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class. and check its validity for a certain class.
...@@ -1078,9 +1092,11 @@ extern struct rtx_def *cc0_reg_rtx; ...@@ -1078,9 +1092,11 @@ extern struct rtx_def *cc0_reg_rtx;
else if (GET_CODE (X) == MEM) \ else if (GET_CODE (X) == MEM) \
output_address (XEXP (X, 0)); \ output_address (XEXP (X, 0)); \
else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != SImode) \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != SImode) \
{ char buf[30]; \ { REAL_VALUE_TYPE r; \
real_to_decimal (buf, CONST_DOUBLE_REAL_VALUE (X), sizeof (buf), 0, 1); \ long sval[2]; \
fprintf (FILE, "$0F%s", buf); } \ 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); }} else { putc ('$', FILE); output_addr_const_pdp11 (FILE, X); }}
/* Print a memory address as an operand to reference that memory location. */ /* Print a memory address as an operand to reference that memory location. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment