Commit fecb5663 authored by Robin Redeker's avatar Robin Redeker
Browse files

amd64: implemented Store, Mul and Sub.

[r27667]
parent ca8f7598
......@@ -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("\tmov ");
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("\tadd ");
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("\tsub ");
amd64_emit_dest_register(node, 0);
be_emit_irprintf(", $%u", offs);
be_emit_finish_line_gas(node);
} else {
be_emit_irprintf("\tadd ");
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("\tadd ");
} else if (irn->op == op_amd64_Mul) {
be_emit_cstring("\tmul ");
} else if (irn->op == op_amd64_Sub) {
be_emit_cstring("\tsub ");
}
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("\tmov ");
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);
}
......
......@@ -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);
......
......@@ -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 => '. movq %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",
......
......@@ -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);
}
......
......@@ -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 {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment