Index: lib/IR/DataLayout.cpp =================================================================== --- lib/IR/DataLayout.cpp +++ lib/IR/DataLayout.cpp @@ -155,7 +155,8 @@ const char *DataLayout::getManglingComponent(const Triple &T) { if (T.isOSBinFormatMachO()) return "-m:o"; - if (T.isOSBinFormatELF() || T.isArch64Bit()) + if (T.isOSBinFormatELF() || T.isArch64Bit() || + (T.isOSWindows() && T.getArch() != Triple::x86)) return "-m:e"; assert(T.isOSBinFormatCOFF()); return "-m:w"; Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -250,7 +250,8 @@ setLibcallName(RTLIB::SRL_I128, 0); setLibcallName(RTLIB::SRA_I128, 0); - if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO()) { + if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO() && + !Subtarget->isTargetWindows()) { // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 setLibcallName(RTLIB::ADD_F64, "__aeabi_dadd"); Index: lib/Target/ARM/ARMSubtarget.h =================================================================== --- lib/Target/ARM/ARMSubtarget.h +++ lib/Target/ARM/ARMSubtarget.h @@ -311,14 +311,14 @@ const Triple &getTargetTriple() const { return TargetTriple; } - bool isTargetIOS() const { return TargetTriple.isiOS(); } bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } - bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } + bool isTargetIOS() const { return TargetTriple.isiOS(); } bool isTargetLinux() const { return TargetTriple.isOSLinux(); } - bool isTargetNetBSD() const { - return TargetTriple.getOS() == Triple::NetBSD; - } + bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } + bool isTargetNetBSD() const { return TargetTriple.getOS() == Triple::NetBSD; } + bool isTargetWindows() const { return TargetTriple.isOSWindows(); } + bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } @@ -332,7 +332,7 @@ bool isTargetAEABI() const { return (TargetTriple.getEnvironment() == Triple::EABI || TargetTriple.getEnvironment() == Triple::EABIHF) && - !isTargetDarwin(); + !isTargetDarwin() && !isTargetWindows(); } // ARM Targets that support EHABI exception handling standard @@ -343,12 +343,14 @@ TargetTriple.getEnvironment() == Triple::EABIHF || TargetTriple.getEnvironment() == Triple::GNUEABIHF || TargetTriple.getEnvironment() == Triple::Android) && - !isTargetDarwin(); + !isTargetDarwin() && !isTargetWindows(); } bool isTargetHardFloat() const { + // FIXME: this is invalid for WindowsCE return TargetTriple.getEnvironment() == Triple::GNUEABIHF || - TargetTriple.getEnvironment() == Triple::EABIHF; + TargetTriple.getEnvironment() == Triple::EABIHF || + isTargetWindows(); } bool isAPCS_ABI() const { Index: lib/Target/ARM/ARMSubtarget.cpp =================================================================== --- lib/Target/ARM/ARMSubtarget.cpp +++ lib/Target/ARM/ARMSubtarget.cpp @@ -211,6 +211,12 @@ } } + // FIXME: this is invalid for WindowsCE + if (isTargetWindows()) { + TargetABI = ARM_ABI_AAPCS; + NoARM = true; + } + if (isAAPCS_ABI()) stackAlignment = 8; if (isTargetNaCl()) Index: lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h +++ lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_ARMTARGETASMINFO_H #define LLVM_ARMTARGETASMINFO_H +#include "llvm/MC/MCAsmInfoCOFF.h" #include "llvm/MC/MCAsmInfoDarwin.h" #include "llvm/MC/MCAsmInfoELF.h" @@ -33,6 +34,18 @@ void setUseIntegratedAssembler(bool Value) override; }; + class ARMCOFFMCAsmInfoMicrosoft : public MCAsmInfoMicrosoft { + void anchor(); + public: + explicit ARMCOFFMCAsmInfoMicrosoft(); + }; + + class ARMCOFFMCAsmInfoGNU : public MCAsmInfoGNUCOFF { + void anchor(); + public: + explicit ARMCOFFMCAsmInfoGNU(); + }; + } // namespace llvm #endif Index: lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -76,3 +76,31 @@ DwarfRegNumForCFI = true; } } + +void ARMCOFFMCAsmInfoMicrosoft::anchor() { } + +ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() { + AlignmentIsInBytes = false; + + PrivateGlobalPrefix = "$M"; +} + +void ARMCOFFMCAsmInfoGNU::anchor() { } + +ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() { + AlignmentIsInBytes = false; + + CommentString = "@"; + Code16Directive = ".thumb"; + Code32Directive = ".error \"ARM mode code is not permitted on this target\""; + PrivateGlobalPrefix = ".L"; + + HasLEB128 = true; + SupportsDebugInformation = true; + ExceptionsType = ExceptionHandling::None; + UseParensForSymbolVariant = true; + + UseIntegratedAssembler = false; + DwarfRegNumForCFI = true; +} + Index: lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -218,10 +218,31 @@ Triple TheTriple(TT); MCAsmInfo *MAI; - if (TheTriple.isOSBinFormatMachO()) + switch (TheTriple.getOS()) { + case llvm::Triple::Darwin: + case llvm::Triple::IOS: + case llvm::Triple::MacOSX: MAI = new ARMMCAsmInfoDarwin(TT); - else - MAI = new ARMELFMCAsmInfo(TT); + break; + case llvm::Triple::Win32: + switch (TheTriple.getEnvironment()) { + case llvm::Triple::Itanium: + MAI = new ARMCOFFMCAsmInfoGNU(); + break; + case llvm::Triple::MSVC: + MAI = new ARMCOFFMCAsmInfoMicrosoft(); + break; + default: + llvm_unreachable("invalid environment"); + } + break; + default: + if (TheTriple.isOSBinFormatMachO()) + MAI = new ARMMCAsmInfoDarwin(TT); + else + MAI = new ARMELFMCAsmInfo(TT); + break; + } unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0)); Index: test/CodeGen/ARM/Windows/aapcs.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/aapcs.ll @@ -0,0 +1,16 @@ +; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s + +; AAPCS mandates an 8-byte stack alignment. The alloca is implicitly aligned, +; and no bic is required. + +declare void @callee(i8 *%i) + +define void @caller() { + %i = alloca i8, align 8 + call void @callee(i8* %i) + ret void +} + +; CHECK: sub sp, #8 +; CHECK-NOT: bic + Index: test/CodeGen/ARM/Windows/hard-float.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/hard-float.ll @@ -0,0 +1,10 @@ +; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s + +define float @function(float %f, float %g) nounwind { +entry: + %h = fadd float %f, %g + ret float %h +} + +; CHECK: vadd.f32 s0, s0, s1 + Index: test/CodeGen/ARM/Windows/mangling.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/mangling.ll @@ -0,0 +1,9 @@ +; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s + +define void @function() nounwind { +entry: + ret void +} + +; CHECK-LABEL: function + Index: test/CodeGen/ARM/Windows/no-aeabi.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/no-aeabi.ll @@ -0,0 +1,10 @@ +; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s + +define i32 @divide(i32 %i, i32 %j) nounwind { +entry: + %quotient = sdiv i32 %i, %j + ret i32 %quotient +} + +; CHECK-NOT: __aeabi_idiv + Index: test/CodeGen/ARM/Windows/no-arm-mode.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/no-arm-mode.ll @@ -0,0 +1,5 @@ +; RUN: not llc -mtriple=armv7-windows-itanium -mcpu=cortex-a9 -o /dev/null %s 2>&1 \ +; RUN: | FileCheck %s + +; CHECK: does not support ARM mode execution + Index: test/CodeGen/ARM/Windows/no-ehabi.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/no-ehabi.ll @@ -0,0 +1,21 @@ +; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s + +declare void @callee(i32 %i) + +define i32 @caller(i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, + i32 %p) { +entry: + %q = add nsw i32 %j, %i + %r = add nsw i32 %q, %k + %s = add nsw i32 %r, %l + call void @callee(i32 %s) + %t = add nsw i32 %n, %m + %u = add nsw i32 %t, %o + %v = add nsw i32 %u, %p + call void @callee(i32 %v) + %w = add nsw i32 %v, %s + ret i32 %w +} + +; CHECK-NOT: .save {{{.*}}} +