ARMSubArch_v7em,
ARMSubArch_v7m,
ARMSubArch_v7s,
+ ARMSubArch_v7k,
ARMSubArch_v6,
ARMSubArch_v6m,
ARMSubArch_v6k,
AMDHSA, // AMD HSA Runtime
PS4,
ELFIAMCU,
- LastOSType = ELFIAMCU
+ TvOS, // Apple tvOS
+ WatchOS, // Apple watchOS
+ LastOSType = WatchOS
};
enum EnvironmentType {
UnknownEnvironment,
}
/// Is this an iOS triple.
+ /// Note: This identifies tvOS as a variant of iOS. If that ever
+ /// changes, i.e., if the two operating systems diverge or their version
+ /// numbers get out of sync, that will need to be changed.
+ /// watchOS has completely different version numbers so it is not included.
bool isiOS() const {
- return getOS() == Triple::IOS;
+ return getOS() == Triple::IOS || isTvOS();
}
- /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
+ /// Is this an Apple tvOS triple.
+ bool isTvOS() const {
+ return getOS() == Triple::TvOS;
+ }
+
+ /// Is this an Apple watchOS triple.
+ bool isWatchOS() const {
+ return getOS() == Triple::WatchOS;
+ }
+
+ /// isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
bool isOSDarwin() const {
- return isMacOSX() || isiOS();
+ return isMacOSX() || isiOS() || isWatchOS();
}
bool isOSNetBSD() const {
enum MCVersionMinType {
MCVM_IOSVersionMin, ///< .ios_version_min
- MCVM_OSXVersionMin ///< .macosx_version_min
+ MCVM_OSXVersionMin, ///< .macosx_version_min
+ MCVM_TvOSVersionMin, ///< .tvos_version_min
+ MCVM_WatchOSVersionMin, ///< .watchos_version_min
};
} // end namespace llvm
bool Error(SMLoc L, const Twine &Msg) {
return getParser().Error(L, Msg);
}
+ void Note(SMLoc L, const Twine &Msg) {
+ getParser().Note(L, Msg);
+ }
bool TokError(const Twine &Msg) {
return getParser().TokError(Msg);
}
ARM_CPU_NAME("cortex-m4", AK_ARMV7EM, FK_NONE, true, AEK_NONE)
ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true,
(AEK_HWDIVARM | AEK_HWDIV))
+ARM_CPU_NAME("cortex-a7", AK_ARMV7K, FK_NONE, true, AEK_HWDIVARM | AEK_HWDIV)
// Invalid CPU
ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AEK_INVALID)
#undef ARM_CPU_NAME
LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
LC_ENCRYPTION_INFO_64 = 0x0000002Cu,
LC_LINKER_OPTION = 0x0000002Du,
- LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu
+ LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu,
+ LC_VERSION_MIN_TVOS = 0x0000002Fu,
+ LC_VERSION_MIN_WATCHOS = 0x00000030u,
};
enum : uint32_t {
unsigned Major, Minor, Update;
TT.getOSVersion(Major, Minor, Update);
// If there is a version specified, Major will be non-zero.
- if (Major)
- OutStreamer->EmitVersionMin((TT.isMacOSX() ?
- MCVM_OSXVersionMin : MCVM_IOSVersionMin),
- Major, Minor, Update);
+ if (Major) {
+ MCVersionMinType VersionType;
+ if (TT.isWatchOS())
+ VersionType = MCVM_WatchOSVersionMin;
+ else if (TT.isTvOS())
+ VersionType = MCVM_TvOSVersionMin;
+ else if (TT.isMacOSX())
+ VersionType = MCVM_OSXVersionMin;
+ else
+ VersionType = MCVM_IOSVersionMin;
+ OutStreamer->EmitVersionMin(VersionType, Major, Minor, Update);
+ }
}
// Allow the target to emit any magic that it wants at the start of the file.
void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
unsigned Minor, unsigned Update) {
switch (Kind) {
+ case MCVM_WatchOSVersionMin: OS << "\t.watchos_version_min"; break;
+ case MCVM_TvOSVersionMin: OS << "\t.tvos_version_min"; break;
case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
}
unsigned Major, Minor, Update;
TT.getOSVersion(Major, Minor, Update);
// If there is a version specified, Major will be non-zero.
- if (Major)
- S->EmitVersionMin((TT.isMacOSX() ?
- MCVM_OSXVersionMin : MCVM_IOSVersionMin),
- Major, Minor, Update);
+ if (Major) {
+ MCVersionMinType VersionType;
+ if (TT.isWatchOS())
+ VersionType = MCVM_WatchOSVersionMin;
+ else if (TT.isTvOS())
+ VersionType = MCVM_TvOSVersionMin;
+ else if (TT.isMacOSX())
+ VersionType = MCVM_OSXVersionMin;
+ else {
+ assert(TT.isiOS() && "Must only be iOS platform left");
+ VersionType = MCVM_IOSVersionMin;
+ }
+ S->EmitVersionMin(VersionType, Major, Minor, Update);
+ }
}
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
unsigned TAA = 0, unsigned ImplicitAlign = 0,
unsigned StubSize = 0);
+ SMLoc LastVersionMinDirective;
+
public:
DarwinAsmParser() {}
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
+ addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
+ ".watchos_version_min");
+ addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".tvos_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
".macosx_version_min");
+
+ LastVersionMinDirective = SMLoc();
}
bool parseDirectiveDesc(StringRef, SMLoc);
/// parseVersionMin
/// ::= .ios_version_min major,minor[,update]
/// ::= .macosx_version_min major,minor[,update]
-bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
+bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) {
int64_t Major = 0, Minor = 0, Update = 0;
int Kind = StringSwitch<int>(Directive)
+ .Case(".watchos_version_min", MCVM_WatchOSVersionMin)
+ .Case(".tvos_version_min", MCVM_TvOSVersionMin)
.Case(".ios_version_min", MCVM_IOSVersionMin)
.Case(".macosx_version_min", MCVM_OSXVersionMin);
// Get the major version number.
Lex();
}
+ const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
+ Triple::OSType ExpectedOS = Triple::UnknownOS;
+ switch ((MCVersionMinType)Kind) {
+ case MCVM_WatchOSVersionMin: ExpectedOS = Triple::WatchOS; break;
+ case MCVM_TvOSVersionMin: ExpectedOS = Triple::TvOS; break;
+ case MCVM_IOSVersionMin: ExpectedOS = Triple::IOS; break;
+ case MCVM_OSXVersionMin: ExpectedOS = Triple::MacOSX; break;
+ }
+ if (T.getOS() != ExpectedOS)
+ Warning(Loc, Directive + " should only be used for " +
+ Triple::getOSTypeName(ExpectedOS) + " targets");
+
+ if (LastVersionMinDirective.isValid()) {
+ Warning(Loc, "overriding previous version_min directive");
+ Note(LastVersionMinDirective, "previous definition is here");
+ }
+ LastVersionMinDirective = Loc;
+
// We've parsed a correct version specifier, so send it to the streamer.
getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
assert(VersionInfo.Major < 65536 && "unencodable major target version");
uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
(VersionInfo.Major << 16);
- write32(VersionInfo.Kind == MCVM_OSXVersionMin ? MachO::LC_VERSION_MIN_MACOSX :
- MachO::LC_VERSION_MIN_IPHONEOS);
+ MachO::LoadCommandType LCType;
+ switch (VersionInfo.Kind) {
+ case MCVM_OSXVersionMin:
+ LCType = MachO::LC_VERSION_MIN_MACOSX;
+ break;
+ case MCVM_IOSVersionMin:
+ LCType = MachO::LC_VERSION_MIN_IPHONEOS;
+ break;
+ case MCVM_TvOSVersionMin:
+ LCType = MachO::LC_VERSION_MIN_TVOS;
+ break;
+ case MCVM_WatchOSVersionMin:
+ LCType = MachO::LC_VERSION_MIN_WATCHOS;
+ break;
+ }
+ write32(LCType);
write32(sizeof(MachO::version_min_command));
write32(EncodedVersion);
write32(0); // reserved.
return ARM::PK_R;
case ARM::AK_ARMV7:
case ARM::AK_ARMV7A:
+ case ARM::AK_ARMV7K:
case ARM::AK_ARMV7L:
case ARM::AK_ARMV8A:
case ARM::AK_ARMV8_1A:
case AMDHSA: return "amdhsa";
case PS4: return "ps4";
case ELFIAMCU: return "elfiamcu";
+ case TvOS: return "tvos";
+ case WatchOS: return "watchos";
}
llvm_unreachable("Invalid OSType");
.StartsWith("amdhsa", Triple::AMDHSA)
.StartsWith("ps4", Triple::PS4)
.StartsWith("elfiamcu", Triple::ELFIAMCU)
+ .StartsWith("tvos", Triple::TvOS)
+ .StartsWith("watchos", Triple::WatchOS)
.Default(Triple::UnknownOS);
}
case ARM::AK_ARMV7L:
case ARM::AK_ARMV7HL:
return Triple::ARMSubArch_v7;
+ case ARM::AK_ARMV7K:
+ return Triple::ARMSubArch_v7k;
case ARM::AK_ARMV7M:
return Triple::ARMSubArch_v7m;
case ARM::AK_ARMV7S:
return false;
break;
case IOS:
+ case TvOS:
+ case WatchOS:
// Ignore the version from the triple. This is only handled because the
// the clang driver combines OS X and IOS support into a common Darwin
// toolchain that wants to know the OS X version number even when targeting
default: llvm_unreachable("unexpected OS for Darwin triple");
case Darwin:
case MacOSX:
+ case WatchOS:
// Ignore the version from the triple. This is only handled because the
// the clang driver combines OS X and IOS support into a common Darwin
// toolchain that wants to know the iOS version number even when targeting
Micro = 0;
break;
case IOS:
+ case TvOS:
getOSVersion(Major, Minor, Micro);
// Default to 5.0 (or 7.0 for arm64).
if (Major == 0)
// Use CPU to figure out the exact features.
ARMArchFeature = "+v7";
break;
- case Triple::ARMSubArch_v7:
+ case Triple::ARMSubArch_v7k:
+ if (NoCPU)
+ // v7k: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS
+ // A7
+ ARMArchFeature = "+v7,+a7,+neon,+db,+t2dsp,+ras";
+ else
+ // Use CPU to figure out the exact features.
+ ARMArchFeature = "+v7";
+ break; case Triple::ARMSubArch_v7:
// v7 CPUs have lots of different feature sets. If no CPU is specified,
// then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
// the "minimum" feature set and use CPU string to figure out the exact
--- /dev/null
+// RUN: llvm-mc -triple armv7-apple-tvos %s -filetype=obj -o - | llvm-readobj --macho-version-min | FileCheck %s
+
+
+// Test the formation of the version-min load command in the MachO.
+// use a nonsense but well formed version.
+.tvos_version_min 99,8,7
+
+// CHECK: MinVersion {
+// CHECK-NEXT: Cmd: LC_VERSION_MIN_TVOS
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Version: 99.8.7
+// CHECK-NEXT: SDK: n/a
+// CHECK-NEXT: }
.macosx_version_min 10,-1,1
.macosx_version_min 0,1,1
.macosx_version_min 70000,1
+.tvos_version_min 99,2,257
+.tvos_version_min 50,256,1
+.tvos_version_min 10,-1,1
+.tvos_version_min 0,1,1
+.tvos_version_min 70000,1
+.watchos_version_min 99,2,257
+.watchos_version_min 50,256,1
+.watchos_version_min 10,-1,1
+.watchos_version_min 0,1,1
+.watchos_version_min 70000,1
// CHECK: error: invalid OS update number
// CHECK: error: invalid OS major version number
// CHECK: .macosx_version_min 70000,1
// CHECK: ^
+// CHECK: error: invalid OS update number
+// CHECK: .tvos_version_min 99,2,257
+// CHECK: ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .tvos_version_min 50,256,1
+// CHECK: ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .tvos_version_min 10,-1,1
+// CHECK: ^
+// CHECK: error: invalid OS major version number
+// CHECK: .tvos_version_min 0,1,1
+// CHECK: ^
+// CHECK: error: invalid OS major version number
+// CHECK: .tvos_version_min 70000,1
+// CHECK: ^
+// CHECK: error: invalid OS update number
+// CHECK: .watchos_version_min 99,2,257
+// CHECK: ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .watchos_version_min 50,256,1
+// CHECK: ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .watchos_version_min 10,-1,1
+// CHECK: ^
+// CHECK: error: invalid OS major version number
+// CHECK: .watchos_version_min 0,1,1
+// CHECK: ^
+// CHECK: error: invalid OS major version number
+// CHECK: .watchos_version_min 70000,1
+// CHECK: ^
--- /dev/null
+// RUN: llvm-mc -triple i386-apple-ios %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=IOS
+// RUN: llvm-mc -triple i386-apple-watchos %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=WATCHOS
+// RUN: llvm-mc -triple i386-apple-tvos %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=TVOS
+// RUN: llvm-mc -triple i386-apple-macosx %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MACOSX
+
+.ios_version_min 1,2,3
+// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .ios_version_min should only be used for ios targets
+// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .ios_version_min should only be used for ios targets
+// MACOSX: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .ios_version_min should only be used for ios targets
+// IOS-NOT: warning: .ios_version_min should only be used for ios targets
+
+.macosx_version_min 4,5,6
+// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .macosx_version_min should only be used for macosx targets
+// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .macosx_version_min should only be used for macosx targets
+// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .macosx_version_min should only be used for macosx targets
+// MACOSX-NOT: warning: .macosx_version_min should only be used for macosx targets
+// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
+// CHECK: version-min-diagnostics2.s:[[@LINE-12]]:1: note: previous definition is here
+
+.tvos_version_min 7,8,9
+// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .tvos_version_min should only be used for tvos targets
+// MACOSX: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .tvos_version_min should only be used for tvos targets
+// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .tvos_version_min should only be used for tvos targets
+// TVOS-NOT: warning: .tvos_version_min should only be used for tvos targets
+// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
+// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here
+
+.watchos_version_min 10,11,12
+// MACOSX: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .watchos_version_min should only be used for watchos targets
+// IOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .watchos_version_min should only be used for watchos targets
+// TVOS-NOT: warning: .tvos_version_min should only be used for tvos targets
+// WATCHOS-NOT: warning: .watchos_version_min should only be used for watchos targets
+// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
+// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here
// CHECK: .macosx_version_min 10, 2
// CHECK: .macosx_version_min 10, 8, 1
// CHECK: .macosx_version_min 2, 0
+
+.tvos_version_min 5,2,0
+.tvos_version_min 3,2,1
+.tvos_version_min 5,0
+
+// CHECK: .tvos_version_min 5, 2
+// CHECK: .tvos_version_min 3, 2, 1
+// CHECK: .tvos_version_min 5, 0
+
+.watchos_version_min 5,2,0
+.watchos_version_min 3,2,1
+.watchos_version_min 5,0
+
+// CHECK: .watchos_version_min 5, 2
+// CHECK: .watchos_version_min 3, 2, 1
+// CHECK: .watchos_version_min 5, 0
// RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s --check-prefix=CHECK-DARWIN
// Test version-min load command should be inferred from triple and should always be generated on Darwin
-// CHECK: cmd LC_VERSION_MIN_MACOSX
-// CHECK-NEXT: cmdsize 16
-// CHECK-NEXT: version 10.10
+// CHECK: Load command
+// CHECK: cmd LC_VERSION_MIN_MACOSX
+// CHECK: cmdsize 16
+// CHECK: version 10.10
-// CHECK-IOS: cmd LC_VERSION_MIN_IPHONEOS
-// CHECK-IOS-NEXT: cmdsize 16
-// CHECK-IOS-NEXT: version 8.0
+// CHECK-IOS: Load command
+// CHECK-IOS: cmd LC_VERSION_MIN_IPHONEOS
+// CHECK-IOS: cmdsize 16
+// CHECK-IOS: version 8.0
// CHECK-DARWIN-NOT: LC_VERSION_MIN
+
+
+// FIXME: llvm-objdump doesn't know about WATCHOS LC yet
+// FIXME: llvm-mc -triple x86_64-apple-watchos1.0.0 %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s --check-prefix=CHECK-WATCHOS
+// CHECK-WATCHOS: Load command
+// CHECK-WATCHOS: cmd LC_VERSION_MIN_WATCHOS
+// CHECK-WATCHOS: cmdsize 16
+// CHECK-WATCHOS: version 1.0
void MachODumper::printMachOVersionMin() {
for (const auto &Load : Obj->load_commands()) {
- if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
- Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
- MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
- DictScope Group(W, "MinVersion");
- StringRef Cmd;
- if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX)
- Cmd = "LC_VERSION_MIN_MACOSX";
- else
- Cmd = "LC_VERSION_MIN_IPHONEOS";
- W.printString("Cmd", Cmd);
- W.printNumber("Size", VMC.cmdsize);
- SmallString<32> Version;
- Version = utostr(MachOObjectFile::getVersionMinMajor(VMC, false)) + "." +
- utostr(MachOObjectFile::getVersionMinMinor(VMC, false));
- uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, false);
+ StringRef Cmd;
+ switch (Load.C.cmd) {
+ case MachO::LC_VERSION_MIN_MACOSX:
+ Cmd = "LC_VERSION_MIN_MACOSX";
+ break;
+ case MachO::LC_VERSION_MIN_IPHONEOS:
+ Cmd = "LC_VERSION_MIN_IPHONEOS";
+ break;
+ case MachO::LC_VERSION_MIN_TVOS:
+ Cmd = "LC_VERSION_MIN_TVOS";
+ break;
+ case MachO::LC_VERSION_MIN_WATCHOS:
+ Cmd = "LC_VERSION_MIN_WATCHOS";
+ break;
+ default:
+ continue;
+ }
+
+ MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
+ DictScope Group(W, "MinVersion");
+ W.printString("Cmd", Cmd);
+ W.printNumber("Size", VMC.cmdsize);
+ SmallString<32> Version;
+ Version = utostr(MachOObjectFile::getVersionMinMajor(VMC, false)) + "." +
+ utostr(MachOObjectFile::getVersionMinMinor(VMC, false));
+ uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, false);
+ if (Update != 0)
+ Version += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, false));
+ W.printString("Version", Version);
+ SmallString<32> SDK;
+ if (VMC.sdk == 0)
+ SDK = "n/a";
+ else {
+ SDK = utostr(MachOObjectFile::getVersionMinMajor(VMC, true)) + "." +
+ utostr(MachOObjectFile::getVersionMinMinor(VMC, true));
+ uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, true);
if (Update != 0)
- Version += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC,
- false));
- W.printString("Version", Version);
- SmallString<32> SDK;
- if (VMC.sdk == 0)
- SDK = "n/a";
- else {
- SDK = utostr(MachOObjectFile::getVersionMinMajor(VMC, true)) + "." +
- utostr(MachOObjectFile::getVersionMinMinor(VMC, true));
- uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, true);
- if (Update != 0)
- SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC,
- true));
- }
- W.printString("SDK", SDK);
+ SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, true));
}
+ W.printString("SDK", SDK);
}
}