5 #define memset __builtin_memset
9 void report(const char *name
, int result
)
13 printf("PASS: %s\n", name
);
15 printf("FAIL: %s\n", name
);
20 void test_cmps(void *mem
)
22 unsigned char *m1
= mem
, *m2
= mem
+ 1024;
23 unsigned char m3
[1024];
27 for (int i
= 0; i
< 100; ++i
)
28 m1
[i
] = m2
[i
] = m3
[i
] = i
;
29 for (int i
= 100; i
< 200; ++i
)
30 m1
[i
] = (m3
[i
] = m2
[i
] = i
) + 1;
32 rsi
= m1
; rdi
= m3
; rcx
= 30;
33 asm volatile("xor %[tmp], %[tmp] \n\t"
35 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
37 report("repe/cmpsb (1)", rcx
== 0 && rsi
== m1
+ 30 && rdi
== m3
+ 30);
39 rsi
= m1
; rdi
= m3
; rcx
= 15;
40 asm volatile("xor %[tmp], %[tmp] \n\t"
42 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
44 report("repe/cmpsw (1)", rcx
== 0 && rsi
== m1
+ 30 && rdi
== m3
+ 30);
46 rsi
= m1
; rdi
= m3
; rcx
= 7;
47 asm volatile("xor %[tmp], %[tmp] \n\t"
49 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
51 report("repe/cmpll (1)", rcx
== 0 && rsi
== m1
+ 28 && rdi
== m3
+ 28);
53 rsi
= m1
; rdi
= m3
; rcx
= 4;
54 asm volatile("xor %[tmp], %[tmp] \n\t"
56 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
58 report("repe/cmpsq (1)", rcx
== 0 && rsi
== m1
+ 32 && rdi
== m3
+ 32);
60 rsi
= m1
; rdi
= m3
; rcx
= 130;
61 asm volatile("xor %[tmp], %[tmp] \n\t"
63 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
65 report("repe/cmpsb (2)",
66 rcx
== 29 && rsi
== m1
+ 101 && rdi
== m3
+ 101);
68 rsi
= m1
; rdi
= m3
; rcx
= 65;
69 asm volatile("xor %[tmp], %[tmp] \n\t"
71 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
73 report("repe/cmpsw (2)",
74 rcx
== 14 && rsi
== m1
+ 102 && rdi
== m3
+ 102);
76 rsi
= m1
; rdi
= m3
; rcx
= 32;
77 asm volatile("xor %[tmp], %[tmp] \n\t"
79 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
81 report("repe/cmpll (2)",
82 rcx
== 6 && rsi
== m1
+ 104 && rdi
== m3
+ 104);
84 rsi
= m1
; rdi
= m3
; rcx
= 16;
85 asm volatile("xor %[tmp], %[tmp] \n\t"
87 : "+S"(rsi
), "+D"(rdi
), "+c"(rcx
), [tmp
]"=&r"(tmp
)
89 report("repe/cmpsq (2)",
90 rcx
== 3 && rsi
== m1
+ 104 && rdi
== m3
+ 104);
96 unsigned long src
, dst
;
100 asm volatile("mov %[src], %%cr8; mov %%cr8, %[dst]"
101 : [dst
]"+r"(dst
), [src
]"+r"(src
));
102 report("mov %cr8", dst
== 3 && src
== 3);
105 void test_push(void *mem
)
108 unsigned long *stack_top
= mem
+ 4096;
109 unsigned long *new_stack_top
;
110 unsigned long memw
= 0x123456789abcdeful
;
112 memset(mem
, 0x55, (void *)stack_top
- mem
);
114 asm volatile("mov %%rsp, %[tmp] \n\t"
115 "mov %[stack_top], %%rsp \n\t"
118 "pushq (%[mem]) \n\t"
119 "pushq $-7070707 \n\t"
120 "mov %%rsp, %[new_stack_top] \n\t"
122 : [tmp
]"=&r"(tmp
), [new_stack_top
]"=r"(new_stack_top
)
123 : [stack_top
]"r"(stack_top
),
124 [reg
]"r"(-17l), [mem
]"r"(&memw
)
127 report("push $imm8", stack_top
[-1] == -7ul);
128 report("push %reg", stack_top
[-2] == -17ul);
129 report("push mem", stack_top
[-3] == 0x123456789abcdeful
);
130 report("push $imm", stack_top
[-4] == -7070707);
133 void test_pop(void *mem
)
136 unsigned long *stack_top
= mem
+ 4096;
137 unsigned long *new_stack_top
;
138 unsigned long memw
= 0x123456789abcdeful
;
139 static unsigned long tmp2
;
141 memset(mem
, 0x55, (void *)stack_top
- mem
);
143 asm volatile("pushq %[val] \n\t"
145 : : [val
]"m"(memw
), [mem
]"r"(mem
) : "memory");
146 report("pop mem", *(unsigned long *)mem
== memw
);
149 asm volatile("mov %%rsp, %[tmp] \n\t"
150 "mov %[stack_top], %%rsp \n\t"
154 : [tmp
]"=&r"(tmp
), [tmp2
]"=m"(tmp2
)
155 : [val
]"r"(memw
), [stack_top
]"r"(stack_top
)
157 report("pop mem (2)", tmp2
== memw
);
161 unsigned long read_cr0(void)
165 asm volatile ("mov %%cr0, %0" : "=r"(cr0
));
172 unsigned short msw
, msw_orig
, *pmsw
;
175 msw_orig
= read_cr0();
177 asm("smsw %0" : "=r"(msw
));
178 report("smsw (1)", msw
== msw_orig
);
182 asm("smsw %0" : "=m"(pmsw
[4]));
184 for (i
= 0; i
< 8; ++i
)
185 if (i
!= 4 && pmsw
[i
])
187 report("smsw (2)", msw
== pmsw
[4] && zero
);
193 unsigned short msw
, *pmsw
;
199 asm("lmsw %0" : : "r"(msw
));
200 printf("before %lx after %lx\n", cr0
, read_cr0());
201 report("lmsw (1)", (cr0
^ read_cr0()) == 8);
205 asm("lmsw %0" : : "m"(*pmsw
));
206 printf("before %lx after %lx\n", cr0
, read_cr0());
207 report("lmsw (2)", cr0
== read_cr0());
213 unsigned long t1
, t2
;
216 mem
= vmap(IORAM_BASE_PHYS
, IORAM_LEN
);
218 // test mov reg, r/m and mov r/m, reg
219 t1
= 0x123456789abcdef;
220 asm volatile("mov %[t1], (%[mem]) \n\t"
221 "mov (%[mem]), %[t2]"
223 : [t1
]"r"(t1
), [mem
]"r"(mem
)
225 report("mov reg, r/m (1)", t2
== 0x123456789abcdef);
237 printf("\nSUMMARY: %d tests, %d failures\n", tests
, fails
);
238 return fails
? 1 : 0;