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
a7180f70
Commit
a7180f70
authored
Jun 26, 2000
by
Bernd Schmidt
Committed by
Bernd Schmidt
Jun 26, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add MMX and SSE registers to i386 machine description
From-SVN: r34721
parent
5397b155
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
408 additions
and
142 deletions
+408
-142
gcc/ChangeLog
+51
-0
gcc/config/i386/i386-protos.h
+4
-0
gcc/config/i386/i386.c
+151
-2
gcc/config/i386/i386.h
+193
-136
gcc/config/i386/i386elf.h
+2
-1
gcc/config/i386/ptx4-i.h
+2
-1
gcc/config/i386/sysv4.h
+2
-1
gcc/config/i386/unix.h
+3
-1
No files found.
gcc/ChangeLog
View file @
a7180f70
2000-06-27 Bernd Schmidt <bernds@cygnus.co.uk>
Add MMX and SSE registers to i386 machine description.
* i386-protos.h (ix86_constant_alignment, ix86_data_alignment,
ix86_local_alignment): Declare.
* i386.h (TARGET_MMX, TARGET_SSE): New.
(FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, CALL_USED_REGISTERS,
REG_ALLOC_ORDER, HARD_REGNO_NREGS, HARD_REGNO_MODE_OK,
REG_CLASS_NAMES, REG_CLASS_CONTENTS,REG_CLASS_FROM_LETTER,
enum reg_class, HI_REGISTER_NAMES): Added MMX/SSE registers.
(FIRST_SSE_REG, LAST_SSE_REG, SSE_REGNO_P): New.
(FIRST_MMX_REG, LAST_MMX_REG, MMX_REGNO_P, MMX_REG_P): New macros.
(RETURN_IN_MEMORY): Handle MMX/SSE.
(REG_PARM_STACK_SPACE): Added so the first three TImode parameters
also get stack space.
(MUST_PASS_IN_STACK): Added TImode to the default definition.
(CUMULATIVE_ARGS): Added sse_nregs, sse_regno and sse_words.
(MMX_REGISTER_NAMES): New.
(ALIGN_MODE_128): New macro.
(CONSTANT_ALIGNMENT): Code moved out-of-line; just call the function.
(DATA_ALIGNMENT): Likewise.
(LOCAL_ALIGNMENT): Likewise.
(CONDITIONAL_REGISTER_USAGE): Make MMX/SSE regs fixed if not
TARGET_MMX/TARGET_SSE.
(VALID_SSE_REG_MODE, VALID_MMX_REG_MODE): New macros.
(REG_CLASS_FROM_LETTER): 'y' for MMX regs.
(SECONDARY_MEMORY_NEEDED): Be conservative about copying between
SSE/MMX regs and something else.
(CLASS_MAX_NREGS): 1 for SSE and MMX regs.
(REGISTER_MOVE_COST): 10 if trying to move between MMX and SSE regs,
3 if moving between MMX regs and something else.
* i386.c (reg_class): Add SSE_REGS, MMX_REGS.
(regclass_map): Add MMX/SSE registers.
(print_operand): Add code to print XMMWORD as appropriate.
(ix86_split_movdi): Abort for MMX regs.
(init_cumulative_args): Also allow SSE_REGS
(function_arg_advance, function_arg): Likewise
(print_reg): Support 'm'. Add case for TImode.
(override_options): TARGET_SSE implies TARGET_MMX.
(ix86_constant_alignment, ix86_data_alignment, ix86_local_alignment):
New functions.
* config/i386/unix.h (VALUE_REGNO): VECTOR_MODE values go to
FIRST_SSE_REG.
* config/i386/ptx4-i.h (RETURN_IN_MEMORY): Return MMX values in
memory.
* config/i386/sysv4.h (RETURN_IN_MEMORY): Likewise.
* config/i386/i386elf.h (RETURN_IN_MEMORY): Likewise.
2000-06-26 Geoff Keating <geoffk@cygnus.com>
2000-06-26 Geoff Keating <geoffk@cygnus.com>
* ssa.c (struct rename_set_data): Change the name of field
* ssa.c (struct rename_set_data): Change the name of field
...
...
gcc/config/i386/i386-protos.h
View file @
a7180f70
...
@@ -135,6 +135,10 @@ extern int ix86_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree));
...
@@ -135,6 +135,10 @@ extern int ix86_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree));
extern
int
ix86_valid_type_attribute_p
PARAMS
((
tree
,
tree
,
tree
,
tree
));
extern
int
ix86_valid_type_attribute_p
PARAMS
((
tree
,
tree
,
tree
,
tree
));
extern
int
ix86_comp_type_attributes
PARAMS
((
tree
,
tree
));
extern
int
ix86_comp_type_attributes
PARAMS
((
tree
,
tree
));
extern
int
ix86_return_pops_args
PARAMS
((
tree
,
tree
,
int
));
extern
int
ix86_return_pops_args
PARAMS
((
tree
,
tree
,
int
));
extern
int
ix86_data_alignment
PARAMS
((
tree
,
int
));
extern
int
ix86_local_alignment
PARAMS
((
tree
,
int
));
extern
int
ix86_constant_alignment
PARAMS
((
tree
,
int
));
#endif
#endif
gcc/config/i386/i386.c
View file @
a7180f70
...
@@ -247,7 +247,11 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
...
@@ -247,7 +247,11 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
/* arg pointer */
/* arg pointer */
NON_Q_REGS
,
NON_Q_REGS
,
/* flags, fpsr, dirflag, frame */
/* flags, fpsr, dirflag, frame */
NO_REGS
,
NO_REGS
,
NO_REGS
,
NON_Q_REGS
NO_REGS
,
NO_REGS
,
NO_REGS
,
NON_Q_REGS
,
SSE_REGS
,
SSE_REGS
,
SSE_REGS
,
SSE_REGS
,
SSE_REGS
,
SSE_REGS
,
SSE_REGS
,
SSE_REGS
,
MMX_REGS
,
MMX_REGS
,
MMX_REGS
,
MMX_REGS
,
MMX_REGS
,
MMX_REGS
,
MMX_REGS
,
MMX_REGS
};
};
/* The "default" register map. */
/* The "default" register map. */
...
@@ -257,6 +261,8 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
...
@@ -257,6 +261,8 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
0
,
2
,
1
,
3
,
6
,
7
,
4
,
5
,
/* general regs */
0
,
2
,
1
,
3
,
6
,
7
,
4
,
5
,
/* general regs */
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
/* fp regs */
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
/* fp regs */
-
1
,
-
1
,
-
1
,
-
1
,
/* arg, flags, fpsr, dir */
-
1
,
-
1
,
-
1
,
-
1
,
/* arg, flags, fpsr, dir */
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
/* SSE */
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
/* MMX */
};
};
/* Define the register numbers to be used in Dwarf debugging information.
/* Define the register numbers to be used in Dwarf debugging information.
...
@@ -318,6 +324,8 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
...
@@ -318,6 +324,8 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
0
,
2
,
1
,
3
,
6
,
7
,
5
,
4
,
/* general regs */
0
,
2
,
1
,
3
,
6
,
7
,
5
,
4
,
/* general regs */
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
/* fp regs */
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
/* fp regs */
-
1
,
9
,
-
1
,
-
1
,
/* arg, flags, fpsr, dir */
-
1
,
9
,
-
1
,
-
1
,
/* arg, flags, fpsr, dir */
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
/* SSE registers */
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
/* MMX registers */
};
};
...
@@ -625,6 +633,11 @@ override_options ()
...
@@ -625,6 +633,11 @@ override_options ()
/* If we're planning on using `loop', use it. */
/* If we're planning on using `loop', use it. */
if
(
TARGET_USE_LOOP
&&
optimize
)
if
(
TARGET_USE_LOOP
&&
optimize
)
flag_branch_on_count_reg
=
1
;
flag_branch_on_count_reg
=
1
;
/* It makes no sense to ask for just SSE builtins, so MMX is also turned
on by -msse. */
if
(
TARGET_SSE
)
target_flags
|=
MASK_MMX
;
}
}
/* A C statement (sans semicolon) to choose the order in which to
/* A C statement (sans semicolon) to choose the order in which to
...
@@ -3092,11 +3105,16 @@ print_reg (x, code, file)
...
@@ -3092,11 +3105,16 @@ print_reg (x, code, file)
code
=
3
;
code
=
3
;
else
if
(
code
==
'h'
)
else
if
(
code
==
'h'
)
code
=
0
;
code
=
0
;
else
if
(
code
==
'm'
||
MMX_REG_P
(
x
))
code
=
5
;
else
else
code
=
GET_MODE_SIZE
(
GET_MODE
(
x
));
code
=
GET_MODE_SIZE
(
GET_MODE
(
x
));
switch
(
code
)
switch
(
code
)
{
{
case
5
:
fputs
(
hi_reg_name
[
REGNO
(
x
)],
file
);
break
;
case
3
:
case
3
:
if
(
STACK_TOP_P
(
x
))
if
(
STACK_TOP_P
(
x
))
{
{
...
@@ -3110,6 +3128,7 @@ print_reg (x, code, file)
...
@@ -3110,6 +3128,7 @@ print_reg (x, code, file)
if
(
!
FP_REG_P
(
x
))
if
(
!
FP_REG_P
(
x
))
putc
(
'e'
,
file
);
putc
(
'e'
,
file
);
/* FALLTHRU */
/* FALLTHRU */
case
16
:
case
2
:
case
2
:
fputs
(
hi_reg_name
[
REGNO
(
x
)],
file
);
fputs
(
hi_reg_name
[
REGNO
(
x
)],
file
);
break
;
break
;
...
@@ -3139,7 +3158,8 @@ print_reg (x, code, file)
...
@@ -3139,7 +3158,8 @@ print_reg (x, code, file)
w -- likewise, print the HImode name of the register.
w -- likewise, print the HImode name of the register.
k -- likewise, print the SImode name of the register.
k -- likewise, print the SImode name of the register.
h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
y -- print "st(0)" instead of "st" as a register. */
y -- print "st(0)" instead of "st" as a register.
m -- print "st(n)" as an mmx register. */
void
void
print_operand
(
file
,
x
,
code
)
print_operand
(
file
,
x
,
code
)
...
@@ -3243,6 +3263,7 @@ print_operand (file, x, code)
...
@@ -3243,6 +3263,7 @@ print_operand (file, x, code)
case
'k'
:
case
'k'
:
case
'h'
:
case
'h'
:
case
'y'
:
case
'y'
:
case
'm'
:
case
'X'
:
case
'X'
:
case
'P'
:
case
'P'
:
break
;
break
;
...
@@ -3297,6 +3318,7 @@ print_operand (file, x, code)
...
@@ -3297,6 +3318,7 @@ print_operand (file, x, code)
case
4
:
size
=
"DWORD"
;
break
;
case
4
:
size
=
"DWORD"
;
break
;
case
8
:
size
=
"QWORD"
;
break
;
case
8
:
size
=
"QWORD"
;
break
;
case
12
:
size
=
"XWORD"
;
break
;
case
12
:
size
=
"XWORD"
;
break
;
case
16
:
size
=
"XMMWORD"
;
break
;
default
:
default
:
abort
();
abort
();
}
}
...
@@ -5440,6 +5462,8 @@ ix86_split_to_parts (operand, parts, mode)
...
@@ -5440,6 +5462,8 @@ ix86_split_to_parts (operand, parts, mode)
{
{
int
size
=
GET_MODE_SIZE
(
mode
)
/
4
;
int
size
=
GET_MODE_SIZE
(
mode
)
/
4
;
if
(
GET_CODE
(
operand
)
==
REG
&&
MMX_REGNO_P
(
REGNO
(
operand
)))
abort
();
if
(
size
<
2
||
size
>
3
)
if
(
size
<
2
||
size
>
3
)
abort
();
abort
();
...
@@ -6863,3 +6887,128 @@ ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
...
@@ -6863,3 +6887,128 @@ ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
return
--
ix86_sched_data
.
ppro
.
issued_this_cycle
;
return
--
ix86_sched_data
.
ppro
.
issued_this_cycle
;
}
}
}
}
/* Compute the alignment given to a constant that is being placed in memory.
EXP is the constant and ALIGN is the alignment that the object would
ordinarily have.
The value of this function is used instead of that alignment to align
the object. */
int
ix86_constant_alignment
(
exp
,
align
)
tree
exp
;
int
align
;
{
if
(
TREE_CODE
(
exp
)
==
REAL_CST
)
{
if
(
TYPE_MODE
(
TREE_TYPE
(
exp
))
==
DFmode
&&
align
<
64
)
return
64
;
else
if
(
ALIGN_MODE_128
(
TYPE_MODE
(
TREE_TYPE
(
exp
)))
&&
align
<
128
)
return
128
;
}
else
if
(
TREE_CODE
(
exp
)
==
STRING_CST
&&
TREE_STRING_LENGTH
(
exp
)
>=
31
&&
align
<
256
)
return
256
;
return
align
;
}
/* Compute the alignment for a static variable.
TYPE is the data type, and ALIGN is the alignment that
the object would ordinarily have. The value of this function is used
instead of that alignment to align the object. */
int
ix86_data_alignment
(
type
,
align
)
tree
type
;
int
align
;
{
if
(
AGGREGATE_TYPE_P
(
type
)
&&
TYPE_SIZE
(
type
)
&&
TREE_CODE
(
TYPE_SIZE
(
type
))
==
INTEGER_CST
&&
(
TREE_INT_CST_LOW
(
TYPE_SIZE
(
type
))
>=
256
||
TREE_INT_CST_HIGH
(
TYPE_SIZE
(
type
)))
&&
align
<
256
)
return
256
;
if
(
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
{
if
(
TYPE_MODE
(
TREE_TYPE
(
type
))
==
DFmode
&&
align
<
64
)
return
64
;
if
(
ALIGN_MODE_128
(
TYPE_MODE
(
TREE_TYPE
(
type
)))
&&
align
<
128
)
return
128
;
}
else
if
(
TREE_CODE
(
type
)
==
COMPLEX_TYPE
)
{
if
(
TYPE_MODE
(
type
)
==
DCmode
&&
align
<
64
)
return
64
;
if
(
TYPE_MODE
(
type
)
==
XCmode
&&
align
<
128
)
return
128
;
}
else
if
((
TREE_CODE
(
type
)
==
RECORD_TYPE
||
TREE_CODE
(
type
)
==
UNION_TYPE
||
TREE_CODE
(
type
)
==
QUAL_UNION_TYPE
)
&&
TYPE_FIELDS
(
type
))
{
if
(
DECL_MODE
(
TYPE_FIELDS
(
type
))
==
DFmode
&&
align
<
64
)
return
64
;
if
(
ALIGN_MODE_128
(
DECL_MODE
(
TYPE_FIELDS
(
type
)))
&&
align
<
128
)
return
128
;
}
else
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
||
TREE_CODE
(
type
)
==
VECTOR_TYPE
||
TREE_CODE
(
type
)
==
INTEGER_TYPE
)
{
if
(
TYPE_MODE
(
type
)
==
DFmode
&&
align
<
64
)
return
64
;
if
(
ALIGN_MODE_128
(
TYPE_MODE
(
type
))
&&
align
<
128
)
return
128
;
}
return
align
;
}
/* Compute the alignment for a local variable.
TYPE is the data type, and ALIGN is the alignment that
the object would ordinarily have. The value of this macro is used
instead of that alignment to align the object. */
int
ix86_local_alignment
(
type
,
align
)
tree
type
;
int
align
;
{
if
(
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
{
if
(
TYPE_MODE
(
TREE_TYPE
(
type
))
==
DFmode
&&
align
<
64
)
return
64
;
if
(
ALIGN_MODE_128
(
TYPE_MODE
(
TREE_TYPE
(
type
)))
&&
align
<
128
)
return
128
;
}
else
if
(
TREE_CODE
(
type
)
==
COMPLEX_TYPE
)
{
if
(
TYPE_MODE
(
type
)
==
DCmode
&&
align
<
64
)
return
64
;
if
(
TYPE_MODE
(
type
)
==
XCmode
&&
align
<
128
)
return
128
;
}
else
if
((
TREE_CODE
(
type
)
==
RECORD_TYPE
||
TREE_CODE
(
type
)
==
UNION_TYPE
||
TREE_CODE
(
type
)
==
QUAL_UNION_TYPE
)
&&
TYPE_FIELDS
(
type
))
{
if
(
DECL_MODE
(
TYPE_FIELDS
(
type
))
==
DFmode
&&
align
<
64
)
return
64
;
if
(
ALIGN_MODE_128
(
DECL_MODE
(
TYPE_FIELDS
(
type
)))
&&
align
<
128
)
return
128
;
}
else
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
||
TREE_CODE
(
type
)
==
VECTOR_TYPE
||
TREE_CODE
(
type
)
==
INTEGER_TYPE
)
{
if
(
TYPE_MODE
(
type
)
==
DFmode
&&
align
<
64
)
return
64
;
if
(
ALIGN_MODE_128
(
TYPE_MODE
(
type
))
&&
align
<
128
)
return
128
;
}
return
align
;
}
gcc/config/i386/i386.h
View file @
a7180f70
...
@@ -102,6 +102,8 @@ extern int target_flags;
...
@@ -102,6 +102,8 @@ extern int target_flags;
#define MASK_INLINE_ALL_STROPS 0x00002000
/* Inline stringops in all cases */
#define MASK_INLINE_ALL_STROPS 0x00002000
/* Inline stringops in all cases */
#define MASK_NO_PUSH_ARGS 0x00004000
/* Use push instructions */
#define MASK_NO_PUSH_ARGS 0x00004000
/* Use push instructions */
#define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000
/* Accumulate outgoing args */
#define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000
/* Accumulate outgoing args */
#define MASK_MMX 0x00010000
/* Support MMX regs/builtins */
#define MASK_SSE 0x00020000
/* Support SSE regs/builtins */
/* Temporary codegen switches */
/* Temporary codegen switches */
#define MASK_INTEL_SYNTAX 0x00000200
#define MASK_INTEL_SYNTAX 0x00000200
...
@@ -218,6 +220,9 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
...
@@ -218,6 +220,9 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
#define ASSEMBLER_DIALECT ((target_flags & MASK_INTEL_SYNTAX) != 0)
#define ASSEMBLER_DIALECT ((target_flags & MASK_INTEL_SYNTAX) != 0)
#define TARGET_SSE ((target_flags & MASK_SSE) != 0)
#define TARGET_MMX ((target_flags & MASK_MMX) != 0)
#define TARGET_SWITCHES \
#define TARGET_SWITCHES \
{ { "80387", MASK_80387, "Use hardware fp" }, \
{ { "80387", MASK_80387, "Use hardware fp" }, \
{ "no-80387", -MASK_80387, "Do not use hardware fp" }, \
{ "no-80387", -MASK_80387, "Do not use hardware fp" }, \
...
@@ -280,6 +285,11 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
...
@@ -280,6 +285,11 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
"Use push instructions to save outgoing arguments" }, \
"Use push instructions to save outgoing arguments" }, \
{ "no-accumulate-outgoing-args",-MASK_ACCUMULATE_OUTGOING_ARGS, \
{ "no-accumulate-outgoing-args",-MASK_ACCUMULATE_OUTGOING_ARGS, \
"Do not use push instructions to save outgoing arguments" }, \
"Do not use push instructions to save outgoing arguments" }, \
{ "mmx", MASK_MMX, "Support MMX builtins" }, \
{ "no-mmx", -MASK_MMX, "Do not support MMX builtins" }, \
{ "sse", MASK_SSE, "Support MMX and SSE builtins" }, \
{ "no-sse", -MASK_SSE, \
"Do not support MMX and SSE builtins" }, \
SUBTARGET_SWITCHES \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT, 0 }}
{ "", TARGET_DEFAULT, 0 }}
...
@@ -497,6 +507,11 @@ extern int ix86_arch;
...
@@ -497,6 +507,11 @@ extern int ix86_arch;
#define BIGGEST_ALIGNMENT 128
#define BIGGEST_ALIGNMENT 128
/* Decide whether a variable of mode MODE must be 128 bit aligned. */
#define ALIGN_MODE_128(MODE) \
((MODE) == XFmode || ((MODE) == TImode) || (MODE) == V4SFmode \
|| (MODE) == V4SImode)
/* The published ABIs say that doubles should be aligned on word
/* The published ABIs say that doubles should be aligned on word
boundaries, so lower the aligment for structure fields unless
boundaries, so lower the aligment for structure fields unless
-malign-double is set. */
-malign-double is set. */
...
@@ -509,7 +524,7 @@ extern int ix86_arch;
...
@@ -509,7 +524,7 @@ extern int ix86_arch;
#endif
#endif
/* If defined, a C expression to compute the alignment given to a
/* If defined, a C expression to compute the alignment given to a
constant that is being placed in memory.
CONSTANT
is the constant
constant that is being placed in memory.
EXP
is the constant
and ALIGN is the alignment that the object would ordinarily have.
and ALIGN is the alignment that the object would ordinarily have.
The value of this macro is used instead of that alignment to align
The value of this macro is used instead of that alignment to align
the object.
the object.
...
@@ -520,18 +535,7 @@ extern int ix86_arch;
...
@@ -520,18 +535,7 @@ extern int ix86_arch;
constants to be word aligned so that `strcpy' calls that copy
constants to be word aligned so that `strcpy' calls that copy
constants can be done inline. */
constants can be done inline. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
#define CONSTANT_ALIGNMENT(EXP, ALIGN) ix86_constant_alignment (EXP, ALIGN)
(TREE_CODE (EXP) == REAL_CST \
? ((TYPE_MODE (TREE_TYPE (EXP)) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TREE_TYPE (EXP)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (EXP) == STRING_CST \
? ((TREE_STRING_LENGTH (EXP) >= 31 && (ALIGN) < 256) \
? 256 \
: (ALIGN)) \
: (ALIGN))
/* If defined, a C expression to compute the alignment for a static
/* If defined, a C expression to compute the alignment for a static
variable. TYPE is the data type, and ALIGN is the alignment that
variable. TYPE is the data type, and ALIGN is the alignment that
...
@@ -545,41 +549,7 @@ extern int ix86_arch;
...
@@ -545,41 +549,7 @@ extern int ix86_arch;
cause character arrays to be word-aligned so that `strcpy' calls
cause character arrays to be word-aligned so that `strcpy' calls
that copy constants to character arrays can be done inline. */
that copy constants to character arrays can be done inline. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
#define DATA_ALIGNMENT(TYPE, ALIGN) ix86_data_alignment (TYPE, ALIGN)
((AGGREGATE_TYPE_P (TYPE) \
&& TYPE_SIZE (TYPE) \
&& TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& (TREE_INT_CST_LOW (TYPE_SIZE (TYPE)) >= 256 \
|| TREE_INT_CST_HIGH (TYPE_SIZE (TYPE))) && (ALIGN) < 256) \
? 256 \
: TREE_CODE (TYPE) == ARRAY_TYPE \
? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == COMPLEX_TYPE \
? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: ((TREE_CODE (TYPE) == RECORD_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
|| TREE_CODE (TYPE) == QUAL_UNION_TYPE) \
&& TYPE_FIELDS (TYPE)) \
? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == REAL_TYPE \
? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: (ALIGN))
/* If defined, a C expression to compute the alignment for a local
/* If defined, a C expression to compute the alignment for a local
variable. TYPE is the data type, and ALIGN is the alignment that
variable. TYPE is the data type, and ALIGN is the alignment that
...
@@ -591,35 +561,7 @@ extern int ix86_arch;
...
@@ -591,35 +561,7 @@ extern int ix86_arch;
One use of this macro is to increase alignment of medium-size
One use of this macro is to increase alignment of medium-size
data to make it all fit in fewer cache lines. */
data to make it all fit in fewer cache lines. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
#define LOCAL_ALIGNMENT(TYPE, ALIGN) ix86_local_alignment (TYPE, ALIGN)
(TREE_CODE (TYPE) == ARRAY_TYPE \
? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == COMPLEX_TYPE \
? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: ((TREE_CODE (TYPE) == RECORD_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
|| TREE_CODE (TYPE) == QUAL_UNION_TYPE) \
&& TYPE_FIELDS (TYPE)) \
? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == REAL_TYPE \
? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: (ALIGN))
/* Set this non-zero if move instructions will actually fail to work
/* Set this non-zero if move instructions will actually fail to work
when given unaligned data. */
when given unaligned data. */
...
@@ -666,7 +608,7 @@ extern int ix86_arch;
...
@@ -666,7 +608,7 @@ extern int ix86_arch;
eliminated during reloading in favor of either the stack or frame
eliminated during reloading in favor of either the stack or frame
pointer. */
pointer. */
#define FIRST_PSEUDO_REGISTER
21
#define FIRST_PSEUDO_REGISTER
37
/* Number of hardware registers that go into the DWARF-2 unwind info.
/* Number of hardware registers that go into the DWARF-2 unwind info.
If not defined, equals FIRST_PSEUDO_REGISTER. */
If not defined, equals FIRST_PSEUDO_REGISTER. */
...
@@ -676,11 +618,15 @@ extern int ix86_arch;
...
@@ -676,11 +618,15 @@ extern int ix86_arch;
/* 1 for registers that have pervasive standard uses
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
and are not available for the register allocator.
On the 80386, the stack pointer is such, as is the arg pointer. */
On the 80386, the stack pointer is such, as is the arg pointer. */
#define FIXED_REGISTERS \
#define FIXED_REGISTERS \
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg,flags,fpsr, dir*/
\
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/
\
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, \
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
/*frame */
\
/*arg,flags,fpsr,dir,frame*/
\
1}
1, 0, 0, 0, 1, \
/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/
\
0, 0, 0, 0, 0, 0, 0, 0, \
/*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/
\
0, 0, 0, 0, 0, 0, 0, 0}
/* 1 for registers not available across function calls.
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
These must include the FIXED_REGISTERS and also any
...
@@ -689,11 +635,15 @@ extern int ix86_arch;
...
@@ -689,11 +635,15 @@ extern int ix86_arch;
and the register where structure-value addresses are passed.
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like. */
Aside from that, you can include as many other registers as you like. */
#define CALL_USED_REGISTERS \
#define CALL_USED_REGISTERS \
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg,flags,fpsr, dir*/
\
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/
\
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/*frame */
\
/*arg,flags,fpsr,dir,frame*/
\
1}
1, 1, 1, 1, 1, \
/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/
\
1, 1, 1, 1, 1, 1, 1, 1, \
/*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/
\
1, 1, 1, 1, 1, 1, 1, 1}
/* Order in which to allocate registers. Each register must be
/* Order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS. List frame pointer
listed once, even those in FIXED_REGISTERS. List frame pointer
...
@@ -714,11 +664,15 @@ extern int ix86_arch;
...
@@ -714,11 +664,15 @@ extern int ix86_arch;
functions, and a slightly slower compiler. Users complained about the code
functions, and a slightly slower compiler. Users complained about the code
generated by allocating edx first, so restore the 'natural' order of things. */
generated by allocating edx first, so restore the 'natural' order of things. */
#define REG_ALLOC_ORDER \
#define REG_ALLOC_ORDER \
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg,cc,fpsr, dir*/
\
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/
\
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, \
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \
/*frame */
\
/*,arg,cc,fpsr,dir,frame*/
\
20}
16,17, 18, 19, 20, \
/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/
\
21, 22, 23, 24, 25, 26, 27, 28, \
/*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/
\
29, 30, 31, 32, 33, 34, 35, 36 }
/* A C statement (sans semicolon) to choose the order in which to
/* A C statement (sans semicolon) to choose the order in which to
allocate hard registers for pseudo-registers local to a basic
allocate hard registers for pseudo-registers local to a basic
...
@@ -736,22 +690,36 @@ extern int ix86_arch;
...
@@ -736,22 +690,36 @@ extern int ix86_arch;
#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
/* Macro to conditionally modify fixed_regs/call_used_regs. */
/* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \
#define CONDITIONAL_REGISTER_USAGE \
{ \
{ \
if (flag_pic) \
if (flag_pic) \
{ \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
} \
} \
if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387) \
if (! TARGET_MMX) \
{ \
{ \
int i; \
int i; \
HARD_REG_SET x; \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]); \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i)) \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
fixed_regs[i] = call_used_regs[i] = 1; \
if (TEST_HARD_REG_BIT (x, i)) \
} \
fixed_regs[i] = call_used_regs[i] = 1; \
if (! TARGET_SSE) \
} \
{ \
int i; \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i)) \
fixed_regs[i] = call_used_regs[i] = 1; \
} \
if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387) \
{ \
int i; \
HARD_REG_SET x; \
COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]); \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (x, i)) \
fixed_regs[i] = call_used_regs[i] = 1; \
} \
}
}
/* Return number of consecutive hard regs needed starting at reg REGNO
/* Return number of consecutive hard regs needed starting at reg REGNO
...
@@ -765,9 +733,20 @@ extern int ix86_arch;
...
@@ -765,9 +733,20 @@ extern int ix86_arch;
*/
*/
#define HARD_REGNO_NREGS(REGNO, MODE) \
#define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) ? 1 \
(FP_REGNO_P (REGNO)
|| SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO)
? 1 \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define VALID_SSE_REG_MODE(MODE) \
((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode)
#define VALID_MMX_REG_MODE(MODE) \
((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
|| (MODE) == V2SImode || (MODE) == SImode)
#define VECTOR_MODE_SUPPORTED_P(MODE) \
(VALID_SSE_REG_MODE (MODE) && TARGET_SSE ? 1 \
: VALID_MMX_REG_MODE (MODE) && TARGET_MMX ? 1 : 0)
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
...
@@ -781,6 +760,10 @@ extern int ix86_arch;
...
@@ -781,6 +760,10 @@ extern int ix86_arch;
? ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
? ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
&& GET_MODE_UNIT_SIZE (MODE) <= (LONG_DOUBLE_TYPE_SIZE == 96 ? 12 : 8))\
&& GET_MODE_UNIT_SIZE (MODE) <= (LONG_DOUBLE_TYPE_SIZE == 96 ? 12 : 8))\
: SSE_REGNO_P (REGNO) ? VALID_SSE_REG_MODE (MODE) \
: MMX_REGNO_P (REGNO) ? VALID_MMX_REG_MODE (MODE) \
/* Only SSE and MMX regs can hold vector modes. */
\
: VECTOR_MODE_P (MODE) || (MODE) == TImode ? 0 \
: (REGNO) < 4 ? 1 \
: (REGNO) < 4 ? 1 \
/* Other regs cannot do byte accesses. */
\
/* Other regs cannot do byte accesses. */
\
: (MODE) != QImode ? 1 \
: (MODE) != QImode ? 1 \
...
@@ -831,6 +814,12 @@ extern int ix86_arch;
...
@@ -831,6 +814,12 @@ extern int ix86_arch;
#define FPSR_REG 18
#define FPSR_REG 18
#define DIRFLAG_REG 19
#define DIRFLAG_REG 19
#define FIRST_SSE_REG (FRAME_POINTER_REGNUM + 1)
#define LAST_SSE_REG (FIRST_SSE_REG + 7)
#define FIRST_MMX_REG (LAST_SSE_REG + 1)
#define LAST_MMX_REG (FIRST_MMX_REG + 7)
/* Value should be nonzero if functions must have frame pointers.
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms
Zero means the frame pointer need not be set up (and parms
may be accessed via the stack pointer) in functions that seem suitable.
may be accessed via the stack pointer) in functions that seem suitable.
...
@@ -873,8 +862,11 @@ extern int ix86_arch;
...
@@ -873,8 +862,11 @@ extern int ix86_arch;
should always be returned in memory. You should instead use
should always be returned in memory. You should instead use
`DEFAULT_PCC_STRUCT_RETURN' to indicate this. */
`DEFAULT_PCC_STRUCT_RETURN' to indicate this. */
#define RETURN_IN_MEMORY(TYPE) \
#define RETURN_IN_MEMORY(TYPE) \
((TYPE_MODE (TYPE) == BLKmode) || int_size_in_bytes (TYPE) > 12)
((TYPE_MODE (TYPE) == BLKmode) \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8) \
|| (int_size_in_bytes (TYPE) > 12 && TYPE_MODE (TYPE) != TImode \
&& ! VECTOR_MODE_P (TYPE_MODE (TYPE))))
/* Define the classes of registers for register constraints in the
/* Define the classes of registers for register constraints in the
...
@@ -914,6 +906,8 @@ enum reg_class
...
@@ -914,6 +906,8 @@ enum reg_class
GENERAL_REGS
,
/* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
GENERAL_REGS
,
/* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
FP_TOP_REG
,
FP_SECOND_REG
,
/* %st(0) %st(1) */
FP_TOP_REG
,
FP_SECOND_REG
,
/* %st(0) %st(1) */
FLOAT_REGS
,
FLOAT_REGS
,
SSE_REGS
,
MMX_REGS
,
FLOAT_INT_REGS
,
/* FLOAT_REGS and GENERAL_REGS. */
FLOAT_INT_REGS
,
/* FLOAT_REGS and GENERAL_REGS. */
ALL_REGS
,
LIM_REG_CLASSES
ALL_REGS
,
LIM_REG_CLASSES
};
};
...
@@ -936,6 +930,8 @@ enum reg_class
...
@@ -936,6 +930,8 @@ enum reg_class
"GENERAL_REGS", \
"GENERAL_REGS", \
"FP_TOP_REG", "FP_SECOND_REG", \
"FP_TOP_REG", "FP_SECOND_REG", \
"FLOAT_REGS", \
"FLOAT_REGS", \
"SSE_REGS", \
"MMX_REGS", \
"FLOAT_INT_REGS", \
"FLOAT_INT_REGS", \
"ALL_REGS" }
"ALL_REGS" }
...
@@ -943,19 +939,22 @@ enum reg_class
...
@@ -943,19 +939,22 @@ enum reg_class
This is an initializer for a vector of HARD_REG_SET
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
#define REG_CLASS_CONTENTS \
{ {0}, \
{ { 0x00, 0x0 }, \
{0x1}, {0x2}, {0x4}, {0x8},
/* AREG, DREG, CREG, BREG */
\
{ 0x01, 0x0 }, { 0x02, 0x0 },
/* AREG, DREG */
\
{0x10}, {0x20},
/* SIREG, DIREG */
\
{ 0x04, 0x0 }, { 0x08, 0x0 },
/* CREG, BREG */
\
{0x3},
/* AD_REGS */
\
{ 0x10, 0x0 }, { 0x20, 0x0 },
/* SIREG, DIREG */
\
{0xf},
/* Q_REGS */
\
{ 0x03, 0x0 },
/* AD_REGS */
\
{0x1100f0},
/* NON_Q_REGS */
\
{ 0x0f, 0x0 },
/* Q_REGS */
\
{0x7f},
/* INDEX_REGS */
\
{ 0x1100f0, 0x0 },
/* NON_Q_REGS */
\
{0x1100ff},
/* GENERAL_REGS */
\
{ 0x7f, 0x0 },
/* INDEX_REGS */
\
{0x0100}, {0x0200},
/* FP_TOP_REG, FP_SECOND_REG */
\
{ 0x1100ff, 0x0 },
/* GENERAL_REGS */
\
{0xff00},
/* FLOAT_REGS */
\
{ 0x100, 0x0 }, { 0x0200, 0x0 },
/* FP_TOP_REG, FP_SECOND_REG */
\
{0x11ffff},
/* FLOAT_INT_REGS */
\
{ 0xff00, 0x0 },
/* FLOAT_REGS */
\
{0x17ffff} \
{ 0x1fe00000, 0x0 },
/* SSE_REGS */
\
{ 0xe0000000, 0x1f },
/* MMX_REGS */
\
{ 0x1ffff, 0x0 },
/* FLOAT_INT_REGS */
\
{ 0xffffffff, 0x1f } \
}
}
/* The same information, inverted:
/* The same information, inverted:
...
@@ -978,6 +977,11 @@ enum reg_class
...
@@ -978,6 +977,11 @@ enum reg_class
#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
#define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
#define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
#define SSE_REGNO_P(n) ((n) >= FIRST_SSE_REG && (n) <= LAST_SSE_REG)
#define MMX_REGNO_P(n) ((n) >= FIRST_MMX_REG && (n) <= LAST_MMX_REG)
#define MMX_REG_P(xop) (REG_P (xop) && MMX_REGNO_P (REGNO (xop)))
#define STACK_REG_P(xop) (REG_P (xop) && \
#define STACK_REG_P(xop) (REG_P (xop) && \
REGNO (xop) >= FIRST_STACK_REG && \
REGNO (xop) >= FIRST_STACK_REG && \
...
@@ -1013,6 +1017,8 @@ enum reg_class
...
@@ -1013,6 +1017,8 @@ enum reg_class
(C) == 'b' ? BREG : \
(C) == 'b' ? BREG : \
(C) == 'c' ? CREG : \
(C) == 'c' ? CREG : \
(C) == 'd' ? DREG : \
(C) == 'd' ? DREG : \
(C) == 'x' ? SSE_REGS : \
(C) == 'y' ? MMX_REGS : \
(C) == 'A' ? AD_REGS : \
(C) == 'A' ? AD_REGS : \
(C) == 'D' ? DIREG : \
(C) == 'D' ? DIREG : \
(C) == 'S' ? SIREG : NO_REGS)
(C) == 'S' ? SIREG : NO_REGS)
...
@@ -1079,9 +1085,11 @@ enum reg_class
...
@@ -1079,9 +1085,11 @@ enum reg_class
/* If we are copying between general and FP registers, we need a memory
/* If we are copying between general and FP registers, we need a memory
location. */
location. */
/* The same is true for SSE and MMX registers. */
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
(FLOAT_CLASS_P (CLASS1) != FLOAT_CLASS_P (CLASS2))
(FLOAT_CLASS_P (CLASS1) != FLOAT_CLASS_P (CLASS2) \
|| ((CLASS1 == SSE_REGS) != (CLASS2 == SSE_REGS)) \
|| ((CLASS1 == MMX_REGS) != (CLASS2 == MMX_REGS) && (MODE) != SImode))
/* QImode spills from non-QI registers need a scratch. This does not
/* QImode spills from non-QI registers need a scratch. This does not
happen often -- the only example so far requires an uninitialized
happen often -- the only example so far requires an uninitialized
...
@@ -1094,9 +1102,10 @@ enum reg_class
...
@@ -1094,9 +1102,10 @@ enum reg_class
needed to represent mode MODE in a register of class CLASS. */
needed to represent mode MODE in a register of class CLASS. */
/* On the 80386, this is the size of MODE in words,
/* On the 80386, this is the size of MODE in words,
except in the FP regs, where a single reg is always enough. */
except in the FP regs, where a single reg is always enough. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
#define CLASS_MAX_NREGS(CLASS, MODE) \
(FLOAT_CLASS_P (CLASS) ? 1 : \
(FLOAT_CLASS_P (CLASS) || (CLASS) == SSE_REGS || (CLASS) == MMX_REGS \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
? 1 \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
/* A C expression whose value is nonzero if pseudos that have been
/* A C expression whose value is nonzero if pseudos that have been
assigned to registers of class CLASS would likely be spilled
assigned to registers of class CLASS would likely be spilled
...
@@ -1178,6 +1187,34 @@ enum reg_class
...
@@ -1178,6 +1187,34 @@ enum reg_class
/* Offset of first parameter from the argument pointer register value. */
/* Offset of first parameter from the argument pointer register value. */
#define FIRST_PARM_OFFSET(FNDECL) 0
#define FIRST_PARM_OFFSET(FNDECL) 0
/* Define this macro if functions should assume that stack space has been
allocated for arguments even when their values are passed in registers.
The value of this macro is the size, in bytes, of the area reserved for
arguments passed in registers for the function represented by FNDECL.
This space can be allocated by the caller, or be a part of the
machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
which. */
#define REG_PARM_STACK_SPACE(FNDECL) 0
/* Define as a C expression that evaluates to nonzero if we do not know how
to pass TYPE solely in registers. The file expr.h defines a
definition that is usually appropriate, refer to expr.h for additional
documentation. If `REG_PARM_STACK_SPACE' is defined, the argument will be
computed in the stack and then loaded into a register. */
#define MUST_PASS_IN_STACK(MODE,TYPE) \
((TYPE) != 0 \
&& (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
|| TREE_ADDRESSABLE (TYPE) \
|| ((MODE) == TImode) \
|| ((MODE) == BLKmode \
&& ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& 0 == (int_size_in_bytes (TYPE) \
% (PARM_BOUNDARY / BITS_PER_UNIT))) \
&& (FUNCTION_ARG_PADDING (MODE, TYPE) \
== (BYTES_BIG_ENDIAN ? upward : downward)))))
/* Value is the number of bytes of arguments automatically
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
popped when returning from a subroutine call.
FUNDECL is the declaration node of the function (as a tree),
FUNDECL is the declaration node of the function (as a tree),
...
@@ -1231,6 +1268,9 @@ typedef struct ix86_args {
...
@@ -1231,6 +1268,9 @@ typedef struct ix86_args {
int
words
;
/* # words passed so far */
int
words
;
/* # words passed so far */
int
nregs
;
/* # registers available for passing */
int
nregs
;
/* # registers available for passing */
int
regno
;
/* next available register number */
int
regno
;
/* next available register number */
int
sse_words
;
/* # sse words passed so far */
int
sse_nregs
;
/* # sse registers available for passing */
int
sse_regno
;
/* next available sse register number */
}
CUMULATIVE_ARGS
;
}
CUMULATIVE_ARGS
;
/* Initialize a variable CUM of type CUMULATIVE_ARGS
/* Initialize a variable CUM of type CUMULATIVE_ARGS
...
@@ -2060,11 +2100,15 @@ while (0)
...
@@ -2060,11 +2100,15 @@ while (0)
arbitary high cost.
arbitary high cost.
*/
*/
#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \
((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \
? (MEMORY_MOVE_COST (DFmode, CLASS1, 0) \
? (MEMORY_MOVE_COST (DFmode, CLASS1, 0) \
+ MEMORY_MOVE_COST (DFmode, CLASS2, 1)) \
+ MEMORY_MOVE_COST (DFmode, CLASS2, 1)) \
: (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2)) ? 10 : 2)
: (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2)) ? 10 \
: ((CLASS1) == MMX_REGS && (CLASS2) == SSE_REGS) ? 10 \
: ((CLASS1) == SSE_REGS && (CLASS2) == MMX_REGS) ? 10 \
: ((CLASS1) == MMX_REGS) != ((CLASS2) == MMX_REGS) ? 3 \
: 2)
/* A C expression for the cost of moving data of mode M between a
/* A C expression for the cost of moving data of mode M between a
register and memory. A value of 2 is the default; this cost is
register and memory. A value of 2 is the default; this cost is
...
@@ -2239,6 +2283,14 @@ while (0)
...
@@ -2239,6 +2283,14 @@ while (0)
"st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","", \
"st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","", \
"flags","fpsr", "dirflag", "frame" }
"flags","fpsr", "dirflag", "frame" }
#undef HI_REGISTER_NAMES
#define HI_REGISTER_NAMES \
{"ax","dx","cx","bx","si","di","bp","sp", \
"st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","", \
"flags","fpsr", "dirflag", "frame", \
"xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7", \
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }
#define REGISTER_NAMES HI_REGISTER_NAMES
#define REGISTER_NAMES HI_REGISTER_NAMES
/* Table of additional register names to use in user input. */
/* Table of additional register names to use in user input. */
...
@@ -2247,7 +2299,9 @@ while (0)
...
@@ -2247,7 +2299,9 @@ while (0)
{ { "eax", 0 }, { "edx", 1 }, { "ecx", 2 }, { "ebx", 3 }, \
{ { "eax", 0 }, { "edx", 1 }, { "ecx", 2 }, { "ebx", 3 }, \
{ "esi", 4 }, { "edi", 5 }, { "ebp", 6 }, { "esp", 7 }, \
{ "esi", 4 }, { "edi", 5 }, { "ebp", 6 }, { "esp", 7 }, \
{ "al", 0 }, { "dl", 1 }, { "cl", 2 }, { "bl", 3 }, \
{ "al", 0 }, { "dl", 1 }, { "cl", 2 }, { "bl", 3 }, \
{ "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 } }
{ "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 }, \
{ "mm0", 8}, { "mm1", 9}, { "mm2", 10}, { "mm3", 11}, \
{ "mm4", 12}, { "mm5", 13}, { "mm6", 14}, { "mm7", 15} }
/* Note we are omitting these since currently I don't know how
/* Note we are omitting these since currently I don't know how
to get gcc to use these, since they want the same but different
to get gcc to use these, since they want the same but different
...
@@ -2267,6 +2321,9 @@ number as al, and ax.
...
@@ -2267,6 +2321,9 @@ number as al, and ax.
#define QI_HIGH_REGISTER_NAMES \
#define QI_HIGH_REGISTER_NAMES \
{"ah", "dh", "ch", "bh", }
{"ah", "dh", "ch", "bh", }
#define MMX_REGISTER_NAMES \
{0,0,0,0,0,0,0,0,"mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"}
/* How to renumber registers for dbx and gdb. */
/* How to renumber registers for dbx and gdb. */
#define DBX_REGISTER_NUMBER(n) dbx_register_map[n]
#define DBX_REGISTER_NUMBER(n) dbx_register_map[n]
...
...
gcc/config/i386/i386elf.h
View file @
a7180f70
...
@@ -39,7 +39,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -39,7 +39,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef RETURN_IN_MEMORY
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
#define RETURN_IN_MEMORY(TYPE) \
(TYPE_MODE (TYPE) == BLKmode)
(TYPE_MODE (TYPE) == BLKmode \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8))
/* This used to define X86, but james@bigtex.cactus.org says that
/* This used to define X86, but james@bigtex.cactus.org says that
is supposed to be defined optionally by user programs--not by default. */
is supposed to be defined optionally by user programs--not by default. */
...
...
gcc/config/i386/ptx4-i.h
View file @
a7180f70
...
@@ -34,7 +34,8 @@ Boston, MA 02111-1307, USA. */
...
@@ -34,7 +34,8 @@ Boston, MA 02111-1307, USA. */
#undef RETURN_IN_MEMORY
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
#define RETURN_IN_MEMORY(TYPE) \
(TYPE_MODE (TYPE) == BLKmode)
(TYPE_MODE (TYPE) == BLKmode \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8))
/* Define which macros to predefine. _SEQUENT_ is our extension. */
/* Define which macros to predefine. _SEQUENT_ is our extension. */
/* This used to define X86, but james@bigtex.cactus.org says that
/* This used to define X86, but james@bigtex.cactus.org says that
...
...
gcc/config/i386/sysv4.h
View file @
a7180f70
...
@@ -32,7 +32,8 @@ Boston, MA 02111-1307, USA. */
...
@@ -32,7 +32,8 @@ Boston, MA 02111-1307, USA. */
#undef RETURN_IN_MEMORY
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
#define RETURN_IN_MEMORY(TYPE) \
(TYPE_MODE (TYPE) == BLKmode)
(TYPE_MODE (TYPE) == BLKmode \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8))
/* Define which macros to predefine. __svr4__ is our extension. */
/* Define which macros to predefine. __svr4__ is our extension. */
/* This used to define X86, but james@bigtex.cactus.org says that
/* This used to define X86, but james@bigtex.cactus.org says that
...
...
gcc/config/i386/unix.h
View file @
a7180f70
...
@@ -73,7 +73,9 @@ Boston, MA 02111-1307, USA. */
...
@@ -73,7 +73,9 @@ Boston, MA 02111-1307, USA. */
#define VALUE_REGNO(MODE) \
#define VALUE_REGNO(MODE) \
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& TARGET_FLOAT_RETURNS_IN_80387 ? FIRST_FLOAT_REG : 0)
&& TARGET_FLOAT_RETURNS_IN_80387 ? FIRST_FLOAT_REG \
: (MODE) == TImode || VECTOR_MODE_P (MODE) ? FIRST_SSE_REG \
: 0)
/* 1 if N is a possible register number for a function value. */
/* 1 if N is a possible register number for a function value. */
...
...
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