Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
96ec0781
Commit
96ec0781
authored
May 21, 2014
by
Tobias Rapp
Browse files
amd64: Added SSE registers and first SSE node Xorp0
parent
59f25976
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_cconv.c
View file @
96ec0781
...
@@ -34,11 +34,26 @@ static const arch_register_t* const param_regs[] = {
...
@@ -34,11 +34,26 @@ static const arch_register_t* const param_regs[] = {
&
amd64_registers
[
REG_R9
],
&
amd64_registers
[
REG_R9
],
};
};
static
const
arch_register_t
*
const
float_param_regs
[]
=
{
&
amd64_registers
[
REG_XMM0
],
&
amd64_registers
[
REG_XMM1
],
&
amd64_registers
[
REG_XMM2
],
&
amd64_registers
[
REG_XMM3
],
&
amd64_registers
[
REG_XMM4
],
&
amd64_registers
[
REG_XMM5
],
&
amd64_registers
[
REG_XMM6
],
&
amd64_registers
[
REG_XMM7
],
};
static
const
arch_register_t
*
const
result_regs
[]
=
{
static
const
arch_register_t
*
const
result_regs
[]
=
{
&
amd64_registers
[
REG_RAX
],
&
amd64_registers
[
REG_RAX
],
&
amd64_registers
[
REG_RDX
],
&
amd64_registers
[
REG_RDX
],
};
};
static
const
arch_register_t
*
const
float_result_regs
[]
=
{
&
amd64_registers
[
REG_XMM0
],
};
static
const
unsigned
caller_saves
[]
=
{
static
const
unsigned
caller_saves
[]
=
{
REG_RAX
,
REG_RAX
,
REG_RCX
,
REG_RCX
,
...
@@ -49,6 +64,14 @@ static const unsigned caller_saves[] = {
...
@@ -49,6 +64,14 @@ static const unsigned caller_saves[] = {
REG_R9
,
REG_R9
,
REG_R10
,
REG_R10
,
REG_R11
,
REG_R11
,
REG_XMM0
,
REG_XMM1
,
REG_XMM2
,
REG_XMM3
,
REG_XMM4
,
REG_XMM5
,
REG_XMM6
,
REG_XMM7
,
};
};
static
unsigned
default_caller_saves
[
BITSET_SIZE_ELEMS
(
N_AMD64_REGISTERS
)];
static
unsigned
default_caller_saves
[
BITSET_SIZE_ELEMS
(
N_AMD64_REGISTERS
)];
...
@@ -94,11 +117,14 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
...
@@ -94,11 +117,14 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
rbitset_copy
(
callee_saves
,
default_callee_saves
,
N_AMD64_REGISTERS
);
rbitset_copy
(
callee_saves
,
default_callee_saves
,
N_AMD64_REGISTERS
);
/* determine how parameters are passed */
/* determine how parameters are passed */
size_t
n_params
=
get_method_n_params
(
function_type
);
size_t
n_params
=
get_method_n_params
(
function_type
);
size_t
regnum
=
0
;
size_t
param_regnum
=
0
;
reg_or_stackslot_t
*
params
=
XMALLOCNZ
(
reg_or_stackslot_t
,
n_params
);
size_t
float_param_regnum
=
0
;
reg_or_stackslot_t
*
params
=
XMALLOCNZ
(
reg_or_stackslot_t
,
n_params
);
size_t
n_param_regs
=
ARRAY_SIZE
(
param_regs
);
size_t
n_param_regs
=
ARRAY_SIZE
(
param_regs
);
size_t
n_float_param_regs
=
ARRAY_SIZE
(
float_param_regs
);
unsigned
stack_offset
=
0
;
unsigned
stack_offset
=
0
;
for
(
size_t
i
=
0
;
i
<
n_params
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
n_params
;
++
i
)
{
ir_type
*
param_type
=
get_method_param_type
(
function_type
,
i
);
ir_type
*
param_type
=
get_method_param_type
(
function_type
,
i
);
...
@@ -111,12 +137,18 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
...
@@ -111,12 +137,18 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
int
bits
=
get_mode_size_bits
(
mode
);
int
bits
=
get_mode_size_bits
(
mode
);
reg_or_stackslot_t
*
param
=
&
params
[
i
];
reg_or_stackslot_t
*
param
=
&
params
[
i
];
if
(
regnum
<
n_param_regs
)
{
if
(
mode_is_float
(
mode
)
&&
float_param_regnum
<
n_float_param_regs
)
{
const
arch_register_t
*
reg
=
param_regs
[
regnum
];
const
arch_register_t
*
reg
=
float_param_regs
[
float_param_regnum
];
param
->
reg
=
reg
;
param
->
req
=
reg
->
single_req
;
param
->
reg_offset
=
float_param_regnum
;
++
float_param_regnum
;
}
else
if
(
param_regnum
<
n_param_regs
)
{
const
arch_register_t
*
reg
=
param_regs
[
param_regnum
];
param
->
reg
=
reg
;
param
->
reg
=
reg
;
param
->
req
=
reg
->
single_req
;
param
->
req
=
reg
->
single_req
;
param
->
reg_offset
=
regnum
;
param
->
reg_offset
=
param_
regnum
;
++
regnum
;
++
param_
regnum
;
}
else
{
}
else
{
param
->
type
=
param_type
;
param
->
type
=
param_type
;
param
->
offset
=
stack_offset
;
param
->
offset
=
stack_offset
;
...
@@ -125,36 +157,48 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
...
@@ -125,36 +157,48 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
stack_offset
+=
MAX
(
bits
/
8
,
AMD64_REGISTER_SIZE
);
stack_offset
+=
MAX
(
bits
/
8
,
AMD64_REGISTER_SIZE
);
continue
;
continue
;
}
}
}
}
unsigned
n_param_regs_used
=
regnum
;
unsigned
n_param_regs_used
=
param_regnum
+
float_param_regnum
;
/* determine how results are passed */
/* determine how results are passed */
size_t
n_results
=
get_method_n_ress
(
function_type
);
size_t
n_results
=
get_method_n_ress
(
function_type
);
unsigned
n_reg_results
=
0
;
unsigned
n_reg_results
=
0
;
reg_or_stackslot_t
*
results
=
XMALLOCNZ
(
reg_or_stackslot_t
,
n_results
);
reg_or_stackslot_t
*
results
=
XMALLOCNZ
(
reg_or_stackslot_t
,
n_results
);
unsigned
res_regnum
=
0
;
unsigned
res_regnum
=
0
;
unsigned
res_float_regnum
=
0
;
size_t
n_result_regs
=
ARRAY_SIZE
(
result_regs
);
size_t
n_result_regs
=
ARRAY_SIZE
(
result_regs
);
size_t
n_float_result_regs
=
ARRAY_SIZE
(
float_result_regs
);
for
(
size_t
i
=
0
;
i
<
n_results
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
n_results
;
++
i
)
{
ir_type
*
result_type
=
get_method_res_type
(
function_type
,
i
);
ir_type
*
result_type
=
get_method_res_type
(
function_type
,
i
);
ir_mode
*
result_mode
=
get_type_mode
(
result_type
);
ir_mode
*
result_mode
=
get_type_mode
(
result_type
);
reg_or_stackslot_t
*
result
=
&
results
[
i
];
reg_or_stackslot_t
*
result
=
&
results
[
i
];
if
(
mode_is_float
(
result_mode
))
{
if
(
mode_is_float
(
result_mode
))
{
panic
(
"amd64: float return NIY"
);
if
(
res_float_regnum
>=
n_float_result_regs
)
{
panic
(
"Too many floating points results"
);
}
else
{
const
arch_register_t
*
reg
=
float_result_regs
[
res_float_regnum
++
];
result
->
req
=
reg
->
single_req
;
result
->
reg_offset
=
i
;
rbitset_clear
(
caller_saves
,
reg
->
global_index
);
++
n_reg_results
;
}
}
else
{
}
else
{
if
(
res_regnum
>=
n_result_regs
)
{
if
(
res_regnum
>=
n_result_regs
)
{
panic
(
"Too many results"
);
panic
(
"Too many results"
);
}
else
{
}
else
{
const
arch_register_t
*
reg
=
result_regs
[
res_regnum
++
];
const
arch_register_t
*
reg
=
result_regs
[
res_regnum
++
];
result
->
req
=
reg
->
single_req
;
result
->
req
=
reg
->
single_req
;
result
->
reg_offset
=
i
;
result
->
reg_offset
=
i
;
rbitset_clear
(
caller_saves
,
reg
->
global_index
);
rbitset_clear
(
caller_saves
,
reg
->
global_index
);
++
n_reg_results
;
++
n_reg_results
;
}
}
}
}
}
}
amd64_cconv_t
*
cconv
=
XMALLOCZ
(
amd64_cconv_t
);
amd64_cconv_t
*
cconv
=
XMALLOCZ
(
amd64_cconv_t
);
cconv
->
parameters
=
params
;
cconv
->
parameters
=
params
;
cconv
->
param_stack_size
=
stack_offset
;
cconv
->
param_stack_size
=
stack_offset
;
cconv
->
n_param_regs
=
n_param_regs_used
;
cconv
->
n_param_regs
=
n_param_regs_used
;
...
...
ir/be/amd64/amd64_emitter.c
View file @
96ec0781
...
@@ -58,6 +58,20 @@ static void amd64_emit_insn_mode_suffix(amd64_insn_mode_t mode)
...
@@ -58,6 +58,20 @@ static void amd64_emit_insn_mode_suffix(amd64_insn_mode_t mode)
be_emit_char
(
c
);
be_emit_char
(
c
);
}
}
static
void
amd64_emit_xmm_mode_suffix
(
ir_mode
*
mode
)
{
assert
(
mode_is_float
(
mode
));
char
c
;
switch
(
get_mode_size_bits
(
mode
))
{
case
32
:
c
=
's'
;
break
;
case
64
:
c
=
'd'
;
break
;
default:
panic
(
"invalid floating point mode"
);
}
be_emit_char
(
c
);
}
static
const
char
*
get_8bit_name
(
const
arch_register_t
*
reg
)
static
const
char
*
get_8bit_name
(
const
arch_register_t
*
reg
)
{
{
switch
(
reg
->
index
)
{
switch
(
reg
->
index
)
{
...
@@ -480,30 +494,36 @@ emit_R:
...
@@ -480,30 +494,36 @@ emit_R:
?
INSN_MODE_64
:
INSN_MODE_32
;
?
INSN_MODE_64
:
INSN_MODE_32
;
emit_register_insn_mode
(
reg
,
dest_mode
);
emit_register_insn_mode
(
reg
,
dest_mode
);
}
else
{
}
else
{
amd64_insn_mode_t
insn_mode
=
get_amd64_insn_mode
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
emit_register_insn_mode
(
reg
,
insn_mode
);
if
(
mode_is_float
(
mode
))
{
emit_register
(
reg
);
}
else
{
amd64_insn_mode_t
insn_mode
=
get_amd64_insn_mode
(
node
);
emit_register_insn_mode
(
reg
,
insn_mode
);
}
}
}
break
;
break
;
}
}
case
'M'
:
{
case
'M'
:
{
amd64_insn_mode_t
insn_mode
;
if
(
*
fmt
==
'S'
)
{
if
(
*
fmt
==
'S'
)
{
++
fmt
;
++
fmt
;
const
amd64_shift_attr_t
*
attr
const
amd64_shift_attr_t
*
attr
=
get_amd64_shift_attr_const
(
node
);
=
get_amd64_shift_attr_const
(
node
);
insn_mode
=
attr
->
insn_mode
;
amd64_emit_
insn_mode
_suffix
(
attr
->
insn_mode
)
;
}
else
if
(
*
fmt
==
'M'
)
{
}
else
if
(
*
fmt
==
'M'
)
{
++
fmt
;
++
fmt
;
const
amd64_movimm_attr_t
*
attr
const
amd64_movimm_attr_t
*
attr
=
get_amd64_movimm_attr_const
(
node
);
=
get_amd64_movimm_attr_const
(
node
);
insn_mode
=
attr
->
insn_mode
;
amd64_emit_insn_mode_suffix
(
attr
->
insn_mode
);
}
else
if
(
*
fmt
==
'X'
)
{
++
fmt
;
amd64_emit_xmm_mode_suffix
(
get_irn_mode
(
node
));
}
else
{
}
else
{
amd64_addr_attr_t
const
*
const
attr
amd64_addr_attr_t
const
*
const
attr
=
get_amd64_addr_attr_const
(
node
);
=
get_amd64_addr_attr_const
(
node
);
insn_mode
=
attr
->
insn_mode
;
amd64_emit_
insn_mode
_suffix
(
attr
->
insn_mode
)
;
}
}
amd64_emit_insn_mode_suffix
(
insn_mode
);
break
;
break
;
}
}
...
...
ir/be/amd64/amd64_new_nodes.h
View file @
96ec0781
...
@@ -48,7 +48,8 @@ static inline bool amd64_has_addr_attr(const ir_node *node)
...
@@ -48,7 +48,8 @@ static inline bool amd64_has_addr_attr(const ir_node *node)
||
attr
->
op_mode
==
AMD64_OP_UNOP_REG
||
attr
->
op_mode
==
AMD64_OP_UNOP_REG
||
attr
->
op_mode
==
AMD64_OP_RAX_ADDR
||
attr
->
op_mode
==
AMD64_OP_RAX_ADDR
||
attr
->
op_mode
==
AMD64_OP_RAX_REG
)
||
attr
->
op_mode
==
AMD64_OP_RAX_REG
)
&&
(
get_irn_op
(
node
)
!=
op_amd64_Xor0
);
&&
(
get_irn_op
(
node
)
!=
op_amd64_Xor0
)
&&
(
get_irn_op
(
node
)
!=
op_amd64_Xorp0
);
}
}
static
inline
amd64_addr_attr_t
*
get_amd64_addr_attr
(
ir_node
*
node
)
static
inline
amd64_addr_attr_t
*
get_amd64_addr_attr
(
ir_node
*
node
)
...
...
ir/be/amd64/amd64_spec.pl
View file @
96ec0781
$arch
=
"
amd64
";
$arch
=
"
amd64
";
$mode_gp
=
"
mode_Lu
";
$mode_flags
=
"
mode_Iu
";
$mode_xmm
=
"
mode_D
";
#TODO 128bit fp-mode
$status_flags
=
"
all
";
# TODO
$all_flags
=
"
all
";
%reg_classes
=
(
%reg_classes
=
(
gp
=>
[
gp
=>
[
{
name
=>
"
rax
",
dwarf
=>
0
},
{
name
=>
"
rax
",
dwarf
=>
0
},
...
@@ -18,19 +24,25 @@ $arch = "amd64";
...
@@ -18,19 +24,25 @@ $arch = "amd64";
{
name
=>
"
r13
",
dwarf
=>
13
},
{
name
=>
"
r13
",
dwarf
=>
13
},
{
name
=>
"
r14
",
dwarf
=>
14
},
{
name
=>
"
r14
",
dwarf
=>
14
},
{
name
=>
"
r15
",
dwarf
=>
15
},
{
name
=>
"
r15
",
dwarf
=>
15
},
{
mode
=>
"
mode_
Lu
"
}
{
mode
=>
$
mode_
gp
}
],
],
flags
=>
[
flags
=>
[
{
name
=>
"
eflags
",
dwarf
=>
49
},
{
name
=>
"
eflags
",
dwarf
=>
49
},
{
mode
=>
"
mode_
Iu
"
,
flags
=>
"
manual_ra
"
}
{
mode
=>
$
mode_
flags
,
flags
=>
"
manual_ra
"
}
],
],
xmm
=>
[
{
name
=>
"
xmm0
",
dwarf
=>
17
},
{
name
=>
"
xmm1
",
dwarf
=>
18
},
{
name
=>
"
xmm2
",
dwarf
=>
19
},
{
name
=>
"
xmm3
",
dwarf
=>
20
},
{
name
=>
"
xmm4
",
dwarf
=>
21
},
{
name
=>
"
xmm5
",
dwarf
=>
22
},
{
name
=>
"
xmm6
",
dwarf
=>
23
},
{
name
=>
"
xmm7
",
dwarf
=>
24
},
{
mode
=>
$mode_xmm
}
]
);
);
$mode_gp
=
"
mode_Lu
";
$mode_flags
=
"
mode_Iu
";
$status_flags
=
"
all
";
# TODO
$all_flags
=
"
all
";
sub
amd64_custom_init_attr
{
sub
amd64_custom_init_attr
{
my
$constr
=
shift
;
my
$constr
=
shift
;
my
$node
=
shift
;
my
$node
=
shift
;
...
@@ -457,4 +469,16 @@ Return => {
...
@@ -457,4 +469,16 @@ Return => {
mode
=>
"
mode_X
",
mode
=>
"
mode_X
",
},
},
# SSE
Xorp0
=>
{
op_flags
=>
[
"
constlike
"
],
irn_flags
=>
[
"
rematerializable
"
],
reg_req
=>
{
out
=>
[
"
xmm
"
]
},
outs
=>
[
"
res
"
],
fixed
=>
"
amd64_op_mode_t op_mode = AMD64_OP_REG_REG;
",
emit
=>
"
xorp%MX %D0, %D0
",
mode
=>
$mode_xmm
,
},
);
);
ir/be/amd64/amd64_transform.c
View file @
96ec0781
...
@@ -257,9 +257,16 @@ static ir_node *gen_Const(ir_node *node)
...
@@ -257,9 +257,16 @@ static ir_node *gen_Const(ir_node *node)
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
if
(
!
mode_needs_gp_reg
(
mode
))
panic
(
"amd64: float constant not supported yet"
);
ir_tarval
*
tv
=
get_Const_tarval
(
node
);
ir_tarval
*
tv
=
get_Const_tarval
(
node
);
if
(
!
mode_needs_gp_reg
(
mode
))
{
if
(
tarval_is_null
(
tv
))
{
return
new_bd_amd64_Xorp0
(
dbgi
,
block
);
}
panic
(
"amd64: float constant not supported yet"
);
}
uint64_t
val
=
get_tarval_uint64
(
tv
);
uint64_t
val
=
get_tarval_uint64
(
tv
);
amd64_insn_mode_t
imode
=
val
>
UINT32_MAX
?
INSN_MODE_64
:
INSN_MODE_32
;
amd64_insn_mode_t
imode
=
val
>
UINT32_MAX
?
INSN_MODE_64
:
INSN_MODE_32
;
return
new_bd_amd64_MovImm
(
dbgi
,
block
,
imode
,
val
,
NULL
);
return
new_bd_amd64_MovImm
(
dbgi
,
block
,
imode
,
val
,
NULL
);
...
...
Write
Preview
Supports
Markdown
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