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
d3797078
Commit
d3797078
authored
Apr 18, 1992
by
Richard Stallman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
entered into RCS
From-SVN: r782
parent
e1fde2b5
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
300 additions
and
0 deletions
+300
-0
gcc/config/vax/vax.c
+300
-0
No files found.
gcc/config/vax/vax.c
View file @
d3797078
...
...
@@ -276,3 +276,303 @@ rev_cond_name (op)
abort
();
}
}
int
vax_float_literal
(
c
)
register
rtx
c
;
{
register
enum
machine_mode
mode
;
int
i
;
union
{
double
d
;
int
i
[
2
];}
val
;
if
(
GET_CODE
(
c
)
!=
CONST_DOUBLE
)
return
0
;
mode
=
GET_MODE
(
c
);
if
(
c
==
const_tiny_rtx
[(
int
)
mode
][
0
]
||
c
==
const_tiny_rtx
[(
int
)
mode
][
1
]
||
c
==
const_tiny_rtx
[(
int
)
mode
][
2
])
return
1
;
#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
val
.
i
[
0
]
=
CONST_DOUBLE_LOW
(
c
);
val
.
i
[
1
]
=
CONST_DOUBLE_HIGH
(
c
);
for
(
i
=
0
;
i
<
7
;
i
++
)
if
(
val
.
d
==
1
<<
i
||
val
.
d
==
1
/
(
1
<<
i
))
return
1
;
#endif
return
0
;
}
/* Return the cost in cycles of a memory address, relative to register
indirect.
Each of the following adds the indicated number of cycles:
1 - symbolic address
1 - pre-decrement
1 - indexing and/or offset(register)
2 - indirect */
int
vax_address_cost
(
addr
)
register
rtx
addr
;
{
int
reg
=
0
,
indexed
=
0
,
indir
=
0
,
offset
=
0
,
predec
=
0
;
rtx
plus_op0
=
0
,
plus_op1
=
0
;
restart
:
switch
(
GET_CODE
(
addr
))
{
case
PRE_DEC
:
predec
=
1
;
case
REG
:
case
SUBREG
:
case
POST_INC
:
reg
=
1
;
break
;
case
MULT
:
indexed
=
1
;
/* 2 on VAX 2 */
break
;
case
CONST_INT
:
/* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
if
(
offset
==
0
)
offset
=
(
unsigned
)(
INTVAL
(
addr
)
+
128
)
>
256
;
break
;
case
CONST
:
case
SYMBOL_REF
:
offset
=
1
;
/* 2 on VAX 2 */
break
;
case
LABEL_REF
:
/* this is probably a byte offset from the pc */
if
(
offset
==
0
)
offset
=
1
;
break
;
case
PLUS
:
if
(
plus_op0
)
plus_op1
=
XEXP
(
addr
,
0
);
else
plus_op0
=
XEXP
(
addr
,
0
);
addr
=
XEXP
(
addr
,
1
);
goto
restart
;
case
MEM
:
indir
=
2
;
/* 3 on VAX 2 */
addr
=
XEXP
(
addr
,
0
);
goto
restart
;
}
/* Up to 3 things can be added in an address. They are stored in
plus_op0, plus_op1, and addr. */
if
(
plus_op0
)
{
addr
=
plus_op0
;
plus_op0
=
0
;
goto
restart
;
}
if
(
plus_op1
)
{
addr
=
plus_op1
;
plus_op1
=
0
;
goto
restart
;
}
/* Indexing and register+offset can both be used (except on a VAX 2)
without increasing execution time over either one alone. */
if
(
reg
&&
indexed
&&
offset
)
return
reg
+
indir
+
offset
+
predec
;
return
reg
+
indexed
+
indir
+
offset
+
predec
;
}
/* Cost of an expression on a VAX. This version has costs tuned for the
CVAX chip (found in the VAX 3 series) with comments for variations on
other models. */
int
vax_rtx_cost
(
x
)
register
rtx
x
;
{
register
enum
rtx_code
code
=
GET_CODE
(
x
);
enum
machine_mode
mode
=
GET_MODE
(
x
);
register
int
c
;
int
i
=
0
;
/* may be modified in switch */
char
*
fmt
=
GET_RTX_FORMAT
(
code
);
/* may be modified in switch */
switch
(
code
)
{
case
POST_INC
:
return
2
;
case
PRE_DEC
:
return
3
;
case
MULT
:
switch
(
mode
)
{
case
DFmode
:
c
=
16
;
/* 4 on VAX 9000 */
break
;
case
SFmode
:
c
=
9
;
/* 4 on VAX 9000, 12 on VAX 2 */
break
;
case
DImode
:
c
=
16
;
/* 6 on VAX 9000, 28 on VAX 2 */
break
;
case
SImode
:
case
HImode
:
case
QImode
:
c
=
10
;
/* 3-4 on VAX 9000, 20-28 on VAX 2 */
break
;
}
break
;
case
UDIV
:
c
=
17
;
break
;
case
DIV
:
if
(
mode
==
DImode
)
c
=
30
;
/* highly variable */
else
if
(
mode
==
DFmode
)
/* divide takes 28 cycles if the result is not zero, 13 otherwise */
c
=
24
;
else
c
=
11
;
/* 25 on VAX 2 */
break
;
case
MOD
:
c
=
23
;
break
;
case
UMOD
:
c
=
29
;
break
;
case
FLOAT
:
c
=
6
+
(
mode
==
DFmode
)
+
(
GET_MODE
(
XEXP
(
x
,
0
))
!=
SImode
);
/* 4 on VAX 9000 */
break
;
case
FIX
:
c
=
7
;
/* 17 on VAX 2 */
break
;
case
LSHIFT
:
case
ASHIFT
:
case
LSHIFTRT
:
case
ASHIFTRT
:
if
(
mode
==
DImode
)
c
=
12
;
else
c
=
10
;
/* 6 on VAX 9000 */
break
;
case
ROTATE
:
case
ROTATERT
:
c
=
6
;
/* 5 on VAX 2, 4 on VAX 9000 */
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
CONST_INT
)
fmt
=
"e"
;
/* all constant rotate counts are short */
break
;
case
PLUS
:
/* Check for small negative integer operand: subl2 can be used with
a short positive constant instead. */
if
(
GET_CODE
(
XEXP
(
x
,
1
))
==
CONST_INT
)
if
((
unsigned
)(
INTVAL
(
XEXP
(
x
,
1
))
+
63
)
<
127
)
fmt
=
"e"
;
case
MINUS
:
c
=
(
mode
==
DFmode
)
?
13
:
8
;
/* 6/8 on VAX 9000, 16/15 on VAX 2 */
case
IOR
:
case
XOR
:
c
=
3
;
break
;
case
AND
:
/* AND is special because the first operand is complemented. */
c
=
3
;
if
(
GET_CODE
(
XEXP
(
x
,
0
))
==
CONST_INT
)
{
if
((
unsigned
)
~
INTVAL
(
XEXP
(
x
,
0
))
>
63
)
c
=
4
;
fmt
=
"e"
;
i
=
1
;
}
break
;
case
NEG
:
if
(
mode
==
DFmode
)
return
9
;
else
if
(
mode
==
SFmode
)
return
6
;
else
if
(
mode
==
DImode
)
return
4
;
case
NOT
:
return
2
;
case
ZERO_EXTRACT
:
case
SIGN_EXTRACT
:
c
=
15
;
break
;
case
MEM
:
if
(
mode
==
DImode
||
mode
==
DFmode
)
c
=
5
;
/* 7 on VAX 2 */
else
c
=
3
;
/* 4 on VAX 2 */
x
=
XEXP
(
x
,
0
);
if
(
GET_CODE
(
x
)
==
REG
||
GET_CODE
(
x
)
==
POST_INC
)
return
c
;
return
c
+
vax_address_cost
(
x
);
default
:
c
=
3
;
break
;
}
/* Now look inside the expression. Operands which are not registers or
short constants add to the cost.
FMT and I may have been adjusted in the switch above for instructions
which require special handling */
while
(
*
fmt
++
==
'e'
)
{
register
rtx
op
=
XEXP
(
x
,
i
++
);
code
=
GET_CODE
(
op
);
/* A NOT is likely to be found as the first operand of an AND
(in which case the relevant cost is of the operand inside
the not) and not likely to be found anywhere else. */
if
(
code
==
NOT
)
op
=
XEXP
(
op
,
0
),
code
=
GET_CODE
(
op
);
switch
(
code
)
{
case
CONST_INT
:
if
((
unsigned
)
INTVAL
(
op
)
>
63
&&
GET_MODE
(
x
)
!=
QImode
)
c
+=
1
;
/* 2 on VAX 2 */
break
;
case
CONST
:
case
LABEL_REF
:
case
SYMBOL_REF
:
c
+=
1
;
/* 2 on VAX 2 */
break
;
case
CONST_DOUBLE
:
if
(
GET_MODE_CLASS
(
GET_MODE
(
op
))
==
MODE_FLOAT
)
{
/* Registers are faster than floating point constants -- even
those constants which can be encoded in a single byte. */
if
(
vax_float_literal
(
op
))
c
++
;
else
c
+=
(
GET_MODE
(
x
)
==
DFmode
)
?
3
:
2
;
}
else
{
if
(
CONST_DOUBLE_HIGH
(
op
)
!=
0
||
(
unsigned
)
CONST_DOUBLE_LOW
(
op
)
>
63
)
c
+=
2
;
}
break
;
case
MEM
:
c
+=
1
;
/* 2 on VAX 2 */
if
(
GET_CODE
(
XEXP
(
op
,
0
))
!=
REG
)
c
+=
vax_address_cost
(
XEXP
(
op
,
0
));
break
;
case
REG
:
case
SUBREG
:
break
;
default
:
c
+=
1
;
break
;
}
}
return
c
;
}
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