Skip to content
Permalink
Browse files

Implement and test clz32, use it in the MIPS interpreter cores.

This will be useful for our vfpu-dot implementations later.
  • Loading branch information...
hrydgard committed Jun 14, 2019
1 parent 730fd06 commit 30831f3ea1bdcce53c7ad62c3c0790a866a02dad
Showing with 71 additions and 33 deletions.
  1. +36 −0 Common/BitScan.h
  2. +1 −1 Common/Common.vcxproj
  3. +2 −1 Common/Common.vcxproj.filters
  4. +2 −8 Core/MIPS/IR/IRInterpreter.cpp
  5. +3 −23 Core/MIPS/MIPSInt.cpp
  6. +27 −0 unittest/UnitTest.cpp
@@ -0,0 +1,36 @@
#pragma once

#include "ppsspp_config.h"

#if PPSSPP_PLATFORM(WINDOWS)
#include "Common/CommonWindows.h"

// Use this if you know the value is non-zero.
inline uint32_t clz32_nonzero(uint32_t value) {
DWORD index;
BitScanReverse(&index, value);
return 31 ^ (uint32_t)index;
}

inline uint32_t clz32(uint32_t value) {
if (!value)
return 32;
DWORD index;
BitScanReverse(&index, value);
return 31 ^ (uint32_t)index;
}

#else

// Use this if you know the value is non-zero.
inline uint32_t clz32_nonzero(uint32_t value) {
return __builtin_clz(value);
}

inline uint32_t clz32(uint32_t value) {
if (!value)
return 32;
return __builtin_clz(value);
}

#endif
@@ -128,7 +128,6 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -384,6 +383,7 @@
<ClInclude Include="Atomics.h" />
<ClInclude Include="Atomic_GCC.h" />
<ClInclude Include="Atomic_Win32.h" />
<ClInclude Include="BitScan.h" />
<ClInclude Include="BitSet.h" />
<ClInclude Include="ColorConvNEON.h" />
<ClInclude Include="ChunkFile.h" />
@@ -73,6 +73,7 @@
<ClInclude Include="OSVersion.h" />
<ClInclude Include="Hashmaps.h" />
<ClInclude Include="Vulkan\VulkanDebug.h" />
<ClInclude Include="BitScan.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@@ -149,4 +150,4 @@
<UniqueIdentifier>{c14d66ef-5f7c-4565-975a-72774e7ccfb9}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>
@@ -4,6 +4,7 @@
#include "ppsspp_config.h"
#include "math/math_util.h"
#include "Common/Common.h"
#include "Common/BitScan.h"

#ifdef _M_SSE
#include <emmintrin.h>
@@ -563,14 +564,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {

case IROp::Clz:
{
int x = 31;
int count = 0;
int value = mips->r[inst->src1];
while (x >= 0 && !(value & (1 << x))) {
count++;
x--;
}
mips->r[inst->dest] = count;
mips->r[inst->dest] = clz32(mips->r[inst->src1]);
break;
}

@@ -15,13 +15,12 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

// MIPS is really trivial :)

#include <cmath>

#include "math/math_util.h"

#include "Common/Common.h"
#include "Common/BitScan.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "Core/Host.h"
@@ -281,7 +280,6 @@ namespace MIPSInt
switch (op & 0x3f)
{
case 8: //jr
// LOG(CPU,"returning from: %08x",PC);
DelayBranchTo(addr);
break;
case 9: //jalr
@@ -551,28 +549,10 @@ namespace MIPSInt
switch (op & 63)
{
case 22: //clz
{ //TODO: verify
int x = 31;
int count=0;
while (x >= 0 && !(R(rs) & (1<<x)))
{
count++;
x--;
}
R(rd) = count;
}
R(rd) = clz32(R(rs));
break;
case 23: //clo
{ //TODO: verify
int x = 31;
int count=0;
while (x >= 0 && (R(rs) & (1<<x)))
{
count++;
x--;
}
R(rd) = count;
}
R(rd) = clz32(~R(rs));
break;
default:
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
@@ -31,6 +31,9 @@
#include <string>
#include <sstream>

#include "Common/BitScan.h"
#include "Core/MIPS/MIPSVFPUUtils.h"

#include "base/NativeApp.h"
#include "base/logging.h"
#include "input/input_state.h"
@@ -459,6 +462,29 @@ bool TestQuickTexHash() {
return true;
}

bool TestCLZ() {
static const uint32_t input[] = {
0xFFFFFFFF,
0x00FFFFF0,
0x00101000,
0x00003000,
0x00000001,
0x00000000,
};
static const uint32_t expected[] = {
0,
8,
11,
18,
31,
32,
};
for (int i = 0; i < ARRAY_SIZE(input); i++) {
EXPECT_EQ_INT(clz32(input[i]), expected[i]);
}
return true;
}

typedef bool (*TestFunc)();
struct TestItem {
const char *name;
@@ -491,6 +517,7 @@ TestItem availableTests[] = {
TEST_ITEM(MatrixTranspose),
TEST_ITEM(ParseLBN),
TEST_ITEM(QuickTexHash),
TEST_ITEM(CLZ),
};

int main(int argc, const char *argv[]) {

0 comments on commit 30831f3

Please sign in to comment.
You can’t perform that action at this time.