Switched to a newer testing framework, fixed warnings on AArch64

This commit is contained in:
kobalicek
2023-03-05 15:27:51 +01:00
parent 76520a513d
commit d38b12a2b5
19 changed files with 971 additions and 895 deletions

View File

@@ -17,66 +17,66 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
#if defined(ASMJIT_TEST) #if defined(ASMJIT_TEST)
UNIT(a64_operand) { UNIT(a64_operand) {
INFO("Checking if a64::reg(...) matches built-in IDs"); INFO("Checking if a64::reg(...) matches built-in IDs");
EXPECT(w(5) == w5); EXPECT_EQ(w(5), w5);
EXPECT(x(5) == x5); EXPECT_EQ(x(5), x5);
INFO("Checking Gp register properties"); INFO("Checking Gp register properties");
EXPECT(Gp().isReg() == true); EXPECT_TRUE(Gp().isReg());
EXPECT(w0.isReg() == true); EXPECT_TRUE(w0.isReg());
EXPECT(x0.isReg() == true); EXPECT_TRUE(x0.isReg());
EXPECT(w0.id() == 0); EXPECT_EQ(w0.id(), 0u);
EXPECT(x0.id() == 0); EXPECT_EQ(x0.id(), 0u);
EXPECT(wzr.id() == Gp::kIdZr); EXPECT_EQ(wzr.id(), Gp::kIdZr);
EXPECT(xzr.id() == Gp::kIdZr); EXPECT_EQ(xzr.id(), Gp::kIdZr);
EXPECT(wsp.id() == Gp::kIdSp); EXPECT_EQ(wsp.id(), Gp::kIdSp);
EXPECT(sp.id() == Gp::kIdSp); EXPECT_EQ(sp.id(), Gp::kIdSp);
EXPECT(w0.size() == 4); EXPECT_EQ(w0.size(), 4u);
EXPECT(x0.size() == 8); EXPECT_EQ(x0.size(), 8u);
EXPECT(w0.type() == RegType::kARM_GpW); EXPECT_EQ(w0.type(), RegType::kARM_GpW);
EXPECT(x0.type() == RegType::kARM_GpX); EXPECT_EQ(x0.type(), RegType::kARM_GpX);
EXPECT(w0.group() == RegGroup::kGp); EXPECT_EQ(w0.group(), RegGroup::kGp);
EXPECT(x0.group() == RegGroup::kGp); EXPECT_EQ(x0.group(), RegGroup::kGp);
INFO("Checking Vec register properties"); INFO("Checking Vec register properties");
EXPECT(v0.type() == RegType::kARM_VecV); EXPECT_EQ(v0.type(), RegType::kARM_VecV);
EXPECT(d0.type() == RegType::kARM_VecD); EXPECT_EQ(d0.type(), RegType::kARM_VecD);
EXPECT(s0.type() == RegType::kARM_VecS); EXPECT_EQ(s0.type(), RegType::kARM_VecS);
EXPECT(h0.type() == RegType::kARM_VecH); EXPECT_EQ(h0.type(), RegType::kARM_VecH);
EXPECT(b0.type() == RegType::kARM_VecB); EXPECT_EQ(b0.type(), RegType::kARM_VecB);
EXPECT(v0.group() == RegGroup::kVec); EXPECT_EQ(v0.group(), RegGroup::kVec);
EXPECT(d0.group() == RegGroup::kVec); EXPECT_EQ(d0.group(), RegGroup::kVec);
EXPECT(s0.group() == RegGroup::kVec); EXPECT_EQ(s0.group(), RegGroup::kVec);
EXPECT(h0.group() == RegGroup::kVec); EXPECT_EQ(h0.group(), RegGroup::kVec);
EXPECT(b0.group() == RegGroup::kVec); EXPECT_EQ(b0.group(), RegGroup::kVec);
INFO("Checking Vec register element[] access"); INFO("Checking Vec register element[] access");
Vec vd_1 = v15.d(1); Vec vd_1 = v15.d(1);
EXPECT(vd_1.type() == RegType::kARM_VecV); EXPECT_EQ(vd_1.type(), RegType::kARM_VecV);
EXPECT(vd_1.group() == RegGroup::kVec); EXPECT_EQ(vd_1.group(), RegGroup::kVec);
EXPECT(vd_1.id() == 15); EXPECT_EQ(vd_1.id(), 15u);
EXPECT(vd_1.isVecD2()); EXPECT_TRUE(vd_1.isVecD2());
EXPECT(vd_1.elementType() == Vec::kElementTypeD); EXPECT_EQ(vd_1.elementType(), Vec::kElementTypeD);
EXPECT(vd_1.hasElementIndex()); EXPECT_TRUE(vd_1.hasElementIndex());
EXPECT(vd_1.elementIndex() == 1); EXPECT_EQ(vd_1.elementIndex(), 1u);
Vec vs_3 = v15.s(3); Vec vs_3 = v15.s(3);
EXPECT(vs_3.type() == RegType::kARM_VecV); EXPECT_EQ(vs_3.type(), RegType::kARM_VecV);
EXPECT(vs_3.group() == RegGroup::kVec); EXPECT_EQ(vs_3.group(), RegGroup::kVec);
EXPECT(vs_3.id() == 15); EXPECT_EQ(vs_3.id(), 15u);
EXPECT(vs_3.isVecS4()); EXPECT_TRUE(vs_3.isVecS4());
EXPECT(vs_3.elementType() == Vec::kElementTypeS); EXPECT_EQ(vs_3.elementType(), Vec::kElementTypeS);
EXPECT(vs_3.hasElementIndex()); EXPECT_TRUE(vs_3.hasElementIndex());
EXPECT(vs_3.elementIndex() == 3); EXPECT_EQ(vs_3.elementIndex(), 3u);
Vec vb_4 = v15.b4(3); Vec vb_4 = v15.b4(3);
EXPECT(vb_4.type() == RegType::kARM_VecV); EXPECT_EQ(vb_4.type(), RegType::kARM_VecV);
EXPECT(vb_4.group() == RegGroup::kVec); EXPECT_EQ(vb_4.group(), RegGroup::kVec);
EXPECT(vb_4.id() == 15); EXPECT_EQ(vb_4.id(), 15u);
EXPECT(vb_4.isVecB4x4()); EXPECT_TRUE(vb_4.isVecB4x4());
EXPECT(vb_4.elementType() == Vec::kElementTypeB4); EXPECT_EQ(vb_4.elementType(), Vec::kElementTypeB4);
EXPECT(vb_4.hasElementIndex()); EXPECT_TRUE(vb_4.hasElementIndex());
EXPECT(vb_4.elementIndex() == 3); EXPECT_EQ(vb_4.elementIndex(), 3u);
} }
#endif #endif

View File

@@ -1126,30 +1126,30 @@ UNIT(code_holder) {
env.init(Arch::kX86); env.init(Arch::kX86);
code.init(env); code.init(env);
EXPECT(code.arch() == Arch::kX86); EXPECT_EQ(code.arch(), Arch::kX86);
INFO("Verifying named labels"); INFO("Verifying named labels");
LabelEntry* le; LabelEntry* le;
EXPECT(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, LabelType::kGlobal) == kErrorOk); EXPECT_EQ(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, LabelType::kGlobal), kErrorOk);
EXPECT(strcmp(le->name(), "NamedLabel") == 0); EXPECT_EQ(strcmp(le->name(), "NamedLabel"), 0);
EXPECT(code.labelIdByName("NamedLabel") == le->id()); EXPECT_EQ(code.labelIdByName("NamedLabel"), le->id());
INFO("Verifying section ordering"); INFO("Verifying section ordering");
Section* section1; Section* section1;
EXPECT(code.newSection(&section1, "high-priority", SIZE_MAX, SectionFlags::kNone, 1, -1) == kErrorOk); EXPECT_EQ(code.newSection(&section1, "high-priority", SIZE_MAX, SectionFlags::kNone, 1, -1), kErrorOk);
EXPECT(code.sections()[1] == section1); EXPECT_EQ(code.sections()[1], section1);
EXPECT(code.sectionsByOrder()[0] == section1); EXPECT_EQ(code.sectionsByOrder()[0], section1);
Section* section0; Section* section0;
EXPECT(code.newSection(&section0, "higher-priority", SIZE_MAX, SectionFlags::kNone, 1, -2) == kErrorOk); EXPECT_EQ(code.newSection(&section0, "higher-priority", SIZE_MAX, SectionFlags::kNone, 1, -2), kErrorOk);
EXPECT(code.sections()[2] == section0); EXPECT_EQ(code.sections()[2], section0);
EXPECT(code.sectionsByOrder()[0] == section0); EXPECT_EQ(code.sectionsByOrder()[0], section0);
EXPECT(code.sectionsByOrder()[1] == section1); EXPECT_EQ(code.sectionsByOrder()[1], section1);
Section* section3; Section* section3;
EXPECT(code.newSection(&section3, "low-priority", SIZE_MAX, SectionFlags::kNone, 1, 2) == kErrorOk); EXPECT_EQ(code.newSection(&section3, "low-priority", SIZE_MAX, SectionFlags::kNone, 1, 2), kErrorOk);
EXPECT(code.sections()[3] == section3); EXPECT_EQ(code.sections()[3], section3);
EXPECT(code.sectionsByOrder()[3] == section3); EXPECT_EQ(code.sectionsByOrder()[3], section3);
} }
#endif #endif

View File

@@ -252,18 +252,18 @@ UNIT(const_pool) {
size_t curOffset; size_t curOffset;
uint64_t c = 0x0101010101010101u; uint64_t c = 0x0101010101010101u;
EXPECT(pool.add(&c, 8, prevOffset) == kErrorOk); EXPECT_EQ(pool.add(&c, 8, prevOffset), kErrorOk);
EXPECT(prevOffset == 0); EXPECT_EQ(prevOffset, 0u);
for (i = 1; i < kCount; i++) { for (i = 1; i < kCount; i++) {
c++; c++;
EXPECT(pool.add(&c, 8, curOffset) == kErrorOk); EXPECT_EQ(pool.add(&c, 8, curOffset), kErrorOk);
EXPECT(prevOffset + 8 == curOffset); EXPECT_EQ(prevOffset + 8, curOffset);
EXPECT(pool.size() == (i + 1) * 8); EXPECT_EQ(pool.size(), (i + 1) * 8);
prevOffset = curOffset; prevOffset = curOffset;
} }
EXPECT(pool.alignment() == 8); EXPECT_EQ(pool.alignment(), 8u);
} }
INFO("Retrieving %u constants from the pool", kCount); INFO("Retrieving %u constants from the pool", kCount);
@@ -272,8 +272,8 @@ UNIT(const_pool) {
for (i = 0; i < kCount; i++) { for (i = 0; i < kCount; i++) {
size_t offset; size_t offset;
EXPECT(pool.add(&c, 8, offset) == kErrorOk); EXPECT_EQ(pool.add(&c, 8, offset), kErrorOk);
EXPECT(offset == i * 8); EXPECT_EQ(offset, i * 8);
c++; c++;
} }
} }
@@ -283,8 +283,8 @@ UNIT(const_pool) {
uint32_t c = 0x01010101; uint32_t c = 0x01010101;
for (i = 0; i < kCount; i++) { for (i = 0; i < kCount; i++) {
size_t offset; size_t offset;
EXPECT(pool.add(&c, 4, offset) == kErrorOk); EXPECT_EQ(pool.add(&c, 4, offset), kErrorOk);
EXPECT(offset == i * 8); EXPECT_EQ(offset, i * 8);
c++; c++;
} }
} }
@@ -294,9 +294,9 @@ UNIT(const_pool) {
uint16_t c = 0xFFFF; uint16_t c = 0xFFFF;
size_t offset; size_t offset;
EXPECT(pool.add(&c, 2, offset) == kErrorOk); EXPECT_EQ(pool.add(&c, 2, offset), kErrorOk);
EXPECT(offset == kCount * 8); EXPECT_EQ(offset, kCount * 8);
EXPECT(pool.alignment() == 8); EXPECT_EQ(pool.alignment(), 8u);
} }
INFO("Adding 8 byte constant to check if pool gets aligned again"); INFO("Adding 8 byte constant to check if pool gets aligned again");
@@ -304,8 +304,8 @@ UNIT(const_pool) {
uint64_t c = 0xFFFFFFFFFFFFFFFFu; uint64_t c = 0xFFFFFFFFFFFFFFFFu;
size_t offset; size_t offset;
EXPECT(pool.add(&c, 8, offset) == kErrorOk); EXPECT_EQ(pool.add(&c, 8, offset), kErrorOk);
EXPECT(offset == kCount * 8 + 8); EXPECT_EQ(offset, kCount * 8 + 8u);
} }
INFO("Adding 2 byte constant to verify the gap is filled"); INFO("Adding 2 byte constant to verify the gap is filled");
@@ -313,9 +313,9 @@ UNIT(const_pool) {
uint16_t c = 0xFFFE; uint16_t c = 0xFFFE;
size_t offset; size_t offset;
EXPECT(pool.add(&c, 2, offset) == kErrorOk); EXPECT_EQ(pool.add(&c, 2, offset), kErrorOk);
EXPECT(offset == kCount * 8 + 2); EXPECT_EQ(offset, kCount * 8 + 2);
EXPECT(pool.alignment() == 8); EXPECT_EQ(pool.alignment(), 8u);
} }
INFO("Checking reset functionality"); INFO("Checking reset functionality");
@@ -323,8 +323,8 @@ UNIT(const_pool) {
pool.reset(&zone); pool.reset(&zone);
zone.reset(); zone.reset();
EXPECT(pool.size() == 0); EXPECT_EQ(pool.size(), 0u);
EXPECT(pool.alignment() == 0); EXPECT_EQ(pool.alignment(), 0u);
} }
INFO("Checking pool alignment when combined constants are added"); INFO("Checking pool alignment when combined constants are added");
@@ -333,29 +333,29 @@ UNIT(const_pool) {
size_t offset; size_t offset;
pool.add(bytes, 1, offset); pool.add(bytes, 1, offset);
EXPECT(pool.size() == 1); EXPECT_EQ(pool.size(), 1u);
EXPECT(pool.alignment() == 1); EXPECT_EQ(pool.alignment(), 1u);
EXPECT(offset == 0); EXPECT_EQ(offset, 0u);
pool.add(bytes, 2, offset); pool.add(bytes, 2, offset);
EXPECT(pool.size() == 4); EXPECT_EQ(pool.size(), 4u);
EXPECT(pool.alignment() == 2); EXPECT_EQ(pool.alignment(), 2u);
EXPECT(offset == 2); EXPECT_EQ(offset, 2u);
pool.add(bytes, 4, offset); pool.add(bytes, 4, offset);
EXPECT(pool.size() == 8); EXPECT_EQ(pool.size(), 8u);
EXPECT(pool.alignment() == 4); EXPECT_EQ(pool.alignment(), 4u);
EXPECT(offset == 4); EXPECT_EQ(offset, 4u);
pool.add(bytes, 4, offset); pool.add(bytes, 4, offset);
EXPECT(pool.size() == 8); EXPECT_EQ(pool.size(), 8u);
EXPECT(pool.alignment() == 4); EXPECT_EQ(pool.alignment(), 4u);
EXPECT(offset == 4); EXPECT_EQ(offset, 4u);
pool.add(bytes, 32, offset); pool.add(bytes, 32, offset);
EXPECT(pool.size() == 64); EXPECT_EQ(pool.size(), 64u);
EXPECT(pool.alignment() == 32); EXPECT_EQ(pool.alignment(), 32u);
EXPECT(offset == 32); EXPECT_EQ(offset, 32u);
} }
} }
#endif #endif

View File

@@ -1104,16 +1104,16 @@ public:
Record* record; Record* record;
record = _records.get(p); record = _records.get(p);
if (record) EXPECT_NULL(record)
EXPECT(record == nullptr, "Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size); .message("Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size);
record = _records.get(pEnd); record = _records.get(pEnd);
if (record) EXPECT_NULL(record)
EXPECT(record == nullptr, "Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size); .message("Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size);
uint64_t pattern = _rng.nextUInt64(); uint64_t pattern = _rng.nextUInt64();
record = _heap.newT<Record>(pRX, pRW, size, pattern); record = _heap.newT<Record>(pRX, pRW, size, pattern);
EXPECT(record != nullptr, "Out of memory, cannot allocate 'Record'"); EXPECT_NOT_NULL(record);
{ {
VirtMem::ProtectJitReadWriteScope scope(pRW, size); VirtMem::ProtectJitReadWriteScope scope(pRW, size);
@@ -1121,17 +1121,17 @@ public:
} }
VirtMem::flushInstructionCache(pRX, size); VirtMem::flushInstructionCache(pRX, size);
EXPECT(JitAllocatorUtils::verifyPattern64(pRX, pattern, size) == true); EXPECT_TRUE(JitAllocatorUtils::verifyPattern64(pRX, pattern, size));
_records.insert(record); _records.insert(record);
} }
void _remove(void* p) noexcept { void _remove(void* p) noexcept {
Record* record = _records.get(static_cast<uint8_t*>(p)); Record* record = _records.get(static_cast<uint8_t*>(p));
EXPECT(record != nullptr, "Address [%p] doesn't exist\n", p); EXPECT_NOT_NULL(record);
EXPECT(JitAllocatorUtils::verifyPattern64(record->rx(), record->pattern, record->size) == true); EXPECT_TRUE(JitAllocatorUtils::verifyPattern64(record->rx(), record->pattern, record->size));
EXPECT(JitAllocatorUtils::verifyPattern64(record->rw(), record->pattern, record->size) == true); EXPECT_TRUE(JitAllocatorUtils::verifyPattern64(record->rw(), record->pattern, record->size));
_records.remove(record); _records.remove(record);
_heap.release(record, sizeof(Record)); _heap.release(record, sizeof(Record));
@@ -1142,7 +1142,8 @@ public:
void* rwPtr; void* rwPtr;
Error err = _allocator.alloc(&rxPtr, &rwPtr, size); Error err = _allocator.alloc(&rxPtr, &rwPtr, size);
EXPECT(err == kErrorOk, "JitAllocator failed to allocate %zu bytes\n", size); EXPECT_EQ(err, kErrorOk)
.message("JitAllocator failed to allocate %zu bytes\n", size);
_insert(rxPtr, rwPtr, size); _insert(rxPtr, rwPtr, size);
return rxPtr; return rxPtr;
@@ -1150,18 +1151,20 @@ public:
void release(void* p) noexcept { void release(void* p) noexcept {
_remove(p); _remove(p);
EXPECT(_allocator.release(p) == kErrorOk, "JitAllocator failed to release '%p'\n", p); EXPECT_EQ(_allocator.release(p), kErrorOk)
.message("JitAllocator failed to release '%p'\n", p);
} }
void shrink(void* p, size_t newSize) noexcept { void shrink(void* p, size_t newSize) noexcept {
Record* record = _records.get(static_cast<uint8_t*>(p)); Record* record = _records.get(static_cast<uint8_t*>(p));
EXPECT(record != nullptr, "Address [%p] doesn't exist\n", p); EXPECT_NOT_NULL(record);
if (!newSize) if (!newSize)
return release(p); return release(p);
Error err = _allocator.shrink(p, newSize); Error err = _allocator.shrink(p, newSize);
EXPECT(err == kErrorOk, "JitAllocator failed to shrink %p to %zu bytes\n", p, newSize); EXPECT_EQ(err, kErrorOk)
.message("JitAllocator failed to shrink %p to %zu bytes\n", p, newSize);
record->size = newSize; record->size = newSize;
} }
@@ -1203,7 +1206,8 @@ static void BitVectorRangeIterator_testRandom(Random& rnd, size_t count) noexcep
} }
for (size_t j = 0; j < kPatternSize; j++) { for (size_t j = 0; j < kPatternSize; j++) {
EXPECT(in[j] == out[j], "Invalid pattern detected at [%zu] (%llX != %llX)", j, (unsigned long long)in[j], (unsigned long long)out[j]); EXPECT_EQ(in[j], out[j])
.message("Invalid pattern detected at [%zu] (%llX != %llX)", j, (unsigned long long)in[j], (unsigned long long)out[j]);
} }
} }
} }
@@ -1259,8 +1263,7 @@ static void test_jit_allocator_alloc_release() noexcept {
INFO(" Memory alloc/release test - %d allocations", kCount); INFO(" Memory alloc/release test - %d allocations", kCount);
void** ptrArray = (void**)::malloc(sizeof(void*) * size_t(kCount)); void** ptrArray = (void**)::malloc(sizeof(void*) * size_t(kCount));
EXPECT(ptrArray != nullptr, EXPECT_NOT_NULL(ptrArray);
"Couldn't allocate '%u' bytes for pointer-array", unsigned(sizeof(void*) * size_t(kCount)));
// Random blocks tests... // Random blocks tests...
INFO(" Allocating random blocks..."); INFO(" Allocating random blocks...");
@@ -1351,18 +1354,18 @@ static void test_jit_allocator_query() noexcept {
void* rwPtr = nullptr; void* rwPtr = nullptr;
size_t size = 100; size_t size = 100;
EXPECT(allocator.alloc(&rxPtr, &rwPtr, size) == kErrorOk); EXPECT_EQ(allocator.alloc(&rxPtr, &rwPtr, size), kErrorOk);
EXPECT(rxPtr != nullptr); EXPECT_NOT_NULL(rxPtr);
EXPECT(rwPtr != nullptr); EXPECT_NOT_NULL(rwPtr);
void* rxPtrQueried = nullptr; void* rxPtrQueried = nullptr;
void* rwPtrQueried = nullptr; void* rwPtrQueried = nullptr;
size_t sizeQueried; size_t sizeQueried;
EXPECT(allocator.query(rxPtr, &rxPtrQueried, &rwPtrQueried, &sizeQueried) == kErrorOk); EXPECT_EQ(allocator.query(rxPtr, &rxPtrQueried, &rwPtrQueried, &sizeQueried), kErrorOk);
EXPECT(rxPtrQueried == rxPtr); EXPECT_EQ(rxPtrQueried, rxPtr);
EXPECT(rwPtrQueried == rwPtr); EXPECT_EQ(rwPtrQueried, rwPtr);
EXPECT(sizeQueried == Support::alignUp(size, allocator.granularity())); EXPECT_EQ(sizeQueried, Support::alignUp(size, allocator.granularity()));
} }
UNIT(jit_allocator) { UNIT(jit_allocator) {

View File

@@ -19,36 +19,36 @@ enum class StrongEnumForImmTests : uint32_t {
UNIT(operand) { UNIT(operand) {
INFO("Checking operand sizes"); INFO("Checking operand sizes");
EXPECT(sizeof(Operand) == 16); EXPECT_EQ(sizeof(Operand), 16u);
EXPECT(sizeof(BaseReg) == 16); EXPECT_EQ(sizeof(BaseReg), 16u);
EXPECT(sizeof(BaseMem) == 16); EXPECT_EQ(sizeof(BaseMem), 16u);
EXPECT(sizeof(Imm) == 16); EXPECT_EQ(sizeof(Imm), 16u);
EXPECT(sizeof(Label) == 16); EXPECT_EQ(sizeof(Label), 16u);
INFO("Checking basic functionality of Operand"); INFO("Checking basic functionality of Operand");
Operand a, b; Operand a, b;
Operand dummy; Operand dummy;
EXPECT(a.isNone() == true); EXPECT_TRUE(a.isNone());
EXPECT(a.isReg() == false); EXPECT_FALSE(a.isReg());
EXPECT(a.isMem() == false); EXPECT_FALSE(a.isMem());
EXPECT(a.isImm() == false); EXPECT_FALSE(a.isImm());
EXPECT(a.isLabel() == false); EXPECT_FALSE(a.isLabel());
EXPECT(a == b); EXPECT_EQ(a, b);
EXPECT(a._data[0] == 0); EXPECT_EQ(a._data[0], 0u);
EXPECT(a._data[1] == 0); EXPECT_EQ(a._data[1], 0u);
INFO("Checking basic functionality of Label"); INFO("Checking basic functionality of Label");
Label label; Label label;
EXPECT(label.isValid() == false); EXPECT_FALSE(label.isValid());
EXPECT(label.id() == Globals::kInvalidId); EXPECT_EQ(label.id(), Globals::kInvalidId);
INFO("Checking basic functionality of BaseReg"); INFO("Checking basic functionality of BaseReg");
EXPECT(BaseReg().isReg() == true); EXPECT_TRUE(BaseReg().isReg());
EXPECT(BaseReg().isValid() == false); EXPECT_FALSE(BaseReg().isValid());
EXPECT(BaseReg()._data[0] == 0); EXPECT_EQ(BaseReg()._data[0], 0u);
EXPECT(BaseReg()._data[1] == 0); EXPECT_EQ(BaseReg()._data[1], 0u);
EXPECT(dummy.as<BaseReg>().isValid() == false); EXPECT_FALSE(dummy.as<BaseReg>().isValid());
// Create some register (not specific to any architecture). // Create some register (not specific to any architecture).
OperandSignature rSig = OperandSignature::fromOpType(OperandType::kReg) | OperandSignature rSig = OperandSignature::fromOpType(OperandType::kReg) |
@@ -57,75 +57,75 @@ UNIT(operand) {
OperandSignature::fromSize(8); OperandSignature::fromSize(8);
BaseReg r1(rSig, 5); BaseReg r1(rSig, 5);
EXPECT(r1.isValid() == true); EXPECT_TRUE(r1.isValid());
EXPECT(r1.isReg() == true); EXPECT_TRUE(r1.isReg());
EXPECT(r1.isReg(RegType::kVec128) == true); EXPECT_TRUE(r1.isReg(RegType::kVec128));
EXPECT(r1.isPhysReg() == true); EXPECT_TRUE(r1.isPhysReg());
EXPECT(r1.isVirtReg() == false); EXPECT_FALSE(r1.isVirtReg());
EXPECT(r1.signature() == rSig); EXPECT_EQ(r1.signature(), rSig);
EXPECT(r1.type() == RegType::kVec128); EXPECT_EQ(r1.type(), RegType::kVec128);
EXPECT(r1.group() == RegGroup::kVec); EXPECT_EQ(r1.group(), RegGroup::kVec);
EXPECT(r1.size() == 8); EXPECT_EQ(r1.size(), 8u);
EXPECT(r1.id() == 5); EXPECT_EQ(r1.id(), 5u);
EXPECT(r1.isReg(RegType::kVec128, 5) == true); // RegType and Id. EXPECT_TRUE(r1.isReg(RegType::kVec128, 5)); // RegType and Id.
EXPECT(r1._data[0] == 0); EXPECT_EQ(r1._data[0], 0u);
EXPECT(r1._data[1] == 0); EXPECT_EQ(r1._data[1], 0u);
// The same type of register having different id. // The same type of register having different id.
BaseReg r2(r1, 6); BaseReg r2(r1, 6);
EXPECT(r2.isValid() == true); EXPECT_TRUE(r2.isValid());
EXPECT(r2.isReg() == true); EXPECT_TRUE(r2.isReg());
EXPECT(r2.isReg(RegType::kVec128) == true); EXPECT_TRUE(r2.isReg(RegType::kVec128));
EXPECT(r2.isPhysReg() == true); EXPECT_TRUE(r2.isPhysReg());
EXPECT(r2.isVirtReg() == false); EXPECT_FALSE(r2.isVirtReg());
EXPECT(r2.signature() == rSig); EXPECT_EQ(r2.signature(), rSig);
EXPECT(r2.type() == r1.type()); EXPECT_EQ(r2.type(), r1.type());
EXPECT(r2.group() == r1.group()); EXPECT_EQ(r2.group(), r1.group());
EXPECT(r2.size() == r1.size()); EXPECT_EQ(r2.size(), r1.size());
EXPECT(r2.id() == 6); EXPECT_EQ(r2.id(), 6u);
EXPECT(r2.isReg(RegType::kVec128, 6) == true); EXPECT_TRUE(r2.isReg(RegType::kVec128, 6));
r1.reset(); r1.reset();
EXPECT(!r1.isReg()); EXPECT_FALSE(r1.isReg());
EXPECT(!r1.isValid()); EXPECT_FALSE(r1.isValid());
INFO("Checking basic functionality of BaseMem"); INFO("Checking basic functionality of BaseMem");
BaseMem m; BaseMem m;
EXPECT(m.isMem()); EXPECT_TRUE(m.isMem());
EXPECT(m == BaseMem()); EXPECT_EQ(m, BaseMem());
EXPECT(m.hasBase() == false); EXPECT_FALSE(m.hasBase());
EXPECT(m.hasIndex() == false); EXPECT_FALSE(m.hasIndex());
EXPECT(m.hasOffset() == false); EXPECT_FALSE(m.hasOffset());
EXPECT(m.isOffset64Bit() == true); EXPECT_TRUE(m.isOffset64Bit());
EXPECT(m.offset() == 0); EXPECT_EQ(m.offset(), 0);
m.setOffset(-1); m.setOffset(-1);
EXPECT(m.offsetLo32() == -1); EXPECT_EQ(m.offsetLo32(), -1);
EXPECT(m.offset() == -1); EXPECT_EQ(m.offset(), -1);
int64_t x = int64_t(0xFF00FF0000000001u); int64_t x = int64_t(0xFF00FF0000000001u);
int32_t xHi = int32_t(0xFF00FF00u); int32_t xHi = int32_t(0xFF00FF00u);
m.setOffset(x); m.setOffset(x);
EXPECT(m.offset() == x); EXPECT_EQ(m.offset(), x);
EXPECT(m.offsetLo32() == 1); EXPECT_EQ(m.offsetLo32(), 1);
EXPECT(m.offsetHi32() == xHi); EXPECT_EQ(m.offsetHi32(), xHi);
INFO("Checking basic functionality of Imm"); INFO("Checking basic functionality of Imm");
Imm immValue(-42); Imm immValue(-42);
EXPECT(immValue.type() == ImmType::kInt); EXPECT_EQ(immValue.type(), ImmType::kInt);
EXPECT(Imm(-1).value() == -1); EXPECT_EQ(Imm(-1).value(), -1);
EXPECT(imm(-1).value() == -1); EXPECT_EQ(imm(-1).value(), -1);
EXPECT(immValue.value() == -42); EXPECT_EQ(immValue.value(), -42);
EXPECT(imm(0xFFFFFFFF).value() == int64_t(0xFFFFFFFF)); EXPECT_EQ(imm(0xFFFFFFFF).value(), int64_t(0xFFFFFFFF));
Imm immDouble(0.4); Imm immDouble(0.4);
EXPECT(immDouble.type() == ImmType::kDouble); EXPECT_EQ(immDouble.type(), ImmType::kDouble);
EXPECT(immDouble.valueAs<double>() == 0.4); EXPECT_EQ(immDouble.valueAs<double>(), 0.4);
EXPECT(immDouble == imm(0.4)); EXPECT_EQ(immDouble, imm(0.4));
EXPECT(Imm(StrongEnumForImmTests::kValue0).value() == 0); EXPECT_EQ(Imm(StrongEnumForImmTests::kValue0).value(), 0);
EXPECT(Imm(StrongEnumForImmTests::kValue0xFFFFFFFF).value() == 0xFFFFFFFFu); EXPECT_EQ(Imm(StrongEnumForImmTests::kValue0xFFFFFFFF).value(), 0xFFFFFFFFu);
} }
#endif #endif

View File

@@ -491,68 +491,68 @@ bool String::eq(const char* other, size_t size) const noexcept {
UNIT(core_string) { UNIT(core_string) {
String s; String s;
EXPECT(s.isLargeOrExternal() == false); EXPECT_FALSE(s.isLargeOrExternal());
EXPECT(s.isExternal() == false); EXPECT_FALSE(s.isExternal());
EXPECT(s.assign('a') == kErrorOk); EXPECT_EQ(s.assign('a'), kErrorOk);
EXPECT(s.size() == 1); EXPECT_EQ(s.size(), 1u);
EXPECT(s.capacity() == String::kSSOCapacity); EXPECT_EQ(s.capacity(), String::kSSOCapacity);
EXPECT(s.data()[0] == 'a'); EXPECT_EQ(s.data()[0], 'a');
EXPECT(s.data()[1] == '\0'); EXPECT_EQ(s.data()[1], '\0');
EXPECT(s.eq("a") == true); EXPECT_TRUE(s.eq("a"));
EXPECT(s.eq("a", 1) == true); EXPECT_TRUE(s.eq("a", 1));
EXPECT(s.assignChars('b', 4) == kErrorOk); EXPECT_EQ(s.assignChars('b', 4), kErrorOk);
EXPECT(s.size() == 4); EXPECT_EQ(s.size(), 4u);
EXPECT(s.capacity() == String::kSSOCapacity); EXPECT_EQ(s.capacity(), String::kSSOCapacity);
EXPECT(s.data()[0] == 'b'); EXPECT_EQ(s.data()[0], 'b');
EXPECT(s.data()[1] == 'b'); EXPECT_EQ(s.data()[1], 'b');
EXPECT(s.data()[2] == 'b'); EXPECT_EQ(s.data()[2], 'b');
EXPECT(s.data()[3] == 'b'); EXPECT_EQ(s.data()[3], 'b');
EXPECT(s.data()[4] == '\0'); EXPECT_EQ(s.data()[4], '\0');
EXPECT(s.eq("bbbb") == true); EXPECT_TRUE(s.eq("bbbb"));
EXPECT(s.eq("bbbb", 4) == true); EXPECT_TRUE(s.eq("bbbb", 4));
EXPECT(s.assign("abc") == kErrorOk); EXPECT_EQ(s.assign("abc"), kErrorOk);
EXPECT(s.size() == 3); EXPECT_EQ(s.size(), 3u);
EXPECT(s.capacity() == String::kSSOCapacity); EXPECT_EQ(s.capacity(), String::kSSOCapacity);
EXPECT(s.data()[0] == 'a'); EXPECT_EQ(s.data()[0], 'a');
EXPECT(s.data()[1] == 'b'); EXPECT_EQ(s.data()[1], 'b');
EXPECT(s.data()[2] == 'c'); EXPECT_EQ(s.data()[2], 'c');
EXPECT(s.data()[3] == '\0'); EXPECT_EQ(s.data()[3], '\0');
EXPECT(s.eq("abc") == true); EXPECT_TRUE(s.eq("abc"));
EXPECT(s.eq("abc", 3) == true); EXPECT_TRUE(s.eq("abc", 3));
const char* large = "Large string that will not fit into SSO buffer"; const char* large = "Large string that will not fit into SSO buffer";
EXPECT(s.assign(large) == kErrorOk); EXPECT_EQ(s.assign(large), kErrorOk);
EXPECT(s.isLargeOrExternal() == true); EXPECT_TRUE(s.isLargeOrExternal());
EXPECT(s.size() == strlen(large)); EXPECT_EQ(s.size(), strlen(large));
EXPECT(s.capacity() > String::kSSOCapacity); EXPECT_GT(s.capacity(), String::kSSOCapacity);
EXPECT(s.eq(large) == true); EXPECT_TRUE(s.eq(large));
EXPECT(s.eq(large, strlen(large)) == true); EXPECT_TRUE(s.eq(large, strlen(large)));
const char* additional = " (additional content)"; const char* additional = " (additional content)";
EXPECT(s.isLargeOrExternal() == true); EXPECT_TRUE(s.isLargeOrExternal());
EXPECT(s.append(additional) == kErrorOk); EXPECT_EQ(s.append(additional), kErrorOk);
EXPECT(s.size() == strlen(large) + strlen(additional)); EXPECT_EQ(s.size(), strlen(large) + strlen(additional));
EXPECT(s.clear() == kErrorOk); EXPECT_EQ(s.clear(), kErrorOk);
EXPECT(s.size() == 0); EXPECT_EQ(s.size(), 0u);
EXPECT(s.empty() == true); EXPECT_TRUE(s.empty());
EXPECT(s.data()[0] == '\0'); EXPECT_EQ(s.data()[0], '\0');
EXPECT(s.isLargeOrExternal() == true); // Clear should never release the memory. EXPECT_TRUE(s.isLargeOrExternal()); // Clear should never release the memory.
EXPECT(s.appendUInt(1234) == kErrorOk); EXPECT_EQ(s.appendUInt(1234), kErrorOk);
EXPECT(s.eq("1234") == true); EXPECT_TRUE(s.eq("1234"));
EXPECT(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate) == kErrorOk); EXPECT_EQ(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate), kErrorOk);
EXPECT(s.eq("0xFFFF")); EXPECT_TRUE(s.eq("0xFFFF"));
StringTmp<64> sTmp; StringTmp<64> sTmp;
EXPECT(sTmp.isLargeOrExternal()); EXPECT_TRUE(sTmp.isLargeOrExternal());
EXPECT(sTmp.isExternal()); EXPECT_TRUE(sTmp.isExternal());
EXPECT(sTmp.appendChars(' ', 1000) == kErrorOk); EXPECT_EQ(sTmp.appendChars(' ', 1000), kErrorOk);
EXPECT(!sTmp.isExternal()); EXPECT_FALSE(sTmp.isExternal());
} }
#endif #endif

View File

@@ -15,74 +15,76 @@ ASMJIT_BEGIN_NAMESPACE
template<typename T> template<typename T>
static void testArrays(const T* a, const T* b, size_t size) noexcept { static void testArrays(const T* a, const T* b, size_t size) noexcept {
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
EXPECT(a[i] == b[i], "Mismatch at %u", unsigned(i)); EXPECT_EQ(a[i], b[i])
.message("Mismatch at %u", unsigned(i));
} }
static void testAlignment() noexcept { static void testAlignment() noexcept {
INFO("Support::isAligned()"); INFO("Support::isAligned()");
EXPECT(Support::isAligned<size_t>(0xFFFF, 4) == false); EXPECT_FALSE(Support::isAligned<size_t>(0xFFFF, 4u));
EXPECT(Support::isAligned<size_t>(0xFFF4, 4) == true); EXPECT_TRUE(Support::isAligned<size_t>(0xFFF4, 4u));
EXPECT(Support::isAligned<size_t>(0xFFF8, 8) == true); EXPECT_TRUE(Support::isAligned<size_t>(0xFFF8, 8u));
EXPECT(Support::isAligned<size_t>(0xFFF0, 16) == true); EXPECT_TRUE(Support::isAligned<size_t>(0xFFF0, 16u));
INFO("Support::alignUp()"); INFO("Support::alignUp()");
EXPECT(Support::alignUp<size_t>(0xFFFF, 4) == 0x10000); EXPECT_EQ(Support::alignUp<size_t>(0xFFFF, 4), 0x10000u);
EXPECT(Support::alignUp<size_t>(0xFFF4, 4) == 0x0FFF4); EXPECT_EQ(Support::alignUp<size_t>(0xFFF4, 4), 0x0FFF4u);
EXPECT(Support::alignUp<size_t>(0xFFF8, 8) == 0x0FFF8); EXPECT_EQ(Support::alignUp<size_t>(0xFFF8, 8), 0x0FFF8u);
EXPECT(Support::alignUp<size_t>(0xFFF0, 16) == 0x0FFF0); EXPECT_EQ(Support::alignUp<size_t>(0xFFF0, 16), 0x0FFF0u);
EXPECT(Support::alignUp<size_t>(0xFFF0, 32) == 0x10000); EXPECT_EQ(Support::alignUp<size_t>(0xFFF0, 32), 0x10000u);
INFO("Support::alignUpDiff()"); INFO("Support::alignUpDiff()");
EXPECT(Support::alignUpDiff<size_t>(0xFFFF, 4) == 1); EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFFF, 4), 1u);
EXPECT(Support::alignUpDiff<size_t>(0xFFF4, 4) == 0); EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF4, 4), 0u);
EXPECT(Support::alignUpDiff<size_t>(0xFFF8, 8) == 0); EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF8, 8), 0u);
EXPECT(Support::alignUpDiff<size_t>(0xFFF0, 16) == 0); EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF0, 16), 0u);
EXPECT(Support::alignUpDiff<size_t>(0xFFF0, 32) == 16); EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF0, 32), 16u);
INFO("Support::alignUpPowerOf2()"); INFO("Support::alignUpPowerOf2()");
EXPECT(Support::alignUpPowerOf2<size_t>(0x0000) == 0x00000); EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x0000), 0x00000u);
EXPECT(Support::alignUpPowerOf2<size_t>(0xFFFF) == 0x10000); EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0xFFFF), 0x10000u);
EXPECT(Support::alignUpPowerOf2<size_t>(0xF123) == 0x10000); EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0xF123), 0x10000u);
EXPECT(Support::alignUpPowerOf2<size_t>(0x0F00) == 0x01000); EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x0F00), 0x01000u);
EXPECT(Support::alignUpPowerOf2<size_t>(0x0100) == 0x00100); EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x0100), 0x00100u);
EXPECT(Support::alignUpPowerOf2<size_t>(0x1001) == 0x02000); EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x1001), 0x02000u);
} }
static void testBitUtils() noexcept { static void testBitUtils() noexcept {
uint32_t i; uint32_t i;
INFO("Support::shl() / shr()"); INFO("Support::shl() / shr()");
EXPECT(Support::shl(int32_t(0x00001111), 16) == int32_t(0x11110000u)); EXPECT_EQ(Support::shl(int32_t(0x00001111), 16), int32_t(0x11110000u));
EXPECT(Support::shl(uint32_t(0x00001111), 16) == uint32_t(0x11110000u)); EXPECT_EQ(Support::shl(uint32_t(0x00001111), 16), uint32_t(0x11110000u));
EXPECT(Support::shr(int32_t(0x11110000u), 16) == int32_t(0x00001111u)); EXPECT_EQ(Support::shr(int32_t(0x11110000u), 16), int32_t(0x00001111u));
EXPECT(Support::shr(uint32_t(0x11110000u), 16) == uint32_t(0x00001111u)); EXPECT_EQ(Support::shr(uint32_t(0x11110000u), 16), uint32_t(0x00001111u));
EXPECT(Support::sar(int32_t(0xFFFF0000u), 16) == int32_t(0xFFFFFFFFu)); EXPECT_EQ(Support::sar(int32_t(0xFFFF0000u), 16), int32_t(0xFFFFFFFFu));
EXPECT(Support::sar(uint32_t(0xFFFF0000u), 16) == uint32_t(0xFFFFFFFFu)); EXPECT_EQ(Support::sar(uint32_t(0xFFFF0000u), 16), uint32_t(0xFFFFFFFFu));
INFO("Support::blsi()"); INFO("Support::blsi()");
for (i = 0; i < 32; i++) EXPECT(Support::blsi(uint32_t(1) << i) == uint32_t(1) << i); for (i = 0; i < 32; i++) EXPECT_EQ(Support::blsi(uint32_t(1) << i), uint32_t(1) << i);
for (i = 0; i < 31; i++) EXPECT(Support::blsi(uint32_t(3) << i) == uint32_t(1) << i); for (i = 0; i < 31; i++) EXPECT_EQ(Support::blsi(uint32_t(3) << i), uint32_t(1) << i);
for (i = 0; i < 64; i++) EXPECT(Support::blsi(uint64_t(1) << i) == uint64_t(1) << i); for (i = 0; i < 64; i++) EXPECT_EQ(Support::blsi(uint64_t(1) << i), uint64_t(1) << i);
for (i = 0; i < 63; i++) EXPECT(Support::blsi(uint64_t(3) << i) == uint64_t(1) << i); for (i = 0; i < 63; i++) EXPECT_EQ(Support::blsi(uint64_t(3) << i), uint64_t(1) << i);
INFO("Support::ctz()"); INFO("Support::ctz()");
for (i = 0; i < 32; i++) EXPECT(Support::Internal::clzFallback(uint32_t(1) << i) == 31 - i); for (i = 0; i < 32; i++) EXPECT_EQ(Support::Internal::clzFallback(uint32_t(1) << i), 31 - i);
for (i = 0; i < 64; i++) EXPECT(Support::Internal::clzFallback(uint64_t(1) << i) == 63 - i); for (i = 0; i < 64; i++) EXPECT_EQ(Support::Internal::clzFallback(uint64_t(1) << i), 63 - i);
for (i = 0; i < 32; i++) EXPECT(Support::Internal::ctzFallback(uint32_t(1) << i) == i); for (i = 0; i < 32; i++) EXPECT_EQ(Support::Internal::ctzFallback(uint32_t(1) << i), i);
for (i = 0; i < 64; i++) EXPECT(Support::Internal::ctzFallback(uint64_t(1) << i) == i); for (i = 0; i < 64; i++) EXPECT_EQ(Support::Internal::ctzFallback(uint64_t(1) << i), i);
for (i = 0; i < 32; i++) EXPECT(Support::clz(uint32_t(1) << i) == 31 - i); for (i = 0; i < 32; i++) EXPECT_EQ(Support::clz(uint32_t(1) << i), 31 - i);
for (i = 0; i < 64; i++) EXPECT(Support::clz(uint64_t(1) << i) == 63 - i); for (i = 0; i < 64; i++) EXPECT_EQ(Support::clz(uint64_t(1) << i), 63 - i);
for (i = 0; i < 32; i++) EXPECT(Support::ctz(uint32_t(1) << i) == i); for (i = 0; i < 32; i++) EXPECT_EQ(Support::ctz(uint32_t(1) << i), i);
for (i = 0; i < 64; i++) EXPECT(Support::ctz(uint64_t(1) << i) == i); for (i = 0; i < 64; i++) EXPECT_EQ(Support::ctz(uint64_t(1) << i), i);
INFO("Support::bitMask()"); INFO("Support::bitMask()");
EXPECT(Support::bitMask(0, 1, 7) == 0x83u); EXPECT_EQ(Support::bitMask(0, 1, 7), 0x83u);
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
EXPECT(Support::bitMask(i) == (1u << i)); EXPECT_EQ(Support::bitMask(i), (1u << i));
INFO("Support::bitTest()"); INFO("Support::bitTest()");
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
EXPECT(Support::bitTest((1 << i), i) == true, "Support::bitTest(%X, %u) should return true", (1 << i), i); EXPECT_TRUE(Support::bitTest((1 << i), i))
.message("Support::bitTest(%X, %u) should return true", (1 << i), i);
} }
INFO("Support::lsbMask<uint32_t>()"); INFO("Support::lsbMask<uint32_t>()");
@@ -90,7 +92,7 @@ static void testBitUtils() noexcept {
uint32_t expectedBits = 0; uint32_t expectedBits = 0;
for (uint32_t b = 0; b < i; b++) for (uint32_t b = 0; b < i; b++)
expectedBits |= uint32_t(1) << b; expectedBits |= uint32_t(1) << b;
EXPECT(Support::lsbMask<uint32_t>(i) == expectedBits); EXPECT_EQ(Support::lsbMask<uint32_t>(i), expectedBits);
} }
INFO("Support::lsbMask<uint64_t>()"); INFO("Support::lsbMask<uint64_t>()");
@@ -98,31 +100,31 @@ static void testBitUtils() noexcept {
uint64_t expectedBits = 0; uint64_t expectedBits = 0;
for (uint32_t b = 0; b < i; b++) for (uint32_t b = 0; b < i; b++)
expectedBits |= uint64_t(1) << b; expectedBits |= uint64_t(1) << b;
EXPECT(Support::lsbMask<uint64_t>(i) == expectedBits); EXPECT_EQ(Support::lsbMask<uint64_t>(i), expectedBits);
} }
INFO("Support::popcnt()"); INFO("Support::popcnt()");
for (i = 0; i < 32; i++) EXPECT(Support::popcnt((uint32_t(1) << i)) == 1); for (i = 0; i < 32; i++) EXPECT_EQ(Support::popcnt((uint32_t(1) << i)), 1u);
for (i = 0; i < 64; i++) EXPECT(Support::popcnt((uint64_t(1) << i)) == 1); for (i = 0; i < 64; i++) EXPECT_EQ(Support::popcnt((uint64_t(1) << i)), 1u);
EXPECT(Support::popcnt(0x000000F0) == 4); EXPECT_EQ(Support::popcnt(0x000000F0), 4u);
EXPECT(Support::popcnt(0x10101010) == 4); EXPECT_EQ(Support::popcnt(0x10101010), 4u);
EXPECT(Support::popcnt(0xFF000000) == 8); EXPECT_EQ(Support::popcnt(0xFF000000), 8u);
EXPECT(Support::popcnt(0xFFFFFFF7) == 31); EXPECT_EQ(Support::popcnt(0xFFFFFFF7), 31u);
EXPECT(Support::popcnt(0x7FFFFFFF) == 31); EXPECT_EQ(Support::popcnt(0x7FFFFFFF), 31u);
INFO("Support::isPowerOf2()"); INFO("Support::isPowerOf2()");
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
EXPECT(Support::isPowerOf2(uint64_t(1) << i) == true); EXPECT_TRUE(Support::isPowerOf2(uint64_t(1) << i));
EXPECT(Support::isPowerOf2((uint64_t(1) << i) ^ 0x001101) == false); EXPECT_FALSE(Support::isPowerOf2((uint64_t(1) << i) ^ 0x001101));
} }
} }
static void testIntUtils() noexcept { static void testIntUtils() noexcept {
INFO("Support::byteswap()"); INFO("Support::byteswap()");
EXPECT(Support::byteswap16(int32_t(0x0102)) == int32_t(0x0201)); EXPECT_EQ(Support::byteswap16(0x0102), 0x0201u);
EXPECT(Support::byteswap32(int32_t(0x01020304)) == int32_t(0x04030201)); EXPECT_EQ(Support::byteswap32(0x01020304), 0x04030201u);
EXPECT(Support::byteswap32(uint32_t(0x01020304)) == uint32_t(0x04030201)); EXPECT_EQ(Support::byteswap32(0x01020304), 0x04030201u);
EXPECT(Support::byteswap64(uint64_t(0x0102030405060708)) == uint64_t(0x0807060504030201)); EXPECT_EQ(Support::byteswap64(uint64_t(0x0102030405060708)), uint64_t(0x0807060504030201));
INFO("Support::bytepack()"); INFO("Support::bytepack()");
union BytePackData { union BytePackData {
@@ -131,60 +133,60 @@ static void testIntUtils() noexcept {
} bpdata; } bpdata;
bpdata.u32 = Support::bytepack32_4x8(0x00, 0x11, 0x22, 0x33); bpdata.u32 = Support::bytepack32_4x8(0x00, 0x11, 0x22, 0x33);
EXPECT(bpdata.bytes[0] == 0x00); EXPECT_EQ(bpdata.bytes[0], 0x00);
EXPECT(bpdata.bytes[1] == 0x11); EXPECT_EQ(bpdata.bytes[1], 0x11);
EXPECT(bpdata.bytes[2] == 0x22); EXPECT_EQ(bpdata.bytes[2], 0x22);
EXPECT(bpdata.bytes[3] == 0x33); EXPECT_EQ(bpdata.bytes[3], 0x33);
INFO("Support::isBetween()"); INFO("Support::isBetween()");
EXPECT(Support::isBetween<int>(10 , 10, 20) == true); EXPECT_TRUE(Support::isBetween<int>(10 , 10, 20));
EXPECT(Support::isBetween<int>(11 , 10, 20) == true); EXPECT_TRUE(Support::isBetween<int>(11 , 10, 20));
EXPECT(Support::isBetween<int>(20 , 10, 20) == true); EXPECT_TRUE(Support::isBetween<int>(20 , 10, 20));
EXPECT(Support::isBetween<int>(9 , 10, 20) == false); EXPECT_FALSE(Support::isBetween<int>(9 , 10, 20));
EXPECT(Support::isBetween<int>(21 , 10, 20) == false); EXPECT_FALSE(Support::isBetween<int>(21 , 10, 20));
EXPECT(Support::isBetween<int>(101, 10, 20) == false); EXPECT_FALSE(Support::isBetween<int>(101, 10, 20));
INFO("Support::isInt8()"); INFO("Support::isInt8()");
EXPECT(Support::isInt8(-128) == true); EXPECT_TRUE(Support::isInt8(-128));
EXPECT(Support::isInt8( 127) == true); EXPECT_TRUE(Support::isInt8( 127));
EXPECT(Support::isInt8(-129) == false); EXPECT_FALSE(Support::isInt8(-129));
EXPECT(Support::isInt8( 128) == false); EXPECT_FALSE(Support::isInt8( 128));
INFO("Support::isInt16()"); INFO("Support::isInt16()");
EXPECT(Support::isInt16(-32768) == true); EXPECT_TRUE(Support::isInt16(-32768));
EXPECT(Support::isInt16( 32767) == true); EXPECT_TRUE(Support::isInt16( 32767));
EXPECT(Support::isInt16(-32769) == false); EXPECT_FALSE(Support::isInt16(-32769));
EXPECT(Support::isInt16( 32768) == false); EXPECT_FALSE(Support::isInt16( 32768));
INFO("Support::isInt32()"); INFO("Support::isInt32()");
EXPECT(Support::isInt32( 2147483647 ) == true); EXPECT_TRUE(Support::isInt32( 2147483647 ));
EXPECT(Support::isInt32(-2147483647 - 1) == true); EXPECT_TRUE(Support::isInt32(-2147483647 - 1));
EXPECT(Support::isInt32(uint64_t(2147483648u)) == false); EXPECT_FALSE(Support::isInt32(uint64_t(2147483648u)));
EXPECT(Support::isInt32(uint64_t(0xFFFFFFFFu)) == false); EXPECT_FALSE(Support::isInt32(uint64_t(0xFFFFFFFFu)));
EXPECT(Support::isInt32(uint64_t(0xFFFFFFFFu) + 1) == false); EXPECT_FALSE(Support::isInt32(uint64_t(0xFFFFFFFFu) + 1));
INFO("Support::isUInt8()"); INFO("Support::isUInt8()");
EXPECT(Support::isUInt8(0) == true); EXPECT_TRUE(Support::isUInt8(0) );
EXPECT(Support::isUInt8(255) == true); EXPECT_TRUE(Support::isUInt8(255));
EXPECT(Support::isUInt8(256) == false); EXPECT_FALSE(Support::isUInt8(256));
EXPECT(Support::isUInt8(-1) == false); EXPECT_FALSE(Support::isUInt8(-1) );
INFO("Support::isUInt12()"); INFO("Support::isUInt12()");
EXPECT(Support::isUInt12(0) == true); EXPECT_TRUE(Support::isUInt12(0) );
EXPECT(Support::isUInt12(4095) == true); EXPECT_TRUE(Support::isUInt12(4095));
EXPECT(Support::isUInt12(4096) == false); EXPECT_FALSE(Support::isUInt12(4096));
EXPECT(Support::isUInt12(-1) == false); EXPECT_FALSE(Support::isUInt12(-1) );
INFO("Support::isUInt16()"); INFO("Support::isUInt16()");
EXPECT(Support::isUInt16(0) == true); EXPECT_TRUE(Support::isUInt16(0) );
EXPECT(Support::isUInt16(65535) == true); EXPECT_TRUE(Support::isUInt16(65535));
EXPECT(Support::isUInt16(65536) == false); EXPECT_FALSE(Support::isUInt16(65536));
EXPECT(Support::isUInt16(-1) == false); EXPECT_FALSE(Support::isUInt16(-1) );
INFO("Support::isUInt32()"); INFO("Support::isUInt32()");
EXPECT(Support::isUInt32(uint64_t(0xFFFFFFFF)) == true); EXPECT_TRUE(Support::isUInt32(uint64_t(0xFFFFFFFF)));
EXPECT(Support::isUInt32(uint64_t(0xFFFFFFFF) + 1) == false); EXPECT_FALSE(Support::isUInt32(uint64_t(0xFFFFFFFF) + 1));
EXPECT(Support::isUInt32(-1) == false); EXPECT_FALSE(Support::isUInt32(-1));
} }
static void testReadWrite() noexcept { static void testReadWrite() noexcept {
@@ -194,17 +196,17 @@ static void testReadWrite() noexcept {
Support::writeU16uBE(arr + 1, 0x0102u); Support::writeU16uBE(arr + 1, 0x0102u);
Support::writeU16uBE(arr + 3, 0x0304u); Support::writeU16uBE(arr + 3, 0x0304u);
EXPECT(Support::readU32uBE(arr + 1) == 0x01020304u); EXPECT_EQ(Support::readU32uBE(arr + 1), 0x01020304u);
EXPECT(Support::readU32uLE(arr + 1) == 0x04030201u); EXPECT_EQ(Support::readU32uLE(arr + 1), 0x04030201u);
EXPECT(Support::readU32uBE(arr + 2) == 0x02030400u); EXPECT_EQ(Support::readU32uBE(arr + 2), 0x02030400u);
EXPECT(Support::readU32uLE(arr + 2) == 0x00040302u); EXPECT_EQ(Support::readU32uLE(arr + 2), 0x00040302u);
Support::writeU32uLE(arr + 5, 0x05060708u); Support::writeU32uLE(arr + 5, 0x05060708u);
EXPECT(Support::readU64uBE(arr + 1) == 0x0102030408070605u); EXPECT_EQ(Support::readU64uBE(arr + 1), 0x0102030408070605u);
EXPECT(Support::readU64uLE(arr + 1) == 0x0506070804030201u); EXPECT_EQ(Support::readU64uLE(arr + 1), 0x0506070804030201u);
Support::writeU64uLE(arr + 7, 0x1122334455667788u); Support::writeU64uLE(arr + 7, 0x1122334455667788u);
EXPECT(Support::readU32uBE(arr + 8) == 0x77665544u); EXPECT_EQ(Support::readU32uBE(arr + 8), 0x77665544u);
} }
static void testBitVector() noexcept { static void testBitVector() noexcept {
@@ -212,132 +214,132 @@ static void testBitVector() noexcept {
{ {
uint32_t vec[3] = { 0 }; uint32_t vec[3] = { 0 };
Support::bitVectorFill(vec, 1, 64); Support::bitVectorFill(vec, 1, 64);
EXPECT(vec[0] == 0xFFFFFFFEu); EXPECT_EQ(vec[0], 0xFFFFFFFEu);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0x00000001u); EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorClear(vec, 1, 1); Support::bitVectorClear(vec, 1, 1);
EXPECT(vec[0] == 0xFFFFFFFCu); EXPECT_EQ(vec[0], 0xFFFFFFFCu);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0x00000001u); EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorFill(vec, 0, 32); Support::bitVectorFill(vec, 0, 32);
EXPECT(vec[0] == 0xFFFFFFFFu); EXPECT_EQ(vec[0], 0xFFFFFFFFu);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0x00000001u); EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorClear(vec, 0, 32); Support::bitVectorClear(vec, 0, 32);
EXPECT(vec[0] == 0x00000000u); EXPECT_EQ(vec[0], 0x00000000u);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0x00000001u); EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorFill(vec, 1, 30); Support::bitVectorFill(vec, 1, 30);
EXPECT(vec[0] == 0x7FFFFFFEu); EXPECT_EQ(vec[0], 0x7FFFFFFEu);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0x00000001u); EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorClear(vec, 1, 95); Support::bitVectorClear(vec, 1, 95);
EXPECT(vec[0] == 0x00000000u); EXPECT_EQ(vec[0], 0x00000000u);
EXPECT(vec[1] == 0x00000000u); EXPECT_EQ(vec[1], 0x00000000u);
EXPECT(vec[2] == 0x00000000u); EXPECT_EQ(vec[2], 0x00000000u);
Support::bitVectorFill(vec, 32, 64); Support::bitVectorFill(vec, 32, 64);
EXPECT(vec[0] == 0x00000000u); EXPECT_EQ(vec[0], 0x00000000u);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0xFFFFFFFFu); EXPECT_EQ(vec[2], 0xFFFFFFFFu);
Support::bitVectorSetBit(vec, 1, true); Support::bitVectorSetBit(vec, 1, true);
EXPECT(vec[0] == 0x00000002u); EXPECT_EQ(vec[0], 0x00000002u);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0xFFFFFFFFu); EXPECT_EQ(vec[2], 0xFFFFFFFFu);
Support::bitVectorSetBit(vec, 95, false); Support::bitVectorSetBit(vec, 95, false);
EXPECT(vec[0] == 0x00000002u); EXPECT_EQ(vec[0], 0x00000002u);
EXPECT(vec[1] == 0xFFFFFFFFu); EXPECT_EQ(vec[1], 0xFFFFFFFFu);
EXPECT(vec[2] == 0x7FFFFFFFu); EXPECT_EQ(vec[2], 0x7FFFFFFFu);
Support::bitVectorClear(vec, 33, 32); Support::bitVectorClear(vec, 33, 32);
EXPECT(vec[0] == 0x00000002u); EXPECT_EQ(vec[0], 0x00000002u);
EXPECT(vec[1] == 0x00000001u); EXPECT_EQ(vec[1], 0x00000001u);
EXPECT(vec[2] == 0x7FFFFFFEu); EXPECT_EQ(vec[2], 0x7FFFFFFEu);
} }
INFO("Support::bitVectorIndexOf"); INFO("Support::bitVectorIndexOf");
{ {
uint32_t vec1[1] = { 0x80000000 }; uint32_t vec1[1] = { 0x80000000 };
EXPECT(Support::bitVectorIndexOf(vec1, 0, true) == 31); EXPECT_EQ(Support::bitVectorIndexOf(vec1, 0, true), 31u);
EXPECT(Support::bitVectorIndexOf(vec1, 1, true) == 31); EXPECT_EQ(Support::bitVectorIndexOf(vec1, 1, true), 31u);
EXPECT(Support::bitVectorIndexOf(vec1, 31, true) == 31); EXPECT_EQ(Support::bitVectorIndexOf(vec1, 31, true), 31u);
uint32_t vec2[2] = { 0x00000000, 0x80000000 }; uint32_t vec2[2] = { 0x00000000, 0x80000000 };
EXPECT(Support::bitVectorIndexOf(vec2, 0, true) == 63); EXPECT_EQ(Support::bitVectorIndexOf(vec2, 0, true), 63u);
EXPECT(Support::bitVectorIndexOf(vec2, 1, true) == 63); EXPECT_EQ(Support::bitVectorIndexOf(vec2, 1, true), 63u);
EXPECT(Support::bitVectorIndexOf(vec2, 31, true) == 63); EXPECT_EQ(Support::bitVectorIndexOf(vec2, 31, true), 63u);
EXPECT(Support::bitVectorIndexOf(vec2, 32, true) == 63); EXPECT_EQ(Support::bitVectorIndexOf(vec2, 32, true), 63u);
EXPECT(Support::bitVectorIndexOf(vec2, 33, true) == 63); EXPECT_EQ(Support::bitVectorIndexOf(vec2, 33, true), 63u);
EXPECT(Support::bitVectorIndexOf(vec2, 63, true) == 63); EXPECT_EQ(Support::bitVectorIndexOf(vec2, 63, true), 63u);
uint32_t vec3[3] = { 0x00000001, 0x00000000, 0x80000000 }; uint32_t vec3[3] = { 0x00000001, 0x00000000, 0x80000000 };
EXPECT(Support::bitVectorIndexOf(vec3, 0, true) == 0); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 0, true), 0u);
EXPECT(Support::bitVectorIndexOf(vec3, 1, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 1, true), 95u);
EXPECT(Support::bitVectorIndexOf(vec3, 2, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 2, true), 95u);
EXPECT(Support::bitVectorIndexOf(vec3, 31, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 31, true), 95u);
EXPECT(Support::bitVectorIndexOf(vec3, 32, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 32, true), 95u);
EXPECT(Support::bitVectorIndexOf(vec3, 63, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 63, true), 95u);
EXPECT(Support::bitVectorIndexOf(vec3, 64, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 64, true), 95u);
EXPECT(Support::bitVectorIndexOf(vec3, 95, true) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec3, 95, true), 95u);
uint32_t vec4[3] = { ~vec3[0], ~vec3[1], ~vec3[2] }; uint32_t vec4[3] = { ~vec3[0], ~vec3[1], ~vec3[2] };
EXPECT(Support::bitVectorIndexOf(vec4, 0, false) == 0); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 0, false), 0u);
EXPECT(Support::bitVectorIndexOf(vec4, 1, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 1, false), 95u);
EXPECT(Support::bitVectorIndexOf(vec4, 2, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 2, false), 95u);
EXPECT(Support::bitVectorIndexOf(vec4, 31, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 31, false), 95u);
EXPECT(Support::bitVectorIndexOf(vec4, 32, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 32, false), 95u);
EXPECT(Support::bitVectorIndexOf(vec4, 63, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 63, false), 95u);
EXPECT(Support::bitVectorIndexOf(vec4, 64, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 64, false), 95u);
EXPECT(Support::bitVectorIndexOf(vec4, 95, false) == 95); EXPECT_EQ(Support::bitVectorIndexOf(vec4, 95, false), 95u);
} }
INFO("Support::BitWordIterator<uint32_t>"); INFO("Support::BitWordIterator<uint32_t>");
{ {
Support::BitWordIterator<uint32_t> it(0x80000F01u); Support::BitWordIterator<uint32_t> it(0x80000F01u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 0); EXPECT_EQ(it.next(), 0u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 8); EXPECT_EQ(it.next(), 8u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 9); EXPECT_EQ(it.next(), 9u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 10); EXPECT_EQ(it.next(), 10u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 11); EXPECT_EQ(it.next(), 11u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 31); EXPECT_EQ(it.next(), 31u);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
// No bits set. // No bits set.
it.init(0x00000000u); it.init(0x00000000u);
ASMJIT_ASSERT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
// Only first bit set. // Only first bit set.
it.init(0x00000001u); it.init(0x00000001u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 0); EXPECT_EQ(it.next(), 0u);
ASMJIT_ASSERT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
// Only last bit set (special case). // Only last bit set (special case).
it.init(0x80000000u); it.init(0x80000000u);
ASMJIT_ASSERT(it.hasNext()); EXPECT_TRUE(it.hasNext());
ASMJIT_ASSERT(it.next() == 31); EXPECT_EQ(it.next(), 31u);
ASMJIT_ASSERT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
} }
INFO("Support::BitWordIterator<uint64_t>"); INFO("Support::BitWordIterator<uint64_t>");
{ {
Support::BitWordIterator<uint64_t> it(uint64_t(1) << 63); Support::BitWordIterator<uint64_t> it(uint64_t(1) << 63);
ASMJIT_ASSERT(it.hasNext()); EXPECT_TRUE(it.hasNext());
ASMJIT_ASSERT(it.next() == 63); EXPECT_EQ(it.next(), 63u);
ASMJIT_ASSERT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
} }
INFO("Support::BitVectorIterator<uint32_t>"); INFO("Support::BitVectorIterator<uint32_t>");
@@ -346,63 +348,63 @@ static void testBitVector() noexcept {
static const uint32_t bitsNone[] = { 0xFFFFFFFFu }; static const uint32_t bitsNone[] = { 0xFFFFFFFFu };
Support::BitVectorIterator<uint32_t> it(bitsNone, 0); Support::BitVectorIterator<uint32_t> it(bitsNone, 0);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
it.init(bitsNone, 0, 1); it.init(bitsNone, 0, 1);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
it.init(bitsNone, 0, 128); it.init(bitsNone, 0, 128);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
static const uint32_t bits1[] = { 0x80000008u, 0x80000001u, 0x00000000u, 0x80000000u, 0x00000000u, 0x00000000u, 0x00003000u }; static const uint32_t bits1[] = { 0x80000008u, 0x80000001u, 0x00000000u, 0x80000000u, 0x00000000u, 0x00000000u, 0x00003000u };
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1)); it.init(bits1, ASMJIT_ARRAY_SIZE(bits1));
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 3); EXPECT_EQ(it.next(), 3u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 31); EXPECT_EQ(it.next(), 31u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 32); EXPECT_EQ(it.next(), 32u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 63); EXPECT_EQ(it.next(), 63u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 127); EXPECT_EQ(it.next(), 127u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 204); EXPECT_EQ(it.next(), 204u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 205); EXPECT_EQ(it.next(), 205u);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 4); it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 4);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 31); EXPECT_EQ(it.next(), 31u);
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 64); it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 64);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 127); EXPECT_EQ(it.next(), 127u);
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 127); it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 127);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 127); EXPECT_EQ(it.next(), 127u);
static const uint32_t bits2[] = { 0x80000000u, 0x80000000u, 0x00000000u, 0x80000000u }; static const uint32_t bits2[] = { 0x80000000u, 0x80000000u, 0x00000000u, 0x80000000u };
it.init(bits2, ASMJIT_ARRAY_SIZE(bits2)); it.init(bits2, ASMJIT_ARRAY_SIZE(bits2));
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 31); EXPECT_EQ(it.next(), 31u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 63); EXPECT_EQ(it.next(), 63u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 127); EXPECT_EQ(it.next(), 127u);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
static const uint32_t bits3[] = { 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u }; static const uint32_t bits3[] = { 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u };
it.init(bits3, ASMJIT_ARRAY_SIZE(bits3)); it.init(bits3, ASMJIT_ARRAY_SIZE(bits3));
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
static const uint32_t bits4[] = { 0x00000000u, 0x00000000u, 0x00000000u, 0x80000000u }; static const uint32_t bits4[] = { 0x00000000u, 0x00000000u, 0x00000000u, 0x80000000u };
it.init(bits4, ASMJIT_ARRAY_SIZE(bits4)); it.init(bits4, ASMJIT_ARRAY_SIZE(bits4));
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 127); EXPECT_EQ(it.next(), 127u);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
} }
INFO("Support::BitVectorIterator<uint64_t>"); INFO("Support::BitVectorIterator<uint64_t>");
@@ -410,20 +412,20 @@ static void testBitVector() noexcept {
static const uint64_t bits1[] = { 0x80000000u, 0x80000000u, 0x00000000u, 0x80000000u }; static const uint64_t bits1[] = { 0x80000000u, 0x80000000u, 0x00000000u, 0x80000000u };
Support::BitVectorIterator<uint64_t> it(bits1, ASMJIT_ARRAY_SIZE(bits1)); Support::BitVectorIterator<uint64_t> it(bits1, ASMJIT_ARRAY_SIZE(bits1));
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 31); EXPECT_EQ(it.next(), 31u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 95); EXPECT_EQ(it.next(), 95u);
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 223); EXPECT_EQ(it.next(), 223u);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
static const uint64_t bits2[] = { 0x8000000000000000u, 0, 0, 0 }; static const uint64_t bits2[] = { 0x8000000000000000u, 0, 0, 0 };
it.init(bits2, ASMJIT_ARRAY_SIZE(bits2)); it.init(bits2, ASMJIT_ARRAY_SIZE(bits2));
EXPECT(it.hasNext()); EXPECT_TRUE(it.hasNext());
EXPECT(it.next() == 63); EXPECT_EQ(it.next(), 63u);
EXPECT(!it.hasNext()); EXPECT_FALSE(it.hasNext());
} }
} }

View File

@@ -288,8 +288,8 @@ UNIT(zone_hash) {
for (key = 0; key < count; key++) { for (key = 0; key < count; key++) {
node = hashTable.get(MyKeyMatcher(key)); node = hashTable.get(MyKeyMatcher(key));
EXPECT(node != nullptr); EXPECT_NOT_NULL(node);
EXPECT(node->_key == key); EXPECT_EQ(node->_key, key);
} }
{ {
@@ -298,11 +298,11 @@ UNIT(zone_hash) {
hashTable.remove(&allocator, node); hashTable.remove(&allocator, node);
node = hashTable.get(MyKeyMatcher(count)); node = hashTable.get(MyKeyMatcher(count));
EXPECT(node == nullptr); EXPECT_NULL(node);
} }
} while (count); } while (count);
EXPECT(hashTable.empty()); EXPECT_TRUE(hashTable.empty());
} }
#endif #endif

View File

@@ -27,136 +27,136 @@ UNIT(zone_list) {
INFO("Append / Unlink"); INFO("Append / Unlink");
// [] // []
EXPECT(list.empty() == true); EXPECT_TRUE(list.empty());
// [A] // [A]
list.append(a); list.append(a);
EXPECT(list.empty() == false); EXPECT_FALSE(list.empty());
EXPECT(list.first() == a); EXPECT_EQ(list.first(), a);
EXPECT(list.last() == a); EXPECT_EQ(list.last(), a);
EXPECT(a->prev() == nullptr); EXPECT_NULL(a->prev());
EXPECT(a->next() == nullptr); EXPECT_NULL(a->next());
// [A, B] // [A, B]
list.append(b); list.append(b);
EXPECT(list.first() == a); EXPECT_EQ(list.first(), a);
EXPECT(list.last() == b); EXPECT_EQ(list.last(), b);
EXPECT(a->prev() == nullptr); EXPECT_NULL(a->prev());
EXPECT(a->next() == b); EXPECT_EQ(a->next(), b);
EXPECT(b->prev() == a); EXPECT_EQ(b->prev(), a);
EXPECT(b->next() == nullptr); EXPECT_NULL(b->next());
// [A, B, C] // [A, B, C]
list.append(c); list.append(c);
EXPECT(list.first() == a); EXPECT_EQ(list.first(), a);
EXPECT(list.last() == c); EXPECT_EQ(list.last(), c);
EXPECT(a->prev() == nullptr); EXPECT_NULL(a->prev());
EXPECT(a->next() == b); EXPECT_EQ(a->next(), b);
EXPECT(b->prev() == a); EXPECT_EQ(b->prev(), a);
EXPECT(b->next() == c); EXPECT_EQ(b->next(), c);
EXPECT(c->prev() == b); EXPECT_EQ(c->prev(), b);
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
// [B, C] // [B, C]
list.unlink(a); list.unlink(a);
EXPECT(list.first() == b); EXPECT_EQ(list.first(), b);
EXPECT(list.last() == c); EXPECT_EQ(list.last(), c);
EXPECT(a->prev() == nullptr); EXPECT_NULL(a->prev());
EXPECT(a->next() == nullptr); EXPECT_NULL(a->next());
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == c); EXPECT_EQ(b->next(), c);
EXPECT(c->prev() == b); EXPECT_EQ(c->prev(), b);
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
// [B] // [B]
list.unlink(c); list.unlink(c);
EXPECT(list.first() == b); EXPECT_EQ(list.first(), b);
EXPECT(list.last() == b); EXPECT_EQ(list.last(), b);
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == nullptr); EXPECT_NULL(b->next());
EXPECT(c->prev() == nullptr); EXPECT_NULL(c->prev());
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
// [] // []
list.unlink(b); list.unlink(b);
EXPECT(list.empty() == true); EXPECT_TRUE(list.empty());
EXPECT(list.first() == nullptr); EXPECT_NULL(list.first());
EXPECT(list.last() == nullptr); EXPECT_NULL(list.last());
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == nullptr); EXPECT_NULL(b->next());
INFO("Prepend / Unlink"); INFO("Prepend / Unlink");
// [A] // [A]
list.prepend(a); list.prepend(a);
EXPECT(list.empty() == false); EXPECT_FALSE(list.empty());
EXPECT(list.first() == a); EXPECT_EQ(list.first(), a);
EXPECT(list.last() == a); EXPECT_EQ(list.last(), a);
EXPECT(a->prev() == nullptr); EXPECT_NULL(a->prev());
EXPECT(a->next() == nullptr); EXPECT_NULL(a->next());
// [B, A] // [B, A]
list.prepend(b); list.prepend(b);
EXPECT(list.first() == b); EXPECT_EQ(list.first(), b);
EXPECT(list.last() == a); EXPECT_EQ(list.last(), a);
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == a); EXPECT_EQ(b->next(), a);
EXPECT(a->prev() == b); EXPECT_EQ(a->prev(), b);
EXPECT(a->next() == nullptr); EXPECT_NULL(a->next());
INFO("InsertAfter / InsertBefore"); INFO("InsertAfter / InsertBefore");
// [B, A, C] // [B, A, C]
list.insertAfter(a, c); list.insertAfter(a, c);
EXPECT(list.first() == b); EXPECT_EQ(list.first(), b);
EXPECT(list.last() == c); EXPECT_EQ(list.last(), c);
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == a); EXPECT_EQ(b->next(), a);
EXPECT(a->prev() == b); EXPECT_EQ(a->prev(), b);
EXPECT(a->next() == c); EXPECT_EQ(a->next(), c);
EXPECT(c->prev() == a); EXPECT_EQ(c->prev(), a);
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
// [B, D, A, C] // [B, D, A, C]
list.insertBefore(a, d); list.insertBefore(a, d);
EXPECT(list.first() == b); EXPECT_EQ(list.first(), b);
EXPECT(list.last() == c); EXPECT_EQ(list.last(), c);
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == d); EXPECT_EQ(b->next(), d);
EXPECT(d->prev() == b); EXPECT_EQ(d->prev(), b);
EXPECT(d->next() == a); EXPECT_EQ(d->next(), a);
EXPECT(a->prev() == d); EXPECT_EQ(a->prev(), d);
EXPECT(a->next() == c); EXPECT_EQ(a->next(), c);
EXPECT(c->prev() == a); EXPECT_EQ(c->prev(), a);
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
INFO("PopFirst / Pop"); INFO("PopFirst / Pop");
// [D, A, C] // [D, A, C]
EXPECT(list.popFirst() == b); EXPECT_EQ(list.popFirst(), b);
EXPECT(b->prev() == nullptr); EXPECT_NULL(b->prev());
EXPECT(b->next() == nullptr); EXPECT_NULL(b->next());
EXPECT(list.first() == d); EXPECT_EQ(list.first(), d);
EXPECT(list.last() == c); EXPECT_EQ(list.last(), c);
EXPECT(d->prev() == nullptr); EXPECT_NULL(d->prev());
EXPECT(d->next() == a); EXPECT_EQ(d->next(), a);
EXPECT(a->prev() == d); EXPECT_EQ(a->prev(), d);
EXPECT(a->next() == c); EXPECT_EQ(a->next(), c);
EXPECT(c->prev() == a); EXPECT_EQ(c->prev(), a);
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
// [D, A] // [D, A]
EXPECT(list.pop() == c); EXPECT_EQ(list.pop(), c);
EXPECT(c->prev() == nullptr); EXPECT_NULL(c->prev());
EXPECT(c->next() == nullptr); EXPECT_NULL(c->next());
EXPECT(list.first() == d); EXPECT_EQ(list.first(), d);
EXPECT(list.last() == a); EXPECT_EQ(list.last(), a);
EXPECT(d->prev() == nullptr); EXPECT_NULL(d->prev());
EXPECT(d->next() == a); EXPECT_EQ(d->next(), a);
EXPECT(a->prev() == d); EXPECT_EQ(a->prev(), d);
EXPECT(a->next() == nullptr); EXPECT_NULL(a->next());
} }
#endif #endif

View File

@@ -100,18 +100,24 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
INFO("Testing ZoneStack<%s>", typeName); INFO("Testing ZoneStack<%s>", typeName);
INFO(" (%d items per one Block)", ZoneStack<T>::kNumBlockItems); INFO(" (%d items per one Block)", ZoneStack<T>::kNumBlockItems);
EXPECT(stack.init(allocator) == kErrorOk); EXPECT_EQ(stack.init(allocator), kErrorOk);
EXPECT(stack.empty(), "Stack must be empty after `init()`"); EXPECT_TRUE(stack.empty());
EXPECT(stack.append(42) == kErrorOk); EXPECT_EQ(stack.append(42), kErrorOk);
EXPECT(!stack.empty() , "Stack must not be empty after an item has been appended"); EXPECT_FALSE(stack.empty())
EXPECT(stack.pop() == 42 , "Stack.pop() must return the item that has been appended last"); .message("Stack must not be empty after an item has been appended");
EXPECT(stack.empty() , "Stack must be empty after the last item has been removed"); EXPECT_EQ(stack.pop(), 42)
.message("Stack.pop() must return the item that has been appended last");
EXPECT_TRUE(stack.empty())
.message("Stack must be empty after the last item has been removed");
EXPECT(stack.prepend(43) == kErrorOk); EXPECT_EQ(stack.prepend(43), kErrorOk);
EXPECT(!stack.empty() , "Stack must not be empty after an item has been prepended"); EXPECT_FALSE(stack.empty())
EXPECT(stack.popFirst() == 43, "Stack.popFirst() must return the item that has been prepended last"); .message("Stack must not be empty after an item has been prepended");
EXPECT(stack.empty() , "Stack must be empty after the last item has been removed"); EXPECT_EQ(stack.popFirst(), 43)
.message("Stack.popFirst() must return the item that has been prepended last");
EXPECT_TRUE(stack.empty())
.message("Stack must be empty after the last item has been removed");
int i; int i;
int iMin =-100000; int iMin =-100000;
@@ -121,27 +127,31 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
for (i = iMax; i >= 0; i--) stack.prepend(T(i)); for (i = iMax; i >= 0; i--) stack.prepend(T(i));
for (i = 0; i <= iMax; i++) { for (i = 0; i <= iMax; i++) {
T item = stack.popFirst(); T item = stack.popFirst();
EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); EXPECT_EQ(i, item)
.message("Item '%d' didn't match the item '%lld' popped", i, (long long)item);
if (!stack.empty()) { if (!stack.empty()) {
item = stack.popFirst(); item = stack.popFirst();
EXPECT(i + 1 == item, "Item '%d' didn't match the item '%lld' popped", i + 1, (long long)item); EXPECT_EQ(i + 1, item)
.message("Item '%d' didn't match the item '%lld' popped", i + 1, (long long)item);
stack.prepend(item); stack.prepend(item);
} }
} }
EXPECT(stack.empty()); EXPECT_TRUE(stack.empty());
INFO("Validating append() & pop()"); INFO("Validating append() & pop()");
for (i = 0; i <= iMax; i++) stack.append(T(i)); for (i = 0; i <= iMax; i++) stack.append(T(i));
for (i = iMax; i >= 0; i--) { for (i = iMax; i >= 0; i--) {
T item = stack.pop(); T item = stack.pop();
EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); EXPECT_EQ(i, item)
.message("Item '%d' didn't match the item '%lld' popped", i, (long long)item);
if (!stack.empty()) { if (!stack.empty()) {
item = stack.pop(); item = stack.pop();
EXPECT(i - 1 == item, "Item '%d' didn't match the item '%lld' popped", i - 1, (long long)item); EXPECT_EQ(i - 1, item)
.message("Item '%d' didn't match the item '%lld' popped", i - 1, (long long)item);
stack.append(item); stack.append(item);
} }
} }
EXPECT(stack.empty()); EXPECT_TRUE(stack.empty());
INFO("Validating append()/prepend() & popFirst()"); INFO("Validating append()/prepend() & popFirst()");
for (i = 1; i <= iMax; i++) stack.append(T(i)); for (i = 1; i <= iMax; i++) stack.append(T(i));
@@ -149,9 +159,9 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
for (i = iMin; i <= iMax; i++) { for (i = iMin; i <= iMax; i++) {
T item = stack.popFirst(); T item = stack.popFirst();
EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); EXPECT_EQ(i, item);
} }
EXPECT(stack.empty()); EXPECT_TRUE(stack.empty());
INFO("Validating append()/prepend() & pop()"); INFO("Validating append()/prepend() & pop()");
for (i = 0; i >= iMin; i--) stack.prepend(T(i)); for (i = 0; i >= iMin; i--) stack.prepend(T(i));
@@ -159,9 +169,9 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
for (i = iMax; i >= iMin; i--) { for (i = iMax; i >= iMin; i--) {
T item = stack.pop(); T item = stack.pop();
EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); EXPECT_EQ(i, item);
} }
EXPECT(stack.empty()); EXPECT_TRUE(stack.empty());
} }
UNIT(zone_stack) { UNIT(zone_stack) {

View File

@@ -19,7 +19,7 @@ struct ZoneRBUnit {
typedef ZoneTree<NodeT> Tree; typedef ZoneTree<NodeT> Tree;
static void verifyTree(Tree& tree) noexcept { static void verifyTree(Tree& tree) noexcept {
EXPECT(checkHeight(static_cast<NodeT*>(tree._root)) > 0); EXPECT_GT(checkHeight(static_cast<NodeT*>(tree._root)), 0);
} }
// Check whether the Red-Black tree is valid. // Check whether the Red-Black tree is valid.
@@ -30,17 +30,16 @@ struct ZoneRBUnit {
NodeT* rn = node->right(); NodeT* rn = node->right();
// Invalid tree. // Invalid tree.
EXPECT(ln == nullptr || *ln < *node); EXPECT_TRUE(ln == nullptr || *ln < *node);
EXPECT(rn == nullptr || *rn > *node); EXPECT_TRUE(rn == nullptr || *rn > *node);
// Red violation. // Red violation.
EXPECT(!node->isRed() || EXPECT_TRUE(!node->isRed() || (!ZoneTreeNode::_isValidRed(ln) && !ZoneTreeNode::_isValidRed(rn)));
(!ZoneTreeNode::_isValidRed(ln) && !ZoneTreeNode::_isValidRed(rn)));
// Black violation. // Black violation.
int lh = checkHeight(ln); int lh = checkHeight(ln);
int rh = checkHeight(rn); int rh = checkHeight(rn);
EXPECT(!lh || !rh || lh == rh); EXPECT_TRUE(!lh || !rh || lh == rh);
// Only count black links. // Only count black links.
return (lh && rh) ? lh + !node->isRed() : 0; return (lh && rh) ? lh + !node->isRed() : 0;
@@ -83,8 +82,8 @@ UNIT(zone_rbtree) {
for (key = 0; key < count; key++) { for (key = 0; key < count; key++) {
node = rbTree.get(key); node = rbTree.get(key);
EXPECT(node != nullptr); EXPECT_NOT_NULL(node);
EXPECT(node->_key == key); EXPECT_EQ(node->_key, key);
} }
node = rbTree.get(--count); node = rbTree.get(--count);
@@ -92,7 +91,7 @@ UNIT(zone_rbtree) {
ZoneRBUnit<MyRBNode>::verifyTree(rbTree); ZoneRBUnit<MyRBNode>::verifyTree(rbTree);
} while (count); } while (count);
EXPECT(rbTree.empty()); EXPECT_TRUE(rbTree.empty());
} }
#endif #endif

View File

@@ -272,26 +272,26 @@ static void test_zone_vector(ZoneAllocator* allocator, const char* typeName) {
ZoneVector<T> vec; ZoneVector<T> vec;
INFO("ZoneVector<%s> basic tests", typeName); INFO("ZoneVector<%s> basic tests", typeName);
EXPECT(vec.append(allocator, 0) == kErrorOk); EXPECT_EQ(vec.append(allocator, 0), kErrorOk);
EXPECT(vec.empty() == false); EXPECT_FALSE(vec.empty());
EXPECT(vec.size() == 1); EXPECT_EQ(vec.size(), 1u);
EXPECT(vec.capacity() >= 1); EXPECT_GE(vec.capacity(), 1u);
EXPECT(vec.indexOf(0) == 0); EXPECT_EQ(vec.indexOf(0), 0u);
EXPECT(vec.indexOf(-11) == Globals::kNotFound); EXPECT_EQ(vec.indexOf(-11), Globals::kNotFound);
vec.clear(); vec.clear();
EXPECT(vec.empty()); EXPECT_TRUE(vec.empty());
EXPECT(vec.size() == 0); EXPECT_EQ(vec.size(), 0u);
EXPECT(vec.indexOf(0) == Globals::kNotFound); EXPECT_EQ(vec.indexOf(0), Globals::kNotFound);
for (i = 0; i < kMax; i++) { for (i = 0; i < kMax; i++) {
EXPECT(vec.append(allocator, T(i)) == kErrorOk); EXPECT_EQ(vec.append(allocator, T(i)), kErrorOk);
} }
EXPECT(vec.empty() == false); EXPECT_FALSE(vec.empty());
EXPECT(vec.size() == uint32_t(kMax)); EXPECT_EQ(vec.size(), uint32_t(kMax));
EXPECT(vec.indexOf(T(kMax - 1)) == uint32_t(kMax - 1)); EXPECT_EQ(vec.indexOf(T(kMax - 1)), uint32_t(kMax - 1));
EXPECT(vec.rbegin()[0] == kMax - 1); EXPECT_EQ(vec.rbegin()[0], kMax - 1);
vec.release(allocator); vec.release(allocator);
} }
@@ -303,31 +303,31 @@ static void test_zone_bitvector(ZoneAllocator* allocator) {
uint32_t kMaxCount = 100; uint32_t kMaxCount = 100;
ZoneBitVector vec; ZoneBitVector vec;
EXPECT(vec.empty()); EXPECT_TRUE(vec.empty());
EXPECT(vec.size() == 0); EXPECT_EQ(vec.size(), 0u);
INFO("ZoneBitVector::resize()"); INFO("ZoneBitVector::resize()");
for (count = 1; count < kMaxCount; count++) { for (count = 1; count < kMaxCount; count++) {
vec.clear(); vec.clear();
EXPECT(vec.resize(allocator, count, false) == kErrorOk); EXPECT_EQ(vec.resize(allocator, count, false), kErrorOk);
EXPECT(vec.size() == count); EXPECT_EQ(vec.size(), count);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
EXPECT(vec.bitAt(i) == false); EXPECT_FALSE(vec.bitAt(i));
vec.clear(); vec.clear();
EXPECT(vec.resize(allocator, count, true) == kErrorOk); EXPECT_EQ(vec.resize(allocator, count, true), kErrorOk);
EXPECT(vec.size() == count); EXPECT_EQ(vec.size(), count);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
EXPECT(vec.bitAt(i) == true); EXPECT_TRUE(vec.bitAt(i));
} }
INFO("ZoneBitVector::fillBits() / clearBits()"); INFO("ZoneBitVector::fillBits() / clearBits()");
for (count = 1; count < kMaxCount; count += 2) { for (count = 1; count < kMaxCount; count += 2) {
vec.clear(); vec.clear();
EXPECT(vec.resize(allocator, count) == kErrorOk); EXPECT_EQ(vec.resize(allocator, count), kErrorOk);
EXPECT(vec.size() == count); EXPECT_EQ(vec.size(), count);
for (i = 0; i < (count + 1) / 2; i++) { for (i = 0; i < (count + 1) / 2; i++) {
bool value = bool(i & 1); bool value = bool(i & 1);
@@ -338,7 +338,7 @@ static void test_zone_bitvector(ZoneAllocator* allocator) {
} }
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
EXPECT(vec.bitAt(i) == bool(i & 1)); EXPECT_EQ(vec.bitAt(i), bool(i & 1));
} }
} }
} }

View File

@@ -4274,7 +4274,7 @@ EmitModSib_LabelRip_X86:
} }
else { else {
// Non-bound label or label bound to a different section. // Non-bound label or label bound to a different section.
relOffset = -4 - immSize; relOffset = -4 - int32_t(immSize);
relSize = 4; relSize = 4;
goto EmitRel; goto EmitRel;
} }

View File

@@ -1667,15 +1667,14 @@ UNIT(x86_inst_api_text) {
INFO("Matching all X86 instructions"); INFO("Matching all X86 instructions");
for (uint32_t a = 1; a < Inst::_kIdCount; a++) { for (uint32_t a = 1; a < Inst::_kIdCount; a++) {
StringTmp<128> aName; StringTmp<128> aName;
EXPECT(InstInternal::instIdToString(Arch::kX86, a, aName) == kErrorOk, EXPECT_EQ(InstInternal::instIdToString(Arch::kX86, a, aName), kErrorOk)
"Failed to get the name of instruction #%u", a); .message("Failed to get the name of instruction #%u", a);
uint32_t b = InstInternal::stringToInstId(Arch::kX86, aName.data(), aName.size()); uint32_t b = InstInternal::stringToInstId(Arch::kX86, aName.data(), aName.size());
StringTmp<128> bName; StringTmp<128> bName;
InstInternal::instIdToString(Arch::kX86, b, bName); InstInternal::instIdToString(Arch::kX86, b, bName);
EXPECT_EQ(a, b)
EXPECT(a == b, .message("Instructions do not match \"%s\" (#%u) != \"%s\" (#%u)", aName.data(), a, bName.data(), b);
"Instructions do not match \"%s\" (#%u) != \"%s\" (#%u)", aName.data(), a, bName.data(), b);
} }
} }
@@ -1693,10 +1692,10 @@ UNIT(x86_inst_api_rm_feature) {
InstRWInfo rwi; InstRWInfo rwi;
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdPextrw, InstOptions::kNone, eax, mm1, imm(1)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdPextrw, InstOptions::kNone, eax, mm1, imm(1));
EXPECT(rwi.rmFeature() == 0); EXPECT_EQ(rwi.rmFeature(), 0u);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdPextrw, InstOptions::kNone, eax, xmm1, imm(1)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdPextrw, InstOptions::kNone, eax, xmm1, imm(1));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kSSE4_1); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kSSE4_1);
} }
INFO("Verifying whether RM/feature is reported correctly for AVX512 shift instructions"); INFO("Verifying whether RM/feature is reported correctly for AVX512 shift instructions");
@@ -1704,40 +1703,40 @@ UNIT(x86_inst_api_rm_feature) {
InstRWInfo rwi; InstRWInfo rwi;
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslld, InstOptions::kNone, xmm1, xmm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslld, InstOptions::kNone, xmm1, xmm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllq, InstOptions::kNone, ymm1, ymm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllq, InstOptions::kNone, ymm1, ymm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrad, InstOptions::kNone, xmm1, xmm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrad, InstOptions::kNone, xmm1, xmm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrld, InstOptions::kNone, ymm1, ymm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrld, InstOptions::kNone, ymm1, ymm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrlq, InstOptions::kNone, xmm1, xmm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrlq, InstOptions::kNone, xmm1, xmm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslldq, InstOptions::kNone, xmm1, xmm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslldq, InstOptions::kNone, xmm1, xmm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllw, InstOptions::kNone, ymm1, ymm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllw, InstOptions::kNone, ymm1, ymm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsraw, InstOptions::kNone, xmm1, xmm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsraw, InstOptions::kNone, xmm1, xmm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrldq, InstOptions::kNone, ymm1, ymm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrldq, InstOptions::kNone, ymm1, ymm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrlw, InstOptions::kNone, xmm1, xmm2, imm(8)); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrlw, InstOptions::kNone, xmm1, xmm2, imm(8));
EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW); EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslld, InstOptions::kNone, xmm1, xmm2, xmm3); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslld, InstOptions::kNone, xmm1, xmm2, xmm3);
EXPECT(rwi.rmFeature() == 0); EXPECT_EQ(rwi.rmFeature(), 0u);
queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllw, InstOptions::kNone, xmm1, xmm2, xmm3); queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllw, InstOptions::kNone, xmm1, xmm2, xmm3);
EXPECT(rwi.rmFeature() == 0); EXPECT_EQ(rwi.rmFeature(), 0u);
} }
} }
#endif #endif

View File

@@ -5931,20 +5931,33 @@ UNIT(x86_inst_db) {
INFO("Checking validity of Inst enums"); INFO("Checking validity of Inst enums");
// Cross-validate prefixes. // Cross-validate prefixes.
EXPECT(uint32_t(InstOptions::kX86_Rex ) == 0x40000000u, "REX prefix must be at 0x40000000"); EXPECT_EQ(uint32_t(InstOptions::kX86_Rex ), 0x40000000u)
EXPECT(uint32_t(InstOptions::kX86_Evex) == 0x00001000u, "EVEX prefix must be at 0x00001000"); .message("REX prefix must be at 0x40000000");
EXPECT_EQ(uint32_t(InstOptions::kX86_Evex), 0x00001000u)
.message("EVEX prefix must be at 0x00001000");
// These could be combined together to form a valid REX prefix, they must match. // These could be combined together to form a valid REX prefix, they must match.
EXPECT(uint32_t(InstOptions::kX86_OpCodeB) == uint32_t(Opcode::kB), "Opcode::kB must match InstOptions::kX86_OpCodeB"); EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeB), uint32_t(Opcode::kB))
EXPECT(uint32_t(InstOptions::kX86_OpCodeX) == uint32_t(Opcode::kX), "Opcode::kX must match InstOptions::kX86_OpCodeX"); .message("Opcode::kB must match InstOptions::kX86_OpCodeB");
EXPECT(uint32_t(InstOptions::kX86_OpCodeR) == uint32_t(Opcode::kR), "Opcode::kR must match InstOptions::kX86_OpCodeR");
EXPECT(uint32_t(InstOptions::kX86_OpCodeW) == uint32_t(Opcode::kW), "Opcode::kW must match InstOptions::kX86_OpCodeW"); EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeX), uint32_t(Opcode::kX))
.message("Opcode::kX must match InstOptions::kX86_OpCodeX");
EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeR), uint32_t(Opcode::kR))
.message("Opcode::kR must match InstOptions::kX86_OpCodeR");
EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeW), uint32_t(Opcode::kW))
.message("Opcode::kW must match InstOptions::kX86_OpCodeW");
uint32_t rex_rb = (Opcode::kR >> Opcode::kREX_Shift) | (Opcode::kB >> Opcode::kREX_Shift) | 0x40; uint32_t rex_rb = (Opcode::kR >> Opcode::kREX_Shift) | (Opcode::kB >> Opcode::kREX_Shift) | 0x40;
uint32_t rex_rw = (Opcode::kR >> Opcode::kREX_Shift) | (Opcode::kW >> Opcode::kREX_Shift) | 0x40; uint32_t rex_rw = (Opcode::kR >> Opcode::kREX_Shift) | (Opcode::kW >> Opcode::kREX_Shift) | 0x40;
EXPECT(rex_rb == 0x45, "Opcode::kR|B must form a valid REX prefix (0x45) if combined with 0x40"); EXPECT_EQ(rex_rb, 0x45u)
EXPECT(rex_rw == 0x4C, "Opcode::kR|W must form a valid REX prefix (0x4C) if combined with 0x40"); .message("Opcode::kR|B must form a valid REX prefix (0x45) if combined with 0x40");
EXPECT_EQ(rex_rw, 0x4Cu)
.message("Opcode::kR|W must form a valid REX prefix (0x4C) if combined with 0x40");
} }
#endif #endif

View File

@@ -19,210 +19,210 @@ UNIT(x86_operand) {
Label L(1000); // Label with some ID. Label L(1000); // Label with some ID.
INFO("Checking basic properties of built-in X86 registers"); INFO("Checking basic properties of built-in X86 registers");
EXPECT(gpb(Gp::kIdAx) == al); EXPECT_EQ(gpb(Gp::kIdAx), al);
EXPECT(gpb(Gp::kIdBx) == bl); EXPECT_EQ(gpb(Gp::kIdBx), bl);
EXPECT(gpb(Gp::kIdCx) == cl); EXPECT_EQ(gpb(Gp::kIdCx), cl);
EXPECT(gpb(Gp::kIdDx) == dl); EXPECT_EQ(gpb(Gp::kIdDx), dl);
EXPECT(gpb_lo(Gp::kIdAx) == al); EXPECT_EQ(gpb_lo(Gp::kIdAx), al);
EXPECT(gpb_lo(Gp::kIdBx) == bl); EXPECT_EQ(gpb_lo(Gp::kIdBx), bl);
EXPECT(gpb_lo(Gp::kIdCx) == cl); EXPECT_EQ(gpb_lo(Gp::kIdCx), cl);
EXPECT(gpb_lo(Gp::kIdDx) == dl); EXPECT_EQ(gpb_lo(Gp::kIdDx), dl);
EXPECT(gpb_hi(Gp::kIdAx) == ah); EXPECT_EQ(gpb_hi(Gp::kIdAx), ah);
EXPECT(gpb_hi(Gp::kIdBx) == bh); EXPECT_EQ(gpb_hi(Gp::kIdBx), bh);
EXPECT(gpb_hi(Gp::kIdCx) == ch); EXPECT_EQ(gpb_hi(Gp::kIdCx), ch);
EXPECT(gpb_hi(Gp::kIdDx) == dh); EXPECT_EQ(gpb_hi(Gp::kIdDx), dh);
EXPECT(gpw(Gp::kIdAx) == ax); EXPECT_EQ(gpw(Gp::kIdAx), ax);
EXPECT(gpw(Gp::kIdBx) == bx); EXPECT_EQ(gpw(Gp::kIdBx), bx);
EXPECT(gpw(Gp::kIdCx) == cx); EXPECT_EQ(gpw(Gp::kIdCx), cx);
EXPECT(gpw(Gp::kIdDx) == dx); EXPECT_EQ(gpw(Gp::kIdDx), dx);
EXPECT(gpd(Gp::kIdAx) == eax); EXPECT_EQ(gpd(Gp::kIdAx), eax);
EXPECT(gpd(Gp::kIdBx) == ebx); EXPECT_EQ(gpd(Gp::kIdBx), ebx);
EXPECT(gpd(Gp::kIdCx) == ecx); EXPECT_EQ(gpd(Gp::kIdCx), ecx);
EXPECT(gpd(Gp::kIdDx) == edx); EXPECT_EQ(gpd(Gp::kIdDx), edx);
EXPECT(gpq(Gp::kIdAx) == rax); EXPECT_EQ(gpq(Gp::kIdAx), rax);
EXPECT(gpq(Gp::kIdBx) == rbx); EXPECT_EQ(gpq(Gp::kIdBx), rbx);
EXPECT(gpq(Gp::kIdCx) == rcx); EXPECT_EQ(gpq(Gp::kIdCx), rcx);
EXPECT(gpq(Gp::kIdDx) == rdx); EXPECT_EQ(gpq(Gp::kIdDx), rdx);
EXPECT(gpb(Gp::kIdAx) != dl); EXPECT_NE(gpb(Gp::kIdAx), dl);
EXPECT(gpw(Gp::kIdBx) != cx); EXPECT_NE(gpw(Gp::kIdBx), cx);
EXPECT(gpd(Gp::kIdCx) != ebx); EXPECT_NE(gpd(Gp::kIdCx), ebx);
EXPECT(gpq(Gp::kIdDx) != rax); EXPECT_NE(gpq(Gp::kIdDx), rax);
INFO("Checking if x86::reg(...) matches built-in IDs"); INFO("Checking if x86::reg(...) matches built-in IDs");
EXPECT(gpb(5) == bpl); EXPECT_EQ(gpb(5), bpl);
EXPECT(gpw(5) == bp); EXPECT_EQ(gpw(5), bp);
EXPECT(gpd(5) == ebp); EXPECT_EQ(gpd(5), ebp);
EXPECT(gpq(5) == rbp); EXPECT_EQ(gpq(5), rbp);
EXPECT(st(5) == st5); EXPECT_EQ(st(5) , st5);
EXPECT(mm(5) == mm5); EXPECT_EQ(mm(5) , mm5);
EXPECT(k(5) == k5); EXPECT_EQ(k(5) , k5);
EXPECT(cr(5) == cr5); EXPECT_EQ(cr(5) , cr5);
EXPECT(dr(5) == dr5); EXPECT_EQ(dr(5) , dr5);
EXPECT(xmm(5) == xmm5); EXPECT_EQ(xmm(5), xmm5);
EXPECT(ymm(5) == ymm5); EXPECT_EQ(ymm(5), ymm5);
EXPECT(zmm(5) == zmm5); EXPECT_EQ(zmm(5), zmm5);
INFO("Checking x86::Gp register properties"); INFO("Checking x86::Gp register properties");
EXPECT(Gp().isReg() == true); EXPECT_TRUE(Gp().isReg());
EXPECT(eax.isReg() == true); EXPECT_TRUE(eax.isReg());
EXPECT(eax.id() == 0); EXPECT_EQ(eax.id(), 0u);
EXPECT(eax.size() == 4); EXPECT_EQ(eax.size(), 4u);
EXPECT(eax.type() == RegType::kX86_Gpd); EXPECT_EQ(eax.type(), RegType::kX86_Gpd);
EXPECT(eax.group() == RegGroup::kGp); EXPECT_EQ(eax.group(), RegGroup::kGp);
INFO("Checking x86::Xmm register properties"); INFO("Checking x86::Xmm register properties");
EXPECT(Xmm().isReg() == true); EXPECT_TRUE(Xmm().isReg());
EXPECT(xmm4.isReg() == true); EXPECT_TRUE(xmm4.isReg());
EXPECT(xmm4.id() == 4); EXPECT_EQ(xmm4.id(), 4u);
EXPECT(xmm4.size() == 16); EXPECT_EQ(xmm4.size(), 16u);
EXPECT(xmm4.type() == RegType::kX86_Xmm); EXPECT_EQ(xmm4.type(), RegType::kX86_Xmm);
EXPECT(xmm4.group() == RegGroup::kVec); EXPECT_EQ(xmm4.group(), RegGroup::kVec);
EXPECT(xmm4.isVec()); EXPECT_TRUE(xmm4.isVec());
INFO("Checking x86::Ymm register properties"); INFO("Checking x86::Ymm register properties");
EXPECT(Ymm().isReg() == true); EXPECT_TRUE(Ymm().isReg());
EXPECT(ymm5.isReg() == true); EXPECT_TRUE(ymm5.isReg());
EXPECT(ymm5.id() == 5); EXPECT_EQ(ymm5.id(), 5u);
EXPECT(ymm5.size() == 32); EXPECT_EQ(ymm5.size(), 32u);
EXPECT(ymm5.type() == RegType::kX86_Ymm); EXPECT_EQ(ymm5.type(), RegType::kX86_Ymm);
EXPECT(ymm5.group() == RegGroup::kVec); EXPECT_EQ(ymm5.group(), RegGroup::kVec);
EXPECT(ymm5.isVec()); EXPECT_TRUE(ymm5.isVec());
INFO("Checking x86::Zmm register properties"); INFO("Checking x86::Zmm register properties");
EXPECT(Zmm().isReg() == true); EXPECT_TRUE(Zmm().isReg());
EXPECT(zmm6.isReg() == true); EXPECT_TRUE(zmm6.isReg());
EXPECT(zmm6.id() == 6); EXPECT_EQ(zmm6.id(), 6u);
EXPECT(zmm6.size() == 64); EXPECT_EQ(zmm6.size(), 64u);
EXPECT(zmm6.type() == RegType::kX86_Zmm); EXPECT_EQ(zmm6.type(), RegType::kX86_Zmm);
EXPECT(zmm6.group() == RegGroup::kVec); EXPECT_EQ(zmm6.group(), RegGroup::kVec);
EXPECT(zmm6.isVec()); EXPECT_TRUE(zmm6.isVec());
INFO("Checking x86::Vec register properties"); INFO("Checking x86::Vec register properties");
EXPECT(Vec().isReg() == true); EXPECT_TRUE(Vec().isReg());
// Converts a VEC register to a type of the passed register, but keeps the ID. // Converts a VEC register to a type of the passed register, but keeps the ID.
EXPECT(xmm4.cloneAs(ymm10) == ymm4); EXPECT_EQ(xmm4.cloneAs(ymm10), ymm4);
EXPECT(xmm4.cloneAs(zmm11) == zmm4); EXPECT_EQ(xmm4.cloneAs(zmm11), zmm4);
EXPECT(ymm5.cloneAs(xmm12) == xmm5); EXPECT_EQ(ymm5.cloneAs(xmm12), xmm5);
EXPECT(ymm5.cloneAs(zmm13) == zmm5); EXPECT_EQ(ymm5.cloneAs(zmm13), zmm5);
EXPECT(zmm6.cloneAs(xmm14) == xmm6); EXPECT_EQ(zmm6.cloneAs(xmm14), xmm6);
EXPECT(zmm6.cloneAs(ymm15) == ymm6); EXPECT_EQ(zmm6.cloneAs(ymm15), ymm6);
EXPECT(xmm7.xmm() == xmm7); EXPECT_EQ(xmm7.xmm(), xmm7);
EXPECT(xmm7.ymm() == ymm7); EXPECT_EQ(xmm7.ymm(), ymm7);
EXPECT(xmm7.zmm() == zmm7); EXPECT_EQ(xmm7.zmm(), zmm7);
EXPECT(ymm7.xmm() == xmm7); EXPECT_EQ(ymm7.xmm(), xmm7);
EXPECT(ymm7.ymm() == ymm7); EXPECT_EQ(ymm7.ymm(), ymm7);
EXPECT(ymm7.zmm() == zmm7); EXPECT_EQ(ymm7.zmm(), zmm7);
EXPECT(zmm7.xmm() == xmm7); EXPECT_EQ(zmm7.xmm(), xmm7);
EXPECT(zmm7.ymm() == ymm7); EXPECT_EQ(zmm7.ymm(), ymm7);
EXPECT(zmm7.zmm() == zmm7); EXPECT_EQ(zmm7.zmm(), zmm7);
INFO("Checking x86::Mm register properties"); INFO("Checking x86::Mm register properties");
EXPECT(Mm().isReg() == true); EXPECT_TRUE(Mm().isReg());
EXPECT(mm2.isReg() == true); EXPECT_TRUE(mm2.isReg());
EXPECT(mm2.id() == 2); EXPECT_EQ(mm2.id(), 2u);
EXPECT(mm2.size() == 8); EXPECT_EQ(mm2.size(), 8u);
EXPECT(mm2.type() == RegType::kX86_Mm); EXPECT_EQ(mm2.type(), RegType::kX86_Mm);
EXPECT(mm2.group() == RegGroup::kX86_MM); EXPECT_EQ(mm2.group(), RegGroup::kX86_MM);
INFO("Checking x86::KReg register properties"); INFO("Checking x86::KReg register properties");
EXPECT(KReg().isReg() == true); EXPECT_TRUE(KReg().isReg());
EXPECT(k3.isReg() == true); EXPECT_TRUE(k3.isReg());
EXPECT(k3.id() == 3); EXPECT_EQ(k3.id(), 3u);
EXPECT(k3.size() == 0); EXPECT_EQ(k3.size(), 0u);
EXPECT(k3.type() == RegType::kX86_KReg); EXPECT_EQ(k3.type(), RegType::kX86_KReg);
EXPECT(k3.group() == RegGroup::kX86_K); EXPECT_EQ(k3.group(), RegGroup::kX86_K);
INFO("Checking x86::St register properties"); INFO("Checking x86::St register properties");
EXPECT(St().isReg() == true); EXPECT_TRUE(St().isReg());
EXPECT(st1.isReg() == true); EXPECT_TRUE(st1.isReg());
EXPECT(st1.id() == 1); EXPECT_EQ(st1.id(), 1u);
EXPECT(st1.size() == 10); EXPECT_EQ(st1.size(), 10u);
EXPECT(st1.type() == RegType::kX86_St); EXPECT_EQ(st1.type(), RegType::kX86_St);
EXPECT(st1.group() == RegGroup::kX86_St); EXPECT_EQ(st1.group(), RegGroup::kX86_St);
INFO("Checking if default constructed regs behave as expected"); INFO("Checking if default constructed regs behave as expected");
EXPECT(Reg().isValid() == false); EXPECT_FALSE(Reg().isValid());
EXPECT(Gp().isValid() == false); EXPECT_FALSE(Gp().isValid());
EXPECT(Xmm().isValid() == false); EXPECT_FALSE(Xmm().isValid());
EXPECT(Ymm().isValid() == false); EXPECT_FALSE(Ymm().isValid());
EXPECT(Zmm().isValid() == false); EXPECT_FALSE(Zmm().isValid());
EXPECT(Mm().isValid() == false); EXPECT_FALSE(Mm().isValid());
EXPECT(KReg().isValid() == false); EXPECT_FALSE(KReg().isValid());
EXPECT(SReg().isValid() == false); EXPECT_FALSE(SReg().isValid());
EXPECT(CReg().isValid() == false); EXPECT_FALSE(CReg().isValid());
EXPECT(DReg().isValid() == false); EXPECT_FALSE(DReg().isValid());
EXPECT(St().isValid() == false); EXPECT_FALSE(St().isValid());
EXPECT(Bnd().isValid() == false); EXPECT_FALSE(Bnd().isValid());
INFO("Checking x86::Mem operand"); INFO("Checking x86::Mem operand");
Mem m; Mem m;
EXPECT(m == Mem(), "Two default constructed x86::Mem operands must be equal"); EXPECT_EQ(m, Mem());
m = ptr(L); m = ptr(L);
EXPECT(m.hasBase() == true); EXPECT_TRUE(m.hasBase());
EXPECT(m.hasBaseReg() == false); EXPECT_FALSE(m.hasBaseReg());
EXPECT(m.hasBaseLabel() == true); EXPECT_TRUE(m.hasBaseLabel());
EXPECT(m.hasOffset() == false); EXPECT_FALSE(m.hasOffset());
EXPECT(m.isOffset64Bit() == false); EXPECT_FALSE(m.isOffset64Bit());
EXPECT(m.offset() == 0); EXPECT_EQ(m.offset(), 0);
EXPECT(m.offsetLo32() == 0); EXPECT_EQ(m.offsetLo32(), 0);
m = ptr(0x0123456789ABCDEFu); m = ptr(0x0123456789ABCDEFu);
EXPECT(m.hasBase() == false); EXPECT_FALSE(m.hasBase());
EXPECT(m.hasBaseReg() == false); EXPECT_FALSE(m.hasBaseReg());
EXPECT(m.hasIndex() == false); EXPECT_FALSE(m.hasIndex());
EXPECT(m.hasIndexReg() == false); EXPECT_FALSE(m.hasIndexReg());
EXPECT(m.hasOffset() == true); EXPECT_TRUE(m.hasOffset());
EXPECT(m.isOffset64Bit() == true); EXPECT_TRUE(m.isOffset64Bit());
EXPECT(m.offset() == int64_t(0x0123456789ABCDEFu)); EXPECT_EQ(m.offset(), int64_t(0x0123456789ABCDEFu));
EXPECT(m.offsetLo32() == int32_t(0x89ABCDEFu)); EXPECT_EQ(m.offsetLo32(), int32_t(0x89ABCDEFu));
m.addOffset(1); m.addOffset(1);
EXPECT(m.offset() == int64_t(0x0123456789ABCDF0u)); EXPECT_EQ(m.offset(), int64_t(0x0123456789ABCDF0u));
m = ptr(0x0123456789ABCDEFu, rdi, 3); m = ptr(0x0123456789ABCDEFu, rdi, 3);
EXPECT(m.hasSegment() == false); EXPECT_FALSE(m.hasSegment());
EXPECT(m.hasBase() == false); EXPECT_FALSE(m.hasBase());
EXPECT(m.hasBaseReg() == false); EXPECT_FALSE(m.hasBaseReg());
EXPECT(m.hasIndex() == true); EXPECT_TRUE(m.hasIndex());
EXPECT(m.hasIndexReg() == true); EXPECT_TRUE(m.hasIndexReg());
EXPECT(m.indexType() == rdi.type()); EXPECT_EQ(m.indexType(), rdi.type());
EXPECT(m.indexId() == rdi.id()); EXPECT_EQ(m.indexId(), rdi.id());
EXPECT(m.shift() == 3); EXPECT_EQ(m.shift(), 3u);
EXPECT(m.hasOffset() == true); EXPECT_TRUE(m.hasOffset());
EXPECT(m.isOffset64Bit() == true); EXPECT_TRUE(m.isOffset64Bit());
EXPECT(m.offset() == int64_t(0x0123456789ABCDEFu)); EXPECT_EQ(m.offset(), int64_t(0x0123456789ABCDEFu));
EXPECT(m.offsetLo32() == int32_t(0x89ABCDEFu)); EXPECT_EQ(m.offsetLo32(), int32_t(0x89ABCDEFu));
m.resetIndex(); m.resetIndex();
EXPECT(m.hasIndex() == false); EXPECT_FALSE(m.hasIndex());
EXPECT(m.hasIndexReg() == false); EXPECT_FALSE(m.hasIndexReg());
m = ptr(rax); m = ptr(rax);
EXPECT(m.hasBase() == true); EXPECT_TRUE(m.hasBase());
EXPECT(m.hasBaseReg() == true); EXPECT_TRUE(m.hasBaseReg());
EXPECT(m.baseType() == rax.type()); EXPECT_EQ(m.baseType(), rax.type());
EXPECT(m.baseId() == rax.id()); EXPECT_EQ(m.baseId(), rax.id());
EXPECT(m.hasIndex() == false); EXPECT_FALSE(m.hasIndex());
EXPECT(m.hasIndexReg() == false); EXPECT_FALSE(m.hasIndexReg());
EXPECT(m.indexType() == RegType::kNone); EXPECT_EQ(m.indexType(), RegType::kNone);
EXPECT(m.indexId() == 0); EXPECT_EQ(m.indexId(), 0u);
EXPECT(m.hasOffset() == false); EXPECT_FALSE(m.hasOffset());
EXPECT(m.isOffset64Bit() == false); EXPECT_FALSE(m.isOffset64Bit());
EXPECT(m.offset() == 0); EXPECT_EQ(m.offset(), 0);
EXPECT(m.offsetLo32() == 0); EXPECT_EQ(m.offsetLo32(), 0);
m.setIndex(rsi); m.setIndex(rsi);
EXPECT(m.hasIndex() == true); EXPECT_TRUE(m.hasIndex());
EXPECT(m.hasIndexReg() == true); EXPECT_TRUE(m.hasIndexReg());
EXPECT(m.indexType() == rsi.type()); EXPECT_EQ(m.indexType(), rsi.type());
EXPECT(m.indexId() == rsi.id()); EXPECT_EQ(m.indexId(), rsi.id());
} }
#endif #endif

View File

@@ -2384,19 +2384,19 @@ static void generateAvx512SequenceInternalRegOnly(
cc.evex().vcvtqq2ps(xmmA, ymmB); cc.evex().vcvtqq2ps(xmmA, ymmB);
cc.evex().vcvtqq2ps(ymmA, zmmB); cc.evex().vcvtqq2ps(ymmA, zmmB);
cc.evex().vcvtsd2si(gpd, xmmB); cc.evex().vcvtsd2si(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvtsd2si(gpq, xmmB); cc.evex().vcvtsd2si(gpz, xmmB);
cc.evex().vcvtsd2ss(xmmA, xmmB, xmmC); cc.evex().vcvtsd2ss(xmmA, xmmB, xmmC);
cc.evex().vcvtsd2usi(gpd, xmmB); cc.evex().vcvtsd2usi(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvtsd2usi(gpq, xmmB); cc.evex().vcvtsd2usi(gpz, xmmB);
cc.evex().vcvtsi2sd(xmmA, xmmB, gpd); cc.evex().vcvtsi2sd(xmmA, xmmB, gpd);
if (cc.is64Bit()) cc.evex().vcvtsi2sd(xmmA, xmmB, gpq); cc.evex().vcvtsi2sd(xmmA, xmmB, gpz);
cc.evex().vcvtsi2ss(xmmA, xmmB, gpd); cc.evex().vcvtsi2ss(xmmA, xmmB, gpd);
if (cc.is64Bit()) cc.evex().vcvtsi2ss(xmmA, xmmB, gpq); cc.evex().vcvtsi2ss(xmmA, xmmB, gpz);
cc.evex().vcvtss2sd(xmmA, xmmB, xmmC); cc.evex().vcvtss2sd(xmmA, xmmB, xmmC);
cc.evex().vcvtss2si(gpd, xmmB); cc.evex().vcvtss2si(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvtss2si(gpq, xmmB); cc.evex().vcvtss2si(gpz, xmmB);
cc.evex().vcvtss2usi(gpd, xmmB); cc.evex().vcvtss2usi(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvtss2usi(gpq, xmmB); cc.evex().vcvtss2usi(gpz, xmmB);
cc.evex().vcvttpd2dq(xmmA, xmmB); cc.evex().vcvttpd2dq(xmmA, xmmB);
cc.evex().vcvttpd2dq(xmmA, ymmB); cc.evex().vcvttpd2dq(xmmA, ymmB);
cc.evex().vcvttpd2dq(ymmA, zmmB); cc.evex().vcvttpd2dq(ymmA, zmmB);
@@ -2422,13 +2422,13 @@ static void generateAvx512SequenceInternalRegOnly(
cc.evex().vcvttps2uqq(ymmA, xmmB); cc.evex().vcvttps2uqq(ymmA, xmmB);
cc.evex().vcvttps2uqq(zmmA, ymmB); cc.evex().vcvttps2uqq(zmmA, ymmB);
cc.evex().vcvttsd2si(gpd, xmmB); cc.evex().vcvttsd2si(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvttsd2si(gpq, xmmB); cc.evex().vcvttsd2si(gpz, xmmB);
cc.evex().vcvttsd2usi(gpd, xmmB); cc.evex().vcvttsd2usi(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvttsd2usi(gpq, xmmB); cc.evex().vcvttsd2usi(gpz, xmmB);
cc.evex().vcvttss2si(gpd, xmmB); cc.evex().vcvttss2si(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvttss2si(gpq, xmmB); cc.evex().vcvttss2si(gpz, xmmB);
cc.evex().vcvttss2usi(gpd, xmmB); cc.evex().vcvttss2usi(gpd, xmmB);
if (cc.is64Bit()) cc.evex().vcvttss2usi(gpq, xmmB); cc.evex().vcvttss2usi(gpz, xmmB);
cc.evex().vcvtudq2pd(xmmA, xmmB); cc.evex().vcvtudq2pd(xmmA, xmmB);
cc.evex().vcvtudq2pd(ymmA, xmmB); cc.evex().vcvtudq2pd(ymmA, xmmB);
cc.evex().vcvtudq2pd(zmmA, ymmB); cc.evex().vcvtudq2pd(zmmA, ymmB);
@@ -2442,9 +2442,9 @@ static void generateAvx512SequenceInternalRegOnly(
cc.evex().vcvtuqq2ps(xmmA, ymmB); cc.evex().vcvtuqq2ps(xmmA, ymmB);
cc.evex().vcvtuqq2ps(ymmA, zmmB); cc.evex().vcvtuqq2ps(ymmA, zmmB);
cc.evex().vcvtusi2sd(xmmA, xmmB, gpd); cc.evex().vcvtusi2sd(xmmA, xmmB, gpd);
if (cc.is64Bit()) cc.evex().vcvtusi2sd(xmmA, xmmB, gpq); cc.evex().vcvtusi2sd(xmmA, xmmB, gpz);
cc.evex().vcvtusi2ss(xmmA, xmmB, gpd); cc.evex().vcvtusi2ss(xmmA, xmmB, gpd);
if (cc.is64Bit()) cc.evex().vcvtusi2ss(xmmA, xmmB, gpq); cc.evex().vcvtusi2ss(xmmA, xmmB, gpz);
cc.evex().vdbpsadbw(xmmA, xmmB, xmmC, 0); cc.evex().vdbpsadbw(xmmA, xmmB, xmmC, 0);
cc.evex().vdbpsadbw(ymmA, ymmB, ymmC, 0); cc.evex().vdbpsadbw(ymmA, ymmB, ymmC, 0);
cc.evex().vdbpsadbw(zmmA, zmmB, zmmC, 0); cc.evex().vdbpsadbw(zmmA, zmmB, zmmC, 0);
@@ -3706,19 +3706,19 @@ static void generateAvx512SequenceInternalRegMem(
cc.evex().vcvtqq2ps(xmmA, m256); cc.evex().vcvtqq2ps(xmmA, m256);
cc.evex().vcvtqq2ps(ymmA, m512); cc.evex().vcvtqq2ps(ymmA, m512);
cc.evex().vcvtsd2si(gpd, m); cc.evex().vcvtsd2si(gpd, m);
if (cc.is64Bit()) cc.evex().vcvtsd2si(gpq, m); cc.evex().vcvtsd2si(gpz, m);
cc.evex().vcvtsd2ss(xmmA, xmmB, m); cc.evex().vcvtsd2ss(xmmA, xmmB, m);
cc.evex().vcvtsd2usi(gpd, m); cc.evex().vcvtsd2usi(gpd, m);
if (cc.is64Bit()) cc.evex().vcvtsd2usi(gpq, m); cc.evex().vcvtsd2usi(gpz, m);
cc.evex().vcvtsi2sd(xmmA, xmmB, m32); cc.evex().vcvtsi2sd(xmmA, xmmB, m32);
if (cc.is64Bit()) cc.evex().vcvtsi2sd(xmmA, xmmB, m64); if (cc.is64Bit()) cc.evex().vcvtsi2sd(xmmA, xmmB, m64);
cc.evex().vcvtsi2ss(xmmA, xmmB, m32); cc.evex().vcvtsi2ss(xmmA, xmmB, m32);
if (cc.is64Bit()) cc.evex().vcvtsi2ss(xmmA, xmmB, m64); if (cc.is64Bit()) cc.evex().vcvtsi2ss(xmmA, xmmB, m64);
cc.evex().vcvtss2sd(xmmA, xmmB, m); cc.evex().vcvtss2sd(xmmA, xmmB, m);
cc.evex().vcvtss2si(gpd, m); cc.evex().vcvtss2si(gpd, m);
if (cc.is64Bit()) cc.evex().vcvtss2si(gpq, m); cc.evex().vcvtss2si(gpz, m);
cc.evex().vcvtss2usi(gpd, m); cc.evex().vcvtss2usi(gpd, m);
if (cc.is64Bit()) cc.evex().vcvtss2usi(gpq, m); cc.evex().vcvtss2usi(gpz, m);
cc.evex().vcvttpd2dq(xmmA, m128); cc.evex().vcvttpd2dq(xmmA, m128);
cc.evex().vcvttpd2dq(xmmA, m256); cc.evex().vcvttpd2dq(xmmA, m256);
cc.evex().vcvttpd2dq(ymmA, m512); cc.evex().vcvttpd2dq(ymmA, m512);
@@ -3744,13 +3744,13 @@ static void generateAvx512SequenceInternalRegMem(
cc.evex().vcvttps2uqq(ymmA, m); cc.evex().vcvttps2uqq(ymmA, m);
cc.evex().vcvttps2uqq(zmmA, m); cc.evex().vcvttps2uqq(zmmA, m);
cc.evex().vcvttsd2si(gpd, m); cc.evex().vcvttsd2si(gpd, m);
if (cc.is64Bit()) cc.evex().vcvttsd2si(gpq, m); cc.evex().vcvttsd2si(gpz, m);
cc.evex().vcvttsd2usi(gpd, m); cc.evex().vcvttsd2usi(gpd, m);
if (cc.is64Bit()) cc.evex().vcvttsd2usi(gpq, m); cc.evex().vcvttsd2usi(gpz, m);
cc.evex().vcvttss2si(gpd, m); cc.evex().vcvttss2si(gpd, m);
if (cc.is64Bit()) cc.evex().vcvttss2si(gpq, m); cc.evex().vcvttss2si(gpz, m);
cc.evex().vcvttss2usi(gpd, m); cc.evex().vcvttss2usi(gpd, m);
if (cc.is64Bit()) cc.evex().vcvttss2usi(gpq, m); cc.evex().vcvttss2usi(gpz, m);
cc.evex().vcvtudq2pd(xmmA, m); cc.evex().vcvtudq2pd(xmmA, m);
cc.evex().vcvtudq2pd(ymmA, m); cc.evex().vcvtudq2pd(ymmA, m);
cc.evex().vcvtudq2pd(zmmA, m); cc.evex().vcvtudq2pd(zmmA, m);

View File

@@ -25,12 +25,11 @@
// //
// For more information, please refer to <http://unlicense.org> // For more information, please refer to <http://unlicense.org>
#include "./broken.h" #include "broken.h"
#include <stdarg.h> #include <stdarg.h>
// ============================================================================ // Broken - Globals
// [Broken - Global] // ================
// ============================================================================
// Zero initialized globals. // Zero initialized globals.
struct BrokenGlobal { struct BrokenGlobal {
@@ -56,9 +55,8 @@ struct BrokenGlobal {
}; };
static BrokenGlobal _brokenGlobal; static BrokenGlobal _brokenGlobal;
// ============================================================================ // Broken - API
// [Broken - API] // ============
// ============================================================================
// Get whether the string `a` starts with string `b`. // Get whether the string `a` starts with string `b`.
static bool BrokenAPI_startsWith(const char* a, const char* b) noexcept { static bool BrokenAPI_startsWith(const char* a, const char* b) noexcept {
@@ -185,7 +183,7 @@ bool BrokenAPI::hasArg(const char* name) noexcept {
return _brokenGlobal.hasArg(name); return _brokenGlobal.hasArg(name);
} }
void BrokenAPI::add(Unit* unit) noexcept { void BrokenAPI::addUnit(Unit* unit) noexcept {
Unit** pPrev = &_brokenGlobal._unitList; Unit** pPrev = &_brokenGlobal._unitList;
Unit* current = *pPrev; Unit* current = *pPrev;
@@ -308,5 +306,5 @@ void BrokenAPI::fail(const char* file, int line, const char* expression, const c
fprintf(dst, " SOURCE: %s (Line: %d)\n", file, line); fprintf(dst, " SOURCE: %s (Line: %d)\n", file, line);
fflush(dst); fflush(dst);
exit(1); abort();
} }

View File

@@ -38,79 +38,125 @@
//! \cond //! \cond
// ============================================================================ // Broken - API
// [Broken - API] // ============
// ============================================================================
struct BrokenAPI { namespace BrokenAPI {
//! Entry point of a unit test defined by `UNIT` macro.
typedef void (*Entry)(void);
enum Flags : unsigned { //! Entry point of a unit test defined by `UNIT` macro.
kFlagFinished = 0x1 typedef void (*Entry)(void);
};
//! Test defined by `UNIT` macro. enum Flags : unsigned {
struct Unit { kFlagFinished = 0x1
Entry entry; };
const char* name;
int priority;
unsigned flags;
Unit* next;
};
//! Automatic unit registration by using static initialization. struct Unit;
struct AutoUnit : Unit {
inline AutoUnit(Entry entry_, const char* name_, int priority_ = 0, int dummy_ = 0) noexcept {
// Not used, only to trick `UNIT()` macro.
(void)dummy_;
this->entry = entry_; bool hasArg(const char* name) noexcept;
this->name = name_;
this->priority = priority_;
this->flags = 0;
this->next = nullptr;
BrokenAPI::add(this);
}
};
static bool hasArg(const char* name) noexcept; //! Register a new unit test (called automatically by `AutoUnit` and `UNIT`).
void addUnit(Unit* unit) noexcept;
//! Register a new unit test (called automatically by `AutoUnit` and `UNIT`). //! Set output file to a `file`.
static void add(Unit* unit) noexcept; void setOutputFile(FILE* file) noexcept;
//! Set output file to a `file`. //! Initialize `Broken` framework.
static void setOutputFile(FILE* file) noexcept; //!
//! Returns `true` if `run()` should be called.
int run(int argc, const char* argv[], Entry onBeforeRun = nullptr, Entry onAfterRun = nullptr);
//! Initialize `Broken` framework. //! Log message, adds automatically new line if not present.
//! void info(const char* fmt, ...) noexcept;
//! Returns `true` if `run()` should be called.
static int run(int argc, const char* argv[], Entry onBeforeRun = nullptr, Entry onAfterRun = nullptr);
//! Log message, adds automatically new line if not present. //! Called on `EXPECT()` failure.
static void info(const char* fmt, ...) noexcept; void fail(const char* file, int line, const char* expression, const char* fmt, ...) noexcept;
//! Called on `EXPECT()` failure. //! Test defined by `UNIT` macro.
static void fail(const char* file, int line, const char* expression, const char* fmt, ...) noexcept; struct Unit {
Entry entry;
const char* name;
int priority;
unsigned flags;
Unit* next;
};
//! Used internally by `EXPECT` macro. //! Automatic unit registration by using static initialization.
template<typename T> class AutoUnit : public Unit {
static inline void expect(const char* file, int line, const char* expression, const T& result) noexcept { public:
if (!result) inline AutoUnit(Entry entry_, const char* name_, int priority_ = 0, int dummy_ = 0) noexcept {
fail(file, line, expression, nullptr); // Not used, only to trick `UNIT()` macro.
} (void)dummy_;
//! Used internally by `EXPECT` macro. this->entry = entry_;
template<typename T, typename... Args> this->name = name_;
static inline void expect(const char* file, int line, const char* expression, const T& result, const char* fmt, Args&&... args) noexcept { this->priority = priority_;
if (!result) this->flags = 0;
fail(file, line, expression, fmt, std::forward<Args>(args)...); this->next = nullptr;
addUnit(this);
} }
}; };
// ============================================================================ class Failure {
// [Broken - Macros] public:
// ============================================================================ const char* _file = nullptr;
const char* _expression = nullptr;
int _line = 0;
bool _handled = false;
inline Failure(const char* file, int line, const char* expression) noexcept
: _file(file),
_expression(expression),
_line(line) {}
inline ~Failure() noexcept {
if (!_handled)
fail(_file, _line, _expression, nullptr);
}
template<typename... Args>
inline void message(const char* fmt, Args&&... args) noexcept {
fail(_file, _line, _expression, fmt, std::forward<Args>(args)...);
_handled = true;
}
};
template<typename Result>
static inline bool check(Result&& result) noexcept { return !!result; }
template<typename LHS, typename RHS>
static inline bool checkEq(LHS&& lhs, RHS&& rhs) noexcept { return lhs == rhs; }
template<typename LHS, typename RHS>
static inline bool checkNe(LHS&& lhs, RHS&& rhs) noexcept { return lhs != rhs; }
template<typename LHS, typename RHS>
static inline bool checkGt(LHS&& lhs, RHS&& rhs) noexcept { return lhs > rhs; }
template<typename LHS, typename RHS>
static inline bool checkGe(LHS&& lhs, RHS&& rhs) noexcept { return lhs >= rhs; }
template<typename LHS, typename RHS>
static inline bool checkLt(LHS&& lhs, RHS&& rhs) noexcept { return lhs < rhs; }
template<typename LHS, typename RHS>
static inline bool checkLe(LHS&& lhs, RHS&& rhs) noexcept { return lhs <= rhs; }
template<typename Result>
static inline bool checkTrue(Result&& result) noexcept { return !!result; }
template<typename Result>
static inline bool checkFalse(Result&& result) noexcept { return !result; }
template<typename Result>
static inline bool checkNull(Result&& result) noexcept { return result == nullptr; }
template<typename Result>
static inline bool checkNotNull(Result&& result) noexcept { return result != nullptr; }
} // {BrokenAPI}
// Broken - Macros
// ===============
//! Internal macro used by `UNIT()`. //! Internal macro used by `UNIT()`.
#define BROKEN_UNIT_INTERNAL(NAME, PRIORITY) \ #define BROKEN_UNIT_INTERNAL(NAME, PRIORITY) \
@@ -118,19 +164,14 @@ struct BrokenAPI {
static ::BrokenAPI::AutoUnit unit_##NAME##_autoinit(unit_##NAME##_entry, #NAME, PRIORITY); \ static ::BrokenAPI::AutoUnit unit_##NAME##_autoinit(unit_##NAME##_entry, #NAME, PRIORITY); \
static void unit_##NAME##_entry(void) static void unit_##NAME##_entry(void)
//! Stringifies the expression used by EXPECT().
#define BROKEN_STRINFIGY_EXPRESSION_INTERNAL(EXP, ...) #EXP
//! \def UNIT(NAME [, PRIORITY]) //! \def UNIT(NAME [, PRIORITY])
//! //!
//! Define a unit test with an optional priority. //! Define a unit test with an optional priority.
//! //!
//! `NAME` can only contain ASCII characters, numbers and underscore. It has //! `NAME` can only contain ASCII characters, numbers and underscore. It has the same rules as identifiers in C and C++.
//! the same rules as identifiers in C and C++.
//! //!
//! `PRIORITY` specifies the order in which unit tests are run. Lesses value //! `PRIORITY` specifies the order in which unit tests are run. Lesses value increases the priority. At the moment all
//! increases the priority. At the moment all units are first sorted by //!units are first sorted by priority and then by name - this makes the run always deterministic.
//! priority and then by name - this makes the run always deterministic.
#define UNIT(NAME, ...) BROKEN_UNIT_INTERNAL(NAME, __VA_ARGS__ + 0) #define UNIT(NAME, ...) BROKEN_UNIT_INTERNAL(NAME, __VA_ARGS__ + 0)
//! #define INFO(FORMAT [, ...]) //! #define INFO(FORMAT [, ...])
@@ -138,10 +179,21 @@ struct BrokenAPI {
//! Informative message printed to `stdout`. //! Informative message printed to `stdout`.
#define INFO(...) ::BrokenAPI::info(__VA_ARGS__) #define INFO(...) ::BrokenAPI::info(__VA_ARGS__)
//! #define INFO(EXP [, FORMAT [, ...]]) #define BROKEN_EXPECT_INTERNAL(file, line, expression, result) \
//! for (bool _testInternalResult = (result); !_testInternalResult; _testInternalResult = true) \
//! Expect `EXP` to be true or evaluates to true, fail otherwise. ::BrokenAPI::Failure(file, line, expression)
#define EXPECT(...) ::BrokenAPI::expect(__FILE__, __LINE__, BROKEN_STRINFIGY_EXPRESSION_INTERNAL(__VA_ARGS__), __VA_ARGS__)
#define EXPECT(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT(" #__VA_ARGS__ ")", !!(__VA_ARGS__))
#define EXPECT_EQ(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_EQ(" #__VA_ARGS__ ")", ::BrokenAPI::checkEq(__VA_ARGS__))
#define EXPECT_NE(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_NE(" #__VA_ARGS__ ")", ::BrokenAPI::checkNe(__VA_ARGS__))
#define EXPECT_GT(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_GT(" #__VA_ARGS__ ")", ::BrokenAPI::checkGt(__VA_ARGS__))
#define EXPECT_GE(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_GE(" #__VA_ARGS__ ")", ::BrokenAPI::checkGe(__VA_ARGS__))
#define EXPECT_LT(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_LT(" #__VA_ARGS__ ")", ::BrokenAPI::checkLt(__VA_ARGS__))
#define EXPECT_LE(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_LE(" #__VA_ARGS__ ")", ::BrokenAPI::checkLe(__VA_ARGS__))
#define EXPECT_TRUE(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_TRUE(" #__VA_ARGS__ ")", ::BrokenAPI::checkTrue(__VA_ARGS__))
#define EXPECT_FALSE(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_FALSE(" #__VA_ARGS__ ")", ::BrokenAPI::checkFalse(__VA_ARGS__))
#define EXPECT_NULL(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_NULL(" #__VA_ARGS__ ")", ::BrokenAPI::checkNull(__VA_ARGS__))
#define EXPECT_NOT_NULL(...) BROKEN_EXPECT_INTERNAL(__FILE__, __LINE__, "EXPECT_NOT_NULL(" #__VA_ARGS__ ")", ::BrokenAPI::checkNotNull(__VA_ARGS__))
//! \endcond //! \endcond