sparc: split Mulh node into SMulh and UMulh
authorMatthias Braun <matze@braunis.de>
Mon, 5 Sep 2011 14:48:49 +0000 (16:48 +0200)
committerMatthias Braun <matze@braunis.de>
Tue, 6 Sep 2011 11:57:05 +0000 (13:57 +0200)
(Hannes ancient technique based on the Proj-mode is deprecated)

ir/be/sparc/sparc_emitter.c
ir/be/sparc/sparc_emitter.h
ir/be/sparc/sparc_spec.pl
ir/be/sparc/sparc_transform.c

index a09be00..ed3d867 100644 (file)
@@ -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);
index c469cd5..2726d19 100644 (file)
@@ -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);
index 592c65a..005dc2e 100644 (file)
@@ -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,
index 38206d2..666d291 100644 (file)
@@ -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)