Commit fac55170 by Jim Stichnoth

Subzero: Move to C++11 static_assert().

BUG= none R=jvoung@chromium.org, kschimpf@google.com Review URL: https://codereview.chromium.org/618313003
parent 9c234e2a
...@@ -32,15 +32,8 @@ ...@@ -32,15 +32,8 @@
#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h" // LLVM_STATIC_ASSERT
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
// Roll our own static_assert<> in the absence of C++11. TODO: change
// to static_assert<> with C++11.
template <bool> struct staticAssert;
template <> struct staticAssert<true> {}; // only true is defined
#define STATIC_ASSERT(x) staticAssert<(x)>()
namespace Ice { namespace Ice {
class Cfg; class Cfg;
......
...@@ -23,11 +23,10 @@ ...@@ -23,11 +23,10 @@
namespace Ice { namespace Ice {
namespace { static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4,
"Unexpected sizeof(IntrinsicInfo)");
void __attribute__((unused)) xIntrinsicInfoSizeCheck() { namespace {
STATIC_ASSERT(sizeof(Intrinsics::IntrinsicInfo) == 4);
}
#define INTRIN(ID, SE, RT) { Intrinsics::ID, Intrinsics::SE, Intrinsics::RT } #define INTRIN(ID, SE, RT) { Intrinsics::ID, Intrinsics::SE, Intrinsics::RT }
......
...@@ -61,9 +61,9 @@ const struct TableFcmp_ { ...@@ -61,9 +61,9 @@ const struct TableFcmp_ {
#define X(val, dflt, swapS, C1, C2, swapV, pred) \ #define X(val, dflt, swapS, C1, C2, swapV, pred) \
{ dflt, swapS, CondX86::C1, CondX86::C2, swapV, CondX86::pred } \ { dflt, swapS, CondX86::C1, CondX86::C2, swapV, CondX86::pred } \
, ,
FCMPX8632_TABLE FCMPX8632_TABLE
#undef X #undef X
}; };
const size_t TableFcmpSize = llvm::array_lengthof(TableFcmp); const size_t TableFcmpSize = llvm::array_lengthof(TableFcmp);
// The following table summarizes the logic for lowering the icmp instruction // The following table summarizes the logic for lowering the icmp instruction
...@@ -155,109 +155,120 @@ uint32_t applyStackAlignment(uint32_t Value) { ...@@ -155,109 +155,120 @@ uint32_t applyStackAlignment(uint32_t Value) {
// Instruction set options // Instruction set options
namespace cl = ::llvm::cl; namespace cl = ::llvm::cl;
cl::opt<TargetX8632::X86InstructionSet> CLInstructionSet( cl::opt<TargetX8632::X86InstructionSet>
"mattr", cl::desc("X86 target attributes"), CLInstructionSet("mattr", cl::desc("X86 target attributes"),
cl::init(TargetX8632::SSE2), cl::init(TargetX8632::SSE2),
cl::values( cl::values(clEnumValN(TargetX8632::SSE2, "sse2",
clEnumValN(TargetX8632::SSE2, "sse2", "Enable SSE2 instructions (default)"),
"Enable SSE2 instructions (default)"), clEnumValN(TargetX8632::SSE4_1, "sse4.1",
clEnumValN(TargetX8632::SSE4_1, "sse4.1", "Enable SSE 4.1 instructions"),
"Enable SSE 4.1 instructions"), clEnumValEnd)); clEnumValEnd));
// In some cases, there are x-macros tables for both high-level and // In some cases, there are x-macros tables for both high-level and
// low-level instructions/operands that use the same enum key value. // low-level instructions/operands that use the same enum key value.
// The tables are kept separate to maintain a proper separation // The tables are kept separate to maintain a proper separation
// between abstraction layers. There is a risk that the tables // between abstraction layers. There is a risk that the tables could
// could get out of sync if enum values are reordered or if entries // get out of sync if enum values are reordered or if entries are
// are added or deleted. This dummy function uses static_assert to // added or deleted. The following dummy namespaces use
// ensure everything is kept in sync. // static_asserts to ensure everything is kept in sync.
void __attribute__((unused)) xMacroIntegrityCheck() {
// Validate the enum values in FCMPX8632_TABLE. // Validate the enum values in FCMPX8632_TABLE.
{ namespace dummy1 {
// Define a temporary set of enum values based on low-level // Define a temporary set of enum values based on low-level table
// table entries. // entries.
enum _tmp_enum { enum _tmp_enum {
#define X(val, dflt, swapS, C1, C2, swapV, pred) _tmp_##val, #define X(val, dflt, swapS, C1, C2, swapV, pred) _tmp_##val,
FCMPX8632_TABLE FCMPX8632_TABLE
#undef X #undef X
_num _num
}; };
// Define a set of constants based on high-level table entries. // Define a set of constants based on high-level table entries.
#define X(tag, str) static const int _table1_##tag = InstFcmp::tag; #define X(tag, str) static const int _table1_##tag = InstFcmp::tag;
ICEINSTFCMP_TABLE; ICEINSTFCMP_TABLE;
#undef X #undef X
// Define a set of constants based on low-level table entries, // Define a set of constants based on low-level table entries, and
// and ensure the table entry keys are consistent. // ensure the table entry keys are consistent.
#define X(val, dflt, swapS, C1, C2, swapV, pred) \ #define X(val, dflt, swapS, C1, C2, swapV, pred) \
static const int _table2_##val = _tmp_##val; \ static const int _table2_##val = _tmp_##val; \
STATIC_ASSERT(_table1_##val == _table2_##val); static_assert( \
FCMPX8632_TABLE; _table1_##val == _table2_##val, \
"Inconsistency between FCMPX8632_TABLE and ICEINSTFCMP_TABLE");
FCMPX8632_TABLE;
#undef X #undef X
// Repeat the static asserts with respect to the high-level // Repeat the static asserts with respect to the high-level table
// table entries in case the high-level table has extra entries. // entries in case the high-level table has extra entries.
#define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); #define X(tag, str) \
ICEINSTFCMP_TABLE; static_assert( \
_table1_##tag == _table2_##tag, \
"Inconsistency between FCMPX8632_TABLE and ICEINSTFCMP_TABLE");
ICEINSTFCMP_TABLE;
#undef X #undef X
} } // end of namespace dummy1
// Validate the enum values in ICMPX8632_TABLE. // Validate the enum values in ICMPX8632_TABLE.
{ namespace dummy2 {
// Define a temporary set of enum values based on low-level // Define a temporary set of enum values based on low-level table
// table entries. // entries.
enum _tmp_enum { enum _tmp_enum {
#define X(val, C_32, C1_64, C2_64, C3_64) _tmp_##val, #define X(val, C_32, C1_64, C2_64, C3_64) _tmp_##val,
ICMPX8632_TABLE ICMPX8632_TABLE
#undef X #undef X
_num _num
}; };
// Define a set of constants based on high-level table entries. // Define a set of constants based on high-level table entries.
#define X(tag, str) static const int _table1_##tag = InstIcmp::tag; #define X(tag, str) static const int _table1_##tag = InstIcmp::tag;
ICEINSTICMP_TABLE; ICEINSTICMP_TABLE;
#undef X #undef X
// Define a set of constants based on low-level table entries, // Define a set of constants based on low-level table entries, and
// and ensure the table entry keys are consistent. // ensure the table entry keys are consistent.
#define X(val, C_32, C1_64, C2_64, C3_64) \ #define X(val, C_32, C1_64, C2_64, C3_64) \
static const int _table2_##val = _tmp_##val; \ static const int _table2_##val = _tmp_##val; \
STATIC_ASSERT(_table1_##val == _table2_##val); static_assert( \
ICMPX8632_TABLE; _table1_##val == _table2_##val, \
"Inconsistency between ICMPX8632_TABLE and ICEINSTICMP_TABLE");
ICMPX8632_TABLE;
#undef X #undef X
// Repeat the static asserts with respect to the high-level // Repeat the static asserts with respect to the high-level table
// table entries in case the high-level table has extra entries. // entries in case the high-level table has extra entries.
#define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); #define X(tag, str) \
ICEINSTICMP_TABLE; static_assert( \
_table1_##tag == _table2_##tag, \
"Inconsistency between ICMPX8632_TABLE and ICEINSTICMP_TABLE");
ICEINSTICMP_TABLE;
#undef X #undef X
} } // end of namespace dummy2
// Validate the enum values in ICETYPEX8632_TABLE. // Validate the enum values in ICETYPEX8632_TABLE.
{ namespace dummy3 {
// Define a temporary set of enum values based on low-level // Define a temporary set of enum values based on low-level table
// table entries. // entries.
enum _tmp_enum { enum _tmp_enum {
#define X(tag, elementty, cvt, sdss, pack, width) _tmp_##tag, #define X(tag, elementty, cvt, sdss, pack, width) _tmp_##tag,
ICETYPEX8632_TABLE ICETYPEX8632_TABLE
#undef X #undef X
_num _num
}; };
// Define a set of constants based on high-level table entries. // Define a set of constants based on high-level table entries.
#define X(tag, size, align, elts, elty, str) \ #define X(tag, size, align, elts, elty, str) \
static const int _table1_##tag = tag; static const int _table1_##tag = tag;
ICETYPE_TABLE; ICETYPE_TABLE;
#undef X #undef X
// Define a set of constants based on low-level table entries, // Define a set of constants based on low-level table entries, and
// and ensure the table entry keys are consistent. // ensure the table entry keys are consistent.
#define X(tag, elementty, cvt, sdss, pack, width) \ #define X(tag, elementty, cvt, sdss, pack, width) \
static const int _table2_##tag = _tmp_##tag; \ static const int _table2_##tag = _tmp_##tag; \
STATIC_ASSERT(_table1_##tag == _table2_##tag); static_assert(_table1_##tag == _table2_##tag, \
ICETYPEX8632_TABLE; "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
ICETYPEX8632_TABLE;
#undef X #undef X
// Repeat the static asserts with respect to the high-level // Repeat the static asserts with respect to the high-level table
// table entries in case the high-level table has extra entries. // entries in case the high-level table has extra entries.
#define X(tag, size, align, elts, elty, str) \ #define X(tag, size, align, elts, elty, str) \
STATIC_ASSERT(_table1_##tag == _table2_##tag); static_assert(_table1_##tag == _table2_##tag, \
ICETYPE_TABLE; "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
ICETYPE_TABLE;
#undef X #undef X
} } // end of namespace dummy3
}
} // end of anonymous namespace } // end of anonymous namespace
...@@ -2796,8 +2807,8 @@ void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { ...@@ -2796,8 +2807,8 @@ void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) {
// T := SourceVectRM // T := SourceVectRM
// ElementR := ElementR[0, 0] T[0, 2] // ElementR := ElementR[0, 0] T[0, 2]
// T := T[0, 1] ElementR[3, 0] // T := T[0, 1] ElementR[3, 0]
const unsigned char Mask1[3] = {0, 192, 128}; const unsigned char Mask1[3] = { 0, 192, 128 };
const unsigned char Mask2[3] = {227, 196, 52}; const unsigned char Mask2[3] = { 227, 196, 52 };
Constant *Mask1Constant = Constant *Mask1Constant =
Ctx->getConstantInt32(IceType_i8, Mask1[Index - 1]); Ctx->getConstantInt32(IceType_i8, Mask1[Index - 1]);
...@@ -2842,12 +2853,12 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -2842,12 +2853,12 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
switch (Instr->getIntrinsicInfo().ID) { switch (Instr->getIntrinsicInfo().ID) {
case Intrinsics::AtomicCmpxchg: { case Intrinsics::AtomicCmpxchg: {
if (!Intrinsics::VerifyMemoryOrder( if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) { llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) {
Func->setError("Unexpected memory ordering (success) for AtomicCmpxchg"); Func->setError("Unexpected memory ordering (success) for AtomicCmpxchg");
return; return;
} }
if (!Intrinsics::VerifyMemoryOrder( if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger32>(Instr->getArg(4))->getValue())) { llvm::cast<ConstantInteger32>(Instr->getArg(4))->getValue())) {
Func->setError("Unexpected memory ordering (failure) for AtomicCmpxchg"); Func->setError("Unexpected memory ordering (failure) for AtomicCmpxchg");
return; return;
} }
...@@ -2862,7 +2873,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -2862,7 +2873,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} }
case Intrinsics::AtomicFence: case Intrinsics::AtomicFence:
if (!Intrinsics::VerifyMemoryOrder( if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue())) { llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicFence"); Func->setError("Unexpected memory ordering for AtomicFence");
return; return;
} }
...@@ -2908,7 +2919,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -2908,7 +2919,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
// We require the memory address to be naturally aligned. // We require the memory address to be naturally aligned.
// Given that is the case, then normal loads are atomic. // Given that is the case, then normal loads are atomic.
if (!Intrinsics::VerifyMemoryOrder( if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger32>(Instr->getArg(1))->getValue())) { llvm::cast<ConstantInteger32>(Instr->getArg(1))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicLoad"); Func->setError("Unexpected memory ordering for AtomicLoad");
return; return;
} }
...@@ -2941,18 +2952,18 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -2941,18 +2952,18 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} }
case Intrinsics::AtomicRMW: case Intrinsics::AtomicRMW:
if (!Intrinsics::VerifyMemoryOrder( if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) { llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicRMW"); Func->setError("Unexpected memory ordering for AtomicRMW");
return; return;
} }
lowerAtomicRMW(Instr->getDest(), lowerAtomicRMW(Instr->getDest(),
static_cast<uint32_t>(llvm::cast<ConstantInteger32>( static_cast<uint32_t>(llvm::cast<ConstantInteger32>(
Instr->getArg(0))->getValue()), Instr->getArg(0))->getValue()),
Instr->getArg(1), Instr->getArg(2)); Instr->getArg(1), Instr->getArg(2));
return; return;
case Intrinsics::AtomicStore: { case Intrinsics::AtomicStore: {
if (!Intrinsics::VerifyMemoryOrder( if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger32>(Instr->getArg(2))->getValue())) { llvm::cast<ConstantInteger32>(Instr->getArg(2))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicStore"); Func->setError("Unexpected memory ordering for AtomicStore");
return; return;
} }
...@@ -3106,9 +3117,8 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -3106,9 +3117,8 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
case Intrinsics::NaClReadTP: { case Intrinsics::NaClReadTP: {
if (Ctx->getFlags().UseSandboxing) { if (Ctx->getFlags().UseSandboxing) {
Constant *Zero = Ctx->getConstantZero(IceType_i32); Constant *Zero = Ctx->getConstantZero(IceType_i32);
Operand *Src = Operand *Src = OperandX8632Mem::create(
OperandX8632Mem::create(Func, IceType_i32, NULL, Zero, NULL, Func, IceType_i32, NULL, Zero, NULL, 0, OperandX8632Mem::SegReg_GS);
0, OperandX8632Mem::SegReg_GS);
Variable *Dest = Instr->getDest(); Variable *Dest = Instr->getDest();
Variable *T = NULL; Variable *T = NULL;
_mov(T, Src); _mov(T, Src);
...@@ -3900,7 +3910,7 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) { ...@@ -3900,7 +3910,7 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
} else { } else {
assert(typeNumElements(SrcTy) == 8 || typeNumElements(SrcTy) == 16); assert(typeNumElements(SrcTy) == 8 || typeNumElements(SrcTy) == 16);
Type SignExtTy = Condition->getType() == IceType_v8i1 ? IceType_v8i16 Type SignExtTy = Condition->getType() == IceType_v8i1 ? IceType_v8i16
: IceType_v16i8; : IceType_v16i8;
Variable *xmm0 = makeReg(SignExtTy, RegX8632::Reg_xmm0); Variable *xmm0 = makeReg(SignExtTy, RegX8632::Reg_xmm0);
lowerCast(InstCast::create(Func, InstCast::Sext, xmm0, Condition)); lowerCast(InstCast::create(Func, InstCast::Sext, xmm0, Condition));
_movp(T, SrcFRM); _movp(T, SrcFRM);
......
...@@ -18,61 +18,61 @@ namespace Ice { ...@@ -18,61 +18,61 @@ namespace Ice {
namespace { namespace {
// Dummy function to make sure the two type tables have the same // Show tags match between ICETYPE_TABLE and ICETYPE_PROPS_TABLE.
// enumerated types.
void __attribute__((unused)) xIceTypeMacroIntegrityCheck() {
// Show tags match between ICETYPE_TABLE and ICETYPE_PROPS_TABLE. // Define a temporary set of enum values based on ICETYPE_TABLE
enum {
// Define a temporary set of enum values based on ICETYPE_TABLE
enum {
#define X(tag, size, align, elts, elty, str) _table_tag_##tag, #define X(tag, size, align, elts, elty, str) _table_tag_##tag,
ICETYPE_TABLE ICETYPE_TABLE
#undef X #undef X
_enum_table_tag_Names _enum_table_tag_Names
}; };
// Define a temporary set of enum values based on ICETYPE_PROPS_TABLE // Define a temporary set of enum values based on ICETYPE_PROPS_TABLE
enum { enum {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \
_props_table_tag_##tag, _props_table_tag_##tag,
ICETYPE_PROPS_TABLE ICETYPE_PROPS_TABLE
#undef X #undef X
_enum_props_table_tag_Names _enum_props_table_tag_Names
}; };
// Assert that tags in ICETYPE_TABLE are also in ICETYPE_PROPS_TABLE. // Assert that tags in ICETYPE_TABLE are also in ICETYPE_PROPS_TABLE.
#define X(tag, size, align, elts, elty, str) \ #define X(tag, size, align, elts, elty, str) \
STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag); static_assert( \
ICETYPE_TABLE; (unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag, \
"Inconsistency between ICETYPE_PROPS_TABLE and ICETYPE_TABLE");
ICETYPE_TABLE;
#undef X #undef X
// Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE. // Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE.
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \
STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag); static_assert( \
ICETYPE_PROPS_TABLE (unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag, \
"Inconsistency between ICETYPE_PROPS_TABLE and ICETYPE_TABLE");
ICETYPE_PROPS_TABLE
#undef X #undef X
// Show vector definitions match in ICETYPE_TABLE and // Show vector definitions match in ICETYPE_TABLE and
// ICETYPE_PROPS_TABLE. // ICETYPE_PROPS_TABLE.
// Define constants for each element size in ICETYPE_TABLE. // Define constants for each element size in ICETYPE_TABLE.
enum { enum {
#define X(tag, size, align, elts, elty, str) _table_elts_##tag = elts, #define X(tag, size, align, elts, elty, str) _table_elts_##tag = elts,
ICETYPE_TABLE ICETYPE_TABLE
#undef X #undef X
_enum_table_elts_Elements = 0 _enum_table_elts_Elements = 0
}; };
// Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE. // Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE.
enum { enum {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \
_props_table_IsVec_##tag = IsVec, _props_table_IsVec_##tag = IsVec,
ICETYPE_PROPS_TABLE ICETYPE_PROPS_TABLE
#undef X #undef X
}; };
// Verify that the number of vector elements is consistent with IsVec. // Verify that the number of vector elements is consistent with IsVec.
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, CompareResult) \
STATIC_ASSERT((_table_elts_##tag > 1) == _props_table_IsVec_##tag); static_assert((_table_elts_##tag > 1) == _props_table_IsVec_##tag, \
ICETYPE_PROPS_TABLE; "Inconsistent vector specification in ICETYPE_PROPS_TABLE");
ICETYPE_PROPS_TABLE;
#undef X #undef X
}
struct TypeAttributeFields { struct TypeAttributeFields {
size_t TypeWidthInBytes; size_t TypeWidthInBytes;
...@@ -86,7 +86,7 @@ const struct TypeAttributeFields TypeAttributes[] = { ...@@ -86,7 +86,7 @@ const struct TypeAttributeFields TypeAttributes[] = {
#define X(tag, size, align, elts, elty, str) \ #define X(tag, size, align, elts, elty, str) \
{ size, align, elts, elty, str } \ { size, align, elts, elty, str } \
, ,
ICETYPE_TABLE ICETYPE_TABLE
#undef X #undef X
}; };
...@@ -110,7 +110,7 @@ const TypePropertyFields TypePropertiesTable[] = { ...@@ -110,7 +110,7 @@ const TypePropertyFields TypePropertiesTable[] = {
IsFloat && !IsVec, IsFloat && IsVec, IsLoadStore, CompareResult \ IsFloat && !IsVec, IsFloat && IsVec, IsLoadStore, CompareResult \
} \ } \
, ,
ICETYPE_PROPS_TABLE ICETYPE_PROPS_TABLE
#undef X #undef X
}; };
......
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