Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
4e74d8ec
Commit
4e74d8ec
authored
Mar 11, 1996
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make long longs use normal CONST_DOUBLE in movdi, do not split too early
From-SVN: r11513
parent
9740123d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
246 additions
and
58 deletions
+246
-58
gcc/config/rs6000/rs6000.c
+102
-10
gcc/config/rs6000/rs6000.h
+8
-3
gcc/config/rs6000/rs6000.md
+136
-45
No files found.
gcc/config/rs6000/rs6000.c
View file @
4e74d8ec
...
...
@@ -524,6 +524,90 @@ reg_or_cint_operand (op, mode)
return
GET_CODE
(
op
)
==
CONST_INT
||
gpc_reg_operand
(
op
,
mode
);
}
/* Return the number of instructions it takes to form a constant in an
integer register. */
static
int
num_insns_constant_wide
(
value
)
HOST_WIDE_INT
value
;
{
/* signed constant loadable with {cal|addi} */
if
(((
unsigned
HOST_WIDE_INT
)
value
+
0x8000
)
<
0x10000
)
return
1
;
#if HOST_BITS_PER_WIDE_INT == 32
/* constant loadable with {cau|addis} */
else
if
((
value
&
0xffff
)
==
0
)
return
1
;
#else
/* constant loadable with {cau|addis} */
else
if
((
value
&
0xffff
)
==
0
&&
(
value
&
~
0xffffffff
)
==
0
)
return
1
;
else
if
(
TARGET_64BIT
)
{
HOST_WIDE_INT
low
=
value
&
0xffffffff
;
HOST_WIDE_INT
high
=
value
>>
32
;
if
(
high
==
0
&&
(
low
&
0x80000000
)
==
0
)
return
2
;
else
if
(
high
==
0xffffffff
&&
(
low
&
0x80000000
)
!=
0
)
return
2
;
else
if
(
!
low
)
return
num_insns_constant_wide
(
high
)
+
1
;
else
return
(
num_insns_constant_wide
(
high
)
+
num_insns_constant_low
(
low
)
+
1
);
}
#endif
else
return
2
;
}
int
num_insns_constant
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
mode
!=
SImode
&&
mode
!=
DImode
)
abort
();
if
(
GET_CODE
(
op
)
==
CONST_INT
)
return
num_insns_constant_wide
(
INTVAL
(
op
));
else
if
(
GET_CODE
(
op
)
==
CONST_DOUBLE
&&
TARGET_32BIT
)
return
(
num_insns_constant_wide
(
CONST_DOUBLE_LOW
(
op
))
+
num_insns_constant_wide
(
CONST_DOUBLE_HIGH
(
op
)));
else
if
(
GET_CODE
(
op
)
==
CONST_DOUBLE
&&
TARGET_64BIT
)
{
HOST_WIDE_INT
low
=
CONST_DOUBLE_LOW
(
op
);
HOST_WIDE_INT
high
=
CONST_DOUBLE_HIGH
(
op
);
if
(
high
==
0
&&
(
low
&
0x80000000
)
==
0
)
return
num_insns_constant_wide
(
low
);
else
if
(((
high
&
0xffffffff
)
==
0xffffffff
)
&&
((
low
&
0x80000000
)
!=
0
))
return
num_insns_constant_wide
(
low
);
else
if
(
low
==
0
)
return
num_insns_constant_wide
(
high
)
+
1
;
else
return
(
num_insns_constant_wide
(
high
)
+
num_insns_constant_wide
(
low
)
+
1
);
}
else
abort
();
}
/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a register
with one instruction per word. We only do this if we can safely read
CONST_DOUBLE_{LOW,HIGH}. */
...
...
@@ -535,11 +619,11 @@ easy_fp_constant (op, mode)
{
if
(
GET_CODE
(
op
)
!=
CONST_DOUBLE
||
GET_MODE
(
op
)
!=
mode
||
GET_MODE_CLASS
(
mode
)
!=
MODE_FLOAT
)
||
(
GET_MODE_CLASS
(
mode
)
!=
MODE_FLOAT
&&
mode
!=
DImode
)
)
return
0
;
/* Consider all constants with -msoft-float to be easy */
if
(
TARGET_SOFT_FLOAT
)
if
(
TARGET_SOFT_FLOAT
&&
mode
!=
DImode
)
return
1
;
if
(
mode
==
DFmode
)
...
...
@@ -550,10 +634,11 @@ easy_fp_constant (op, mode)
REAL_VALUE_FROM_CONST_DOUBLE
(
rv
,
op
);
REAL_VALUE_TO_TARGET_DOUBLE
(
rv
,
k
);
return
(
((
unsigned
)
(
k
[
0
]
+
0x8000
)
<
0x10000
||
(
k
[
0
]
&
0xffff
)
==
0
)
&&
((
unsigned
)
(
k
[
1
]
+
0x8000
)
<
0x10000
||
(
k
[
1
]
&
0xffff
)
==
0
)
);
return
(
num_insns_constant_wide
((
HOST_WIDE_INT
)
k
[
0
])
==
1
&&
num_insns_constant_wide
((
HOST_WIDE_INT
)
k
[
1
])
==
1
);
}
else
else
if
(
mode
==
SFmode
)
{
long
l
;
REAL_VALUE_TYPE
rv
;
...
...
@@ -561,8 +646,14 @@ easy_fp_constant (op, mode)
REAL_VALUE_FROM_CONST_DOUBLE
(
rv
,
op
);
REAL_VALUE_TO_TARGET_SINGLE
(
rv
,
l
);
return
((
unsigned
)
(
l
+
0x8000
)
<
0x10000
||
(
l
&
0xffff
)
==
0
)
;
return
num_insns_constant_wide
(
l
)
==
1
;
}
else
if
(
mode
==
DImode
&&
TARGET_32BIT
)
return
num_insns_constant
(
op
,
DImode
)
==
2
;
else
abort
();
}
/* Return 1 if the operand is in volatile memory. Note that during the
...
...
@@ -821,6 +912,11 @@ input_operand (op, mode)
&&
easy_fp_constant
(
op
,
mode
))
return
1
;
/* Allow any integer constant. */
if
(
GET_MODE_CLASS
(
mode
)
==
MODE_INT
&&
(
GET_CODE
(
op
)
==
CONST_INT
||
GET_CODE
(
op
)
==
CONST_DOUBLE
))
return
1
;
/* For floating-point or multi-word mode, the only remaining valid type
is a register. */
if
(
GET_MODE_CLASS
(
mode
)
==
MODE_FLOAT
...
...
@@ -833,10 +929,6 @@ input_operand (op, mode)
if
(
register_operand
(
op
,
mode
))
return
1
;
/* For integer modes, any constant is ok. */
if
(
GET_CODE
(
op
)
==
CONST_INT
)
return
1
;
/* A SYMBOL_REF referring to the TOC is valid. */
if
(
LEGITIMATE_CONSTANT_POOL_ADDRESS_P
(
op
))
return
1
;
...
...
gcc/config/rs6000/rs6000.h
View file @
4e74d8ec
...
...
@@ -995,10 +995,14 @@ enum reg_class
Here VALUE is the CONST_DOUBLE rtx itself.
We flag for special constants when we can copy the constant into
a general register in two insns for DF
and one insn for SF. */
a general register in two insns for DF
/DI and one insn for SF.
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? easy_fp_constant (VALUE, GET_MODE (VALUE)) : 0)
'H' is used for DI constants that take 3 insns. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? easy_fp_constant (VALUE, GET_MODE (VALUE)) : \
(C) == 'H' ? (num_insns_constant (VALUE, DImode) == 3) : \
0)
/* Optional extra constraints for this machine.
...
...
@@ -2819,6 +2823,7 @@ extern int reg_or_short_operand ();
extern
int
reg_or_neg_short_operand
();
extern
int
reg_or_u_short_operand
();
extern
int
reg_or_cint_operand
();
extern
int
num_insns_constant
();
extern
int
easy_fp_constant
();
extern
int
volatile_mem_operand
();
extern
int
offsettable_addr_operand
();
...
...
gcc/config/rs6000/rs6000.md
View file @
4e74d8ec
...
...
@@ -5429,8 +5429,9 @@
if (GET_CODE (operands
[
0
]
) != REG)
operands
[
1
]
= force_reg (DImode, operands
[
1
]
);
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE
|| GET_CODE (operands
[
1
]
) == CONST_INT)
if (TARGET_64BIT
&& (GET_CODE (operands
[
1
]
) == CONST_DOUBLE
|| GET_CODE (operands
[
1
]
) == CONST_INT))
{
HOST_WIDE_INT low;
HOST_WIDE_INT high;
...
...
@@ -5453,39 +5454,23 @@
}
#endif
if (! TARGET_POWERPC64)
{
emit_move_insn (gen_rtx (SUBREG, SImode, operands[0],
WORDS_BIG_ENDIAN), GEN_INT (low));
emit_move_insn (gen_rtx (SUBREG, SImode, operands[0],
! WORDS_BIG_ENDIAN), GEN_INT (high));
DONE;
}
else
{
if (high + 0x8000 >= 0x10000)
{
emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], 1),
GEN_INT (high));
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32)));
if (low)
{
HOST_WIDE_INT low_low = low & 0xffff;
HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff);
if (low_high)
emit_insn (gen_iordi3 (operands[0], operands[0],
GEN_INT (low_high)));
if (low_low)
emit_insn (gen_iordi3 (operands[0], operands[0],
GEN_INT (low_low)));
}
}
else if (low)
emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], 1),
GEN_INT (low));
DONE;
}
if (high)
{
emit_move_insn (operands[0], GEN_INT (high));
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32)));
if (low)
{
HOST_WIDE_INT low_low = low & 0xffff;
HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff);
if (low_high)
emit_insn (gen_iordi3 (operands[0], operands[0],
GEN_INT (low_high)));
if (low_low)
emit_insn (gen_iordi3 (operands[0], operands[0],
GEN_INT (low_low)));
}
DONE;
}
}
/* Stores between FPR and any non-FPR registers must go through a
...
...
@@ -5506,10 +5491,11 @@
}")
(define_insn ""
[
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m")
(match_operand:DI 1 "input_operand" "r,m,r,f,m,f"))]
"! TARGET_POWERPC64 && (gpc_reg_operand (operands
[
0
]
, DImode)
|| gpc_reg_operand (operands
[
1
]
, DImode))"
[
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r")
(match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
"TARGET_32BIT
&& (gpc_reg_operand (operands
[
0
]
, DImode)
|| gpc_reg_operand (operands
[
1
]
, DImode))"
"
*
{
switch (which_alternative)
...
...
@@ -5540,16 +5526,121 @@
return
\"
lfd%U1%X1 %0,%1
\"
;
case 5:
return
\"
stfd%U0%X0 %1,%0
\"
;
case 6:
case 7:
case 8:
case 9:
case 10:
return
\"
#
\"
;
}
}"
[
(set_attr "type" "
*
,load,store,fp,fpload,fpstore")
(set_attr "length" "8,8,8,
*,*
,
*
")])
[
(set_attr "type" "
*,load,store,fp,fpload,fpstore,*
,
*,*
,
*,*
")
(set_attr "length" "8,8,8,
*,*
,
*
,8,12,8,12,16")])
(define_split
[
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_int_operand" ""))]
"TARGET_32BIT && reload_completed && num_insns_constant (operands
[
1
]
, DImode) <= 1"
[
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 1))]
"
{
operands
[
2
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN == 0);
operands
[
3
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN != 0);
operands
[
4
]
= (INTVAL (operands
[
1
]
) & 0x80000000) ? constm1_rtx : const0_rtx;
}")
(define_split
[
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_int_operand" ""))]
"TARGET_32BIT && reload_completed && num_insns_constant (operands
[
1
]
, DImode) >= 2"
[
(set (match_dup 3) (match_dup 5))
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
"
{
HOST_WIDE_INT value = INTVAL (operands
[
1
]
);
operands
[
2
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN == 0);
operands
[
3
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN != 0);
operands
[
4
]
= (value & 0x80000000) ? constm1_rtx : const0_rtx;
operands
[
5
]
= GEN_INT (value & 0xffff0000);
operands
[
6
]
= GEN_INT (value & 0x0000ffff);
}")
(define_split
[
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
"TARGET_32BIT && reload_completed && num_insns_constant (operands
[
1
]
, DImode) <= 2"
[
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"
{
operands
[
2
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN == 0);
operands
[
3
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN != 0);
operands
[
4
]
= GEN_INT (CONST_DOUBLE_HIGH (operands
[
1
]
));
operands
[
5
]
= GEN_INT (CONST_DOUBLE_LOW (operands
[
1
]
));
}")
(define_split
[
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
"TARGET_32BIT && reload_completed && num_insns_constant (operands
[
1
]
, DImode) == 3"
[
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))
(set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
"
{
HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands
[
1
]
);
HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands
[
1
]
);
rtx high_reg = gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN == 0);
rtx low_reg = gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN != 0);
if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
|| (low & 0xffff) == 0)
{
operands
[
2
]
= high_reg;
operands
[
3
]
= low_reg;
operands
[
4
]
= GEN_INT (high & 0xffff0000);
operands
[
5
]
= GEN_INT (low);
operands
[
6
]
= GEN_INT (high & 0x0000ffff);
}
else
{
operands
[
2
]
= low_reg;
operands
[
3
]
= high_reg;
operands
[
4
]
= GEN_INT (low & 0xffff0000);
operands
[
5
]
= GEN_INT (high);
operands
[
6
]
= GEN_INT (low & 0x0000ffff);
}
}")
(define_split
[
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
"TARGET_32BIT && reload_completed && num_insns_constant (operands
[
1
]
, DImode) >= 4"
[
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))
(set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
(set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
"
{
HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands
[
1
]
);
HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands
[
1
]
);
operands
[
2
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN == 0);
operands
[
3
]
= gen_rtx (SUBREG, SImode, operands
[
0
]
, WORDS_BIG_ENDIAN != 0);
operands
[
4
]
= GEN_INT (high & 0xffff0000);
operands
[
5
]
= GEN_INT (low & 0xffff0000);
operands
[
6
]
= GEN_INT (high & 0x0000ffff);
operands
[
7
]
= GEN_INT (low & 0x0000ffff);
}")
(define_insn ""
[
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,
*h,*
h")
(match_operand:DI 1 "input_operand" "r,m,r,I,J,n,R,f,m,f,
*
h,r,0"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands
[
0
]
, DImode)
|| gpc_reg_operand (operands
[
1
]
, DImode))"
(match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,
*
h,r,0"))]
"TARGET_64BIT
&& (gpc_reg_operand (operands
[
0
]
, DImode)
|| gpc_reg_operand (operands
[
1
]
, DImode))"
"@
mr %0,%1
ld%U1%X1 %0,%1
...
...
@@ -5574,7 +5665,7 @@
(define_split
[
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
"TARGET_
POWERPC64
"
"TARGET_
64BIT && num_insns_constant (operands
[
1
]
, DImode) > 1
"
[
(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment