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
7339c88d
Commit
7339c88d
authored
May 04, 1992
by
Richard Stallman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r888
parent
8241a41f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
306 additions
and
144 deletions
+306
-144
gcc/genattrtab.c
+306
-144
No files found.
gcc/genattrtab.c
View file @
7339c88d
...
@@ -90,8 +90,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -90,8 +90,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
#include "obstack.h"
#include "insn-config.h"
/* For REGISTER_CONSTRAINTS */
#include "insn-config.h"
/* For REGISTER_CONSTRAINTS */
static
struct
obstack
obstack
;
static
struct
obstack
obstack
,
obstack1
;
struct
obstack
*
rtl_obstack
=
&
obstack
;
struct
obstack
*
rtl_obstack
=
&
obstack
;
struct
obstack
*
hash_obstack
=
&
obstack1
;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#define obstack_chunk_free free
...
@@ -256,6 +257,7 @@ static void check_defs ();
...
@@ -256,6 +257,7 @@ static void check_defs ();
static
rtx
convert_const_symbol_ref
();
static
rtx
convert_const_symbol_ref
();
static
rtx
make_canonical
();
static
rtx
make_canonical
();
static
struct
attr_value
*
get_attr_value
();
static
struct
attr_value
*
get_attr_value
();
static
rtx
copy_rtx_unchanging
();
static
void
expand_delays
();
static
void
expand_delays
();
static
rtx
operate_exp
();
static
rtx
operate_exp
();
static
void
expand_units
();
static
void
expand_units
();
...
@@ -348,7 +350,8 @@ attr_hash_add_rtx (hashcode, rtl)
...
@@ -348,7 +350,8 @@ attr_hash_add_rtx (hashcode, rtl)
{
{
register
struct
attr_hash
*
h
;
register
struct
attr_hash
*
h
;
h
=
(
struct
attr_hash
*
)
xmalloc
(
sizeof
(
struct
attr_hash
));
h
=
(
struct
attr_hash
*
)
obstack_alloc
(
hash_obstack
,
sizeof
(
struct
attr_hash
));
h
->
hashcode
=
hashcode
;
h
->
hashcode
=
hashcode
;
h
->
u
.
rtl
=
rtl
;
h
->
u
.
rtl
=
rtl
;
h
->
next
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
->
next
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
...
@@ -364,7 +367,8 @@ attr_hash_add_string (hashcode, str)
...
@@ -364,7 +367,8 @@ attr_hash_add_string (hashcode, str)
{
{
register
struct
attr_hash
*
h
;
register
struct
attr_hash
*
h
;
h
=
(
struct
attr_hash
*
)
xmalloc
(
sizeof
(
struct
attr_hash
));
h
=
(
struct
attr_hash
*
)
obstack_alloc
(
hash_obstack
,
sizeof
(
struct
attr_hash
));
h
->
hashcode
=
-
hashcode
;
h
->
hashcode
=
-
hashcode
;
h
->
u
.
str
=
str
;
h
->
u
.
str
=
str
;
h
->
next
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
->
next
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
...
@@ -388,6 +392,7 @@ attr_rtx (va_alist)
...
@@ -388,6 +392,7 @@ attr_rtx (va_alist)
register
rtx
rt_val
;
/* RTX to return to caller... */
register
rtx
rt_val
;
/* RTX to return to caller... */
int
hashcode
;
int
hashcode
;
register
struct
attr_hash
*
h
;
register
struct
attr_hash
*
h
;
struct
obstack
*
old_obstack
=
rtl_obstack
;
va_start
(
p
);
va_start
(
p
);
code
=
va_arg
(
p
,
enum
rtx_code
);
code
=
va_arg
(
p
,
enum
rtx_code
);
...
@@ -409,6 +414,7 @@ attr_rtx (va_alist)
...
@@ -409,6 +414,7 @@ attr_rtx (va_alist)
if
(
h
==
0
)
if
(
h
==
0
)
{
{
rtl_obstack
=
hash_obstack
;
rt_val
=
rtx_alloc
(
code
);
rt_val
=
rtx_alloc
(
code
);
XEXP
(
rt_val
,
0
)
=
arg0
;
XEXP
(
rt_val
,
0
)
=
arg0
;
}
}
...
@@ -430,6 +436,7 @@ attr_rtx (va_alist)
...
@@ -430,6 +436,7 @@ attr_rtx (va_alist)
if
(
h
==
0
)
if
(
h
==
0
)
{
{
rtl_obstack
=
hash_obstack
;
rt_val
=
rtx_alloc
(
code
);
rt_val
=
rtx_alloc
(
code
);
XEXP
(
rt_val
,
0
)
=
arg0
;
XEXP
(
rt_val
,
0
)
=
arg0
;
XEXP
(
rt_val
,
1
)
=
arg1
;
XEXP
(
rt_val
,
1
)
=
arg1
;
...
@@ -449,6 +456,7 @@ attr_rtx (va_alist)
...
@@ -449,6 +456,7 @@ attr_rtx (va_alist)
if
(
h
==
0
)
if
(
h
==
0
)
{
{
rtl_obstack
=
hash_obstack
;
rt_val
=
rtx_alloc
(
code
);
rt_val
=
rtx_alloc
(
code
);
XSTR
(
rt_val
,
0
)
=
arg0
;
XSTR
(
rt_val
,
0
)
=
arg0
;
}
}
...
@@ -470,6 +478,7 @@ attr_rtx (va_alist)
...
@@ -470,6 +478,7 @@ attr_rtx (va_alist)
if
(
h
==
0
)
if
(
h
==
0
)
{
{
rtl_obstack
=
hash_obstack
;
rt_val
=
rtx_alloc
(
code
);
rt_val
=
rtx_alloc
(
code
);
XSTR
(
rt_val
,
0
)
=
arg0
;
XSTR
(
rt_val
,
0
)
=
arg0
;
XSTR
(
rt_val
,
1
)
=
arg1
;
XSTR
(
rt_val
,
1
)
=
arg1
;
...
@@ -512,6 +521,7 @@ attr_rtx (va_alist)
...
@@ -512,6 +521,7 @@ attr_rtx (va_alist)
return
rt_val
;
return
rt_val
;
}
}
rtl_obstack
=
old_obstack
;
va_end
(
p
);
va_end
(
p
);
attr_hash_add_rtx
(
hashcode
,
rt_val
);
attr_hash_add_rtx
(
hashcode
,
rt_val
);
return
rt_val
;
return
rt_val
;
...
@@ -649,7 +659,7 @@ check_attr_test (exp, is_const)
...
@@ -649,7 +659,7 @@ check_attr_test (exp, is_const)
RTX_UNCHANGING_P
(
exp
)
=
1
;
RTX_UNCHANGING_P
(
exp
)
=
1
;
return
exp
;
return
exp
;
}
}
else
else
fatal
(
"Unknown attribute `%s' in EQ_ATTR"
,
XEXP
(
exp
,
0
));
fatal
(
"Unknown attribute `%s' in EQ_ATTR"
,
XEXP
(
exp
,
0
));
}
}
...
@@ -1053,16 +1063,26 @@ make_canonical (attr, exp)
...
@@ -1053,16 +1063,26 @@ make_canonical (attr, exp)
case
COND
:
case
COND
:
cond
:
cond
:
/* First, check for degenerate COND. */
{
if
(
XVECLEN
(
exp
,
0
)
==
0
)
int
allsame
=
1
;
r
eturn
make_canonical
(
attr
,
XEXP
(
exp
,
1
))
;
r
tx
defval
;
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
/* First, check for degenerate COND. */
XVECEXP
(
exp
,
0
,
i
+
1
)
if
(
XVECLEN
(
exp
,
0
)
==
0
)
=
make_canonical
(
attr
,
XVECEXP
(
exp
,
0
,
i
+
1
));
return
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
defval
=
XEXP
(
exp
,
1
)
=
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
XEXP
(
exp
,
1
)
=
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
break
;
{
XVECEXP
(
exp
,
0
,
i
+
1
)
=
make_canonical
(
attr
,
XVECEXP
(
exp
,
0
,
i
+
1
));
if
(
!
rtx_equal_p
(
XVECEXP
(
exp
,
0
,
i
+
1
),
defval
))
allsame
=
0
;
}
if
(
allsame
)
return
defval
;
break
;
}
}
}
return
exp
;
return
exp
;
...
@@ -1261,22 +1281,46 @@ operate_exp (op, left, right)
...
@@ -1261,22 +1281,46 @@ operate_exp (op, left, right)
else
if
(
GET_CODE
(
right
)
==
IF_THEN_ELSE
)
else
if
(
GET_CODE
(
right
)
==
IF_THEN_ELSE
)
{
{
/* Apply recursively to all values within. */
/* Apply recursively to all values within. */
return
attr_rtx
(
IF_THEN_ELSE
,
XEXP
(
right
,
0
),
rtx
newleft
=
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
));
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
)),
rtx
newright
=
operate_exp
(
op
,
left
,
XEXP
(
right
,
2
));
operate_exp
(
op
,
left
,
XEXP
(
right
,
2
)));
if
(
rtx_equal_p
(
newleft
,
newright
))
return
newleft
;
return
attr_rtx
(
IF_THEN_ELSE
,
XEXP
(
right
,
0
),
newleft
,
newright
);
}
}
else
if
(
GET_CODE
(
right
)
==
COND
)
else
if
(
GET_CODE
(
right
)
==
COND
)
{
{
int
allsame
=
1
;
rtx
defval
;
newexp
=
rtx_alloc
(
COND
);
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
right
,
0
));
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
right
,
0
));
defval
=
XEXP
(
newexp
,
1
)
=
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
));
for
(
i
=
0
;
i
<
XVECLEN
(
right
,
0
);
i
+=
2
)
for
(
i
=
0
;
i
<
XVECLEN
(
right
,
0
);
i
+=
2
)
{
{
XVECEXP
(
newexp
,
0
,
i
)
=
XVECEXP
(
right
,
0
,
i
);
XVECEXP
(
newexp
,
0
,
i
)
=
XVECEXP
(
right
,
0
,
i
);
XVECEXP
(
newexp
,
0
,
i
+
1
)
XVECEXP
(
newexp
,
0
,
i
+
1
)
=
operate_exp
(
op
,
left
,
XVECEXP
(
right
,
0
,
i
+
1
));
=
operate_exp
(
op
,
left
,
XVECEXP
(
right
,
0
,
i
+
1
));
if
(
!
rtx_equal_p
(
XVECEXP
(
newexp
,
0
,
i
+
1
),
defval
))
allsame
=
0
;
}
}
XEXP
(
newexp
,
1
)
=
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
));
/* If the resulting cond is trivial (all alternatives
give the same value), optimize it away. */
if
(
allsame
)
{
obstack_free
(
rtl_obstack
,
newexp
);
return
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
));
}
/* If the result is the same as the RIGHT operand,
just use that. */
if
(
rtx_equal_p
(
newexp
,
right
))
{
obstack_free
(
rtl_obstack
,
newexp
);
return
right
;
}
return
newexp
;
return
newexp
;
}
}
...
@@ -1287,23 +1331,46 @@ operate_exp (op, left, right)
...
@@ -1287,23 +1331,46 @@ operate_exp (op, left, right)
/* Otherwise, do recursion the other way. */
/* Otherwise, do recursion the other way. */
else
if
(
GET_CODE
(
left
)
==
IF_THEN_ELSE
)
else
if
(
GET_CODE
(
left
)
==
IF_THEN_ELSE
)
{
{
return
attr_rtx
(
IF_THEN_ELSE
,
XEXP
(
left
,
0
),
rtx
newleft
=
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
);
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
),
rtx
newright
=
operate_exp
(
op
,
XEXP
(
left
,
2
),
right
);
operate_exp
(
op
,
XEXP
(
left
,
2
),
right
));
if
(
rtx_equal_p
(
newleft
,
newright
))
return
newleft
;
return
attr_rtx
(
IF_THEN_ELSE
,
XEXP
(
left
,
0
),
newleft
,
newright
);
}
}
else
if
(
GET_CODE
(
left
)
==
COND
)
else
if
(
GET_CODE
(
left
)
==
COND
)
{
{
int
allsame
=
1
;
rtx
defval
;
newexp
=
rtx_alloc
(
COND
);
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
left
,
0
));
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
left
,
0
));
defval
=
XEXP
(
newexp
,
1
)
=
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
);
for
(
i
=
0
;
i
<
XVECLEN
(
left
,
0
);
i
+=
2
)
for
(
i
=
0
;
i
<
XVECLEN
(
left
,
0
);
i
+=
2
)
{
{
XVECEXP
(
newexp
,
0
,
i
)
=
XVECEXP
(
left
,
0
,
i
);
XVECEXP
(
newexp
,
0
,
i
)
=
XVECEXP
(
left
,
0
,
i
);
XVECEXP
(
newexp
,
0
,
i
+
1
)
XVECEXP
(
newexp
,
0
,
i
+
1
)
=
operate_exp
(
op
,
XVECEXP
(
left
,
0
,
i
+
1
),
right
);
=
operate_exp
(
op
,
XVECEXP
(
left
,
0
,
i
+
1
),
right
);
if
(
!
rtx_equal_p
(
XVECEXP
(
newexp
,
0
,
i
+
1
),
defval
))
allsame
=
0
;
}
}
XEXP
(
newexp
,
1
)
=
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
);
/* If the cond is trivial (all alternatives give the same value),
optimize it away. */
if
(
allsame
)
{
obstack_free
(
rtl_obstack
,
newexp
);
return
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
);
}
/* If the result is the same as the LEFT operand,
just use that. */
if
(
rtx_equal_p
(
newexp
,
left
))
{
obstack_free
(
rtl_obstack
,
newexp
);
return
left
;
}
return
newexp
;
return
newexp
;
}
}
...
@@ -1618,8 +1685,7 @@ max_fn (exp)
...
@@ -1618,8 +1685,7 @@ max_fn (exp)
Also call ourselves on any COND operations that are values of this COND.
Also call ourselves on any COND operations that are values of this COND.
We only do the first replacement found directly and call ourselves
We do not modify EXP; rather, we make and return a new rtx. */
recursively for subsequent replacements. */
static
rtx
static
rtx
simplify_cond
(
exp
,
insn_code
,
insn_index
)
simplify_cond
(
exp
,
insn_code
,
insn_index
)
...
@@ -1627,129 +1693,128 @@ simplify_cond (exp, insn_code, insn_index)
...
@@ -1627,129 +1693,128 @@ simplify_cond (exp, insn_code, insn_index)
int
insn_code
,
insn_index
;
int
insn_code
,
insn_index
;
{
{
int
i
,
j
;
int
i
,
j
;
rtx
newtest
;
/* We store the desired contents here,
rtx
value
;
then build a new expression if they don't match EXP. */
rtx
newexp
=
exp
;
rtx
defval
=
XEXP
(
exp
,
1
);
int
len
=
XVECLEN
(
exp
,
0
);
rtx
*
tests
=
(
rtx
*
)
alloca
(
len
*
sizeof
(
rtx
));
int
allsame
=
1
;
char
*
spacer
,
*
first_spacer
;
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
/* This lets us free all storage allocated below, if appropriate. */
{
first_spacer
=
(
char
*
)
obstack_next_free
(
rtl_obstack
);
newtest
=
SIMPLIFY_TEST_EXP
(
XVECEXP
(
exp
,
0
,
i
),
insn_code
,
insn_index
);
if
(
newtest
==
true_rtx
)
{
/* Make a new COND with any previous conditions and the value for
this pair as the default value. */
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
i
);
for
(
j
=
0
;
j
<
i
;
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XEXP
(
newexp
,
1
)
=
XVECEXP
(
exp
,
0
,
i
+
1
);
bcopy
(
&
XVECEXP
(
exp
,
0
,
0
),
tests
,
len
*
sizeof
(
rtx
));
break
;
}
else
if
(
newtest
==
false_rtx
)
/* See if default value needs simplification. */
{
if
(
GET_CODE
(
defval
)
==
COND
)
/* Build a new COND without this test. */
defval
=
simplify_cond
(
defval
,
insn_code
,
insn_index
);
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
)
-
2
);
for
(
j
=
0
;
j
<
i
;
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
for
(
j
=
i
;
j
<
XVECLEN
(
newexp
,
0
);
j
++
)
/* Simplify now, just to see what tests we can get rid of. */
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
+
2
);
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
/* Work from back to front, so if all values match the default,
break
;
we get rid of all of them. */
}
for
(
i
=
len
-
2
;
i
>=
0
;
i
-=
2
)
{
rtx
newtest
,
newval
;
else
if
(
newtest
!=
XVECEXP
(
exp
,
0
,
i
))
/* Simplify this test. */
{
newtest
=
SIMPLIFY_TEST_EXP
(
tests
[
i
],
insn_code
,
insn_index
);
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
));
for
(
j
=
0
;
j
<
XVECLEN
(
exp
,
0
);
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
XVECEXP
(
newexp
,
0
,
i
)
=
newtest
;
newval
=
tests
[
i
+
1
];
break
;
/* See if this value may need simplification. */
if
(
GET_CODE
(
newval
)
==
COND
)
newval
=
simplify_cond
(
newval
,
insn_code
,
insn_index
);
/* Look for ways to delete or combine this test. */
if
(
newtest
==
true_rtx
)
{
/* If test is true, make this value the default
and discard this + any following tests. */
len
=
i
;
defval
=
tests
[
i
];
}
}
/* See if this value may need simplification. */
else
if
(
newtest
==
false_rtx
)
if
(
GET_CODE
(
XVECEXP
(
exp
,
0
,
i
+
1
))
==
COND
)
{
{
value
=
simplify_cond
(
XVECEXP
(
exp
,
0
,
i
+
1
),
/* If test is false, discard it and its value. */
insn_code
,
insn_index
);
for
(
j
=
i
;
j
<
len
-
2
;
j
++
)
if
(
value
!=
XVECEXP
(
exp
,
0
,
i
+
1
))
tests
[
j
]
=
tests
[
j
+
2
];
{
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
));
for
(
j
=
0
;
j
<
XVECLEN
(
exp
,
0
);
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
XVECEXP
(
newexp
,
0
,
i
+
1
)
=
value
;
len
-=
2
;
break
;
}
}
}
/* If this is the last condition in a COND and our value is the same
/* If this is the last condition in a COND and our value is the same
as the default value, our test isn't needed. */
as the default value, our test isn't needed. */
if
(
i
==
XVECLEN
(
exp
,
0
)
-
2
else
if
(
i
==
len
-
2
&&
rtx_equal_p
(
newval
,
defval
))
&&
rtx_equal_p
(
XVECEXP
(
exp
,
0
,
i
+
1
),
XEXP
(
exp
,
1
)))
len
-=
2
;
{
}
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
)
-
2
);
for
(
j
=
0
;
j
<
i
;
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
break
;
}
/* If this value and the value for the next test are the same, merge the
obstack_free
(
rtl_obstack
,
first_spacer
);
tests. */
else
if
(
i
!=
XVECLEN
(
exp
,
0
)
-
2
&&
rtx_equal_p
(
XVECEXP
(
exp
,
0
,
i
+
1
),
XVECEXP
(
exp
,
0
,
i
+
3
)))
{
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
)
-
2
);
for
(
j
=
0
;
j
<
i
;
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XVECEXP
(
newexp
,
0
,
j
)
if
(
len
==
0
)
=
insert_right_side
(
IOR
,
XVECEXP
(
exp
,
0
,
i
),
{
XVECEXP
(
exp
,
0
,
i
+
2
),
defval
=
XEXP
(
exp
,
1
);
insn_code
,
insn_index
);
if
(
GET_CODE
(
defval
)
==
COND
)
XVECEXP
(
newexp
,
0
,
j
+
1
)
=
XVECEXP
(
exp
,
0
,
i
+
1
);
return
simplify_cond
(
defval
,
insn_code
,
insn_index
);
return
defval
;
}
else
{
rtx
newexp
;
for
(
j
=
i
+
2
;
j
<
XVECLEN
(
newexp
,
0
);
j
++
)
/* Simplify again, for real this time. */
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
+
2
);
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
if
(
GET_CODE
(
defval
)
==
COND
)
break
;
defval
=
simplify_cond
(
defval
,
insn_code
,
insn_index
);
}
}
/* See if default value needs simplification. */
for
(
i
=
len
-
2
;
i
>=
0
;
i
-=
2
)
if
(
GET_CODE
(
XEXP
(
exp
,
1
))
==
COND
)
{
value
=
simplify_cond
(
XEXP
(
exp
,
1
),
insn_code
,
insn_index
);
if
(
value
!=
XEXP
(
exp
,
1
))
{
{
newexp
=
rtx_alloc
(
COND
);
/* See if this value may need simplification. */
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
));
if
(
GET_CODE
(
tests
[
i
+
1
])
==
COND
)
for
(
j
=
0
;
j
<
XVECLEN
(
exp
,
0
);
j
++
)
tests
[
i
+
1
]
=
simplify_cond
(
tests
[
i
+
1
],
insn_code
,
insn_index
);
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XEXP
(
newexp
,
1
)
=
value
;
/* Simplify this test. */
tests
[
i
]
=
SIMPLIFY_TEST_EXP
(
tests
[
i
],
insn_code
,
insn_index
);
/* If this value and the value for the next test are the same, merge the
tests. */
if
(
i
!=
len
-
2
&&
rtx_equal_p
(
tests
[
i
+
1
],
tests
[
i
+
3
]))
{
/* Merge following test into this one. */
tests
[
i
]
=
insert_right_side
(
IOR
,
tests
[
i
],
tests
[
i
+
2
],
insn_code
,
insn_index
);
/* Delete the following test/value. */
for
(
j
=
i
+
2
;
j
<
len
-
2
;
j
++
)
tests
[
j
]
=
tests
[
j
+
2
];
len
-=
2
;
}
}
}
/* See if we changed anything. */
if
(
len
!=
XVECLEN
(
exp
,
0
)
||
defval
!=
XEXP
(
exp
,
1
))
allsame
=
0
;
else
for
(
i
=
0
;
i
<
len
;
i
++
)
if
(
!
rtx_equal_p
(
tests
[
i
],
XVECEXP
(
exp
,
0
,
i
)))
{
allsame
=
0
;
break
;
}
if
(
allsame
)
return
exp
;
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
len
);
bcopy
(
tests
,
&
XVECEXP
(
newexp
,
0
,
0
),
len
*
sizeof
(
rtx
));
XEXP
(
newexp
,
1
)
=
defval
;
return
newexp
;
}
}
if
(
exp
==
newexp
)
return
exp
;
else
if
(
XVECLEN
(
newexp
,
0
)
==
1
)
return
XVECEXP
(
newexp
,
0
,
0
);
else
return
simplify_cond
(
newexp
,
insn_code
,
insn_index
);
}
}
/* Remove an insn entry from an attribute value. */
/* Remove an insn entry from an attribute value. */
...
@@ -1807,6 +1872,26 @@ insert_right_side (code, exp, term, insn_code, insn_index)
...
@@ -1807,6 +1872,26 @@ insert_right_side (code, exp, term, insn_code, insn_index)
{
{
rtx
newexp
;
rtx
newexp
;
/* Avoid consing in some special cases. */
if
(
code
==
AND
&&
term
==
true_rtx
)
return
exp
;
if
(
code
==
AND
&&
term
==
false_rtx
)
return
false_rtx
;
if
(
code
==
AND
&&
exp
==
true_rtx
)
return
term
;
if
(
code
==
AND
&&
exp
==
false_rtx
)
return
false_rtx
;
if
(
code
==
IOR
&&
term
==
true_rtx
)
return
true_rtx
;
if
(
code
==
IOR
&&
term
==
false_rtx
)
return
exp
;
if
(
code
==
IOR
&&
exp
==
true_rtx
)
return
true_rtx
;
if
(
code
==
IOR
&&
exp
==
false_rtx
)
return
term
;
if
(
rtx_equal_p
(
exp
,
term
))
return
exp
;
if
(
GET_CODE
(
term
)
==
code
)
if
(
GET_CODE
(
term
)
==
code
)
{
{
exp
=
insert_right_side
(
code
,
exp
,
XEXP
(
term
,
0
),
exp
=
insert_right_side
(
code
,
exp
,
XEXP
(
term
,
0
),
...
@@ -1819,16 +1904,19 @@ insert_right_side (code, exp, term, insn_code, insn_index)
...
@@ -1819,16 +1904,19 @@ insert_right_side (code, exp, term, insn_code, insn_index)
if
(
GET_CODE
(
exp
)
==
code
)
if
(
GET_CODE
(
exp
)
==
code
)
{
{
/* Make a copy of this expression and call recursively. */
rtx
new
=
insert_right_side
(
code
,
XEXP
(
exp
,
1
),
newexp
=
attr_rtx
(
code
,
XEXP
(
exp
,
0
),
term
,
insn_code
,
insn_index
);
insert_right_side
(
code
,
XEXP
(
exp
,
1
),
if
(
new
!=
XEXP
(
exp
,
1
))
term
,
insn_code
,
insn_index
));
/* Make a copy of this expression and call recursively. */
newexp
=
attr_rtx
(
code
,
XEXP
(
exp
,
0
),
new
);
else
newexp
=
exp
;
}
}
else
else
{
{
/* Insert the new term. */
/* Insert the new term. */
newexp
=
attr_rtx
(
code
,
exp
,
term
);
newexp
=
attr_rtx
(
code
,
exp
,
term
);
}
}
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
}
...
@@ -1892,6 +1980,8 @@ make_alternative_compare (mask)
...
@@ -1892,6 +1980,8 @@ make_alternative_compare (mask)
computation. If a test condition involves an address, we leave the EQ_ATTR
computation. If a test condition involves an address, we leave the EQ_ATTR
intact because addresses are only valid for the `length' attribute. */
intact because addresses are only valid for the `length' attribute. */
/* ??? Kenner, document the meanings of the arguments!!! */
static
rtx
static
rtx
evaluate_eq_attr
(
exp
,
value
,
insn_code
,
insn_index
)
evaluate_eq_attr
(
exp
,
value
,
insn_code
,
insn_index
)
rtx
exp
;
rtx
exp
;
...
@@ -1929,8 +2019,10 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
...
@@ -1929,8 +2019,10 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
for
(
i
=
0
;
i
<
XVECLEN
(
value
,
0
);
i
+=
2
)
for
(
i
=
0
;
i
<
XVECLEN
(
value
,
0
);
i
+=
2
)
{
{
right
=
insert_right_side
(
AND
,
andexp
,
rtx
this
=
SIMPLIFY_TEST_EXP
(
XVECEXP
(
value
,
0
,
i
),
XVECEXP
(
value
,
0
,
i
),
insn_code
,
insn_index
);
right
=
insert_right_side
(
AND
,
andexp
,
this
,
insn_code
,
insn_index
);
insn_code
,
insn_index
);
right
=
insert_right_side
(
AND
,
right
,
right
=
insert_right_side
(
AND
,
right
,
evaluate_eq_attr
(
exp
,
XVECEXP
(
value
,
0
,
i
+
1
),
evaluate_eq_attr
(
exp
,
XVECEXP
(
value
,
0
,
i
+
1
),
...
@@ -1940,7 +2032,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
...
@@ -1940,7 +2032,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
insn_code
,
insn_index
);
insn_code
,
insn_index
);
/* Add this condition into the AND expression. */
/* Add this condition into the AND expression. */
newexp
=
attr_rtx
(
NOT
,
XVECEXP
(
value
,
0
,
i
)
);
newexp
=
attr_rtx
(
NOT
,
this
);
andexp
=
insert_right_side
(
AND
,
andexp
,
newexp
,
andexp
=
insert_right_side
(
AND
,
andexp
,
newexp
,
insn_code
,
insn_index
);
insn_code
,
insn_index
);
}
}
...
@@ -1964,9 +2056,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
...
@@ -1964,9 +2056,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
if
(
address_used
)
if
(
address_used
)
{
{
if
(
!
RTX_UNCHANGING_P
(
exp
))
if
(
!
RTX_UNCHANGING_P
(
exp
))
exp
=
copy_rtx
(
exp
);
return
copy_rtx_unchanging
(
exp
);
RTX_UNCHANGING_P
(
exp
)
=
1
;
return
exp
;
return
exp
;
}
}
else
else
...
@@ -2194,6 +2284,21 @@ simplify_test_exp (exp, insn_code, insn_index)
...
@@ -2194,6 +2284,21 @@ simplify_test_exp (exp, insn_code, insn_index)
struct
insn_ent
*
ie
;
struct
insn_ent
*
ie
;
int
i
;
int
i
;
rtx
newexp
=
exp
;
rtx
newexp
=
exp
;
char
*
spacer
=
(
char
*
)
obstack_next_free
(
rtl_obstack
);
static
rtx
loser
=
0
;
static
int
count
=
0
;
static
stopcount
=
0
;
if
(
exp
==
loser
)
do_nothing
();
count
++
;
if
(
count
==
stopcount
)
do_nothing
();
/* Don't re-simplify something we already simplified. */
if
(
RTX_UNCHANGING_P
(
exp
))
return
exp
;
switch
(
GET_CODE
(
exp
))
switch
(
GET_CODE
(
exp
))
{
{
...
@@ -2228,11 +2333,20 @@ simplify_test_exp (exp, insn_code, insn_index)
...
@@ -2228,11 +2333,20 @@ simplify_test_exp (exp, insn_code, insn_index)
left
=
simplify_and_tree
(
left
,
&
right
,
insn_code
,
insn_index
);
left
=
simplify_and_tree
(
left
,
&
right
,
insn_code
,
insn_index
);
if
(
left
==
false_rtx
||
right
==
false_rtx
)
if
(
left
==
false_rtx
||
right
==
false_rtx
)
return
false_rtx
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
false_rtx
;
}
else
if
(
left
==
true_rtx
)
else
if
(
left
==
true_rtx
)
return
right
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
SIMPLIFY_TEST_EXP
(
XEXP
(
exp
,
1
),
insn_code
,
insn_index
);
}
else
if
(
right
==
true_rtx
)
else
if
(
right
==
true_rtx
)
return
left
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
SIMPLIFY_TEST_EXP
(
XEXP
(
exp
,
0
),
insn_code
,
insn_index
);
}
/* See if all or all but one of the insn's alternatives are specified
/* See if all or all but one of the insn's alternatives are specified
in this tree. Optimize if so. */
in this tree. Optimize if so. */
...
@@ -2286,11 +2400,20 @@ simplify_test_exp (exp, insn_code, insn_index)
...
@@ -2286,11 +2400,20 @@ simplify_test_exp (exp, insn_code, insn_index)
left
=
simplify_or_tree
(
left
,
&
right
,
insn_code
,
insn_index
);
left
=
simplify_or_tree
(
left
,
&
right
,
insn_code
,
insn_index
);
if
(
right
==
true_rtx
||
left
==
true_rtx
)
if
(
right
==
true_rtx
||
left
==
true_rtx
)
return
true_rtx
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
true_rtx
;
}
else
if
(
left
==
false_rtx
)
else
if
(
left
==
false_rtx
)
return
right
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
SIMPLIFY_TEST_EXP
(
XEXP
(
exp
,
1
),
insn_code
,
insn_index
);
}
else
if
(
right
==
false_rtx
)
else
if
(
right
==
false_rtx
)
return
left
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
SIMPLIFY_TEST_EXP
(
XEXP
(
exp
,
0
),
insn_code
,
insn_index
);
}
/* Test for simple cases where the distributive law is useful. I.e.,
/* Test for simple cases where the distributive law is useful. I.e.,
convert (ior (and (x) (y))
convert (ior (and (x) (y))
...
@@ -2352,14 +2475,23 @@ simplify_test_exp (exp, insn_code, insn_index)
...
@@ -2352,14 +2475,23 @@ simplify_test_exp (exp, insn_code, insn_index)
break
;
break
;
case
NOT
:
case
NOT
:
if
(
GET_CODE
(
XEXP
(
exp
,
0
))
==
NOT
)
return
SIMPLIFY_TEST_EXP
(
XEXP
(
XEXP
(
exp
,
0
),
0
),
insn_code
,
insn_index
);
left
=
SIMPLIFY_TEST_EXP
(
XEXP
(
exp
,
0
),
insn_code
,
insn_index
);
left
=
SIMPLIFY_TEST_EXP
(
XEXP
(
exp
,
0
),
insn_code
,
insn_index
);
if
(
GET_CODE
(
left
)
==
NOT
)
if
(
GET_CODE
(
left
)
==
NOT
)
return
XEXP
(
left
,
0
);
return
XEXP
(
left
,
0
);
if
(
left
==
false_rtx
)
if
(
left
==
false_rtx
)
return
true_rtx
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
true_rtx
;
}
else
if
(
left
==
true_rtx
)
else
if
(
left
==
true_rtx
)
return
false_rtx
;
{
obstack_free
(
rtl_obstack
,
spacer
);
return
false_rtx
;
}
/* Try to apply De`Morgan's laws. */
/* Try to apply De`Morgan's laws. */
else
if
(
GET_CODE
(
left
)
==
IOR
)
else
if
(
GET_CODE
(
left
)
==
IOR
)
...
@@ -2401,12 +2533,14 @@ simplify_test_exp (exp, insn_code, insn_index)
...
@@ -2401,12 +2533,14 @@ simplify_test_exp (exp, insn_code, insn_index)
to process (i.e., we are canonicalizing something.). */
to process (i.e., we are canonicalizing something.). */
if
(
insn_code
!=
-
2
&&
!
RTX_UNCHANGING_P
(
newexp
))
if
(
insn_code
!=
-
2
&&
!
RTX_UNCHANGING_P
(
newexp
))
{
{
newexp
=
copy_rtx
(
newexp
);
return
copy_rtx_unchanging
(
newexp
);
RTX_UNCHANGING_P
(
newexp
)
=
1
;
}
}
return
newexp
;
return
newexp
;
}
}
do_nothing
()
{}
/* Optimize the attribute lists by seeing if we can determine conditional
/* Optimize the attribute lists by seeing if we can determine conditional
values from the known values of other attributes. This will save subroutine
values from the known values of other attributes. This will save subroutine
...
@@ -3819,6 +3953,33 @@ xmalloc (size)
...
@@ -3819,6 +3953,33 @@ xmalloc (size)
return
val
;
return
val
;
}
}
static
rtx
copy_rtx_unchanging
(
orig
)
register
rtx
orig
;
{
register
rtx
copy
;
register
RTX_CODE
code
;
code
=
GET_CODE
(
orig
);
switch
(
code
)
{
case
CONST_INT
:
case
CONST_DOUBLE
:
case
SYMBOL_REF
:
case
CODE_LABEL
:
return
orig
;
}
copy
=
rtx_alloc
(
code
);
PUT_MODE
(
copy
,
GET_MODE
(
orig
));
RTX_UNCHANGING_P
(
copy
)
=
1
;
bcopy
(
&
XEXP
(
orig
,
0
),
&
XEXP
(
copy
,
0
),
GET_RTX_LENGTH
(
GET_CODE
(
copy
))
*
sizeof
(
rtx
));
return
copy
;
}
static
void
static
void
fatal
(
s
,
a1
,
a2
)
fatal
(
s
,
a1
,
a2
)
char
*
s
;
char
*
s
;
...
@@ -3852,6 +4013,7 @@ main (argc, argv)
...
@@ -3852,6 +4013,7 @@ main (argc, argv)
rtx
tem
;
rtx
tem
;
obstack_init
(
rtl_obstack
);
obstack_init
(
rtl_obstack
);
obstack_init
(
hash_obstack
);
if
(
argc
<=
1
)
if
(
argc
<=
1
)
fatal
(
"No input file name."
);
fatal
(
"No input file name."
);
...
...
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