/*
Copyright (C) JAEHYUK CHO
All rights reserved.
Author: JAEHYUK CHO <mailto:minzkn@minzkn.com>
*/
#include <stdio.h>
#define DEF_TESTCOUNT (10)
typedef unsigned long long t_mz_qword;
#define DEF_ASM __asm__ volatile
#define DEF_RDTSC(m_X) DEF_ASM("rdtsc\n\t" : "=A"(m_X))
#define __emit_x8__(m_X) do{ {m_X}{m_X}{m_X}{m_X} {m_X}{m_X}{m_X}{m_X} }while(0)
#define __emit_x32__(m_X) do{ __emit_x8__(m_X); __emit_x8__(m_X); __emit_x8__(m_X); __emit_x8__(m_X); }while(0)
#define __emit_x128__(m_X) do{ __emit_x32__(m_X); __emit_x32__(m_X); __emit_x32__(m_X); __emit_x32__(m_X); }while(0)
#define __emit_x512__(m_X) do{ __emit_x128__(m_X); __emit_x128__(m_X); __emit_x128__(m_X); __emit_x128__(m_X); }while(0)
#define __emit_x2048__(m_X) do{ __emit_x512__(m_X); __emit_x512__(m_X); __emit_x512__(m_X); __emit_x512__(m_X); }while(0)
/* Inline loop code */
#define __emit_code__(m_X) __emit_x2048__(m_X)
/* Volatile var */
volatile unsigned int g_resx = 640;
volatile unsigned int g_resy = 480;
volatile unsigned int g_x = 640 >> 1;
volatile unsigned int g_y = 480 >> 1;
volatile unsigned int g_result = 0;
t_mz_qword test0(void)
{
/* ** */ t_mz_qword s_p_start, s_p_end;
/* ** */ DEF_RDTSC(s_p_start);
/* ** */ __emit_code__(
/* !! */ g_result = (g_y * 640) + g_x;
/* ** */ );
/* ** */ DEF_RDTSC(s_p_end);
/* ** */ return(s_p_end - s_p_start);
}
t_mz_qword test1(void)
{
/* ** */ t_mz_qword s_p_start, s_p_end;
/* ** */ DEF_RDTSC(s_p_start);
/* ** */ DEF_ASM("\n\t":: "d"(g_x), "c"(g_y));
/* ** */ __emit_code__(
/* ** */ DEF_ASM(
/* ** */ "movl %%ecx, %%eax\n\t"
/* !! */ "leal (%%eax,%%eax,4),%%eax\n\t"
/* !! */ "shll $0x07, %%eax\n\t"
/* ** */ "addl %%edx, %%eax\n\t"
/* ** */ ::);
/* ** */ );
/* ** */ DEF_ASM("\n\t": "=a"(g_result));
/* ** */ DEF_RDTSC(s_p_end);
/* ** */ return(s_p_end - s_p_start);
}
t_mz_qword test2(void)
{
/* ** */ t_mz_qword s_p_start, s_p_end;
/* ** */ DEF_RDTSC(s_p_start);
/* ** */ DEF_ASM("\n\t":: "d"(g_x), "c"(g_y));
/* ** */ __emit_code__(
/* ** */ DEF_ASM(
/* ** */ "movl %%ecx, %%eax\n\t"
/* !! */ "imul $640, %%eax, %%eax\n\t"
/* ** */ "addl %%edx, %%eax\n\t"
/* ** */ ::);
/* ** */ );
/* ** */ DEF_ASM("\n\t": "=a"(g_result));
/* ** */ DEF_RDTSC(s_p_end);
/* ** */ return(s_p_end - s_p_start);
}
t_mz_qword test3(void)
{
/* ** */ t_mz_qword s_p_start, s_p_end;
/* ** */ DEF_RDTSC(s_p_start);
/* ** */ DEF_ASM("\n\t":: "d"(g_x), "c"(g_y));
/* ** */ __emit_code__(
/* ** */ DEF_ASM(
/* ** */ "movl %%ecx, %%eax\n\t"
/* !! */ "leal (%%eax,%%eax,4),%%eax\n\t"
/* !! */ "addl %%eax, %%eax\n\t" /* 1 */
/* !! */ "addl %%eax, %%eax\n\t" /* 2 */
/* !! */ "addl %%eax, %%eax\n\t" /* 3 */
/* !! */ "addl %%eax, %%eax\n\t" /* 4 */
/* !! */ "addl %%eax, %%eax\n\t" /* 5 */
/* !! */ "addl %%eax, %%eax\n\t" /* 6 */
/* !! */ "addl %%eax, %%eax\n\t" /* 7 */
/* ** */ "addl %%edx, %%eax\n\t"
/* ** */ ::);
/* ** */ );
/* ** */ DEF_ASM("\n\t": "=a"(g_result));
/* ** */ DEF_RDTSC(s_p_end);
/* ** */ return(s_p_end - s_p_start);
}
void test(int s_TestCount)
{
t_mz_qword s_p_start, s_p_end;
t_mz_qword s_p_test_0, s_p_test_1, s_p_test_2, s_p_test_3;
unsigned int s_result_0, s_result_1, s_result_2, s_result_3;
/* start */
DEF_RDTSC(s_p_start);
g_result = 0; s_p_test_0 = test0(); s_result_0 = g_result;
g_result = 0; s_p_test_1 = test1(); s_result_1 = g_result;
g_result = 0; s_p_test_2 = test2(); s_result_2 = g_result;
g_result = 0; s_p_test_3 = test3(); s_result_3 = g_result;
DEF_RDTSC(s_p_end);
/* report */
fprintf(stdout,
"=== TEST [%d] === -------------------------------------- (%8llu clock)\n"
"test_0 : %8llu (result=%u) /* C source */\n"
"test_1 : %8llu (result=%u) /* LEA + SHL */\n"
"test_2 : %8llu (result=%u) /* IMUL */\n"
"test_3 : %8llu (result=%u) /* LEA + ADDx7 */\n"
"\n",
s_TestCount, s_p_end - s_p_start,
s_p_test_0, s_result_0,
s_p_test_1, s_result_1,
s_p_test_2, s_result_2,
s_p_test_3, s_result_3);
}
int main(void)
{
int s_TestCount;
fprintf(stdout, "TEST START !\n");
for(s_TestCount = 1;s_TestCount <= DEF_TESTCOUNT;s_TestCount++)test(s_TestCount);
fprintf(stdout, "\nEnd of test.\n");
return(0);
}
/* End of source */