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
8079805d
Commit
8079805d
authored
Mar 06, 1994
by
Richard Kenner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(subst): Split into five functions.
(simplify_{rtx,if_then_else,set,logical}): New functions. From-SVN: r6703
parent
02fa1284
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
554 additions
and
645 deletions
+554
-645
gcc/combine.c
+554
-645
No files found.
gcc/combine.c
View file @
8079805d
...
@@ -386,6 +386,10 @@ static rtx try_combine PROTO((rtx, rtx, rtx));
...
@@ -386,6 +386,10 @@ static rtx try_combine PROTO((rtx, rtx, rtx));
static
void
undo_all
PROTO
((
void
));
static
void
undo_all
PROTO
((
void
));
static
rtx
*
find_split_point
PROTO
((
rtx
*
,
rtx
));
static
rtx
*
find_split_point
PROTO
((
rtx
*
,
rtx
));
static
rtx
subst
PROTO
((
rtx
,
rtx
,
rtx
,
int
,
int
));
static
rtx
subst
PROTO
((
rtx
,
rtx
,
rtx
,
int
,
int
));
static
rtx
simplify_rtx
PROTO
((
rtx
,
enum
machine_mode
,
int
,
int
));
static
rtx
simplify_if_then_else
PROTO
((
rtx
));
static
rtx
simplify_set
PROTO
((
rtx
));
static
rtx
simplify_logical
PROTO
((
rtx
,
int
));
static
rtx
expand_compound_operation
PROTO
((
rtx
));
static
rtx
expand_compound_operation
PROTO
((
rtx
));
static
rtx
expand_field_assignment
PROTO
((
rtx
));
static
rtx
expand_field_assignment
PROTO
((
rtx
));
static
rtx
make_extraction
PROTO
((
enum
machine_mode
,
rtx
,
int
,
rtx
,
int
,
static
rtx
make_extraction
PROTO
((
enum
machine_mode
,
rtx
,
int
,
rtx
,
int
,
...
@@ -2725,28 +2729,11 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -2725,28 +2729,11 @@ subst (x, from, to, in_dest, unique_copy)
int
in_dest
;
int
in_dest
;
int
unique_copy
;
int
unique_copy
;
{
{
register
char
*
fmt
;
register
int
len
,
i
;
register
enum
rtx_code
code
=
GET_CODE
(
x
),
orig_code
=
code
;
register
enum
rtx_code
code
=
GET_CODE
(
x
),
orig_code
=
code
;
rtx
temp
;
enum
machine_mode
mode
=
GET_MODE
(
x
);
enum
machine_mode
op0_mode
=
VOIDmode
;
enum
machine_mode
op0_mode
=
VOIDmode
;
rtx
other_insn
;
register
char
*
fmt
;
rtx
*
cc_use
;
register
int
len
,
i
;
int
n_restarts
=
0
;
rtx
new
;
/* FAKE_EXTEND_SAFE_P (MODE, FROM) is 1 if (subreg:MODE FROM 0) is a safe
replacement for (zero_extend:MODE FROM) or (sign_extend:MODE FROM).
If it is 0, that cannot be done. We can now do this for any MEM
because (SUBREG (MEM...)) is guaranteed to cause the MEM to be reloaded.
If not for that, MEM's would very rarely be safe. */
/* Reject MODEs bigger than a word, because we might not be able
to reference a two-register group starting with an arbitrary register
(and currently gen_lowpart might crash for a SUBREG). */
#define FAKE_EXTEND_SAFE_P(MODE, FROM) \
(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
/* Two expressions are equal if they are identical copies of a shared
/* Two expressions are equal if they are identical copies of a shared
RTX or if they are both registers with the same register number
RTX or if they are both registers with the same register number
...
@@ -2812,7 +2799,6 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -2812,7 +2799,6 @@ subst (x, from, to, in_dest, unique_copy)
register
int
j
;
register
int
j
;
for
(
j
=
XVECLEN
(
x
,
i
)
-
1
;
j
>=
0
;
j
--
)
for
(
j
=
XVECLEN
(
x
,
i
)
-
1
;
j
>=
0
;
j
--
)
{
{
register
rtx
new
;
if
(
COMBINE_RTX_EQUAL_P
(
XVECEXP
(
x
,
i
,
j
),
from
))
if
(
COMBINE_RTX_EQUAL_P
(
XVECEXP
(
x
,
i
,
j
),
from
))
{
{
new
=
(
unique_copy
&&
n_occurrences
?
copy_rtx
(
to
)
:
to
);
new
=
(
unique_copy
&&
n_occurrences
?
copy_rtx
(
to
)
:
to
);
...
@@ -2832,8 +2818,6 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -2832,8 +2818,6 @@ subst (x, from, to, in_dest, unique_copy)
}
}
else
if
(
fmt
[
i
]
==
'e'
)
else
if
(
fmt
[
i
]
==
'e'
)
{
{
register
rtx
new
;
if
(
COMBINE_RTX_EQUAL_P
(
XEXP
(
x
,
i
),
from
))
if
(
COMBINE_RTX_EQUAL_P
(
XEXP
(
x
,
i
),
from
))
{
{
/* In general, don't install a subreg involving two modes not
/* In general, don't install a subreg involving two modes not
...
@@ -2850,7 +2834,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -2850,7 +2834,8 @@ subst (x, from, to, in_dest, unique_copy)
&&
!
MODES_TIEABLE_P
(
GET_MODE
(
to
),
&&
!
MODES_TIEABLE_P
(
GET_MODE
(
to
),
GET_MODE
(
SUBREG_REG
(
to
)))
GET_MODE
(
SUBREG_REG
(
to
)))
&&
!
(
code
==
SUBREG
&&
!
(
code
==
SUBREG
&&
MODES_TIEABLE_P
(
mode
,
GET_MODE
(
SUBREG_REG
(
to
))))
&&
MODES_TIEABLE_P
(
GET_MODE
(
x
),
GET_MODE
(
SUBREG_REG
(
to
))))
#ifdef HAVE_cc0
#ifdef HAVE_cc0
&&
!
(
code
==
SET
&&
i
==
1
&&
XEXP
(
x
,
0
)
==
cc0_rtx
)
&&
!
(
code
==
SET
&&
i
==
1
&&
XEXP
(
x
,
0
)
==
cc0_rtx
)
#endif
#endif
...
@@ -2889,25 +2874,49 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -2889,25 +2874,49 @@ subst (x, from, to, in_dest, unique_copy)
}
}
}
}
/*
We come back to here if we have replaced the expression with one of
/*
Try to simplify X. If the simplification changed the code, it is likely
a different code and it is likely that further simplification will be
that further simplification will help, so loop, but limit the number
possible
. */
of repetitions that will be performed
. */
restart
:
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* If X is sufficiently simple, don't bother trying to do anything
with it. */
if
(
code
!=
CONST_INT
&&
code
!=
REG
&&
code
!=
CLOBBER
)
x
=
simplify_rtx
(
x
,
op0_mode
,
i
==
3
,
in_dest
);
/* If we have restarted more than 4 times, we are probably looping, so
if
(
GET_CODE
(
x
)
==
code
)
give up. */
break
;
if
(
++
n_restarts
>
4
)
return
x
;
/* If we are restarting at all, it means that we no longer know the
code
=
GET_CODE
(
x
);
original mode of operand 0 (since we have probably changed the
form of X). */
if
(
n_restarts
>
1
)
/* We no longer know the original mode of operand 0 since we
have changed the form of X) */
op0_mode
=
VOIDmode
;
op0_mode
=
VOIDmode
;
}
code
=
GET_CODE
(
x
);
return
x
;
}
/* Simplify X, a piece of RTL. We just operate on the expression at the
outer level; call `subst' to simplify recursively. Return the new
expression.
OP0_MODE is the original mode of XEXP (x, 0); LAST is nonzero if this
will be the iteration even if an expression with a code different from
X is returned; IN_DEST is nonzero if we are inside a SET_DEST. */
static
rtx
simplify_rtx
(
x
,
op0_mode
,
last
,
in_dest
)
rtx
x
;
enum
machine_mode
op0_mode
;
int
last
;
int
in_dest
;
{
enum
rtx_code
code
=
GET_CODE
(
x
);
enum
machine_mode
mode
=
GET_MODE
(
x
);
rtx
temp
;
int
i
;
/* If this is a commutative operation, put a constant last and a complex
/* If this is a commutative operation, put a constant last and a complex
expression first. We don't need to do this for comparisons here. */
expression first. We don't need to do this for comparisons here. */
...
@@ -3025,12 +3034,9 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3025,12 +3034,9 @@ subst (x, from, to, in_dest, unique_copy)
gen_binary
(
reverse_condition
(
cond_code
),
gen_binary
(
reverse_condition
(
cond_code
),
mode
,
cond
,
cop1
));
mode
,
cond
,
cop1
));
else
else
{
return
gen_rtx
(
IF_THEN_ELSE
,
mode
,
x
=
gen_rtx
(
IF_THEN_ELSE
,
mode
,
gen_binary
(
cond_code
,
VOIDmode
,
cond
,
cop1
),
gen_binary
(
cond_code
,
VOIDmode
,
cond
,
cop1
),
true
,
false
);
true
,
false
);
goto
restart
;
}
code
=
GET_CODE
(
x
);
code
=
GET_CODE
(
x
);
op0_mode
=
VOIDmode
;
op0_mode
=
VOIDmode
;
...
@@ -3117,11 +3123,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3117,11 +3123,7 @@ subst (x, from, to, in_dest, unique_copy)
}
}
if
(
inner
)
if
(
inner
)
{
return
gen_binary
(
code
,
mode
,
other
,
inner
);
x
=
gen_binary
(
code
,
mode
,
other
,
inner
);
goto
restart
;
}
}
}
}
}
...
@@ -3261,17 +3263,12 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3261,17 +3263,12 @@ subst (x, from, to, in_dest, unique_copy)
/* (not (plus X -1)) can become (neg X). */
/* (not (plus X -1)) can become (neg X). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
PLUS
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
PLUS
&&
XEXP
(
XEXP
(
x
,
0
),
1
)
==
constm1_rtx
)
&&
XEXP
(
XEXP
(
x
,
0
),
1
)
==
constm1_rtx
)
{
return
gen_rtx_combine
(
NEG
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
));
x
=
gen_rtx_combine
(
NEG
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
));
goto
restart
;
}
/* Similarly, (not (neg X)) is (plus X -1). */
/* Similarly, (not (neg X)) is (plus X -1). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NEG
)
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NEG
)
{
return
gen_rtx_combine
(
PLUS
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
x
=
gen_rtx_combine
(
PLUS
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
constm1_rtx
);
constm1_rtx
);
goto
restart
;
}
/* (not (xor X C)) for C constant is (xor X D) with D = ~ C. */
/* (not (xor X C)) for C constant is (xor X D) with D = ~ C. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
...
@@ -3290,11 +3287,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3290,11 +3287,8 @@ subst (x, from, to, in_dest, unique_copy)
but this doesn't seem common enough to bother with. */
but this doesn't seem common enough to bother with. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFT
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFT
&&
XEXP
(
XEXP
(
x
,
0
),
0
)
==
const1_rtx
)
&&
XEXP
(
XEXP
(
x
,
0
),
0
)
==
const1_rtx
)
{
return
gen_rtx
(
ROTATE
,
mode
,
gen_unary
(
NOT
,
mode
,
const1_rtx
),
x
=
gen_rtx
(
ROTATE
,
mode
,
gen_unary
(
NOT
,
mode
,
const1_rtx
),
XEXP
(
XEXP
(
x
,
0
),
1
));
XEXP
(
XEXP
(
x
,
0
),
1
));
goto
restart
;
}
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SUBREG
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SUBREG
&&
subreg_lowpart_p
(
XEXP
(
x
,
0
))
&&
subreg_lowpart_p
(
XEXP
(
x
,
0
))
...
@@ -3308,8 +3302,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3308,8 +3302,7 @@ subst (x, from, to, in_dest, unique_copy)
x
=
gen_rtx
(
ROTATE
,
inner_mode
,
x
=
gen_rtx
(
ROTATE
,
inner_mode
,
gen_unary
(
NOT
,
inner_mode
,
const1_rtx
),
gen_unary
(
NOT
,
inner_mode
,
const1_rtx
),
XEXP
(
SUBREG_REG
(
XEXP
(
x
,
0
)),
1
));
XEXP
(
SUBREG_REG
(
XEXP
(
x
,
0
)),
1
));
x
=
gen_lowpart_for_combine
(
mode
,
x
);
return
gen_lowpart_for_combine
(
mode
,
x
);
goto
restart
;
}
}
#if STORE_FLAG_VALUE == -1
#if STORE_FLAG_VALUE == -1
...
@@ -3360,9 +3353,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3360,9 +3353,8 @@ subst (x, from, to, in_dest, unique_copy)
in2
=
in1
;
in1
=
tem
;
in2
=
in1
;
in1
=
tem
;
}
}
x
=
gen_rtx_combine
(
GET_CODE
(
XEXP
(
x
,
0
))
==
IOR
?
AND
:
IOR
,
return
gen_rtx_combine
(
GET_CODE
(
XEXP
(
x
,
0
))
==
IOR
?
AND
:
IOR
,
mode
,
in1
,
in2
);
mode
,
in1
,
in2
);
goto
restart
;
}
}
break
;
break
;
...
@@ -3370,17 +3362,11 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3370,17 +3362,11 @@ subst (x, from, to, in_dest, unique_copy)
/* (neg (plus X 1)) can become (not X). */
/* (neg (plus X 1)) can become (not X). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
PLUS
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
PLUS
&&
XEXP
(
XEXP
(
x
,
0
),
1
)
==
const1_rtx
)
&&
XEXP
(
XEXP
(
x
,
0
),
1
)
==
const1_rtx
)
{
return
gen_rtx_combine
(
NOT
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
));
x
=
gen_rtx_combine
(
NOT
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
));
goto
restart
;
}
/* Similarly, (neg (not X)) is (plus X 1). */
/* Similarly, (neg (not X)) is (plus X 1). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NOT
)
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NOT
)
{
return
plus_constant
(
XEXP
(
XEXP
(
x
,
0
),
0
),
1
);
x
=
plus_constant
(
XEXP
(
XEXP
(
x
,
0
),
0
),
1
);
goto
restart
;
}
/* (neg (minus X Y)) can become (minus Y X). */
/* (neg (minus X Y)) can become (minus Y X). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
MINUS
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
MINUS
...
@@ -3388,19 +3374,13 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3388,19 +3374,13 @@ subst (x, from, to, in_dest, unique_copy)
/* x-y != -(y-x) with IEEE floating point. */
/* x-y != -(y-x) with IEEE floating point. */
||
TARGET_FLOAT_FORMAT
!=
IEEE_FLOAT_FORMAT
||
TARGET_FLOAT_FORMAT
!=
IEEE_FLOAT_FORMAT
||
flag_fast_math
))
||
flag_fast_math
))
{
return
gen_binary
(
MINUS
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
1
),
x
=
gen_binary
(
MINUS
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
XEXP
(
x
,
0
),
0
));
XEXP
(
XEXP
(
x
,
0
),
0
));
goto
restart
;
}
/* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
/* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
&&
XEXP
(
XEXP
(
x
,
0
),
1
)
==
const1_rtx
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
&&
XEXP
(
XEXP
(
x
,
0
),
1
)
==
const1_rtx
&&
nonzero_bits
(
XEXP
(
XEXP
(
x
,
0
),
0
),
mode
)
==
1
)
&&
nonzero_bits
(
XEXP
(
XEXP
(
x
,
0
),
0
),
mode
)
==
1
)
{
return
gen_binary
(
PLUS
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
constm1_rtx
);
x
=
gen_binary
(
PLUS
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
constm1_rtx
);
goto
restart
;
}
/* NEG commutes with ASHIFT since it is multiplication. Only do this
/* NEG commutes with ASHIFT since it is multiplication. Only do this
if we can then eliminate the NEG (e.g.,
if we can then eliminate the NEG (e.g.,
...
@@ -3426,11 +3406,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3426,11 +3406,8 @@ subst (x, from, to, in_dest, unique_copy)
if
(
GET_CODE
(
temp
)
==
ASHIFTRT
if
(
GET_CODE
(
temp
)
==
ASHIFTRT
&&
GET_CODE
(
XEXP
(
temp
,
1
))
==
CONST_INT
&&
GET_CODE
(
XEXP
(
temp
,
1
))
==
CONST_INT
&&
INTVAL
(
XEXP
(
temp
,
1
))
==
GET_MODE_BITSIZE
(
mode
)
-
1
)
&&
INTVAL
(
XEXP
(
temp
,
1
))
==
GET_MODE_BITSIZE
(
mode
)
-
1
)
{
return
simplify_shift_const
(
temp
,
LSHIFTRT
,
mode
,
XEXP
(
temp
,
0
),
x
=
simplify_shift_const
(
temp
,
LSHIFTRT
,
mode
,
XEXP
(
temp
,
0
),
INTVAL
(
XEXP
(
temp
,
1
)));
INTVAL
(
XEXP
(
temp
,
1
)));
goto
restart
;
}
/* If X has only a single bit that might be nonzero, say, bit I, convert
/* If X has only a single bit that might be nonzero, say, bit I, convert
(neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of
(neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of
...
@@ -3456,10 +3433,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3456,10 +3433,7 @@ subst (x, from, to, in_dest, unique_copy)
if
(
GET_CODE
(
temp1
)
!=
ASHIFTRT
if
(
GET_CODE
(
temp1
)
!=
ASHIFTRT
||
GET_CODE
(
XEXP
(
temp1
,
0
))
!=
ASHIFT
||
GET_CODE
(
XEXP
(
temp1
,
0
))
!=
ASHIFT
||
XEXP
(
XEXP
(
temp1
,
0
),
0
)
!=
temp
)
||
XEXP
(
XEXP
(
temp1
,
0
),
0
)
!=
temp
)
{
return
temp1
;
x
=
temp1
;
goto
restart
;
}
}
}
break
;
break
;
...
@@ -3535,15 +3509,12 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3535,15 +3509,12 @@ subst (x, from, to, in_dest, unique_copy)
||
(
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
0
))
==
ZERO_EXTEND
||
(
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
0
))
==
ZERO_EXTEND
&&
(
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
0
)))
&&
(
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
0
)))
==
i
+
1
))))
==
i
+
1
))))
{
return
simplify_shift_const
x
=
simplify_shift_const
(
NULL_RTX
,
ASHIFTRT
,
mode
,
(
NULL_RTX
,
ASHIFTRT
,
mode
,
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
0
),
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
0
),
GET_MODE_BITSIZE
(
mode
)
-
(
i
+
1
)),
GET_MODE_BITSIZE
(
mode
)
-
(
i
+
1
)),
GET_MODE_BITSIZE
(
mode
)
-
(
i
+
1
));
GET_MODE_BITSIZE
(
mode
)
-
(
i
+
1
));
goto
restart
;
}
/* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
/* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
...
@@ -3553,12 +3524,11 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3553,12 +3524,11 @@ subst (x, from, to, in_dest, unique_copy)
&&
reversible_comparison_p
(
XEXP
(
x
,
0
))
&&
reversible_comparison_p
(
XEXP
(
x
,
0
))
&&
((
STORE_FLAG_VALUE
==
-
1
&&
XEXP
(
x
,
1
)
==
const1_rtx
)
&&
((
STORE_FLAG_VALUE
==
-
1
&&
XEXP
(
x
,
1
)
==
const1_rtx
)
||
(
STORE_FLAG_VALUE
==
1
&&
XEXP
(
x
,
1
)
==
constm1_rtx
)))
||
(
STORE_FLAG_VALUE
==
1
&&
XEXP
(
x
,
1
)
==
constm1_rtx
)))
{
return
x
=
gen_binary
(
reverse_condition
(
GET_CODE
(
XEXP
(
x
,
0
))),
gen_unary
(
NEG
,
mode
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
XEXP
(
x
,
0
),
1
));
gen_binary
(
reverse_condition
(
GET_CODE
(
XEXP
(
x
,
0
))),
x
=
gen_unary
(
NEG
,
mode
,
x
);
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
goto
restart
;
XEXP
(
XEXP
(
x
,
0
),
1
)));
}
/* If only the low-order bit of X is possibly nonzero, (plus x -1)
/* If only the low-order bit of X is possibly nonzero, (plus x -1)
can become (ashiftrt (ashift (xor x 1) C) C) where C is
can become (ashiftrt (ashift (xor x 1) C) C) where C is
...
@@ -3569,16 +3539,12 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3569,16 +3539,12 @@ subst (x, from, to, in_dest, unique_copy)
&&
!
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SUBREG
&&
!
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SUBREG
&&
GET_CODE
(
SUBREG_REG
(
XEXP
(
x
,
0
)))
==
REG
)
&&
GET_CODE
(
SUBREG_REG
(
XEXP
(
x
,
0
)))
==
REG
)
&&
nonzero_bits
(
XEXP
(
x
,
0
),
mode
)
==
1
)
&&
nonzero_bits
(
XEXP
(
x
,
0
),
mode
)
==
1
)
{
return
simplify_shift_const
(
NULL_RTX
,
ASHIFTRT
,
mode
,
x
=
simplify_shift_const
(
NULL_RTX
,
ASHIFTRT
,
mode
,
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
gen_rtx_combine
(
XOR
,
mode
,
gen_rtx_combine
(
XOR
,
mode
,
XEXP
(
x
,
0
),
const1_rtx
),
XEXP
(
x
,
0
),
const1_rtx
),
GET_MODE_BITSIZE
(
mode
)
-
1
),
GET_MODE_BITSIZE
(
mode
)
-
1
),
GET_MODE_BITSIZE
(
mode
)
-
1
);
GET_MODE_BITSIZE
(
mode
)
-
1
);
goto
restart
;
}
/* If we are adding two things that have no bits in common, convert
/* If we are adding two things that have no bits in common, convert
the addition into an IOR. This will often be further simplified,
the addition into an IOR. This will often be further simplified,
...
@@ -3588,10 +3554,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3588,10 +3554,7 @@ subst (x, from, to, in_dest, unique_copy)
if
(
GET_MODE_BITSIZE
(
mode
)
<=
HOST_BITS_PER_WIDE_INT
if
(
GET_MODE_BITSIZE
(
mode
)
<=
HOST_BITS_PER_WIDE_INT
&&
(
nonzero_bits
(
XEXP
(
x
,
0
),
mode
)
&&
(
nonzero_bits
(
XEXP
(
x
,
0
),
mode
)
&
nonzero_bits
(
XEXP
(
x
,
1
),
mode
))
==
0
)
&
nonzero_bits
(
XEXP
(
x
,
1
),
mode
))
==
0
)
{
return
gen_binary
(
IOR
,
mode
,
XEXP
(
x
,
0
),
XEXP
(
x
,
1
));
x
=
gen_binary
(
IOR
,
mode
,
XEXP
(
x
,
0
),
XEXP
(
x
,
1
));
goto
restart
;
}
break
;
break
;
case
MINUS
:
case
MINUS
:
...
@@ -3612,22 +3575,16 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3612,22 +3575,16 @@ subst (x, from, to, in_dest, unique_copy)
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
1
),
1
))
==
CONST_INT
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
1
),
1
))
==
CONST_INT
&&
exact_log2
(
-
INTVAL
(
XEXP
(
XEXP
(
x
,
1
),
1
)))
>=
0
&&
exact_log2
(
-
INTVAL
(
XEXP
(
XEXP
(
x
,
1
),
1
)))
>=
0
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
1
),
0
),
XEXP
(
x
,
0
)))
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
1
),
0
),
XEXP
(
x
,
0
)))
{
return
simplify_and_const_int
(
NULL_RTX
,
mode
,
XEXP
(
x
,
0
),
x
=
simplify_and_const_int
(
NULL_RTX
,
mode
,
XEXP
(
x
,
0
),
-
INTVAL
(
XEXP
(
XEXP
(
x
,
1
),
1
))
-
1
);
-
INTVAL
(
XEXP
(
XEXP
(
x
,
1
),
1
))
-
1
);
goto
restart
;
}
/* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
/* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
integers. */
integers. */
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
PLUS
&&
INTEGRAL_MODE_P
(
mode
))
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
PLUS
&&
INTEGRAL_MODE_P
(
mode
))
{
return
gen_binary
(
MINUS
,
mode
,
x
=
gen_binary
(
MINUS
,
mode
,
gen_binary
(
MINUS
,
mode
,
XEXP
(
x
,
0
),
gen_binary
(
MINUS
,
mode
,
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
1
),
0
)),
XEXP
(
XEXP
(
x
,
1
),
0
)),
XEXP
(
XEXP
(
x
,
1
),
1
));
XEXP
(
XEXP
(
x
,
1
),
1
));
goto
restart
;
}
break
;
break
;
case
MULT
:
case
MULT
:
...
@@ -3645,7 +3602,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3645,7 +3602,7 @@ subst (x, from, to, in_dest, unique_copy)
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
))));
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
))));
if
(
GET_CODE
(
x
)
!=
MULT
)
if
(
GET_CODE
(
x
)
!=
MULT
)
goto
restart
;
return
x
;
}
}
/* If this is multiplication by a power of two and its first operand is
/* If this is multiplication by a power of two and its first operand is
...
@@ -3658,10 +3615,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3658,10 +3615,7 @@ subst (x, from, to, in_dest, unique_copy)
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFTRT
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFTRT
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATE
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATE
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATERT
))
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATERT
))
{
return
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
XEXP
(
x
,
0
),
i
);
x
=
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
XEXP
(
x
,
0
),
i
);
goto
restart
;
}
/* Convert (mult (ashift (const_int 1) A) B) to (ashift B A). */
/* Convert (mult (ashift (const_int 1) A) B) to (ashift B A). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFT
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFT
...
@@ -3680,10 +3634,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3680,10 +3634,7 @@ subst (x, from, to, in_dest, unique_copy)
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFTRT
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFTRT
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATE
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATE
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATERT
))
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ROTATERT
))
{
return
simplify_shift_const
(
NULL_RTX
,
LSHIFTRT
,
mode
,
XEXP
(
x
,
0
),
i
);
x
=
simplify_shift_const
(
NULL_RTX
,
LSHIFTRT
,
mode
,
XEXP
(
x
,
0
),
i
);
goto
restart
;
}
break
;
break
;
case
EQ
:
case
NE
:
case
EQ
:
case
NE
:
...
@@ -3733,8 +3684,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3733,8 +3684,8 @@ subst (x, from, to, in_dest, unique_copy)
==
GET_MODE_BITSIZE
(
mode
)))
==
GET_MODE_BITSIZE
(
mode
)))
{
{
op0
=
expand_compound_operation
(
op0
);
op0
=
expand_compound_operation
(
op0
);
x
=
gen_unary
(
NEG
,
mode
,
gen_lowpart_for_combine
(
mode
,
op0
));
return
gen_unary
(
NEG
,
mode
,
goto
restart
;
gen_lowpart_for_combine
(
mode
,
op0
))
;
}
}
else
if
(
new_code
==
EQ
&&
GET_MODE_CLASS
(
mode
)
==
MODE_INT
else
if
(
new_code
==
EQ
&&
GET_MODE_CLASS
(
mode
)
==
MODE_INT
...
@@ -3742,10 +3693,9 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3742,10 +3693,9 @@ subst (x, from, to, in_dest, unique_copy)
&&
nonzero_bits
(
op0
,
mode
)
==
1
)
&&
nonzero_bits
(
op0
,
mode
)
==
1
)
{
{
op0
=
expand_compound_operation
(
op0
);
op0
=
expand_compound_operation
(
op0
);
x
=
gen_binary
(
XOR
,
mode
,
return
gen_binary
(
XOR
,
mode
,
gen_lowpart_for_combine
(
mode
,
op0
),
gen_lowpart_for_combine
(
mode
,
op0
),
const1_rtx
);
const1_rtx
);
goto
restart
;
}
}
else
if
(
new_code
==
EQ
&&
GET_MODE_CLASS
(
mode
)
==
MODE_INT
else
if
(
new_code
==
EQ
&&
GET_MODE_CLASS
(
mode
)
==
MODE_INT
...
@@ -3754,8 +3704,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3754,8 +3704,7 @@ subst (x, from, to, in_dest, unique_copy)
==
GET_MODE_BITSIZE
(
mode
)))
==
GET_MODE_BITSIZE
(
mode
)))
{
{
op0
=
expand_compound_operation
(
op0
);
op0
=
expand_compound_operation
(
op0
);
x
=
plus_constant
(
gen_lowpart_for_combine
(
mode
,
op0
),
1
);
return
plus_constant
(
gen_lowpart_for_combine
(
mode
,
op0
),
1
);
goto
restart
;
}
}
#endif
#endif
...
@@ -3774,8 +3723,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3774,8 +3723,8 @@ subst (x, from, to, in_dest, unique_copy)
&&
nonzero_bits
(
op0
,
mode
)
==
1
)
&&
nonzero_bits
(
op0
,
mode
)
==
1
)
{
{
op0
=
expand_compound_operation
(
op0
);
op0
=
expand_compound_operation
(
op0
);
x
=
gen_unary
(
NEG
,
mode
,
gen_lowpart_for_combine
(
mode
,
op0
));
return
gen_unary
(
NEG
,
mode
,
goto
restart
;
gen_lowpart_for_combine
(
mode
,
op0
))
;
}
}
else
if
(
new_code
==
EQ
&&
GET_MODE_CLASS
(
mode
)
==
MODE_INT
else
if
(
new_code
==
EQ
&&
GET_MODE_CLASS
(
mode
)
==
MODE_INT
...
@@ -3784,8 +3733,8 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3784,8 +3733,8 @@ subst (x, from, to, in_dest, unique_copy)
==
GET_MODE_BITSIZE
(
mode
)))
==
GET_MODE_BITSIZE
(
mode
)))
{
{
op0
=
expand_compound_operation
(
op0
);
op0
=
expand_compound_operation
(
op0
);
x
=
gen_unary
(
NOT
,
mode
,
gen_lowpart_for_combine
(
mode
,
op0
));
return
gen_unary
(
NOT
,
mode
,
goto
restart
;
gen_lowpart_for_combine
(
mode
,
op0
))
;
}
}
/* If X is 0/1, (eq X 0) is X-1. */
/* If X is 0/1, (eq X 0) is X-1. */
...
@@ -3794,8 +3743,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3794,8 +3743,7 @@ subst (x, from, to, in_dest, unique_copy)
&&
nonzero_bits
(
op0
,
mode
)
==
1
)
&&
nonzero_bits
(
op0
,
mode
)
==
1
)
{
{
op0
=
expand_compound_operation
(
op0
);
op0
=
expand_compound_operation
(
op0
);
x
=
plus_constant
(
gen_lowpart_for_combine
(
mode
,
op0
),
-
1
);
return
plus_constant
(
gen_lowpart_for_combine
(
mode
,
op0
),
-
1
);
goto
restart
;
}
}
#endif
#endif
...
@@ -3833,38 +3781,125 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3833,38 +3781,125 @@ subst (x, from, to, in_dest, unique_copy)
break
;
break
;
case
IF_THEN_ELSE
:
case
IF_THEN_ELSE
:
return
simplify_if_then_else
(
x
);
case
ZERO_EXTRACT
:
case
SIGN_EXTRACT
:
case
ZERO_EXTEND
:
case
SIGN_EXTEND
:
/* If we are processing SET_DEST, we are done. */
if
(
in_dest
)
return
x
;
return
expand_compound_operation
(
x
);
case
SET
:
return
simplify_set
(
x
);
case
AND
:
case
IOR
:
case
XOR
:
return
simplify_logical
(
x
,
last
);
case
ABS
:
/* (abs (neg <foo>)) -> (abs <foo>) */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NEG
)
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
));
/* If operand is something known to be positive, ignore the ABS. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
FFS
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ABS
||
((
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
x
,
0
)))
<=
HOST_BITS_PER_WIDE_INT
)
&&
((
nonzero_bits
(
XEXP
(
x
,
0
),
GET_MODE
(
XEXP
(
x
,
0
)))
&
((
HOST_WIDE_INT
)
1
<<
(
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
x
,
0
)))
-
1
)))
==
0
)))
return
XEXP
(
x
,
0
);
/* If operand is known to be only -1 or 0, convert ABS to NEG. */
if
(
num_sign_bit_copies
(
XEXP
(
x
,
0
),
mode
)
==
GET_MODE_BITSIZE
(
mode
))
return
gen_rtx_combine
(
NEG
,
mode
,
XEXP
(
x
,
0
));
break
;
case
FFS
:
/* (ffs (*_extend <X>)) = (ffs <X>) */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SIGN_EXTEND
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ZERO_EXTEND
)
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
));
break
;
case
FLOAT
:
/* (float (sign_extend <X>)) = (float <X>). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SIGN_EXTEND
)
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
));
break
;
case
LSHIFT
:
case
ASHIFT
:
case
LSHIFTRT
:
case
ASHIFTRT
:
case
ROTATE
:
case
ROTATERT
:
/* If this is a shift by a constant amount, simplify it. */
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
CONST_INT
)
return
simplify_shift_const
(
x
,
code
,
mode
,
XEXP
(
x
,
0
),
INTVAL
(
XEXP
(
x
,
1
)));
#ifdef SHIFT_COUNT_TRUNCATED
else
if
(
SHIFT_COUNT_TRUNCATED
&&
GET_CODE
(
XEXP
(
x
,
1
))
!=
REG
)
SUBST
(
XEXP
(
x
,
1
),
force_to_mode
(
XEXP
(
x
,
1
),
GET_MODE
(
x
),
((
HOST_WIDE_INT
)
1
<<
exact_log2
(
GET_MODE_BITSIZE
(
GET_MODE
(
x
))))
-
1
,
NULL_RTX
,
0
));
#endif
break
;
}
return
x
;
}
/* Simplify X, an IF_THEN_ELSE expression. Return the new expression. */
static
rtx
simplify_if_then_else
(
x
)
rtx
x
;
{
enum
machine_mode
mode
=
GET_MODE
(
x
);
rtx
cond
=
XEXP
(
x
,
0
);
rtx
true
=
XEXP
(
x
,
1
);
rtx
false
=
XEXP
(
x
,
2
);
enum
rtx_code
true_code
=
GET_CODE
(
cond
);
int
comparison_p
=
GET_RTX_CLASS
(
true_code
)
==
'<'
;
rtx
temp
;
int
i
;
/* Simplify storing of the truth value. */
/* Simplify storing of the truth value. */
if
(
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
if
(
comparison_p
&&
true
==
const_true_rtx
&&
false
==
const0_rtx
)
&&
XEXP
(
x
,
1
)
==
const_true_rtx
return
gen_binary
(
true_code
,
mode
,
XEXP
(
cond
,
0
),
XEXP
(
cond
,
1
));
&&
XEXP
(
x
,
2
)
==
const0_rtx
)
return
gen_binary
(
GET_CODE
(
XEXP
(
x
,
0
)),
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
XEXP
(
x
,
0
),
1
));
/* Also when the truth value has to be reversed. */
/* Also when the truth value has to be reversed. */
if
(
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
if
(
comparison_p
&&
reversible_comparison_p
(
cond
)
&&
reversible_comparison_p
(
XEXP
(
x
,
0
))
&&
true
==
const0_rtx
&&
false
==
const_true_rtx
)
&&
XEXP
(
x
,
1
)
==
const0_rtx
return
gen_binary
(
reverse_condition
(
true_code
),
&&
XEXP
(
x
,
2
)
==
const_true_rtx
)
mode
,
XEXP
(
cond
,
0
),
XEXP
(
cond
,
1
));
return
gen_binary
(
reverse_condition
(
GET_CODE
(
XEXP
(
x
,
0
))),
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
XEXP
(
x
,
0
),
1
));
/* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register
/* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used
used in it is being compared against certain values. Get the
in it is being compared against certain values. Get the true and false
true and false comparisons and see if that says anything about the
comparisons and see if that says anything about the value of each arm. */
value of each arm. */
if
(
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
if
(
comparison_p
&&
reversible_comparison_p
(
cond
)
&&
reversible_comparison_p
(
XEXP
(
x
,
0
))
&&
GET_CODE
(
XEXP
(
cond
,
0
))
==
REG
)
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
0
))
==
REG
)
{
{
HOST_WIDE_INT
nzb
;
HOST_WIDE_INT
nzb
;
rtx
from
=
XEXP
(
XEXP
(
x
,
0
),
0
);
rtx
from
=
XEXP
(
cond
,
0
);
enum
rtx_code
true_code
=
GET_CODE
(
XEXP
(
x
,
0
));
enum
rtx_code
false_code
=
reverse_condition
(
true_code
);
enum
rtx_code
false_code
=
reverse_condition
(
true_code
);
rtx
true_val
=
XEXP
(
XEXP
(
x
,
0
)
,
1
);
rtx
true_val
=
XEXP
(
cond
,
1
);
rtx
false_val
=
true_val
;
rtx
false_val
=
true_val
;
rtx
true_arm
=
XEXP
(
x
,
1
);
rtx
false_arm
=
XEXP
(
x
,
2
);
int
swapped
=
0
;
int
swapped
=
0
;
/* If FALSE_CODE is EQ, swap the codes and arms. */
/* If FALSE_CODE is EQ, swap the codes and arms. */
...
@@ -3872,13 +3907,12 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3872,13 +3907,12 @@ subst (x, from, to, in_dest, unique_copy)
if
(
false_code
==
EQ
)
if
(
false_code
==
EQ
)
{
{
swapped
=
1
,
true_code
=
EQ
,
false_code
=
NE
;
swapped
=
1
,
true_code
=
EQ
,
false_code
=
NE
;
true_arm
=
XEXP
(
x
,
2
),
false_arm
=
XEXP
(
x
,
1
)
;
temp
=
true
,
true
=
false
,
false
=
temp
;
}
}
/* If we are comparing against zero and the expression being tested
/* If we are comparing against zero and the expression being tested has
has only a single bit that might be nonzero, that is its value
only a single bit that might be nonzero, that is its value when it is
when it is not equal to zero. Similarly if it is known to be
not equal to zero. Similarly if it is known to be -1 or 0. */
-1 or 0. */
if
(
true_code
==
EQ
&&
true_val
==
const0_rtx
if
(
true_code
==
EQ
&&
true_val
==
const0_rtx
&&
exact_log2
(
nzb
=
nonzero_bits
(
from
,
GET_MODE
(
from
)))
>=
0
)
&&
exact_log2
(
nzb
=
nonzero_bits
(
from
,
GET_MODE
(
from
)))
>=
0
)
...
@@ -3888,134 +3922,124 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -3888,134 +3922,124 @@ subst (x, from, to, in_dest, unique_copy)
==
GET_MODE_BITSIZE
(
GET_MODE
(
from
))))
==
GET_MODE_BITSIZE
(
GET_MODE
(
from
))))
false_code
=
EQ
,
false_val
=
constm1_rtx
;
false_code
=
EQ
,
false_val
=
constm1_rtx
;
/* Now simplify an arm if we know the value of the register
/* Now simplify an arm if we know the value of the register in the
in the branch and it is used in the arm. Be carefull due to
branch and it is used in the arm. Be careful due to the potential
the potential
of locally-shared RTL. */
of locally-shared RTL. */
if
(
reg_mentioned_p
(
from
,
true_arm
))
if
(
reg_mentioned_p
(
from
,
true
))
true_arm
=
subst
(
known_cond
(
copy_rtx
(
true_arm
),
true_code
,
true
=
subst
(
known_cond
(
copy_rtx
(
true
),
true_code
,
from
,
true_val
),
from
,
true_val
),
pc_rtx
,
pc_rtx
,
0
,
0
);
pc_rtx
,
pc_rtx
,
0
,
0
);
if
(
reg_mentioned_p
(
from
,
false_arm
))
if
(
reg_mentioned_p
(
from
,
false
))
false_arm
=
subst
(
known_cond
(
copy_rtx
(
false_arm
),
false_code
,
false
=
subst
(
known_cond
(
copy_rtx
(
false
),
false_code
,
from
,
false_val
),
from
,
false_val
),
pc_rtx
,
pc_rtx
,
0
,
0
);
pc_rtx
,
pc_rtx
,
0
,
0
);
SUBST
(
XEXP
(
x
,
1
),
swapped
?
false_arm
:
true_arm
);
SUBST
(
XEXP
(
x
,
1
),
swapped
?
false
:
true
);
SUBST
(
XEXP
(
x
,
2
),
swapped
?
true_arm
:
false_arm
);
SUBST
(
XEXP
(
x
,
2
),
swapped
?
true
:
false
);
true
=
XEXP
(
x
,
1
),
false
=
XEXP
(
x
,
2
),
true_code
=
GET_CODE
(
cond
);
}
}
/* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be
/* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be
reversed, do so to avoid needing two sets of patterns for
reversed, do so to avoid needing two sets of patterns for
subtract-and-branch insns. Similarly if we have a constant in the
subtract-and-branch insns. Similarly if we have a constant in the true
true arm, the false arm is the same as the first operand of the
arm, the false arm is the same as the first operand of the comparison, or
comparison, or the false arm is more complicated than the true
the false arm is more complicated than the true arm. */
arm. */
if
(
comparison_p
&&
reversible_comparison_p
(
cond
)
if
(
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
&&
(
true
==
pc_rtx
&&
reversible_comparison_p
(
XEXP
(
x
,
0
))
||
(
CONSTANT_P
(
true
)
&&
(
XEXP
(
x
,
1
)
==
pc_rtx
&&
GET_CODE
(
false
)
!=
CONST_INT
&&
false
!=
pc_rtx
)
||
(
CONSTANT_P
(
XEXP
(
x
,
1
))
||
true
==
const0_rtx
&&
GET_CODE
(
XEXP
(
x
,
2
))
!=
CONST_INT
||
(
GET_RTX_CLASS
(
GET_CODE
(
true
))
==
'o'
&&
XEXP
(
x
,
2
)
!=
pc_rtx
)
&&
GET_RTX_CLASS
(
GET_CODE
(
false
))
!=
'o'
)
||
XEXP
(
x
,
1
)
==
const0_rtx
||
(
GET_CODE
(
true
)
==
SUBREG
||
(
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
1
)))
==
'o'
&&
GET_RTX_CLASS
(
GET_CODE
(
SUBREG_REG
(
true
)))
==
'o'
&&
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
2
)))
!=
'o'
)
&&
GET_RTX_CLASS
(
GET_CODE
(
false
))
!=
'o'
)
||
(
GET_CODE
(
XEXP
(
x
,
1
))
==
SUBREG
||
reg_mentioned_p
(
true
,
false
)
&&
GET_RTX_CLASS
(
GET_CODE
(
SUBREG_REG
(
XEXP
(
x
,
1
))))
==
'o'
||
rtx_equal_p
(
false
,
XEXP
(
cond
,
0
))))
&&
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
2
)))
!=
'o'
)
{
||
reg_mentioned_p
(
XEXP
(
x
,
1
),
XEXP
(
x
,
2
))
true_code
=
reverse_condition
(
true_code
);
||
rtx_equal_p
(
XEXP
(
x
,
2
),
XEXP
(
XEXP
(
x
,
0
),
0
))))
{
SUBST
(
XEXP
(
x
,
0
),
SUBST
(
XEXP
(
x
,
0
),
gen_binary
(
reverse_condition
(
GET_CODE
(
XEXP
(
x
,
0
))),
gen_binary
(
true_code
,
GET_MODE
(
cond
),
XEXP
(
cond
,
0
),
GET_MODE
(
XEXP
(
x
,
0
)),
XEXP
(
cond
,
1
)));
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
XEXP
(
x
,
0
),
1
)));
SUBST
(
XEXP
(
x
,
1
),
false
);
SUBST
(
XEXP
(
x
,
2
),
true
);
temp
=
XEXP
(
x
,
1
);
temp
=
true
,
true
=
false
,
false
=
temp
,
cond
=
XEXP
(
x
,
0
);
SUBST
(
XEXP
(
x
,
1
),
XEXP
(
x
,
2
));
SUBST
(
XEXP
(
x
,
2
),
temp
);
}
}
/* If the two arms are identical, we don't need the comparison. */
/* If the two arms are identical, we don't need the comparison. */
if
(
rtx_equal_p
(
XEXP
(
x
,
1
),
XEXP
(
x
,
2
))
if
(
rtx_equal_p
(
true
,
false
)
&&
!
side_effects_p
(
cond
))
&&
!
side_effects_p
(
XEXP
(
x
,
0
)))
return
true
;
return
XEXP
(
x
,
1
);
/* Look for cases where we have (abs x) or (neg (abs X)). */
/* Look for cases where we have (abs x) or (neg (abs X)). */
if
(
GET_MODE_CLASS
(
mode
)
==
MODE_INT
if
(
GET_MODE_CLASS
(
mode
)
==
MODE_INT
&&
GET_CODE
(
XEXP
(
x
,
2
)
)
==
NEG
&&
GET_CODE
(
false
)
==
NEG
&&
rtx_equal_p
(
XEXP
(
x
,
1
),
XEXP
(
XEXP
(
x
,
2
)
,
0
))
&&
rtx_equal_p
(
true
,
XEXP
(
false
,
0
))
&&
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
&&
comparison_p
&&
rtx_equal_p
(
XEXP
(
x
,
1
),
XEXP
(
XEXP
(
x
,
0
)
,
0
))
&&
rtx_equal_p
(
true
,
XEXP
(
cond
,
0
))
&&
!
side_effects_p
(
XEXP
(
x
,
1
)
))
&&
!
side_effects_p
(
true
))
switch
(
GET_CODE
(
XEXP
(
x
,
0
))
)
switch
(
true_code
)
{
{
case
GT
:
case
GT
:
case
GE
:
case
GE
:
x
=
gen_unary
(
ABS
,
mode
,
XEXP
(
x
,
1
));
return
gen_unary
(
ABS
,
mode
,
true
);
goto
restart
;
case
LT
:
case
LT
:
case
LE
:
case
LE
:
x
=
gen_unary
(
NEG
,
mode
,
gen_unary
(
ABS
,
mode
,
XEXP
(
x
,
1
)));
return
gen_unary
(
NEG
,
mode
,
gen_unary
(
ABS
,
mode
,
true
));
goto
restart
;
}
}
/* Look for MIN or MAX. */
/* Look for MIN or MAX. */
if
(
!
FLOAT_MODE_P
(
mode
)
if
((
!
FLOAT_MODE_P
(
mode
)
|
flag_fast_math
)
&&
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
&&
comparison_p
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
)
)
&&
rtx_equal_p
(
XEXP
(
cond
,
0
),
true
)
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
2
)
)
&&
rtx_equal_p
(
XEXP
(
cond
,
1
),
false
)
&&
!
side_effects_p
(
XEXP
(
x
,
0
)
))
&&
!
side_effects_p
(
cond
))
switch
(
GET_CODE
(
XEXP
(
x
,
0
))
)
switch
(
true_code
)
{
{
case
GE
:
case
GE
:
case
GT
:
case
GT
:
x
=
gen_binary
(
SMAX
,
mode
,
XEXP
(
x
,
1
),
XEXP
(
x
,
2
));
return
gen_binary
(
SMAX
,
mode
,
true
,
false
);
goto
restart
;
case
LE
:
case
LE
:
case
LT
:
case
LT
:
x
=
gen_binary
(
SMIN
,
mode
,
XEXP
(
x
,
1
),
XEXP
(
x
,
2
));
return
gen_binary
(
SMIN
,
mode
,
true
,
false
);
goto
restart
;
case
GEU
:
case
GEU
:
case
GTU
:
case
GTU
:
x
=
gen_binary
(
UMAX
,
mode
,
XEXP
(
x
,
1
),
XEXP
(
x
,
2
));
return
gen_binary
(
UMAX
,
mode
,
true
,
false
);
goto
restart
;
case
LEU
:
case
LEU
:
case
LTU
:
case
LTU
:
x
=
gen_binary
(
UMIN
,
mode
,
XEXP
(
x
,
1
),
XEXP
(
x
,
2
));
return
gen_binary
(
UMIN
,
mode
,
true
,
false
);
goto
restart
;
}
}
#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
/* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when
/* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its
its second operand is zero, this can be done as (OP Z (mult COND C2))
second operand is zero, this can be done as (OP Z (mult COND C2)) where
where C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer
C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or
ZERO_EXTEND or SIGN_EXTEND as long as Z is already extended (so
SIGN_EXTEND as long as Z is already extended (so we don't destroy it).
we don't destroy it). We can do this kind of thing in some
We can do this kind of thing in some cases when STORE_FLAG_VALUE is
cases when STORE_FLAG_VALUE is neither of the above, but it isn't
neither of the above, but it isn't worth checking for.
worth checking for.
Similarly, (if_then_else COND Z 0) can be replaced by
Similarly, (if_then_else COND Z 0) can be replaced by
(mult COND (mult Z STORE_FLAG_VALUE)). */
(mult COND (mult Z STORE_FLAG_VALUE)). */
if
(
mode
!=
VOIDmode
&&
!
side_effects_p
(
x
))
if
(
comparison_p
&&
mode
!=
VOIDmode
&&
!
side_effects_p
(
x
))
{
{
rtx
t
=
make_compound_operation
(
XEXP
(
x
,
1
),
SET
);
rtx
t
=
make_compound_operation
(
true
,
SET
);
rtx
f
=
make_compound_operation
(
XEXP
(
x
,
2
),
SET
);
rtx
f
=
make_compound_operation
(
false
,
SET
);
rtx
cond_op0
=
XEXP
(
XEXP
(
x
,
0
),
0
);
rtx
cond_op0
=
XEXP
(
cond
,
0
);
rtx
cond_op1
=
XEXP
(
XEXP
(
x
,
0
),
1
);
rtx
cond_op1
=
XEXP
(
cond
,
1
);
enum
rtx_code
cond_op
=
GET_CODE
(
XEXP
(
x
,
0
));
enum
rtx_code
op
,
extend_op
=
NIL
;
enum
rtx_code
op
,
extend_op
=
NIL
;
enum
machine_mode
m
=
mode
;
enum
machine_mode
m
=
mode
;
rtx
z
=
0
,
c1
,
c2
;
rtx
z
=
0
,
c1
,
c2
;
if
(
f
==
const0_rtx
)
if
(
f
==
const0_rtx
)
return
gen_binary
(
MULT
,
mode
,
gen_binary
(
cond_op
,
mode
,
cond_op0
,
return
gen_binary
(
MULT
,
mode
,
gen_binary
(
true_code
,
mode
,
cond_op0
,
cond_op1
),
cond_op1
),
gen_binary
(
MULT
,
mode
,
t
,
const_true_rtx
));
gen_binary
(
MULT
,
mode
,
t
,
const_true_rtx
));
...
@@ -4045,8 +4069,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4045,8 +4069,7 @@ subst (x, from, to, in_dest, unique_copy)
&&
rtx_equal_p
(
SUBREG_REG
(
XEXP
(
XEXP
(
t
,
0
),
0
)),
f
)
&&
rtx_equal_p
(
SUBREG_REG
(
XEXP
(
XEXP
(
t
,
0
),
0
)),
f
)
&&
(
num_sign_bit_copies
(
f
,
GET_MODE
(
f
))
&&
(
num_sign_bit_copies
(
f
,
GET_MODE
(
f
))
>
(
GET_MODE_BITSIZE
(
mode
)
>
(
GET_MODE_BITSIZE
(
mode
)
-
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
t
,
0
),
-
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
t
,
0
),
0
))))))
0
))))))
{
{
c1
=
XEXP
(
XEXP
(
t
,
0
),
1
);
z
=
f
;
op
=
GET_CODE
(
XEXP
(
t
,
0
));
c1
=
XEXP
(
XEXP
(
t
,
0
),
1
);
z
=
f
;
op
=
GET_CODE
(
XEXP
(
t
,
0
));
extend_op
=
SIGN_EXTEND
;
extend_op
=
SIGN_EXTEND
;
...
@@ -4061,8 +4084,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4061,8 +4084,7 @@ subst (x, from, to, in_dest, unique_copy)
&&
rtx_equal_p
(
SUBREG_REG
(
XEXP
(
XEXP
(
t
,
0
),
1
)),
f
)
&&
rtx_equal_p
(
SUBREG_REG
(
XEXP
(
XEXP
(
t
,
0
),
1
)),
f
)
&&
(
num_sign_bit_copies
(
f
,
GET_MODE
(
f
))
&&
(
num_sign_bit_copies
(
f
,
GET_MODE
(
f
))
>
(
GET_MODE_BITSIZE
(
mode
)
>
(
GET_MODE_BITSIZE
(
mode
)
-
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
t
,
0
),
-
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
t
,
0
),
1
))))))
1
))))))
{
{
c1
=
XEXP
(
XEXP
(
t
,
0
),
0
);
z
=
f
;
op
=
GET_CODE
(
XEXP
(
t
,
0
));
c1
=
XEXP
(
XEXP
(
t
,
0
),
0
);
z
=
f
;
op
=
GET_CODE
(
XEXP
(
t
,
0
));
extend_op
=
SIGN_EXTEND
;
extend_op
=
SIGN_EXTEND
;
...
@@ -4107,15 +4129,11 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4107,15 +4129,11 @@ subst (x, from, to, in_dest, unique_copy)
if
(
z
)
if
(
z
)
{
{
temp
=
subst
(
gen_binary
(
cond_op
,
m
,
cond_op0
,
cond_op1
),
temp
=
subst
(
gen_binary
(
true_code
,
m
,
cond_op0
,
cond_op1
),
pc_rtx
,
pc_rtx
,
0
,
0
);
pc_rtx
,
pc_rtx
,
0
,
0
);
temp
=
gen_binary
(
MULT
,
m
,
temp
,
temp
=
gen_binary
(
MULT
,
m
,
temp
,
gen_binary
(
MULT
,
m
,
c1
,
const_true_rtx
));
gen_binary
(
MULT
,
m
,
c1
,
const_true_rtx
));
temp
=
subst
(
temp
,
pc_rtx
,
pc_rtx
,
0
,
0
);
temp
=
subst
(
temp
,
pc_rtx
,
pc_rtx
,
0
,
0
);
temp
=
gen_binary
(
op
,
m
,
gen_lowpart_for_combine
(
m
,
z
),
temp
);
temp
=
gen_binary
(
op
,
m
,
gen_lowpart_for_combine
(
m
,
z
),
temp
);
if
(
extend_op
!=
NIL
)
if
(
extend_op
!=
NIL
)
...
@@ -4126,96 +4144,91 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4126,96 +4144,91 @@ subst (x, from, to, in_dest, unique_copy)
}
}
#endif
#endif
/* If we have (if_then_else (ne A 0) C1 0) and either A is known to
/* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or
be 0 or 1 and C1 is a single bit or A is known to be 0 or -1 and
1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the
C1 is the negation of a single bit, we can convert this operation
negation of a single bit, we can convert this operation to a shift. We
to a shift. We can actually do this in more general cases, but it
can actually do this more generally, but it doesn't seem worth it. */
doesn't seem worth it. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NE
&&
XEXP
(
XEXP
(
x
,
0
)
,
1
)
==
const0_rtx
if
(
true_code
==
NE
&&
XEXP
(
cond
,
1
)
==
const0_rtx
&&
XEXP
(
x
,
2
)
==
const0_rtx
&&
GET_CODE
(
XEXP
(
x
,
1
)
)
==
CONST_INT
&&
false
==
const0_rtx
&&
GET_CODE
(
true
)
==
CONST_INT
&&
((
1
==
nonzero_bits
(
XEXP
(
XEXP
(
x
,
0
)
,
0
),
mode
)
&&
((
1
==
nonzero_bits
(
XEXP
(
cond
,
0
),
mode
)
&&
(
i
=
exact_log2
(
INTVAL
(
XEXP
(
x
,
1
)
)))
>=
0
)
&&
(
i
=
exact_log2
(
INTVAL
(
true
)))
>=
0
)
||
((
num_sign_bit_copies
(
XEXP
(
XEXP
(
x
,
0
)
,
0
),
mode
)
||
((
num_sign_bit_copies
(
XEXP
(
cond
,
0
),
mode
)
==
GET_MODE_BITSIZE
(
mode
))
==
GET_MODE_BITSIZE
(
mode
))
&&
(
i
=
exact_log2
(
-
INTVAL
(
XEXP
(
x
,
1
)
)))
>=
0
)))
&&
(
i
=
exact_log2
(
-
INTVAL
(
true
)))
>=
0
)))
return
return
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
simplify_shift_const
(
NULL_RTX
,
ASHIFT
,
mode
,
gen_lowpart_for_combine
(
mode
,
gen_lowpart_for_combine
(
mode
,
XEXP
(
cond
,
0
)),
i
);
XEXP
(
XEXP
(
x
,
0
),
0
)),
i
);
break
;
case
ZERO_EXTRACT
:
case
SIGN_EXTRACT
:
case
ZERO_EXTEND
:
case
SIGN_EXTEND
:
/* If we are processing SET_DEST, we are done. */
if
(
in_dest
)
return
x
;
return
x
;
}
x
=
expand_compound_operation
(
x
);
/* Simplify X, a SET expression. Return the new expression. */
if
(
GET_CODE
(
x
)
!=
code
)
goto
restart
;
static
rtx
break
;
simplify_set
(
x
)
rtx
x
;
{
rtx
src
=
SET_SRC
(
x
);
rtx
dest
=
SET_DEST
(
x
);
enum
machine_mode
mode
=
GET_MODE
(
src
)
!=
VOIDmode
?
GET_MODE
(
src
)
:
GET_MODE
(
dest
);
rtx
other_insn
;
rtx
*
cc_use
;
case
SET
:
/* (set (pc) (return)) gets written as (return). */
/* (set (pc) (return)) gets written as (return). */
if
(
GET_CODE
(
SET_DEST
(
x
))
==
PC
&&
GET_CODE
(
SET_SRC
(
x
)
)
==
RETURN
)
if
(
GET_CODE
(
dest
)
==
PC
&&
GET_CODE
(
src
)
==
RETURN
)
return
SET_SRC
(
x
)
;
return
src
;
/* Convert this into a field assignment operation, if possible. */
/* Convert this into a field assignment operation, if possible. */
x
=
make_field_assignment
(
x
);
x
=
make_field_assignment
(
x
);
/* If we are setting CC0 or if the source is a COMPARE, look for the
/* If we are setting CC0 or if the source is a COMPARE, look for the use of
use of the comparison result and try to simplify it unless we already
the comparison result and try to simplify it unless we already have used
have used
undobuf.other_insn. */
undobuf.other_insn. */
if
((
GET_CODE
(
SET_SRC
(
x
)
)
==
COMPARE
if
((
GET_CODE
(
src
)
==
COMPARE
#ifdef HAVE_cc0
#ifdef HAVE_cc0
||
SET_DEST
(
x
)
==
cc0_rtx
||
dest
==
cc0_rtx
#endif
#endif
)
)
&&
(
cc_use
=
find_single_use
(
SET_DEST
(
x
),
subst_insn
,
&&
(
cc_use
=
find_single_use
(
dest
,
subst_insn
,
&
other_insn
))
!=
0
&
other_insn
))
!=
0
&&
(
undobuf
.
other_insn
==
0
||
other_insn
==
undobuf
.
other_insn
)
&&
(
undobuf
.
other_insn
==
0
||
other_insn
==
undobuf
.
other_insn
)
&&
GET_RTX_CLASS
(
GET_CODE
(
*
cc_use
))
==
'<'
&&
GET_RTX_CLASS
(
GET_CODE
(
*
cc_use
))
==
'<'
&&
XEXP
(
*
cc_use
,
0
)
==
SET_DEST
(
x
)
)
&&
XEXP
(
*
cc_use
,
0
)
==
dest
)
{
{
enum
rtx_code
old_code
=
GET_CODE
(
*
cc_use
);
enum
rtx_code
old_code
=
GET_CODE
(
*
cc_use
);
enum
rtx_code
new_code
;
enum
rtx_code
new_code
;
rtx
op0
,
op1
;
rtx
op0
,
op1
;
int
other_changed
=
0
;
int
other_changed
=
0
;
enum
machine_mode
compare_mode
=
GET_MODE
(
SET_DEST
(
x
)
);
enum
machine_mode
compare_mode
=
GET_MODE
(
dest
);
if
(
GET_CODE
(
SET_SRC
(
x
)
)
==
COMPARE
)
if
(
GET_CODE
(
src
)
==
COMPARE
)
op0
=
XEXP
(
SET_SRC
(
x
),
0
),
op1
=
XEXP
(
SET_SRC
(
x
)
,
1
);
op0
=
XEXP
(
src
,
0
),
op1
=
XEXP
(
src
,
1
);
else
else
op0
=
SET_SRC
(
x
)
,
op1
=
const0_rtx
;
op0
=
src
,
op1
=
const0_rtx
;
/* Simplify our comparison, if possible. */
/* Simplify our comparison, if possible. */
new_code
=
simplify_comparison
(
old_code
,
&
op0
,
&
op1
);
new_code
=
simplify_comparison
(
old_code
,
&
op0
,
&
op1
);
#ifdef EXTRA_CC_MODES
#ifdef EXTRA_CC_MODES
/* If this machine has CC modes other than CCmode, check to se
e
/* If this machine has CC modes other than CCmode, check to see if w
e
if we
need to use a different CC mode here. */
need to use a different CC mode here. */
compare_mode
=
SELECT_CC_MODE
(
new_code
,
op0
,
op1
);
compare_mode
=
SELECT_CC_MODE
(
new_code
,
op0
,
op1
);
#endif
/* EXTRA_CC_MODES */
#endif
/* EXTRA_CC_MODES */
#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES)
#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES)
/* If the mode changed, we have to change SET_DEST, the mode
/* If the mode changed, we have to change SET_DEST, the mode in the
in the compare, and the mode in the place SET_DEST is used.
compare, and the mode in the place SET_DEST is used. If SET_DEST is
If SET_DEST is a hard register, just build new versions with
a hard register, just build new versions with the proper mode. If it
the proper mode. If it is a pseudo, we lose unless it is only
is a pseudo, we lose unless it is only time we set the pseudo, in
time we set the pseudo, in which case we can safely change
which case we can safely change its mode. */
its mode. */
if
(
compare_mode
!=
GET_MODE
(
dest
))
if
(
compare_mode
!=
GET_MODE
(
SET_DEST
(
x
)))
{
{
int
regno
=
REGNO
(
dest
);
int
regno
=
REGNO
(
SET_DEST
(
x
));
rtx
new_dest
=
gen_rtx
(
REG
,
compare_mode
,
regno
);
rtx
new_dest
=
gen_rtx
(
REG
,
compare_mode
,
regno
);
if
(
regno
<
FIRST_PSEUDO_REGISTER
if
(
regno
<
FIRST_PSEUDO_REGISTER
||
(
reg_n_sets
[
regno
]
==
1
||
(
reg_n_sets
[
regno
]
==
1
&&
!
REG_USERVAR_P
(
dest
)))
&&
!
REG_USERVAR_P
(
SET_DEST
(
x
))))
{
{
if
(
regno
>=
FIRST_PSEUDO_REGISTER
)
if
(
regno
>=
FIRST_PSEUDO_REGISTER
)
SUBST
(
regno_reg_rtx
[
regno
],
new_dest
);
SUBST
(
regno_reg_rtx
[
regno
],
new_dest
);
...
@@ -4223,33 +4236,32 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4223,33 +4236,32 @@ subst (x, from, to, in_dest, unique_copy)
SUBST
(
SET_DEST
(
x
),
new_dest
);
SUBST
(
SET_DEST
(
x
),
new_dest
);
SUBST
(
XEXP
(
*
cc_use
,
0
),
new_dest
);
SUBST
(
XEXP
(
*
cc_use
,
0
),
new_dest
);
other_changed
=
1
;
other_changed
=
1
;
dest
=
new_dest
;
}
}
}
}
#endif
#endif
/* If the code changed, we have to build a new compariso
n
/* If the code changed, we have to build a new comparison i
n
in
undobuf.other_insn. */
undobuf.other_insn. */
if
(
new_code
!=
old_code
)
if
(
new_code
!=
old_code
)
{
{
unsigned
HOST_WIDE_INT
mask
;
unsigned
HOST_WIDE_INT
mask
;
SUBST
(
*
cc_use
,
gen_rtx_combine
(
new_code
,
GET_MODE
(
*
cc_use
),
SUBST
(
*
cc_use
,
gen_rtx_combine
(
new_code
,
GET_MODE
(
*
cc_use
),
SET_DEST
(
x
)
,
const0_rtx
));
dest
,
const0_rtx
));
/* If the only change we made was to change an EQ into an
/* If the only change we made was to change an EQ into an NE or
NE or vice versa, OP0 has only one bit that might be nonzero,
vice versa, OP0 has only one bit that might be nonzero, and OP1
and OP1 is zero, check if changing the user of the condition
is zero, check if changing the user of the condition code will
code will produce a valid insn. If it won't, we can keep
produce a valid insn. If it won't, we can keep the original code
the original code in that insn by surrounding our operation
in that insn by surrounding our operation with an XOR. */
with an XOR. */
if
(((
old_code
==
NE
&&
new_code
==
EQ
)
if
(((
old_code
==
NE
&&
new_code
==
EQ
)
||
(
old_code
==
EQ
&&
new_code
==
NE
))
||
(
old_code
==
EQ
&&
new_code
==
NE
))
&&
!
other_changed
&&
op1
==
const0_rtx
&&
!
other_changed
&&
op1
==
const0_rtx
&&
(
GET_MODE_BITSIZE
(
GET_MODE
(
op0
))
&&
GET_MODE_BITSIZE
(
GET_MODE
(
op0
))
<=
HOST_BITS_PER_WIDE_INT
<=
HOST_BITS_PER_WIDE_INT
)
&&
exact_log2
(
mask
=
nonzero_bits
(
op0
,
GET_MODE
(
op0
)))
>=
0
)
&&
(
exact_log2
(
mask
=
nonzero_bits
(
op0
,
GET_MODE
(
op0
)))
>=
0
))
{
{
rtx
pat
=
PATTERN
(
other_insn
),
note
=
0
;
rtx
pat
=
PATTERN
(
other_insn
),
note
=
0
;
...
@@ -4259,8 +4271,7 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4259,8 +4271,7 @@ subst (x, from, to, in_dest, unique_copy)
PUT_CODE
(
*
cc_use
,
old_code
);
PUT_CODE
(
*
cc_use
,
old_code
);
other_insn
=
0
;
other_insn
=
0
;
op0
=
gen_binary
(
XOR
,
GET_MODE
(
op0
),
op0
,
op0
=
gen_binary
(
XOR
,
GET_MODE
(
op0
),
op0
,
GEN_INT
(
mask
));
GEN_INT
(
mask
));
}
}
}
}
...
@@ -4273,109 +4284,112 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4273,109 +4284,112 @@ subst (x, from, to, in_dest, unique_copy)
#ifdef HAVE_cc0
#ifdef HAVE_cc0
/* If we are now comparing against zero, change our source if
/* If we are now comparing against zero, change our source if
needed. If we do not use cc0, we always have a COMPARE. */
needed. If we do not use cc0, we always have a COMPARE. */
if
(
op1
==
const0_rtx
&&
SET_DEST
(
x
)
==
cc0_rtx
)
if
(
op1
==
const0_rtx
&&
dest
==
cc0_rtx
)
{
SUBST
(
SET_SRC
(
x
),
op0
);
SUBST
(
SET_SRC
(
x
),
op0
);
src
=
op0
;
}
else
else
#endif
#endif
/* Otherwise, if we didn't previously have a COMPARE in the
/* Otherwise, if we didn't previously have a COMPARE in the
correct mode, we need one. */
correct mode, we need one. */
if
(
GET_CODE
(
SET_SRC
(
x
))
!=
COMPARE
if
(
GET_CODE
(
src
)
!=
COMPARE
||
GET_MODE
(
src
)
!=
compare_mode
)
||
GET_MODE
(
SET_SRC
(
x
))
!=
compare_mode
)
{
SUBST
(
SET_SRC
(
x
),
gen_rtx_combine
(
COMPARE
,
compare_mode
,
SUBST
(
SET_SRC
(
x
),
op0
,
op1
));
gen_rtx_combine
(
COMPARE
,
compare_mode
,
op0
,
op1
));
src
=
SET_SRC
(
x
);
}
else
else
{
{
/* Otherwise, update the COMPARE if needed. */
/* Otherwise, update the COMPARE if needed. */
SUBST
(
XEXP
(
SET_SRC
(
x
)
,
0
),
op0
);
SUBST
(
XEXP
(
src
,
0
),
op0
);
SUBST
(
XEXP
(
SET_SRC
(
x
)
,
1
),
op1
);
SUBST
(
XEXP
(
src
,
1
),
op1
);
}
}
}
}
else
else
{
{
/* Get SET_SRC in a form where we have placed back any
/* Get SET_SRC in a form where we have placed back any
compound expressions. Then do the checks below. */
compound expressions. Then do the checks below. */
temp
=
make_compound_operation
(
SET_SRC
(
x
)
,
SET
);
src
=
make_compound_operation
(
src
,
SET
);
SUBST
(
SET_SRC
(
x
),
temp
);
SUBST
(
SET_SRC
(
x
),
src
);
}
}
/* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some
/* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation,
operation, and X being a REG or (subreg (reg)), we may be able
to
and X being a REG or (subreg (reg)), we may be able to convert this
to
convert this to (set (subreg:m2 x) (op)).
(set (subreg:m2 x) (op)).
We can always do this if M1 is narrower than M2 because
that
We can always do this if M1 is narrower than M2 because that means
that
means that
we only care about the low bits of the result.
we only care about the low bits of the result.
However, on machines without WORD_REGISTER_OPERATIONS defined,
However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot
we cannot perform a narrower operation that requested since the
perform a narrower operation that requested since the high-order bits will
high-order bits will be undefined. On machine where it is defined,
be undefined. On machine where it is defined, this transformation is safe
this transformation is safe as long as M1 and M2 have the same
as long as M1 and M2 have the same number of words. */
number of words. */
if
(
GET_CODE
(
SET_SRC
(
x
))
==
SUBREG
if
(
GET_CODE
(
src
)
==
SUBREG
&&
subreg_lowpart_p
(
src
)
&&
subreg_lowpart_p
(
SET_SRC
(
x
))
&&
GET_RTX_CLASS
(
GET_CODE
(
SUBREG_REG
(
src
)))
!=
'o'
&&
GET_RTX_CLASS
(
GET_CODE
(
SUBREG_REG
(
SET_SRC
(
x
))))
!=
'o'
&&
(((
GET_MODE_SIZE
(
GET_MODE
(
src
))
+
(
UNITS_PER_WORD
-
1
))
&&
(((
GET_MODE_SIZE
(
GET_MODE
(
SET_SRC
(
x
)))
+
(
UNITS_PER_WORD
-
1
))
/
UNITS_PER_WORD
)
/
UNITS_PER_WORD
)
==
((
GET_MODE_SIZE
(
GET_MODE
(
SUBREG_REG
(
SET_SRC
(
x
)
)))
==
((
GET_MODE_SIZE
(
GET_MODE
(
SUBREG_REG
(
src
)))
+
(
UNITS_PER_WORD
-
1
))
/
UNITS_PER_WORD
))
+
(
UNITS_PER_WORD
-
1
))
/
UNITS_PER_WORD
))
#ifndef WORD_REGISTER_OPERATIONS
#ifndef WORD_REGISTER_OPERATIONS
&&
(
GET_MODE_SIZE
(
GET_MODE
(
SET_SRC
(
x
)
))
&&
(
GET_MODE_SIZE
(
GET_MODE
(
src
))
<
GET_MODE_SIZE
(
GET_MODE
(
SUBREG_REG
(
SET_SRC
(
x
)
))))
<
GET_MODE_SIZE
(
GET_MODE
(
SUBREG_REG
(
src
))))
#endif
#endif
&&
(
GET_CODE
(
SET_DEST
(
x
)
)
==
REG
&&
(
GET_CODE
(
dest
)
==
REG
||
(
GET_CODE
(
SET_DEST
(
x
)
)
==
SUBREG
||
(
GET_CODE
(
dest
)
==
SUBREG
&&
GET_CODE
(
SUBREG_REG
(
SET_DEST
(
x
)
))
==
REG
)))
&&
GET_CODE
(
SUBREG_REG
(
dest
))
==
REG
)))
{
{
SUBST
(
SET_DEST
(
x
),
SUBST
(
SET_DEST
(
x
),
gen_lowpart_for_combine
(
GET_MODE
(
SUBREG_REG
(
SET_SRC
(
x
))),
gen_lowpart_for_combine
(
GET_MODE
(
SUBREG_REG
(
src
)),
SET_DEST
(
x
)));
dest
));
SUBST
(
SET_SRC
(
x
),
SUBREG_REG
(
SET_SRC
(
x
)));
SUBST
(
SET_SRC
(
x
),
SUBREG_REG
(
src
));
src
=
SET_SRC
(
x
),
dest
=
SET_DEST
(
x
);
}
}
#ifdef LOAD_EXTEND_OP
#ifdef LOAD_EXTEND_OP
/* If we have (set FOO (subreg:M (mem:N BAR) 0)) with
/* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
M wider than N, this would require a paradoxical subreg.
would require a paradoxical subreg. Replace the subreg with a
Replace the subreg with a zero_extend to avoid the reload that
zero_extend to avoid the reload that would otherwise be required. */
would otherwise be required. */
if
(
GET_CODE
(
src
)
==
SUBREG
&&
subreg_lowpart_p
(
src
)
if
(
GET_CODE
(
SET_SRC
(
x
))
==
SUBREG
&&
LOAD_EXTEND_OP
(
GET_MODE
(
SUBREG_REG
(
src
)))
!=
NIL
&&
LOAD_EXTEND_OP
(
GET_MODE
(
SUBREG_REG
(
SET_SRC
(
x
))))
!=
NIL
&&
SUBREG_WORD
(
src
)
==
0
&&
subreg_lowpart_p
(
SET_SRC
(
x
))
&&
(
GET_MODE_SIZE
(
GET_MODE
(
src
))
&&
SUBREG_WORD
(
SET_SRC
(
x
))
==
0
>
GET_MODE_SIZE
(
GET_MODE
(
SUBREG_REG
(
src
))))
&&
(
GET_MODE_SIZE
(
GET_MODE
(
SET_SRC
(
x
)))
&&
GET_CODE
(
SUBREG_REG
(
src
))
==
MEM
)
>
GET_MODE_SIZE
(
GET_MODE
(
SUBREG_REG
(
SET_SRC
(
x
)))))
{
&&
GET_CODE
(
SUBREG_REG
(
SET_SRC
(
x
)))
==
MEM
)
SUBST
(
SET_SRC
(
x
),
SUBST
(
SET_SRC
(
x
),
gen_rtx_combine
(
LOAD_EXTEND_OP
(
GET_MODE
gen_rtx_combine
(
LOAD_EXTEND_OP
(
GET_MODE
(
SUBREG_REG
(
src
))),
(
SUBREG_REG
(
SET_SRC
(
x
)))),
GET_MODE
(
src
),
XEXP
(
src
,
0
)));
GET_MODE
(
SET_SRC
(
x
)),
XEXP
(
SET_SRC
(
x
),
0
)));
src
=
SET_SRC
(
x
);
}
#endif
#endif
#ifndef HAVE_conditional_move
#ifndef HAVE_conditional_move
/* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE,
/* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we
and we are comparing an item known to be 0 or -1 against 0, use a
are comparing an item known to be 0 or -1 against 0, use a logical
logical operation instead. Check for one of the arms being an IOR
operation instead. Check for one of the arms being an IOR of the other
of the other arm with some value. We compute three terms to be
arm with some value. We compute three terms to be IOR'ed together. In
IOR'ed together. In practice, at most two will be nonzero. Then
practice, at most two will be nonzero. Then we do the IOR's. */
we do the IOR's. */
if
(
GET_CODE
(
dest
)
!=
PC
if
(
GET_CODE
(
SET_DEST
(
x
))
!=
PC
&&
GET_CODE
(
src
)
==
IF_THEN_ELSE
&&
GET_CODE
(
SET_SRC
(
x
))
==
IF_THEN_ELSE
&&
(
GET_CODE
(
XEXP
(
src
,
0
))
==
EQ
||
GET_CODE
(
XEXP
(
src
,
0
))
==
NE
)
&&
(
GET_CODE
(
XEXP
(
SET_SRC
(
x
),
0
))
==
EQ
&&
XEXP
(
XEXP
(
src
,
0
),
1
)
==
const0_rtx
||
GET_CODE
(
XEXP
(
SET_SRC
(
x
),
0
))
==
NE
)
&&
(
num_sign_bit_copies
(
XEXP
(
XEXP
(
src
,
0
),
0
),
&&
XEXP
(
XEXP
(
SET_SRC
(
x
),
0
),
1
)
==
const0_rtx
GET_MODE
(
XEXP
(
XEXP
(
src
,
0
),
0
)))
&&
(
num_sign_bit_copies
(
XEXP
(
XEXP
(
SET_SRC
(
x
),
0
),
0
),
==
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
src
,
0
),
0
))))
GET_MODE
(
XEXP
(
XEXP
(
SET_SRC
(
x
),
0
),
0
)))
&&
!
side_effects_p
(
src
))
==
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
XEXP
(
SET_SRC
(
x
),
0
),
0
))))
{
&&
!
side_effects_p
(
SET_SRC
(
x
)))
rtx
true
=
(
GET_CODE
(
XEXP
(
src
,
0
))
==
NE
{
?
XEXP
(
src
,
1
)
:
XEXP
(
src
,
2
));
rtx
true
=
(
GET_CODE
(
XEXP
(
SET_SRC
(
x
),
0
))
==
NE
rtx
false
=
(
GET_CODE
(
XEXP
(
src
,
0
))
==
NE
?
XEXP
(
SET_SRC
(
x
),
1
)
:
XEXP
(
SET_SRC
(
x
),
2
));
?
XEXP
(
src
,
2
)
:
XEXP
(
src
,
1
));
rtx
false
=
(
GET_CODE
(
XEXP
(
SET_SRC
(
x
),
0
))
==
NE
?
XEXP
(
SET_SRC
(
x
),
2
)
:
XEXP
(
SET_SRC
(
x
),
1
));
rtx
term1
=
const0_rtx
,
term2
,
term3
;
rtx
term1
=
const0_rtx
,
term2
,
term3
;
if
(
GET_CODE
(
true
)
==
IOR
&&
rtx_equal_p
(
XEXP
(
true
,
0
),
false
))
if
(
GET_CODE
(
true
)
==
IOR
&&
rtx_equal_p
(
XEXP
(
true
,
0
),
false
))
...
@@ -4390,94 +4404,91 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4390,94 +4404,91 @@ subst (x, from, to, in_dest, unique_copy)
&&
rtx_equal_p
(
XEXP
(
false
,
1
),
true
))
&&
rtx_equal_p
(
XEXP
(
false
,
1
),
true
))
term1
=
true
,
false
=
XEXP
(
false
,
0
),
true
=
const0_rtx
;
term1
=
true
,
false
=
XEXP
(
false
,
0
),
true
=
const0_rtx
;
term2
=
gen_binary
(
AND
,
GET_MODE
(
SET_SRC
(
x
)),
term2
=
gen_binary
(
AND
,
GET_MODE
(
src
),
XEXP
(
XEXP
(
src
,
0
),
0
),
true
);
XEXP
(
XEXP
(
SET_SRC
(
x
),
0
),
0
),
true
);
term3
=
gen_binary
(
AND
,
GET_MODE
(
src
),
term3
=
gen_binary
(
AND
,
GET_MODE
(
SET_SRC
(
x
)),
gen_unary
(
NOT
,
GET_MODE
(
src
),
gen_unary
(
NOT
,
GET_MODE
(
SET_SRC
(
x
)),
XEXP
(
XEXP
(
src
,
0
),
0
)),
XEXP
(
XEXP
(
SET_SRC
(
x
),
0
),
0
)),
false
);
false
);
SUBST
(
SET_SRC
(
x
),
SUBST
(
SET_SRC
(
x
),
gen_binary
(
IOR
,
GET_MODE
(
SET_SRC
(
x
)),
gen_binary
(
IOR
,
GET_MODE
(
src
),
gen_binary
(
IOR
,
GET_MODE
(
SET_SRC
(
x
)),
gen_binary
(
IOR
,
GET_MODE
(
src
),
term1
,
term2
),
term1
,
term2
),
term3
));
term3
));
src
=
SET_SRC
(
x
);
}
}
#endif
#endif
break
;
return
x
;
}
/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified
result. LAST is nonzero if this is the last retry. */
static
rtx
simplify_logical
(
x
,
last
)
rtx
x
;
int
last
;
{
enum
machine_mode
mode
=
GET_MODE
(
x
);
rtx
op0
=
XEXP
(
x
,
0
);
rtx
op1
=
XEXP
(
x
,
1
);
switch
(
GET_CODE
(
x
))
{
case
AND
:
case
AND
:
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
CONST_INT
)
/* Convert (A ^ B) & A to A & (~ B) since the latter is often a single
insn (and may simplify more). */
if
(
GET_CODE
(
op0
)
==
XOR
&&
rtx_equal_p
(
XEXP
(
op0
,
0
),
op1
)
&&
!
side_effects_p
(
op1
))
x
=
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
op0
,
1
)),
op1
);
if
(
GET_CODE
(
op0
)
==
XOR
&&
rtx_equal_p
(
XEXP
(
op0
,
1
),
op1
)
&&
!
side_effects_p
(
op1
))
x
=
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
op0
,
0
)),
op1
);
/* Similarly for (~ (A ^ B)) & A. */
if
(
GET_CODE
(
op0
)
==
NOT
&&
GET_CODE
(
XEXP
(
op0
,
0
))
==
XOR
&&
rtx_equal_p
(
XEXP
(
XEXP
(
op0
,
0
),
0
),
op1
)
&&
!
side_effects_p
(
op1
))
x
=
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
op0
,
0
),
1
),
op1
);
if
(
GET_CODE
(
op0
)
==
NOT
&&
GET_CODE
(
XEXP
(
op0
,
0
))
==
XOR
&&
rtx_equal_p
(
XEXP
(
XEXP
(
op0
,
0
),
1
),
op1
)
&&
!
side_effects_p
(
op1
))
x
=
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
op0
,
0
),
0
),
op1
);
if
(
GET_CODE
(
op1
)
==
CONST_INT
)
{
{
x
=
simplify_and_const_int
(
x
,
mode
,
XEXP
(
x
,
0
),
x
=
simplify_and_const_int
(
x
,
mode
,
op0
,
INTVAL
(
op1
));
INTVAL
(
XEXP
(
x
,
1
)));
/* If we have (ior (and (X C1) C2)) and the next restart would be
/* If we have (ior (and (X C1) C2)) and the next restart would be
the last, simplify this by making C1 as small as possible
the last, simplify this by making C1 as small as possible
and then exit. */
and then exit. */
if
(
n_restarts
>=
3
&&
GET_CODE
(
x
)
==
IOR
if
(
last
&&
GET_CODE
(
XEXP
(
x
,
0
))
==
AND
&&
GET_CODE
(
x
)
==
IOR
&&
GET_CODE
(
op0
)
==
AND
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
1
))
==
CONST_INT
&&
GET_CODE
(
XEXP
(
op0
,
1
))
==
CONST_INT
&&
GET_CODE
(
XEXP
(
x
,
1
))
==
CONST_INT
)
&&
GET_CODE
(
op1
)
==
CONST_INT
)
{
return
gen_binary
(
IOR
,
mode
,
temp
=
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
gen_binary
(
AND
,
mode
,
XEXP
(
op0
,
0
),
GEN_INT
(
INTVAL
(
XEXP
(
XEXP
(
x
,
0
),
1
))
GEN_INT
(
INTVAL
(
XEXP
(
op0
,
1
))
&
~
INTVAL
(
XEXP
(
x
,
1
))));
&
~
INTVAL
(
op1
))),
op1
);
return
gen_binary
(
IOR
,
mode
,
temp
,
XEXP
(
x
,
1
));
}
if
(
GET_CODE
(
x
)
!=
AND
)
if
(
GET_CODE
(
x
)
!=
AND
)
goto
restart
;
return
x
;
}
}
/* Convert (A | B) & A to A. */
/* Convert (A | B) & A to A. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
IOR
if
(
GET_CODE
(
op0
)
==
IOR
&&
(
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
))
&&
(
rtx_equal_p
(
XEXP
(
op0
,
0
),
op1
)
||
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
)))
||
rtx_equal_p
(
XEXP
(
op0
,
1
),
op1
))
&&
!
side_effects_p
(
XEXP
(
XEXP
(
x
,
0
),
0
))
&&
!
side_effects_p
(
XEXP
(
op0
,
0
))
&&
!
side_effects_p
(
XEXP
(
XEXP
(
x
,
0
),
1
)))
&&
!
side_effects_p
(
XEXP
(
op0
,
1
)))
return
XEXP
(
x
,
1
);
return
op1
;
/* Convert (A ^ B) & A to A & (~ B) since the latter is often a single
insn (and may simplify more). */
else
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
))
&&
!
side_effects_p
(
XEXP
(
x
,
1
)))
{
x
=
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
1
)),
XEXP
(
x
,
1
));
goto
restart
;
}
else
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
))
&&
!
side_effects_p
(
XEXP
(
x
,
1
)))
{
x
=
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
)),
XEXP
(
x
,
1
));
goto
restart
;
}
/* Similarly for (~ (A ^ B)) & A. */
else
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NOT
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
0
))
==
XOR
&&
rtx_equal_p
(
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
0
),
XEXP
(
x
,
1
))
&&
!
side_effects_p
(
XEXP
(
x
,
1
)))
{
x
=
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
1
),
XEXP
(
x
,
1
));
goto
restart
;
}
else
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NOT
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
0
))
==
XOR
&&
rtx_equal_p
(
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
1
),
XEXP
(
x
,
1
))
&&
!
side_effects_p
(
XEXP
(
x
,
1
)))
{
x
=
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
XEXP
(
x
,
0
),
0
),
0
),
XEXP
(
x
,
1
));
goto
restart
;
}
/* In the following group of tests (and those in case IOR below),
/* In the following group of tests (and those in case IOR below),
we start with some combination of logical operations and apply
we start with some combination of logical operations and apply
...
@@ -4489,129 +4500,97 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4489,129 +4500,97 @@ subst (x, from, to, in_dest, unique_copy)
For example, (and (ior A B) (not B)) can occur as the result of
For example, (and (ior A B) (not B)) can occur as the result of
expanding a bit field assignment. When we apply the distributive
expanding a bit field assignment. When we apply the distributive
law to this, we get (ior (and (A (not B))) (and (B (not B)))),
law to this, we get (ior (and (A (not B))) (and (B (not B)))),
which then simplifies to (and (A (not B))).
*/
which then simplifies to (and (A (not B))).
/*
If we have (and (ior A B) C), apply the distributive law and then
If we have (and (ior A B) C), apply the distributive law and then
the inverse distributive law to see if things simplify. */
the inverse distributive law to see if things simplify. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
IOR
||
GET_CODE
(
XEXP
(
x
,
0
)
)
==
XOR
)
if
(
GET_CODE
(
op0
)
==
IOR
||
GET_CODE
(
op0
)
==
XOR
)
{
{
x
=
apply_distributive_law
x
=
apply_distributive_law
(
gen_binary
(
GET_CODE
(
XEXP
(
x
,
0
)),
mode
,
(
gen_binary
(
GET_CODE
(
op0
),
mode
,
gen_binary
(
AND
,
mode
,
gen_binary
(
AND
,
mode
,
XEXP
(
op0
,
0
),
op1
),
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
)),
gen_binary
(
AND
,
mode
,
XEXP
(
op0
,
1
),
op1
)));
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
))));
if
(
GET_CODE
(
x
)
!=
AND
)
if
(
GET_CODE
(
x
)
!=
AND
)
goto
restart
;
return
x
;
}
}
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
IOR
||
GET_CODE
(
XEXP
(
x
,
1
))
==
XOR
)
if
(
GET_CODE
(
op1
)
==
IOR
||
GET_CODE
(
op1
)
==
XOR
)
{
return
apply_distributive_law
x
=
apply_distributive_law
(
gen_binary
(
GET_CODE
(
op1
),
mode
,
(
gen_binary
(
GET_CODE
(
XEXP
(
x
,
1
)),
mode
,
gen_binary
(
AND
,
mode
,
XEXP
(
op1
,
0
),
op0
),
gen_binary
(
AND
,
mode
,
gen_binary
(
AND
,
mode
,
XEXP
(
op1
,
1
),
op0
)));
XEXP
(
XEXP
(
x
,
1
),
0
),
XEXP
(
x
,
0
)),
gen_binary
(
AND
,
mode
,
XEXP
(
XEXP
(
x
,
1
),
1
),
XEXP
(
x
,
0
))));
if
(
GET_CODE
(
x
)
!=
AND
)
goto
restart
;
}
/* Similarly, taking advantage of the fact that
/* Similarly, taking advantage of the fact that
(and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */
(and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NOT
&&
GET_CODE
(
XEXP
(
x
,
1
))
==
XOR
)
if
(
GET_CODE
(
op0
)
==
NOT
&&
GET_CODE
(
op1
)
==
XOR
)
{
return
apply_distributive_law
x
=
apply_distributive_law
(
gen_binary
(
XOR
,
mode
,
(
gen_binary
(
XOR
,
mode
,
gen_binary
(
IOR
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
gen_binary
(
IOR
,
mode
,
XEXP
(
op0
,
0
),
XEXP
(
op1
,
0
)),
XEXP
(
XEXP
(
x
,
1
),
0
)),
gen_binary
(
IOR
,
mode
,
XEXP
(
op0
,
0
),
XEXP
(
op1
,
1
))));
gen_binary
(
IOR
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
XEXP
(
x
,
1
),
1
))));
if
(
GET_CODE
(
x
)
!=
AND
)
goto
restart
;
}
else
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
NOT
&&
GET_CODE
(
XEXP
(
x
,
0
))
==
XOR
)
else
if
(
GET_CODE
(
op1
)
==
NOT
&&
GET_CODE
(
op0
)
==
XOR
)
{
return
apply_distributive_law
x
=
apply_distributive_law
(
gen_binary
(
XOR
,
mode
,
(
gen_binary
(
XOR
,
mode
,
gen_binary
(
IOR
,
mode
,
XEXP
(
XEXP
(
x
,
1
),
0
),
gen_binary
(
IOR
,
mode
,
XEXP
(
op1
,
0
),
XEXP
(
op0
,
0
)),
XEXP
(
XEXP
(
x
,
0
),
0
)),
gen_binary
(
IOR
,
mode
,
XEXP
(
op1
,
0
),
XEXP
(
op0
,
1
))));
gen_binary
(
IOR
,
mode
,
XEXP
(
XEXP
(
x
,
1
),
0
),
XEXP
(
XEXP
(
x
,
0
),
1
))));
if
(
GET_CODE
(
x
)
!=
AND
)
goto
restart
;
}
break
;
break
;
case
IOR
:
case
IOR
:
/* (ior A C) is C if all bits of A that might be nonzero are on in C. */
/* (ior A C) is C if all bits of A that might be nonzero are on in C. */
if
(
GET_CODE
(
XEXP
(
x
,
1
)
)
==
CONST_INT
if
(
GET_CODE
(
op1
)
==
CONST_INT
&&
GET_MODE_BITSIZE
(
mode
)
<=
HOST_BITS_PER_WIDE_INT
&&
GET_MODE_BITSIZE
(
mode
)
<=
HOST_BITS_PER_WIDE_INT
&&
(
nonzero_bits
(
XEXP
(
x
,
0
),
mode
)
&
~
INTVAL
(
XEXP
(
x
,
1
)
))
==
0
)
&&
(
nonzero_bits
(
op0
,
mode
)
&
~
INTVAL
(
op1
))
==
0
)
return
XEXP
(
x
,
1
)
;
return
op1
;
/* Convert (A & B) | A to A. */
/* Convert (A & B) | A to A. */
if
(
GET_CODE
(
XEXP
(
x
,
0
)
)
==
AND
if
(
GET_CODE
(
op0
)
==
AND
&&
(
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
)
)
&&
(
rtx_equal_p
(
XEXP
(
op0
,
0
),
op1
)
||
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
)
))
||
rtx_equal_p
(
XEXP
(
op0
,
1
),
op1
))
&&
!
side_effects_p
(
XEXP
(
XEXP
(
x
,
0
)
,
0
))
&&
!
side_effects_p
(
XEXP
(
op0
,
0
))
&&
!
side_effects_p
(
XEXP
(
XEXP
(
x
,
0
)
,
1
)))
&&
!
side_effects_p
(
XEXP
(
op0
,
1
)))
return
XEXP
(
x
,
1
)
;
return
op1
;
/* If we have (ior (and A B) C), apply the distributive law and then
/* If we have (ior (and A B) C), apply the distributive law and then
the inverse distributive law to see if things simplify. */
the inverse distributive law to see if things simplify. */
if
(
GET_CODE
(
XEXP
(
x
,
0
)
)
==
AND
)
if
(
GET_CODE
(
op0
)
==
AND
)
{
{
x
=
apply_distributive_law
x
=
apply_distributive_law
(
gen_binary
(
AND
,
mode
,
(
gen_binary
(
AND
,
mode
,
gen_binary
(
IOR
,
mode
,
gen_binary
(
IOR
,
mode
,
XEXP
(
op0
,
0
),
op1
),
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
)),
gen_binary
(
IOR
,
mode
,
XEXP
(
op0
,
1
),
op1
)));
gen_binary
(
IOR
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
))));
if
(
GET_CODE
(
x
)
!=
IOR
)
if
(
GET_CODE
(
x
)
!=
IOR
)
goto
restart
;
return
x
;
}
}
if
(
GET_CODE
(
XEXP
(
x
,
1
)
)
==
AND
)
if
(
GET_CODE
(
op1
)
==
AND
)
{
{
x
=
apply_distributive_law
x
=
apply_distributive_law
(
gen_binary
(
AND
,
mode
,
(
gen_binary
(
AND
,
mode
,
gen_binary
(
IOR
,
mode
,
gen_binary
(
IOR
,
mode
,
XEXP
(
op1
,
0
),
op0
),
XEXP
(
XEXP
(
x
,
1
),
0
),
XEXP
(
x
,
0
)),
gen_binary
(
IOR
,
mode
,
XEXP
(
op1
,
1
),
op0
)));
gen_binary
(
IOR
,
mode
,
XEXP
(
XEXP
(
x
,
1
),
1
),
XEXP
(
x
,
0
))));
if
(
GET_CODE
(
x
)
!=
IOR
)
if
(
GET_CODE
(
x
)
!=
IOR
)
goto
restart
;
return
x
;
}
}
/* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
/* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
mode size to (rotate A CX). */
mode size to (rotate A CX). */
if
(((
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFT
if
(((
GET_CODE
(
op0
)
==
ASHIFT
&&
GET_CODE
(
op1
)
==
LSHIFTRT
)
&&
GET_CODE
(
XEXP
(
x
,
1
))
==
LSHIFTRT
)
||
(
GET_CODE
(
op1
)
==
ASHIFT
&&
GET_CODE
(
op0
)
==
LSHIFTRT
))
||
(
GET_CODE
(
XEXP
(
x
,
1
))
==
ASHIFT
&&
rtx_equal_p
(
XEXP
(
op0
,
0
),
XEXP
(
op1
,
0
))
&&
GET_CODE
(
XEXP
(
x
,
0
))
==
LSHIFTRT
))
&&
GET_CODE
(
XEXP
(
op0
,
1
))
==
CONST_INT
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
XEXP
(
x
,
1
),
0
))
&&
GET_CODE
(
XEXP
(
op1
,
1
))
==
CONST_INT
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
),
1
))
==
CONST_INT
&&
(
INTVAL
(
XEXP
(
op0
,
1
))
+
INTVAL
(
XEXP
(
op1
,
1
))
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
1
),
1
))
==
CONST_INT
&&
(
INTVAL
(
XEXP
(
XEXP
(
x
,
0
),
1
))
+
INTVAL
(
XEXP
(
XEXP
(
x
,
1
),
1
))
==
GET_MODE_BITSIZE
(
mode
)))
==
GET_MODE_BITSIZE
(
mode
)))
{
return
gen_rtx
(
ROTATE
,
mode
,
XEXP
(
op0
,
0
),
rtx
shift_count
;
(
GET_CODE
(
op0
)
==
ASHIFT
?
XEXP
(
op0
,
1
)
:
XEXP
(
op1
,
1
)));
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
ASHIFT
)
shift_count
=
XEXP
(
XEXP
(
x
,
0
),
1
);
else
shift_count
=
XEXP
(
XEXP
(
x
,
1
),
1
);
x
=
gen_rtx
(
ROTATE
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
shift_count
);
goto
restart
;
}
break
;
break
;
case
XOR
:
case
XOR
:
...
@@ -4620,69 +4599,55 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4620,69 +4599,55 @@ subst (x, from, to, in_dest, unique_copy)
(NOT y). */
(NOT y). */
{
{
int
num_negated
=
0
;
int
num_negated
=
0
;
rtx
in1
=
XEXP
(
x
,
0
),
in2
=
XEXP
(
x
,
1
);
if
(
GET_CODE
(
in1
)
==
NOT
)
if
(
GET_CODE
(
op0
)
==
NOT
)
num_negated
++
,
in1
=
XEXP
(
in1
,
0
);
num_negated
++
,
op0
=
XEXP
(
op0
,
0
);
if
(
GET_CODE
(
in2
)
==
NOT
)
if
(
GET_CODE
(
op1
)
==
NOT
)
num_negated
++
,
in2
=
XEXP
(
in2
,
0
);
num_negated
++
,
op1
=
XEXP
(
op1
,
0
);
if
(
num_negated
==
2
)
if
(
num_negated
==
2
)
{
{
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
)
);
SUBST
(
XEXP
(
x
,
0
),
op0
);
SUBST
(
XEXP
(
x
,
1
),
XEXP
(
XEXP
(
x
,
1
),
0
)
);
SUBST
(
XEXP
(
x
,
1
),
op1
);
}
}
else
if
(
num_negated
==
1
)
else
if
(
num_negated
==
1
)
{
return
gen_unary
(
NOT
,
mode
,
gen_binary
(
XOR
,
mode
,
op0
,
op1
));
x
=
gen_unary
(
NOT
,
mode
,
gen_binary
(
XOR
,
mode
,
in1
,
in2
));
goto
restart
;
}
}
}
/* Convert (xor (and A B) B) to (and (not A) B). The latter may
/* Convert (xor (and A B) B) to (and (not A) B). The latter may
correspond to a machine insn or result in further simplifications
correspond to a machine insn or result in further simplifications
if B is a constant. */
if B is a constant. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
AND
if
(
GET_CODE
(
op0
)
==
AND
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
1
),
XEXP
(
x
,
1
))
&&
rtx_equal_p
(
XEXP
(
op0
,
1
),
op1
)
&&
!
side_effects_p
(
XEXP
(
x
,
1
)))
&&
!
side_effects_p
(
op1
))
{
return
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
op0
,
0
)),
x
=
gen_binary
(
AND
,
mode
,
op1
);
gen_unary
(
NOT
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
)),
XEXP
(
x
,
1
));
goto
restart
;
}
else
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
AND
&&
rtx_equal_p
(
XEXP
(
XEXP
(
x
,
0
),
0
),
XEXP
(
x
,
1
))
&&
!
side_effects_p
(
XEXP
(
x
,
1
)))
{
x
=
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
XEXP
(
x
,
0
),
1
)),
XEXP
(
x
,
1
));
goto
restart
;
}
else
if
(
GET_CODE
(
op0
)
==
AND
&&
rtx_equal_p
(
XEXP
(
op0
,
0
),
op1
)
&&
!
side_effects_p
(
op1
))
return
gen_binary
(
AND
,
mode
,
gen_unary
(
NOT
,
mode
,
XEXP
(
op0
,
1
)),
op1
);
#if STORE_FLAG_VALUE == 1
#if STORE_FLAG_VALUE == 1
/* (xor (comparison foo bar) (const_int 1)) can become the reversed
/* (xor (comparison foo bar) (const_int 1)) can become the reversed
comparison. */
comparison. */
if
(
XEXP
(
x
,
1
)
==
const1_rtx
if
(
op1
==
const1_rtx
&&
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
&&
GET_RTX_CLASS
(
GET_CODE
(
op0
))
==
'<'
&&
reversible_comparison_p
(
XEXP
(
x
,
0
)))
&&
reversible_comparison_p
(
op0
))
return
gen_rtx_combine
(
reverse_condition
(
GET_CODE
(
XEXP
(
x
,
0
))),
return
gen_rtx_combine
(
reverse_condition
(
GET_CODE
(
op0
)),
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
mode
,
XEXP
(
op0
,
0
),
XEXP
(
op0
,
1
));
XEXP
(
XEXP
(
x
,
0
),
1
));
/* (lshiftrt foo C) where C is the number of bits in FOO minus 1
/* (lshiftrt foo C) where C is the number of bits in FOO minus 1
is (lt foo (const_int 0)), so we can perform the above
is (lt foo (const_int 0)), so we can perform the above
simplification. */
simplification. */
if
(
XEXP
(
x
,
1
)
==
const1_rtx
if
(
op1
==
const1_rtx
&&
GET_CODE
(
XEXP
(
x
,
0
)
)
==
LSHIFTRT
&&
GET_CODE
(
op0
)
==
LSHIFTRT
&&
GET_CODE
(
XEXP
(
XEXP
(
x
,
0
)
,
1
))
==
CONST_INT
&&
GET_CODE
(
XEXP
(
op0
,
1
))
==
CONST_INT
&&
INTVAL
(
XEXP
(
XEXP
(
x
,
0
)
,
1
))
==
GET_MODE_BITSIZE
(
mode
)
-
1
)
&&
INTVAL
(
XEXP
(
op0
,
1
))
==
GET_MODE_BITSIZE
(
mode
)
-
1
)
return
gen_rtx_combine
(
GE
,
mode
,
XEXP
(
XEXP
(
x
,
0
)
,
0
),
const0_rtx
);
return
gen_rtx_combine
(
GE
,
mode
,
XEXP
(
op0
,
0
),
const0_rtx
);
#endif
#endif
/* (xor (comparison foo bar) (const_int sign-bit))
/* (xor (comparison foo bar) (const_int sign-bit))
...
@@ -4690,76 +4655,11 @@ subst (x, from, to, in_dest, unique_copy)
...
@@ -4690,76 +4655,11 @@ subst (x, from, to, in_dest, unique_copy)
if
(
GET_MODE_BITSIZE
(
mode
)
<=
HOST_BITS_PER_WIDE_INT
if
(
GET_MODE_BITSIZE
(
mode
)
<=
HOST_BITS_PER_WIDE_INT
&&
(
STORE_FLAG_VALUE
&&
(
STORE_FLAG_VALUE
==
(
HOST_WIDE_INT
)
1
<<
(
GET_MODE_BITSIZE
(
mode
)
-
1
))
==
(
HOST_WIDE_INT
)
1
<<
(
GET_MODE_BITSIZE
(
mode
)
-
1
))
&&
XEXP
(
x
,
1
)
==
const_true_rtx
&&
op1
==
const_true_rtx
&&
GET_RTX_CLASS
(
GET_CODE
(
XEXP
(
x
,
0
)))
==
'<'
&&
GET_RTX_CLASS
(
GET_CODE
(
op0
))
==
'<'
&&
reversible_comparison_p
(
XEXP
(
x
,
0
)))
&&
reversible_comparison_p
(
op0
))
return
gen_rtx_combine
(
reverse_condition
(
GET_CODE
(
XEXP
(
x
,
0
))),
return
gen_rtx_combine
(
reverse_condition
(
GET_CODE
(
op0
)),
mode
,
XEXP
(
XEXP
(
x
,
0
),
0
),
mode
,
XEXP
(
op0
,
0
),
XEXP
(
op0
,
1
));
XEXP
(
XEXP
(
x
,
0
),
1
));
break
;
case
ABS
:
/* (abs (neg <foo>)) -> (abs <foo>) */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
NEG
)
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
));
/* If operand is something known to be positive, ignore the ABS. */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
FFS
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ABS
||
((
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
x
,
0
)))
<=
HOST_BITS_PER_WIDE_INT
)
&&
((
nonzero_bits
(
XEXP
(
x
,
0
),
GET_MODE
(
XEXP
(
x
,
0
)))
&
((
HOST_WIDE_INT
)
1
<<
(
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
x
,
0
)))
-
1
)))
==
0
)))
return
XEXP
(
x
,
0
);
/* If operand is known to be only -1 or 0, convert ABS to NEG. */
if
(
num_sign_bit_copies
(
XEXP
(
x
,
0
),
mode
)
==
GET_MODE_BITSIZE
(
mode
))
{
x
=
gen_rtx_combine
(
NEG
,
mode
,
XEXP
(
x
,
0
));
goto
restart
;
}
break
;
case
FFS
:
/* (ffs (*_extend <X>)) = (ffs <X>) */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SIGN_EXTEND
||
GET_CODE
(
XEXP
(
x
,
0
))
==
ZERO_EXTEND
)
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
));
break
;
case
FLOAT
:
/* (float (sign_extend <X>)) = (float <X>). */
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
SIGN_EXTEND
)
SUBST
(
XEXP
(
x
,
0
),
XEXP
(
XEXP
(
x
,
0
),
0
));
break
;
case
LSHIFT
:
case
ASHIFT
:
case
LSHIFTRT
:
case
ASHIFTRT
:
case
ROTATE
:
case
ROTATERT
:
/* If this is a shift by a constant amount, simplify it. */
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
CONST_INT
)
{
x
=
simplify_shift_const
(
x
,
code
,
mode
,
XEXP
(
x
,
0
),
INTVAL
(
XEXP
(
x
,
1
)));
if
(
GET_CODE
(
x
)
!=
code
)
goto
restart
;
}
#ifdef SHIFT_COUNT_TRUNCATED
else
if
(
SHIFT_COUNT_TRUNCATED
&&
GET_CODE
(
XEXP
(
x
,
1
))
!=
REG
)
SUBST
(
XEXP
(
x
,
1
),
force_to_mode
(
XEXP
(
x
,
1
),
GET_MODE
(
x
),
((
HOST_WIDE_INT
)
1
<<
exact_log2
(
GET_MODE_BITSIZE
(
GET_MODE
(
x
))))
-
1
,
NULL_RTX
,
0
));
#endif
break
;
break
;
}
}
...
@@ -4804,7 +4704,16 @@ expand_compound_operation (x)
...
@@ -4804,7 +4704,16 @@ expand_compound_operation (x)
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
CONST_INT
)
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
CONST_INT
)
return
x
;
return
x
;
if
(
!
FAKE_EXTEND_SAFE_P
(
GET_MODE
(
XEXP
(
x
,
0
)),
XEXP
(
x
,
0
)))
/* Return if (subreg:MODE FROM 0) is not a safe replacement for
(zero_extend:MODE FROM) or (sign_extend:MODE FROM). It is for any MEM
because (SUBREG (MEM...)) is guaranteed to cause the MEM to be
reloaded. If not for that, MEM's would very rarely be safe.
Reject MODEs bigger than a word, because we might not be able
to reference a two-register group starting with an arbitrary register
(and currently gen_lowpart might crash for a SUBREG). */
if
(
GET_MODE_SIZE
(
GET_MODE
(
XEXP
(
x
,
0
)))
>
UNITS_PER_WORD
)
return
x
;
return
x
;
len
=
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
x
,
0
)));
len
=
GET_MODE_BITSIZE
(
GET_MODE
(
XEXP
(
x
,
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