Implement new naming scheme for --target.
Now targets are named like "<isa>-i<mask size>x<gang size>", e.g. "sse4-i8x16", or "avx2-i32x16". The old target names are still supported.
This commit is contained in:
@@ -489,54 +489,72 @@ on which you're running ``ispc`` is used to determine the target CPU.
|
||||
|
||||
ispc foo.ispc -o foo.obj --cpu=corei7-avx
|
||||
|
||||
Finally, ``--target`` selects the target instruction set. The following
|
||||
targets are currently supported:
|
||||
Finally, ``--target`` selects the target instruction set. The target
|
||||
string is of the form ``[ISA]-i[mask size]x[gang size]``. For example,
|
||||
``--target=avx2-i32x16`` specifies a target with the AVX2 instruction set,
|
||||
a mask size of 32 bits, and a gang size of 16.
|
||||
|
||||
=========== ========= =======================================
|
||||
Target Gang Size Description
|
||||
----------- --------- ---------------------------------------
|
||||
avx 8 AVX (2010-2011 era Intel CPUs)
|
||||
avx-x2 16 "Double-pumped" AVX target, running
|
||||
twice as many program instances as the
|
||||
native vector width.
|
||||
avx1.1 8 AVX 1.1 target (2012 era "Ivybridge"
|
||||
Intel CPUs).
|
||||
avx1.1-x2 16 Double-pumped AVX 1.1 target.
|
||||
avx2 8 AVX 2 target (2013- Intel "Haswell"
|
||||
CPUs.)
|
||||
avx2-x2 16 Double-pumped AVX 2 target.
|
||||
neon-8 16 ARM NEON target, targeting computation
|
||||
on 8-bit data types.
|
||||
neon-16 8 ARM NEON target, targeting computation
|
||||
on 16-bit data types.
|
||||
neon-32 4 ARM NEON target, targeting computation
|
||||
on 32-bit data types.
|
||||
sse2 4 SSE2 (early 2000s era x86 CPUs).
|
||||
sse2-x2 8 Double-pumped SSE2.
|
||||
sse4 4 SSE4 (generally 2008-2010 Intel CPUs).
|
||||
sse4-x2 8 Double-pumped SSE4.
|
||||
sse4-8 16 SSE4 target targeting computation on
|
||||
8-bit data types.
|
||||
sse4-16 8 SSE4 target targeting computation on
|
||||
16-bit data types.
|
||||
=========== ========= =======================================
|
||||
The following target ISAs are supported:
|
||||
|
||||
============ ==========================================
|
||||
Target Description
|
||||
------------ ------------------------------------------
|
||||
avx, avx1 AVX (2010-2011 era Intel CPUs)
|
||||
avx1.1 AVX 1.1 (2012 era "Ivybridge" Intel CPUs)
|
||||
avx2 AVX 2 target (2013- Intel "Haswell" CPUs)
|
||||
neon ARM NEON
|
||||
sse2 SSE2 (early 2000s era x86 CPUs)
|
||||
sse4 SSE4 (generally 2008-2010 Intel CPUs)
|
||||
============ ==========================================
|
||||
|
||||
Consult your CPU's manual for specifics on which vector instruction set it
|
||||
supports.
|
||||
|
||||
The mask size may be 8, 16, or 32 bits, though not all combinations of ISAs
|
||||
and mask sizes are supported. For best performance, the best general
|
||||
approach is to choose a mask size equal to the size of the most common
|
||||
datatype in your programs. For example, if most of your computation is on
|
||||
32-bit floating-point values, an ``i32`` target is appropriate. However,
|
||||
if you're mostly doing computation on 8-bit images, ``i8`` is a better choice.
|
||||
|
||||
See `Basic Concepts: Program Instances and Gangs of Program Instances`_ for
|
||||
more discussion of the "gang size" and its implications for program
|
||||
execution.
|
||||
|
||||
instruction sets. (As general context, SSE2 was first introduced in
|
||||
processors that shipped in 2001, SSE4 was introduced in 2007, and
|
||||
processors with AVX were introduced in 2010, and AVX2 arrived in 2013.
|
||||
Consult your CPU's
|
||||
manual for specifics on which vector instruction set it supports.)
|
||||
Running ``ispc --help`` and looking at the output for the ``--target``
|
||||
option gives the most up-to-date documentation about which targets your
|
||||
compiler binary supports.
|
||||
|
||||
The naming scheme for compilation targets changed in August 2013; the
|
||||
following table shows the relationship between names in the old scheme and
|
||||
in the new scheme:
|
||||
|
||||
============= ===========
|
||||
Target Former Name
|
||||
------------- -----------
|
||||
avx1-i32x8 avx, avx1
|
||||
avx1-i32x16 avx-x2
|
||||
avx1.1-i32x8 avx1.1
|
||||
avx1.1-i32x16 avx1.1-x2
|
||||
avx2-i32x8 avx2
|
||||
avx2-i32x16 avx2-x2
|
||||
neon-8 n/a
|
||||
neon-16 n/a
|
||||
neon-32 n/a
|
||||
sse2-i32x4 sse2
|
||||
sse2-i32x8 sse2-x2
|
||||
sse4-i32x4 sse4
|
||||
sse4-i32x8 sse4-x2
|
||||
sse4-i8x16 n/a
|
||||
sse4-i16x8 n/a
|
||||
============= ===========
|
||||
|
||||
By default, the target instruction set is chosen based on the most capable
|
||||
one supported by the system on which you're running ``ispc``. You can
|
||||
override this choice with the ``--target`` flag; for example, to select
|
||||
Intel® SSE2, use ``--target=sse2``. (As with the other options in this
|
||||
section, see the output of ``ispc --help`` for a full list of supported
|
||||
targets.)
|
||||
Intel® SSE2 with a 32-bit mask and 4 program instances in a gang, use
|
||||
``--target=sse2-i32x4``. (As with the other options in this section, see
|
||||
the output of ``ispc --help`` for a full list of supported targets.)
|
||||
|
||||
Generating Generic C++ Output
|
||||
-----------------------------
|
||||
|
||||
116
ispc.cpp
116
ispc.cpp
@@ -106,7 +106,7 @@ static void __cpuidex(int info[4], int level, int count) {
|
||||
static const char *
|
||||
lGetSystemISA() {
|
||||
#ifdef __arm__
|
||||
return "neon-32";
|
||||
return "neon-i32x4";
|
||||
#else
|
||||
int info[4];
|
||||
__cpuid(info, 1);
|
||||
@@ -121,19 +121,19 @@ lGetSystemISA() {
|
||||
int info2[4];
|
||||
__cpuidex(info2, 7, 0);
|
||||
if ((info2[1] & (1 << 5)) != 0)
|
||||
return "avx2";
|
||||
return "avx2-i32x8";
|
||||
else
|
||||
return "avx1.1";
|
||||
return "avx1.1-i32x8";
|
||||
}
|
||||
// Regular AVX
|
||||
return "avx";
|
||||
return "avx-i32x8";
|
||||
}
|
||||
else if ((info[2] & (1 << 19)) != 0)
|
||||
return "sse4";
|
||||
return "sse4-i32x4";
|
||||
else if ((info[3] & (1 << 26)) != 0)
|
||||
return "sse2";
|
||||
return "sse2-i32x4";
|
||||
else {
|
||||
fprintf(stderr, "Unable to detect supported SSE/AVX ISA. Exiting.\n");
|
||||
Error(SourcePos(), "Unable to detect supported SSE/AVX ISA. Exiting.");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
@@ -186,22 +186,22 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
// If a CPU was specified explicitly, try to pick the best
|
||||
// possible ISA based on that.
|
||||
if (!strcmp(cpu, "core-avx2"))
|
||||
isa = "avx2";
|
||||
isa = "avx2-i32x8";
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
else if (!strcmp(cpu, "cortex-a9") ||
|
||||
!strcmp(cpu, "cortex-a15"))
|
||||
isa = "neon-32";
|
||||
isa = "neon-i32x4";
|
||||
#endif
|
||||
else if (!strcmp(cpu, "core-avx-i"))
|
||||
isa = "avx1.1";
|
||||
isa = "avx1.1-i32x8";
|
||||
else if (!strcmp(cpu, "sandybridge") ||
|
||||
!strcmp(cpu, "corei7-avx"))
|
||||
isa = "avx";
|
||||
isa = "avx-i32x8";
|
||||
else if (!strcmp(cpu, "corei7") ||
|
||||
!strcmp(cpu, "penryn"))
|
||||
isa = "sse4";
|
||||
isa = "sse4-i32x4";
|
||||
else
|
||||
isa = "sse2";
|
||||
isa = "sse2-i32x4";
|
||||
Warning(SourcePos(), "No --target specified on command-line. "
|
||||
"Using ISA \"%s\" based on specified CPU \"%s\".", isa,
|
||||
cpu);
|
||||
@@ -211,7 +211,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
// supports.
|
||||
isa = lGetSystemISA();
|
||||
Warning(SourcePos(), "No --target specified on command-line. "
|
||||
"Using system ISA \"%s\".", isa);
|
||||
"Using default system target \"%s\".", isa);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,8 +241,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
}
|
||||
}
|
||||
if (foundCPU == false) {
|
||||
fprintf(stderr, "Error: CPU type \"%s\" unknown. Supported CPUs: "
|
||||
"%s.\n", cpu, SupportedTargetCPUs().c_str());
|
||||
Error(SourcePos(), "Error: CPU type \"%s\" unknown. Supported CPUs: "
|
||||
"%s.", cpu, SupportedCPUs().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -283,7 +283,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
}
|
||||
|
||||
// Check default LLVM generated targets
|
||||
if (!strcasecmp(isa, "sse2")) {
|
||||
if (!strcasecmp(isa, "sse2") ||
|
||||
!strcasecmp(isa, "sse2-i32x4")) {
|
||||
this->m_isa = Target::SSE2;
|
||||
this->m_nativeVectorWidth = 4;
|
||||
this->m_vectorWidth = 4;
|
||||
@@ -291,7 +292,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "sse2-x2")) {
|
||||
else if (!strcasecmp(isa, "sse2-x2") ||
|
||||
!strcasecmp(isa, "sse2-i32x8")) {
|
||||
this->m_isa = Target::SSE2;
|
||||
this->m_nativeVectorWidth = 4;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -299,7 +301,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "sse4")) {
|
||||
else if (!strcasecmp(isa, "sse4") ||
|
||||
!strcasecmp(isa, "sse4-i32x4")) {
|
||||
this->m_isa = Target::SSE4;
|
||||
this->m_nativeVectorWidth = 4;
|
||||
this->m_vectorWidth = 4;
|
||||
@@ -308,7 +311,9 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "sse4x2") || !strcasecmp(isa, "sse4-x2")) {
|
||||
else if (!strcasecmp(isa, "sse4x2") ||
|
||||
!strcasecmp(isa, "sse4-x2") ||
|
||||
!strcasecmp(isa, "sse4-i32x8")) {
|
||||
this->m_isa = Target::SSE4;
|
||||
this->m_nativeVectorWidth = 4;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -316,7 +321,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "sse4-8")) {
|
||||
else if (!strcasecmp(isa, "sse4-i8x16")) {
|
||||
this->m_isa = Target::SSE4;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_vectorWidth = 16;
|
||||
@@ -324,7 +329,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 8;
|
||||
}
|
||||
else if (!strcasecmp(isa, "sse4-16")) {
|
||||
else if (!strcasecmp(isa, "sse4-i16x8")) {
|
||||
this->m_isa = Target::SSE4;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -332,7 +337,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 16;
|
||||
}
|
||||
else if (!strcasecmp(isa, "generic-4")) {
|
||||
else if (!strcasecmp(isa, "generic-4") ||
|
||||
!strcasecmp(isa, "generic-x4")) {
|
||||
this->m_isa = Target::GENERIC;
|
||||
this->m_nativeVectorWidth = 4;
|
||||
this->m_vectorWidth = 4;
|
||||
@@ -342,7 +348,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasTranscendentals = true;
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
}
|
||||
else if (!strcasecmp(isa, "generic-8")) {
|
||||
else if (!strcasecmp(isa, "generic-8") ||
|
||||
!strcasecmp(isa, "generic-x8")) {
|
||||
this->m_isa = Target::GENERIC;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -352,7 +359,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasTranscendentals = true;
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
}
|
||||
else if (!strcasecmp(isa, "generic-16")) {
|
||||
else if (!strcasecmp(isa, "generic-16") ||
|
||||
!strcasecmp(isa, "generic-x16")) {
|
||||
this->m_isa = Target::GENERIC;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_vectorWidth = 16;
|
||||
@@ -362,7 +370,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasTranscendentals = true;
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
}
|
||||
else if (!strcasecmp(isa, "generic-32")) {
|
||||
else if (!strcasecmp(isa, "generic-32") ||
|
||||
!strcasecmp(isa, "generic-x32")) {
|
||||
this->m_isa = Target::GENERIC;
|
||||
this->m_nativeVectorWidth = 32;
|
||||
this->m_vectorWidth = 32;
|
||||
@@ -372,7 +381,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasTranscendentals = true;
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
}
|
||||
else if (!strcasecmp(isa, "generic-64")) {
|
||||
else if (!strcasecmp(isa, "generic-64") ||
|
||||
!strcasecmp(isa, "generic-x64")) {
|
||||
this->m_isa = Target::GENERIC;
|
||||
this->m_nativeVectorWidth = 64;
|
||||
this->m_vectorWidth = 64;
|
||||
@@ -382,14 +392,17 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasTranscendentals = true;
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
}
|
||||
else if (!strcasecmp(isa, "generic-1")) {
|
||||
else if (!strcasecmp(isa, "generic-1") ||
|
||||
!strcasecmp(isa, "generic-x1")) {
|
||||
this->m_isa = Target::GENERIC;
|
||||
this->m_nativeVectorWidth = 1;
|
||||
this->m_vectorWidth = 1;
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "avx") || !strcasecmp(isa, "avx1")) {
|
||||
else if (!strcasecmp(isa, "avx") ||
|
||||
!strcasecmp(isa, "avx1") ||
|
||||
!strcasecmp(isa, "avx1-i32x8")) {
|
||||
this->m_isa = Target::AVX;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -397,7 +410,9 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "avx-x2") || !strcasecmp(isa, "avx1-x2")) {
|
||||
else if (!strcasecmp(isa, "avx-x2") ||
|
||||
!strcasecmp(isa, "avx1-x2") ||
|
||||
!strcasecmp(isa, "avx1-i32x16")) {
|
||||
this->m_isa = Target::AVX;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 16;
|
||||
@@ -405,7 +420,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 32;
|
||||
}
|
||||
else if (!strcasecmp(isa, "avx1.1")) {
|
||||
else if (!strcasecmp(isa, "avx1.1") ||
|
||||
!strcasecmp(isa, "avx1.1-i32x8")) {
|
||||
this->m_isa = Target::AVX11;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -418,7 +434,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasRand = true;
|
||||
#endif
|
||||
}
|
||||
else if (!strcasecmp(isa, "avx1.1-x2")) {
|
||||
else if (!strcasecmp(isa, "avx1.1-x2") ||
|
||||
!strcasecmp(isa, "avx1.1-i32x16")) {
|
||||
this->m_isa = Target::AVX11;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 16;
|
||||
@@ -431,7 +448,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasRand = true;
|
||||
#endif
|
||||
}
|
||||
else if (!strcasecmp(isa, "avx2")) {
|
||||
else if (!strcasecmp(isa, "avx2") ||
|
||||
!strcasecmp(isa, "avx2-i32x8")) {
|
||||
this->m_isa = Target::AVX2;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -449,7 +467,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_hasGather = true;
|
||||
#endif
|
||||
}
|
||||
else if (!strcasecmp(isa, "avx2-x2")) {
|
||||
else if (!strcasecmp(isa, "avx2-x2") ||
|
||||
!strcasecmp(isa, "avx2-i32x16")) {
|
||||
this->m_isa = Target::AVX2;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_vectorWidth = 16;
|
||||
@@ -468,7 +487,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
#endif
|
||||
}
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
else if (!strcasecmp(isa, "neon-8")) {
|
||||
else if (!strcasecmp(isa, "neon-i8x16")) {
|
||||
this->m_isa = Target::NEON8;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_vectorWidth = 16;
|
||||
@@ -477,7 +496,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 8;
|
||||
}
|
||||
else if (!strcasecmp(isa, "neon-16")) {
|
||||
else if (!strcasecmp(isa, "neon-i16x8")) {
|
||||
this->m_isa = Target::NEON16;
|
||||
this->m_nativeVectorWidth = 8;
|
||||
this->m_vectorWidth = 8;
|
||||
@@ -486,7 +505,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
this->m_maskingIsFree = false;
|
||||
this->m_maskBitCount = 16;
|
||||
}
|
||||
else if (!strcasecmp(isa, "neon-32") || !strcasecmp(isa, "neon")) {
|
||||
else if (!strcasecmp(isa, "neon") ||
|
||||
!strcasecmp(isa, "neon-i32x4")) {
|
||||
this->m_isa = Target::NEON32;
|
||||
this->m_nativeVectorWidth = 4;
|
||||
this->m_vectorWidth = 4;
|
||||
@@ -497,8 +517,8 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n",
|
||||
isa, SupportedTargetISAs());
|
||||
Error(SourcePos(), "Target \"%s\" is unknown. Choices are: %s.",
|
||||
isa, SupportedTargets());
|
||||
error = true;
|
||||
}
|
||||
|
||||
@@ -592,7 +612,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
|
||||
|
||||
|
||||
std::string
|
||||
Target::SupportedTargetCPUs() {
|
||||
Target::SupportedCPUs() {
|
||||
std::string ret;
|
||||
int count = sizeof(supportedCPUs) / sizeof(supportedCPUs[0]);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
@@ -605,7 +625,7 @@ Target::SupportedTargetCPUs() {
|
||||
|
||||
|
||||
const char *
|
||||
Target::SupportedTargetArchs() {
|
||||
Target::SupportedArchs() {
|
||||
return
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
"arm, "
|
||||
@@ -615,14 +635,18 @@ Target::SupportedTargetArchs() {
|
||||
|
||||
|
||||
const char *
|
||||
Target::SupportedTargetISAs() {
|
||||
Target::SupportedTargets() {
|
||||
return
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
"neon-8, neon-16, neon-32, "
|
||||
"neon-i8x16, neon-16x8, neon-32x4, "
|
||||
#endif
|
||||
"sse2, sse2-x2, sse4, sse4-8, sse4-16, sse4-x2, "
|
||||
"avx, avx-x2, avx1.1, avx1.1-x2, avx2, avx2-x2, "
|
||||
"generic-1, generic-4, generic-8, generic-16, generic-32";
|
||||
"sse2-i32x4, sse2-i32x8, "
|
||||
"sse4-i32x4, sse4-i32x8, sse4-i16x8, sse4-i8x16, "
|
||||
"avx1-i32x8, avx1-i32x16, "
|
||||
"avx1.1-i32x8, avx1.1-i32x16, "
|
||||
"avx2-i32x8, avx2-i32x16, "
|
||||
"generic-x1, generic-x4, generic-x8, generic-x16, "
|
||||
"generic-x32, generic-x64";
|
||||
}
|
||||
|
||||
|
||||
|
||||
12
ispc.h
12
ispc.h
@@ -192,16 +192,16 @@ public:
|
||||
Target(const char *arch, const char *cpu, const char *isa, bool pic);
|
||||
|
||||
/** Returns a comma-delimited string giving the names of the currently
|
||||
supported target ISAs. */
|
||||
static const char *SupportedTargetISAs();
|
||||
supported compilation targets. */
|
||||
static const char *SupportedTargets();
|
||||
|
||||
/** Returns a comma-delimited string giving the names of the currently
|
||||
supported target CPUs. */
|
||||
static std::string SupportedTargetCPUs();
|
||||
supported CPUs. */
|
||||
static std::string SupportedCPUs();
|
||||
|
||||
/** Returns a comma-delimited string giving the names of the currently
|
||||
supported target architectures. */
|
||||
static const char *SupportedTargetArchs();
|
||||
supported architectures. */
|
||||
static const char *SupportedArchs();
|
||||
|
||||
/** Returns a triple string specifying the target architecture, vendor,
|
||||
and environment. */
|
||||
|
||||
15
main.cpp
15
main.cpp
@@ -85,13 +85,16 @@ usage(int ret) {
|
||||
printf(" \t\taddressing calculations are done by default, even\n");
|
||||
printf(" \t\ton 64-bit target architectures.)\n");
|
||||
printf(" [--arch={%s}]\t\tSelect target architecture\n",
|
||||
Target::SupportedTargetArchs());
|
||||
Target::SupportedArchs());
|
||||
printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n");
|
||||
#ifndef ISPC_IS_WINDOWS
|
||||
printf(" [--colored-output]\t\tAlways use terminal colors in error/warning messages.\n");
|
||||
#endif
|
||||
printf(" [--cpu=<cpu>]\t\t\tSelect target CPU type\n");
|
||||
printf(" <cpu>={%s}\n", Target::SupportedTargetCPUs().c_str());
|
||||
printf(" ");
|
||||
char cpuHelp[2048];
|
||||
sprintf(cpuHelp, "[--cpu=<cpu>]\t\t\tSelect target CPU type\n<cpu>={%s}\n",
|
||||
Target::SupportedCPUs().c_str());
|
||||
PrintWithWordBreaks(cpuHelp, 16, TerminalWidth(), stdout);
|
||||
printf(" [-D<foo>]\t\t\t\t#define given value when running preprocessor\n");
|
||||
printf(" [--dev-stub <filename>]\t\tEmit device-side offload stub functions to file\n");
|
||||
printf(" [--emit-asm]\t\t\tGenerate assembly language file as output\n");
|
||||
@@ -126,7 +129,11 @@ usage(int ret) {
|
||||
printf(" [--pic]\t\t\t\tGenerate position-independent code\n");
|
||||
#endif // !ISPC_IS_WINDOWS
|
||||
printf(" [--quiet]\t\t\t\tSuppress all output\n");
|
||||
printf(" [--target=<isa>]\t\t\tSelect target ISA. <isa>={%s}\n", Target::SupportedTargetISAs());
|
||||
printf(" ");
|
||||
char targetHelp[2048];
|
||||
sprintf(targetHelp, "[--target=<t>]\t\t\tSelect target ISA and width.\n"
|
||||
"<t>={%s}", Target::SupportedTargets());
|
||||
PrintWithWordBreaks(targetHelp, 24, TerminalWidth(), stdout);
|
||||
printf(" [--version]\t\t\t\tPrint ispc version\n");
|
||||
printf(" [--werror]\t\t\t\tTreat warnings as errors\n");
|
||||
printf(" [--woff]\t\t\t\tDisable warnings\n");
|
||||
|
||||
@@ -37,7 +37,7 @@ parser.add_option("-g", "--generics-include", dest="include_file", help="Filenam
|
||||
parser.add_option("-f", "--ispc-flags", dest="ispc_flags", help="Additional flags for ispc (-g, -O1, ...)",
|
||||
default="")
|
||||
parser.add_option('-t', '--target', dest='target',
|
||||
help='Set compilation target (neon8, neon16, neon32, sse2, sse2-x2, sse4, sse4-x2, sse4-8, sse4-16, avx, avx-x2, generic-4, generic-8, generic-16, generic-32)',
|
||||
help='Set compilation target (sse2-i32x4, sse2-i32x8, sse4-i32x4, sse4-i32x8, sse4-i16x8, sse4-i8x16, avx1-i32x8, avx1-i32x16, avx1.1-i32x8, avx1.1-i32x16, avx2-i32x8, avx2-i32x16, generic-x1, generic-x4, generic-x8, generic-x16, generic-x32, generic-x64)',
|
||||
default="sse4")
|
||||
parser.add_option('-a', '--arch', dest='arch',
|
||||
help='Set architecture (arm, x86, x86-64)',
|
||||
|
||||
10
util.cpp
10
util.cpp
@@ -79,8 +79,8 @@
|
||||
compiler under a debuffer; in this case, just return a reasonable
|
||||
default.
|
||||
*/
|
||||
static int
|
||||
lTerminalWidth() {
|
||||
int
|
||||
TerminalWidth() {
|
||||
if (g->disableLineWrap)
|
||||
return 1<<30;
|
||||
|
||||
@@ -228,8 +228,8 @@ lFindIndent(int numColons, const char *buf) {
|
||||
/** Print the given string to the given FILE, assuming the given output
|
||||
column width. Break words as needed to avoid words spilling past the
|
||||
last column. */
|
||||
static void
|
||||
lPrintWithWordBreaks(const char *buf, int indent, int columnWidth, FILE *out) {
|
||||
void
|
||||
PrintWithWordBreaks(const char *buf, int indent, int columnWidth, FILE *out) {
|
||||
#ifdef ISPC_IS_WINDOWS
|
||||
fputs(buf, out);
|
||||
fputs("\n", out);
|
||||
@@ -375,7 +375,7 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
||||
return;
|
||||
printed.insert(formattedBuf);
|
||||
|
||||
lPrintWithWordBreaks(formattedBuf, indent, lTerminalWidth(), stderr);
|
||||
PrintWithWordBreaks(formattedBuf, indent, TerminalWidth(), stderr);
|
||||
lPrintFileLineContext(p);
|
||||
|
||||
free(errorBuf);
|
||||
|
||||
14
util.h
14
util.h
@@ -156,4 +156,18 @@ void GetDirectoryAndFileName(const std::string ¤tDir,
|
||||
bool VerifyDataLayoutCompatibility(const std::string &module_dl,
|
||||
const std::string &lib_dl);
|
||||
|
||||
/** Print the given string to the given FILE, assuming the given output
|
||||
column width. Break words as needed to avoid words spilling past the
|
||||
last column. */
|
||||
void PrintWithWordBreaks(const char *buf, int indent, int columnWidth,
|
||||
FILE *out);
|
||||
|
||||
/** Returns the width of the terminal where the compiler is running.
|
||||
Finding this out may fail in a variety of reasonable situations (piping
|
||||
compiler output to 'less', redirecting output to a file, running the
|
||||
compiler under a debuffer; in this case, just return a reasonable
|
||||
default.
|
||||
*/
|
||||
int TerminalWidth();
|
||||
|
||||
#endif // ISPC_UTIL_H
|
||||
|
||||
Reference in New Issue
Block a user