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
2a0b0bf5
Commit
2a0b0bf5
authored
Oct 24, 1996
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Permit sign_extend operands
From-SVN: r13028
parent
7f423031
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
196 additions
and
4 deletions
+196
-4
gcc/config/mips/mips.c
+196
-4
No files found.
gcc/config/mips/mips.c
View file @
2a0b0bf5
...
...
@@ -719,6 +719,151 @@ move_operand (op, mode)
&&
!
(
mips_split_addresses
&&
mips_check_split
(
op
,
mode
)));
}
/* Return true if OPERAND is valid as a source operand for movdi.
This accepts not only general_operand, but also sign extended
constants and registers. We need to accept sign extended constants
in case a sign extended register which is used in an expression,
and is equivalent to a constant, is spilled. */
int
movdi_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
(
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
||
(
GET_CODE
(
XEXP
(
op
,
0
))
==
CONST_INT
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
VOIDmode
))
&&
(
register_operand
(
XEXP
(
op
,
0
),
SImode
)
||
immediate_operand
(
XEXP
(
op
,
0
),
SImode
)))
return
1
;
return
general_operand
(
op
,
mode
);
}
/* Like register_operand, but when in 64 bit mode also accept a sign
extend of a 32 bit register, since the value is known to be already
sign extended. */
int
se_register_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
&&
register_operand
(
XEXP
(
op
,
0
),
SImode
))
return
1
;
return
register_operand
(
op
,
mode
);
}
/* Like reg_or_0_operand, but when in 64 bit mode also accept a sign
extend of a 32 bit register, since the value is known to be already
sign extended. */
int
se_reg_or_0_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
&&
register_operand
(
XEXP
(
op
,
0
),
SImode
))
return
1
;
return
reg_or_0_operand
(
op
,
mode
);
}
/* Like uns_arith_operand, but when in 64 bit mode also accept a sign
extend of a 32 bit register, since the value is known to be already
sign extended. */
int
se_uns_arith_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
&&
register_operand
(
XEXP
(
op
,
0
),
SImode
))
return
1
;
return
uns_arith_operand
(
op
,
mode
);
}
/* Like arith_operand, but when in 64 bit mode also accept a sign
extend of a 32 bit register, since the value is known to be already
sign extended. */
int
se_arith_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
&&
register_operand
(
XEXP
(
op
,
0
),
SImode
))
return
1
;
return
arith_operand
(
op
,
mode
);
}
/* Like nonmemory_operand, but when in 64 bit mode also accept a sign
extend of a 32 bit register, since the value is known to be already
sign extended. */
int
se_nonmemory_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
&&
register_operand
(
XEXP
(
op
,
0
),
SImode
))
return
1
;
return
nonmemory_operand
(
op
,
mode
);
}
/* Like nonimmediate_operand, but when in 64 bit mode also accept a
sign extend of a 32 bit register, since the value is known to be
already sign extended. */
int
se_nonimmediate_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
;
{
if
(
TARGET_64BIT
&&
mode
==
DImode
&&
GET_CODE
(
op
)
==
SIGN_EXTEND
&&
GET_MODE
(
op
)
==
DImode
&&
GET_MODE
(
XEXP
(
op
,
0
))
==
SImode
&&
register_operand
(
XEXP
(
op
,
0
),
SImode
))
return
1
;
return
nonimmediate_operand
(
op
,
mode
);
}
/* Return true if we split the address into high and low parts. */
/* ??? We should also handle reg+array somewhere. We get four
...
...
@@ -1382,6 +1527,12 @@ mips_move_2words (operands, insn)
code0
=
GET_CODE
(
op0
);
}
if
(
code1
==
SIGN_EXTEND
)
{
op1
=
XEXP
(
op1
,
0
);
code1
=
GET_CODE
(
op1
);
}
while
(
code1
==
SUBREG
)
{
subreg_word1
+=
SUBREG_WORD
(
op1
);
...
...
@@ -1389,6 +1540,12 @@ mips_move_2words (operands, insn)
code1
=
GET_CODE
(
op1
);
}
/* Sanity check. */
if
(
GET_CODE
(
operands
[
1
])
==
SIGN_EXTEND
&&
code1
!=
REG
&&
code1
!=
CONST_INT
)
abort
();
if
(
code0
==
REG
)
{
int
regno0
=
REGNO
(
op0
)
+
subreg_word0
;
...
...
@@ -1567,7 +1724,9 @@ mips_move_2words (operands, insn)
{
if
(
TARGET_64BIT
)
{
if
(
HOST_BITS_PER_WIDE_INT
<
64
)
if
(
GET_CODE
(
operands
[
1
])
==
SIGN_EXTEND
)
ret
=
"li
\t
%0,%1
\t\t
# %X1"
;
else
if
(
HOST_BITS_PER_WIDE_INT
<
64
)
/* We can't use 'X' for negative numbers, because then we won't
get the right value for the upper 32 bits. */
ret
=
((
INTVAL
(
op1
)
<
0
)
?
"dli
\t
%0,%1
\t\t\t
# %X1"
...
...
@@ -3862,6 +4021,13 @@ print_operand (file, op, letter)
}
code
=
GET_CODE
(
op
);
if
(
code
==
SIGN_EXTEND
)
{
op
=
XEXP
(
op
,
0
);
code
=
GET_CODE
(
op
);
}
if
(
letter
==
'C'
)
switch
(
code
)
{
...
...
@@ -3919,9 +4085,14 @@ print_operand (file, op, letter)
fprintf
(
file
,
"%s,"
,
reg_names
[
regnum
]);
}
else
if
(
code
==
REG
)
else
if
(
code
==
REG
||
code
==
SUBREG
)
{
register
int
regnum
=
REGNO
(
op
);
register
int
regnum
;
if
(
code
==
REG
)
regnum
=
REGNO
(
op
);
else
regnum
=
true_regnum
(
op
);
if
((
letter
==
'M'
&&
!
WORDS_BIG_ENDIAN
)
||
(
letter
==
'L'
&&
WORDS_BIG_ENDIAN
)
...
...
@@ -5832,7 +6003,28 @@ mips_secondary_reload_class (class, mode, x, in_p)
{
int
regno
=
-
1
;
if
(
GET_CODE
(
x
)
==
REG
||
GET_CODE
(
x
)
==
SUBREG
)
if
(
GET_CODE
(
x
)
==
SIGN_EXTEND
)
{
int
off
=
0
;
x
=
XEXP
(
x
,
0
);
/* We may be called with reg_renumber NULL from regclass.
??? This is probably a bug. */
if
(
reg_renumber
)
regno
=
true_regnum
(
x
);
else
{
while
(
GET_CODE
(
x
)
==
SUBREG
)
{
off
+=
SUBREG_WORD
(
x
);
x
=
SUBREG_REG
(
x
);
}
if
(
GET_CODE
(
x
)
==
REG
)
regno
=
REGNO
(
x
)
+
off
;
}
}
else
if
(
GET_CODE
(
x
)
==
REG
||
GET_CODE
(
x
)
==
SUBREG
)
regno
=
true_regnum
(
x
);
/* We always require a general register when copying anything to
...
...
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