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 memw
= 0x123456789abcdeful
;
138 static unsigned long tmp2
;
140 memset(mem
, 0x55, (void *)stack_top
- mem
);
142 asm volatile("pushq %[val] \n\t"
144 : : [val
]"m"(memw
), [mem
]"r"(mem
) : "memory");
145 report("pop mem", *(unsigned long *)mem
== memw
);
148 asm volatile("mov %%rsp, %[tmp] \n\t"
149 "mov %[stack_top], %%rsp \n\t"
153 : [tmp
]"=&r"(tmp
), [tmp2
]"=m"(tmp2
)
154 : [val
]"r"(memw
), [stack_top
]"r"(stack_top
)
156 report("pop mem (2)", tmp2
== memw
);
158 memw
= 129443 - memw
;
159 asm volatile("mov %%rsp, %[tmp] \n\t"
160 "mov %[stack_top], %%rsp \n\t"
164 : [tmp
]"=&r"(tmp
), [tmp2
]"=r"(tmp2
)
165 : [val
]"r"(memw
), [stack_top
]"r"(stack_top
)
167 report("pop reg", tmp2
== memw
);
169 asm volatile("mov %%rsp, %[tmp] \n\t"
170 "mov %[stack_top], %%rsp \n\t"
174 "1: mov %[tmp], %%rsp"
175 : [tmp
]"=&r"(tmp
) : [stack_top
]"r"(stack_top
)
180 unsigned long read_cr0(void)
184 asm volatile ("mov %%cr0, %0" : "=r"(cr0
));
191 unsigned short msw
, msw_orig
, *pmsw
;
194 msw_orig
= read_cr0();
196 asm("smsw %0" : "=r"(msw
));
197 report("smsw (1)", msw
== msw_orig
);
201 asm("smsw %0" : "=m"(pmsw
[4]));
203 for (i
= 0; i
< 8; ++i
)
204 if (i
!= 4 && pmsw
[i
])
206 report("smsw (2)", msw
== pmsw
[4] && zero
);
212 unsigned short msw
, *pmsw
;
218 asm("lmsw %0" : : "r"(msw
));
219 printf("before %lx after %lx\n", cr0
, read_cr0());
220 report("lmsw (1)", (cr0
^ read_cr0()) == 8);
224 asm("lmsw %0" : : "m"(*pmsw
));
225 printf("before %lx after %lx\n", cr0
, read_cr0());
226 report("lmsw (2)", cr0
== read_cr0());
232 unsigned long t1
, t2
;
235 mem
= vmap(IORAM_BASE_PHYS
, IORAM_LEN
);
237 // test mov reg, r/m and mov r/m, reg
238 t1
= 0x123456789abcdef;
239 asm volatile("mov %[t1], (%[mem]) \n\t"
240 "mov (%[mem]), %[t2]"
242 : [t1
]"r"(t1
), [mem
]"r"(mem
)
244 report("mov reg, r/m (1)", t2
== 0x123456789abcdef);
256 printf("\nSUMMARY: %d tests, %d failures\n", tests
, fails
);
257 return fails
? 1 : 0;