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
35016322
Commit
35016322
authored
Apr 18, 1992
by
Jim Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r788
parent
56a2f049
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
185 additions
and
0 deletions
+185
-0
gcc/config/sparc/sparc.c
+101
-0
gcc/config/sparc/sparc.md
+84
-0
No files found.
gcc/config/sparc/sparc.c
View file @
35016322
...
...
@@ -2250,6 +2250,107 @@ output_arc_profiler (arcno, insert_after)
emit_insn_after
(
gen_rtx
(
SET
,
VOIDmode
,
mem_ref
,
profiler_reg
),
insert_after
);
}
/* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1.
This makes them candidates for using ldd and std insns.
Note reg1 and reg2 *must* be hard registers. To be sure we will
abort if we are passed pseudo registers. */
int
registers_ok_for_ldd
(
reg1
,
reg2
)
rtx
reg1
,
reg2
;
{
/* We might have been passed a SUBREG. */
if
(
GET_CODE
(
reg1
)
!=
REG
||
GET_CODE
(
reg2
)
!=
REG
)
return
0
;
/* Should never happen. */
if
(
REGNO
(
reg1
)
>
FIRST_PSEUDO_REGISTER
||
REGNO
(
reg2
)
>
FIRST_PSEUDO_REGISTER
)
abort
();
if
(
REGNO
(
reg1
)
%
2
!=
0
)
return
0
;
return
(
REGNO
(
reg1
)
==
REGNO
(
reg2
)
-
1
);
}
/* Return 1 if addr1 and addr2 are suitable for use in an ldd or
std insn.
This can only happen when addr1 and addr2 are consecutive memory
locations (addr1 + 4 == addr2). addr1 must also be aligned on a
64 bit boundary (addr1 % 8 == 0).
We know %sp and %fp are kept aligned on a 64 bit boundary. Other
registers are assumed to *never* be properly aligned and are
rejected.
Knowing %sp and %fp are kept aligned on a 64 bit boundary, we
need only check that the offset for addr1 % 8 == 0. */
int
memory_ok_for_ldd
(
addr1
,
addr2
)
rtx
addr1
,
addr2
;
{
int
reg1
,
offset1
;
/* Extract a register number and offset (if used) from the first addr. */
if
(
GET_CODE
(
addr1
)
==
PLUS
)
{
/* If not a REG, return zero. */
if
(
GET_CODE
(
XEXP
(
addr1
,
0
))
!=
REG
)
return
0
;
else
{
reg1
=
REGNO
(
XEXP
(
addr1
,
0
));
/* The offset must be constant! */
if
(
GET_CODE
(
XEXP
(
addr1
,
1
))
!=
CONST_INT
)
return
0
;
offset1
=
INTVAL
(
XEXP
(
addr1
,
1
));
}
}
else
if
(
GET_CODE
(
addr1
)
!=
REG
)
return
0
;
else
{
reg1
=
REGNO
(
addr1
);
/* This was a simple (mem (reg)) expression. Offset is 0. */
offset1
=
0
;
}
/* Make sure the second address is a (mem (plus (reg) (const_int). */
if
(
GET_CODE
(
addr2
)
!=
PLUS
)
return
0
;
if
(
GET_CODE
(
XEXP
(
addr2
,
0
))
!=
REG
||
GET_CODE
(
XEXP
(
addr2
,
1
))
!=
CONST_INT
)
return
0
;
/* Only %fp and %sp are allowed. Additionally both addresses must
use the same register. */
if
(
reg1
!=
FRAME_POINTER_REGNUM
&&
reg1
!=
STACK_POINTER_REGNUM
)
return
0
;
if
(
reg1
!=
REGNO
(
XEXP
(
addr2
,
0
)))
return
0
;
/* The first offset must be evenly divisable by 8 to ensure the
address is 64 bit aligned. */
if
(
offset1
%
8
!=
0
)
return
0
;
/* The offset for the second addr must be 4 more than the first addr. */
if
(
INTVAL
(
XEXP
(
addr2
,
1
))
!=
offset1
+
4
)
return
0
;
/* All the tests passed. addr1 and addr2 are valid for ldd and std
instructions. */
return
1
;
}
/* Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
...
...
gcc/config/sparc/sparc.md
View file @
35016322
...
...
@@ -2584,6 +2584,90 @@
;; Peepholes go at the end.
;; Optimize consecutive loads or stores into ldd and std when possible.
;; The conditions in which we do this are very restricted and are
;; explained in the code for {registers,memory}_ok_for_ldd functions.
(define_peephole
[
(set (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "memory_operand" ""))
(set (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd (operands
[
0
]
, operands
[
2
]
)
&& ! MEM_VOLATILE_P (operands
[
1
]
) && ! MEM_VOLATILE_P (operands
[
3
]
)
&& memory_ok_for_ldd (XEXP (operands
[
1
]
, 0), XEXP (operands
[
3
]
, 0))"
"ldd %1,%0")
(define_peephole
[
(set (match_operand:SI 0 "memory_operand" "")
(match_operand:SI 1 "register_operand" "r"))
(set (match_operand:SI 2 "memory_operand" "")
(match_operand:SI 3 "register_operand" "r"))]
"registers_ok_for_ldd (operands
[
1
]
, operands
[
3
]
)
&& ! MEM_VOLATILE_P (operands
[
0
]
) && ! MEM_VOLATILE_P (operands
[
2
]
)
&& memory_ok_for_ldd (XEXP (operands
[
0
]
, 0), XEXP (operands
[
2
]
, 0))"
"std %1,%0")
(define_peephole
[
(set (match_operand:SF 0 "register_operand" "fr")
(match_operand:SF 1 "memory_operand" ""))
(set (match_operand:SF 2 "register_operand" "fr")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd (operands
[
0
]
, operands
[
2
]
)
&& ! MEM_VOLATILE_P (operands
[
1
]
) && ! MEM_VOLATILE_P (operands
[
3
]
)
&& memory_ok_for_ldd (XEXP (operands
[
1
]
, 0), XEXP (operands
[
3
]
, 0))"
"ldd %1,%0")
(define_peephole
[
(set (match_operand:SF 0 "memory_operand" "")
(match_operand:SF 1 "register_operand" "fr"))
(set (match_operand:SF 2 "memory_operand" "")
(match_operand:SF 3 "register_operand" "fr"))]
"registers_ok_for_ldd (operands
[
1
]
, operands
[
3
]
)
&& ! MEM_VOLATILE_P (operands
[
0
]
) && ! MEM_VOLATILE_P (operands
[
2
]
)
&& memory_ok_for_ldd (XEXP (operands
[
0
]
, 0), XEXP (operands
[
2
]
, 0))"
"std %1,%0")
(define_peephole
[
(set (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "memory_operand" ""))
(set (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd (operands
[
2
]
, operands
[
0
]
)
&& ! MEM_VOLATILE_P (operands
[
3
]
) && ! MEM_VOLATILE_P (operands
[
1
]
)
&& memory_ok_for_ldd (XEXP (operands
[
3
]
, 0), XEXP (operands
[
1
]
, 0))"
"ldd %3,%2")
(define_peephole
[
(set (match_operand:SI 0 "memory_operand" "")
(match_operand:SI 1 "register_operand" "r"))
(set (match_operand:SI 2 "memory_operand" "")
(match_operand:SI 3 "register_operand" "r"))]
"registers_ok_for_ldd (operands
[
3
]
, operands
[
1
]
)
&& ! MEM_VOLATILE_P (operands
[
2
]
) && ! MEM_VOLATILE_P (operands
[
0
]
)
&& memory_ok_for_ldd (XEXP (operands
[
2
]
, 0), XEXP (operands
[
0
]
, 0))"
"std %3,%2")
(define_peephole
[
(set (match_operand:SF 0 "register_operand" "fr")
(match_operand:SF 1 "memory_operand" ""))
(set (match_operand:SF 2 "register_operand" "fr")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd (operands
[
2
]
, operands
[
0
]
)
&& ! MEM_VOLATILE_P (operands
[
3
]
) && ! MEM_VOLATILE_P (operands
[
1
]
)
&& memory_ok_for_ldd (XEXP (operands
[
3
]
, 0), XEXP (operands
[
1
]
, 0))"
"ldd %3,%2")
(define_peephole
[
(set (match_operand:SF 0 "memory_operand" "")
(match_operand:SF 1 "register_operand" "fr"))
(set (match_operand:SF 2 "memory_operand" "")
(match_operand:SF 3 "register_operand" "fr"))]
"registers_ok_for_ldd (operands
[
3
]
, operands
[
1
]
)
&& ! MEM_VOLATILE_P (operands
[
2
]
) && ! MEM_VOLATILE_P (operands
[
0
]
)
&& memory_ok_for_ldd (XEXP (operands
[
2
]
, 0), XEXP (operands
[
0
]
, 0))"
"std %3,%2")
;; Optimize the case of following a reg-reg move with a test
;; of reg just moved.
...
...
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