Add orr (register) and orr (immediate) to ARM integrated assembler.

Also cleans up comments about handling a rotated imm8 value.

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

Review URL: https://codereview.chromium.org/1412923006 .
diff --git a/src/DartARM32/assembler_arm.cc b/src/DartARM32/assembler_arm.cc
index f2fd997..d1730c6 100644
--- a/src/DartARM32/assembler_arm.cc
+++ b/src/DartARM32/assembler_arm.cc
@@ -274,19 +274,18 @@
   EmitType01(cond, o.type(), CMN, 1, rn, R0, o);
 }
 
-
+#if 0
+// Moved to ARM32::AssemberARM32::orr()
 void Assembler::orr(Register rd, Register rn, Operand o, Condition cond) {
   EmitType01(cond, o.type(), ORR, 0, rn, rd, o);
 }
 
-
+// Moved to ARM32::AssemberARM32::orr()
 void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) {
   EmitType01(cond, o.type(), ORR, 1, rn, rd, o);
 }
 
-
-#if 0
-// Moved to AssemblerARM32::mov(..FlexImm..)
+// Moved to AssemblerARM32::mov()
 // TODO(kschimpf) other forms of move.
 void Assembler::mov(Register rd, Operand o, Condition cond) {
   EmitType01(cond, o.type(), MOV, 0, R0, rd, o);
diff --git a/src/DartARM32/assembler_arm.h b/src/DartARM32/assembler_arm.h
index 46cba56..cc8f6a3 100644
--- a/src/DartARM32/assembler_arm.h
+++ b/src/DartARM32/assembler_arm.h
@@ -481,11 +481,12 @@
 
   void cmn(Register rn, Operand o, Condition cond = AL);
 
+#if 0
+  // Moved to ARM32::IceAssemblerARM32::orr().
   void orr(Register rd, Register rn, Operand o, Condition cond = AL);
   void orrs(Register rd, Register rn, Operand o, Condition cond = AL);
 
-#if 0
-  // Moved to IceAssemblerARM32::mov()
+  // Moved to ARM32::IceAssemblerARM32::mov()
   void mov(Register rd, Operand o, Condition cond = AL);
   void movs(Register rd, Operand o, Condition cond = AL);
 #endif
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index 4e5549d..eda6e74 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -442,7 +442,7 @@
     //   adc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
     //
     // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
-    // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
+    // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
     if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
       // Conditions of rule violated.
       return setNeedsTextFixup();
@@ -490,7 +490,7 @@
     //   add{s}<c> <Rd>, sp, #<RotatedImm8>
     //
     // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
-    // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
+    // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
     if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
       // Conditions of rule violated.
       return setNeedsTextFixup();
@@ -722,7 +722,7 @@
     //   sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
     //
     // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
-    // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
+    // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
     if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
       // Conditions of rule violated.
       return setNeedsTextFixup();
@@ -768,6 +768,50 @@
   emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
 }
 
+void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
+                         const Operand *OpSrc1, bool SetFlags,
+                         CondARM32::Cond Cond) {
+  IValueT Rd;
+  if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
+    return setNeedsTextFixup();
+  IValueT Rn;
+  if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
+    return setNeedsTextFixup();
+  constexpr IValueT Orr = B3 | B2; // i.e. 1100
+  IValueT Src1Value;
+  // TODO(kschimpf) Handle other possible decodings of orr.
+  switch (decodeOperand(OpSrc1, Src1Value)) {
+  default:
+    return setNeedsTextFixup();
+  case DecodedAsRegister: {
+    // ORR (register) - ARM Section A8.8.123, encoding A1:
+    //   orr{s}<c> <Rd>, <Rn>, <Rm>
+    //
+    // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
+    // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
+    constexpr IValueT Shift = 0;
+    Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Shift);
+    if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
+      // Conditions of rule violated.
+      return setNeedsTextFixup();
+    emitType01(Cond, kInstTypeDataRegister, Orr, SetFlags, Rn, Rd, Src1Value);
+    return;
+  }
+  case DecodedAsRotatedImm8: {
+    // ORR (register) - ARM Section A8.8.123, encoding A1:
+    //   orr{s}<c> <Rd>, <Rn>,  #<RotatedImm8>
+    //
+    // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
+    // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
+    if (Rd == RegARM32::Encoded_Reg_pc && SetFlags)
+      // Conditions of rule violated.
+      return setNeedsTextFixup();
+    emitType01(Cond, kInstTypeDataImmediate, Orr, SetFlags, Rn, Rd, Src1Value);
+    return;
+  }
+  }
+}
+
 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
                          const Operand *OpSrc1, bool SetFlags,
                          CondARM32::Cond Cond) {
@@ -816,7 +860,8 @@
     //
     // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
     // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
-    Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
+    constexpr IValueT Shift = 0;
+    Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Shift);
     if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
       // Conditions of rule violated.
       return setNeedsTextFixup();
@@ -830,7 +875,7 @@
     //    sub{s}<c> sp, <Rn>, #<RotatedImm8>
     //
     // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
-    // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8
+    // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
     if (Rd == RegARM32::Encoded_Reg_pc)
       // Conditions of rule violated.
       return setNeedsTextFixup();
diff --git a/src/IceAssemblerARM32.h b/src/IceAssemblerARM32.h
index 2bf53a5..0443869 100644
--- a/src/IceAssemblerARM32.h
+++ b/src/IceAssemblerARM32.h
@@ -161,6 +161,9 @@
 
   void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
 
+  void orr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
+           bool SetFlags, CondARM32::Cond Cond);
+
   void sbc(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
            bool SetFlags, CondARM32::Cond Cond);
 
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index e9a0922..8f3872a 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -365,6 +365,13 @@
     emitUsingTextFixup(Func);
 }
 
+template <> void InstARM32Orr::emitIAS(const Cfg *Func) const {
+  ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+  Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
+  if (Asm->needsTextFixup())
+    emitUsingTextFixup(Func);
+}
+
 template <> void InstARM32Mul::emitIAS(const Cfg *Func) const {
   ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
   Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
diff --git a/tests_lit/assembler/arm32/orr.ll b/tests_lit/assembler/arm32/orr.ll
new file mode 100644
index 0000000..480b99a
--- /dev/null
+++ b/tests_lit/assembler/arm32/orr.ll
@@ -0,0 +1,110 @@
+; Show that we know how to translate or.
+
+; NOTE: We use -O2 to get rid of memory stores.
+
+; REQUIRES: allow_dump
+
+; Compile using standalone assembler.
+; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 \
+; RUN:   | FileCheck %s --check-prefix=ASM
+
+; Show bytes in assembled standalone code.
+; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
+; RUN:   --args -O2 | FileCheck %s --check-prefix=DIS
+
+; Compile using integrated assembler.
+; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
+; RUN:   | FileCheck %s --check-prefix=IASM
+
+; Show bytes in assembled integrated code.
+; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
+; RUN:   --args -O2 | FileCheck %s --check-prefix=DIS
+
+define internal i32 @Or1WithR0(i32 %p) {
+  %v = or i32 %p, 1
+  ret i32 %v
+}
+
+; ASM-LABEL:Or1WithR0:
+; ASM-NEXT:.LOr1WithR0$__0:
+; ASM-NEXT:     orr     r0, r0, #1
+
+; DIS-LABEL:00000000 <Or1WithR0>:
+; DIS-NEXT:   0:        e3800001
+
+; IASM-LABEL:Or1WithR0:
+; IASM-NEXT:.LOr1WithR0$__0:
+; IASM-NEXT:    .byte 0x1
+; IASM-NEXT:    .byte 0x0
+; IASM-NEXT:    .byte 0x80
+; IASM-NEXT:    .byte 0xe3
+
+define internal i32 @Or2Regs(i32 %p1, i32 %p2) {
+  %v = or i32 %p1, %p2
+  ret i32 %v
+}
+
+; ASM-LABEL:Or2Regs:
+; ASM-NEXT:.LOr2Regs$__0:
+; ASM-NEXT:     orr     r0, r0, r1
+
+; DIS-LABEL:00000010 <Or2Regs>:
+; DIS-NEXT:  10:        e1800001
+
+; IASM-LABEL:Or2Regs:
+; IASM-NEXT:.LOr2Regs$__0:
+; IASM-NEXT:    .byte 0x1
+; IASM-NEXT:    .byte 0x0
+; IASM-NEXT:    .byte 0x80
+; IASM-NEXT:    .byte 0xe1
+
+define internal i64 @OrI64WithR0R1(i64 %p) {
+  %v = or i64 %p, 1
+  ret i64 %v
+}
+
+; ASM-LABEL:OrI64WithR0R1:
+; ASM-NEXT:.LOrI64WithR0R1$__0:
+; ASM-NEXT:     orr     r0, r0, #1
+; ASM-NEXT:     orr     r1, r1, #0
+
+; DIS-LABEL:00000020 <OrI64WithR0R1>:
+; DIS-NEXT:  20:        e3800001
+; DIS-NEXT:  24:        e3811000
+
+; IASM-LABEL:OrI64WithR0R1:
+; IASM-NEXT:.LOrI64WithR0R1$__0:
+; IASM-NEXT:    .byte 0x1
+; IASM-NEXT:    .byte 0x0
+; IASM-NEXT:    .byte 0x80
+; IASM-NEXT:    .byte 0xe3
+; IASM-NEXT:    .byte 0x0
+; IASM-NEXT:    .byte 0x10
+; IASM-NEXT:    .byte 0x81
+; IASM-NEXT:    .byte 0xe3
+
+
+define internal i64 @OrI64Regs(i64 %p1, i64 %p2) {
+  %v = or i64 %p1, %p2
+  ret i64 %v
+}
+
+; ASM-LABEL:OrI64Regs:
+; ASM-NEXT:.LOrI64Regs$__0:
+; ASM-NEXT:     orr     r0, r0, r2
+; ASM-NEXT:     orr     r1, r1, r3
+
+; DIS-LABEL:00000030 <OrI64Regs>:
+; DIS-NEXT:  30:        e1800002
+; DIS-NEXT:  34:        e1811003
+
+; IASM-LABEL:OrI64Regs:
+; IASM-NEXT:.LOrI64Regs$__0:
+; IASM-NEXT:    .byte 0x2
+; IASM-NEXT:    .byte 0x0
+; IASM-NEXT:    .byte 0x80
+; IASM-NEXT:    .byte 0xe1
+; IASM-NEXT:    .byte 0x3
+; IASM-NEXT:    .byte 0x10
+; IASM-NEXT:    .byte 0x81
+; IASM-NEXT:    .byte 0xe1