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
c5defebb
Commit
c5defebb
authored
Apr 05, 1992
by
Richard Kenner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r691
parent
5f61baa4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
9 deletions
+78
-9
gcc/config/rs6000/rs6000.c
+17
-0
gcc/config/rs6000/rs6000.h
+12
-8
gcc/config/rs6000/rs6000.md
+49
-1
No files found.
gcc/config/rs6000/rs6000.c
View file @
c5defebb
...
@@ -516,6 +516,9 @@ scc_comparison_operator (op, mode)
...
@@ -516,6 +516,9 @@ scc_comparison_operator (op, mode)
&&
(
cc_mode
!=
CCUNSmode
))
&&
(
cc_mode
!=
CCUNSmode
))
return
0
;
return
0
;
if
(
cc_mode
==
CCEQmode
&&
code
!=
EQ
&&
code
!=
NE
)
return
0
;
return
1
;
return
1
;
}
}
...
@@ -607,6 +610,12 @@ ccr_bit (op, scc_p)
...
@@ -607,6 +610,12 @@ ccr_bit (op, scc_p)
cc_regnum
=
REGNO
(
XEXP
(
op
,
0
));
cc_regnum
=
REGNO
(
XEXP
(
op
,
0
));
base_bit
=
4
*
(
cc_regnum
-
68
);
base_bit
=
4
*
(
cc_regnum
-
68
);
/* In CCEQmode cases we have made sure that the result is always in the
third bit of the CR field. */
if
(
cc_mode
==
CCEQmode
)
return
base_bit
+
3
;
switch
(
code
)
switch
(
code
)
{
{
case
NE
:
case
NE
:
...
@@ -817,6 +826,14 @@ print_operand (file, x, code)
...
@@ -817,6 +826,14 @@ print_operand (file, x, code)
fprintf
(
file
,
"%d"
,
32
-
4
*
(
REGNO
(
x
)
-
68
));
fprintf
(
file
,
"%d"
,
32
-
4
*
(
REGNO
(
x
)
-
68
));
return
;
return
;
case
'E'
:
/* X is a CR register. Print the number of the third bit of the CR */
if
(
GET_CODE
(
x
)
!=
REG
||
!
CR_REGNO_P
(
REGNO
(
x
)))
output_operand_lossage
(
"invalid %%E value"
);
fprintf
(
file
,
"%d"
,
4
*
(
REGNO
(
x
)
-
68
)
+
3
);
break
;
case
'R'
:
case
'R'
:
/* X is a CR register. Print the mask for `mtcrf'. */
/* X is a CR register. Print the mask for `mtcrf'. */
if
(
GET_CODE
(
x
)
!=
REG
||
!
CR_REGNO_P
(
REGNO
(
x
)))
if
(
GET_CODE
(
x
)
!=
REG
||
!
CR_REGNO_P
(
REGNO
(
x
)))
...
...
gcc/config/rs6000/rs6000.h
View file @
c5defebb
...
@@ -1245,22 +1245,26 @@ struct rs6000_args {int words, fregno, nargs_prototype; };
...
@@ -1245,22 +1245,26 @@ struct rs6000_args {int words, fregno, nargs_prototype; };
/* Add any extra modes needed to represent the condition code.
/* Add any extra modes needed to represent the condition code.
For the RS/6000, we need separate modes when unsigned (logical) comparisons
For the RS/6000, we need separate modes when unsigned (logical) comparisons
are being done and we need a separate mode for floating-point. */
are being done and we need a separate mode for floating-point. We also
use a mode for the case when we are comparing the results of two
comparisons. */
#define EXTRA_CC_MODES CCUNSmode, CCFPmode
#define EXTRA_CC_MODES CCUNSmode, CCFPmode
, CCEQmode
/* Define the names for the modes specified above. */
/* Define the names for the modes specified above. */
#define EXTRA_CC_NAMES "CCUNS", "CCFP"
#define EXTRA_CC_NAMES "CCUNS", "CCFP"
, "CCEQ"
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. For floating-point, CCFPmode
return the mode to be used for the comparison. For floating-point, CCFPmode
should be used. CC_NOOVmode should be used when the first operand is a
should be used. CCUNSmode should be used for unsigned comparisons.
PLUS, MINUS, or NEG. CCmode should be used when no special processing is
CCEQmode should be used when we are doing an inequality comparison on
needed. */
the result of a comparison. CCmode should be used in all other cases. */
#define SELECT_CC_MODE(OP,X) \
#define SELECT_CC_MODE(OP,X) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode \
: ((OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU \
: (OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU ? CCUNSmode \
? CCUNSmode : CCmode))
: (((OP) == EQ || (OP) == NE) && GET_RTX_CLASS (GET_CODE (X)) == '<' \
? CCEQmode : CCmode))
/* Define the information needed to generate branch and scc insns. This is
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. Note that we can't use "rtx" here
stored from the compare operation. Note that we can't use "rtx" here
...
...
gcc/config/rs6000/rs6000.md
View file @
c5defebb
...
@@ -3294,7 +3294,9 @@
...
@@ -3294,7 +3294,9 @@
;; way the machine works.
;; way the machine works.
;;
;;
;; Note that this is probably faster if we can put an insn between the
;; Note that this is probably faster if we can put an insn between the
;; mfcr and rlinm, but this is tricky. Let's leave it for now.
;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
;; cases the insns below which don't use an intermediate CR field will
;; be used instead.
(define_insn ""
(define_insn ""
[
(set (match_operand:SI 0 "gen_reg_operand" "=r")
[
(set (match_operand:SI 0 "gen_reg_operand" "=r")
(match_operator:SI 1 "scc_comparison_operator"
(match_operator:SI 1 "scc_comparison_operator"
...
@@ -3369,6 +3371,52 @@
...
@@ -3369,6 +3371,52 @@
}"
}"
[
(set_attr "type" "delayed_compare")
]
)
[
(set_attr "type" "delayed_compare")
]
)
;; If we are comparing the result of two comparisons, this can be done
;; using creqv or crxor.
(define_insn ""
[
(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
(compare:CCEQ (match_operator 1 "scc_comparison_operator"
[
(match_operand 2 "cc_reg_operand" "y")
(const_int 0)])
(match_operator 3 "scc_comparison_operator"
[
(match_operand 4 "cc_reg_operand" "y")
(const_int 0)])))]
"REGNO (operands
[
2
]
) != REGNO (operands
[
4
]
)"
"
*
{
enum rtx_code code1, code2;
code1 = GET_CODE (operands
[
1
]
);
code2 = GET_CODE (operands
[
3
]
);
if ((code1 == EQ || code1 == LT || code1 == GT
|| code1 == LTU || code1 == GTU
|| (code1 != NE && GET_MODE (operands
[
2
]
) == CCFPmode))
!=
(code2 == EQ || code2 == LT || code2 == GT
|| code2 == LTU || code2 == GTU
|| (code2 != NE && GET_MODE (operands
[
4
]
) == CCFPmode)))
return
\"
%C1%C3crxor %E0,%j1,%j3
\"
;
else
return
\"
%C1%C3creqv %E0,%j1,%j3
\"
;
}")
;; There is a 3 cycle delay between consecutive mfcr instructions
;; so it is useful to combine 2 scc instructions to use only one mfcr.
(define_peephole
[
(set (match_operand:SI 0 "gen_reg_operand" "=r")
(match_operator:SI 1 "scc_comparison_operator"
[
(match_operand 2 "cc_reg_operand" "y")
(const_int 0)]))
(set (match_operand:SI 3 "gen_reg_operand" "=r")
(match_operator:SI 4 "scc_comparison_operator"
[
(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
"REGNO (operands
[
2
]
) != REGNO (operands
[
5
]
)"
"%D1%D4mfcr %3
\;
rlinm %0,%3,%J1,31,31
\;
rlinm %3,%3,%J4,31,31")
;; There are some scc insns that can be done directly, without a compare.
;; There are some scc insns that can be done directly, without a compare.
;; These are faster because they don't involve the communications between
;; These are faster because they don't involve the communications between
;; the FXU and branch units. In fact, we will be replacing all of the
;; the FXU and branch units. In fact, we will be replacing all of the
...
...
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