aboutsummaryrefslogtreecommitdiff
path: root/tests/test-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-i386.c')
-rw-r--r--tests/test-i386.c148
1 files changed, 94 insertions, 54 deletions
diff --git a/tests/test-i386.c b/tests/test-i386.c
index f9a5991863..866c769e4b 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -635,6 +635,65 @@ void test_bcd(void)
TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
}
+#define TEST_XCHG(op, size, opconst)\
+{\
+ int op0, op1;\
+ op0 = 0x12345678;\
+ op1 = 0xfbca7654;\
+ asm(#op " %" size "0, %" size "1" \
+ : "=q" (op0), opconst (op1) \
+ : "0" (op0), "1" (op1));\
+ printf("%-10s A=%08x B=%08x\n",\
+ #op, op0, op1);\
+}
+
+#define TEST_CMPXCHG(op, size, opconst, eax)\
+{\
+ int op0, op1;\
+ op0 = 0x12345678;\
+ op1 = 0xfbca7654;\
+ asm(#op " %" size "0, %" size "1" \
+ : "=q" (op0), opconst (op1) \
+ : "0" (op0), "1" (op1), "a" (eax));\
+ printf("%-10s EAX=%08x A=%08x C=%08x\n",\
+ #op, eax, op0, op1);\
+}
+
+void test_xchg(void)
+{
+ TEST_XCHG(xchgl, "", "=q");
+ TEST_XCHG(xchgw, "w", "=q");
+ TEST_XCHG(xchgb, "b", "=q");
+
+ TEST_XCHG(xchgl, "", "=m");
+ TEST_XCHG(xchgw, "w", "=m");
+ TEST_XCHG(xchgb, "b", "=m");
+
+ TEST_XCHG(xaddl, "", "=q");
+ TEST_XCHG(xaddw, "w", "=q");
+ TEST_XCHG(xaddb, "b", "=q");
+
+ TEST_XCHG(xaddl, "", "=m");
+ TEST_XCHG(xaddw, "w", "=m");
+ TEST_XCHG(xaddb, "b", "=m");
+
+ TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
+
+ TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
+
+ TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
+ TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
+
+ TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
+ TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
+}
+
/**********************************************/
/* segmentation tests */
@@ -646,7 +705,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
uint8_t seg_data1[4096];
uint8_t seg_data2[4096];
-#define MK_SEL(n) (((n) << 3) | 4)
+#define MK_SEL(n) (((n) << 3) | 7)
/* NOTE: we use Linux modify_ldt syscall */
void test_segs(void)
@@ -715,65 +774,45 @@ void test_segs(void)
printf("SS[tmp] = %02x\n", res2);
}
-#define TEST_XCHG(op, size, opconst)\
-{\
- int op0, op1;\
- op0 = 0x12345678;\
- op1 = 0xfbca7654;\
- asm(#op " %" size "0, %" size "1" \
- : "=q" (op0), opconst (op1) \
- : "0" (op0), "1" (op1));\
- printf("%-10s A=%08x B=%08x\n",\
- #op, op0, op1);\
-}
-
-#define TEST_CMPXCHG(op, size, opconst, eax)\
-{\
- int op0, op1;\
- op0 = 0x12345678;\
- op1 = 0xfbca7654;\
- asm(#op " %" size "0, %" size "1" \
- : "=q" (op0), opconst (op1) \
- : "0" (op0), "1" (op1), "a" (eax));\
- printf("%-10s EAX=%08x A=%08x C=%08x\n",\
- #op, eax, op0, op1);\
-}
+/* 16 bit code test */
+extern char code16_start, code16_end;
+extern char code16_func1;
+extern char code16_func2;
+extern char code16_func3;
-void test_xchg(void)
+void test_code16(void)
{
- TEST_XCHG(xchgl, "", "=q");
- TEST_XCHG(xchgw, "w", "=q");
- TEST_XCHG(xchgb, "b", "=q");
-
- TEST_XCHG(xchgl, "", "=m");
- TEST_XCHG(xchgw, "w", "=m");
- TEST_XCHG(xchgb, "b", "=m");
-
- TEST_XCHG(xaddl, "", "=q");
- TEST_XCHG(xaddw, "w", "=q");
- TEST_XCHG(xaddb, "b", "=q");
-
- TEST_XCHG(xaddl, "", "=m");
- TEST_XCHG(xaddw, "w", "=m");
- TEST_XCHG(xaddb, "b", "=m");
-
- TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
-
- TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
+ struct modify_ldt_ldt_s ldt;
+ int res, res2;
- TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
+ /* build a code segment */
+ ldt.entry_number = 1;
+ ldt.base_addr = (unsigned long)&code16_start;
+ ldt.limit = &code16_end - &code16_start;
+ ldt.seg_32bit = 0;
+ ldt.contents = MODIFY_LDT_CONTENTS_CODE;
+ ldt.read_exec_only = 0;
+ ldt.limit_in_pages = 0;
+ ldt.seg_not_present = 0;
+ ldt.useable = 1;
+ modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
- TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
+ /* call the first function */
+ asm volatile ("lcall %1, %2"
+ : "=a" (res)
+ : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
+ printf("func1() = 0x%08x\n", res);
+ asm volatile ("lcall %2, %3"
+ : "=a" (res), "=c" (res2)
+ : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
+ printf("func2() = 0x%08x spdec=%d\n", res, res2);
+ asm volatile ("lcall %1, %2"
+ : "=a" (res)
+ : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
+ printf("func3() = 0x%08x\n", res);
}
+
static void *call_end __init_call = NULL;
int main(int argc, char **argv)
@@ -794,5 +833,6 @@ int main(int argc, char **argv)
test_xchg();
test_lea();
test_segs();
+ test_code16();
return 0;
}