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
fecb5663
Commit
fecb5663
authored
Jun 28, 2010
by
Robin Redeker
Browse files
amd64: implemented Store, Mul and Sub.
[r27667]
parent
ca8f7598
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_emitter.c
View file @
fecb5663
...
...
@@ -115,6 +115,12 @@ static const arch_register_t *get_out_reg(const ir_node *node, int pos)
* |_| |_|
*************************************************************/
void
amd64_emit_register
(
const
arch_register_t
*
reg
)
{
be_emit_char
(
'%'
);
be_emit_string
(
arch_register_get_name
(
reg
));
}
void
amd64_emit_immediate
(
const
ir_node
*
node
)
{
const
amd64_attr_t
*
attr
=
get_amd64_attr_const
(
node
);
...
...
@@ -124,16 +130,12 @@ void amd64_emit_immediate(const ir_node *node)
void
amd64_emit_source_register
(
const
ir_node
*
node
,
int
pos
)
{
const
arch_register_t
*
reg
=
get_in_reg
(
node
,
pos
);
be_emit_char
(
'%'
);
be_emit_string
(
arch_register_get_name
(
reg
));
amd64_emit_register
(
get_in_reg
(
node
,
pos
));
}
void
amd64_emit_dest_register
(
const
ir_node
*
node
,
int
pos
)
{
const
arch_register_t
*
reg
=
get_out_reg
(
node
,
pos
);
be_emit_char
(
'%'
);
be_emit_string
(
arch_register_get_name
(
reg
));
amd64_emit_register
(
get_out_reg
(
node
,
pos
));
}
/**
...
...
@@ -367,18 +369,41 @@ static void emit_amd64_FrameAddr(const ir_node *irn)
const
amd64_SymConst_attr_t
*
attr
=
get_irn_generic_attr_const
(
irn
);
be_emit_cstring
(
"
\t
mov "
);
amd64_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
amd64_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
amd64_emit_dest_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
be_emit_cstring
(
"
\t
add "
);
amd64_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
be_emit_irprintf
(
"$0x%X"
,
attr
->
fp_offset
);
be_emit_cstring
(
", "
);
amd64_emit_dest_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
}
/**
* Emits code to increase stack pointer.
*/
static
void
emit_be_IncSP
(
const
ir_node
*
node
)
{
int
offs
=
be_get_IncSP_offset
(
node
);
if
(
offs
==
0
)
return
;
if
(
offs
>
0
)
{
be_emit_irprintf
(
"
\t
sub "
);
amd64_emit_dest_register
(
node
,
0
);
be_emit_irprintf
(
", $%u"
,
offs
);
be_emit_finish_line_gas
(
node
);
}
else
{
be_emit_irprintf
(
"
\t
add "
);
amd64_emit_dest_register
(
node
,
0
);
be_emit_irprintf
(
", $%u"
,
-
offs
);
be_emit_finish_line_gas
(
node
);
}
}
/**
* Emits code for a return.
*/
...
...
@@ -388,6 +413,51 @@ static void emit_be_Return(const ir_node *node)
be_emit_finish_line_gas
(
node
);
}
static
void
emit_amd64_binop_op
(
const
ir_node
*
irn
,
int
second_op
)
{
if
(
irn
->
op
==
op_amd64_Add
)
{
be_emit_cstring
(
"
\t
add "
);
}
else
if
(
irn
->
op
==
op_amd64_Mul
)
{
be_emit_cstring
(
"
\t
mul "
);
}
else
if
(
irn
->
op
==
op_amd64_Sub
)
{
be_emit_cstring
(
"
\t
sub "
);
}
amd64_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
amd64_emit_source_register
(
irn
,
second_op
);
be_emit_finish_line_gas
(
irn
);
}
/**
* Emits an arithmetic operation that handles arbitraty input registers.
*/
static
void
emit_amd64_binop
(
const
ir_node
*
irn
)
{
const
arch_register_t
*
reg_s1
=
get_in_reg
(
irn
,
0
);
const
arch_register_t
*
reg_s2
=
get_in_reg
(
irn
,
1
);
const
arch_register_t
*
reg_d1
=
get_out_reg
(
irn
,
0
);
int
second_op
=
0
;
if
(
reg_d1
!=
reg_s1
&&
reg_d1
!=
reg_s2
)
{
be_emit_cstring
(
"
\t
mov "
);
amd64_emit_register
(
reg_s1
);
be_emit_cstring
(
", "
);
amd64_emit_register
(
reg_d1
);
be_emit_finish_line_gas
(
irn
);
second_op
=
1
;
}
else
if
(
reg_d1
==
reg_s2
&&
reg_d1
!=
reg_s1
)
{
second_op
=
0
;
}
emit_amd64_binop_op
(
irn
,
second_op
);
}
/**
* The type of a emitter function.
*/
...
...
@@ -420,11 +490,14 @@ static void amd64_register_emitters(void)
set_emitter
(
op_be_Return
,
emit_be_Return
);
set_emitter
(
op_be_Call
,
emit_be_Call
);
set_emitter
(
op_be_Copy
,
emit_be_Copy
);
set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
set_emitter
(
op_amd64_Add
,
emit_amd64_binop
);
set_emitter
(
op_amd64_Mul
,
emit_amd64_binop
);
set_emitter
(
op_be_Start
,
emit_nothing
);
set_emitter
(
op_be_Keep
,
emit_nothing
);
set_emitter
(
op_be_Barrier
,
emit_nothing
);
set_emitter
(
op_be_IncSP
,
emit_nothing
);
set_emitter
(
op_Phi
,
emit_nothing
);
}
...
...
ir/be/amd64/amd64_emitter.h
View file @
fecb5663
...
...
@@ -34,6 +34,7 @@
#include
"bearch_amd64_t.h"
void
amd64_emit_register
(
const
arch_register_t
*
reg
);
void
amd64_emit_source_register
(
const
ir_node
*
node
,
int
pos
);
void
amd64_emit_dest_register
(
const
ir_node
*
node
,
int
pos
);
void
amd64_emit_immediate
(
const
ir_node
*
node
);
...
...
ir/be/amd64/amd64_spec.pl
View file @
fecb5663
...
...
@@ -203,22 +203,43 @@ Push => {
# units => [ "GP" ],
},
Add
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
in
=>
[
"
left
",
"
right
"
],
emit
=>
"
. mov %D1, %S2
\n
"
.
"
. add %D1, %S1
\n
",
outs
=>
[
"
res
"
],
mode
=>
$mode_gp
,
modified_flags
=>
1
,
},
Mul
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
in
=>
[
"
left
",
"
right
"
],
outs
=>
[
"
res
"
],
mode
=>
$mode_gp
,
modified_flags
=>
1
,
},
Sub
=>
{
irn_flags
=>
"
R
",
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
in
=>
[
"
left
",
"
right
"
],
outs
=>
[
"
res
"
],
mode
=>
$mode_gp
,
modified_flags
=>
1
,
},
Immediate
=>
{
op_flags
=>
"
c
",
attr
=>
"
unsigned imm_value
",
init_attr
=>
"
attr->ext.imm_value = imm_value;
",
reg_req
=>
{
out
=>
[
"
gp
"
]
},
emit
=>
'
. mov
q
%
D1
, %
C
',
emit
=>
'
. mov %
C
, %
D1
',
mode
=>
$mode_gp
,
},
SymConst
=>
{
...
...
@@ -275,7 +296,7 @@ Load => {
out
=>
[
"
gp
",
"
none
"
]
},
ins
=>
[
"
ptr
",
"
mem
"
],
outs
=>
[
"
res
",
"
M
"
],
emit
=>
"
.
lea %D1, [%S1]
"
emit
=>
"
.
mov (%S1), %D1
"
},
FrameAddr
=>
{
op_flags
=>
"
c
",
...
...
@@ -286,15 +307,15 @@ FrameAddr => {
attr_type
=>
"
amd64_SymConst_attr_t
",
mode
=>
$mode_gp
,
},
#
Store => {
#
op_flags => "L|F",
#
state => "exc_pinned",
#
reg_req => { in => [ "gp", "gp", "none"
, "gp"
], out => [
"none",
"none" ] },
#
ins => [ "
base", "index", "mem", "val
" ],
#
outs => [ "M"
, "X_exc"
],
#
mode => "mode_M",
#},
Store
=>
{
op_flags
=>
"
L|F
",
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
none
"
]
},
ins
=>
[
"
ptr
",
"
val
",
"
mem
"
],
outs
=>
[
"
M
"
],
mode
=>
"
mode_M
",
emit
=>
"
. mov (%S1), %S2
"
},
#NoReg_GP => {
# state => "pinned",
...
...
ir/be/amd64/amd64_transform.c
View file @
fecb5663
...
...
@@ -358,6 +358,34 @@ static ir_node *gen_Conv(ir_node *node)
}
}
/**
* Transforms a Store.
*
* @return the created AMD64 Store node
*/
static
ir_node
*
gen_Store
(
ir_node
*
node
)
{
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_node
*
ptr
=
get_Store_ptr
(
node
);
ir_node
*
new_ptr
=
be_transform_node
(
ptr
);
ir_node
*
mem
=
get_Store_mem
(
node
);
ir_node
*
new_mem
=
be_transform_node
(
mem
);
ir_node
*
val
=
get_Store_value
(
node
);
ir_node
*
new_val
=
be_transform_node
(
val
);
ir_mode
*
mode
=
get_irn_mode
(
val
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
new_store
=
NULL
;
if
(
mode_is_float
(
mode
))
{
panic
(
"Float not supported yet"
);
}
else
{
assert
(
mode_is_data
(
mode
)
&&
"unsupported mode for Store"
);
new_store
=
new_bd_amd64_Store
(
dbgi
,
block
,
new_ptr
,
new_val
,
new_mem
);
}
set_irn_pinned
(
new_store
,
get_irn_pinned
(
node
));
return
new_store
;
}
/**
* Transforms a Load.
*
...
...
@@ -531,6 +559,7 @@ static void amd64_register_transformers(void)
set_transformer
(
op_Cond
,
gen_Cond
);
set_transformer
(
op_Phi
,
gen_Phi
);
set_transformer
(
op_Load
,
gen_Load
);
set_transformer
(
op_Store
,
gen_Store
);
set_transformer
(
op_Proj
,
gen_Proj
);
}
...
...
ir/be/amd64/bearch_amd64.c
View file @
fecb5663
...
...
@@ -402,6 +402,21 @@ static const be_abi_callbacks_t amd64_abi_callbacks = {
amd64_abi_epilogue
,
};
static
const
arch_register_t
*
gpreg_param_reg_std
[]
=
{
&
amd64_gp_regs
[
REG_RDI
],
&
amd64_gp_regs
[
REG_RSI
],
&
amd64_gp_regs
[
REG_RDX
],
&
amd64_gp_regs
[
REG_RCX
],
&
amd64_gp_regs
[
REG_R8
],
&
amd64_gp_regs
[
REG_R9
],
};
static
const
arch_register_t
*
amd64_get_RegParam_reg
(
int
n
)
{
assert
(
n
<
6
&&
n
>=
0
&&
"register param > 6 requested"
);
return
gpreg_param_reg_std
[
n
];
}
/**
* Get the ABI restrictions for procedure calls.
* @param self The this pointer.
...
...
@@ -434,11 +449,9 @@ static void amd64_get_call_abi(const void *self, ir_type *method_type,
mode
=
get_type_mode
(
tp
);
//d// printf ("MODE %p %p XX %d\n", mode, mode_Iu, i);
if
(
!
no_reg
&&
(
i
==
0
||
i
==
1
)
&&
mode
==
mode
_Iu
)
{
if
(
!
no_reg
&&
i
<
6
&&
mode_is_data
(
mode
)
)
{
//d// printf("TEST%d\n", i);
be_abi_call_param_reg
(
abi
,
i
,
i
==
0
?
&
amd64_gp_regs
[
REG_RDI
]
:
&
amd64_gp_regs
[
REG_RSI
],
be_abi_call_param_reg
(
abi
,
i
,
amd64_get_RegParam_reg
(
i
),
ABI_CONTEXT_BOTH
);
/* default: all parameters on stack */
}
else
{
...
...
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