From: Michael Beck Date: Mon, 29 Dec 2008 02:16:45 +0000 (+0000) Subject: - implemented ia32 inport, outport for ir_bk_(in|out)port X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=644c7ca46f7d4b85ba28c6e59f31068f3e323216;p=libfirm - implemented ia32 inport, outport for ir_bk_(in|out)port [r24938] --- diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 2555b5717..a55008299 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -243,6 +243,12 @@ static void emit_16bit_register(const arch_register_t *reg) be_emit_string(reg_name); } +/** + * emit a register, possible shortened by a mode + * + * @param reg the register + * @param mode the mode of the register or NULL for full register + */ static void emit_register(const arch_register_t *reg, const ir_mode *mode) { const char *reg_name; @@ -335,6 +341,19 @@ void ia32_emit_8bit_high_source_register(const ir_node *node, int pos) emit_8bit_register_high(reg); } +void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos) +{ + const arch_register_t *reg; + const ir_node *in = get_irn_n(node, pos); + if (is_ia32_Immediate(in)) { + emit_ia32_Immediate(in); + return; + } + + reg = get_in_reg(node, pos); + emit_16bit_register(reg); +} + void ia32_emit_dest_register(const ir_node *node, int pos) { const arch_register_t *reg = get_out_reg(node, pos); @@ -342,6 +361,13 @@ void ia32_emit_dest_register(const ir_node *node, int pos) emit_register(reg, NULL); } +void ia32_emit_dest_register_size(const ir_node *node, int pos) +{ + const arch_register_t *reg = get_out_reg(node, pos); + + emit_register(reg, get_ia32_ls_mode(node)); +} + void ia32_emit_8bit_dest_register(const ir_node *node, int pos) { const arch_register_t *reg = get_out_reg(node, pos); diff --git a/ir/be/ia32/ia32_emitter.h b/ir/be/ia32/ia32_emitter.h index fc16668d0..f490c462b 100644 --- a/ir/be/ia32/ia32_emitter.h +++ b/ir/be/ia32/ia32_emitter.h @@ -34,11 +34,13 @@ void ia32_emit_source_register(const ir_node *node, int pos); void ia32_emit_dest_register(const ir_node *node, int pos); +void ia32_emit_dest_register_size(const ir_node *node, int pos); void ia32_emit_8bit_dest_register(const ir_node *node, int pos); void ia32_emit_x87_register(const ir_node *node, int pos); void ia32_emit_source_register_or_immediate(const ir_node *node, int pos); void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos); void ia32_emit_8bit_high_source_register(const ir_node *node, int pos); +void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos); void ia32_emit_mode_suffix(const ir_node *node); void ia32_emit_x87_mode_suffix(const ir_node *node); void ia32_emit_xmm_mode_suffix(const ir_node *node); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 56850632a..709e1dbe5 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -202,10 +202,13 @@ $arch = "ia32"; SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);", SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);", SH0 => "${arch}_emit_8bit_high_source_register(node, 0);", + SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);", + SI0 => "${arch}_emit_source_register_or_immediate(node, 0);", SI1 => "${arch}_emit_source_register_or_immediate(node, 1);", SI3 => "${arch}_emit_source_register_or_immediate(node, 3);", D0 => "${arch}_emit_dest_register(node, 0);", D1 => "${arch}_emit_dest_register(node, 1);", + DS0 => "${arch}_emit_dest_register_size(node, 0);", DB0 => "${arch}_emit_8bit_dest_register(node, 0);", X0 => "${arch}_emit_x87_register(node, 0);", X1 => "${arch}_emit_x87_register(node, 1);", @@ -1624,6 +1627,37 @@ UD2 => { mode => mode_M, }, +# +# outport +# +Outport => { + irn_flags => "R", + state => "pinned", + reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] }, + ins => [ "port", "value", "mem" ], + emit => '. out%M %SS0, %SI1', + units => [ "GP" ], + latency => 1, + mode => mode_M, + modified_flags => $status_flags +}, + +# +# inport +# +Inport => { + irn_flags => "R", + state => "pinned", + reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] }, + ins => [ "port", "mem" ], + outs => [ "res", "M" ], + emit => '. in%M %DS0, %SS0', + units => [ "GP" ], + latency => 1, + mode => mode_T, + modified_flags => $status_flags +}, + # # Intel style prefetching # diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index d7b25cb51..6a585ece7 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -4990,6 +4990,42 @@ static ir_node *gen_bswap(ir_node *node) { } } +/** + * Transform builtin outport. + */ +static ir_node *gen_outport(ir_node *node) { + ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0); + ir_node *oldv = get_Builtin_param(node, 1); + ir_mode *mode = get_irn_mode(oldv); + ir_node *value = be_transform_node(oldv); + ir_node *block = be_transform_node(get_nodes_block(node)); + ir_node *mem = be_transform_node(get_Builtin_mem(node)); + dbg_info *dbgi = get_irn_dbg_info(node); + + ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem); + set_ia32_ls_mode(res, mode); + return res; +} + +/** + * Transform builtin inport. + */ +static ir_node *gen_inport(ir_node *node) { + ir_type *tp = get_Builtin_type(node); + ir_type *rstp = get_method_res_type(tp, 0); + ir_mode *mode = get_type_mode(rstp); + ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0); + ir_node *block = be_transform_node(get_nodes_block(node)); + ir_node *mem = be_transform_node(get_Builtin_mem(node)); + dbg_info *dbgi = get_irn_dbg_info(node); + + ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem); + set_ia32_ls_mode(res, mode); + + /* check for missing Result Proj */ + return res; +} + /** * Transform Builtin node. */ @@ -5019,6 +5055,10 @@ static ir_node *gen_Builtin(ir_node *node) { return gen_popcount(node); case ir_bk_bswap: return gen_bswap(node); + case ir_bk_outport: + return gen_outport(node); + case ir_bk_inport: + return gen_inport(node); } panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind)); } @@ -5027,7 +5067,7 @@ static ir_node *gen_Builtin(ir_node *node) { * Transform Proj(Builtin) node. */ static ir_node *gen_Proj_Builtin(ir_node *proj) { - ir_node *node = get_Proj_pred(proj); + ir_node *node = get_Proj_pred(proj); ir_node *new_node = be_transform_node(node); ir_builtin_kind kind = get_Builtin_kind(node); @@ -5045,8 +5085,18 @@ static ir_node *gen_Proj_Builtin(ir_node *proj) { case ir_bk_trap: case ir_bk_debugbreak: case ir_bk_prefetch: + case ir_bk_outport: assert(get_Proj_proj(proj) == pn_Builtin_M); return new_node; + case ir_bk_inport: + if (get_Proj_proj(proj) == pn_Builtin_1_result) { + return new_r_Proj(current_ir_graph, get_nodes_block(new_node), + new_node, get_irn_mode(proj), pn_ia32_Inport_res); + } else { + assert(get_Proj_proj(proj) == pn_Builtin_M); + return new_r_Proj(current_ir_graph, get_nodes_block(new_node), + new_node, mode_M, pn_ia32_Inport_M); + } } panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind)); }