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
071a6595
Commit
071a6595
authored
Dec 02, 1994
by
Per Bothner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* expr.c (store_constructor): Add support for SET_TYPE.
From-SVN: r8604
parent
0be37202
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
167 additions
and
0 deletions
+167
-0
gcc/expr.c
+167
-0
No files found.
gcc/expr.c
View file @
071a6595
...
@@ -188,6 +188,7 @@ static rtx compare PROTO((tree, enum rtx_code, enum rtx_code));
...
@@ -188,6 +188,7 @@ static rtx compare PROTO((tree, enum rtx_code, enum rtx_code));
static
rtx
do_store_flag
PROTO
((
tree
,
rtx
,
enum
machine_mode
,
int
));
static
rtx
do_store_flag
PROTO
((
tree
,
rtx
,
enum
machine_mode
,
int
));
static
tree
defer_cleanups_to
PROTO
((
tree
));
static
tree
defer_cleanups_to
PROTO
((
tree
));
extern
void
(
*
interim_eh_hook
)
PROTO
((
tree
));
extern
void
(
*
interim_eh_hook
)
PROTO
((
tree
));
extern
tree
get_set_constructor_words
PROTO
((
tree
,
HOST_WIDE_INT
*
,
int
));
/* Record for each mode whether we can move a register directly to or
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
from an object of that mode in memory. If we can't, we won't try
...
@@ -3099,6 +3100,172 @@ store_constructor (exp, target)
...
@@ -3099,6 +3100,172 @@ store_constructor (exp, target)
}
}
}
}
}
}
/* set constructor assignments */
else
if
(
TREE_CODE
(
type
)
==
SET_TYPE
)
{
tree
elt
;
rtx
xtarget
=
XEXP
(
target
,
0
);
int
set_word_size
=
TYPE_ALIGN
(
type
);
int
nbytes
=
int_size_in_bytes
(
type
);
int
nwords
;
tree
non_const_elements
;
int
need_to_clear_first
;
tree
domain
=
TYPE_DOMAIN
(
type
);
tree
domain_min
,
domain_max
,
bitlength
;
/* The default implementation stategy is to extract the constant
parts of the constructor, use that to initialize the target,
and then "or" in whatever non-constant ranges we need in addition.
If a large set is all zero or all ones, it is
probably better to set it using memset (if available) or bzero.
Also, if a large set has just a single range, it may also be
better to first clear all the first clear the set (using
bzero/memset), and set the bits we want. */
/* Check for all zeros. */
if
(
CONSTRUCTOR_ELTS
(
exp
)
==
NULL_TREE
)
{
clear_storage
(
target
,
nbytes
);
return
;
}
if
(
nbytes
<
0
)
abort
();
nwords
=
(
nbytes
*
BITS_PER_UNIT
)
/
set_word_size
;
if
(
nwords
==
0
)
nwords
=
1
;
domain_min
=
convert
(
sizetype
,
TYPE_MIN_VALUE
(
domain
));
domain_max
=
convert
(
sizetype
,
TYPE_MAX_VALUE
(
domain
));
bitlength
=
size_binop
(
PLUS_EXPR
,
size_binop
(
MINUS_EXPR
,
domain_max
,
domain_min
),
size_one_node
);
/* Check for range all ones, or at most a single range.
(This optimization is only a win for big sets.) */
if
(
GET_MODE
(
target
)
==
BLKmode
&&
nbytes
>
16
&&
TREE_CHAIN
(
CONSTRUCTOR_ELTS
(
exp
))
==
NULL_TREE
)
{
need_to_clear_first
=
1
;
non_const_elements
=
CONSTRUCTOR_ELTS
(
exp
);
}
else
{
HOST_WIDE_INT
*
buffer
=
(
HOST_WIDE_INT
*
)
alloca
(
sizeof
(
HOST_WIDE_INT
)
*
nwords
);
non_const_elements
=
get_set_constructor_words
(
exp
,
buffer
,
nwords
);
if
(
nbytes
*
BITS_PER_UNIT
<=
set_word_size
)
{
if
(
BITS_BIG_ENDIAN
)
buffer
[
0
]
>>=
set_word_size
-
nbytes
*
BITS_PER_UNIT
;
emit_move_insn
(
target
,
GEN_INT
(
buffer
[
0
]));
}
else
{
rtx
addr
=
XEXP
(
target
,
0
);
rtx
to_rtx
;
register
int
i
;
enum
machine_mode
mode
=
mode_for_size
(
set_word_size
,
MODE_INT
,
1
);
for
(
i
=
0
;
i
<
nwords
;
i
++
)
{
int
offset
=
i
*
set_word_size
/
BITS_PER_UNIT
;
rtx
datum
=
GEN_INT
(
buffer
[
i
]);
rtx
to_rtx
=
change_address
(
target
,
mode
,
plus_constant
(
addr
,
offset
));
MEM_IN_STRUCT_P
(
to_rtx
)
=
1
;
emit_move_insn
(
to_rtx
,
datum
);
}
}
need_to_clear_first
=
0
;
}
for
(
elt
=
non_const_elements
;
elt
!=
NULL_TREE
;
elt
=
TREE_CHAIN
(
elt
))
{
/* start of range of element or NULL */
tree
startbit
=
TREE_PURPOSE
(
elt
);
/* end of range of element, or element value */
tree
endbit
=
TREE_VALUE
(
elt
);
HOST_WIDE_INT
startb
,
endb
;
rtx
bitlength_rtx
,
startbit_rtx
,
endbit_rtx
,
targetx
;
bitlength_rtx
=
expand_expr
(
bitlength
,
NULL_RTX
,
MEM
,
EXPAND_CONST_ADDRESS
);
/* handle non-range tuple element like [ expr ] */
if
(
startbit
==
NULL_TREE
)
{
startbit
=
save_expr
(
endbit
);
endbit
=
startbit
;
}
startbit
=
convert
(
sizetype
,
startbit
);
endbit
=
convert
(
sizetype
,
endbit
);
if
(
!
integer_zerop
(
domain_min
))
{
startbit
=
size_binop
(
MINUS_EXPR
,
startbit
,
domain_min
);
endbit
=
size_binop
(
MINUS_EXPR
,
endbit
,
domain_min
);
}
startbit_rtx
=
expand_expr
(
startbit
,
NULL_RTX
,
MEM
,
EXPAND_CONST_ADDRESS
);
endbit_rtx
=
expand_expr
(
endbit
,
NULL_RTX
,
MEM
,
EXPAND_CONST_ADDRESS
);
if
(
REG_P
(
target
))
{
targetx
=
assign_stack_temp
(
GET_MODE
(
target
),
GET_MODE_SIZE
(
GET_MODE
(
target
)),
0
);
emit_move_insn
(
targetx
,
target
);
}
else
if
(
GET_CODE
(
target
)
==
MEM
)
targetx
=
target
;
else
abort
();
#ifdef TARGET_MEM_FUNCTIONS
/* Optimization: If startbit and endbit are
constants divisble by BITS_PER_UNIT,
call memset instead. */
if
(
TREE_CODE
(
startbit
)
==
INTEGER_CST
&&
TREE_CODE
(
endbit
)
==
INTEGER_CST
&&
(
startb
=
TREE_INT_CST_LOW
(
startbit
))
%
BITS_PER_UNIT
==
0
&&
(
endb
=
TREE_INT_CST_LOW
(
endbit
))
%
BITS_PER_UNIT
==
0
)
{
if
(
need_to_clear_first
&&
endb
-
startb
!=
nbytes
*
BITS_PER_UNIT
)
clear_storage
(
target
,
nbytes
);
need_to_clear_first
=
0
;
emit_library_call
(
memset_libfunc
,
0
,
VOIDmode
,
3
,
plus_constant
(
XEXP
(
targetx
,
0
),
startb
),
Pmode
,
constm1_rtx
,
Pmode
,
GEN_INT
((
endb
-
startb
)
/
BITS_PER_UNIT
),
Pmode
);
}
else
#endif
{
if
(
need_to_clear_first
)
{
clear_storage
(
target
,
nbytes
);
need_to_clear_first
=
0
;
}
emit_library_call
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
"__setbits"
),
0
,
VOIDmode
,
4
,
XEXP
(
targetx
,
0
),
Pmode
,
bitlength_rtx
,
TYPE_MODE
(
sizetype
),
startbit_rtx
,
TYPE_MODE
(
sizetype
),
endbit_rtx
,
TYPE_MODE
(
sizetype
));
}
if
(
REG_P
(
target
))
emit_move_insn
(
target
,
targetx
);
}
}
else
else
abort
();
abort
();
...
...
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