Build constants using instructions mov/orr or mvn/eor.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33141 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMCommon.cpp b/lib/Target/ARM/ARMCommon.cpp
new file mode 100644
index 0000000..fd37573
--- /dev/null
+++ b/lib/Target/ARM/ARMCommon.cpp
@@ -0,0 +1,84 @@
+//===-- ARMCommon.cpp - Define support functions for ARM --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the "Instituto Nokia de Tecnologia" and
+// is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//
+//===----------------------------------------------------------------------===//
+#include "ARMCommon.h"
+
+static inline unsigned rotateL(unsigned x, unsigned n){
+  return ((x << n) | (x  >> (32 - n)));
+}
+
+static inline unsigned rotateR(unsigned x, unsigned n){
+  return ((x >> n) | (x  << (32 - n)));
+}
+
+// finds the end position of largest sequence of zeros in binary representation
+// of 'immediate'.
+static int findLargestZeroSequence(unsigned immediate){
+  int max_zero_pos = 0;
+  int max_zero_length = 0;
+  int zero_pos;
+  int zero_length;
+  int pos = 0;
+  int end_pos;
+
+  while ((immediate & 0x3) == 0) {
+    immediate = rotateR(immediate, 2);
+    pos+=2;
+  }
+  end_pos = pos+32;
+
+  while (pos<end_pos){
+    while (((immediate & 0x3) != 0)&&(pos<end_pos)) {
+      immediate = rotateR(immediate, 2);
+      pos+=2;
+    }
+    zero_pos = pos;
+    while (((immediate & 0x3) == 0)&&(pos<end_pos)) {
+      immediate = rotateR(immediate, 2);
+      pos+=2;
+    }
+    zero_length = pos - zero_pos;
+    if (zero_length > max_zero_length){
+      max_zero_length = zero_length;
+      max_zero_pos = zero_pos % 32;
+    }
+
+  }
+
+  return (max_zero_pos + max_zero_length) % 32;
+}
+
+std::vector<unsigned> splitImmediate(unsigned immediate){
+  std::vector<unsigned> immediatePieces;
+
+  if (immediate == 0){
+    immediatePieces.push_back(0);
+  } else {
+    int start_pos = findLargestZeroSequence(immediate);
+    unsigned immediate_tmp = rotateR(immediate, start_pos);
+    int pos = 0;
+    while (pos < 32){
+      while(((immediate_tmp&0x3) == 0)&&(pos<32)){
+        immediate_tmp = rotateR(immediate_tmp,2);
+        pos+=2;
+      }
+      if (pos < 32){
+        immediatePieces.push_back(rotateL(immediate_tmp&0xFF,
+                                          (start_pos + pos) % 32 ));
+        immediate_tmp = rotateR(immediate_tmp,8);
+        pos+=8;
+      }
+    }
+  }
+  return immediatePieces;
+}