diff options
Diffstat (limited to 'tests/test-i386.c')
-rw-r--r-- | tests/test-i386.c | 140 |
1 files changed, 136 insertions, 4 deletions
diff --git a/tests/test-i386.c b/tests/test-i386.c index 5fb9c5cd05..55dd9eb2c7 100644 --- a/tests/test-i386.c +++ b/tests/test-i386.c @@ -14,13 +14,12 @@ #define CC_S 0x0080 #define CC_O 0x0800 -/* XXX: currently no A flag */ -#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O) - #define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) static void *call_start __init_call = NULL; +#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) + #define OP add #include "test-i386.h" @@ -67,6 +66,9 @@ static void *call_start __init_call = NULL; #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" @@ -268,18 +270,148 @@ void test_jcc(void) TEST_JCC("jns", 0, 0); } +#undef CC_MASK +#define CC_MASK (CC_O | CC_C) + +#define OP mul +#include "test-i386-muldiv.h" + +#define OP imul +#include "test-i386-muldiv.h" + +#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_imulw2(int op0, int op1) +{ + int res, s1, s0, flags; + s0 = op0; + s1 = op1; + res = s0; + flags = 0; + asm ("push %4\n\t" + "popf\n\t" + "imulw %w2, %w0\n\t" + "pushf\n\t" + "popl %1\n\t" + : "=q" (res), "=g" (flags) + : "q" (s1), "0" (res), "1" (flags)); + printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", + "imulw", s0, s1, res, flags & CC_MASK); +} + +void test_imull2(int op0, int op1) +{ + int res, s1, s0, flags; + s0 = op0; + s1 = op1; + res = s0; + flags = 0; + asm ("push %4\n\t" + "popf\n\t" + "imull %2, %0\n\t" + "pushf\n\t" + "popl %1\n\t" + : "=q" (res), "=g" (flags) + : "q" (s1), "0" (res), "1" (flags)); + printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", + "imull", s0, s1, res, flags & CC_MASK); +} + +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_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); +} + + static void *call_end __init_call = NULL; int main(int argc, char **argv) { void **ptr; void (*func)(void); + + test_mul(); +#if 0 ptr = &call_start + 1; while (*ptr != NULL) { func = *ptr++; func(); } - test_lea(); test_jcc(); + test_lea(); +#endif return 0; } |