Commit c1cfb2ae by Richard Stallman

(standard_68881_constant_p): Initialize REAL_VALUE_TYPE binary constants from decimal values.

(standard_68881_constant_p): Initialize REAL_VALUE_TYPE
binary constants from decimal values.  Use REAL_VALUE_... macros.
(standard_sun_fpa_constant_p): Likewise.
(print_operand, floating_exact_log2): Use REAL_VALUE_... macros.
(init_68881_table): New function.

From-SVN: r3971
parent 896102d0
/* Subroutines for insn-output.c for Motorola 68000 family. /* Subroutines for insn-output.c for Motorola 68000 family.
Copyright (C) 1987 Free Software Foundation, Inc. Copyright (C) 1987, 1993 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -1246,43 +1246,89 @@ output_move_const_single (operands) ...@@ -1246,43 +1246,89 @@ output_move_const_single (operands)
The value, anded with 0xff, gives the code to use in fmovecr The value, anded with 0xff, gives the code to use in fmovecr
to get the desired constant. */ to get the desired constant. */
/* ??? This code should be fixed for cross-compilation. */ /* This code has been fixed for cross-compilation. */
static int inited_68881_table = 0;
char *strings_68881[7] = {
"0.0",
"1.0",
"10.0",
"100.0",
"10000.0",
"1e8",
"1e16"
};
int codes_68881[7] = {
0x0f,
0x32,
0x33,
0x34,
0x35,
0x36,
0x37
};
REAL_VALUE_TYPE values_68881[7];
/* Set up values_68881 array by converting the decimal values
strings_68881 to binary. */
void
init_68881_table ()
{
int i;
REAL_VALUE_TYPE r;
enum machine_mode mode;
mode = DFmode;
for (i = 0; i < 7; i++)
{
if (i == 6)
mode = SFmode;
r = REAL_VALUE_ATOF (strings_68881[i], mode);
values_68881[i] = r;
}
inited_68881_table = 1;
}
int int
standard_68881_constant_p (x) standard_68881_constant_p (x)
rtx x; rtx x;
{ {
register double d; REAL_VALUE_TYPE r;
int i;
enum machine_mode mode;
/* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */ /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
if (TARGET_68040) if (TARGET_68040)
return 0; return 0;
#ifndef REAL_ARITHMETIC
#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
if (! flag_pretend_float) if (! flag_pretend_float)
return 0; return 0;
#endif #endif
#endif
REAL_VALUE_FROM_CONST_DOUBLE (d, x); if (! inited_68881_table)
init_68881_table ();
if (d == 0)
return 0x0f; REAL_VALUE_FROM_CONST_DOUBLE (r, x);
/* Note: there are various other constants available
but it is a nuisance to put in their values here. */ for (i = 0; i < 6; i++)
if (d == 1) {
return 0x32; if (REAL_VALUES_EQUAL (r, values_68881[i]))
if (d == 10) return (codes_68881[i]);
return 0x33; }
if (d == 100)
return 0x34;
if (d == 10000)
return 0x35;
if (d == 1e8)
return 0x36;
if (GET_MODE (x) == SFmode) if (GET_MODE (x) == SFmode)
return 0; return 0;
if (d == 1e16)
return 0x37; if (REAL_VALUES_EQUAL (r, values_68881[6]))
return (codes_68881[6]);
/* larger powers of ten in the constants ram are not used /* larger powers of ten in the constants ram are not used
because they are not equal to a `double' C constant. */ because they are not equal to a `double' C constant. */
return 0; return 0;
...@@ -1295,25 +1341,29 @@ int ...@@ -1295,25 +1341,29 @@ int
floating_exact_log2 (x) floating_exact_log2 (x)
rtx x; rtx x;
{ {
register double d, d1; REAL_VALUE_TYPE r, r1;
int i; int i;
#ifndef REAL_ARITHMETIC
#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
if (! flag_pretend_float) if (! flag_pretend_float)
return 0; return 0;
#endif #endif
#endif
REAL_VALUE_FROM_CONST_DOUBLE (d, x); REAL_VALUE_FROM_CONST_DOUBLE (r, x);
if (! (d > 0)) if (REAL_VALUES_LESS (r, dconst0))
return 0; return 0;
for (d1 = 1.0, i = 0; d1 < d; d1 *= 2.0, i++) i = 0;
; while (REAL_VALUES_LESS (r1, r))
{
if (d == d1) r1 = REAL_VALUE_LDEXP (dconst1, i);
return i; if (REAL_VALUES_EQUAL (r1, r))
return i;
i = i + 1;
}
return 0; return 0;
} }
...@@ -1322,131 +1372,161 @@ floating_exact_log2 (x) ...@@ -1322,131 +1372,161 @@ floating_exact_log2 (x)
from the Sun FPA's constant RAM. from the Sun FPA's constant RAM.
The value returned, anded with 0x1ff, gives the code to use in fpmove The value returned, anded with 0x1ff, gives the code to use in fpmove
to get the desired constant. */ to get the desired constant. */
#define S_E (2.718281745910644531)
#define D_E (2.718281828459045091) static int inited_FPA_table = 0;
#define S_PI (3.141592741012573242)
#define D_PI (3.141592653589793116) char *strings_FPA[38] = {
#define S_SQRT2 (1.414213538169860840) /* small rationals */
#define D_SQRT2 (1.414213562373095145) "0.0",
#define S_LOG2ofE (1.442695021629333496) "1.0",
#define D_LOG2ofE (1.442695040888963387) "0.5",
#define S_LOG2of10 (3.321928024291992188) "-1.0",
#define D_LOG2of10 (3.321928024887362182) "2.0",
#define S_LOGEof2 (0.6931471824645996094) "3.0",
#define D_LOGEof2 (0.6931471805599452862) "4.0",
#define S_LOGEof10 (2.302585124969482442) "8.0",
#define D_LOGEof10 (2.302585092994045901) "0.25",
#define S_LOG10of2 (0.3010300099849700928) "0.125",
#define D_LOG10of2 (0.3010299956639811980) "10.0",
#define S_LOG10ofE (0.4342944920063018799) "-0.5",
#define D_LOG10ofE (0.4342944819032518167) /* Decimal equivalents of double precision values */
"2.718281828459045091", /* D_E */
/* This code should be fixed for cross-compilation. */ "6.283185307179586477", /* 2 pi */
"3.141592653589793116", /* D_PI */
"1.570796326794896619", /* pi/2 */
"1.414213562373095145", /* D_SQRT2 */
"0.7071067811865475244", /* 1/sqrt(2) */
"-1.570796326794896619", /* -pi/2 */
"1.442695040888963387", /* D_LOG2ofE */
"3.321928024887362182", /* D_LOG2of10 */
"0.6931471805599452862", /* D_LOGEof2 */
"2.302585092994045901", /* D_LOGEof10 */
"0.3010299956639811980", /* D_LOG10of2 */
"0.4342944819032518167", /* D_LOG10ofE */
/* Decimal equivalents of single precision values */
"2.718281745910644531", /* S_E */
"6.283185307179586477", /* 2 pi */
"3.141592741012573242", /* S_PI */
"1.570796326794896619", /* pi/2 */
"1.414213538169860840", /* S_SQRT2 */
"0.7071067811865475244", /* 1/sqrt(2) */
"-1.570796326794896619", /* -pi/2 */
"1.442695021629333496", /* S_LOG2ofE */
"3.321928024291992188", /* S_LOG2of10 */
"0.6931471824645996094", /* S_LOGEof2 */
"2.302585124969482442", /* S_LOGEof10 */
"0.3010300099849700928", /* S_LOG10of2 */
"0.4342944920063018799", /* S_LOG10ofE */
};
int codes_FPA[38] = {
/* small rationals */
0x200,
0xe,
0xf,
0x10,
0x11,
0xb1,
0x12,
0x13,
0x15,
0x16,
0x17,
0x2e,
/* double precision */
0x8,
0x9,
0xa,
0xb,
0xc,
0xd,
0x27,
0x28,
0x29,
0x2a,
0x2b,
0x2c,
0x2d,
/* single precision */
0x8,
0x9,
0xa,
0xb,
0xc,
0xd,
0x27,
0x28,
0x29,
0x2a,
0x2b,
0x2c,
0x2d
};
REAL_VALUE_TYPE values_FPA[38];
/* This code has been fixed for cross-compilation. */
void
init_FPA_table ()
{
enum machine_mode mode;
int i;
REAL_VALUE_TYPE r;
mode = DFmode;
for (i = 0; i < 38; i++)
{
if (i == 25)
mode = SFmode;
r = REAL_VALUE_ATOF (strings_FPA[i], mode);
values_FPA[i] = r;
}
inited_FPA_table = 1;
}
int int
standard_sun_fpa_constant_p (x) standard_sun_fpa_constant_p (x)
rtx x; rtx x;
{ {
register double d; REAL_VALUE_TYPE r;
int i;
#ifndef REAL_ARITHMETIC
#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
if (! flag_pretend_float) if (! flag_pretend_float)
return 0; return 0;
#endif #endif
#endif
if (! inited_FPA_table)
init_FPA_table ();
REAL_VALUE_FROM_CONST_DOUBLE (r, x);
for (i=0; i<12; i++)
{
if (REAL_VALUES_EQUAL (r, values_FPA[i]))
return (codes_FPA[i]);
}
REAL_VALUE_FROM_CONST_DOUBLE (d, x);
if (d == 0.0)
return 0x200; /* 0 once 0x1ff is anded with it */
if (d == 1.0)
return 0xe;
if (d == 0.5)
return 0xf;
if (d == -1.0)
return 0x10;
if (d == 2.0)
return 0x11;
if (d == 3.0)
return 0xB1;
if (d == 4.0)
return 0x12;
if (d == 8.0)
return 0x13;
if (d == 0.25)
return 0x15;
if (d == 0.125)
return 0x16;
if (d == 10.0)
return 0x17;
if (d == -(1.0/2.0))
return 0x2E;
/*
* Stuff that looks different if it's single or double
*/
if (GET_MODE (x) == SFmode) if (GET_MODE (x) == SFmode)
{ {
if (d == S_E) for (i=25; i<38; i++)
return 0x8; {
if (d == (2*S_PI)) if (REAL_VALUES_EQUAL (r, values_FPA[i]))
return 0x9; return (codes_FPA[i]);
if (d == S_PI) }
return 0xA;
if (d == (S_PI / 2.0))
return 0xB;
if (d == S_SQRT2)
return 0xC;
if (d == (1.0 / S_SQRT2))
return 0xD;
/* Large powers of 10 in the constant
ram are not used because they are
not equal to a C double constant */
if (d == -(S_PI / 2.0))
return 0x27;
if (d == S_LOG2ofE)
return 0x28;
if (d == S_LOG2of10)
return 0x29;
if (d == S_LOGEof2)
return 0x2A;
if (d == S_LOGEof10)
return 0x2B;
if (d == S_LOG10of2)
return 0x2C;
if (d == S_LOG10ofE)
return 0x2D;
} }
else else
{ {
if (d == D_E) for (i=12; i<25; i++)
return 0x8; {
if (d == (2*D_PI)) if (REAL_VALUES_EQUAL (r, values_FPA[i]))
return 0x9; return (codes_FPA[i]);
if (d == D_PI) }
return 0xA;
if (d == (D_PI / 2.0))
return 0xB;
if (d == D_SQRT2)
return 0xC;
if (d == (1.0 / D_SQRT2))
return 0xD;
/* Large powers of 10 in the constant
ram are not used because they are
not equal to a C double constant */
if (d == -(D_PI / 2.0))
return 0x27;
if (d == D_LOG2ofE)
return 0x28;
if (d == D_LOG2of10)
return 0x29;
if (d == D_LOGEof2)
return 0x2A;
if (d == D_LOGEof10)
return 0x2B;
if (d == D_LOG10of2)
return 0x2C;
if (d == D_LOG10ofE)
return 0x2D;
} }
return 0x0; return 0x0;
} }
...@@ -1601,17 +1681,21 @@ print_operand (file, op, letter) ...@@ -1601,17 +1681,21 @@ print_operand (file, op, letter)
#endif #endif
else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode) else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
{ {
double d; REAL_VALUE_TYPE r;
union { float f; int i; } u1; REAL_VALUE_FROM_CONST_DOUBLE (r, op);
REAL_VALUE_FROM_CONST_DOUBLE (d, op); ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
u1.f = d; }
PRINT_OPERAND_PRINT_FLOAT (letter, file); else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
{
REAL_VALUE_TYPE r;
REAL_VALUE_FROM_CONST_DOUBLE (r, op);
ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
} }
else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode) else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode)
{ {
double d; REAL_VALUE_TYPE r;
REAL_VALUE_FROM_CONST_DOUBLE (d, op); REAL_VALUE_FROM_CONST_DOUBLE (r, op);
ASM_OUTPUT_DOUBLE_OPERAND (file, d); ASM_OUTPUT_DOUBLE_OPERAND (file, r);
} }
else else
{ {
......
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