From 74525abef0010b7196ebaab14fca07126453c7e5 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Wed, 1 Aug 2007 15:59:46 +0000 Subject: [PATCH] add Zex8/Zex16 instructions [r15419] --- ir/be/ia32/ia32_emitter.c | 23 +++++++++++++++++++++++ ir/be/ia32/ia32_emitter.h | 2 ++ ir/be/ia32/ia32_spec.pl | 21 +++++++++++++++++++++ ir/be/ia32/ia32_transform.c | 35 ++++++++++++++++++++++++++--------- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 59c428210..478907329 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -250,6 +250,29 @@ void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int po be_emit_string(env, reg_name); } +void ia32_emit_8bit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos) +{ + const arch_register_t *reg = get_in_reg(env, node, pos); + const char *reg_name = arch_register_get_name(reg); + + assert(pos < get_irn_arity(node)); + + be_emit_char(env, '%'); + be_emit_char(env, reg_name[1]); + be_emit_char(env, 'l'); +} + +void ia32_emit_16bit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos) +{ + const arch_register_t *reg = get_in_reg(env, node, pos); + const char *reg_name = arch_register_get_name(reg); + + assert(pos < get_irn_arity(node)); + + be_emit_char(env, '%'); + be_emit_string(env, ®_name[1]); +} + void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos) { const arch_register_t *reg = get_out_reg(env, node, pos); const char *reg_name = arch_register_get_name(reg); diff --git a/ir/be/ia32/ia32_emitter.h b/ir/be/ia32/ia32_emitter.h index 44fcd6629..c7ca52684 100644 --- a/ir/be/ia32/ia32_emitter.h +++ b/ir/be/ia32/ia32_emitter.h @@ -43,6 +43,8 @@ struct ia32_emit_env_t { }; void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos); +void ia32_emit_8bit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos); +void ia32_emit_16bit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos); void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos); void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos); void ia32_emit_immediate(ia32_emit_env_t *env, const ir_node *node); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index ce821aa6b..5c44177ea 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -253,6 +253,8 @@ $arch = "ia32"; S3 => "${arch}_emit_source_register(env, node, 3);", S4 => "${arch}_emit_source_register(env, node, 4);", S5 => "${arch}_emit_source_register(env, node, 5);", + SB0 => "${arch}_emit_8bit_source_register(env, node, 0);", + SW0 => "${arch}_emit_16bit_source_register(env, node, 0);", D0 => "${arch}_emit_dest_register(env, node, 0);", D1 => "${arch}_emit_dest_register(env, node, 1);", D2 => "${arch}_emit_dest_register(env, node, 2);", @@ -779,6 +781,25 @@ Not => { modified_flags => [] }, +Zex8 => { + irn_flags => "R", + reg_req => { in => [ "eax ebx ecx edx" ], out => [ "gp" ] }, + emit => '. movzbl %SB0, %D0', + units => [ "GP" ], + mode => $mode_gp, + modified_flags => [] +}, + +Zex16 => { + irn_flags => "R", + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. movzwl %SW0, %D0', + units => [ "GP" ], + mode => $mode_gp, + modified_flags => [] +}, + + # other operations CondJmp => { diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 018d09fed..5859bff85 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -872,23 +872,40 @@ static ir_node *gen_Mulh(ir_node *node) { static ir_node *gen_And(ir_node *node) { ir_node *op1 = get_And_left(node); ir_node *op2 = get_And_right(node); - + ir_node *new_op, *load; assert(! mode_is_float(get_irn_mode(node))); - if (is_Const(op2) && is_Load(skip_Proj(op1)) && get_irn_n_edges(op1) == 1) { - /* a Load() & Const */ + /* check for zero extension first */ + if (is_Const(op2)) { tarval *tv = get_Const_tarval(op2); long v = get_tarval_long(tv); if (v == 0xFF) { - ir_node *new_op = be_transform_node(op1); - ir_node *load = skip_Proj(new_op); - set_ia32_ls_mode(load, mode_Bu); + if (is_Load(skip_Proj(op1)) && get_irn_n_edges(op1) == 1) { + new_op = be_transform_node(op1); + load = skip_Proj(new_op); + set_ia32_ls_mode(load, mode_Bu); + new_op = be_transform_node(op1); + } else { + ir_graph *irg = current_ir_graph; + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *block = be_transform_node(get_nodes_block(node)); + + new_op = new_rd_ia32_Zex8(dbgi, irg, block, be_transform_node(op1)); + } return new_op; } else if (v == 0xFFFF) { - ir_node *new_op = be_transform_node(op1); - ir_node *load = skip_Proj(new_op); - set_ia32_ls_mode(load, mode_Hu); + if (is_Load(skip_Proj(op1)) && get_irn_n_edges(op1) == 1) { + new_op = be_transform_node(op1); + load = skip_Proj(new_op); + set_ia32_ls_mode(load, mode_Hu); + } else { + ir_graph *irg = current_ir_graph; + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *block = be_transform_node(get_nodes_block(node)); + + new_op = new_rd_ia32_Zex16(dbgi, irg, block, be_transform_node(op1)); + } return new_op; } } -- 2.20.1