The changes are made in the patch for optimized usage of pcmpne/pcmpeq instructions.
authorAjit Agarwal <ajitkum@xilinx.com>
Tue, 5 May 2015 01:08:45 +0000 (01:08 +0000)
committerMichael Eager <eager@gcc.gnu.org>
Tue, 5 May 2015 01:08:45 +0000 (01:08 +0000)
The changes are made in the patch for optimized usage of pcmpne/pcmpeq
instructions. The xor with register to register is replaced with pcmpeq
/pcmpne instructions and for immediate check still the xori will be used.
The purpose of the change is to acheive the aggressive usage of pcmpne
/pcmpeq instructions instead of xor being used for comparison.

ChangeLog:
2015-05-04  Ajit Agarwal  <ajitkum@xilinx.com>

* config/microblaze/microblaze.md (cbranchsi4): Added immediate
constraints.
(cbranchsi4_reg): New.
* config/microblaze/microblaze.c
(microblaze_expand_conditional_branch_reg): New.
* config/microblaze/microblaze-protos.h
(microblaze_expand_conditional_branch_reg): New prototype.

From-SVN: r222791

gcc/ChangeLog
gcc/config/microblaze/microblaze-protos.h
gcc/config/microblaze/microblaze.c
gcc/config/microblaze/microblaze.md

index 278e6180e956ea6cc1e6adeabbce2fe7808c403a..ce501cac13dfe6d2aac6cd3e10d4124992c7ae34 100644 (file)
@@ -1,3 +1,13 @@
+2015-05-04  Ajit Agarwal  <ajitkum@xilinx.com>
+
+       * config/microblaze/microblaze.md (cbranchsi4): Added immediate
+       constraints.
+       (cbranchsi4_reg): New.
+       * config/microblaze/microblaze.c
+       (microblaze_expand_conditional_branch_reg): New.
+       * config/microblaze/microblaze-protos.h
+       (microblaze_expand_conditional_branch_reg): New prototype.
+
 2015-05-04  Ajit Agarwal  <ajitkum@xilinx.com>
 
        * config/microblaze/microblaze.md (peephole2): New.
index 57879b1065f6fd2f3e6b3cf71b73607a865c575a..3ece34e086f1f7aa996c52dd634b44a917f952fe 100644 (file)
@@ -32,7 +32,8 @@ extern int microblaze_expand_shift (rtx *);
 extern bool microblaze_expand_move (machine_mode, rtx *);
 extern bool microblaze_expand_block_move (rtx, rtx, rtx, rtx);
 extern void microblaze_expand_divide (rtx *);
-extern void microblaze_expand_conditional_branch (machine_mode, rtx *); 
+extern void microblaze_expand_conditional_branch (machine_mode, rtx *);
+extern void microblaze_expand_conditional_branch_reg (enum machine_mode, rtx *);
 extern void microblaze_expand_conditional_branch_sf (rtx *); 
 extern int microblaze_can_use_return_insn (void);
 extern void print_operand (FILE *, rtx, int);
index 8ef40df7349ba052f9c840b8990aeecaf3ee68e5..372be5d8742625100a6c04c8851de0c06306c36f 100644 (file)
@@ -3471,6 +3471,51 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[])
     }
 }
 
+void
+microblaze_expand_conditional_branch_reg (enum machine_mode mode,
+                                          rtx operands[])
+{
+  enum rtx_code code = GET_CODE (operands[0]);
+  rtx cmp_op0 = operands[1];
+  rtx cmp_op1 = operands[2];
+  rtx label1 = operands[3];
+  rtx comp_reg = gen_reg_rtx (SImode);
+  rtx condition;
+
+  gcc_assert ((GET_CODE (cmp_op0) == REG)
+               || (GET_CODE (cmp_op0) == SUBREG));
+
+  /* If comparing against zero, just test source reg.  */
+  if (cmp_op1 == const0_rtx)
+    {
+      comp_reg = cmp_op0;
+      condition = gen_rtx_fmt_ee (signed_condition (code),
+                                  SImode, comp_reg, const0_rtx);
+      emit_jump_insn (gen_condjump (condition, label1));
+    }
+  else if (code == EQ)
+    {
+      emit_insn (gen_seq_internal_pat (comp_reg,
+                                       cmp_op0, cmp_op1));
+      condition = gen_rtx_EQ (SImode, comp_reg, const0_rtx);
+      emit_jump_insn (gen_condjump (condition, label1));
+    }
+  else if (code == NE)
+    {
+      emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0,
+                                       cmp_op1));
+      condition = gen_rtx_NE (SImode, comp_reg, const0_rtx);
+      emit_jump_insn (gen_condjump (condition, label1));
+    }
+  else
+    {
+      /* Generate compare and branch in single instruction. */
+      cmp_op1 = force_reg (mode, cmp_op1);
+      condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1);
+      emit_jump_insn (gen_branch_compare (condition, cmp_op0,
+                                         cmp_op1, label1));
+    }
+}
 
 void
 microblaze_expand_conditional_branch_sf (rtx operands[])
index ad97ca69fa9ef2bfef639470f25d933909c01cda..596968d5b5609d2316a618a8f32352105459e378 100644 (file)
 
 (define_expand "cbranchsi4"
   [(set (pc)
-       (if_then_else (match_operator 0 "ordered_comparison_operator"
-                      [(match_operand:SI 1 "register_operand")
-                       (match_operand:SI 2 "arith_operand")])
-                     (label_ref (match_operand 3 ""))
-                     (pc)))]
+        (if_then_else (match_operator 0 "ordered_comparison_operator"
+                       [(match_operand:SI 1 "register_operand")
+                        (match_operand:SI 2 "arith_operand" "I,i")])
+                      (label_ref (match_operand 3 ""))
+                      (pc)))]
   ""
 {
   microblaze_expand_conditional_branch (SImode, operands);
   DONE;
 })
 
+(define_expand "cbranchsi4_reg"
+  [(set (pc)
+        (if_then_else (match_operator 0 "ordered_comparison_operator"
+                       [(match_operand:SI 1 "register_operand")
+                        (match_operand:SI 2 "register_operand")])
+                      (label_ref (match_operand 3 ""))
+                      (pc)))]
+  ""
+{
+  microblaze_expand_conditional_branch_reg (SImode, operands);
+  DONE;
+})
+
 (define_expand "cbranchsf4"
   [(set (pc)
        (if_then_else (match_operator 0 "ordered_comparison_operator"