From: Matthias Braun Date: Mon, 5 Sep 2011 14:48:49 +0000 (+0200) Subject: sparc: split Mulh node into SMulh and UMulh X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=d1cb53b02702f0ea401e511b4825cf83bc89610a;p=libfirm sparc: split Mulh node into SMulh and UMulh (Hannes ancient technique based on the Proj-mode is deprecated) --- diff --git a/ir/be/sparc/sparc_emitter.c b/ir/be/sparc/sparc_emitter.c index a09be00ac..ed3d867ba 100644 --- a/ir/be/sparc/sparc_emitter.c +++ b/ir/be/sparc/sparc_emitter.c @@ -214,16 +214,6 @@ void sparc_emit_store_mode(const ir_node *node) } } -/** - * emit integer signed/unsigned prefix char - */ -void sparc_emit_mode_sign_prefix(const ir_node *node) -{ - ir_mode *mode = get_irn_mode(node); - bool is_signed = mode_is_signed(mode); - be_emit_string(is_signed ? "s" : "u"); -} - static void emit_fp_suffix(const ir_mode *mode) { unsigned bits = get_mode_size_bits(mode); @@ -332,7 +322,8 @@ static bool emits_multiple_instructions(const ir_node *node) return arch_get_irn_flags(node) & sparc_arch_irn_flag_aggregate_return; } - return is_sparc_Mulh(node) || is_sparc_SDiv(node) || is_sparc_UDiv(node) + return is_sparc_SMulh(node) || is_sparc_UMulh(node) + || is_sparc_SDiv(node) || is_sparc_UDiv(node) || be_is_MemPerm(node) || be_is_Perm(node); } @@ -447,7 +438,12 @@ static void emit_be_IncSP(const ir_node *irn) static void emit_sparc_Mulh(const ir_node *irn) { be_emit_cstring("\t"); - sparc_emit_mode_sign_prefix(irn); + if (is_sparc_UMulh(irn)) { + be_emit_char('u'); + } else { + assert(is_sparc_SMulh(irn)); + be_emit_char('s'); + } be_emit_cstring("mul "); sparc_emit_source_register(irn, 0); @@ -922,7 +918,8 @@ static void sparc_register_emitters(void) set_emitter(op_sparc_Call, emit_sparc_Call); set_emitter(op_sparc_fbfcc, emit_sparc_fbfcc); set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr); - set_emitter(op_sparc_Mulh, emit_sparc_Mulh); + set_emitter(op_sparc_SMulh, emit_sparc_Mulh); + set_emitter(op_sparc_UMulh, emit_sparc_Mulh); set_emitter(op_sparc_Return, emit_sparc_Return); set_emitter(op_sparc_SDiv, emit_sparc_SDiv); set_emitter(op_sparc_SwitchJmp, emit_sparc_SwitchJmp); diff --git a/ir/be/sparc/sparc_emitter.h b/ir/be/sparc/sparc_emitter.h index c469cd5bd..2726d19c3 100644 --- a/ir/be/sparc/sparc_emitter.h +++ b/ir/be/sparc/sparc_emitter.h @@ -45,7 +45,6 @@ void sparc_emit_offset(const ir_node *node, int offset_node_pos); void sparc_emit_load_mode(const ir_node *node); void sparc_emit_store_mode(const ir_node *node); void sparc_emit_float_load_store_mode(const ir_node *node); -void sparc_emit_mode_sign_prefix(const ir_node *node); void sparc_emit_fp_mode_suffix(const ir_node *node); void sparc_emit_fp_conv_source(const ir_node *node); void sparc_emit_fp_conv_destination(const ir_node *node); diff --git a/ir/be/sparc/sparc_spec.pl b/ir/be/sparc/sparc_spec.pl index 592c65a0f..005dc2e48 100644 --- a/ir/be/sparc/sparc_spec.pl +++ b/ir/be/sparc/sparc_spec.pl @@ -664,7 +664,13 @@ Mul => { constructors => \%binop_operand_constructors, }, -Mulh => { +SMulh => { + irn_flags => [ "rematerializable" ], + outs => [ "low", "high" ], + constructors => \%binop_operand_constructors, +}, + +UMulh => { irn_flags => [ "rematerializable" ], outs => [ "low", "high" ], constructors => \%binop_operand_constructors, diff --git a/ir/be/sparc/sparc_transform.c b/ir/be/sparc/sparc_transform.c index 38206d230..666d291f9 100644 --- a/ir/be/sparc/sparc_transform.c +++ b/ir/be/sparc/sparc_transform.c @@ -754,8 +754,13 @@ static ir_node *gen_Mulh(ir_node *node) if (mode_is_float(mode)) panic("FP not supported yet"); - mul = gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_Mulh_reg, new_bd_sparc_Mulh_imm); - return new_r_Proj(mul, mode_gp, pn_sparc_Mulh_low); + if (mode_is_signed(mode)) { + mul = gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_SMulh_reg, new_bd_sparc_SMulh_imm); + return new_r_Proj(mul, mode_gp, pn_sparc_SMulh_low); + } else { + mul = gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_UMulh_reg, new_bd_sparc_UMulh_imm); + return new_r_Proj(mul, mode_gp, pn_sparc_UMulh_low); + } } static ir_node *gen_sign_extension_value(ir_node *node)