mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Windows: Added Windows ARM support to JUCE
This commit is contained in:
parent
5f48ca7269
commit
2d42b9a44f
8 changed files with 189 additions and 93 deletions
|
|
@ -171,7 +171,7 @@ public:
|
||||||
multiProcessorCompilationValue (config, Ids::multiProcessorCompilation, getUndoManager(), true),
|
multiProcessorCompilationValue (config, Ids::multiProcessorCompilation, getUndoManager(), true),
|
||||||
intermediatesPathValue (config, Ids::intermediatesPath, getUndoManager()),
|
intermediatesPathValue (config, Ids::intermediatesPath, getUndoManager()),
|
||||||
characterSetValue (config, Ids::characterSet, getUndoManager()),
|
characterSetValue (config, Ids::characterSet, getUndoManager()),
|
||||||
architectureTypeValue (config, Ids::winArchitecture, getUndoManager(), get64BitArchName()),
|
architectureTypeValue (config, Ids::winArchitecture, getUndoManager(), getIntel64BitArchName()),
|
||||||
fastMathValue (config, Ids::fastMath, getUndoManager()),
|
fastMathValue (config, Ids::fastMath, getUndoManager()),
|
||||||
debugInformationFormatValue (config, Ids::debugInformationFormat, getUndoManager(), isDebug() ? "ProgramDatabase" : "None"),
|
debugInformationFormatValue (config, Ids::debugInformationFormat, getUndoManager(), isDebug() ? "ProgramDatabase" : "None"),
|
||||||
pluginBinaryCopyStepValue (config, Ids::enablePluginBinaryCopyStep, getUndoManager(), false),
|
pluginBinaryCopyStepValue (config, Ids::enablePluginBinaryCopyStep, getUndoManager(), false),
|
||||||
|
|
@ -201,8 +201,10 @@ public:
|
||||||
String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); }
|
String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); }
|
||||||
String getIntermediatesPathString() const { return intermediatesPathValue.get(); }
|
String getIntermediatesPathString() const { return intermediatesPathValue.get(); }
|
||||||
String getCharacterSetString() const { return characterSetValue.get(); }
|
String getCharacterSetString() const { return characterSetValue.get(); }
|
||||||
String get64BitArchName() const { return "x64"; }
|
String getIntel64BitArchName() const { return "x64"; }
|
||||||
String get32BitArchName() const { return "Win32"; }
|
String getIntel32BitArchName() const { return "Win32"; }
|
||||||
|
String getArm64BitArchName() const { return "ARM64"; }
|
||||||
|
String getArm32BitArchName() const { return "ARM"; }
|
||||||
String getArchitectureString() const { return architectureTypeValue.get(); }
|
String getArchitectureString() const { return architectureTypeValue.get(); }
|
||||||
String getDebugInformationFormatString() const { return debugInformationFormatValue.get(); }
|
String getDebugInformationFormatString() const { return debugInformationFormatValue.get(); }
|
||||||
|
|
||||||
|
|
@ -211,14 +213,13 @@ public:
|
||||||
bool shouldLinkIncremental() const { return enableIncrementalLinkingValue.get(); }
|
bool shouldLinkIncremental() const { return enableIncrementalLinkingValue.get(); }
|
||||||
bool isUsingRuntimeLibDLL() const { return useRuntimeLibDLLValue.get(); }
|
bool isUsingRuntimeLibDLL() const { return useRuntimeLibDLLValue.get(); }
|
||||||
bool shouldUseMultiProcessorCompilation() const { return multiProcessorCompilationValue.get(); }
|
bool shouldUseMultiProcessorCompilation() const { return multiProcessorCompilationValue.get(); }
|
||||||
bool is64Bit() const { return getArchitectureString() == get64BitArchName(); }
|
|
||||||
bool isFastMathEnabled() const { return fastMathValue.get(); }
|
bool isFastMathEnabled() const { return fastMathValue.get(); }
|
||||||
bool isPluginBinaryCopyStepEnabled() const { return pluginBinaryCopyStepValue.get(); }
|
bool isPluginBinaryCopyStepEnabled() const { return pluginBinaryCopyStepValue.get(); }
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
String createMSVCConfigName() const
|
String createMSVCConfigName() const
|
||||||
{
|
{
|
||||||
return getName() + "|" + (is64Bit() ? "x64" : "Win32");
|
return getName() + "|" + getArchitectureString();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getOutputFilename (const String& suffix,
|
String getOutputFilename (const String& suffix,
|
||||||
|
|
@ -245,10 +246,9 @@ public:
|
||||||
addVisualStudioPluginInstallPathProperties (props);
|
addVisualStudioPluginInstallPathProperties (props);
|
||||||
|
|
||||||
props.add (new ChoicePropertyComponent (architectureTypeValue, "Architecture",
|
props.add (new ChoicePropertyComponent (architectureTypeValue, "Architecture",
|
||||||
{ get32BitArchName(), get64BitArchName() },
|
{ getIntel32BitArchName(), getIntel64BitArchName(), getArm32BitArchName(), getArm64BitArchName() },
|
||||||
{ get32BitArchName(), get64BitArchName() }),
|
{ getIntel32BitArchName(), getIntel64BitArchName(), getArm32BitArchName(), getArm64BitArchName() }),
|
||||||
"Whether to use a 32-bit or 64-bit architecture.");
|
"Which Windows architecture to use.");
|
||||||
|
|
||||||
|
|
||||||
props.add (new ChoicePropertyComponentWithEnablement (debugInformationFormatValue,
|
props.add (new ChoicePropertyComponentWithEnablement (debugInformationFormatValue,
|
||||||
isDebug() ? isDebugValue : generateDebugSymbolsValue,
|
isDebug() ? isDebugValue : generateDebugSymbolsValue,
|
||||||
|
|
@ -384,13 +384,26 @@ public:
|
||||||
|
|
||||||
void setPluginBinaryCopyLocationDefaults()
|
void setPluginBinaryCopyLocationDefaults()
|
||||||
{
|
{
|
||||||
vstBinaryLocation.setDefault ((is64Bit() ? "%ProgramW6432%" : "%programfiles(x86)%") + String ("\\Steinberg\\Vstplugins"));
|
const auto [programsFolderPath, commonsFolderPath] = [&]() -> std::tuple<String, String>
|
||||||
|
{
|
||||||
|
static const std::map<String, std::tuple<String, String>> options
|
||||||
|
{
|
||||||
|
{ "Win32", { "%programfiles(x86)%", "%CommonProgramFiles(x86)%" } },
|
||||||
|
{ "x64", { "%ProgramW6432%", "%CommonProgramW6432%" } },
|
||||||
|
{ "ARM", { "%programfiles(arm)%", "%CommonProgramFiles(arm)%" } },
|
||||||
|
{ "ARM64", { "%ProgramW6432%", "%CommonProgramW6432%" } }
|
||||||
|
};
|
||||||
|
|
||||||
auto prefix = is64Bit() ? "%CommonProgramW6432%"
|
if (const auto iter = options.find (getArchitectureString()); iter != options.cend())
|
||||||
: "%CommonProgramFiles(x86)%";
|
return iter->second;
|
||||||
|
|
||||||
vst3BinaryLocation.setDefault (prefix + String ("\\VST3"));
|
jassertfalse;
|
||||||
aaxBinaryLocation.setDefault (prefix + String ("\\Avid\\Audio\\Plug-Ins"));
|
return { "%programfiles%", "%CommonProgramFiles%" };
|
||||||
|
}();
|
||||||
|
|
||||||
|
vstBinaryLocation.setDefault (programsFolderPath + String ("\\Steinberg\\Vstplugins"));
|
||||||
|
vst3BinaryLocation.setDefault (commonsFolderPath + String ("\\VST3"));
|
||||||
|
aaxBinaryLocation.setDefault (commonsFolderPath + String ("\\Avid\\Audio\\Plug-Ins"));
|
||||||
lv2BinaryLocation.setDefault ("%APPDATA%\\LV2");
|
lv2BinaryLocation.setDefault ("%APPDATA%\\LV2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,8 +447,7 @@ public:
|
||||||
auto* e = configsGroup->createNewChildElement ("ProjectConfiguration");
|
auto* e = configsGroup->createNewChildElement ("ProjectConfiguration");
|
||||||
e->setAttribute ("Include", config.createMSVCConfigName());
|
e->setAttribute ("Include", config.createMSVCConfigName());
|
||||||
e->createNewChildElement ("Configuration")->addTextElement (config.getName());
|
e->createNewChildElement ("Configuration")->addTextElement (config.getName());
|
||||||
e->createNewChildElement ("Platform")->addTextElement (config.is64Bit() ? config.get64BitArchName()
|
e->createNewChildElement ("Platform")->addTextElement (config.getArchitectureString());
|
||||||
: config.get32BitArchName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -662,7 +674,7 @@ public:
|
||||||
link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (pdbFilename);
|
link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (pdbFilename);
|
||||||
link->createNewChildElement ("SubSystem")->addTextElement (type == ConsoleApp || type == LV2TurtleProgram ? "Console" : "Windows");
|
link->createNewChildElement ("SubSystem")->addTextElement (type == ConsoleApp || type == LV2TurtleProgram ? "Console" : "Windows");
|
||||||
|
|
||||||
if (! config.is64Bit())
|
if (config.getArchitectureString() == "Win32")
|
||||||
link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86");
|
link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86");
|
||||||
|
|
||||||
if (isUsingEditAndContinue)
|
if (isUsingEditAndContinue)
|
||||||
|
|
@ -727,7 +739,7 @@ public:
|
||||||
build_tools::RelativePath::buildTargetFolder).toWindowsStyle());
|
build_tools::RelativePath::buildTargetFolder).toWindowsStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getTargetFileType() == staticLibrary && ! config.is64Bit())
|
if (getTargetFileType() == staticLibrary && config.getArchitectureString() == "Win32")
|
||||||
{
|
{
|
||||||
auto* lib = group->createNewChildElement ("Lib");
|
auto* lib = group->createNewChildElement ("Lib");
|
||||||
lib->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86");
|
lib->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86");
|
||||||
|
|
@ -1207,7 +1219,7 @@ public:
|
||||||
auto outputFilename = config.getOutputFilename (".aaxplugin", true, type);
|
auto outputFilename = config.getOutputFilename (".aaxplugin", true, type);
|
||||||
auto bundleDir = getOwner().getOutDirFile (config, outputFilename);
|
auto bundleDir = getOwner().getOutDirFile (config, outputFilename);
|
||||||
auto bundleContents = bundleDir + "\\Contents";
|
auto bundleContents = bundleDir + "\\Contents";
|
||||||
auto archDir = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32");
|
auto archDir = bundleContents + String ("\\") + config.getArchitectureString();
|
||||||
auto executablePath = archDir + String ("\\") + outputFilename;
|
auto executablePath = archDir + String ("\\") + outputFilename;
|
||||||
|
|
||||||
auto pkgScript = String ("copy /Y ") + getOutputFilePath (config).quoted() + String (" ") + executablePath.quoted() + String ("\r\ncall ")
|
auto pkgScript = String ("copy /Y ") + getOutputFilePath (config).quoted() + String (" ") + executablePath.quoted() + String ("\r\ncall ")
|
||||||
|
|
@ -1285,7 +1297,7 @@ public:
|
||||||
|
|
||||||
auto bundleDir = getOwner().getOutDirFile (config, config.getOutputFilename (".aaxplugin", false, type));
|
auto bundleDir = getOwner().getOutDirFile (config, config.getOutputFilename (".aaxplugin", false, type));
|
||||||
auto bundleContents = bundleDir + "\\Contents";
|
auto bundleContents = bundleDir + "\\Contents";
|
||||||
auto archDir = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32");
|
auto archDir = bundleContents + String ("\\") + config.getArchitectureString();
|
||||||
|
|
||||||
for (auto& folder : StringArray { bundleDir, bundleContents, archDir })
|
for (auto& folder : StringArray { bundleDir, bundleContents, archDir })
|
||||||
script += String ("if not exist \"") + folder + String ("\" mkdir \"") + folder + String ("\"\r\n");
|
script += String ("if not exist \"") + folder + String ("\" mkdir \"") + folder + String ("\"\r\n");
|
||||||
|
|
|
||||||
|
|
@ -1430,34 +1430,44 @@ void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, cons
|
||||||
intptr_t JUCE_CALLTYPE FloatVectorOperations::getFpStatusRegister() noexcept
|
intptr_t JUCE_CALLTYPE FloatVectorOperations::getFpStatusRegister() noexcept
|
||||||
{
|
{
|
||||||
intptr_t fpsr = 0;
|
intptr_t fpsr = 0;
|
||||||
#if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS
|
#if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS
|
||||||
fpsr = static_cast<intptr_t> (_mm_getcsr());
|
fpsr = static_cast<intptr_t> (_mm_getcsr());
|
||||||
#elif defined(__arm64__) || defined(__aarch64__) || JUCE_USE_ARM_NEON
|
#elif (JUCE_64BIT && JUCE_ARM) || JUCE_USE_ARM_NEON
|
||||||
#if defined(__arm64__) || defined(__aarch64__)
|
#if _MSC_VER
|
||||||
|
// _control87 returns static values for x86 bits that don't exist on arm
|
||||||
|
// to emulate x86 behaviour. We are only ever interested in de-normal bits
|
||||||
|
// so mask out only those.
|
||||||
|
fpsr = (intptr_t) (_control87 (0, 0) & _MCW_DN);
|
||||||
|
#else
|
||||||
|
#if JUCE_64BIT
|
||||||
asm volatile("mrs %0, fpcr"
|
asm volatile("mrs %0, fpcr"
|
||||||
: "=r"(fpsr));
|
: "=r"(fpsr));
|
||||||
#elif JUCE_USE_ARM_NEON
|
#elif JUCE_USE_ARM_NEON
|
||||||
asm volatile("vmrs %0, fpscr"
|
asm volatile("vmrs %0, fpscr"
|
||||||
: "=r"(fpsr));
|
: "=r"(fpsr));
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
#if ! (defined(JUCE_INTEL) || defined(JUCE_ARM))
|
|
||||||
jassertfalse; // No support for getting the floating point status register for your platform
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
|
||||||
|
jassertfalse; // No support for getting the floating point status register for your platform
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
return fpsr;
|
return fpsr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JUCE_CALLTYPE FloatVectorOperations::setFpStatusRegister (intptr_t fpsr) noexcept
|
void JUCE_CALLTYPE FloatVectorOperations::setFpStatusRegister (intptr_t fpsr) noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS
|
#if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS
|
||||||
// the volatile keyword here is needed to workaround a bug in AppleClang 13.0
|
// the volatile keyword here is needed to workaround a bug in AppleClang 13.0
|
||||||
// which aggressively optimises away the variable otherwise
|
// which aggressively optimises away the variable otherwise
|
||||||
volatile auto fpsr_w = static_cast<uint32_t> (fpsr);
|
volatile auto fpsr_w = static_cast<uint32_t> (fpsr);
|
||||||
_mm_setcsr (fpsr_w);
|
_mm_setcsr (fpsr_w);
|
||||||
#elif defined(__arm64__) || defined(__aarch64__) || JUCE_USE_ARM_NEON
|
#elif (JUCE_64BIT && JUCE_ARM) || JUCE_USE_ARM_NEON
|
||||||
#if defined(__arm64__) || defined(__aarch64__)
|
#if _MSC_VER
|
||||||
|
_control87 ((unsigned int) fpsr, _MCW_DN);
|
||||||
|
#else
|
||||||
|
#if JUCE_64BIT
|
||||||
asm volatile("msr fpcr, %0"
|
asm volatile("msr fpcr, %0"
|
||||||
:
|
:
|
||||||
: "ri"(fpsr));
|
: "ri"(fpsr));
|
||||||
|
|
@ -1466,17 +1476,18 @@ void JUCE_CALLTYPE FloatVectorOperations::setFpStatusRegister (intptr_t fpsr) no
|
||||||
:
|
:
|
||||||
: "ri"(fpsr));
|
: "ri"(fpsr));
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
#if ! (defined(JUCE_INTEL) || defined(JUCE_ARM))
|
|
||||||
jassertfalse; // No support for getting the floating point status register for your platform
|
|
||||||
#endif
|
|
||||||
ignoreUnused (fpsr);
|
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
|
||||||
|
jassertfalse; // No support for getting the floating point status register for your platform
|
||||||
|
#endif
|
||||||
|
ignoreUnused (fpsr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept
|
void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__))
|
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || (JUCE_64BIT && JUCE_ARM))
|
||||||
#if JUCE_USE_SSE_INTRINSICS
|
#if JUCE_USE_SSE_INTRINSICS
|
||||||
intptr_t mask = _MM_FLUSH_ZERO_MASK;
|
intptr_t mask = _MM_FLUSH_ZERO_MASK;
|
||||||
#else /*JUCE_USE_ARM_NEON*/
|
#else /*JUCE_USE_ARM_NEON*/
|
||||||
|
|
@ -1484,7 +1495,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab
|
||||||
#endif
|
#endif
|
||||||
setFpStatusRegister ((getFpStatusRegister() & (~mask)) | (shouldEnable ? mask : 0));
|
setFpStatusRegister ((getFpStatusRegister() & (~mask)) | (shouldEnable ? mask : 0));
|
||||||
#else
|
#else
|
||||||
#if ! (defined(JUCE_INTEL) || defined(JUCE_ARM))
|
#if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
|
||||||
jassertfalse; // No support for flush to zero mode on your platform
|
jassertfalse; // No support for flush to zero mode on your platform
|
||||||
#endif
|
#endif
|
||||||
ignoreUnused (shouldEnable);
|
ignoreUnused (shouldEnable);
|
||||||
|
|
@ -1493,7 +1504,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab
|
||||||
|
|
||||||
void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool shouldDisable) noexcept
|
void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool shouldDisable) noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__))
|
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || (JUCE_64BIT && JUCE_ARM))
|
||||||
#if JUCE_USE_SSE_INTRINSICS
|
#if JUCE_USE_SSE_INTRINSICS
|
||||||
intptr_t mask = 0x8040;
|
intptr_t mask = 0x8040;
|
||||||
#else /*JUCE_USE_ARM_NEON*/
|
#else /*JUCE_USE_ARM_NEON*/
|
||||||
|
|
@ -1504,7 +1515,7 @@ void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool
|
||||||
#else
|
#else
|
||||||
ignoreUnused (shouldDisable);
|
ignoreUnused (shouldDisable);
|
||||||
|
|
||||||
#if ! (defined(JUCE_INTEL) || defined(JUCE_ARM))
|
#if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
|
||||||
jassertfalse; // No support for disable denormals mode on your platform
|
jassertfalse; // No support for disable denormals mode on your platform
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1512,7 +1523,7 @@ void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool
|
||||||
|
|
||||||
bool JUCE_CALLTYPE FloatVectorOperations::areDenormalsDisabled() noexcept
|
bool JUCE_CALLTYPE FloatVectorOperations::areDenormalsDisabled() noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__))
|
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || (JUCE_64BIT && JUCE_ARM))
|
||||||
#if JUCE_USE_SSE_INTRINSICS
|
#if JUCE_USE_SSE_INTRINSICS
|
||||||
intptr_t mask = 0x8040;
|
intptr_t mask = 0x8040;
|
||||||
#else /*JUCE_USE_ARM_NEON*/
|
#else /*JUCE_USE_ARM_NEON*/
|
||||||
|
|
@ -1527,7 +1538,7 @@ bool JUCE_CALLTYPE FloatVectorOperations::areDenormalsDisabled() noexcept
|
||||||
|
|
||||||
ScopedNoDenormals::ScopedNoDenormals() noexcept
|
ScopedNoDenormals::ScopedNoDenormals() noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__))
|
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || (JUCE_64BIT && JUCE_ARM))
|
||||||
#if JUCE_USE_SSE_INTRINSICS
|
#if JUCE_USE_SSE_INTRINSICS
|
||||||
intptr_t mask = 0x8040;
|
intptr_t mask = 0x8040;
|
||||||
#else /*JUCE_USE_ARM_NEON*/
|
#else /*JUCE_USE_ARM_NEON*/
|
||||||
|
|
@ -1541,7 +1552,7 @@ ScopedNoDenormals::ScopedNoDenormals() noexcept
|
||||||
|
|
||||||
ScopedNoDenormals::~ScopedNoDenormals() noexcept
|
ScopedNoDenormals::~ScopedNoDenormals() noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__))
|
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || (JUCE_64BIT && JUCE_ARM))
|
||||||
FloatVectorOperations::setFpStatusRegister (fpsr);
|
FloatVectorOperations::setFpStatusRegister (fpsr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ public:
|
||||||
~ScopedNoDenormals() noexcept;
|
~ScopedNoDenormals() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
|
#if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || (JUCE_64BIT && JUCE_ARM))
|
||||||
intptr_t fpsr;
|
intptr_t fpsr;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
|
||||||
|
|
||||||
/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
|
/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
|
||||||
* 64 bit compiler and doesn't work on arm. */
|
* 64 bit compiler and doesn't work on arm. */
|
||||||
#if defined(_MSC_VER) && defined(_M_IX86) && !defined(_WIN32_WCE)
|
#if (defined(_MSC_VER) && defined(_M_IX86) && !defined(_WIN32_WCE)) && (! JUCE_ARM)
|
||||||
# define VORBIS_FPU_CONTROL
|
# define VORBIS_FPU_CONTROL
|
||||||
|
|
||||||
typedef ogg_int16_t vorbis_fpu_control;
|
typedef ogg_int16_t vorbis_fpu_control;
|
||||||
|
|
@ -146,7 +146,7 @@ static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
|
||||||
|
|
||||||
/* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
|
/* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
|
||||||
done safely because all x86_64 CPUs supports SSE2. */
|
done safely because all x86_64 CPUs supports SSE2. */
|
||||||
#if ((JUCE_MSVC && JUCE_64BIT) || (JUCE_GCC && defined (__x86_64__)))
|
#if (((JUCE_MSVC && JUCE_64BIT) || (JUCE_GCC && defined (__x86_64__)))) && (! JUCE_ARM)
|
||||||
# define VORBIS_FPU_CONTROL
|
# define VORBIS_FPU_CONTROL
|
||||||
|
|
||||||
typedef ogg_int16_t vorbis_fpu_control;
|
typedef ogg_int16_t vorbis_fpu_control;
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,6 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
#if JUCE_MSVC && ! defined (__INTEL_COMPILER)
|
|
||||||
#pragma intrinsic (__cpuid)
|
|
||||||
#pragma intrinsic (__rdtsc)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Logger::outputDebugString (const String& text)
|
void Logger::outputDebugString (const String& text)
|
||||||
{
|
{
|
||||||
OutputDebugString ((text + "\n").toWideCharPointer());
|
OutputDebugString ((text + "\n").toWideCharPointer());
|
||||||
|
|
@ -39,9 +34,50 @@ void Logger::outputDebugString (const String& text)
|
||||||
JUCE_API void juceDLL_free (void* block) { std::free (block); }
|
JUCE_API void juceDLL_free (void* block) { std::free (block); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
static int findNumberOfPhysicalCores() noexcept
|
||||||
|
{
|
||||||
|
#if JUCE_MINGW
|
||||||
|
// Not implemented in MinGW
|
||||||
|
jassertfalse;
|
||||||
|
|
||||||
#if JUCE_MINGW || JUCE_CLANG
|
return 1;
|
||||||
|
#else
|
||||||
|
|
||||||
|
DWORD bufferSize = 0;
|
||||||
|
GetLogicalProcessorInformation (nullptr, &bufferSize);
|
||||||
|
|
||||||
|
const auto numBuffers = (size_t) (bufferSize / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
|
||||||
|
|
||||||
|
if (numBuffers == 0)
|
||||||
|
{
|
||||||
|
jassertfalse;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
HeapBlock<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer (numBuffers);
|
||||||
|
|
||||||
|
if (! GetLogicalProcessorInformation (buffer, &bufferSize))
|
||||||
|
{
|
||||||
|
jassertfalse;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) std::count_if (buffer.get(), buffer.get() + numBuffers, [] (const auto& info)
|
||||||
|
{
|
||||||
|
return info.Relationship == RelationProcessorCore;
|
||||||
|
});
|
||||||
|
|
||||||
|
#endif // JUCE_MINGW
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
#if JUCE_INTEL
|
||||||
|
#if JUCE_MSVC && ! defined (__INTEL_COMPILER)
|
||||||
|
#pragma intrinsic (__cpuid)
|
||||||
|
#pragma intrinsic (__rdtsc)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if JUCE_MINGW || JUCE_CLANG
|
||||||
static void callCPUID (int result[4], uint32 type)
|
static void callCPUID (int result[4], uint32 type)
|
||||||
{
|
{
|
||||||
uint32 la = (uint32) result[0], lb = (uint32) result[1],
|
uint32 la = (uint32) result[0], lb = (uint32) result[1],
|
||||||
|
|
@ -59,12 +95,12 @@ static void callCPUID (int result[4], uint32 type)
|
||||||
result[0] = (int) la; result[1] = (int) lb;
|
result[0] = (int) la; result[1] = (int) lb;
|
||||||
result[2] = (int) lc; result[3] = (int) ld;
|
result[2] = (int) lc; result[3] = (int) ld;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void callCPUID (int result[4], int infoType)
|
static void callCPUID (int result[4], int infoType)
|
||||||
{
|
{
|
||||||
__cpuid (result, infoType);
|
__cpuid (result, infoType);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String SystemStats::getCpuVendor()
|
String SystemStats::getCpuVendor()
|
||||||
{
|
{
|
||||||
|
|
@ -103,34 +139,6 @@ String SystemStats::getCpuModel()
|
||||||
return String (name).trim();
|
return String (name).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findNumberOfPhysicalCores() noexcept
|
|
||||||
{
|
|
||||||
#if JUCE_MINGW
|
|
||||||
// Not implemented in MinGW
|
|
||||||
jassertfalse;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
|
|
||||||
int numPhysicalCores = 0;
|
|
||||||
DWORD bufferSize = 0;
|
|
||||||
GetLogicalProcessorInformation (nullptr, &bufferSize);
|
|
||||||
|
|
||||||
if (auto numBuffers = (size_t) (bufferSize / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)))
|
|
||||||
{
|
|
||||||
HeapBlock<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer (numBuffers);
|
|
||||||
|
|
||||||
if (GetLogicalProcessorInformation (buffer, &bufferSize))
|
|
||||||
for (size_t i = 0; i < numBuffers; ++i)
|
|
||||||
if (buffer[i].Relationship == RelationProcessorCore)
|
|
||||||
++numPhysicalCores;
|
|
||||||
}
|
|
||||||
|
|
||||||
return numPhysicalCores;
|
|
||||||
#endif // JUCE_MINGW
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
void CPUInformation::initialise() noexcept
|
void CPUInformation::initialise() noexcept
|
||||||
{
|
{
|
||||||
int info[4] = { 0 };
|
int info[4] = { 0 };
|
||||||
|
|
@ -176,6 +184,49 @@ void CPUInformation::initialise() noexcept
|
||||||
if (numPhysicalCPUs <= 0)
|
if (numPhysicalCPUs <= 0)
|
||||||
numPhysicalCPUs = numLogicalCPUs;
|
numPhysicalCPUs = numLogicalCPUs;
|
||||||
}
|
}
|
||||||
|
#elif JUCE_ARM
|
||||||
|
String SystemStats::getCpuVendor()
|
||||||
|
{
|
||||||
|
static const auto cpuVendor = []
|
||||||
|
{
|
||||||
|
static constexpr auto* path = "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\VendorIdentifier";
|
||||||
|
auto vendor = RegistryKeyWrapper::getValue (path, {}, 0).trim();
|
||||||
|
|
||||||
|
return vendor.isEmpty() ? String ("Unknown Vendor") : vendor;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return cpuVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
String SystemStats::getCpuModel()
|
||||||
|
{
|
||||||
|
static const auto cpuModel = []
|
||||||
|
{
|
||||||
|
static constexpr auto* path = "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\ProcessorNameString";
|
||||||
|
auto model = RegistryKeyWrapper::getValue (path, {}, 0).trim();
|
||||||
|
|
||||||
|
return model.isEmpty() ? String ("Unknown Model") : model;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return cpuModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPUInformation::initialise() noexcept
|
||||||
|
{
|
||||||
|
// Windows for arm requires at least armv7 which has neon support
|
||||||
|
hasNeon = true;
|
||||||
|
|
||||||
|
SYSTEM_INFO systemInfo;
|
||||||
|
GetNativeSystemInfo (&systemInfo);
|
||||||
|
numLogicalCPUs = (int) systemInfo.dwNumberOfProcessors;
|
||||||
|
numPhysicalCPUs = findNumberOfPhysicalCores();
|
||||||
|
|
||||||
|
if (numPhysicalCPUs <= 0)
|
||||||
|
numPhysicalCPUs = numLogicalCPUs;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error Unknown CPU architecture type
|
||||||
|
#endif
|
||||||
|
|
||||||
#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
|
#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
|
||||||
struct DebugFlagsInitialiser
|
struct DebugFlagsInitialiser
|
||||||
|
|
@ -442,11 +493,21 @@ double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHa
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
static int64 juce_getClockCycleCounter() noexcept
|
static int64 juce_getClockCycleCounter() noexcept
|
||||||
{
|
{
|
||||||
#if JUCE_MSVC
|
#if JUCE_MSVC
|
||||||
|
#if JUCE_INTEL
|
||||||
// MS intrinsics version...
|
// MS intrinsics version...
|
||||||
return (int64) __rdtsc();
|
return (int64) __rdtsc();
|
||||||
|
#elif JUCE_ARM
|
||||||
#elif JUCE_GCC || JUCE_CLANG
|
#if defined (_M_ARM)
|
||||||
|
return __rdpmccntr64();
|
||||||
|
#elif defined (_M_ARM64)
|
||||||
|
return _ReadStatusReg (ARM64_PMCCNTR_EL0);
|
||||||
|
#else
|
||||||
|
#error Unknown arm architecture
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#elif JUCE_GCC || JUCE_CLANG
|
||||||
|
#if JUCE_INTEL
|
||||||
// GNU inline asm version...
|
// GNU inline asm version...
|
||||||
unsigned int hi = 0, lo = 0;
|
unsigned int hi = 0, lo = 0;
|
||||||
|
|
||||||
|
|
@ -462,9 +523,15 @@ static int64 juce_getClockCycleCounter() noexcept
|
||||||
: "cc", "eax", "ebx", "ecx", "edx", "memory");
|
: "cc", "eax", "ebx", "ecx", "edx", "memory");
|
||||||
|
|
||||||
return (int64) ((((uint64) hi) << 32) | lo);
|
return (int64) ((((uint64) hi) << 32) | lo);
|
||||||
#else
|
#elif JUCE_ARM
|
||||||
#error "unknown compiler?"
|
int64 retval;
|
||||||
#endif
|
|
||||||
|
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r"(retval));
|
||||||
|
return retval;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "unknown compiler?"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int SystemStats::getCpuSpeedInMegahertz()
|
int SystemStats::getCpuSpeedInMegahertz()
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,11 @@
|
||||||
/** If defined, this indicates that the processor is little-endian. */
|
/** If defined, this indicates that the processor is little-endian. */
|
||||||
#define JUCE_LITTLE_ENDIAN 1
|
#define JUCE_LITTLE_ENDIAN 1
|
||||||
|
|
||||||
#define JUCE_INTEL 1
|
#if defined (_M_ARM) || defined (_M_ARM64) || defined (__arm__) || defined (__aarch64__)
|
||||||
|
#define JUCE_ARM 1
|
||||||
|
#else
|
||||||
|
#define JUCE_INTEL 1
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
|
||||||
|
|
@ -79,13 +79,13 @@
|
||||||
#include "widgets/juce_Chorus.cpp"
|
#include "widgets/juce_Chorus.cpp"
|
||||||
|
|
||||||
#if JUCE_USE_SIMD
|
#if JUCE_USE_SIMD
|
||||||
#if defined(__i386__) || defined(__amd64__) || defined(_M_X64) || defined(_X86_) || defined(_M_IX86)
|
#if JUCE_INTEL
|
||||||
#ifdef __AVX2__
|
#ifdef __AVX2__
|
||||||
#include "native/juce_avx_SIMDNativeOps.cpp"
|
#include "native/juce_avx_SIMDNativeOps.cpp"
|
||||||
#else
|
#else
|
||||||
#include "native/juce_sse_SIMDNativeOps.cpp"
|
#include "native/juce_sse_SIMDNativeOps.cpp"
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__arm__) || defined(_M_ARM) || defined (__arm64__) || defined (__aarch64__)
|
#elif JUCE_ARM
|
||||||
#include "native/juce_neon_SIMDNativeOps.cpp"
|
#include "native/juce_neon_SIMDNativeOps.cpp"
|
||||||
#else
|
#else
|
||||||
#error "SIMD register support not implemented for this platform"
|
#error "SIMD register support not implemented for this platform"
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,9 @@
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined (__ARM_NEON__) || defined (__ARM_NEON) || defined (__arm64__) || defined (__aarch64__)
|
// it's ok to check for _M_ARM below as this is only defined on Windows for Arm 32-bit
|
||||||
|
// which has a minimum requirement of armv7, which supports neon.
|
||||||
|
#elif defined (__ARM_NEON__) || defined (__ARM_NEON) || defined (__arm64__) || defined (__aarch64__) || defined (_M_ARM) || defined (_M_ARM64)
|
||||||
|
|
||||||
#ifndef JUCE_USE_SIMD
|
#ifndef JUCE_USE_SIMD
|
||||||
#define JUCE_USE_SIMD 1
|
#define JUCE_USE_SIMD 1
|
||||||
|
|
@ -227,7 +229,7 @@ namespace juce
|
||||||
#else
|
#else
|
||||||
#include "native/juce_sse_SIMDNativeOps.h"
|
#include "native/juce_sse_SIMDNativeOps.h"
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__arm__) || defined(_M_ARM) || defined (__arm64__) || defined (__aarch64__)
|
#elif JUCE_ARM
|
||||||
#include "native/juce_neon_SIMDNativeOps.h"
|
#include "native/juce_neon_SIMDNativeOps.h"
|
||||||
#else
|
#else
|
||||||
#error "SIMD register support not implemented for this platform"
|
#error "SIMD register support not implemented for this platform"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue