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

📄 test-i386.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    asm volatile ("push %4\n\t"         "popf\n\t"         "imull %k2, %k0\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",           "imull", s0, s1, res, flags & CC_MASK);}#if defined(__x86_64__)void test_imulq2(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"         "imulq %2, %0\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",           "imulq", s0, s1, res, flags & CC_MASK);}#endif#define TEST_IMUL_IM(size, rsize, op0, op1)\{\    long res, flags, s1;\    flags = 0;\    res = 0;\    s1 = op1;\    asm volatile ("push %3\n\t"\         "popf\n\t"\         "imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \         "pushf\n\t"\         "pop %1\n\t"\         : "=r" (res), "=g" (flags)\         : "r" (s1), "1" (flags), "0" (res));\    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\           "imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\}#undef CC_MASK#define CC_MASK (0)#define OP div#include "test-i386-muldiv.h"#define OP idiv#include "test-i386-muldiv.h"void test_mul(void){    test_imulb(0x1234561d, 4);    test_imulb(3, -4);    test_imulb(0x80, 0x80);    test_imulb(0x10, 0x10);    test_imulw(0, 0x1234001d, 45);    test_imulw(0, 23, -45);    test_imulw(0, 0x8000, 0x8000);    test_imulw(0, 0x100, 0x100);    test_imull(0, 0x1234001d, 45);    test_imull(0, 23, -45);    test_imull(0, 0x80000000, 0x80000000);    test_imull(0, 0x10000, 0x10000);    test_mulb(0x1234561d, 4);    test_mulb(3, -4);    test_mulb(0x80, 0x80);    test_mulb(0x10, 0x10);    test_mulw(0, 0x1234001d, 45);    test_mulw(0, 23, -45);    test_mulw(0, 0x8000, 0x8000);    test_mulw(0, 0x100, 0x100);    test_mull(0, 0x1234001d, 45);    test_mull(0, 23, -45);    test_mull(0, 0x80000000, 0x80000000);    test_mull(0, 0x10000, 0x10000);    test_imulw2(0x1234001d, 45);    test_imulw2(23, -45);    test_imulw2(0x8000, 0x8000);    test_imulw2(0x100, 0x100);    test_imull2(0x1234001d, 45);    test_imull2(23, -45);    test_imull2(0x80000000, 0x80000000);    test_imull2(0x10000, 0x10000);    TEST_IMUL_IM("w", "w", 45, 0x1234);    TEST_IMUL_IM("w", "w", -45, 23);    TEST_IMUL_IM("w", "w", 0x8000, 0x80000000);    TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);    TEST_IMUL_IM("l", "k", 45, 0x1234);    TEST_IMUL_IM("l", "k", -45, 23);    TEST_IMUL_IM("l", "k", 0x8000, 0x80000000);    TEST_IMUL_IM("l", "k", 0x7fff, 0x1000);    test_idivb(0x12341678, 0x127e);    test_idivb(0x43210123, -5);    test_idivb(0x12340004, -1);    test_idivw(0, 0x12345678, 12347);    test_idivw(0, -23223, -45);    test_idivw(0, 0x12348000, -1);    test_idivw(0x12343, 0x12345678, 0x81238567);    test_idivl(0, 0x12345678, 12347);    test_idivl(0, -233223, -45);    test_idivl(0, 0x80000000, -1);    test_idivl(0x12343, 0x12345678, 0x81234567);    test_divb(0x12341678, 0x127e);    test_divb(0x43210123, -5);    test_divb(0x12340004, -1);    test_divw(0, 0x12345678, 12347);    test_divw(0, -23223, -45);    test_divw(0, 0x12348000, -1);    test_divw(0x12343, 0x12345678, 0x81238567);    test_divl(0, 0x12345678, 12347);    test_divl(0, -233223, -45);    test_divl(0, 0x80000000, -1);    test_divl(0x12343, 0x12345678, 0x81234567);#if defined(__x86_64__)    test_imulq(0, 0x1234001d1234001d, 45);    test_imulq(0, 23, -45);    test_imulq(0, 0x8000000000000000, 0x8000000000000000);    test_imulq(0, 0x100000000, 0x100000000);    test_mulq(0, 0x1234001d1234001d, 45);    test_mulq(0, 23, -45);    test_mulq(0, 0x8000000000000000, 0x8000000000000000);    test_mulq(0, 0x100000000, 0x100000000);    test_imulq2(0x1234001d1234001d, 45);    test_imulq2(23, -45);    test_imulq2(0x8000000000000000, 0x8000000000000000);    test_imulq2(0x100000000, 0x100000000);    TEST_IMUL_IM("q", "", 45, 0x12341234);    TEST_IMUL_IM("q", "", -45, 23);    TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000);    TEST_IMUL_IM("q", "", 0x7fff, 0x10000000);    test_idivq(0, 0x12345678abcdef, 12347);    test_idivq(0, -233223, -45);    test_idivq(0, 0x8000000000000000, -1);    test_idivq(0x12343, 0x12345678, 0x81234567);    test_divq(0, 0x12345678abcdef, 12347);    test_divq(0, -233223, -45);    test_divq(0, 0x8000000000000000, -1);    test_divq(0x12343, 0x12345678, 0x81234567);#endif}#define TEST_BSX(op, size, op0)\{\    long res, val, resz;\    val = op0;\    asm("xor %1, %1\n"\        "mov $0x12345678, %0\n"\        #op " %" size "2, %" size "0 ; setz %b1" \        : "=r" (res), "=q" (resz)\        : "g" (val));\    printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\}void test_bsx(void){    TEST_BSX(bsrw, "w", 0);    TEST_BSX(bsrw, "w", 0x12340128);    TEST_BSX(bsfw, "w", 0);    TEST_BSX(bsfw, "w", 0x12340128);    TEST_BSX(bsrl, "k", 0);    TEST_BSX(bsrl, "k", 0x00340128);    TEST_BSX(bsfl, "k", 0);    TEST_BSX(bsfl, "k", 0x00340128);#if defined(__x86_64__)    TEST_BSX(bsrq, "", 0);    TEST_BSX(bsrq, "", 0x003401281234);    TEST_BSX(bsfq, "", 0);    TEST_BSX(bsfq, "", 0x003401281234);#endif}/**********************************************/union float64u {    double d;    uint64_t l;};union float64u q_nan = { .l = 0xFFF8000000000000 };union float64u s_nan = { .l = 0xFFF0000000000000 };void test_fops(double a, double b){    printf("a=%f b=%f a+b=%f\n", a, b, a + b);    printf("a=%f b=%f a-b=%f\n", a, b, a - b);    printf("a=%f b=%f a*b=%f\n", a, b, a * b);    printf("a=%f b=%f a/b=%f\n", a, b, a / b);    printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));    printf("a=%f sin(a)=%f\n", a, sin(a));    printf("a=%f cos(a)=%f\n", a, cos(a));    printf("a=%f tan(a)=%f\n", a, tan(a));    printf("a=%f log(a)=%f\n", a, log(a));    printf("a=%f exp(a)=%f\n", a, exp(a));    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));    /* just to test some op combining */    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));}void fpu_clear_exceptions(void){    struct __attribute__((packed)) {        uint16_t fpuc;        uint16_t dummy1;        uint16_t fpus;        uint16_t dummy2;        uint16_t fptag;        uint16_t dummy3;        uint32_t ignored[4];        long double fpregs[8];    } float_env32;        asm volatile ("fnstenv %0\n" : : "m" (float_env32));    float_env32.fpus &= ~0x7f;    asm volatile ("fldenv %0\n" : : "m" (float_env32));}/* XXX: display exception bits when supported */#define FPUS_EMASK 0x0000//#define FPUS_EMASK 0x007fvoid test_fcmp(double a, double b){    long eflags, fpus;    fpu_clear_exceptions();    asm("fcom %2\n"        "fstsw %%ax\n"        : "=a" (fpus)        : "t" (a), "u" (b));    printf("fcom(%f %f)=%04lx \n",            a, b, fpus & (0x4500 | FPUS_EMASK));    fpu_clear_exceptions();    asm("fucom %2\n"        "fstsw %%ax\n"        : "=a" (fpus)        : "t" (a), "u" (b));    printf("fucom(%f %f)=%04lx\n",            a, b, fpus & (0x4500 | FPUS_EMASK));    if (TEST_FCOMI) {        /* test f(u)comi instruction */        fpu_clear_exceptions();        asm("fcomi %3, %2\n"            "fstsw %%ax\n"            "pushf\n"            "pop %0\n"            : "=r" (eflags), "=a" (fpus)            : "t" (a), "u" (b));        printf("fcomi(%f %f)=%04lx %02lx\n",                a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));        fpu_clear_exceptions();        asm("fucomi %3, %2\n"            "fstsw %%ax\n"            "pushf\n"            "pop %0\n"            : "=r" (eflags), "=a" (fpus)            : "t" (a), "u" (b));        printf("fucomi(%f %f)=%04lx %02lx\n",                a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));    }    fpu_clear_exceptions();}void test_fcvt(double a){    float fa;    long double la;    int16_t fpuc;    int i;    int64_t lla;    int ia;    int16_t wa;    double ra;    fa = a;    la = a;    printf("(float)%f = %f\n", a, fa);    printf("(long double)%f = %Lf\n", a, la);    printf("a=" FMT64X "\n", *(uint64_t *)&a);    printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,            *(unsigned short *)((char *)(&la) + 8));    /* test all roundings */    asm volatile ("fstcw %0" : "=m" (fpuc));    for(i=0;i<4;i++) {        asm volatile ("fldcw %0" : : "m" ((fpuc & ~0x0c00) | (i << 10)));        asm volatile ("fist %0" : "=m" (wa) : "t" (a));        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));        asm volatile ("fldcw %0" : : "m" (fpuc));        printf("(short)a = %d\n", wa);        printf("(int)a = %d\n", ia);        printf("(int64_t)a = " FMT64X "\n", lla);        printf("rint(a) = %f\n", ra);    }}#define TEST(N) \    asm("fld" #N : "=t" (a)); \    printf("fld" #N "= %f\n", a);void test_fconst(void){    double a;    TEST(1);    TEST(l2t);    TEST(l2e);    TEST(pi);    TEST(lg2);    TEST(ln2);    TEST(z);}void test_fbcd(double a){    unsigned short bcd[5];    double b;    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",            a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);}#define TEST_ENV(env, save, restore)\{\    memset((env), 0xaa, sizeof(*(env)));\    for(i=0;i<5;i++)\        asm volatile ("fldl %0" : : "m" (dtab[i]));\    asm volatile (save " %0\n" : : "m" (*(env)));\    asm volatile (restore " %0\n": : "m" (*(env)));\    for(i=0;i<5;i++)\        asm volatile ("fstpl %0" : "=m" (rtab[i]));\    for(i=0;i<5;i++)\        printf("res[%d]=%f\n", i, rtab[i]);\    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\           (env)->fpuc,\           (env)->fpus & 0xff00,\           (env)->fptag);\}void test_fenv(void){    struct __attribute__((packed)) {        uint16_t fpuc;        uint16_t dummy1;        uint16_t fpus;        uint16_t dummy2;        uint16_t fptag;        uint16_t dummy3;        uint32_t ignored[4];        long double fpregs[8];    } float_env32;    struct __attribute__((packed)) {        uint16_t fpuc;        uint16_t fpus;        uint16_t fptag;        uint16_t ignored[4];        long double fpregs[8];    } float_env16;    double dtab[8];    double rtab[8];    int i;    for(i=0;i<8;i++)        dtab[i] = i + 1;    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");    TEST_ENV(&float_env32, "fnstenv", "fldenv");    TEST_ENV(&float_env32, "fnsave", "frstor");    /* test for ffree */    for(i=0;i<5;i++)        asm volatile ("fldl %0" : : "m" (dtab[i]));    asm volatile("ffree %st(2)");    asm volatile ("fnstenv %0\n" : : "m" (float_env32));    asm volatile ("fninit");    printf("fptag=%04x\n", float_env32.fptag);}#define TEST_FCMOV(a, b, eflags, CC)\{\    double res;\    asm("push %3\n"\        "popf\n"\        "fcmov" CC " %2, %0\n"\        : "=t" (res)\        : "0" (a), "u" (b), "g" (eflags));\    printf("fcmov%s eflags=0x%04lx-> %f\n", \           CC, (long)eflags, res);\}void test_fcmov(void){    double a, b;    long eflags, i;    a = 1.0;    b = 2.0;    for(i = 0; i < 4; i++) {        eflags = 0;        if (i & 1)            eflags |= CC_C;        if (i & 2)            eflags |= CC_Z;        TEST_FCMOV(a, b, eflags, "b");        TEST_FCMOV(a, b, eflags, "e");        TEST_FCMOV(a, b, eflags, "be");        TEST_FCMOV(a, b, eflags, "nb");        TEST_FCMOV(a, b, eflags, "ne");        TEST_FCMOV(a, b, eflags, "nbe");    }    TEST_FCMOV(a, b, 0, "u");    TEST_FCMOV(a, b, CC_P, "u");    TEST_FCMOV(a, b, 0, "nu");    TEST_FCMOV(a, b, CC_P, "nu");}void test_floats(void){    test_fops(2, 3);    test_fops(1.4, -5);    test_fcmp(2, -1);    test_fcmp(2, 2);    test_fcmp(2, 3);    test_fcmp(2, q_nan.d);    test_fcmp(q_nan.d, -1);    test_fcvt(0.5);    test_fcvt(-0.5);    test_fcvt(1.0/7.0);    test_fcvt(-1.0/9.0);    test_fcvt(32768);    test_fcvt(-1e20);    test_fconst();    test_fbcd(1234567890123456);    test_fbcd(-123451234567890);    test_fenv();    if (TEST_CMOV) {        test_fcmov();    }}/**********************************************/#if !defined(__x86_64__)#define TEST_BCD(op, op0, cc_in, cc_mask)\{\    int res, flags;\    res = op0;\    flags = cc_in;\    asm ("push %3\n\t"\         "popf\n\t"\         #op "\n\t"\         "pushf\n\t"\         "pop %1\n\t"\        : "=a" (res), "=g" (flags)\        : "0" (res), "1" (flags));\    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\           #op, op0, res, cc_in, flags & cc_mask);\}

⌨️ 快捷键说明

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