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
f357808b
Commit
f357808b
authored
Apr 11, 1992
by
Richard Kenner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r728
parent
916f14f1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
118 additions
and
47 deletions
+118
-47
gcc/config/rs6000/rs6000.h
+10
-2
gcc/config/rs6000/rs6000.md
+108
-45
No files found.
gcc/config/rs6000/rs6000.h
View file @
f357808b
...
...
@@ -1080,11 +1080,15 @@ struct rs6000_args {int words, fregno, nargs_prototype; };
gen_rtx (CONST_INT, VOIDmode, \
high_int << 16)), 0),\
gen_rtx (CONST_INT, VOIDmode, low_int)); \
goto WIN; \
} \
else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
&& GET_CODE (XEXP (X, 1)) != CONST_INT) \
(X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \
force_operand (XEXP (X, 1), 0)); \
{ \
(X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \
force_reg (SImode, force_operand (XEXP (X, 1), 0))); \
goto WIN; \
} \
}
/* Go to LABEL if ADDR (a legitimate address expression)
...
...
@@ -1814,6 +1818,7 @@ bss_section () \
#define PREDICATE_CODES \
{"short_cint_operand", {CONST_INT}}, \
{"u_short_cint_operand", {CONST_INT}}, \
{"non_short_cint_operand", {CONST_INT}}, \
{"gen_reg_operand", {SUBREG, REG}}, \
{"cc_reg_operand", {SUBREG, REG}}, \
{"reg_or_short_operand", {SUBREG, REG, CONST_INT}}, \
...
...
@@ -1825,8 +1830,11 @@ bss_section () \
{"fp_reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
{"add_operand", {SUBREG, REG, CONST_INT}}, \
{"non_add_cint_operand", {CONST_INT}}, \
{"and_operand", {SUBREG, REG, CONST_INT}}, \
{"non_and_cint_operand", {CONST_INT}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"non_logical_cint_operand", {CONST_INT}}, \
{"mask_operand", {CONST_INT}}, \
{"call_operand", {SYMBOL_REF, REG}}, \
{"input_operand", {SUBREG, MEM, REG, CONST_INT}}, \
...
...
gcc/config/rs6000/rs6000.md
View file @
f357808b
...
...
@@ -165,7 +165,7 @@
[
(set_attr "type" "compare")
]
)
;; Fixed-point arithmetic insns.
(define_insn ""
(define_insn "
addsi3
"
[
(set (match_operand:SI 0 "gen_reg_operand" "=r,r")
(plus:SI (match_operand:SI 1 "gen_reg_operand" "%r,b")
(match_operand:SI 2 "add_operand" "rI,J")))]
...
...
@@ -195,28 +195,27 @@
"a%I2. %0,%1,%2"
[
(set_attr "type" "compare")
]
)
(define_expand "addsi3"
;; Split an add that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine. Note that the low-order
;; add should be last in case the result gets used in an address.
(define_split
[
(set (match_operand:SI 0 "gen_reg_operand" "")
(plus:SI (match_operand:SI 1 "gen_reg_operand" "")
(match_operand:SI 2 "
reg_or
_cint_operand" "")))]
(match_operand:SI 2 "
non_add
_cint_operand" "")))]
""
"
[
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
"
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& (unsigned) (INTVAL (operands
[
2
]
) + 0x8000) >= 0x10000
&& (INTVAL (operands
[
2
]
) & 0xffff) != 0)
{
int low = INTVAL (operands
[
2
]
) & 0xffff;
int high = (unsigned) INTVAL (operands
[
2
]
) >> 16;
int low = INTVAL (operands
[
2
]
) & 0xffff;
int high = (unsigned) INTVAL (operands
[
2
]
) >> 16;
if (low & 0x8000)
high++, low |= 0xffff0000;
if (low & 0x8000)
high++, low |= 0xffff0000;
emit_insn (gen_addsi3 (operands[0], operands[1],
gen_rtx (CONST_INT, VOIDmode, high << 16)));
operands[1] = operands[0];
operands[2] = gen_rtx (CONST_INT, VOIDmode, low);
}
operands
[
3
]
= gen_rtx (CONST_INT, VOIDmode, high << 16);
operands
[
4
]
= gen_rtx (CONST_INT, VOIDmode, low);
}")
(define_insn "one_cmplsi2"
...
...
@@ -657,7 +656,47 @@
rlinm. %0,%1,0,%m2,%M2"
[
(set_attr "type" "compare,compare,compare,delayed_compare")
]
)
(define_insn ""
;; Take a AND with a constant that cannot be done in a single insn and try to
;; split it into two insns. This does not verify that the insns are valid
;; since this need not be done as combine will do it.
(define_split
[
(set (match_operand:SI 0 "gen_reg_operand" "")
(and:SI (match_operand:SI 1 "gen_reg_operand" "")
(match_operand:SI 2 "non_and_cint_operand" "")))]
""
[
(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
"
{
int maskval = INTVAL (operands
[
2
]
);
int i, transitions, last_bit_value;
int orig = maskval, first_c = maskval, second_c;
/
*
We know that MASKVAL must have more than 2 bit-transitions. Start at
the low-order bit and count for the third transition. When we get there,
make a first mask that has everything to the left of that position
a one. Then make the second mask to turn off whatever else is needed.
*
/
for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
{
if (((maskval >>= 1) & 1) != last_bit_value)
last_bit_value ^= 1, transitions++;
if (transitions > 2)
{
first_c |= (~0) << i;
break;
}
}
second_c = orig | ~ first_c;
operands
[
3
]
= gen_rtx (CONST_INT, VOIDmode, first_c);
operands
[
4
]
= gen_rtx (CONST_INT, VOIDmode, second_c);
}")
(define_insn "iorsi3"
[
(set (match_operand:SI 0 "gen_reg_operand" "=r,r,r")
(ior:SI (match_operand:SI 1 "gen_reg_operand" "%r,r,r")
(match_operand:SI 2 "logical_operand" "r,K,J")))]
...
...
@@ -688,26 +727,24 @@
"or. %0,%1,%2"
[
(set_attr "type" "compare")
]
)
(define_expand "iorsi3"
;; Split an IOR that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine.
(define_split
[
(set (match_operand:SI 0 "gen_reg_operand" "")
(ior:SI (match_operand:SI 1 "gen_reg_operand" "")
(match_operand:SI 2 "
reg_or
_cint_operand" "")))]
(match_operand:SI 2 "
non_logical
_cint_operand" "")))]
""
"
[
(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
"
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& ! logical_operand (operands
[
2
]
, SImode))
{
emit_insn (gen_iorsi3 (operands
[
0
]
, operands
[
1
]
,
gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff0000)));
operands
[
1
]
= operands
[
0
]
;
operands
[
2
]
= gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff);
}
operands
[
3
]
= gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff0000);
operands
[
4
]
= gen_rtx (CONST_INT, VOIDmode, INTVAL (operands
[
2
]
) & 0xffff);
}")
(define_insn ""
(define_insn "
xorsi3
"
[
(set (match_operand:SI 0 "gen_reg_operand" "=r,r,r")
(xor:SI (match_operand:SI 1 "gen_reg_operand" "%r,r,r")
(match_operand:SI 2 "logical_operand" "r,K,J")))]
...
...
@@ -738,23 +775,21 @@
"xor. %0,%1,%2"
[
(set_attr "type" "compare")
]
)
(define_expand "xorsi3"
;; Split an XOR that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine.
(define_split
[
(set (match_operand:SI 0 "gen_reg_operand" "")
(xor:SI (match_operand:SI 1 "gen_reg_operand" "")
(match_operand:SI 2 "
reg_or
_cint_operand" "")))]
(match_operand:SI 2 "
non_logical
_cint_operand" "")))]
""
"
[
(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
"
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& ! logical_operand (operands
[
2
]
, SImode))
{
emit_insn (gen_xorsi3 (operands
[
0
]
, operands
[
1
]
,
gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff0000)));
operands
[
1
]
= operands
[
0
]
;
operands
[
2
]
= gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff);
}
operands
[
3
]
= gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff0000);
operands
[
4
]
= gen_rtx (CONST_INT, VOIDmode, INTVAL (operands
[
2
]
) & 0xffff);
}")
(define_insn ""
...
...
@@ -3223,6 +3258,34 @@
"cmp%I2 %0,%1,%2"
[
(set_attr "type" "compare")
]
)
;; If we are comparing a register for equality with a large constant,
;; we can do this with an XOR followed by a compare. But we need a scratch
;; register for the result of the XOR.
(define_split
[
(set (match_operand:CC 0 "cc_reg_operand" "")
(compare:CC (match_operand:SI 1 "gen_reg_operand" "")
(match_operand:SI 2 "non_short_cint_operand" "")))
(clobber (match_operand:SI 3 "gen_reg_operand" ""))]
"find_single_use (operands
[
0
]
, insn, 0)
&& (GET_CODE (
*
find_single_use (operands
[
0
]
, insn, 0)) == EQ
|| GET_CODE (
*
find_single_use (operands
[
0
]
, insn, 0)) == NE)"
[
(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
(set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
"
{
/
*
Get the constant we are comparing against, C, and see what it looks like
sign-extended to 16 bits. Then see what constant could be XOR'ed
with C to get the sign-extended value.
*
/
int c = INTVAL (operands
[
2
]
);
int sextc = (c
<
<
16
)
>
> 16;
int xorv = c ^ sextc;
operands
[
4
]
= gen_rtx (CONST_INT, VOIDmode, xorv);
operands
[
5
]
= gen_rtx (CONST_INT, VOIDmode, sextc);
}")
(define_insn ""
[
(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
(compare:CCUNS (match_operand:SI 1 "gen_reg_operand" "r")
...
...
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