⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test-i386.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  x86 CPU test *  *  Copyright (c) 2003 Fabrice Bellard * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#define _GNU_SOURCE#include <stdlib.h>#include <stdio.h>#include <string.h>#include <inttypes.h>#include <math.h>#include <signal.h>#include <setjmp.h>#include <errno.h>#include <sys/ucontext.h>#include <sys/mman.h>#if !defined(__x86_64__)#define TEST_VM86#define TEST_SEGS#endif//#define LINUX_VM86_IOPL_FIX//#define TEST_P4_FLAGS#if defined(__x86_64__)#define TEST_SSE#define TEST_CMOV  1#define TEST_FCOMI 1#else//#define TEST_SSE#define TEST_CMOV  0#define TEST_FCOMI 0#endif#if defined(__x86_64__)#define FMT64X "%016lx"#define FMTLX "%016lx"#define X86_64_ONLY(x) x#else#define FMT64X "%016llx"#define FMTLX "%08lx"#define X86_64_ONLY(x)#endif#ifdef TEST_VM86#include <asm/vm86.h>#endif#define xglue(x, y) x ## y#define glue(x, y) xglue(x, y)#define stringify(s)	tostring(s)#define tostring(s)	#s#define CC_C   	0x0001#define CC_P 	0x0004#define CC_A	0x0010#define CC_Z	0x0040#define CC_S    0x0080#define CC_O    0x0800#define __init_call	__attribute__ ((unused,__section__ ("initcall")))#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)#if defined(__x86_64__)static inline long i2l(long v){    return v | ((v ^ 0xabcd) << 32);}#elsestatic inline long i2l(long v){    return v;}#endif#define OP add#include "test-i386.h"#define OP sub#include "test-i386.h"#define OP xor#include "test-i386.h"#define OP and#include "test-i386.h"#define OP or#include "test-i386.h"#define OP cmp#include "test-i386.h"#define OP adc#define OP_CC#include "test-i386.h"#define OP sbb#define OP_CC#include "test-i386.h"#define OP inc#define OP_CC#define OP1#include "test-i386.h"#define OP dec#define OP_CC#define OP1#include "test-i386.h"#define OP neg#define OP_CC#define OP1#include "test-i386.h"#define OP not#define OP_CC#define OP1#include "test-i386.h"#undef CC_MASK#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)#define OP shl#include "test-i386-shift.h"#define OP shr#include "test-i386-shift.h"#define OP sar#include "test-i386-shift.h"#define OP rol#include "test-i386-shift.h"#define OP ror#include "test-i386-shift.h"#define OP rcr#define OP_CC#include "test-i386-shift.h"#define OP rcl#define OP_CC#include "test-i386-shift.h"#define OP shld#define OP_SHIFTD#define OP_NOBYTE#include "test-i386-shift.h"#define OP shrd#define OP_SHIFTD#define OP_NOBYTE#include "test-i386-shift.h"/* XXX: should be more precise ? */#undef CC_MASK#define CC_MASK (CC_C)#define OP bt#define OP_NOBYTE#include "test-i386-shift.h"#define OP bts#define OP_NOBYTE#include "test-i386-shift.h"#define OP btr#define OP_NOBYTE#include "test-i386-shift.h"#define OP btc#define OP_NOBYTE#include "test-i386-shift.h"/* lea test (modrm support) */#define TEST_LEAQ(STR)\{\    asm("lea " STR ", %0"\        : "=r" (res)\        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\    printf("lea %s = " FMTLX "\n", STR, res);\}#define TEST_LEA(STR)\{\    asm("lea " STR ", %0"\        : "=r" (res)\        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\    printf("lea %s = " FMTLX "\n", STR, res);\}#define TEST_LEA16(STR)\{\    asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\        : "=wq" (res)\        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\    printf("lea %s = %08lx\n", STR, res);\}void test_lea(void){    long eax, ebx, ecx, edx, esi, edi, res;    eax = i2l(0x0001);    ebx = i2l(0x0002);    ecx = i2l(0x0004);    edx = i2l(0x0008);    esi = i2l(0x0010);    edi = i2l(0x0020);    TEST_LEA("0x4000");    TEST_LEA("(%%eax)");    TEST_LEA("(%%ebx)");    TEST_LEA("(%%ecx)");    TEST_LEA("(%%edx)");    TEST_LEA("(%%esi)");    TEST_LEA("(%%edi)");    TEST_LEA("0x40(%%eax)");    TEST_LEA("0x40(%%ebx)");    TEST_LEA("0x40(%%ecx)");    TEST_LEA("0x40(%%edx)");    TEST_LEA("0x40(%%esi)");    TEST_LEA("0x40(%%edi)");    TEST_LEA("0x4000(%%eax)");    TEST_LEA("0x4000(%%ebx)");    TEST_LEA("0x4000(%%ecx)");    TEST_LEA("0x4000(%%edx)");    TEST_LEA("0x4000(%%esi)");    TEST_LEA("0x4000(%%edi)");    TEST_LEA("(%%eax, %%ecx)");    TEST_LEA("(%%ebx, %%edx)");    TEST_LEA("(%%ecx, %%ecx)");    TEST_LEA("(%%edx, %%ecx)");    TEST_LEA("(%%esi, %%ecx)");    TEST_LEA("(%%edi, %%ecx)");    TEST_LEA("0x40(%%eax, %%ecx)");    TEST_LEA("0x4000(%%ebx, %%edx)");    TEST_LEA("(%%ecx, %%ecx, 2)");    TEST_LEA("(%%edx, %%ecx, 4)");    TEST_LEA("(%%esi, %%ecx, 8)");    TEST_LEA("(,%%eax, 2)");    TEST_LEA("(,%%ebx, 4)");    TEST_LEA("(,%%ecx, 8)");    TEST_LEA("0x40(,%%eax, 2)");    TEST_LEA("0x40(,%%ebx, 4)");    TEST_LEA("0x40(,%%ecx, 8)");    TEST_LEA("-10(%%ecx, %%ecx, 2)");    TEST_LEA("-10(%%edx, %%ecx, 4)");    TEST_LEA("-10(%%esi, %%ecx, 8)");    TEST_LEA("0x4000(%%ecx, %%ecx, 2)");    TEST_LEA("0x4000(%%edx, %%ecx, 4)");    TEST_LEA("0x4000(%%esi, %%ecx, 8)");#if defined(__x86_64__)    TEST_LEAQ("0x4000");    TEST_LEAQ("0x4000(%%rip)");    TEST_LEAQ("(%%rax)");    TEST_LEAQ("(%%rbx)");    TEST_LEAQ("(%%rcx)");    TEST_LEAQ("(%%rdx)");    TEST_LEAQ("(%%rsi)");    TEST_LEAQ("(%%rdi)");    TEST_LEAQ("0x40(%%rax)");    TEST_LEAQ("0x40(%%rbx)");    TEST_LEAQ("0x40(%%rcx)");    TEST_LEAQ("0x40(%%rdx)");    TEST_LEAQ("0x40(%%rsi)");    TEST_LEAQ("0x40(%%rdi)");    TEST_LEAQ("0x4000(%%rax)");    TEST_LEAQ("0x4000(%%rbx)");    TEST_LEAQ("0x4000(%%rcx)");    TEST_LEAQ("0x4000(%%rdx)");    TEST_LEAQ("0x4000(%%rsi)");    TEST_LEAQ("0x4000(%%rdi)");    TEST_LEAQ("(%%rax, %%rcx)");    TEST_LEAQ("(%%rbx, %%rdx)");    TEST_LEAQ("(%%rcx, %%rcx)");    TEST_LEAQ("(%%rdx, %%rcx)");    TEST_LEAQ("(%%rsi, %%rcx)");    TEST_LEAQ("(%%rdi, %%rcx)");    TEST_LEAQ("0x40(%%rax, %%rcx)");    TEST_LEAQ("0x4000(%%rbx, %%rdx)");    TEST_LEAQ("(%%rcx, %%rcx, 2)");    TEST_LEAQ("(%%rdx, %%rcx, 4)");    TEST_LEAQ("(%%rsi, %%rcx, 8)");    TEST_LEAQ("(,%%rax, 2)");    TEST_LEAQ("(,%%rbx, 4)");    TEST_LEAQ("(,%%rcx, 8)");    TEST_LEAQ("0x40(,%%rax, 2)");    TEST_LEAQ("0x40(,%%rbx, 4)");    TEST_LEAQ("0x40(,%%rcx, 8)");    TEST_LEAQ("-10(%%rcx, %%rcx, 2)");    TEST_LEAQ("-10(%%rdx, %%rcx, 4)");    TEST_LEAQ("-10(%%rsi, %%rcx, 8)");    TEST_LEAQ("0x4000(%%rcx, %%rcx, 2)");    TEST_LEAQ("0x4000(%%rdx, %%rcx, 4)");    TEST_LEAQ("0x4000(%%rsi, %%rcx, 8)");#else    /* limited 16 bit addressing test */    TEST_LEA16("0x4000");    TEST_LEA16("(%%bx)");    TEST_LEA16("(%%si)");    TEST_LEA16("(%%di)");    TEST_LEA16("0x40(%%bx)");    TEST_LEA16("0x40(%%si)");    TEST_LEA16("0x40(%%di)");    TEST_LEA16("0x4000(%%bx)");    TEST_LEA16("0x4000(%%si)");    TEST_LEA16("(%%bx,%%si)");    TEST_LEA16("(%%bx,%%di)");    TEST_LEA16("0x40(%%bx,%%si)");    TEST_LEA16("0x40(%%bx,%%di)");    TEST_LEA16("0x4000(%%bx,%%si)");    TEST_LEA16("0x4000(%%bx,%%di)");#endif}#define TEST_JCC(JCC, v1, v2)\{\    int res;\    asm("movl $1, %0\n\t"\        "cmpl %2, %1\n\t"\        "j" JCC " 1f\n\t"\        "movl $0, %0\n\t"\        "1:\n\t"\        : "=r" (res)\        : "r" (v1), "r" (v2));\    printf("%-10s %d\n", "j" JCC, res);\\    asm("movl $0, %0\n\t"\        "cmpl %2, %1\n\t"\        "set" JCC " %b0\n\t"\        : "=r" (res)\        : "r" (v1), "r" (v2));\    printf("%-10s %d\n", "set" JCC, res);\ if (TEST_CMOV) {\    long val = i2l(1);\    long res = i2l(0x12345678);\X86_64_ONLY(\    asm("cmpl %2, %1\n\t"\        "cmov" JCC "q %3, %0\n\t"\        : "=r" (res)\        : "r" (v1), "r" (v2), "m" (val), "0" (res));\        printf("%-10s R=" FMTLX "\n", "cmov" JCC "q", res);)\    asm("cmpl %2, %1\n\t"\        "cmov" JCC "l %k3, %k0\n\t"\        : "=r" (res)\        : "r" (v1), "r" (v2), "m" (val), "0" (res));\        printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);\    asm("cmpl %2, %1\n\t"\        "cmov" JCC "w %w3, %w0\n\t"\        : "=r" (res)\        : "r" (v1), "r" (v2), "r" (1), "0" (res));\        printf("%-10s R=" FMTLX "\n", "cmov" JCC "w", res);\ } \}/* various jump tests */void test_jcc(void){    TEST_JCC("ne", 1, 1);    TEST_JCC("ne", 1, 0);    TEST_JCC("e", 1, 1);    TEST_JCC("e", 1, 0);    TEST_JCC("l", 1, 1);    TEST_JCC("l", 1, 0);    TEST_JCC("l", 1, -1);    TEST_JCC("le", 1, 1);    TEST_JCC("le", 1, 0);    TEST_JCC("le", 1, -1);    TEST_JCC("ge", 1, 1);    TEST_JCC("ge", 1, 0);    TEST_JCC("ge", -1, 1);    TEST_JCC("g", 1, 1);    TEST_JCC("g", 1, 0);    TEST_JCC("g", 1, -1);    TEST_JCC("b", 1, 1);    TEST_JCC("b", 1, 0);    TEST_JCC("b", 1, -1);    TEST_JCC("be", 1, 1);    TEST_JCC("be", 1, 0);    TEST_JCC("be", 1, -1);    TEST_JCC("ae", 1, 1);    TEST_JCC("ae", 1, 0);    TEST_JCC("ae", 1, -1);    TEST_JCC("a", 1, 1);    TEST_JCC("a", 1, 0);    TEST_JCC("a", 1, -1);    TEST_JCC("p", 1, 1);    TEST_JCC("p", 1, 0);    TEST_JCC("np", 1, 1);    TEST_JCC("np", 1, 0);    TEST_JCC("o", 0x7fffffff, 0);    TEST_JCC("o", 0x7fffffff, -1);    TEST_JCC("no", 0x7fffffff, 0);    TEST_JCC("no", 0x7fffffff, -1);    TEST_JCC("s", 0, 1);    TEST_JCC("s", 0, -1);    TEST_JCC("s", 0, 0);    TEST_JCC("ns", 0, 1);    TEST_JCC("ns", 0, -1);    TEST_JCC("ns", 0, 0);}#undef CC_MASK#ifdef TEST_P4_FLAGS#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)#else#define CC_MASK (CC_O | CC_C)#endif#define OP mul#include "test-i386-muldiv.h"#define OP imul#include "test-i386-muldiv.h"void test_imulw2(long op0, long op1) {    long res, s1, s0, flags;    s0 = op0;    s1 = op1;    res = s0;    flags = 0;    asm volatile ("push %4\n\t"         "popf\n\t"         "imulw %w2, %w0\n\t"          "pushf\n\t"         "pop %1\n\t"         : "=q" (res), "=g" (flags)         : "q" (s1), "0" (res), "1" (flags));    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",           "imulw", s0, s1, res, flags & CC_MASK);}void test_imull2(long op0, long op1) {    long res, s1, s0, flags;    s0 = op0;    s1 = op1;    res = s0;    flags = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -