From ba9181676faaa1ad3d9e8bcb4cebe239fdbf05a2 Mon Sep 17 00:00:00 2001
From: David Holsgrove <david.holsgrove@xilix.com>
Date: Tue, 28 Feb 2012 15:32:29 +0530
Subject: [PATCH] microblaze: add support for swap instructions and reorder option

swapb and swaph instructions are introduced in microblaze cpu (mcpu) v8.30a,
but have an undocumented dependence on -mxl-pattern-compare being set.

The conditions for their use are;

mcpu < 8.30a; no swap insns, use of -mxl-reorder produces warning
and ignored

mcpu == 8.30a and -mxl-pattern-compare specified;
and if -mno-xl-reorder not specified, then swap insns allowed

mcpu > 8.30a;
if -mno-xl-reorder not specified, then swap insns allowed

Changelog

2013-02-11  David Holsgrove <david.holsgrove@xilinx.com>

  *  gcc/config/microblaze/microblaze.c: microblaze_has_swap = 0
     Add version check for v8.30.a to enable microblaze_has_swap
  *  gcc/config/microblaze/microblaze.h: Add TARGET_HAS_SWAP
  *  gcc/config/microblaze/microblaze.md: New bswapsi2 and bswaphi2
     instructions
  *  gcc/config/microblaze/microblaze.opt: New options -mxl-reorder
     and -mno-xl-reorder

Signed-off-by: Nagaraju Mekala <nmekala@xilinx.com>
Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
---
 gcc/config/microblaze/microblaze.c   |   38 ++++++++++++++++++++++++++++++++++
 gcc/config/microblaze/microblaze.h   |    5 ++++
 gcc/config/microblaze/microblaze.md  |   14 ++++++++++++
 gcc/config/microblaze/microblaze.opt |    8 +++++++
 4 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index fc0296e..8819655 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -146,6 +146,9 @@ int microblaze_no_unsafe_delay;
 /* Set to one if the targeted core has the CLZ insn.  */
 int microblaze_has_clz = 0;
 
+/* Set to one if the targeted core has the swapb and swaph insn.  */
+int microblaze_has_swap = 0;
+
 /* Which CPU pipeline do we use. We haven't really standardized on a CPU 
    version having only a particular type of pipeline. There can still be 
    options on the CPU to scale pipeline features up or down. :( 
@@ -1380,6 +1383,41 @@ microblaze_option_override (void)
         microblaze_has_clz = 0;
     }
 
+  /* TARGET_REORDER defaults to 0 in microblaze.opt,
+     -mxl-reorder sets TARGET_REORDER to 1,
+     -mno-xl-reorder sets TARGET_NO_REORDER to 1.
+     Swap instructions are not to be emitted if TARGET_NO_REORDER == 1
+     but should be enabled by default if mcpu >= 8.30a */
+  ver = MICROBLAZE_VERSION_COMPARE (microblaze_select_cpu, "v8.30.a");
+  if (ver < 0)
+    {
+        /* MicroBlaze prior to 8.30a didn't have swapb or swaph insns. */
+        if (TARGET_REORDER)
+          warning (0,
+                 "-mxl-reorder can be used only with -mcpu=v8.30.a or greater");
+    }
+  else if (ver == 0)
+    {
+        if (!TARGET_NO_REORDER)
+          {
+            target_flags |= MASK_REORDER;
+            /* MicroBlaze v8.30a has an undocumented dependency on
+               pattern compare for swapb / swaph insns. */
+            if (TARGET_PATTERN_COMPARE)
+              microblaze_has_swap = 1;
+          }
+    }
+  else
+    {
+        if (!TARGET_NO_REORDER)
+          {
+            target_flags |= MASK_REORDER;
+            /* Microblaze versions greater than v8.30a will be able to use
+               swapb / swaph without pattern compare */
+            microblaze_has_swap = 1;
+          }
+    }
+
   if (TARGET_MULTIPLY_HIGH && TARGET_SOFT_MUL)
     error ("-mxl-multiply-high requires -mno-xl-soft-mul");
 
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index a188a2e..76ee811 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -43,6 +43,7 @@ extern int microblaze_dbx_regno[];
 
 extern int microblaze_no_unsafe_delay;
 extern int microblaze_has_clz;
+extern int microblaze_has_swap;
 extern enum pipeline_type microblaze_pipe;
 
 #define OBJECT_FORMAT_ELF
@@ -62,6 +63,9 @@ extern enum pipeline_type microblaze_pipe;
 /* Do we have CLZ?  */
 #define TARGET_HAS_CLZ      (TARGET_PATTERN_COMPARE && microblaze_has_clz)
 
+/* Do we have SWAPB and SWAPH?  */
+#define TARGET_HAS_SWAP     (microblaze_has_swap)
+
 /* The default is to support PIC.  */
 #define TARGET_SUPPORTS_PIC 1
 
@@ -78,6 +82,7 @@ extern enum pipeline_type microblaze_pipe;
 	"%{mno-xl-barrel-shift:%<mxl-barrel-shift}", 	\
 	"%{mno-xl-pattern-compare:%<mxl-pattern-compare}", \
 	"%{mxl-soft-div:%<mno-xl-soft-div}", 		\
+	"%{mxl-reorder:%<mno-xl-reorder}", 		\
 	"%{msoft-float:%<mhard-float}"
 
 /* Tell collect what flags to pass to nm.  */
diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
index 1b42003..2e636c0 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -353,6 +353,20 @@
 (automata_option "time")
 (automata_option "progress")
 
+(define_insn "bswapsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
+  "TARGET_HAS_SWAP"
+  "swapb %0, %1"
+)
+
+(define_insn "bswaphi2"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+        (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
+  "TARGET_HAS_SWAP"
+  "swaph %0, %1"
+)
+
 ;;----------------------------------------------------------------
 ;; Microblaze delay slot description
 ;;----------------------------------------------------------------
diff --git a/gcc/config/microblaze/microblaze.opt b/gcc/config/microblaze/microblaze.opt
index fc7d0cd..b461296 100644
--- a/gcc/config/microblaze/microblaze.opt
+++ b/gcc/config/microblaze/microblaze.opt
@@ -67,6 +67,14 @@ mxl-soft-mul
 Target Mask(SOFT_MUL)
 Use the soft multiply emulation (default)
 
+mxl-reorder
+Target RejectNegative Mask(REORDER)
+Use reorder instructions (default)
+
+mno-xl-reorder
+Target RejectNegative Var(TARGET_NO_REORDER)
+Do not use reorder instructions
+
 mxl-soft-div
 Target Mask(SOFT_DIV)
 Use the software emulation for divides (default)
-- 
1.7.3.2

