Add BIC(register) and BIC(immediate) to ARM integrated assembler.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4334
R=jpp@chromium.org, stichnot@chromium.org
Review URL: https://codereview.chromium.org/1415943009 .
diff --git a/src/DartARM32/assembler_arm.cc b/src/DartARM32/assembler_arm.cc
index 180a182..410edcd 100644
--- a/src/DartARM32/assembler_arm.cc
+++ b/src/DartARM32/assembler_arm.cc
@@ -301,15 +301,17 @@
}
+#if 0
+// Moved to ARM32::AssemblerARM32::bic();
void Assembler::bic(Register rd, Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), BIC, 0, rn, rd, o);
}
-
+// Moved to ARM32::AssemblerARM32::bic();
void Assembler::bics(Register rd, Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), BIC, 1, rn, rd, o);
}
-
+#endif
void Assembler::mvn(Register rd, Operand o, Condition cond) {
EmitType01(cond, o.type(), MVN, 0, R0, rd, o);
diff --git a/src/DartARM32/assembler_arm.h b/src/DartARM32/assembler_arm.h
index ffc360b..1cedcbc 100644
--- a/src/DartARM32/assembler_arm.h
+++ b/src/DartARM32/assembler_arm.h
@@ -501,8 +501,11 @@
void movs(Register rd, Operand o, Condition cond = AL);
#endif
+#if 0
+ // Moved to ARM32::IceAssemblerARM32::bic()
void bic(Register rd, Register rn, Operand o, Condition cond = AL);
void bics(Register rd, Register rn, Operand o, Condition cond = AL);
+#endif
void mvn(Register rd, Operand o, Condition cond = AL);
void mvns(Register rd, Operand o, Condition cond = AL);
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index b6a4fc8..99be795 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -563,6 +563,24 @@
emitInst(Encoding);
}
+void AssemblerARM32::bic(const Operand *OpRd, const Operand *OpRn,
+ const Operand *OpSrc1, bool SetFlags,
+ CondARM32::Cond Cond) {
+ // BIC (register) - ARM section A8.8.22, encoding A1:
+ // bic{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+ //
+ // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
+ // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
+ //
+ // BIC (immediate) - ARM section A8.8.21, encoding A1:
+ // bic{s}<c> <Rd>, <Rn>, #<RotatedImm8>
+ //
+ // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn,
+ // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8.
+ IValueT Opcode = B3 | B2 | B1; // i.e. 1110
+ emitType01(Opcode, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+}
+
void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
// BX - ARM section A8.8.27, encoding A1:
// bx<c> <Rm>
diff --git a/src/IceAssemblerARM32.h b/src/IceAssemblerARM32.h
index 514cb78..1a8edf1 100644
--- a/src/IceAssemblerARM32.h
+++ b/src/IceAssemblerARM32.h
@@ -152,6 +152,9 @@
void cmp(const Operand *OpRn, const Operand *OpSrc1, CondARM32::Cond Cond);
+ void bic(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
+ bool SetFlags, CondARM32::Cond Cond);
+
void eor(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 1697ee8..a5edfc9 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -365,6 +365,13 @@
emitUsingTextFixup(Func);
}
+template <> void InstARM32Bic::emitIAS(const Cfg *Func) const {
+ ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ Asm->bic(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
+ if (Asm->needsTextFixup())
+ emitUsingTextFixup(Func);
+}
+
template <> void InstARM32Eor::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->eor(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
diff --git a/tests_lit/assembler/arm32/bic.ll b/tests_lit/assembler/arm32/bic.ll
new file mode 100644
index 0000000..d30a087
--- /dev/null
+++ b/tests_lit/assembler/arm32/bic.ll
@@ -0,0 +1,89 @@
+; Show that we know how to translate bic.
+
+; 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 @AllocBigAlign() {
+ %addr = alloca i8, align 32
+ %v = ptrtoint i8* %addr to i32
+ ret i32 %v
+}
+
+; ASM-LABEL:AllocBigAlign:
+; ASM:.LAllocBigAlign$__0:
+; ASM: push {fp}
+; ASM: mov fp, sp
+; ASM: sub sp, sp, #12
+; ASM: bic sp, sp, #31
+; ASM: sub sp, sp, #32
+; ASM: mov r0, sp
+; ASM: mov sp, fp
+; ASM: pop {fp}
+; ASM: # fp = def.pseudo
+; ASM: bx lr
+
+; DIS-LABEL:00000000 <AllocBigAlign>:
+; DIS-NEXT: 0: e52db004
+; DIS-NEXT: 4: e1a0b00d
+; DIS-NEXT: 8: e24dd00c
+; DIS-NEXT: c: e3cdd01f
+; DIS-NEXT: 10: e24dd020
+; DIS-NEXT: 14: e1a0000d
+; DIS-NEXT: 18: e1a0d00b
+; DIS-NEXT: 1c: e49db004
+; DIS-NEXT: 20: e12fff1e
+
+; IASM-LABEL:AllocBigAlign:
+; IASM-NEXT:.LAllocBigAlign$__0:
+; IASM: push {fp}
+; IASM: .byte 0xd
+; IASM-NEXT: .byte 0xb0
+; IASM-NEXT: .byte 0xa0
+; IASM-NEXT: .byte 0xe1
+
+; IASM: .byte 0xc
+; IASM-NEXT: .byte 0xd0
+; IASM-NEXT: .byte 0x4d
+; IASM-NEXT: .byte 0xe2
+
+; IASM: .byte 0x1f
+; IASM-NEXT: .byte 0xd0
+; IASM-NEXT: .byte 0xcd
+; IASM-NEXT: .byte 0xe3
+
+; IASM: .byte 0x20
+; IASM-NEXT: .byte 0xd0
+; IASM-NEXT: .byte 0x4d
+; IASM-NEXT: .byte 0xe2
+
+; IASM: .byte 0xd
+; IASM-NEXT: .byte 0x0
+; IASM-NEXT: .byte 0xa0
+; IASM-NEXT: .byte 0xe1
+
+; IASM: .byte 0xb
+; IASM-NEXT: .byte 0xd0
+; IASM-NEXT: .byte 0xa0
+; IASM-NEXT: .byte 0xe1
+; IASM: pop {fp}
+; IASM: .byte 0x1e
+; IASM-NEXT: .byte 0xff
+; IASM-NEXT: .byte 0x2f
+; IASM-NEXT: .byte 0xe1