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
b603a714
Commit
b603a714
authored
Jun 13, 2007
by
Matthias Braun
Browse files
don't fail if type mode can't be determine (which can happen when passing structs)
[r14479]
parent
f6590e7b
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/bearch_ia32.c
View file @
b603a714
...
...
@@ -1603,11 +1603,13 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_cal
for
(
i
=
0
;
i
<
n
;
i
++
)
{
const
ir_mode
*
mode
;
const
arch_register_t
*
reg
;
const
arch_register_t
*
reg
=
NULL
;
tp
=
get_method_param_type
(
method_type
,
i
);
mode
=
get_type_mode
(
tp
);
reg
=
ia32_get_RegParam_reg
(
isa
->
cg
,
cc
,
i
,
mode
);
if
(
mode
!=
NULL
)
{
reg
=
ia32_get_RegParam_reg
(
isa
->
cg
,
cc
,
i
,
mode
);
}
if
(
reg
!=
NULL
)
{
be_abi_call_param_reg
(
abi
,
i
,
reg
);
...
...
ir/be/ia32/ia32_emitter.c
View file @
b603a714
...
...
@@ -387,77 +387,93 @@ void ia32_emit_function_size(ia32_emit_env_t *env, const char *name)
}
static
void
emit_ia32_Immediate
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
/**
* Emits registers and/or address mode of a binary operation.
*/
void
ia32_emit_binop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
)
{
switch
(
get_ia32_op_type
(
node
))
{
case
ia32_Normal
:
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
ia32_emit_immediate
(
env
,
node
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_source_register
(
env
,
node
,
2
);
}
else
{
const
arch_register_t
*
in1
=
get_in_reg
(
env
,
node
,
2
);
const
arch_register_t
*
in2
=
get_in_reg
(
env
,
node
,
3
);
const
arch_register_t
*
out
=
produces_result
(
node
)
?
get_out_reg
(
env
,
node
,
0
)
:
NULL
;
const
arch_register_t
*
in
;
const
char
*
in_name
;
in
=
out
?
(
REGS_ARE_EQUAL
(
out
,
in2
)
?
in1
:
in2
)
:
in2
;
out
=
out
?
out
:
in1
;
in_name
=
arch_register_get_name
(
in
);
const
ir_node
*
right_op
;
if
(
is_ia32_emit_cl
(
node
))
{
assert
(
REGS_ARE_EQUAL
(
&
ia32_gp_regs
[
REG_ECX
],
in
)
&&
"shift operation needs ecx"
);
in_name
=
"cl"
;
}
be_emit_char
(
env
,
'%'
);
be_emit_string
(
env
,
in_name
);
be_emit_cstring
(
env
,
", %"
);
be_emit_string
(
env
,
arch_register_get_name
(
out
));
}
switch
(
get_ia32_op_type
(
node
))
{
case
ia32_Normal
:
right_op
=
get_irn_n
(
node
,
3
);
if
(
is_ia32_Immediate
(
right_op
))
{
emit_ia32_Immediate
(
env
,
right_op
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_source_register
(
env
,
node
,
2
);
break
;
case
ia32_AddrModeS
:
ia32_emit_
am
(
env
,
node
);
}
else
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
ia32_emit_
immediate
(
env
,
node
);
be_emit_cstring
(
env
,
", "
);
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
assert
(
!
produces_result
(
node
)
&&
"Source AM with Const must not produce result"
);
ia32_emit_immediate
(
env
,
node
);
}
else
if
(
produces_result
(
node
))
{
ia32_emit_dest_register
(
env
,
node
,
0
);
}
else
{
ia32_emit_source_register
(
env
,
node
,
2
);
ia32_emit_source_register
(
env
,
node
,
2
);
}
else
{
const
arch_register_t
*
in1
=
get_in_reg
(
env
,
node
,
2
);
const
arch_register_t
*
in2
=
get_in_reg
(
env
,
node
,
3
);
const
arch_register_t
*
out
=
produces_result
(
node
)
?
get_out_reg
(
env
,
node
,
0
)
:
NULL
;
const
arch_register_t
*
in
;
const
char
*
in_name
;
in
=
out
?
(
REGS_ARE_EQUAL
(
out
,
in2
)
?
in1
:
in2
)
:
in2
;
out
=
out
?
out
:
in1
;
in_name
=
arch_register_get_name
(
in
);
if
(
is_ia32_emit_cl
(
node
))
{
assert
(
REGS_ARE_EQUAL
(
&
ia32_gp_regs
[
REG_ECX
],
in
)
&&
"shift operation needs ecx"
);
in_name
=
"cl"
;
}
break
;
case
ia32_AddrModeD
:
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
ia32_emit_immediate
(
env
,
node
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_am
(
env
,
node
);
}
else
{
const
arch_register_t
*
in1
=
get_in_reg
(
env
,
node
,
get_irn_arity
(
node
)
==
5
?
3
:
2
);
ir_mode
*
mode
=
get_ia32_ls_mode
(
node
);
const
char
*
in_name
;
in_name
=
ia32_get_reg_name_for_mode
(
env
,
mode
,
in1
);
be_emit_char
(
env
,
'%'
);
be_emit_string
(
env
,
in_name
);
be_emit_cstring
(
env
,
", %"
);
be_emit_string
(
env
,
arch_register_get_name
(
out
));
}
break
;
case
ia32_AddrModeS
:
ia32_emit_am
(
env
,
node
);
be_emit_cstring
(
env
,
", "
);
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
assert
(
!
produces_result
(
node
)
&&
"Source AM with Const must not produce result"
);
ia32_emit_immediate
(
env
,
node
);
}
else
if
(
produces_result
(
node
))
{
ia32_emit_dest_register
(
env
,
node
,
0
);
}
else
{
ia32_emit_source_register
(
env
,
node
,
2
);
}
break
;
case
ia32_AddrModeD
:
right_op
=
get_irn_n
(
node
,
3
);
if
(
is_ia32_Immediate
(
right_op
))
{
emit_ia32_Immediate
(
env
,
right_op
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_am
(
env
,
node
);
break
;
}
else
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
ia32_emit_immediate
(
env
,
node
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_am
(
env
,
node
);
}
else
{
const
arch_register_t
*
in1
=
get_in_reg
(
env
,
node
,
get_irn_arity
(
node
)
==
5
?
3
:
2
);
ir_mode
*
mode
=
get_ia32_ls_mode
(
node
);
const
char
*
in_name
;
if
(
is_ia32_emit_cl
(
node
))
{
assert
(
REGS_ARE_EQUAL
(
&
ia32_gp_regs
[
REG_ECX
],
in1
)
&&
"shift operation needs ecx"
);
in_name
=
"cl"
;
}
in_name
=
ia32_get_reg_name_for_mode
(
env
,
mode
,
in1
);
be_emit_char
(
env
,
'%'
);
be_emit_string
(
env
,
in_name
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_am
(
env
,
node
);
if
(
is_ia32_emit_cl
(
node
))
{
assert
(
REGS_ARE_EQUAL
(
&
ia32_gp_regs
[
REG_ECX
],
in1
)
&&
"shift operation needs ecx"
);
in_name
=
"cl"
;
}
break
;
default:
assert
(
0
&&
"unsupported op type"
);
be_emit_char
(
env
,
'%'
);
be_emit_string
(
env
,
in_name
);
be_emit_cstring
(
env
,
", "
);
ia32_emit_am
(
env
,
node
);
}
break
;
default:
assert
(
0
&&
"unsupported op type"
);
}
}
...
...
@@ -495,34 +511,39 @@ void ia32_emit_x87_binop(ia32_emit_env_t *env, const ir_node *node) {
}
}
void
ia32_emit_am_or_dest_register
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
,
int
pos
)
{
if
(
get_ia32_op_type
(
node
)
==
ia32_Normal
)
{
ia32_emit_dest_register
(
env
,
node
,
pos
);
}
else
{
assert
(
get_ia32_op_type
(
node
)
==
ia32_AddrModeD
);
ia32_emit_am
(
env
,
node
);
}
}
/**
* Emits registers and/or address mode of a unary operation.
*/
void
ia32_emit_unop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
)
{
void
ia32_emit_unop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
,
int
pos
)
{
const
ir_node
*
op
;
switch
(
get_ia32_op_type
(
node
))
{
case
ia32_Normal
:
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
ia32_emit_immediate
(
env
,
node
);
}
else
{
if
(
is_ia32_Mul
(
node
)
||
is_ia32_IMul1OP
(
node
))
{
ia32_emit_source_register
(
env
,
node
,
3
);
}
else
if
(
is_ia32_IDiv
(
node
)
||
is_ia32_Div
(
node
))
{
ia32_emit_source_register
(
env
,
node
,
4
);
}
else
if
(
is_ia32_Push
(
node
))
{
ia32_emit_source_register
(
env
,
node
,
2
);
}
else
if
(
is_ia32_Pop
(
node
))
{
ia32_emit_dest_register
(
env
,
node
,
1
);
}
else
{
ia32_emit_dest_register
(
env
,
node
,
0
);
}
}
break
;
case
ia32_AddrModeS
:
case
ia32_AddrModeD
:
ia32_emit_am
(
env
,
node
);
break
;
default:
assert
(
0
&&
"unsupported op type"
);
case
ia32_Normal
:
op
=
get_irn_n
(
node
,
pos
);
if
(
is_ia32_Immediate
(
op
))
{
emit_ia32_Immediate
(
env
,
op
);
}
else
if
(
is_ia32_ImmConst
(
node
)
||
is_ia32_ImmSymConst
(
node
))
{
ia32_emit_immediate
(
env
,
node
);
}
else
{
ia32_emit_source_register
(
env
,
node
,
pos
);
}
break
;
case
ia32_AddrModeS
:
case
ia32_AddrModeD
:
ia32_emit_am
(
env
,
node
);
break
;
default:
assert
(
0
&&
"unsupported op type"
);
}
}
...
...
@@ -1317,6 +1338,7 @@ void emit_ia32_Immediate(ia32_emit_env_t *env, const ir_node *node)
{
const
ia32_attr_t
*
attr
=
get_ia32_attr_const
(
node
);
assert
(
attr
->
am_sc
!=
NULL
||
attr
->
cnst_val
.
tv
!=
NULL
);
if
(
attr
->
am_sc
!=
NULL
)
{
ident
*
id
=
get_entity_ld_ident
(
attr
->
am_sc
);
...
...
ir/be/ia32/ia32_emitter.h
View file @
b603a714
...
...
@@ -52,7 +52,9 @@ void ia32_emit_xmm_mode_suffix(ia32_emit_env_t *env, const ir_node *node);
void
ia32_emit_xmm_mode_suffix_s
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
void
ia32_emit_extend_suffix
(
ia32_emit_env_t
*
env
,
const
ir_mode
*
mode
);
void
ia32_emit_binop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
void
ia32_emit_unop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
void
ia32_emit_am_or_dest_register
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
,
int
pos
);
void
ia32_emit_unop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
,
int
pos
);
void
ia32_emit_am
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
void
ia32_emit_adr
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
void
ia32_emit_x87_binop
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
);
...
...
ir/be/ia32/ia32_spec.pl
View file @
b603a714
...
...
@@ -271,7 +271,13 @@ $arch = "ia32";
XXM
=>
"
${arch}
_emit_xmm_mode_suffix(env, node);
",
XSD
=>
"
${arch}
_emit_xmm_mode_suffix_s(env, node);
",
AM
=>
"
${arch}
_emit_am(env, node);
",
unop
=>
"
${arch}
_emit_unop(env, node);
",
unop0
=>
"
${arch}
_emit_unop(env, node, 0);
",
unop1
=>
"
${arch}
_emit_unop(env, node, 1);
",
unop2
=>
"
${arch}
_emit_unop(env, node, 2);
",
unop3
=>
"
${arch}
_emit_unop(env, node, 3);
",
unop4
=>
"
${arch}
_emit_unop(env, node, 4);
",
DAM0
=>
"
${arch}
_emit_am_or_dest_register(env, node, 0);
",
DAM1
=>
"
${arch}
_emit_am_or_dest_register(env, node, 0);
",
binop
=>
"
${arch}
_emit_binop(env, node);
",
x87_binop
=>
"
${arch}
_emit_x87_binop(env, node);
",
);
...
...
@@ -404,8 +410,9 @@ Mul => {
# we should not rematrialize this node. It produces 2 results and has
# very strict constrains
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
eax
",
"
gp
",
"
none
"
],
out
=>
[
"
eax
",
"
edx
",
"
none
"
]
},
emit
=>
'
. mul%M %unop
',
emit
=>
'
. mul%M %unop
3
',
outs
=>
[
"
EAX
",
"
EDX
",
"
M
"
],
ins
=>
[
"
base
",
"
index
",
"
val_high
",
"
val_low
",
"
mem
"
],
latency
=>
10
,
units
=>
[
"
GP
"
],
modified_flags
=>
$status_flags
...
...
@@ -433,8 +440,9 @@ IMul => {
IMul1OP
=>
{
irn_flags
=>
"
R
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
eax
",
"
gp
",
"
none
"
],
out
=>
[
"
eax
",
"
edx
",
"
none
"
]
},
emit
=>
'
. imul%M %unop
',
emit
=>
'
. imul%M %unop
3
',
outs
=>
[
"
EAX
",
"
EDX
",
"
M
"
],
ins
=>
[
"
base
",
"
index
",
"
val_high
",
"
val_low
",
"
mem
"
],
latency
=>
5
,
units
=>
[
"
GP
"
],
modified_flags
=>
$status_flags
...
...
@@ -531,7 +539,7 @@ IDiv => {
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
eax
",
"
edx
",
"
gp
",
"
none
"
],
out
=>
[
"
eax
",
"
edx
",
"
none
"
]
},
attr
=>
"
ia32_op_flavour_t dm_flav
",
init_attr
=>
"
attr->data.op_flav = dm_flav;
",
emit
=>
"
. idiv%M %unop
",
emit
=>
"
. idiv%M %unop
4
",
outs
=>
[
"
div_res
",
"
mod_res
",
"
M
"
],
latency
=>
25
,
units
=>
[
"
GP
"
],
...
...
@@ -544,7 +552,7 @@ Div => {
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
eax
",
"
edx
",
"
gp
",
"
none
"
],
out
=>
[
"
eax
",
"
edx
",
"
none
"
]
},
attr
=>
"
ia32_op_flavour_t dm_flav
",
init_attr
=>
"
attr->data.op_flav = dm_flav;
",
emit
=>
"
. div%M %unop
",
emit
=>
"
. div%M %unop
4
",
outs
=>
[
"
div_res
",
"
mod_res
",
"
M
"
],
latency
=>
25
,
units
=>
[
"
GP
"
],
...
...
@@ -696,7 +704,8 @@ Rol => {
Neg
=>
{
irn_flags
=>
"
R
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
in_r3
"
]
},
emit
=>
'
. neg%M %unop
',
emit
=>
'
. neg%M %unop2
',
ins
=>
[
"
base
",
"
index
",
"
val
",
"
mem
"
],
units
=>
[
"
GP
"
],
mode
=>
$mode_gp
,
modified_flags
=>
$status_flags
...
...
@@ -725,7 +734,7 @@ l_Neg => {
Inc
=>
{
irn_flags
=>
"
R
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
in_r3
"
]
},
emit
=>
'
. inc%M %unop
',
emit
=>
'
. inc%M %unop
2
',
units
=>
[
"
GP
"
],
mode
=>
$mode_gp
,
modified_flags
=>
[
"
OF
",
"
SF
",
"
ZF
",
"
AF
",
"
PF
"
]
...
...
@@ -734,7 +743,7 @@ Inc => {
Dec
=>
{
irn_flags
=>
"
R
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
in_r3
"
]
},
emit
=>
'
. dec%M %unop
',
emit
=>
'
. dec%M %unop
2
',
units
=>
[
"
GP
"
],
mode
=>
$mode_gp
,
modified_flags
=>
[
"
OF
",
"
SF
",
"
ZF
",
"
AF
",
"
PF
"
]
...
...
@@ -743,7 +752,7 @@ Dec => {
Not
=>
{
irn_flags
=>
"
R
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
in_r3
"
]
},
emit
=>
'
. not%M %unop
',
emit
=>
'
. not%M %unop
2
',
units
=>
[
"
GP
"
],
mode
=>
$mode_gp
,
modified_flags
=>
[]
...
...
@@ -962,7 +971,8 @@ Lea => {
Push
=>
{
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
esp
",
"
none
"
],
out
=>
[
"
esp
",
"
none
"
]
},
emit
=>
'
. push%M %unop
',
emit
=>
'
. push%M %unop2
',
ins
=>
[
"
base
",
"
index
",
"
val
",
"
stack
",
"
mem
"
],
outs
=>
[
"
stack:I|S
",
"
M
"
],
latency
=>
3
,
units
=>
[
"
GP
"
],
...
...
@@ -971,8 +981,9 @@ Push => {
Pop
=>
{
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
esp
",
"
none
"
],
out
=>
[
"
esp
",
"
gp
",
"
none
"
]
},
emit
=>
'
. pop%M %
unop
',
emit
=>
'
. pop%M %
DAM1
',
outs
=>
[
"
stack:I|S
",
"
res
",
"
M
"
],
ins
=>
[
"
base
",
"
index
",
"
stack
",
"
mem
"
],
latency
=>
4
,
units
=>
[
"
GP
"
],
modified_flags
=>
[]
,
...
...
@@ -1206,7 +1217,7 @@ CvtSI2SS => {
CvtSI2SD
=>
{
op_flags
=>
"
L|F
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
xmm
"
]
},
emit
=>
'
. cvtsi2sd %unop
',
emit
=>
'
. cvtsi2sd %unop
2
',
latency
=>
2
,
units
=>
[
"
SSE
"
],
mode
=>
$mode_xmm
...
...
ir/be/ia32/ia32_transform.c
View file @
b603a714
...
...
@@ -126,6 +126,8 @@ typedef ir_node *(transform_func)(ir_node *node);
static
ir_node
*
duplicate_node
(
ir_node
*
node
);
static
ir_node
*
transform_node
(
ir_node
*
node
);
static
void
duplicate_deps
(
ir_node
*
old_node
,
ir_node
*
new_node
);
static
ir_node
*
try_create_Immediate
(
ir_node
*
node
,
char
immediate_constraint_type
);
static
INLINE
int
mode_needs_gp_reg
(
ir_mode
*
mode
)
{
...
...
@@ -524,6 +526,7 @@ static void fold_immediate(ir_node *node, int in1, int in2) {
return
;
}
clear_ia32_commutative
(
node
);
set_ia32_am_support
(
node
,
get_ia32_am_support
(
node
)
&
~
ia32_am_Source
);
}
...
...
@@ -536,17 +539,38 @@ static void fold_immediate(ir_node *node, int in1, int in2) {
* @return The constructed ia32 node.
*/
static
ir_node
*
gen_binop
(
ir_node
*
node
,
ir_node
*
op1
,
ir_node
*
op2
,
construct_binop_func
*
func
)
construct_binop_func
*
func
,
int
commutative
)
{
ir_node
*
block
=
transform_node
(
get_nodes_block
(
node
));
ir_node
*
new_op1
=
transform_node
(
op1
)
;
ir_node
*
new_op2
=
transform_node
(
op2
)
;
ir_node
*
new_op1
=
NULL
;
ir_node
*
new_op2
=
NULL
;
ir_node
*
new_node
=
NULL
;
ir_graph
*
irg
=
env
.
irg
;
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
noreg_gp
=
ia32_new_NoReg_gp
(
env
.
cg
);
ir_node
*
nomem
=
new_NoMem
();
if
(
commutative
)
{
new_op2
=
try_create_Immediate
(
op1
,
0
);
if
(
new_op2
!=
NULL
)
{
new_op1
=
transform_node
(
op2
);
commutative
=
0
;
}
}
if
(
new_op2
==
NULL
)
{
new_op2
=
try_create_Immediate
(
op2
,
0
);
if
(
new_op2
!=
NULL
)
{
new_op1
=
transform_node
(
op1
);
commutative
=
0
;
}
}
if
(
new_op2
==
NULL
)
{
new_op1
=
transform_node
(
op1
);
new_op2
=
transform_node
(
op2
);
}
new_node
=
func
(
dbgi
,
irg
,
block
,
noreg_gp
,
noreg_gp
,
new_op1
,
new_op2
,
nomem
);
if
(
func
==
new_rd_ia32_IMul
)
{
set_ia32_am_support
(
new_node
,
ia32_am_Source
);
...
...
@@ -555,10 +579,9 @@ static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
}
SET_IA32_ORIG_NODE
(
new_node
,
ia32_get_old_node_name
(
env
.
cg
,
node
));
if
(
is_op_
commutative
(
get_irn_op
(
node
))
)
{
if
(
commutative
)
{
set_ia32_commutative
(
new_node
);
}
fold_immediate
(
new_node
,
2
,
3
);
return
new_node
;
}
...
...
@@ -700,7 +723,6 @@ static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func)
return
new_node
;
}
/**
* Creates an ia32 Add.
*
...
...
@@ -887,7 +909,7 @@ static ir_node *gen_Mul(ir_node *node) {
signed or unsigned multiplication so we use IMul as it has fewer
constraints
*/
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_IMul
);
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_IMul
,
1
);
}
/**
...
...
@@ -944,7 +966,7 @@ static ir_node *gen_And(ir_node *node) {
ir_node
*
op2
=
get_And_right
(
node
);
assert
(
!
mode_is_float
(
get_irn_mode
(
node
)));
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_And
);
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_And
,
1
);
}
...
...
@@ -959,7 +981,7 @@ static ir_node *gen_Or(ir_node *node) {
ir_node
*
op2
=
get_Or_right
(
node
);
assert
(
!
mode_is_float
(
get_irn_mode
(
node
)));
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_Or
);
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_Or
,
1
);
}
...
...
@@ -974,7 +996,7 @@ static ir_node *gen_Eor(ir_node *node) {
ir_node
*
op2
=
get_Eor_right
(
node
);
assert
(
!
mode_is_float
(
get_irn_mode
(
node
)));
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_Xor
);
return
gen_binop
(
node
,
op1
,
op2
,
new_rd_ia32_Xor
,
1
);
}
...
...
@@ -1961,6 +1983,19 @@ static ir_node *gen_CopyB(ir_node *node) {
return
res
;
}
static
ir_node
*
gen_be_Copy
(
ir_node
*
node
)
{
ir_node
*
result
=
duplicate_node
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
result
);
if
(
mode_needs_gp_reg
(
mode
))
{
set_irn_mode
(
result
,
mode_Iu
);
}
return
result
;
}
#if 0
/**
...
...
@@ -2118,14 +2153,14 @@ static ir_node *gen_Psi(ir_node *node) {
else
{
if
(
is_ia32_Const_1
(
psi_true
)
&&
is_ia32_Const_0
(
psi_default
))
{
/* first case for SETcc: default is 0, set to 1 iff condition is true */
new_op
=
gen_binop
(
node
,
cmp_a
,
cmp_b
,
set_func
);
new_op
=
gen_binop
(
node
,
cmp_a
,
cmp_b
,
set_func
,
0
);
set_ia32_pncode
(
new_op
,
pnc
);
set_ia32_am_support
(
new_op
,
ia32_am_Source
);
}
else
if
(
is_ia32_Const_0
(
psi_true
)
&&
is_ia32_Const_1
(
psi_default
))
{
/* second case for SETcc: default is 1, set to 0 iff condition is true: */
/* we invert condition and set default to 0 */
new_op
=
gen_binop
(
node
,
cmp_a
,
cmp_b
,
set_func
);
new_op
=
gen_binop
(
node
,
cmp_a
,
cmp_b
,
set_func
,
0
);
set_ia32_pncode
(
new_op
,
get_inversed_pnc
(
pnc
));
set_ia32_am_support
(
new_op
,
ia32_am_Source
);
}
...
...
@@ -2294,6 +2329,12 @@ static ir_node *gen_Conv(ir_node *node) {
if
(
mode_is_float
(
src_mode
))
{
/* we convert from float ... */
if
(
mode_is_float
(
tgt_mode
))
{
if
(
src_mode
==
mode_E
&&
tgt_mode
==
mode_D
&&
!
get_Conv_strict
(
node
))
{
DB
((
dbg
,
LEVEL_1
,
"killed Conv(mode, mode) ..."
));
return
new_op
;
}
/* ... to float */
if
(
USE_SSE2
(
env
.
cg
))
{
DB
((
dbg
,
LEVEL_1
,
"create Conv(float, float) ..."
));
...
...
@@ -2397,6 +2438,7 @@ int check_immediate_constraint(tarval *tv, char immediate_constraint_type)
return
0
;
}
static
ir_node
*
try_create_Immediate
(
ir_node
*
node
,
char
immediate_constraint_type
)
{
int
minus
=
0
;
...
...
@@ -2447,8 +2489,8 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type)
offset_sign
=
minus
;
}
}
else
if
(
is_Sub
(
node
))
{
ir_node
*
left
=
get_
Add
_left
(
node
);
ir_node
*
right
=
get_
Add
_right
(
node
);
ir_node
*
left
=
get_
Sub
_left
(
node
);
ir_node
*
right
=
get_
Sub
_right
(
node
);
if
(
is_Const
(
left
)
&&
is_SymConst
(
right
))
{
cnst
=
left
;
symconst
=
right
;
...
...
@@ -2485,6 +2527,8 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type)
return
NULL
;
symconst_ent
=
get_SymConst_entity
(
symconst
);
}
if
(
cnst
==
NULL
&&
symconst
==
NULL
)
return
NULL
;
irg
=
env
.
irg
;
dbgi
=
get_irn_dbg_info
(
node
);
...
...
@@ -2614,6 +2658,7 @@ void parse_asm_constraint(ir_node *node, int pos, constraint_t *constraint,
case
'f'
:
case
't'
:
case
'u'
:
/* TODO: mark values so the x87 simulator knows about t and u */
assert
(
cls
==
NULL
);
cls
=
&
ia32_reg_classes
[
CLASS_ia32_vfp
];
break
;
...
...
@@ -3373,13 +3418,13 @@ static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func, char
* @param env The transformation environment
* @return the created ia32 XXX node
*/
#define GEN_LOWERED_OP(op)
\
static ir_node *gen_ia32_l_##op(ir_node *node) {\
ir_mode *mode = get_irn_mode(node);
\
if (mode_is_float(mode))
\
FP_USED(env.cg);
\
#define GEN_LOWERED_OP(op) \
static ir_node *gen_ia32_l_##op(ir_node *node) {
\
ir_mode *mode = get_irn_mode(node); \
if (mode_is_float(mode)) \
FP_USED(env.cg); \
return gen_binop(node, get_binop_left(node), \
get_binop_right(node), new_rd_ia32_##op);
\
get_binop_right(node), new_rd_ia32_##op
,0
); \
}
#define GEN_LOWERED_x87_OP(op) \
...
...
@@ -4235,6 +4280,7 @@ static void register_transformers(void) {
GEN
(
be_StackParam
);
GEN
(
be_AddSP
);
GEN
(
be_SubSP
);
GEN
(
be_Copy
);
/* set the register for all Unknown nodes */
GEN
(
Unknown
);
...
...
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