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
099dde21
Commit
099dde21
authored
Nov 15, 2000
by
Bernd Schmidt
Committed by
Bernd Schmidt
Nov 15, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Workaround for Itanium A/B step errata
From-SVN: r37482
parent
4e7b85ed
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
159 additions
and
8 deletions
+159
-8
gcc/ChangeLog
+17
-0
gcc/config/ia64/ia64.c
+132
-4
gcc/config/ia64/ia64.h
+10
-4
No files found.
gcc/ChangeLog
View file @
099dde21
2000-11-15 Bernd Schmidt <bernds@redhat.co.uk>
* ia64.c (struct group): New structure.
(last_group): New static array.
(group_idx): New static variable.
(emit_group_barrier_after, errata_find_address_regs, errata_emit_nops):
New static functions.
(emit_insn_group_barriers): Initialize and keep track of group_idx
and last_group.
Call errata_emit_nops if TARGET_B_STEP or TARGET_A_STEP.
Replace all calls to emit_insn_after that emit a group barrier to use
emit_group_barrier_after.
* ia64.h (MASK_B_STEP): New.
(other MASK_XXX macros): Renumbered.
(TARGET_B_STEP): New.
(TARGET_SWITCHES): Add -mb-step.
2000-11-15 Fred Fish <fnf@be.com>
* fixinc/mkfixinc.sh (fixincludes): Add *-*-beos* to list of
...
...
gcc/config/ia64/ia64.c
View file @
099dde21
...
...
@@ -4279,6 +4279,128 @@ rtx_needs_barrier (x, flags, pred)
return
need_barrier
;
}
/* This structure is used to track some details about the previous insns
groups so we can determine if it may be necessary to insert NOPs to
workaround hardware errata. */
static
struct
group
{
HARD_REG_SET
p_reg_set
;
HARD_REG_SET
gr_reg_conditionally_set
;
}
last_group
[
3
];
/* Index into the last_group array. */
static
int
group_idx
;
static
void
emit_group_barrier_after
PARAMS
((
rtx
));
static
int
errata_find_address_regs
PARAMS
((
rtx
*
,
void
*
));
static
void
errata_emit_nops
PARAMS
((
rtx
));
/* Create a new group barrier, emit it after AFTER, and advance group_idx. */
static
void
emit_group_barrier_after
(
after
)
rtx
after
;
{
emit_insn_after
(
gen_insn_group_barrier
(),
after
);
group_idx
=
(
group_idx
+
1
)
%
3
;
memset
(
last_group
+
group_idx
,
0
,
sizeof
last_group
[
group_idx
]);
}
/* Called through for_each_rtx; determines if a hard register that was
conditionally set in the previous group is used as an address register.
It ensures that for_each_rtx returns 1 in that case. */
static
int
errata_find_address_regs
(
xp
,
data
)
rtx
*
xp
;
void
*
data
ATTRIBUTE_UNUSED
;
{
rtx
x
=
*
xp
;
if
(
GET_CODE
(
x
)
!=
MEM
)
return
0
;
x
=
XEXP
(
x
,
0
);
if
(
GET_CODE
(
x
)
==
POST_MODIFY
)
x
=
XEXP
(
x
,
0
);
if
(
GET_CODE
(
x
)
==
REG
)
{
struct
group
*
prev_group
=
last_group
+
(
group_idx
+
2
)
%
3
;
if
(
TEST_HARD_REG_BIT
(
prev_group
->
gr_reg_conditionally_set
,
REGNO
(
x
)))
return
1
;
return
-
1
;
}
return
0
;
}
/* Called for each insn; this function keeps track of the state in
last_group and emits additional NOPs if necessary to work around
an Itanium A/B step erratum. */
static
void
errata_emit_nops
(
insn
)
rtx
insn
;
{
struct
group
*
this_group
=
last_group
+
group_idx
;
struct
group
*
prev_group
=
last_group
+
(
group_idx
+
2
)
%
3
;
rtx
pat
=
PATTERN
(
insn
);
rtx
cond
=
GET_CODE
(
pat
)
==
COND_EXEC
?
COND_EXEC_TEST
(
pat
)
:
0
;
rtx
real_pat
=
cond
?
COND_EXEC_CODE
(
pat
)
:
pat
;
enum
attr_type
type
;
rtx
set
=
real_pat
;
if
(
GET_CODE
(
real_pat
)
==
USE
||
GET_CODE
(
real_pat
)
==
CLOBBER
||
GET_CODE
(
real_pat
)
==
ASM_INPUT
||
GET_CODE
(
real_pat
)
==
ADDR_VEC
||
GET_CODE
(
real_pat
)
==
ADDR_DIFF_VEC
||
asm_noperands
(
insn
)
>=
0
)
return
;
/* single_set doesn't work for COND_EXEC insns, so we have to duplicate
parts of it. */
if
(
GET_CODE
(
set
)
==
PARALLEL
)
{
int
i
;
set
=
XVECEXP
(
real_pat
,
0
,
0
);
for
(
i
=
1
;
i
<
XVECLEN
(
real_pat
,
0
);
i
++
)
if
(
GET_CODE
(
XVECEXP
(
real_pat
,
0
,
i
))
!=
USE
&&
GET_CODE
(
XVECEXP
(
real_pat
,
0
,
i
))
!=
CLOBBER
)
{
set
=
0
;
break
;
}
}
if
(
set
&&
GET_CODE
(
set
)
!=
SET
)
set
=
0
;
type
=
get_attr_type
(
insn
);
if
(
type
==
TYPE_F
&&
set
&&
REG_P
(
SET_DEST
(
set
))
&&
PR_REGNO_P
(
REGNO
(
SET_DEST
(
set
))))
SET_HARD_REG_BIT
(
this_group
->
p_reg_set
,
REGNO
(
SET_DEST
(
set
)));
if
((
type
==
TYPE_M
||
type
==
TYPE_A
)
&&
cond
&&
set
&&
REG_P
(
SET_DEST
(
set
))
&&
GET_CODE
(
SET_SRC
(
set
))
!=
PLUS
&&
GET_CODE
(
SET_SRC
(
set
))
!=
MINUS
&&
(
GET_CODE
(
SET_SRC
(
set
))
!=
MEM
||
GET_CODE
(
XEXP
(
SET_SRC
(
set
),
0
))
!=
POST_MODIFY
)
&&
GENERAL_REGNO_P
(
REGNO
(
SET_DEST
(
set
))))
{
if
(
GET_RTX_CLASS
(
GET_CODE
(
cond
))
!=
'<'
||
!
REG_P
(
XEXP
(
cond
,
0
)))
abort
();
if
(
TEST_HARD_REG_BIT
(
prev_group
->
p_reg_set
,
REGNO
(
XEXP
(
cond
,
0
))))
SET_HARD_REG_BIT
(
this_group
->
gr_reg_conditionally_set
,
REGNO
(
SET_DEST
(
set
)));
}
if
(
for_each_rtx
(
&
real_pat
,
errata_find_address_regs
,
NULL
))
{
emit_insn_before
(
gen_insn_group_barrier
(),
insn
);
emit_insn_before
(
gen_nop
(),
insn
);
emit_insn_before
(
gen_insn_group_barrier
(),
insn
);
}
}
/* INSNS is an chain of instructions. Scan the chain, and insert stop bits
as necessary to eliminate dependendencies. */
...
...
@@ -4290,12 +4412,18 @@ emit_insn_group_barriers (insns)
memset
(
rws_sum
,
0
,
sizeof
(
rws_sum
));
group_idx
=
0
;
memset
(
last_group
,
0
,
sizeof
last_group
);
prev_insn
=
0
;
for
(
insn
=
insns
;
insn
;
insn
=
NEXT_INSN
(
insn
))
{
int
need_barrier
=
0
;
struct
reg_flags
flags
;
if
((
TARGET_B_STEP
||
TARGET_A_STEP
)
&&
INSN_P
(
insn
))
errata_emit_nops
(
insn
);
memset
(
&
flags
,
0
,
sizeof
(
flags
));
switch
(
GET_CODE
(
insn
))
{
...
...
@@ -4310,7 +4438,7 @@ emit_insn_group_barriers (insns)
need_barrier
=
rws_access_regno
(
AR_LC_REGNUM
,
flags
,
0
);
if
(
need_barrier
)
{
emit_
insn_after
(
gen_insn_group_barrier
(),
insn
);
emit_
group_barrier_after
(
insn
);
memset
(
rws_sum
,
0
,
sizeof
(
rws_sum
));
prev_insn
=
NULL_RTX
;
}
...
...
@@ -4328,7 +4456,7 @@ emit_insn_group_barriers (insns)
/* PREV_INSN null can happen if the very first insn is a
volatile asm. */
if
(
prev_insn
)
emit_
insn_after
(
gen_insn_group_barrier
(),
prev_insn
);
emit_
group_barrier_after
(
prev_insn
);
memcpy
(
rws_sum
,
rws_insn
,
sizeof
(
rws_sum
));
}
...
...
@@ -4354,7 +4482,7 @@ emit_insn_group_barriers (insns)
}
if
(
need_barrier
)
{
emit_
insn_after
(
gen_insn_group_barrier
(),
insn
);
emit_
group_barrier_after
(
insn
);
memset
(
rws_sum
,
0
,
sizeof
(
rws_sum
));
prev_insn
=
NULL_RTX
;
}
...
...
@@ -4412,7 +4540,7 @@ emit_insn_group_barriers (insns)
/* PREV_INSN null can happen if the very first insn is a
volatile asm. */
if
(
prev_insn
)
emit_
insn_after
(
gen_insn_group_barrier
(),
prev_insn
);
emit_
group_barrier_after
(
prev_insn
);
memcpy
(
rws_sum
,
rws_insn
,
sizeof
(
rws_sum
));
}
prev_insn
=
insn
;
...
...
gcc/config/ia64/ia64.h
View file @
099dde21
...
...
@@ -55,13 +55,15 @@ extern int target_flags;
#define MASK_A_STEP 0x00000020
/* Emit code for Itanium A step. */
#define MASK_
REG_NAMES 0x00000040
/* Use in/loc/out register names
. */
#define MASK_
B_STEP 0x00000040
/* Emit code for Itanium B step
. */
#define MASK_
NO_SDATA 0x00000080
/* Disable sdata/scommon/sbs
s. */
#define MASK_
REG_NAMES 0x00000080
/* Use in/loc/out register name
s. */
#define MASK_
CONST_GP 0x00000100
/* treat gp as program-wide constant
*/
#define MASK_
NO_SDATA 0x00000100
/* Disable sdata/scommon/sbss.
*/
#define MASK_AUTO_PIC 0x00000200
/* generate automatically PIC */
#define MASK_CONST_GP 0x00000200
/* treat gp as program-wide constant */
#define MASK_AUTO_PIC 0x00000400
/* generate automatically PIC */
#define MASK_INLINE_DIV_LAT 0x00000400
/* inline div, min latency. */
...
...
@@ -81,6 +83,8 @@ extern int target_flags;
#define TARGET_A_STEP (target_flags & MASK_A_STEP)
#define TARGET_B_STEP (target_flags & MASK_B_STEP)
#define TARGET_REG_NAMES (target_flags & MASK_REG_NAMES)
#define TARGET_NO_SDATA (target_flags & MASK_NO_SDATA)
...
...
@@ -124,6 +128,8 @@ extern int target_flags;
N_("Don't emit stop bits before and after volatile extended asms") }, \
{ "a-step", MASK_A_STEP, \
N_("Emit code for Itanium (TM) processor A step")}, \
{ "b-step", MASK_B_STEP, \
N_("Emit code for Itanium (TM) processor B step")}, \
{ "register-names", MASK_REG_NAMES, \
N_("Use in/loc/out register names")}, \
{ "no-sdata", MASK_NO_SDATA, \
...
...
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