Commit 595c2427 authored by fbarchard@google.com's avatar fbarchard@google.com

Simple FixedDiv that does integer divide instruction with 64 bit dividend and 32…

Simple FixedDiv that does integer divide instruction with 64 bit dividend and 32 bit divisor to produce 32 bit result.
BUG=250
TEST=math_test
R=dingkai@google.com

Review URL: https://webrtc-codereview.appspot.com/1681006

git-svn-id: http://libyuv.googlecode.com/svn/trunk@736 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent e5d3e10e
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 735
Version: 736
License: BSD
License File: LICENSE
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 735
#define LIBYUV_VERSION 736
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
This diff is collapsed.
......@@ -5401,35 +5401,16 @@ void I422ToUYVYRow_SSE2(const uint8* src_y,
);
}
// Fixed point 0.32 reciprocal table.
extern const uint32 kRecipTable[4097];
// Divide num by div and return as 16.16 fixed point result.
int FixedDiv(int num, int div) {
asm volatile (
"cmp $0x1000,%%ecx \n"
"jbe 1f \n"
"cdq \n"
"shld $0x10,%%eax,%%edx \n"
"shl $0x10,%%eax \n"
"idiv %%ecx \n"
"jmp 9f \n"
"1: \n"
#if defined(__x86_64__)
"mull (%2,%%rcx,4) \n"
#else
"mull (%2,%%ecx,4) \n"
#endif
"shrd $0x10,%%edx,%%eax \n"
"adc $0,%%eax \n"
"9: \n"
"idiv %1 \n"
"mov %0, %%eax \n"
: "+a"(num) // %0
: "c"(div), // %1
"r"(kRecipTable) // %2
: "c"(div) // %1
: "memory", "cc", "edx"
);
return num;
......
......@@ -6603,27 +6603,15 @@ void I422ToUYVYRow_SSE2(const uint8* src_y,
}
}
// Fixed point 0.32 reciprocal table.
extern const uint32 kRecipTable[4097];
// Divide num by div and return as 16.16 fixed point result.
__declspec(naked) __declspec(align(16))
int FixedDiv(int num, int div) {
__asm {
mov eax, [esp + 4] // num
mov ecx, [esp + 8] // div
cmp ecx, 4096
ja largediv
mul dword ptr kRecipTable[ecx * 4]
shrd eax, edx, 16
adc eax, 0
ret
largediv:
cdq // extend num to 64 bits
shld edx, eax, 16
shld edx, eax, 16 // 32.16
shl eax, 16
idiv ecx
idiv dword ptr [esp + 8]
ret
}
}
......
......@@ -47,6 +47,16 @@ TEST_F(libyuvTest, TestFixedDiv) {
EXPECT_EQ(0x10000, libyuv::FixedDiv(4097, 4097));
EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1));
for (int i = 1; i < 4100; ++i) {
EXPECT_EQ(0x10000, libyuv::FixedDiv(i, i));
EXPECT_EQ(0x20000, libyuv::FixedDiv(i * 2, i));
EXPECT_EQ(0x30000, libyuv::FixedDiv(i * 3, i));
EXPECT_EQ(0x40000, libyuv::FixedDiv(i * 4, i));
EXPECT_EQ(0x08000, libyuv::FixedDiv(i, i * 2));
EXPECT_NEAR(16384 * 65536 / i, libyuv::FixedDiv(16384, i), 1);
}
EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1));
srandom(time(NULL));
MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num));
MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment