Commit cb504ca5 by Karl Schimpf

Add workaround to allow testing of ARM integrated assembler.

It turns out that there are several instruction in the ARM integrated assembler that do not get translated correctly. This results in the spec2k tests not being compilable. To workaround this problem, this CL adds a (temporary) flag that allows all translations to be applied by the integrated assembler. When this flag is false (the default) only correctly working translations to be applied by the integrated assembler. This allows lit tests to still be applied to the correct portions of broken translations. This CL also fixes a bug with local (instruction) labels that did not generate a corresponding label to the -filetype=iasm assembly file. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4334 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1424923005 .
parent 4f8805b7
......@@ -66,8 +66,8 @@ def main():
flat_attrs += v
arch_flags = { 'x8632': [],
'x8664': [],
# ARM doesn't have an integrated assembler yet.
'arm32': ['--filetype=asm'] }
# ARM doesn't have an ELF writer yet.
'arm32': ['--filetype=iasm'] }
# all_keys is only used in the help text.
all_keys = '; '.join([' '.join(targets), ' '.join(sandboxing),
' '.join(opt_levels), ' '.join(flat_attrs)])
......
......@@ -119,7 +119,13 @@ public:
return getOrCreateLabel(Number, LocalLabels);
}
void bindLocalLabel(SizeT Number) {
void bindLocalLabel(const Cfg *Func, const InstARM32Label *InstL,
SizeT Number) {
if (BuildDefs::dump() &&
!Func->getContext()->getFlags().getDisableHybridAssembly()) {
constexpr SizeT InstSize = 0;
emitTextInst(InstL->getName(Func) + ":", InstSize);
}
Label *L = getOrCreateLocalLabel(Number);
if (!getPreliminary())
this->bind(L);
......
......@@ -50,6 +50,12 @@ cl::opt<bool> AllowIacaMarks(
"inserted. These binaries are not executable."),
cl::init(false));
cl::opt<bool> AllowUnsafeIas(
"unsafe-ias",
cl::desc("Convert (potentially broken) instructions to bytes in "
"integrated assembler."),
cl::init(false));
// This is currently needed by crosstest.py.
cl::opt<bool> AllowUninitializedGlobals(
"allow-uninitialized-globals",
......@@ -382,6 +388,7 @@ void ClFlags::resetClFlags(ClFlags &OutFlags) {
OutFlags.AllowErrorRecovery = false;
OutFlags.AllowExternDefinedSymbols = false;
OutFlags.AllowIacaMarks = false;
OutFlags.AllowUnsafeIas = false;
OutFlags.AllowUninitializedGlobals = false;
OutFlags.DataSections = false;
OutFlags.DecorateAsm = false;
......@@ -456,6 +463,7 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
OutFlags.setDisableInternal(::DisableInternal);
OutFlags.setDisableIRGeneration(::DisableIRGeneration);
OutFlags.setDisableTranslation(::DisableTranslation);
OutFlags.setAllowUnsafeIas(::AllowUnsafeIas);
OutFlags.setDumpStats(::DumpStats);
OutFlags.setEnableBlockProfile(::EnableBlockProfile);
OutFlags.setForceMemIntrinOpt(::ForceMemIntrinOpt);
......
......@@ -49,6 +49,9 @@ public:
bool getAllowIacaMarks() const { return AllowIacaMarks; }
void setAllowIacaMarks(bool NewValue) { AllowIacaMarks = NewValue; }
bool getAllowUnsafeIas() const { return AllowUnsafeIas; }
void setAllowUnsafeIas(bool NewValue) { AllowUnsafeIas = NewValue; }
bool getAllowUninitializedGlobals() const {
return AllowUninitializedGlobals;
}
......@@ -256,6 +259,9 @@ private:
bool AllowExternDefinedSymbols;
bool AllowIacaMarks;
bool AllowUninitializedGlobals;
// TODO(kschimpf): This is a temporary flag. Nuke this once the ARM integrated
// assembler is working.
bool AllowUnsafeIas;
bool DataSections;
bool DecorateAsm;
bool DisableHybridAssembly;
......
......@@ -757,7 +757,8 @@ void InstARM32Mov::emit(const Cfg *Func) const {
}
void InstARM32Mov::emitIAS(const Cfg *Func) const {
(void)Func;
if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func);
assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (!(isMultiDest() || isMultiSource())) {
......@@ -810,6 +811,8 @@ void InstARM32Br::emit(const Cfg *Func) const {
}
void InstARM32Br::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (Label) {
Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()), getPredicate());
......@@ -895,7 +898,7 @@ void InstARM32Label::emit(const Cfg *Func) const {
void InstARM32Label::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->bindLocalLabel(Number);
Asm->bindLocalLabel(Func, this, Number);
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
......@@ -991,6 +994,8 @@ template <> void InstARM32Movw::emit(const Cfg *Func) const {
}
template <> void InstARM32Movw::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func);
assert(getSrcSize() == 1);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->movw(getDest(), getSrc(0), getPredicate());
......@@ -1017,6 +1022,8 @@ template <> void InstARM32Movt::emit(const Cfg *Func) const {
}
template <> void InstARM32Movt::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func);
assert(getSrcSize() == 2);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->movt(getDest(), getSrc(1), getPredicate());
......
......@@ -13,12 +13,12 @@
; RUN: --args -O2 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 -unsafe-ias \
; 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
; RUN: --args -O2 -unsafe-ias | FileCheck %s --check-prefix=DIS
define internal i32 @AllocBigAlign() {
%addr = alloca i8, align 32
......
......@@ -9,12 +9,12 @@
; RUN: --args -Om1 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 -unsafe-ias \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 | FileCheck %s --check-prefix=DIS
; RUN: --args -Om1 -unsafe-ias | FileCheck %s --check-prefix=DIS
; REQUIRES: allow_dump
......
......@@ -12,12 +12,12 @@
; RUN: --args -Om1 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 -unsafe-ias \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 | FileCheck %s --check-prefix=DIS
; RUN: --args -Om1 -unsafe-ias | FileCheck %s --check-prefix=DIS
define internal void @simple_uncond_branch() {
; DIS-LABEL: 00000000 <simple_uncond_branch>:
......
......@@ -11,12 +11,12 @@
; RUN: --args -O2 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 -unsafe-ias \
; 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
; RUN: --args -O2 -unsafe-ias | FileCheck %s --check-prefix=DIS
@filler = internal global [128 x i8] zeroinitializer, align 4
......
......@@ -11,12 +11,12 @@
; RUN: --args -Om1 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 -unsafe-ias \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 | FileCheck %s --check-prefix=DIS
; RUN: --args -Om1 -unsafe-ias | FileCheck %s --check-prefix=DIS
define internal i32 @add1ToR0(i32 %p) {
%v = add i32 %p, 1
......
......@@ -11,12 +11,12 @@
; RUN: --args -O2 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 -unsafe-ias \
; 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
; RUN: --args -O2 -unsafe-ias | FileCheck %s --check-prefix=DIS
define internal i32 @Imm1() {
ret i32 1
......
......@@ -13,12 +13,12 @@
; RUN: --args -O2 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 -unsafe-ias \
; 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
; RUN: --args -O2 -unsafe-ias | FileCheck %s --check-prefix=DIS
define internal i32 @MulTwoRegs(i32 %a, i32 %b) {
%v = mul i32 %a, %b
......
......@@ -14,11 +14,12 @@
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 -mattr=hwdiv-arm \
; RUN: | FileCheck %s --check-prefix=IASM
; RUN: -unsafe-ias | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 -mattr=hwdiv-arm | FileCheck %s --check-prefix=DIS
; RUN: --args -O2 -mattr=hwdiv-arm -unsafe-ias \
; RUN: | FileCheck %s --check-prefix=DIS
define internal i32 @SdivTwoRegs(i32 %a, i32 %b) {
%v = sdiv i32 %a, %b
......@@ -49,6 +50,7 @@ define internal i32 @SdivTwoRegs(i32 %a, i32 %b) {
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x1a
; IASM-NEXT: .long 0xe7fedef0
; IASM-NEXT:.LSdivTwoRegs$local$__0:
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xf1
; IASM-NEXT: .byte 0x10
......
......@@ -14,11 +14,12 @@
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 -mattr=hwdiv-arm \
; RUN: | FileCheck %s --check-prefix=IASM
; RUN: -unsafe-ias | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 -mattr=hwdiv-arm | FileCheck %s --check-prefix=DIS
; RUN: --args -O2 -mattr=hwdiv-arm -unsafe-ias \
; RUN: | FileCheck %s --check-prefix=DIS
define internal i32 @UdivTwoRegs(i32 %a, i32 %b) {
%v = udiv i32 %a, %b
......@@ -49,6 +50,7 @@ define internal i32 @UdivTwoRegs(i32 %a, i32 %b) {
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x1a
; IASM-NEXT: .long 0xe7fedef0
; IASM-NEXT:.LUdivTwoRegs$local$__0:
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xf1
; IASM-NEXT: .byte 0x30
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment