Commit 75186801 authored by Robin Redeker's avatar Robin Redeker Committed by Matthias Braun
Browse files

amd64: implemented lowering and implementation of Switch.

parent ecc6afb5
......@@ -220,6 +220,14 @@ static void emit_amd64_Jmp(const ir_node *node)
}
}
static void emit_amd64_SwitchJmp(const ir_node *node)
{
const amd64_switch_jmp_attr_t *attr = get_amd64_switch_jmp_attr_const(node);
amd64_emitf(node, "jmp *%E(,%S0,8)", attr->table_entity);
be_emit_jump_table(node, attr->table, attr->table_entity, get_cfop_target_block);
}
/**
* Emit a Compare with conditional branch.
*/
......@@ -400,6 +408,7 @@ static void amd64_register_emitters(void)
be_set_emitter(op_amd64_FrameAddr, emit_amd64_FrameAddr);
be_set_emitter(op_amd64_Jcc, emit_amd64_Jcc);
be_set_emitter(op_amd64_Jmp, emit_amd64_Jmp);
be_set_emitter(op_amd64_SwitchJmp, emit_amd64_SwitchJmp);
be_set_emitter(op_amd64_SymConst, emit_amd64_SymConst);
be_set_emitter(op_be_Call, emit_be_Call);
be_set_emitter(op_be_Copy, emit_be_Copy);
......
......@@ -99,6 +99,20 @@ amd64_SymConst_attr_t *get_amd64_SymConst_attr(ir_node *node)
return attr;
}
const amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr_const(const ir_node *node)
{
const amd64_switch_jmp_attr_t *attr
= (const amd64_switch_jmp_attr_t*)get_irn_generic_attr_const(node);
return attr;
}
amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr(ir_node *node)
{
amd64_switch_jmp_attr_t *attr
= (amd64_switch_jmp_attr_t*)get_irn_generic_attr(node);
return attr;
}
/**
* Initializes the nodes attributes.
*/
......@@ -134,6 +148,23 @@ static void init_amd64_SymConst_attributes(ir_node *node, ir_entity *entity)
attr->fp_offset = 0;
}
/**
* Initialize SwitchJmp attributes.
*/
static void init_amd64_switch_attributes(ir_node *node, const ir_switch_table *table, ir_entity *table_entity)
{
unsigned n_outs = arch_get_irn_n_outs(node);
unsigned o;
amd64_switch_jmp_attr_t *attr = get_amd64_switch_jmp_attr(node);
attr->table = table;
attr->table_entity = table_entity;
for (o = 0; o < n_outs; o++) {
arch_set_irn_register_req_out(node, o, arch_no_register_req);
}
}
/** Compare node attributes for SymConst. */
static int cmp_amd64_attr_SymConst(const ir_node *a, const ir_node *b)
{
......
......@@ -37,6 +37,9 @@ const amd64_attr_t *get_amd64_attr_const(const ir_node *node);
const amd64_SymConst_attr_t *get_amd64_SymConst_attr_const(const ir_node *node);
amd64_SymConst_attr_t *get_amd64_SymConst_attr(ir_node *node);
const amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr_const(const ir_node *node);
amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr(ir_node *node);
/* Include the generated headers */
#include "gen_amd64_new_nodes.h"
......
......@@ -14,6 +14,7 @@
typedef struct amd64_attr_t amd64_attr_t;
typedef struct amd64_SymConst_attr_t amd64_SymConst_attr_t;
typedef struct amd64_switch_jmp_attr_t amd64_switch_jmp_attr_t;
struct amd64_attr_t
{
......@@ -37,6 +38,13 @@ struct amd64_SymConst_attr_t
unsigned fp_offset;
};
struct amd64_switch_jmp_attr_t
{
amd64_attr_t base;
const ir_switch_table *table;
ir_entity *table_entity;
};
#define CAST_AMD64_ATTR(type,ptr) ((type *)(ptr))
#define CONST_CAST_AMD64_ATTR(type,ptr) ((const type *)(ptr))
......
......@@ -73,12 +73,16 @@ $default_copy_attr = "amd64_copy_attr";
amd64_condcode_attr_t =>
"\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
. "\tinit_amd64_condcode_attributes(res, pnc);",
amd64_switch_jmp_attr_t =>
"\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
. "\tinit_amd64_switch_attributes(res, table, table_entity);"
);
%compare_attr = (
amd64_attr_t => "cmp_amd64_attr",
amd64_SymConst_attr_t => "cmp_amd64_attr_SymConst",
amd64_condcode_attr_t => "cmp_amd64_attr_condcode",
amd64_attr_t => "cmp_amd64_attr",
amd64_SymConst_attr_t => "cmp_amd64_attr_SymConst",
amd64_switch_jmp_attr_t => "cmp_amd64_attr",
amd64_condcode_attr_t => "cmp_amd64_attr_condcode",
);
%nodes = (
......@@ -305,4 +309,15 @@ Store => {
mode => "mode_M",
emit => "mov %S1, %O(%S0)"
},
SwitchJmp => {
op_flags => [ "cfopcode", "forking" ],
state => "pinned",
mode => "mode_T",
reg_req => { in => [ "gp" ], out => [ "none" ] },
out_arity => "variable",
attr_type => "amd64_switch_jmp_attr_t",
attr => "const ir_switch_table *table, ir_entity *table_entity",
},
);
......@@ -138,6 +138,28 @@ static ir_node *gen_Jmp(ir_node *node)
return new_bd_amd64_Jmp(dbgi, new_block);
}
static ir_node *gen_Switch(ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
ir_node *new_block = be_transform_node(get_nodes_block(node));
ir_node *sel = get_Switch_selector(node);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_sel = be_transform_node(sel);
const ir_switch_table *table = get_Switch_table(node);
unsigned n_outs = get_Switch_n_outs(node);
ir_entity *entity;
entity = new_entity(NULL, id_unique("TBL%u"), get_unknown_type());
set_entity_visibility(entity, ir_visibility_private);
add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
table = ir_switch_table_duplicate(irg, table);
ir_node *out = new_bd_amd64_SwitchJmp(dbgi, new_block, new_sel, n_outs, table, entity);
return out;
}
static ir_node *gen_be_Call(ir_node *node)
{
ir_node *res = be_duplicate_node(node);
......@@ -387,6 +409,7 @@ static void amd64_register_transformers(void)
be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
be_set_transform_function(op_Conv, gen_Conv);
be_set_transform_function(op_Jmp, gen_Jmp);
be_set_transform_function(op_Switch, gen_Switch);
be_set_transform_function(op_Cmp, gen_Cmp);
be_set_transform_function(op_Cond, gen_Cond);
be_set_transform_function(op_Phi, gen_Phi);
......
......@@ -358,12 +358,16 @@ static void amd64_get_call_abi(ir_type *method_type, be_abi_call_t *abi)
static void amd64_lower_for_target(void)
{
size_t i, n_irgs = get_irp_n_irgs();
/* lower compound param handling */
lower_calls_with_compounds(LF_RETURN_HIDDEN);
for (i = 0; i < n_irgs; ++i) {
size_t n_irgs = get_irp_n_irgs();
for (size_t i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
lower_switch(irg, 4, 256, mode_Iu);
}
for (size_t i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
/* Turn all small CopyBs into loads/stores, and turn all bigger
* CopyBs into memcpy calls, because we cannot handle CopyB nodes
......
Markdown is supported
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