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
9e453a83
Commit
9e453a83
authored
Aug 09, 2010
by
Matthias Braun
Browse files
sparc: implement all floating point operations in single, double and quad mode
[r27902]
parent
905edd3d
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/sparc/sparc_emitter.c
View file @
9e453a83
...
...
@@ -752,28 +752,55 @@ static void emit_sparc_Ba(const ir_node *node)
be_emit_finish_line_gas
(
node
);
}
static
void
emit_fmov
(
const
ir_node
*
node
,
const
arch_register_t
*
src_reg
,
const
arch_register_t
*
dst_reg
)
{
be_emit_cstring
(
"
\t
fmov "
);
be_emit_string
(
arch_register_get_name
(
src_reg
));
be_emit_cstring
(
", "
);
be_emit_string
(
arch_register_get_name
(
dst_reg
));
be_emit_finish_line_gas
(
node
);
}
static
const
arch_register_t
*
get_next_fp_reg
(
const
arch_register_t
*
reg
)
{
unsigned
index
=
reg
->
index
;
assert
(
reg
==
&
sparc_fp_regs
[
index
]);
index
++
;
assert
(
index
<
N_sparc_fp_REGS
);
return
&
sparc_fp_regs
[
index
];
}
/**
* emit copy node
*/
static
void
emit_be_Copy
(
const
ir_node
*
irn
)
static
void
emit_be_Copy
(
const
ir_node
*
node
)
{
ir_mode
*
mode
=
get_irn_mode
(
irn
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
const
arch_register_t
*
src_reg
=
get_in_reg
(
node
,
0
);
const
arch_register_t
*
dst_reg
=
get_out_reg
(
node
,
0
);
if
(
get_in_reg
(
irn
,
0
)
==
get_out_reg
(
irn
,
0
))
{
/* omitted Copy */
if
(
src_reg
==
dst_reg
)
return
;
}
if
(
mode_is_float
(
mode
))
{
panic
(
"emit_be_Copy: move not supported for FP"
);
unsigned
bits
=
get_mode_size_bits
(
mode
);
int
n
=
bits
>
32
?
bits
>
64
?
3
:
1
:
0
;
int
i
;
emit_fmov
(
node
,
src_reg
,
dst_reg
);
for
(
i
=
0
;
i
<
n
;
++
i
)
{
src_reg
=
get_next_fp_reg
(
src_reg
);
dst_reg
=
get_next_fp_reg
(
dst_reg
);
emit_fmov
(
node
,
src_reg
,
dst_reg
);
}
}
else
if
(
mode_is_data
(
mode
))
{
be_emit_cstring
(
"
\t
mov "
);
sparc_emit_source_register
(
irn
,
0
);
sparc_emit_source_register
(
node
,
0
);
be_emit_cstring
(
", "
);
sparc_emit_dest_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
sparc_emit_dest_register
(
node
,
0
);
be_emit_finish_line_gas
(
node
);
}
else
{
panic
(
"emit_be_Copy:
move not supported for this
mode"
);
panic
(
"emit_be_Copy:
invalid
mode"
);
}
}
...
...
@@ -786,8 +813,6 @@ static void emit_nothing(const ir_node *irn)
(
void
)
irn
;
}
/**
* type of emitter function
*/
...
...
@@ -844,15 +869,15 @@ static void sparc_register_emitters(void)
*/
static
void
sparc_emit_node
(
const
ir_node
*
node
)
{
ir_op
*
op
=
get_irn_op
(
node
);
ir_op
*
op
=
get_irn_op
(
node
);
if
(
op
->
ops
.
generic
)
{
emit_func
func
=
(
emit_func
)
op
->
ops
.
generic
;
be_dbg_set_dbg_info
(
get_irn_dbg_info
(
node
));
(
*
func
)
(
node
);
}
else
{
panic
(
"
Error:
No emit handler for node %+F (graph %+F)
\n
"
,
node
,
current_ir_graph
);
panic
(
"No emit handler for node %+F (graph %+F)
\n
"
,
node
,
current_ir_graph
);
}
}
...
...
ir/be/sparc/sparc_spec.pl
View file @
9e453a83
...
...
@@ -232,6 +232,24 @@ my %float_binop_constructors = (
}
);
my
%float_unop_constructors
=
(
s => {
reg_req => { in =
>
[
"
fp
"
],
out
=>
[
"
fp
"
]
},
ins
=>
[
"
left
",
"
right
"
],
mode
=>
$mode_fp
,
},
d
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|2
"
],
out
=>
[
"
fp:a|2
"
]
},
ins
=>
[
"
left
",
"
right
"
],
mode
=>
$mode_fp2
,
},
q
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|4
"
],
out
=>
[
"
fp:a|4
"
]
},
ins
=>
[
"
left
",
"
right
"
],
mode
=>
$mode_fp4
,
}
);
%nodes
=
(
Add
=>
{
...
...
@@ -531,11 +549,21 @@ Nop => {
fcmp
=>
{
irn_flags
=>
[
"
rematerializable
",
"
modifies_fp_flags
"
],
reg_req
=>
{
in
=>
[
"
fp
",
"
fp
"
],
out
=>
[
"
fpflags
"
]
},
emit
=>
'
. fcmp%FPM %S1, %S2
',
attr_type
=>
"
sparc_fp_attr_t
",
attr
=>
"
ir_mode *fp_mode
",
mode
=>
$mode_fpflags
,
constructors
=>
{
s => {
reg_req => { in =
>
[
"
fp
",
"
fp
"
],
out
=>
[
"
fpflags
"
]
},
},
d
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|2
",
"
fp:a|2
"
],
out
=>
[
"
fpflags
"
]
},
},
q
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|4
",
"
fp:a|4
"
],
out
=>
[
"
fpflags
"
]
},
},
},
},
fadd
=>
{
...
...
@@ -576,27 +604,53 @@ fdiv => {
fneg
=>
{
irn_flags
=>
[
"
rematerializable
"
],
reg_req
=>
{
in
=>
[
"
fp
"
],
out
=>
[
"
fp
"
]
},
emit
=>
'
. fneg%FPM %S1, %D1
',
# note that we only need the first register even for wide-values
emit
=>
'
. fneg %S1, %D1
',
attr_type
=>
"
sparc_fp_attr_t
",
attr
=>
"
ir_mode *fp_mode
",
mode
=>
$mode_fp
,
constructors
=>
\
%float_unop_constructors
,
},
"
fabs
"
=>
{
irn_flags
=>
[
"
rematerializable
"
],
emit
=>
'
. fabs%FPM %S1, %D1
',
# note that we only need the first register even for wide-values
emit
=>
'
. fabs %S1, %D1
',
attr_type
=>
"
sparc_fp_attr_t
",
attr
=>
"
ir_mode *fp_mode
",
constructors
=>
\
%float_
bi
nop_constructors
,
constructors
=>
\
%float_
u
nop_constructors
,
},
fftof
=>
{
irn_flags
=>
[
"
rematerializable
"
],
reg_req
=>
{
in
=>
[
"
fp
"
],
out
=>
[
"
fp
"
]
},
emit
=>
'
. f%FCONVS%.to%FCONVD %S1, %D1
',
attr_type
=>
"
sparc_fp_conv_attr_t
",
attr
=>
"
ir_mode *src_mode, ir_mode *dest_mode
",
mode
=>
$mode_fp
,
constructors
=>
{
s_d
=>
{
reg_req
=>
{
in
=>
[
"
fp
"
],
out
=>
[
"
fp:a|2
"
]
},
mode
=>
$mode_fp2
,
},
s_q
=>
{
reg_req
=>
{
in
=>
[
"
fp
"
],
out
=>
[
"
fp:a|2
"
]
},
mode
=>
$mode_fp4
,
},
d_s
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|2
"
],
out
=>
[
"
fp
"
]
},
mode
=>
$mode_fp
,
},
d_q
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|2
"
],
out
=>
[
"
fp:a|4
"
]
},
mode
=>
$mode_fp4
,
},
q_s
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|4
"
],
out
=>
[
"
fp
"
]
},
mode
=>
$mode_fp
,
},
q_d
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|4
"
],
out
=>
[
"
fp:a|2
"
]
},
mode
=>
$mode_fp2
,
},
},
},
fitof
=>
{
...
...
@@ -605,7 +659,20 @@ fitof => {
emit
=>
'
. fito%FPM %S1, %D1
',
attr_type
=>
"
sparc_fp_attr_t
",
attr
=>
"
ir_mode *fp_mode
",
mode
=>
$mode_fp
,
constructors
=>
{
s => {
reg_req => { in =
>
[
"
gp
"
],
out
=>
[
"
fp
"
]
},
mode
=>
$mode_fp
,
},
d
=>
{
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
fp:a|2
"
]
},
mode
=>
$mode_fp2
,
},
q
=>
{
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
fp:a|4
"
]
},
mode
=>
$mode_fp4
,
},
},
},
fftoi
=>
{
...
...
@@ -615,14 +682,35 @@ fftoi => {
attr_type
=>
"
sparc_fp_attr_t
",
attr
=>
"
ir_mode *fp_mode
",
mode
=>
$mode_gp
,
constructors
=>
{
s => {
reg_req => { in =
>
[
"
gp
"
],
out
=>
[
"
gp
"
]
},
},
d
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|2
"
],
out
=>
[
"
gp
"
]
},
},
q
=>
{
reg_req
=>
{
in
=>
[
"
fp:a|4
"
],
out
=>
[
"
gp
"
]
},
},
},
},
Ldf
=>
{
op_flags
=>
[
"
labeled
",
"
fragile
"
],
state
=>
"
exc_pinned
",
constructors
=>
{
s => {
reg_req => { in =
>
[
"
gp
",
"
none
"
],
out
=>
[
"
fp
",
"
none
"
]
},
},
d
=>
{
reg_req
=>
{
in
=>
[
"
gp
",
"
none
"
],
out
=>
[
"
fp:a|2
",
"
none
"
]
},
},
q
=>
{
reg_req
=>
{
in
=>
[
"
gp
",
"
none
"
],
out
=>
[
"
fp:a|4
",
"
none
"
]
},
},
},
ins
=>
[
"
ptr
",
"
mem
"
],
outs
=>
[
"
res
",
"
M
"
],
reg_req
=>
{
in
=>
[
"
gp
",
"
none
"
],
out
=>
[
"
fp
",
"
none
"
]
},
attr_type
=>
"
sparc_load_store_attr_t
",
attr
=>
"
ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity
",
emit
=>
'
. ld%FLSM [%S1%O], %D1
'
...
...
@@ -631,9 +719,19 @@ Ldf => {
Stf
=>
{
op_flags
=>
[
"
labeled
",
"
fragile
"
],
state
=>
"
exc_pinned
",
constructors
=>
{
s => {
reg_req => { in =
>
[
"
gp
",
"
fp
",
"
none
"
],
out
=>
[
"
none
"
]
},
},
d
=>
{
reg_req
=>
{
in
=>
[
"
gp
",
"
fp:a|2
",
"
none
"
],
out
=>
[
"
none
"
]
},
},
q
=>
{
reg_req
=>
{
in
=>
[
"
gp
",
"
fp:a|4
",
"
none
"
],
out
=>
[
"
none
"
]
},
},
},
ins
=>
[
"
ptr
",
"
val
",
"
mem
"
],
outs
=>
[
"
M
"
],
reg_req
=>
{
in
=>
[
"
gp
",
"
fp
",
"
none
"
],
out
=>
[
"
none
"
]
},
attr_type
=>
"
sparc_load_store_attr_t
",
attr
=>
"
ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity
",
emit
=>
'
. st%FLSM %S2, [%S1%O]
',
...
...
ir/be/sparc/sparc_transform.c
View file @
9e453a83
...
...
@@ -201,6 +201,7 @@ typedef enum {
typedef
ir_node
*
(
*
new_binop_reg_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
ir_node
*
op2
);
typedef
ir_node
*
(
*
new_binop_fp_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
);
typedef
ir_node
*
(
*
new_binop_imm_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
int
simm13
);
typedef
ir_node
*
(
*
new_unop_fp_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
ir_mode
*
mode
);
/**
* checks if a node's value can be encoded as a immediate
...
...
@@ -279,6 +280,30 @@ static ir_node *gen_helper_binfpop(ir_node *node, ir_mode *mode,
panic
(
"unsupported mode %+F for float op"
,
mode
);
}
static
ir_node
*
gen_helper_unfpop
(
ir_node
*
node
,
ir_mode
*
mode
,
new_unop_fp_func
new_func_single
,
new_unop_fp_func
new_func_double
,
new_unop_fp_func
new_func_quad
)
{
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_node
*
op1
=
get_binop_left
(
node
);
ir_node
*
new_op1
=
be_transform_node
(
op1
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
unsigned
bits
=
get_mode_size_bits
(
mode
);
switch
(
bits
)
{
case
32
:
return
new_func_single
(
dbgi
,
block
,
new_op1
,
mode
);
case
64
:
return
new_func_double
(
dbgi
,
block
,
new_op1
,
mode
);
case
128
:
return
new_func_quad
(
dbgi
,
block
,
new_op1
,
mode
);
default:
break
;
}
panic
(
"unsupported mode %+F for float op"
,
mode
);
}
/**
* Creates an sparc Add.
*
...
...
@@ -315,6 +340,45 @@ static ir_node *gen_Sub(ir_node *node)
return
gen_helper_binop
(
node
,
MATCH_NONE
,
new_bd_sparc_Sub_reg
,
new_bd_sparc_Sub_imm
);
}
static
ir_node
*
create_ldf
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
ptr
,
ir_node
*
mem
,
ir_mode
*
mode
,
ir_entity
*
entity
,
int
entity_sign
,
long
offset
,
bool
is_frame_entity
)
{
unsigned
bits
=
get_mode_size_bits
(
mode
);
assert
(
mode_is_float
(
mode
));
if
(
bits
==
32
)
{
return
new_bd_sparc_Ldf_s
(
dbgi
,
block
,
ptr
,
mem
,
mode
,
entity
,
entity_sign
,
offset
,
is_frame_entity
);
}
else
if
(
bits
==
64
)
{
return
new_bd_sparc_Ldf_d
(
dbgi
,
block
,
ptr
,
mem
,
mode
,
entity
,
entity_sign
,
offset
,
is_frame_entity
);
}
else
{
assert
(
bits
==
128
);
return
new_bd_sparc_Ldf_q
(
dbgi
,
block
,
ptr
,
mem
,
mode
,
entity
,
entity_sign
,
offset
,
is_frame_entity
);
}
}
static
ir_node
*
create_stf
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
ptr
,
ir_node
*
value
,
ir_node
*
mem
,
ir_mode
*
mode
,
ir_entity
*
entity
,
int
entity_sign
,
long
offset
,
bool
is_frame_entity
)
{
unsigned
bits
=
get_mode_size_bits
(
mode
);
assert
(
mode_is_float
(
mode
));
if
(
bits
==
32
)
{
return
new_bd_sparc_Stf_s
(
dbgi
,
block
,
ptr
,
value
,
mem
,
mode
,
entity
,
entity_sign
,
offset
,
is_frame_entity
);
}
else
if
(
bits
==
64
)
{
return
new_bd_sparc_Stf_d
(
dbgi
,
block
,
ptr
,
value
,
mem
,
mode
,
entity
,
entity_sign
,
offset
,
is_frame_entity
);
}
else
{
assert
(
bits
==
128
);
return
new_bd_sparc_Stf_q
(
dbgi
,
block
,
ptr
,
value
,
mem
,
mode
,
entity
,
entity_sign
,
offset
,
is_frame_entity
);
}
}
/**
* Transforms a Load.
*
...
...
@@ -333,7 +397,7 @@ static ir_node *gen_Load(ir_node *node)
ir_node
*
new_load
=
NULL
;
if
(
mode_is_float
(
mode
))
{
new_load
=
new_bd_sparc_L
df
(
dbgi
,
block
,
new_ptr
,
new_mem
,
mode
,
NULL
,
0
,
0
,
false
);
new_load
=
create_l
df
(
dbgi
,
block
,
new_ptr
,
new_mem
,
mode
,
NULL
,
0
,
0
,
false
);
}
else
{
new_load
=
new_bd_sparc_Ld
(
dbgi
,
block
,
new_ptr
,
new_mem
,
mode
,
NULL
,
0
,
0
,
false
);
}
...
...
@@ -362,7 +426,7 @@ static ir_node *gen_Store(ir_node *node)
ir_node
*
new_store
=
NULL
;
if
(
mode_is_float
(
mode
))
{
new_store
=
new_bd_sparc_S
tf
(
dbgi
,
block
,
new_ptr
,
new_val
,
new_mem
,
mode
,
NULL
,
0
,
0
,
false
);
new_store
=
create_s
tf
(
dbgi
,
block
,
new_ptr
,
new_val
,
new_mem
,
mode
,
NULL
,
0
,
0
,
false
);
}
else
{
new_store
=
new_bd_sparc_St
(
dbgi
,
block
,
new_ptr
,
new_val
,
new_mem
,
mode
,
NULL
,
0
,
0
,
false
);
}
...
...
@@ -447,8 +511,8 @@ static ir_node *gen_Abs(ir_node *node)
ir_mode
*
const
mode
=
get_irn_mode
(
node
);
if
(
mode_is_float
(
mode
))
{
return
gen_helper_
bi
nfpop
(
node
,
mode
,
new_bd_sparc_fabs_s
,
new_bd_sparc_f
div
_d
,
new_bd_sparc_f
div
_q
);
return
gen_helper_
u
nfpop
(
node
,
mode
,
new_bd_sparc_fabs_s
,
new_bd_sparc_f
abs
_d
,
new_bd_sparc_f
abs
_q
);
}
else
{
ir_node
*
const
block
=
be_transform_node
(
get_nodes_block
(
node
));
dbg_info
*
const
dbgi
=
get_irn_dbg_info
(
node
);
...
...
@@ -518,7 +582,8 @@ static ir_node *gen_Minus(ir_node *node)
ir_mode
*
mode
=
get_irn_mode
(
node
);
if
(
mode_is_float
(
mode
))
{
return
new_bd_sparc_fneg
(
dbgi
,
block
,
new_op
,
mode
);
return
gen_helper_unfpop
(
node
,
mode
,
new_bd_sparc_fneg_s
,
new_bd_sparc_fneg_d
,
new_bd_sparc_fneg_q
);
}
return
new_bd_sparc_Minus
(
dbgi
,
block
,
new_op
);
...
...
@@ -578,9 +643,10 @@ static ir_node *gen_Const(ir_node *node)
ir_node
*
addr
=
make_addr
(
dbgi
,
entity
);
ir_node
*
mem
=
new_NoMem
();
ir_node
*
new_op
=
new_bd_sparc_Ldf
(
dbgi
,
block
,
addr
,
mem
,
mode
,
NULL
,
0
,
0
,
false
);
=
create_ldf
(
dbgi
,
block
,
addr
,
mem
,
mode
,
NULL
,
0
,
0
,
false
);
ir_node
*
proj
=
new_Proj
(
new_op
,
mode
,
pn_sparc_Ldf_res
);
set_irn_pinned
(
new_op
,
op_pin_state_floats
);
return
proj
;
}
...
...
@@ -654,7 +720,15 @@ static ir_node *gen_Cmp(ir_node *node)
assert
(
get_irn_mode
(
op2
)
==
cmp_mode
);
if
(
mode_is_float
(
cmp_mode
))
{
return
new_bd_sparc_fcmp
(
dbgi
,
block
,
new_op1
,
new_op2
,
cmp_mode
);
unsigned
bits
=
get_mode_size_bits
(
cmp_mode
);
if
(
bits
==
32
)
{
return
new_bd_sparc_fcmp_s
(
dbgi
,
block
,
new_op1
,
new_op2
,
cmp_mode
);
}
else
if
(
bits
==
64
)
{
return
new_bd_sparc_fcmp_d
(
dbgi
,
block
,
new_op1
,
new_op2
,
cmp_mode
);
}
else
{
assert
(
bits
==
128
);
return
new_bd_sparc_fcmp_q
(
dbgi
,
block
,
new_op1
,
new_op2
,
cmp_mode
);
}
}
/* integer compare */
...
...
@@ -674,6 +748,64 @@ static ir_node *gen_SymConst(ir_node *node)
return
make_addr
(
dbgi
,
entity
);
}
static
ir_node
*
create_fftof
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
,
ir_mode
*
src_mode
,
ir_mode
*
dst_mode
)
{
unsigned
src_bits
=
get_mode_size_bits
(
src_mode
);
unsigned
dst_bits
=
get_mode_size_bits
(
dst_mode
);
if
(
src_bits
==
32
)
{
if
(
dst_bits
==
64
)
{
return
new_bd_sparc_fftof_s_d
(
dbgi
,
block
,
op
,
src_mode
,
dst_mode
);
}
else
{
assert
(
dst_bits
==
128
);
return
new_bd_sparc_fftof_s_q
(
dbgi
,
block
,
op
,
src_mode
,
dst_mode
);
}
}
else
if
(
src_bits
==
64
)
{
if
(
dst_bits
==
32
)
{
return
new_bd_sparc_fftof_d_s
(
dbgi
,
block
,
op
,
src_mode
,
dst_mode
);
}
else
{
assert
(
dst_bits
==
128
);
return
new_bd_sparc_fftof_d_q
(
dbgi
,
block
,
op
,
src_mode
,
dst_mode
);
}
}
else
{
assert
(
src_bits
==
128
);
if
(
dst_bits
==
32
)
{
return
new_bd_sparc_fftof_q_s
(
dbgi
,
block
,
op
,
src_mode
,
dst_mode
);
}
else
{
assert
(
dst_bits
==
64
);
return
new_bd_sparc_fftof_q_d
(
dbgi
,
block
,
op
,
src_mode
,
dst_mode
);
}
}
}
static
ir_node
*
create_ftoi
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
,
ir_mode
*
src_mode
)
{
unsigned
bits
=
get_mode_size_bits
(
src_mode
);
if
(
bits
==
32
)
{
return
new_bd_sparc_fftoi_s
(
dbgi
,
block
,
op
,
src_mode
);
}
else
if
(
bits
==
64
)
{
return
new_bd_sparc_fftoi_d
(
dbgi
,
block
,
op
,
src_mode
);
}
else
{
assert
(
bits
==
128
);
return
new_bd_sparc_fftoi_q
(
dbgi
,
block
,
op
,
src_mode
);
}
}
static
ir_node
*
create_itof
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
,
ir_mode
*
dst_mode
)
{
unsigned
bits
=
get_mode_size_bits
(
dst_mode
);
if
(
bits
==
32
)
{
return
new_bd_sparc_fitof_s
(
dbgi
,
block
,
op
,
dst_mode
);
}
else
if
(
bits
==
64
)
{
return
new_bd_sparc_fitof_d
(
dbgi
,
block
,
op
,
dst_mode
);
}
else
{
assert
(
bits
==
128
);
return
new_bd_sparc_fitof_q
(
dbgi
,
block
,
op
,
dst_mode
);
}
}
/**
* Transforms a Conv node.
*
...
...
@@ -699,18 +831,18 @@ static ir_node *gen_Conv(ir_node *node)
if
(
mode_is_float
(
src_mode
))
{
if
(
mode_is_float
(
dst_mode
))
{
/* float -> float conv */
return
new_bd_sparc
_fftof
(
dbg
,
block
,
new_op
,
src_mode
,
dst_mode
);
return
create
_fftof
(
dbg
,
block
,
new_op
,
src_mode
,
dst_mode
);
}
else
{
/* float -> int conv */
if
(
!
mode_is_signed
(
dst_mode
))
panic
(
"float to unsigned not implemented yet"
);
return
new_bd_sparc_f
ftoi
(
dbg
,
block
,
new_op
,
src_mode
);
return
create_
ftoi
(
dbg
,
block
,
new_op
,
src_mode
);
}
}
else
{
/* int -> float conv */
if
(
!
mode_is_signed
(
src_mode
))
panic
(
"unsigned to float not implemented yet"
);
return
new_bd_sparc_f
itof
(
dbg
,
block
,
new_op
,
dst_mode
);
return
create_
itof
(
dbg
,
block
,
new_op
,
dst_mode
);
}
}
else
{
/* complete in gp registers */
int
min_bits
;
...
...
@@ -972,7 +1104,7 @@ static ir_node *bitcast_int_to_float(dbg_info *dbgi, ir_node *block,
mode
=
mode_fp
;
}
ldf
=
new_bd_sparc_L
df
(
dbgi
,
block
,
sp
,
mem
,
mode
,
NULL
,
0
,
0
,
true
);
ldf
=
create_l
df
(
dbgi
,
block
,
sp
,
mem
,
mode
,
NULL
,
0
,
0
,
true
);
set_irn_pinned
(
ldf
,
op_pin_state_floats
);
return
new_Proj
(
ldf
,
mode
,
pn_sparc_Ldf_res
);
...
...
@@ -985,8 +1117,8 @@ static void bitcast_float_to_int(dbg_info *dbgi, ir_node *block,
ir_graph
*
irg
=
current_ir_graph
;
ir_node
*
stack
=
get_irg_frame
(
irg
);
ir_node
*
nomem
=
new_NoMem
();
ir_node
*
stf
=
new_bd_sparc_S
tf
(
dbgi
,
block
,
stack
,
node
,
nomem
,
float_mode
,
NULL
,
0
,
0
,
true
);
ir_node
*
stf
=
create_s
tf
(
dbgi
,
block
,
stack
,
node
,
nomem
,
float_mode
,
NULL
,
0
,
0
,
true
);
int
bits
=
get_mode_size_bits
(
float_mode
);
ir_node
*
ld
;
set_irn_pinned
(
stf
,
op_pin_state_floats
);
...
...
@@ -1105,12 +1237,13 @@ static ir_node *gen_Call(ir_node *node)
/* create a parameter frame if necessary */
if
(
mode_is_float
(
mode
))
{
str
=
new_bd_sparc_S
tf
(
dbgi
,
new_block
,
incsp
,
new_value
,
new_mem
,
mode
,
NULL
,
0
,
param
->
offset
,
true
);
str
=
create_s
tf
(
dbgi
,
new_block
,
incsp
,
new_value
,
new_mem
,
mode
,
NULL
,
0
,
param
->
offset
,
true
);
}
else
{
str
=
new_bd_sparc_St
(
dbgi
,
new_block
,
incsp
,
new_value
,
new_mem
,
mode
,
NULL
,
0
,
param
->
offset
,
true
);
}
set_irn_pinned
(
str
,
op_pin_state_floats
);
sync_ins
[
sync_arity
++
]
=
str
;
}
assert
(
in_arity
<=
max_inputs
);
...
...
@@ -1193,6 +1326,47 @@ static ir_node *gen_Sel(ir_node *node)
return
new_bd_sparc_FrameAddr
(
dbgi
,
new_block
,
new_ptr
,
entity
);
}
static
const
arch_register_req_t
float1_req
=
{
arch_register_req_type_normal
,
&
sparc_reg_classes
[
CLASS_sparc_fp
],
NULL
,
0
,
0
,
1
};
static
const
arch_register_req_t
float2_req
=
{
arch_register_req_type_normal
|
arch_register_req_type_aligned
,
&
sparc_reg_classes
[
CLASS_sparc_fp
],
NULL
,
0
,
0
,
2
};
static
const
arch_register_req_t
float4_req
=
{
arch_register_req_type_normal
|
arch_register_req_type_aligned
,
&
sparc_reg_classes
[
CLASS_sparc_fp
],
NULL
,
0
,
0
,
4
};
static
const
arch_register_req_t
*
get_float_req
(
ir_mode
*
mode
)
{
unsigned
bits
=
get_mode_size_bits
(
mode
);
assert
(
mode_is_float
(
mode
));
if
(
bits
==
32
)
{
return
&
float1_req
;
}
else
if
(
bits
==
64
)
{
return
&
float2_req
;
}
else
{
assert
(
bits
==
128
);
return
&
float4_req
;
}
}
/**
* Transform some Phi nodes
*/
...
...
@@ -1211,6 +1385,9 @@ static ir_node *gen_Phi(ir_node *node)
/* all integer operations are on 32bit registers now */
mode
=
mode_gp
;
req
=
sparc_reg_classes
[
CLASS_sparc_gp
].
class_req
;
}
else
if
(
mode_is_float
(
mode
))
{
mode
=
mode
;
req
=
get_float_req
(
mode
);
}
else
{
req
=
arch_no_register_req
;