Handle ARM "ret void" and function alignment with proper padding.

Modify run-pnacl-sz to pass in the correct assembler/disasembler flags
for ARM when not using the integrated assembler.

Model the "ret" pseudo instruction (special form of
"bx" inst). Separate from "bx" to allow epilogue
insertion to find the terminator.

Add a flag "--skip-unimplemented" to skip through all of the
"Not yet implemented" assertions, and use that in the test.

Set up a stack trace printer when ALLOW_DUMP so that the
UnimplementedError prints out some useful information of
*which* case is unimplemented.

Change the .type ...,@function from @function to %function.
ARM assembler seems to only like %function because
"@" is a comment character.

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/1136793002
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
new file mode 100644
index 0000000..9f54e85
--- /dev/null
+++ b/src/IceInstARM32.cpp
@@ -0,0 +1,101 @@
+//===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the InstARM32 and OperandARM32 classes,
+// primarily the constructors and the dump()/emit() methods.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembler_arm32.h"
+#include "IceCfg.h"
+#include "IceCfgNode.h"
+#include "IceInst.h"
+#include "IceInstARM32.h"
+#include "IceOperand.h"
+#include "IceRegistersARM32.h"
+#include "IceTargetLoweringARM32.h"
+
+namespace Ice {
+
+namespace {
+
+const struct TypeARM32Attributes_ {
+  const char *WidthString; // b, h, <blank>, or d
+  int8_t SExtAddrOffsetBits;
+  int8_t ZExtAddrOffsetBits;
+} TypeARM32Attributes[] = {
+#define X(tag, elementty, width, sbits, ubits)                                 \
+  { width, sbits, ubits }                                                      \
+  ,
+    ICETYPEARM32_TABLE
+#undef X
+};
+
+} // end of anonymous namespace
+
+const char *InstARM32::getWidthString(Type Ty) {
+  return TypeARM32Attributes[Ty].WidthString;
+}
+
+bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
+  int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits
+                         : TypeARM32Attributes[Ty].ZExtAddrOffsetBits;
+  if (Bits == 0)
+    return Offset == 0;
+  // Note that encodings for offsets are sign-magnitude for ARM, so we check
+  // with IsAbsoluteUint().
+  if (isScalarFloatingType(Ty))
+    return Utils::IsAligned(Offset, 4) && Utils::IsAbsoluteUint(Bits, Offset);
+  return Utils::IsAbsoluteUint(Bits, Offset);
+}
+
+InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source)
+    : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) {
+  addSource(LR);
+  if (Source)
+    addSource(Source);
+}
+
+// ======================== Dump routines ======================== //
+
+void InstARM32::dump(const Cfg *Func) const {
+  if (!ALLOW_DUMP)
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "[ARM32] ";
+  Inst::dump(Func);
+}
+
+void InstARM32Ret::emit(const Cfg *Func) const {
+  if (!ALLOW_DUMP)
+    return;
+  assert(getSrcSize() > 0);
+  Variable *LR = llvm::cast<Variable>(getSrc(0));
+  assert(LR->hasReg());
+  assert(LR->getRegNum() == RegARM32::Reg_lr);
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << "\tbx\t";
+  LR->emit(Func);
+}
+
+void InstARM32Ret::emitIAS(const Cfg *Func) const {
+  (void)Func;
+  llvm_unreachable("Not yet implemented");
+}
+
+void InstARM32Ret::dump(const Cfg *Func) const {
+  if (!ALLOW_DUMP)
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType());
+  Str << "ret." << Ty << " ";
+  dumpSources(Func);
+}
+
+} // end of namespace Ice