Commit c9f0d966 authored by fbarchard@google.com's avatar fbarchard@google.com

FixedDiv port to gcc

BUG=250
TEST=*Div*
R=ryanpetrie@google.com

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

git-svn-id: http://libyuv.googlecode.com/svn/trunk@733 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 747ceb9f
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 732
Version: 733
License: BSD
License File: LICENSE
......
......@@ -101,6 +101,7 @@ extern "C" {
#define HAS_YUY2TOUV422ROW_SSE2
#define HAS_YUY2TOUVROW_SSE2
#define HAS_YUY2TOYROW_SSE2
#define HAS_FIXEDDIV
// Effects
#define HAS_ARGBADDROW_SSE2
......@@ -130,7 +131,6 @@ extern "C" {
// TODO(fbarchard): Port to gcc.
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER)
#define HAS_ARGBCOLORTABLEROW_X86
#define HAS_FIXEDDIV
// Visual C 2012 required for AVX2.
#if _MSC_VER >= 1700
#define HAS_ARGBSHUFFLEROW_AVX2
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 732
#define LIBYUV_VERSION 733
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
This diff is collapsed.
......@@ -5401,6 +5401,38 @@ 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"
"9: \n"
"mov %0, %%eax \n"
: "+a"(num) // %0
: "c"(div), // %1
"r"(kRecipTable) // %2
: "memory", "cc", "edx"
);
return num;
}
#endif // defined(__x86_64__) || defined(__i386__)
#ifdef __cplusplus
......
......@@ -6619,7 +6619,7 @@ int FixedDiv(int num, int div) {
ret
largediv:
cwd // extend num to 64 bits
cdq // extend num to 64 bits
shld edx, eax, 16
shl eax, 16
idiv ecx
......
......@@ -39,7 +39,7 @@ TEST_F(libyuvTest, Djb2_Test) {
" and feels as if he were in the seventh heaven of typography"
" together with Hermann Zapf";
uint32 foxhash = HashDjb2(reinterpret_cast<const uint8*>(fox), 131, 5381);
const uint32 kExpectedFoxHash = 2611006483;
const uint32 kExpectedFoxHash = 2611006483u;
EXPECT_EQ(kExpectedFoxHash, foxhash);
for (int i = 0; i < kMaxTest; ++i) {
......
......@@ -24,6 +24,29 @@ TEST_F(libyuvTest, TestFixedDiv) {
int result_opt[256];
int result_c[256];
EXPECT_EQ(0x20000, libyuv::FixedDiv(640 * 2, 640));
EXPECT_EQ(0x30000, libyuv::FixedDiv(640 * 3, 640));
EXPECT_EQ(0x40000, libyuv::FixedDiv(640 * 4, 640));
EXPECT_EQ(0x50000, libyuv::FixedDiv(640 * 5, 640));
EXPECT_EQ(0x60000, libyuv::FixedDiv(640 * 6, 640));
EXPECT_EQ(0x70000, libyuv::FixedDiv(640 * 7, 640));
EXPECT_EQ(0x80000, libyuv::FixedDiv(640 * 8, 640));
EXPECT_EQ(0xa0000, libyuv::FixedDiv(640 * 10, 640));
EXPECT_EQ(0x20000, libyuv::FixedDiv(960 * 2, 960));
EXPECT_EQ(0x08000, libyuv::FixedDiv(640 / 2, 640));
EXPECT_EQ(0x04000, libyuv::FixedDiv(640 / 4, 640));
EXPECT_EQ(0x20000, libyuv::FixedDiv(1080 * 2, 1080));
EXPECT_EQ(0x20000, libyuv::FixedDiv(200000, 100000));
EXPECT_EQ(0x18000, libyuv::FixedDiv(150000, 100000));
EXPECT_EQ(0x20000, libyuv::FixedDiv(40000, 20000));
EXPECT_EQ(0x20000, libyuv::FixedDiv(-40000, -20000));
EXPECT_EQ(-0x20000, libyuv::FixedDiv(40000, -20000));
EXPECT_EQ(-0x20000, libyuv::FixedDiv(-40000, 20000));
EXPECT_NEAR(0x10000, libyuv::FixedDiv(4095, 4095), 1);
EXPECT_EQ(0x10000, libyuv::FixedDiv(4096, 4096));
EXPECT_EQ(0x10000, libyuv::FixedDiv(4097, 4097));
EXPECT_NEAR(123 * 65536, libyuv::FixedDiv(123, 1), 1);
srandom(time(NULL));
MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num));
MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div));
......@@ -49,19 +72,6 @@ TEST_F(libyuvTest, TestFixedDiv_Opt) {
int result_opt[256];
int result_c[256];
EXPECT_EQ(0x20000, libyuv::FixedDiv(640 * 2, 640));
EXPECT_EQ(0x30000, libyuv::FixedDiv(640 * 3, 640));
EXPECT_EQ(0x40000, libyuv::FixedDiv(640 * 4, 640));
EXPECT_EQ(0x50000, libyuv::FixedDiv(640 * 5, 640));
EXPECT_EQ(0x60000, libyuv::FixedDiv(640 * 6, 640));
EXPECT_EQ(0x70000, libyuv::FixedDiv(640 * 7, 640));
EXPECT_EQ(0x80000, libyuv::FixedDiv(640 * 8, 640));
EXPECT_EQ(0xa0000, libyuv::FixedDiv(640 * 10, 640));
EXPECT_EQ(0x20000, libyuv::FixedDiv(960 * 2, 960));
EXPECT_EQ(0x08000, libyuv::FixedDiv(640 / 2, 640));
EXPECT_EQ(0x04000, libyuv::FixedDiv(640 / 4, 640));
EXPECT_EQ(0x20000, libyuv::FixedDiv(1080 * 2, 1080));
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