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
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
285 additions
and
123 deletions
+285
-123
gcc/genattrtab.c
+285
-123
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
;
...
@@ -1053,17 +1063,27 @@ make_canonical (attr, exp)
...
@@ -1053,17 +1063,27 @@ make_canonical (attr, exp)
case
COND
:
case
COND
:
cond
:
cond
:
{
int
allsame
=
1
;
rtx
defval
;
/* First, check for degenerate COND. */
/* First, check for degenerate COND. */
if
(
XVECLEN
(
exp
,
0
)
==
0
)
if
(
XVECLEN
(
exp
,
0
)
==
0
)
return
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
return
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
defval
=
XEXP
(
exp
,
1
)
=
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
{
XVECEXP
(
exp
,
0
,
i
+
1
)
XVECEXP
(
exp
,
0
,
i
+
1
)
=
make_canonical
(
attr
,
XVECEXP
(
exp
,
0
,
i
+
1
));
=
make_canonical
(
attr
,
XVECEXP
(
exp
,
0
,
i
+
1
));
if
(
!
rtx_equal_p
(
XVECEXP
(
exp
,
0
,
i
+
1
),
defval
))
XEXP
(
exp
,
1
)
=
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
allsame
=
0
;
}
if
(
allsame
)
return
defval
;
break
;
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
;
}
/* 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
));
}
}
XEXP
(
newexp
,
1
)
=
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
;
}
/* 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
);
}
}
XEXP
(
newexp
,
1
)
=
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
);
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
rtx
*
tests
=
(
rtx
*
)
alloca
(
len
*
sizeof
(
rtx
));
{
int
allsame
=
1
;
newtest
=
SIMPLIFY_TEST_EXP
(
XVECEXP
(
exp
,
0
,
i
),
insn_code
,
insn_index
);
char
*
spacer
,
*
first_spacer
;
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
);
/* This lets us free all storage allocated below, if appropriate. */
break
;
first_spacer
=
(
char
*
)
obstack_next_free
(
rtl_obstack
);
}
else
if
(
newtest
==
false_rtx
)
bcopy
(
&
XVECEXP
(
exp
,
0
,
0
),
tests
,
len
*
sizeof
(
rtx
));
{
/* Build a new COND without this test. */
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
++
)
/* See if default value needs simplification. */
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
+
2
);
if
(
GET_CODE
(
defval
)
==
COND
)
defval
=
simplify_cond
(
defval
,
insn_code
,
insn_index
);
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
/* Simplify now, just to see what tests we can get rid of. */
break
;
}
else
if
(
newtest
!=
XVECEXP
(
exp
,
0
,
i
))
/* Work from back to front, so if all values match the default,
we get rid of all of them. */
for
(
i
=
len
-
2
;
i
>=
0
;
i
-=
2
)
{
{
newexp
=
rtx_alloc
(
COND
);
rtx
newtest
,
newval
;
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
;
/* Simplify this test. */
break
;
newtest
=
SIMPLIFY_TEST_EXP
(
tests
[
i
],
insn_code
,
insn_index
);
}
newval
=
tests
[
i
+
1
];
/* See if this value may need simplification. */
/* See if this value may need simplification. */
if
(
GET_CODE
(
XVECEXP
(
exp
,
0
,
i
+
1
))
==
COND
)
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
)
{
{
value
=
simplify_cond
(
XVECEXP
(
exp
,
0
,
i
+
1
),
/* If test is true, make this value the default
insn_code
,
insn_index
);
and discard this + any following tests. */
if
(
value
!=
XVECEXP
(
exp
,
0
,
i
+
1
))
len
=
i
;
defval
=
tests
[
i
];
}
else
if
(
newtest
==
false_rtx
)
{
{
newexp
=
rtx_alloc
(
COND
);
/* If test is false, discard it and its value. */
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
));
for
(
j
=
i
;
j
<
len
-
2
;
j
++
)
for
(
j
=
0
;
j
<
XVECLEN
(
exp
,
0
);
j
++
)
tests
[
j
]
=
tests
[
j
+
2
];
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
;
}
obstack_free
(
rtl_obstack
,
first_spacer
);
if
(
len
==
0
)
{
{
newexp
=
rtx_alloc
(
COND
);
defval
=
XEXP
(
exp
,
1
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
)
-
2
);
if
(
GET_CODE
(
defval
)
==
COND
)
for
(
j
=
0
;
j
<
i
;
j
++
)
return
simplify_cond
(
defval
,
insn_code
,
insn_index
);
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
return
defval
;
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
break
;
}
}
else
{
rtx
newexp
;
/* Simplify again, for real this time. */
if
(
GET_CODE
(
defval
)
==
COND
)
defval
=
simplify_cond
(
defval
,
insn_code
,
insn_index
);
for
(
i
=
len
-
2
;
i
>=
0
;
i
-=
2
)
{
/* See if this value may need simplification. */
if
(
GET_CODE
(
tests
[
i
+
1
])
==
COND
)
tests
[
i
+
1
]
=
simplify_cond
(
tests
[
i
+
1
],
insn_code
,
insn_index
);
/* 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
/* If this value and the value for the next test are the same, merge the
tests. */
tests. */
else
if
(
i
!=
XVECLEN
(
exp
,
0
)
-
2
if
(
i
!=
len
-
2
&&
rtx_equal_p
(
XVECEXP
(
exp
,
0
,
i
+
1
),
&&
rtx_equal_p
(
tests
[
i
+
1
],
tests
[
i
+
3
]))
XVECEXP
(
exp
,
0
,
i
+
3
)))
{
{
newexp
=
rtx_alloc
(
COND
);
/* Merge following test into this one. */
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
)
-
2
);
tests
[
i
]
for
(
j
=
0
;
j
<
i
;
j
++
)
=
insert_right_side
(
IOR
,
tests
[
i
],
tests
[
i
+
2
],
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XVECEXP
(
newexp
,
0
,
j
)
=
insert_right_side
(
IOR
,
XVECEXP
(
exp
,
0
,
i
),
XVECEXP
(
exp
,
0
,
i
+
2
),
insn_code
,
insn_index
);
insn_code
,
insn_index
);
XVECEXP
(
newexp
,
0
,
j
+
1
)
=
XVECEXP
(
exp
,
0
,
i
+
1
);
for
(
j
=
i
+
2
;
j
<
XVECLEN
(
newexp
,
0
);
j
++
)
/* Delete the following test/value. */
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
+
2
);
for
(
j
=
i
+
2
;
j
<
len
-
2
;
j
++
)
tests
[
j
]
=
tests
[
j
+
2
];
XEXP
(
newexp
,
1
)
=
XEXP
(
exp
,
1
);
len
-=
2
;
break
;
}
}
}
}
/* See if default value needs simplification. */
/* See if we changed anything. */
if
(
GET_CODE
(
XEXP
(
exp
,
1
))
==
COND
)
if
(
len
!=
XVECLEN
(
exp
,
0
)
||
defval
!=
XEXP
(
exp
,
1
))
{
allsame
=
0
;
value
=
simplify_cond
(
XEXP
(
exp
,
1
),
insn_code
,
insn_index
);
else
if
(
value
!=
XEXP
(
exp
,
1
))
for
(
i
=
0
;
i
<
len
;
i
++
)
if
(
!
rtx_equal_p
(
tests
[
i
],
XVECEXP
(
exp
,
0
,
i
)))
{
{
newexp
=
rtx_alloc
(
COND
);
allsame
=
0
;
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
XVECLEN
(
exp
,
0
));
break
;
for
(
j
=
0
;
j
<
XVECLEN
(
exp
,
0
);
j
++
)
XVECEXP
(
newexp
,
0
,
j
)
=
XVECEXP
(
exp
,
0
,
j
);
XEXP
(
newexp
,
1
)
=
value
;
}
}
}
if
(
exp
==
newexp
)
if
(
allsame
)
return
exp
;
return
exp
;
else
if
(
XVECLEN
(
newexp
,
0
)
==
1
)
return
XVECEXP
(
newexp
,
0
,
0
);
newexp
=
rtx_alloc
(
COND
);
else
return
simplify_cond
(
newexp
,
insn_code
,
insn_index
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
len
);
bcopy
(
tests
,
&
XVECEXP
(
newexp
,
0
,
0
),
len
*
sizeof
(
rtx
));
XEXP
(
newexp
,
1
)
=
defval
;
return
newexp
;
}
}
}
/* 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,10 +1904,13 @@ insert_right_side (code, exp, term, insn_code, insn_index)
...
@@ -1819,10 +1904,13 @@ insert_right_side (code, exp, term, insn_code, insn_index)
if
(
GET_CODE
(
exp
)
==
code
)
if
(
GET_CODE
(
exp
)
==
code
)
{
{
rtx
new
=
insert_right_side
(
code
,
XEXP
(
exp
,
1
),
term
,
insn_code
,
insn_index
);
if
(
new
!=
XEXP
(
exp
,
1
))
/* Make a copy of this expression and call recursively. */
/* Make a copy of this expression and call recursively. */
newexp
=
attr_rtx
(
code
,
XEXP
(
exp
,
0
),
newexp
=
attr_rtx
(
code
,
XEXP
(
exp
,
0
),
new
);
insert_right_side
(
code
,
XEXP
(
exp
,
1
),
else
term
,
insn_code
,
insn_index
))
;
newexp
=
exp
;
}
}
else
else
{
{
...
@@ -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
)
{
obstack_free
(
rtl_obstack
,
spacer
);
return
false_rtx
;
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
)
{
obstack_free
(
rtl_obstack
,
spacer
);
return
true_rtx
;
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
)
{
obstack_free
(
rtl_obstack
,
spacer
);
return
true_rtx
;
return
true_rtx
;
}
else
if
(
left
==
true_rtx
)
else
if
(
left
==
true_rtx
)
{
obstack_free
(
rtl_obstack
,
spacer
);
return
false_rtx
;
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,13 +2533,15 @@ simplify_test_exp (exp, insn_code, insn_index)
...
@@ -2401,13 +2533,15 @@ 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
calls during the compilation. */
calls during the compilation. */
...
@@ -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