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
3e7b5313
Commit
3e7b5313
authored
Mar 06, 1992
by
Tom Wood
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r403
parent
e5259eef
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
514 additions
and
176 deletions
+514
-176
gcc/genattrtab.c
+514
-176
No files found.
gcc/genattrtab.c
View file @
3e7b5313
...
...
@@ -21,7 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This program handles insn attribues and the DEFINE_DELAY and
DEFINE_FUNCTION_UNIT definitions.
It produces a series of functions
call `get_attr_...', one for each
It produces a series of functions
named `get_attr_...', one for each insn
attribute. Each of these is given the rtx for an insn and returns a member
of the enum for the attribute.
...
...
@@ -44,6 +44,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
changed are made. The resulting lengths are saved for use by
`get_attr_length'.
A special form of DEFINE_ATTR, where the expression for default value is a
CONST expression, indicates an attribute that is constant for a given run
of the compiler. The subroutine generated for these attributes has no
parameters as it does not depend on any particular insn. Constant
attributes are typically used to specify which variety of processor is
used.
Internal attributes are defined to handle DEFINE_DELAY and
DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
...
...
@@ -66,9 +73,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
optimization simplify them.
Once optimization is complete, any required routines and definitions
will be written. */
will be written.
An optimization that is not yet implemented is to hoist the constant
expressions entirely out of the routines and definitions that are written.
A way to do this is to iterate over all possible combinations of values
for constant attributes and generate a set of functions for that given
combination. An initialization function would be written that evaluates
the attributes and installs the corresponding set of routines and
definitions (each would be accessed through a pointer). */
#include <stdio.h>
#include "gvarargs.h"
#include "config.h"
#include "rtl.h"
#include "obstack.h"
...
...
@@ -133,6 +149,7 @@ struct attr_desc
char
*
name
;
/* Name of attribute. */
struct
attr_desc
*
next
;
/* Next attribute. */
int
is_numeric
;
/* Values of this attribute are numeric. */
int
is_const
;
/* Attribute value constant for each run. */
int
is_special
;
/* Don't call `write_attr_set'. */
struct
attr_value
*
first_value
;
/* First value of this attribute. */
struct
attr_value
*
default_val
;
/* Default value for this attribute. */
...
...
@@ -224,11 +241,15 @@ static char *alternative_name = "alternative";
rtx
frame_pointer_rtx
,
stack_pointer_rtx
,
arg_pointer_rtx
;
static
rtx
attr_rtx
();
static
char
*
attr_printf
();
static
char
*
attr_string
();
static
rtx
check_attr_test
();
static
void
check_attr_value
();
static
rtx
convert_set_attr_alternative
();
static
rtx
convert_set_attr
();
static
void
check_defs
();
static
rtx
convert_const_symbol_ref
();
static
rtx
make_canonical
();
static
struct
attr_value
*
get_attr_value
();
static
void
expand_delays
();
...
...
@@ -283,7 +304,284 @@ char *xrealloc ();
char
*
xmalloc
();
static
void
fatal
();
/* Hash table for sharing RTL and strings. */
/* Each hash table slot is a bucket containing a chain of these structures.
Strings are given negative hash codes; RTL expressions are given positive
hash codes. */
struct
attr_hash
{
struct
attr_hash
*
next
;
/* Next structure in the bucket. */
int
hashcode
;
/* Hash code of this rtx or string. */
union
{
char
*
str
;
/* The string (negative hash codes) */
rtx
rtl
;
/* or the RTL recorded here. */
}
u
;
};
/* Now here is the hash table. When recording an RTL, it is added to
the slot whose index is the hash code mod the table size. Note
that the hash table is used for several kinds of RTL (see attr_rtx)
and for strings. While all these live in the same table, they are
completely independent, and the hash code is computed differently
for each. */
#define RTL_HASH_SIZE 4093
struct
attr_hash
*
attr_hash_table
[
RTL_HASH_SIZE
];
/* Here is how primitive or already-shared RTL's hash
codes are made. */
#define RTL_HASH(RTL) ((int) (RTL) & 0777777)
/* Add an entry to the hash table for RTL with hash code HASHCODE. */
static
void
attr_hash_add_rtx
(
hashcode
,
rtl
)
int
hashcode
;
rtx
rtl
;
{
register
struct
attr_hash
*
h
;
h
=
(
struct
attr_hash
*
)
xmalloc
(
sizeof
(
struct
attr_hash
));
h
->
hashcode
=
hashcode
;
h
->
u
.
rtl
=
rtl
;
h
->
next
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
]
=
h
;
}
/* Add an entry to the hash table for STRING with hash code HASHCODE. */
static
void
attr_hash_add_string
(
hashcode
,
str
)
int
hashcode
;
char
*
str
;
{
register
struct
attr_hash
*
h
;
h
=
(
struct
attr_hash
*
)
xmalloc
(
sizeof
(
struct
attr_hash
));
h
->
hashcode
=
-
hashcode
;
h
->
u
.
str
=
str
;
h
->
next
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
]
=
h
;
}
/* Generate an RTL expression, but allow sharing. Like gen_rtx, but the
mode is not used:
rtx attr_rtx (code, [element1, ..., elementn]) */
/*VARARGS1*/
static
rtx
attr_rtx
(
va_alist
)
va_dcl
{
va_list
p
;
enum
rtx_code
code
;
register
int
i
;
/* Array indices... */
register
char
*
fmt
;
/* Current rtx's format... */
register
rtx
rt_val
;
/* RTX to return to caller... */
int
hashcode
;
register
struct
attr_hash
*
h
;
va_start
(
p
);
code
=
va_arg
(
p
,
enum
rtx_code
);
/* For each of several cases, search the hash table for an existing entry.
Use that entry if one is found; otherwise create a new RTL and add it
to the table. */
if
(
GET_RTX_CLASS
(
code
)
==
'1'
)
{
rtx
arg0
=
va_arg
(
p
,
rtx
);
hashcode
=
(
code
+
RTL_HASH
(
arg0
));
for
(
h
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
;
h
=
h
->
next
)
if
(
h
->
hashcode
==
hashcode
&&
GET_CODE
(
h
->
u
.
rtl
)
==
code
&&
XEXP
(
h
->
u
.
rtl
,
0
)
==
arg0
)
goto
found
;
if
(
h
==
0
)
{
rt_val
=
rtx_alloc
(
code
);
XEXP
(
rt_val
,
0
)
=
arg0
;
}
}
else
if
(
GET_RTX_CLASS
(
code
)
==
'c'
||
GET_RTX_CLASS
(
code
)
==
'2'
||
GET_RTX_CLASS
(
code
)
==
'<'
)
{
rtx
arg0
=
va_arg
(
p
,
rtx
);
rtx
arg1
=
va_arg
(
p
,
rtx
);
hashcode
=
(
code
+
RTL_HASH
(
arg0
)
+
RTL_HASH
(
arg1
));
for
(
h
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
;
h
=
h
->
next
)
if
(
h
->
hashcode
==
hashcode
&&
GET_CODE
(
h
->
u
.
rtl
)
==
code
&&
XEXP
(
h
->
u
.
rtl
,
0
)
==
arg0
&&
XEXP
(
h
->
u
.
rtl
,
1
)
==
arg1
)
goto
found
;
if
(
h
==
0
)
{
rt_val
=
rtx_alloc
(
code
);
XEXP
(
rt_val
,
0
)
=
arg0
;
XEXP
(
rt_val
,
1
)
=
arg1
;
}
}
else
if
(
GET_RTX_LENGTH
(
code
)
==
1
&&
GET_RTX_FORMAT
(
code
)[
0
]
==
's'
)
{
char
*
arg0
=
va_arg
(
p
,
char
*
);
hashcode
=
(
code
+
RTL_HASH
(
arg0
));
for
(
h
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
;
h
=
h
->
next
)
if
(
h
->
hashcode
==
hashcode
&&
GET_CODE
(
h
->
u
.
rtl
)
==
code
&&
XSTR
(
h
->
u
.
rtl
,
0
)
==
arg0
)
goto
found
;
if
(
h
==
0
)
{
rt_val
=
rtx_alloc
(
code
);
XSTR
(
rt_val
,
0
)
=
arg0
;
}
}
else
if
(
GET_RTX_LENGTH
(
code
)
==
2
&&
GET_RTX_FORMAT
(
code
)[
0
]
==
's'
&&
GET_RTX_FORMAT
(
code
)[
1
]
==
's'
)
{
char
*
arg0
=
va_arg
(
p
,
char
*
);
char
*
arg1
=
va_arg
(
p
,
char
*
);
hashcode
=
(
code
+
RTL_HASH
(
arg0
)
+
RTL_HASH
(
arg1
));
for
(
h
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
;
h
=
h
->
next
)
if
(
h
->
hashcode
==
hashcode
&&
GET_CODE
(
h
->
u
.
rtl
)
==
code
&&
XSTR
(
h
->
u
.
rtl
,
0
)
==
arg0
&&
XSTR
(
h
->
u
.
rtl
,
1
)
==
arg1
)
goto
found
;
if
(
h
==
0
)
{
rt_val
=
rtx_alloc
(
code
);
XSTR
(
rt_val
,
0
)
=
arg0
;
XSTR
(
rt_val
,
1
)
=
arg1
;
}
}
else
{
rt_val
=
rtx_alloc
(
code
);
/* Allocate the storage space. */
fmt
=
GET_RTX_FORMAT
(
code
);
/* Find the right format... */
for
(
i
=
0
;
i
<
GET_RTX_LENGTH
(
code
);
i
++
)
{
switch
(
*
fmt
++
)
{
case
'0'
:
/* Unused field. */
break
;
case
'i'
:
/* An integer? */
XINT
(
rt_val
,
i
)
=
va_arg
(
p
,
int
);
break
;
case
's'
:
/* A string? */
XSTR
(
rt_val
,
i
)
=
va_arg
(
p
,
char
*
);
break
;
case
'e'
:
/* An expression? */
case
'u'
:
/* An insn? Same except when printing. */
XEXP
(
rt_val
,
i
)
=
va_arg
(
p
,
rtx
);
break
;
case
'E'
:
/* An RTX vector? */
XVEC
(
rt_val
,
i
)
=
va_arg
(
p
,
rtvec
);
break
;
default
:
abort
();
}
}
va_end
(
p
);
return
rt_val
;
}
va_end
(
p
);
attr_hash_add_rtx
(
hashcode
,
rt_val
);
return
rt_val
;
found
:
va_end
(
p
);
return
h
->
u
.
rtl
;
}
/* Create a new string printed with the printf line arguments into a space
of at most LEN bytes:
rtx attr_printf (len, format, [arg1, ..., argn]) */
/*VARARGS2*/
static
char
*
attr_printf
(
va_alist
)
va_dcl
{
va_list
p
;
register
int
len
;
register
char
*
fmt
;
register
char
*
str
;
/* Print the string into a temporary location. */
va_start
(
p
);
len
=
va_arg
(
p
,
int
);
str
=
(
char
*
)
alloca
(
len
);
fmt
=
va_arg
(
p
,
char
*
);
vsprintf
(
str
,
fmt
,
p
);
va_end
(
p
);
return
attr_string
(
str
,
strlen
(
str
));
}
/* Return a permanent (possibly shared) copy of a string STR (not assumed
to be null terminated) with LEN bytes. */
static
char
*
attr_string
(
str
,
len
)
char
*
str
;
int
len
;
{
register
struct
attr_hash
*
h
;
int
hashcode
;
int
i
;
register
char
*
new_str
;
/* Compute the hash code. */
hashcode
=
(
len
+
1
)
*
613
+
(
unsigned
)
str
[
0
];
for
(
i
=
1
;
i
<=
len
;
i
+=
2
)
hashcode
=
((
hashcode
*
613
)
+
(
unsigned
)
str
[
i
]);
if
(
hashcode
<
0
)
hashcode
=
-
hashcode
;
/* Search the table for the string. */
for
(
h
=
attr_hash_table
[
hashcode
%
RTL_HASH_SIZE
];
h
;
h
=
h
->
next
)
if
(
h
->
hashcode
==
-
hashcode
&&
!
strcmp
(
h
->
u
.
str
,
str
))
return
h
->
u
.
str
;
/* <-- return if found. */
/* Not found; create a permanent copy and add it to the hash table. */
new_str
=
(
char
*
)
xmalloc
(
len
+
1
);
bcopy
(
str
,
new_str
,
len
);
new_str
[
len
]
=
'\0'
;
attr_hash_add_string
(
hashcode
,
new_str
);
return
new_str
;
/* Return the new string. */
}
/* Given a test expression for an attribute, ensure it is validly formed.
IS_CONST indicates whether the expression is constant for each compiler
run (a constant expression may not test any particular insn).
Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
...
...
@@ -295,8 +593,9 @@ static void fatal ();
Return the new expression, if any. */
static
rtx
check_attr_test
(
exp
)
check_attr_test
(
exp
,
is_const
)
rtx
exp
;
int
is_const
;
{
struct
attr_desc
*
attr
;
struct
attr_value
*
av
;
...
...
@@ -308,13 +607,11 @@ check_attr_test (exp)
case
EQ_ATTR
:
/* Handle negation test. */
if
(
XSTR
(
exp
,
1
)[
0
]
==
'!'
)
{
XSTR
(
exp
,
1
)
=
&
XSTR
(
exp
,
1
)[
1
];
newexp
=
rtx_alloc
(
NOT
);
XEXP
(
newexp
,
0
)
=
exp
;
return
check_attr_test
(
newexp
);
}
return
check_attr_test
(
attr_rtx
(
NOT
,
attr_rtx
(
EQ_ATTR
,
XSTR
(
exp
,
0
),
&
XSTR
(
exp
,
1
)[
1
])),
is_const
);
else
if
(
n_comma_elts
(
XSTR
(
exp
,
1
))
==
1
)
{
...
...
@@ -332,6 +629,10 @@ check_attr_test (exp)
fatal
(
"Unknown attribute `%s' in EQ_ATTR"
,
XEXP
(
exp
,
0
));
}
if
(
is_const
&&
!
attr
->
is_const
)
fatal
(
"Constant expression uses insn attribute `%s' in EQ_ATTR"
,
XEXP
(
exp
,
0
));
XSTR
(
exp
,
0
)
=
attr
->
name
;
if
(
attr
->
is_numeric
)
...
...
@@ -360,13 +661,11 @@ check_attr_test (exp)
name_ptr
=
XSTR
(
exp
,
1
);
while
((
p
=
next_comma_elt
(
&
name_ptr
))
!=
NULL
)
{
newexp
=
rtx_alloc
(
EQ_ATTR
);
XSTR
(
newexp
,
0
)
=
XSTR
(
exp
,
0
);
XSTR
(
newexp
,
1
)
=
p
;
newexp
=
attr_rtx
(
EQ_ATTR
,
XSTR
(
exp
,
0
),
p
);
orexp
=
insert_right_side
(
IOR
,
orexp
,
newexp
,
-
2
);
}
return
check_attr_test
(
orexp
);
return
check_attr_test
(
orexp
,
is_const
);
}
break
;
...
...
@@ -379,15 +678,19 @@ check_attr_test (exp)
case
IOR
:
case
AND
:
XEXP
(
exp
,
0
)
=
check_attr_test
(
XEXP
(
exp
,
0
));
XEXP
(
exp
,
1
)
=
check_attr_test
(
XEXP
(
exp
,
1
));
XEXP
(
exp
,
0
)
=
check_attr_test
(
XEXP
(
exp
,
0
)
,
is_const
);
XEXP
(
exp
,
1
)
=
check_attr_test
(
XEXP
(
exp
,
1
)
,
is_const
);
break
;
case
NOT
:
XEXP
(
exp
,
0
)
=
check_attr_test
(
XEXP
(
exp
,
0
));
XEXP
(
exp
,
0
)
=
check_attr_test
(
XEXP
(
exp
,
0
)
,
is_const
);
break
;
case
MATCH_OPERAND
:
if
(
is_const
)
fatal
(
"RTL operator
\"
%s
\"
not valid in constant attribute test"
,
GET_RTX_NAME
(
MATCH_OPERAND
));
case
LE
:
case
LT
:
case
GT
:
case
GE
:
case
LEU
:
case
LTU
:
case
GTU
:
case
GEU
:
case
NE
:
case
EQ
:
...
...
@@ -395,6 +698,14 @@ check_attr_test (exp)
RTX_UNCHANGING_P
(
exp
)
=
1
;
break
;
case
SYMBOL_REF
:
if
(
is_const
)
{
/* These cases are valid for constant attributes, but can't be
simplified. */
RTX_UNCHANGING_P
(
exp
)
=
1
;
break
;
}
default
:
fatal
(
"RTL operator
\"
%s
\"
not valid in attribute test"
,
GET_RTX_NAME
(
GET_CODE
(
exp
)));
...
...
@@ -454,7 +765,8 @@ check_attr_value (exp, attr)
return
;
case
IF_THEN_ELSE
:
XEXP
(
exp
,
0
)
=
check_attr_test
(
XEXP
(
exp
,
0
));
XEXP
(
exp
,
0
)
=
check_attr_test
(
XEXP
(
exp
,
0
),
attr
?
attr
->
is_const
:
0
);
check_attr_value
(
XEXP
(
exp
,
1
),
attr
);
check_attr_value
(
XEXP
(
exp
,
2
),
attr
);
return
;
...
...
@@ -465,13 +777,21 @@ check_attr_value (exp, attr)
for
(
i
=
0
;
i
<
XVECLEN
(
exp
,
0
);
i
+=
2
)
{
XVECEXP
(
exp
,
0
,
i
)
=
check_attr_test
(
XVECEXP
(
exp
,
0
,
i
));
XVECEXP
(
exp
,
0
,
i
)
=
check_attr_test
(
XVECEXP
(
exp
,
0
,
i
),
attr
?
attr
->
is_const
:
0
);
check_attr_value
(
XVECEXP
(
exp
,
0
,
i
+
1
),
attr
);
}
check_attr_value
(
XEXP
(
exp
,
1
),
attr
);
return
;
case
SYMBOL_REF
:
if
(
attr
&&
attr
->
is_const
)
/* A constant SYMBOL_REF is valid as a constant attribute test and
is expanded later by make_canonical into a COND. */
return
;
/* Otherwise, fall through... */
default
:
fatal
(
"Illegal operation `%s' for attribute value"
,
GET_RTX_NAME
(
GET_CODE
(
exp
)));
...
...
@@ -502,21 +822,19 @@ convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
for
(
i
=
0
;
i
<
num_alt
-
1
;
i
++
)
{
char
*
p
;
p
=
attr_printf
(
3
,
"%d"
,
i
);
/* Sharing this EQ_ATTR rtl causes trouble. */
XVECEXP
(
condexp
,
0
,
2
*
i
)
=
rtx_alloc
(
EQ_ATTR
);
XSTR
(
XVECEXP
(
condexp
,
0
,
2
*
i
),
0
)
=
alternative_name
;
XSTR
(
XVECEXP
(
condexp
,
0
,
2
*
i
),
1
)
=
(
char
*
)
xmalloc
(
3
);
sprintf
(
XSTR
(
XVECEXP
(
condexp
,
0
,
2
*
i
),
1
),
"%d"
,
i
);
XSTR
(
XVECEXP
(
condexp
,
0
,
2
*
i
),
1
)
=
p
;
XVECEXP
(
condexp
,
0
,
2
*
i
+
1
)
=
XVECEXP
(
exp
,
1
,
i
);
}
XEXP
(
condexp
,
1
)
=
XVECEXP
(
exp
,
1
,
i
);
newexp
=
rtx_alloc
(
SET
);
XEXP
(
newexp
,
0
)
=
rtx_alloc
(
ATTR
);
XSTR
(
XEXP
(
newexp
,
0
),
0
)
=
XSTR
(
exp
,
0
);
XEXP
(
newexp
,
1
)
=
condexp
;
return
newexp
;
return
attr_rtx
(
SET
,
attr_rtx
(
ATTR
,
XSTR
(
exp
,
0
)),
condexp
);
}
/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
...
...
@@ -536,15 +854,9 @@ convert_set_attr (exp, num_alt, insn_code, insn_index)
/* See how many alternative specified. */
n
=
n_comma_elts
(
XSTR
(
exp
,
1
));
if
(
n
==
1
)
{
newexp
=
rtx_alloc
(
SET
);
XEXP
(
newexp
,
0
)
=
rtx_alloc
(
ATTR
);
XSTR
(
XEXP
(
newexp
,
0
),
0
)
=
XSTR
(
exp
,
0
);
XEXP
(
newexp
,
1
)
=
rtx_alloc
(
CONST_STRING
);
XSTR
(
XEXP
(
newexp
,
1
),
0
)
=
XSTR
(
exp
,
1
);
return
newexp
;
}
return
attr_rtx
(
SET
,
attr_rtx
(
ATTR
,
XSTR
(
exp
,
0
)),
attr_rtx
(
CONST_STRING
,
XSTR
(
exp
,
1
)));
newexp
=
rtx_alloc
(
SET_ATTR_ALTERNATIVE
);
XSTR
(
newexp
,
0
)
=
XSTR
(
exp
,
0
);
...
...
@@ -554,10 +866,7 @@ convert_set_attr (exp, num_alt, insn_code, insn_index)
name_ptr
=
XSTR
(
exp
,
1
);
n
=
0
;
while
((
p
=
next_comma_elt
(
&
name_ptr
))
!=
NULL
)
{
XVECEXP
(
newexp
,
1
,
n
)
=
rtx_alloc
(
CONST_STRING
);
XSTR
(
XVECEXP
(
newexp
,
1
,
n
++
),
0
)
=
p
;
}
XVECEXP
(
newexp
,
1
,
n
++
)
=
attr_rtx
(
CONST_STRING
,
p
);
return
convert_set_attr_alternative
(
newexp
,
num_alt
,
insn_code
,
insn_index
);
}
...
...
@@ -616,6 +925,56 @@ check_defs ()
}
}
/* Given a constant SYMBOL_REF expression, convert to a COND that
explicitly tests each enumerated value. */
static
rtx
convert_const_symbol_ref
(
exp
,
attr
)
rtx
exp
;
struct
attr_desc
*
attr
;
{
rtx
condexp
;
struct
attr_value
*
av
;
int
i
;
int
num_alt
=
0
;
for
(
av
=
attr
->
first_value
;
av
;
av
=
av
->
next
)
num_alt
++
;
/* Make a COND with all tests but the last, and in the original order.
Select the last value via the default. Note that the attr values
are constructed in reverse order. */
condexp
=
rtx_alloc
(
COND
);
XVEC
(
condexp
,
0
)
=
rtvec_alloc
((
num_alt
-
1
)
*
2
);
av
=
attr
->
first_value
;
XEXP
(
condexp
,
1
)
=
av
->
value
;
for
(
i
=
num_alt
-
2
;
av
=
av
->
next
,
i
>=
0
;
i
--
)
{
char
*
p
;
rtx
value
;
XVECEXP
(
condexp
,
0
,
2
*
i
)
=
rtx_alloc
(
EQ
);
XEXP
(
XVECEXP
(
condexp
,
0
,
2
*
i
),
0
)
=
exp
;
XEXP
(
XVECEXP
(
condexp
,
0
,
2
*
i
),
1
)
=
value
=
rtx_alloc
(
SYMBOL_REF
);
RTX_UNCHANGING_P
(
value
)
=
1
;
XSTR
(
value
,
0
)
=
p
=
(
char
*
)
xmalloc
(
2
+
strlen
(
attr
->
name
)
+
strlen
(
XSTR
(
av
->
value
,
0
)));
strcpy
(
p
,
attr
->
name
);
strcat
(
p
,
"_"
);
strcat
(
p
,
XSTR
(
av
->
value
,
0
));
for
(;
*
p
!=
'\0'
;
p
++
)
if
(
*
p
>=
'a'
&&
*
p
<=
'z'
)
*
p
-=
'a'
-
'A'
;
XVECEXP
(
condexp
,
0
,
2
*
i
+
1
)
=
av
->
value
;
}
return
condexp
;
}
/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
expressions by converting them into a COND. This removes cases from this
program. Also, replace an attribute value of "*" with the default attribute
...
...
@@ -645,6 +1004,17 @@ make_canonical (attr, exp)
break
;
case
SYMBOL_REF
:
if
(
!
attr
->
is_const
||
RTX_UNCHANGING_P
(
exp
))
break
;
RTX_UNCHANGING_P
(
exp
)
=
1
;
exp
=
convert_const_symbol_ref
(
exp
,
attr
);
check_attr_value
(
exp
,
attr
);
/* Goto COND case since this is now a COND. Note that while the
new expression is rescanned, all symbol_ref notes are mared as
unchanging. */
goto
cond
;
case
IF_THEN_ELSE
:
newexp
=
rtx_alloc
(
COND
);
XVEC
(
newexp
,
0
)
=
rtvec_alloc
(
2
);
...
...
@@ -657,6 +1027,7 @@ make_canonical (attr, exp)
/* Fall through to COND case since this is now a COND. */
case
COND
:
cond
:
/* First, check for degenerate COND. */
if
(
XVECLEN
(
exp
,
0
)
==
0
)
return
make_canonical
(
attr
,
XEXP
(
exp
,
1
));
...
...
@@ -777,40 +1148,33 @@ expand_delays ()
{
for
(
i
=
0
;
i
<
XVECLEN
(
delay
->
def
,
1
);
i
+=
3
)
{
newexp
=
rtx_alloc
(
IF_THEN_ELSE
);
condexp
=
XVECEXP
(
delay
->
def
,
1
,
i
);
if
(
condexp
==
0
)
condexp
=
false_rtx
;
XEXP
(
newexp
,
0
)
=
condexp
;
XEXP
(
newexp
,
1
)
=
make_numeric_value
(
1
);
XEXP
(
newexp
,
2
)
=
make_numeric_value
(
0
);
newexp
=
attr_rtx
(
IF_THEN_ELSE
,
condexp
,
make_numeric_value
(
1
),
make_numeric_value
(
0
));
p
=
(
char
*
)
xmalloc
(
13
);
sprintf
(
p
,
"*delay_%d_%d"
,
delay
->
num
,
i
/
3
);
p
=
attr_printf
(
13
,
"*delay_%d_%d"
,
delay
->
num
,
i
/
3
);
make_internal_attr
(
p
,
newexp
,
1
);
if
(
have_annul_true
)
{
newexp
=
rtx_alloc
(
IF_THEN_ELSE
);
condexp
=
XVECEXP
(
delay
->
def
,
1
,
i
+
1
);
if
(
condexp
==
0
)
condexp
=
false_rtx
;
XEXP
(
newexp
,
0
)
=
condexp
;
XEXP
(
newexp
,
1
)
=
make_numeric_value
(
1
);
XEXP
(
newexp
,
2
)
=
make_numeric_value
(
0
);
p
=
(
char
*
)
xmalloc
(
18
);
sprintf
(
p
,
"*annul_true_%d_%d"
,
delay
->
num
,
i
/
3
);
newexp
=
attr_rtx
(
IF_THEN_ELSE
,
condexp
,
make_numeric_value
(
1
),
make_numeric_value
(
0
));
p
=
attr_printf
(
18
,
"*annul_true_%d_%d"
,
delay
->
num
,
i
/
3
);
make_internal_attr
(
p
,
newexp
,
1
);
}
if
(
have_annul_false
)
{
newexp
=
rtx_alloc
(
IF_THEN_ELSE
);
condexp
=
XVECEXP
(
delay
->
def
,
1
,
i
+
2
);
if
(
condexp
==
0
)
condexp
=
false_rtx
;
XEXP
(
newexp
,
0
)
=
condexp
;
XEXP
(
newexp
,
1
)
=
make_numeric_value
(
1
);
XEXP
(
newexp
,
2
)
=
make_numeric_value
(
0
);
p
=
(
char
*
)
xmalloc
(
18
);
sprintf
(
p
,
"*annul_false_%d_%d"
,
delay
->
num
,
i
/
3
);
newexp
=
attr_rtx
(
IF_THEN_ELSE
,
condexp
,
make_numeric_value
(
1
),
make_numeric_value
(
0
));
p
=
attr_printf
(
18
,
"*annul_false_%d_%d"
,
delay
->
num
,
i
/
3
);
make_internal_attr
(
p
,
newexp
,
1
);
}
}
...
...
@@ -872,12 +1236,9 @@ operate_exp (op, left, right)
else
if
(
GET_CODE
(
right
)
==
IF_THEN_ELSE
)
{
/* Apply recursively to all values within. */
newexp
=
rtx_alloc
(
IF_THEN_ELSE
);
XEXP
(
newexp
,
0
)
=
XEXP
(
right
,
0
);
XEXP
(
newexp
,
1
)
=
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
));
XEXP
(
newexp
,
2
)
=
operate_exp
(
op
,
left
,
XEXP
(
right
,
2
));
return
newexp
;
return
attr_rtx
(
IF_THEN_ELSE
,
XEXP
(
right
,
0
),
operate_exp
(
op
,
left
,
XEXP
(
right
,
1
)),
operate_exp
(
op
,
left
,
XEXP
(
right
,
2
)));
}
else
if
(
GET_CODE
(
right
)
==
COND
)
{
...
...
@@ -901,12 +1262,9 @@ operate_exp (op, left, right)
/* Otherwise, do recursion the other way. */
else
if
(
GET_CODE
(
left
)
==
IF_THEN_ELSE
)
{
newexp
=
rtx_alloc
(
IF_THEN_ELSE
);
XEXP
(
newexp
,
0
)
=
XEXP
(
left
,
0
);
XEXP
(
newexp
,
1
)
=
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
);
XEXP
(
newexp
,
2
)
=
operate_exp
(
op
,
XEXP
(
left
,
2
),
right
);
return
newexp
;
return
attr_rtx
(
IF_THEN_ELSE
,
XEXP
(
left
,
0
),
operate_exp
(
op
,
XEXP
(
left
,
1
),
right
),
operate_exp
(
op
,
XEXP
(
left
,
2
),
right
));
}
else
if
(
GET_CODE
(
left
)
==
COND
)
...
...
@@ -983,14 +1341,13 @@ expand_units ()
for
(
op
=
unit
->
ops
;
op
;
op
=
op
->
next
)
{
str
=
(
char
*
)
xmalloc
(
strlen
(
unit
->
name
)
+
11
);
/* Validate the expressions we were given for the conditions
and busy cost. Then make an attribute for use in the conflict
function. */
op
->
condexp
=
check_attr_test
(
op
->
condexp
);
op
->
condexp
=
check_attr_test
(
op
->
condexp
,
0
);
check_attr_value
(
op
->
busyexp
,
0
);
sprintf
(
str
,
"*%s_case_%d"
,
unit
->
name
,
op
->
num
);
str
=
attr_printf
(
strlen
(
unit
->
name
)
+
11
,
"*%s_case_%d"
,
unit
->
name
,
op
->
num
);
make_internal_attr
(
str
,
make_canonical
(
0
,
op
->
busyexp
));
/* Make our adjustment to the two COND's being computed. If we are
...
...
@@ -1013,17 +1370,16 @@ expand_units ()
}
/* Make an attribute for the case number and ready delay. */
str
=
(
char
*
)
xmalloc
(
strlen
(
unit
->
name
)
+
8
);
sprintf
(
str
,
"*%s_cases"
,
unit
->
name
);
str
=
attr_printf
(
strlen
(
unit
->
name
)
+
8
,
"*%s_cases"
,
unit
->
name
);
make_internal_attr
(
str
,
caseexp
,
1
);
str
=
(
char
*
)
xmalloc
(
strlen
(
unit
->
name
)
+
20
);
sprintf
(
str
,
"*%s_unit_ready_cost"
,
unit
->
name
);
str
=
attr_printf
(
strlen
(
unit
->
name
)
+
20
,
"*%s_unit_ready_cost"
,
unit
->
name
);
make_internal_attr
(
str
,
readyexp
,
0
);
/* Merge this function unit into the ready cost and unit mask
attributes. */
XEXP
(
newexp
,
0
)
=
check_attr_test
(
unit
->
condexp
);
XEXP
(
newexp
,
0
)
=
check_attr_test
(
unit
->
condexp
,
0
);
XEXP
(
newexp
,
1
)
=
make_numeric_value
(
1
<<
unit
->
num
);
unitsmask
=
operate_exp
(
OR_OP
,
unitsmask
,
newexp
);
...
...
@@ -1122,15 +1478,13 @@ substitute_address (exp, no_address_fn, address_fn)
if
(
address_used
)
return
(
*
address_fn
)
(
exp
);
newexp
=
rtx_alloc
(
IF_THEN_ELSE
);
XEXP
(
newexp
,
0
)
=
substitute_address
(
XEXP
(
exp
,
0
),
no_address_fn
,
address_fn
);
XEXP
(
newexp
,
1
)
=
substitute_address
(
XEXP
(
exp
,
1
),
no_address_fn
,
address_fn
);
XEXP
(
newexp
,
2
)
=
substitute_address
(
XEXP
(
exp
,
2
),
no_address_fn
,
address_fn
);
return
newexp
;
return
attr_rtx
(
IF_THEN_ELSE
,
substitute_address
(
XEXP
(
exp
,
0
),
no_address_fn
,
address_fn
),
substitute_address
(
XEXP
(
exp
,
1
),
no_address_fn
,
address_fn
),
substitute_address
(
XEXP
(
exp
,
2
),
no_address_fn
,
address_fn
));
}
return
(
*
no_address_fn
)
(
exp
);
...
...
@@ -1177,6 +1531,7 @@ make_length_attrs ()
if
(
!
length_attr
->
is_numeric
)
fatal
(
"length attribute must be numeric."
);
length_attr
->
is_const
=
0
;
length_attr
->
is_special
=
1
;
/* Make each new attribute, in turn. */
...
...
@@ -1440,17 +1795,14 @@ insert_right_side (code, exp, term, insn_code, insn_index)
if
(
GET_CODE
(
exp
)
==
code
)
{
/* Make a copy of this expression and call recursively. */
newexp
=
rtx_alloc
(
code
);
XEXP
(
newexp
,
0
)
=
XEXP
(
exp
,
0
);
XEXP
(
newexp
,
1
)
=
insert_right_side
(
code
,
XEXP
(
exp
,
1
),
term
,
insn_code
,
insn_index
);
newexp
=
attr_rtx
(
code
,
XEXP
(
exp
,
0
),
insert_right_side
(
code
,
XEXP
(
exp
,
1
),
term
,
insn_code
,
insn_index
));
}
else
{
/* Insert the new term. */
newexp
=
rtx_alloc
(
code
);
XEXP
(
newexp
,
0
)
=
exp
;
XEXP
(
newexp
,
1
)
=
term
;
newexp
=
attr_rtx
(
code
,
exp
,
term
);
}
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
...
...
@@ -1501,12 +1853,9 @@ make_alternative_compare (mask)
for
(
i
=
0
;
(
mask
&
(
1
<<
i
))
==
0
;
i
++
)
;
alternative
=
(
char
*
)
xmalloc
(
3
);
sprintf
(
alternative
,
"%d"
,
i
);
alternative
=
attr_printf
(
3
,
"%d"
,
i
);
newexp
=
rtx_alloc
(
EQ_ATTR
);
XSTR
(
newexp
,
0
)
=
alternative_name
;
XSTR
(
newexp
,
1
)
=
alternative
;
newexp
=
attr_rtx
(
EQ_ATTR
,
alternative_name
,
alternative
);
RTX_UNCHANGING_P
(
newexp
)
=
1
;
return
newexp
;
...
...
@@ -1566,8 +1915,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
insn_code
,
insn_index
);
/* Add this condition into the AND expression. */
newexp
=
rtx_alloc
(
NOT
);
XEXP
(
newexp
,
0
)
=
XVECEXP
(
value
,
0
,
i
);
newexp
=
attr_rtx
(
NOT
,
XVECEXP
(
value
,
0
,
i
));
andexp
=
insert_right_side
(
AND
,
andexp
,
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1624,9 +1972,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
right
=
simplify_and_tree
(
XEXP
(
exp
,
1
),
pterm
,
insn_code
,
insn_index
);
if
(
left
!=
XEXP
(
exp
,
0
)
||
right
!=
XEXP
(
exp
,
1
))
{
newexp
=
rtx_alloc
(
GET_CODE
(
exp
));
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
GET_CODE
(
exp
),
left
,
right
);
exp
=
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1649,9 +1995,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
if
(
left
!=
XEXP
(
exp
,
0
)
||
right
!=
XEXP
(
exp
,
1
))
{
newexp
=
rtx_alloc
(
GET_CODE
(
exp
));
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
GET_CODE
(
exp
),
left
,
right
);
exp
=
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1747,9 +2091,7 @@ simplify_or_tree (exp, pterm, insn_code, insn_index)
right
=
simplify_or_tree
(
XEXP
(
exp
,
1
),
pterm
,
insn_code
,
insn_index
);
if
(
left
!=
XEXP
(
exp
,
0
)
||
right
!=
XEXP
(
exp
,
1
))
{
newexp
=
rtx_alloc
(
GET_CODE
(
exp
));
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
GET_CODE
(
exp
),
left
,
right
);
exp
=
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1772,9 +2114,7 @@ simplify_or_tree (exp, pterm, insn_code, insn_index)
if
(
left
!=
XEXP
(
exp
,
0
)
||
right
!=
XEXP
(
exp
,
1
))
{
newexp
=
rtx_alloc
(
GET_CODE
(
exp
));
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
GET_CODE
(
exp
),
left
,
right
);
exp
=
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1843,12 +2183,9 @@ simplify_test_exp (exp, insn_code, insn_index)
right
=
tem
;
}
newexp
=
rtx_alloc
(
IOR
);
XEXP
(
newexp
,
0
)
=
rtx_alloc
(
AND
);
XEXP
(
newexp
,
1
)
=
rtx_alloc
(
AND
);
XEXP
(
XEXP
(
newexp
,
0
),
0
)
=
XEXP
(
XEXP
(
newexp
,
1
),
0
)
=
left
;
XEXP
(
XEXP
(
newexp
,
0
),
1
)
=
XEXP
(
right
,
0
);
XEXP
(
XEXP
(
newexp
,
1
),
1
)
=
XEXP
(
right
,
1
);
newexp
=
attr_rtx
(
IOR
,
attr_rtx
(
AND
,
left
,
XEXP
(
right
,
0
)),
attr_rtx
(
AND
,
left
,
XEXP
(
right
,
1
)));
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1895,9 +2232,7 @@ simplify_test_exp (exp, insn_code, insn_index)
alternative and we have tested none of them! */
left
=
make_alternative_compare
(
i
);
right
=
simplify_and_tree
(
exp
,
&
left
,
insn_code
,
insn_index
);
newexp
=
rtx_alloc
(
AND
);
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
AND
,
left
,
right
);
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1905,9 +2240,7 @@ simplify_test_exp (exp, insn_code, insn_index)
if
(
left
!=
XEXP
(
exp
,
0
)
||
right
!=
XEXP
(
exp
,
1
))
{
newexp
=
rtx_alloc
(
AND
);
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
AND
,
left
,
right
);
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
break
;
...
...
@@ -1937,15 +2270,11 @@ simplify_test_exp (exp, insn_code, insn_index)
else
if
(
GET_CODE
(
left
)
==
AND
&&
GET_CODE
(
right
)
==
AND
&&
rtx_equal_p
(
XEXP
(
left
,
0
),
XEXP
(
right
,
0
)))
{
newexp
=
rtx_alloc
(
IOR
);
XEXP
(
newexp
,
0
)
=
XEXP
(
left
,
1
);
XEXP
(
newexp
,
1
)
=
XEXP
(
right
,
1
);
newexp
=
attr_rtx
(
IOR
,
XEXP
(
left
,
1
),
XEXP
(
right
,
1
));
left
=
XEXP
(
left
,
0
);
right
=
newexp
;
newexp
=
rtx_alloc
(
AND
);
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
AND
,
left
,
right
);
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1977,10 +2306,7 @@ simplify_test_exp (exp, insn_code, insn_index)
alternative and we have tested none of them! */
left
=
make_alternative_compare
(
i
);
right
=
simplify_and_tree
(
exp
,
&
left
,
insn_code
,
insn_index
);
newexp
=
rtx_alloc
(
IOR
);
XEXP
(
newexp
,
0
)
=
rtx_alloc
(
NOT
);
XEXP
(
XEXP
(
newexp
,
0
),
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
IOR
,
attr_rtx
(
NOT
,
left
),
right
);
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
...
...
@@ -1988,9 +2314,7 @@ simplify_test_exp (exp, insn_code, insn_index)
if
(
left
!=
XEXP
(
exp
,
0
)
||
right
!=
XEXP
(
exp
,
1
))
{
newexp
=
rtx_alloc
(
IOR
);
XEXP
(
newexp
,
0
)
=
left
;
XEXP
(
newexp
,
1
)
=
right
;
newexp
=
attr_rtx
(
IOR
,
left
,
right
);
return
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
break
;
...
...
@@ -2008,28 +2332,23 @@ simplify_test_exp (exp, insn_code, insn_index)
/* Try to apply De`Morgan's laws. */
else
if
(
GET_CODE
(
left
)
==
IOR
)
{
newexp
=
rtx_alloc
(
AND
);
XEXP
(
newexp
,
0
)
=
rtx_alloc
(
NOT
);
XEXP
(
XEXP
(
newexp
,
0
),
0
)
=
XEXP
(
left
,
0
);
XEXP
(
newexp
,
1
)
=
rtx_alloc
(
NOT
);
XEXP
(
XEXP
(
newexp
,
1
),
0
)
=
XEXP
(
left
,
1
);
newexp
=
attr_rtx
(
AND
,
attr_rtx
(
NOT
,
XEXP
(
left
,
0
)),
attr_rtx
(
NOT
,
XEXP
(
left
,
1
)));
newexp
=
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
else
if
(
GET_CODE
(
left
)
==
AND
)
{
newexp
=
rtx_alloc
(
IOR
);
XEXP
(
newexp
,
0
)
=
rtx_alloc
(
NOT
);
XEXP
(
XEXP
(
newexp
,
0
),
0
)
=
XEXP
(
left
,
0
);
XEXP
(
newexp
,
1
)
=
rtx_alloc
(
NOT
);
XEXP
(
XEXP
(
newexp
,
1
),
0
)
=
XEXP
(
left
,
1
);
newexp
=
attr_rtx
(
IOR
,
attr_rtx
(
NOT
,
XEXP
(
left
,
0
)),
attr_rtx
(
NOT
,
XEXP
(
left
,
1
)));
newexp
=
SIMPLIFY_TEST_EXP
(
newexp
,
insn_code
,
insn_index
);
}
else
if
(
left
!=
XEXP
(
exp
,
0
))
{
newexp
=
rtx_alloc
(
NOT
);
XEXP
(
newexp
,
0
)
=
left
;
newexp
=
attr_rtx
(
NOT
,
left
);
}
break
;
...
...
@@ -2117,8 +2436,7 @@ gen_attr (exp)
while
((
p
=
next_comma_elt
(
&
name_ptr
))
!=
NULL
)
{
av
=
(
struct
attr_value
*
)
xmalloc
(
sizeof
(
struct
attr_value
));
av
->
value
=
rtx_alloc
(
CONST_STRING
);
XSTR
(
av
->
value
,
0
)
=
p
;
av
->
value
=
attr_rtx
(
CONST_STRING
,
p
);
av
->
next
=
attr
->
first_value
;
attr
->
first_value
=
av
;
av
->
first_insn
=
NULL
;
...
...
@@ -2127,6 +2445,15 @@ gen_attr (exp)
}
}
if
(
GET_CODE
(
XEXP
(
exp
,
2
))
==
CONST
)
{
attr
->
is_const
=
1
;
if
(
attr
->
is_numeric
)
fatal
(
"Constant attributes may not take numeric values"
);
/* Get rid of the CONST node. It is allowed only at top-level. */
XEXP
(
exp
,
2
)
=
XEXP
(
XEXP
(
exp
,
2
),
0
);
}
if
(
!
strcmp
(
attr
->
name
,
"length"
)
&&
!
attr
->
is_numeric
)
fatal
(
"`length' attribute must take numeric values"
);
...
...
@@ -2370,10 +2697,9 @@ gen_unit (def)
for
(
i
=
0
;
i
<
XVECLEN
(
def
,
6
);
i
++
)
orexp
=
insert_right_side
(
IOR
,
orexp
,
XVECEXP
(
def
,
6
,
i
),
-
2
);
op
->
busyexp
=
rtx_alloc
(
IF_THEN_ELSE
);
XEXP
(
op
->
busyexp
,
0
)
=
orexp
;
XEXP
(
op
->
busyexp
,
1
)
=
make_numeric_value
(
XINT
(
def
,
5
));
XEXP
(
op
->
busyexp
,
2
)
=
make_numeric_value
(
0
);
op
->
busyexp
=
attr_rtx
(
IF_THEN_ELSE
,
orexp
,
make_numeric_value
(
XINT
(
def
,
5
)),
make_numeric_value
(
0
));
}
else
op
->
busyexp
=
make_numeric_value
(
XINT
(
def
,
5
));
...
...
@@ -2646,8 +2972,11 @@ walk_attr_value (exp)
switch
(
code
)
{
case
SYMBOL_REF
:
/* Since this is an arbitrary expression, it can look at anything. */
must_extract
=
must_constrain
=
1
;
if
(
!
RTX_UNCHANGING_P
(
exp
))
/* Since this is an arbitrary expression, it can look at anything.
However, constant expressions do not depend on any particular
insn. */
must_extract
=
must_constrain
=
1
;
return
;
case
MATCH_OPERAND
:
...
...
@@ -2704,8 +3033,22 @@ write_attr_get (attr)
the subroutine to use, instead of `get_attr_...'. */
if
(
attr
->
name
[
0
]
==
'*'
)
printf
(
"%s (insn)
\n
"
,
&
attr
->
name
[
1
]);
else
else
if
(
attr
->
is_const
==
0
)
printf
(
"get_attr_%s (insn)
\n
"
,
attr
->
name
);
else
{
printf
(
"get_attr_%s ()
\n
"
,
attr
->
name
);
printf
(
"{
\n
"
);
for
(
av
=
attr
->
first_value
;
av
;
av
=
av
->
next
)
if
(
av
->
num_insns
!=
0
)
write_attr_set
(
attr
,
2
,
av
->
value
,
"return"
,
";"
,
true_rtx
,
av
->
first_insn
->
insn_code
,
av
->
first_insn
->
insn_index
);
printf
(
"}
\n\n
"
);
return
;
}
printf
(
" rtx insn;
\n
"
);
printf
(
"{
\n
"
);
printf
(
" switch (recog_memoized (insn))
\n
"
);
...
...
@@ -2791,8 +3134,7 @@ write_attr_set (attr, indent, value, prefix, suffix, known_true,
testexp
=
eliminate_known_true
(
our_known_true
,
XVECEXP
(
value
,
0
,
i
),
insn_code
,
insn_index
);
newexp
=
rtx_alloc
(
NOT
);
XEXP
(
newexp
,
0
)
=
testexp
;
newexp
=
attr_rtx
(
NOT
,
testexp
);
newexp
=
insert_right_side
(
AND
,
our_known_true
,
newexp
,
insn_code
,
insn_index
);
...
...
@@ -3123,7 +3465,7 @@ write_function_unit_info ()
{
/* See if only one case exists and if there is a constant value for
that case. If so, we don't need a function. */
str
=
(
char
*
)
xmalloc
(
strlen
(
unit
->
name
)
+
10
);
str
=
(
char
*
)
alloca
(
strlen
(
unit
->
name
)
+
10
);
sprintf
(
str
,
"*%s_cases"
,
unit
->
name
);
attr
=
find_attr
(
str
,
0
);
if
(
!
attr
)
abort
();
...
...
@@ -3282,11 +3624,9 @@ next_comma_elt (pstr)
for
(
p
=
*
pstr
;
*
p
!=
','
&&
*
p
!=
'\0'
;
p
++
)
;
out_str
=
(
char
*
)
xmalloc
(
p
-
*
pstr
+
1
);
for
(
p
=
out_str
;
**
pstr
!=
','
&&
**
pstr
!=
'\0'
;
(
*
pstr
)
++
)
*
p
++
=
**
pstr
;
out_str
=
attr_string
(
*
pstr
,
p
-
*
pstr
);
*
pstr
=
p
;
*
p
++
=
'\0'
;
if
(
**
pstr
==
','
)
(
*
pstr
)
++
;
...
...
@@ -3327,7 +3667,7 @@ find_attr (name, create)
attr
=
(
struct
attr_desc
*
)
xmalloc
(
sizeof
(
struct
attr_desc
));
attr
->
name
=
new_name
;
attr
->
first_value
=
attr
->
default_val
=
NULL
;
attr
->
is_numeric
=
attr
->
is_special
=
0
;
attr
->
is_numeric
=
attr
->
is_
const
=
attr
->
is_
special
=
0
;
attr
->
next
=
attrs
;
attrs
=
attr
;
...
...
@@ -3349,6 +3689,7 @@ make_internal_attr (name, value, special)
abort
();
attr
->
is_numeric
=
1
;
attr
->
is_const
=
0
;
attr
->
is_special
=
special
;
attr
->
default_val
=
get_attr_value
(
value
,
attr
,
-
2
);
}
...
...
@@ -3404,6 +3745,7 @@ make_numeric_value (n)
{
static
rtx
int_values
[
20
];
rtx
exp
;
char
*
p
;
if
(
n
<
0
)
abort
();
...
...
@@ -3411,10 +3753,8 @@ make_numeric_value (n)
if
(
n
<
20
&&
int_values
[
n
])
return
int_values
[
n
];
exp
=
rtx_alloc
(
CONST_STRING
);
XSTR
(
exp
,
0
)
=
(
char
*
)
xmalloc
((
n
<
1000
?
4
:
HOST_BITS_PER_INT
*
3
/
10
+
3
));
sprintf
(
XSTR
(
exp
,
0
),
"%d"
,
n
);
p
=
attr_printf
((
n
<
1000
?
4
:
HOST_BITS_PER_INT
*
3
/
10
+
3
),
"%d"
,
n
);
exp
=
attr_rtx
(
CONST_STRING
,
p
);
if
(
n
<
20
)
int_values
[
n
]
=
exp
;
...
...
@@ -3492,10 +3832,8 @@ main (argc, argv)
init_rtl
();
/* Set up true and false rtx's */
true_rtx
=
rtx_alloc
(
CONST_INT
);
false_rtx
=
rtx_alloc
(
CONST_INT
);
XINT
(
true_rtx
,
0
)
=
1
;
XINT
(
false_rtx
,
0
)
=
0
;
true_rtx
=
attr_rtx
(
CONST_INT
,
1
);
false_rtx
=
attr_rtx
(
CONST_INT
,
0
);
RTX_UNCHANGING_P
(
true_rtx
)
=
RTX_UNCHANGING_P
(
false_rtx
)
=
1
;
printf
(
"/* Generated automatically by the program `genattrtab'
\n
\
...
...
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