1*7d36db35SAvi Kivity #include "ioram.h" 2*7d36db35SAvi Kivity #include "vm.h" 3*7d36db35SAvi Kivity #include "libcflat.h" 4*7d36db35SAvi Kivity 5*7d36db35SAvi Kivity #define memset __builtin_memset 6*7d36db35SAvi Kivity #define TESTDEV_IO_PORT 0xe0 7*7d36db35SAvi Kivity 8*7d36db35SAvi Kivity int fails, tests; 9*7d36db35SAvi Kivity 10*7d36db35SAvi Kivity void report(const char *name, int result) 11*7d36db35SAvi Kivity { 12*7d36db35SAvi Kivity ++tests; 13*7d36db35SAvi Kivity if (result) 14*7d36db35SAvi Kivity printf("PASS: %s\n", name); 15*7d36db35SAvi Kivity else { 16*7d36db35SAvi Kivity printf("FAIL: %s\n", name); 17*7d36db35SAvi Kivity ++fails; 18*7d36db35SAvi Kivity } 19*7d36db35SAvi Kivity } 20*7d36db35SAvi Kivity 21*7d36db35SAvi Kivity static char st1[] = "abcdefghijklmnop"; 22*7d36db35SAvi Kivity 23*7d36db35SAvi Kivity void test_stringio() 24*7d36db35SAvi Kivity { 25*7d36db35SAvi Kivity unsigned char r = 0; 26*7d36db35SAvi Kivity asm volatile("cld \n\t" 27*7d36db35SAvi Kivity "movw %0, %%dx \n\t" 28*7d36db35SAvi Kivity "rep outsb \n\t" 29*7d36db35SAvi Kivity : : "i"((short)TESTDEV_IO_PORT), 30*7d36db35SAvi Kivity "S"(st1), "c"(sizeof(st1) - 1)); 31*7d36db35SAvi Kivity asm volatile("inb %1, %0\n\t" : "=a"(r) : "i"((short)TESTDEV_IO_PORT)); 32*7d36db35SAvi Kivity report("outsb up", r == st1[sizeof(st1) - 2]); /* last char */ 33*7d36db35SAvi Kivity 34*7d36db35SAvi Kivity asm volatile("std \n\t" 35*7d36db35SAvi Kivity "movw %0, %%dx \n\t" 36*7d36db35SAvi Kivity "rep outsb \n\t" 37*7d36db35SAvi Kivity : : "i"((short)TESTDEV_IO_PORT), 38*7d36db35SAvi Kivity "S"(st1 + sizeof(st1) - 2), "c"(sizeof(st1) - 1)); 39*7d36db35SAvi Kivity asm volatile("cld \n\t" : : ); 40*7d36db35SAvi Kivity asm volatile("in %1, %0\n\t" : "=a"(r) : "i"((short)TESTDEV_IO_PORT)); 41*7d36db35SAvi Kivity report("outsb down", r == st1[0]); 42*7d36db35SAvi Kivity } 43*7d36db35SAvi Kivity 44*7d36db35SAvi Kivity void test_cmps_one(unsigned char *m1, unsigned char *m3) 45*7d36db35SAvi Kivity { 46*7d36db35SAvi Kivity void *rsi, *rdi; 47*7d36db35SAvi Kivity long rcx, tmp; 48*7d36db35SAvi Kivity 49*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 30; 50*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 51*7d36db35SAvi Kivity "repe/cmpsb" 52*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 53*7d36db35SAvi Kivity : : "cc"); 54*7d36db35SAvi Kivity report("repe/cmpsb (1)", rcx == 0 && rsi == m1 + 30 && rdi == m3 + 30); 55*7d36db35SAvi Kivity 56*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 15; 57*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 58*7d36db35SAvi Kivity "repe/cmpsw" 59*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 60*7d36db35SAvi Kivity : : "cc"); 61*7d36db35SAvi Kivity report("repe/cmpsw (1)", rcx == 0 && rsi == m1 + 30 && rdi == m3 + 30); 62*7d36db35SAvi Kivity 63*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 7; 64*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 65*7d36db35SAvi Kivity "repe/cmpsl" 66*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 67*7d36db35SAvi Kivity : : "cc"); 68*7d36db35SAvi Kivity report("repe/cmpll (1)", rcx == 0 && rsi == m1 + 28 && rdi == m3 + 28); 69*7d36db35SAvi Kivity 70*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 4; 71*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 72*7d36db35SAvi Kivity "repe/cmpsq" 73*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 74*7d36db35SAvi Kivity : : "cc"); 75*7d36db35SAvi Kivity report("repe/cmpsq (1)", rcx == 0 && rsi == m1 + 32 && rdi == m3 + 32); 76*7d36db35SAvi Kivity 77*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 130; 78*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 79*7d36db35SAvi Kivity "repe/cmpsb" 80*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 81*7d36db35SAvi Kivity : : "cc"); 82*7d36db35SAvi Kivity report("repe/cmpsb (2)", 83*7d36db35SAvi Kivity rcx == 29 && rsi == m1 + 101 && rdi == m3 + 101); 84*7d36db35SAvi Kivity 85*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 65; 86*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 87*7d36db35SAvi Kivity "repe/cmpsw" 88*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 89*7d36db35SAvi Kivity : : "cc"); 90*7d36db35SAvi Kivity report("repe/cmpsw (2)", 91*7d36db35SAvi Kivity rcx == 14 && rsi == m1 + 102 && rdi == m3 + 102); 92*7d36db35SAvi Kivity 93*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 32; 94*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 95*7d36db35SAvi Kivity "repe/cmpsl" 96*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 97*7d36db35SAvi Kivity : : "cc"); 98*7d36db35SAvi Kivity report("repe/cmpll (2)", 99*7d36db35SAvi Kivity rcx == 6 && rsi == m1 + 104 && rdi == m3 + 104); 100*7d36db35SAvi Kivity 101*7d36db35SAvi Kivity rsi = m1; rdi = m3; rcx = 16; 102*7d36db35SAvi Kivity asm volatile("xor %[tmp], %[tmp] \n\t" 103*7d36db35SAvi Kivity "repe/cmpsq" 104*7d36db35SAvi Kivity : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) 105*7d36db35SAvi Kivity : : "cc"); 106*7d36db35SAvi Kivity report("repe/cmpsq (2)", 107*7d36db35SAvi Kivity rcx == 3 && rsi == m1 + 104 && rdi == m3 + 104); 108*7d36db35SAvi Kivity 109*7d36db35SAvi Kivity } 110*7d36db35SAvi Kivity 111*7d36db35SAvi Kivity void test_cmps(void *mem) 112*7d36db35SAvi Kivity { 113*7d36db35SAvi Kivity unsigned char *m1 = mem, *m2 = mem + 1024; 114*7d36db35SAvi Kivity unsigned char m3[1024]; 115*7d36db35SAvi Kivity 116*7d36db35SAvi Kivity for (int i = 0; i < 100; ++i) 117*7d36db35SAvi Kivity m1[i] = m2[i] = m3[i] = i; 118*7d36db35SAvi Kivity for (int i = 100; i < 200; ++i) 119*7d36db35SAvi Kivity m1[i] = (m3[i] = m2[i] = i) + 1; 120*7d36db35SAvi Kivity test_cmps_one(m1, m3); 121*7d36db35SAvi Kivity test_cmps_one(m1, m2); 122*7d36db35SAvi Kivity } 123*7d36db35SAvi Kivity 124*7d36db35SAvi Kivity void test_cr8(void) 125*7d36db35SAvi Kivity { 126*7d36db35SAvi Kivity unsigned long src, dst; 127*7d36db35SAvi Kivity 128*7d36db35SAvi Kivity dst = 777; 129*7d36db35SAvi Kivity src = 3; 130*7d36db35SAvi Kivity asm volatile("mov %[src], %%cr8; mov %%cr8, %[dst]" 131*7d36db35SAvi Kivity : [dst]"+r"(dst), [src]"+r"(src)); 132*7d36db35SAvi Kivity report("mov %cr8", dst == 3 && src == 3); 133*7d36db35SAvi Kivity } 134*7d36db35SAvi Kivity 135*7d36db35SAvi Kivity void test_push(void *mem) 136*7d36db35SAvi Kivity { 137*7d36db35SAvi Kivity unsigned long tmp; 138*7d36db35SAvi Kivity unsigned long *stack_top = mem + 4096; 139*7d36db35SAvi Kivity unsigned long *new_stack_top; 140*7d36db35SAvi Kivity unsigned long memw = 0x123456789abcdeful; 141*7d36db35SAvi Kivity 142*7d36db35SAvi Kivity memset(mem, 0x55, (void *)stack_top - mem); 143*7d36db35SAvi Kivity 144*7d36db35SAvi Kivity asm volatile("mov %%rsp, %[tmp] \n\t" 145*7d36db35SAvi Kivity "mov %[stack_top], %%rsp \n\t" 146*7d36db35SAvi Kivity "pushq $-7 \n\t" 147*7d36db35SAvi Kivity "pushq %[reg] \n\t" 148*7d36db35SAvi Kivity "pushq (%[mem]) \n\t" 149*7d36db35SAvi Kivity "pushq $-7070707 \n\t" 150*7d36db35SAvi Kivity "mov %%rsp, %[new_stack_top] \n\t" 151*7d36db35SAvi Kivity "mov %[tmp], %%rsp" 152*7d36db35SAvi Kivity : [tmp]"=&r"(tmp), [new_stack_top]"=r"(new_stack_top) 153*7d36db35SAvi Kivity : [stack_top]"r"(stack_top), 154*7d36db35SAvi Kivity [reg]"r"(-17l), [mem]"r"(&memw) 155*7d36db35SAvi Kivity : "memory"); 156*7d36db35SAvi Kivity 157*7d36db35SAvi Kivity report("push $imm8", stack_top[-1] == -7ul); 158*7d36db35SAvi Kivity report("push %reg", stack_top[-2] == -17ul); 159*7d36db35SAvi Kivity report("push mem", stack_top[-3] == 0x123456789abcdeful); 160*7d36db35SAvi Kivity report("push $imm", stack_top[-4] == -7070707); 161*7d36db35SAvi Kivity } 162*7d36db35SAvi Kivity 163*7d36db35SAvi Kivity void test_pop(void *mem) 164*7d36db35SAvi Kivity { 165*7d36db35SAvi Kivity unsigned long tmp; 166*7d36db35SAvi Kivity unsigned long *stack_top = mem + 4096; 167*7d36db35SAvi Kivity unsigned long memw = 0x123456789abcdeful; 168*7d36db35SAvi Kivity static unsigned long tmp2; 169*7d36db35SAvi Kivity 170*7d36db35SAvi Kivity memset(mem, 0x55, (void *)stack_top - mem); 171*7d36db35SAvi Kivity 172*7d36db35SAvi Kivity asm volatile("pushq %[val] \n\t" 173*7d36db35SAvi Kivity "popq (%[mem])" 174*7d36db35SAvi Kivity : : [val]"m"(memw), [mem]"r"(mem) : "memory"); 175*7d36db35SAvi Kivity report("pop mem", *(unsigned long *)mem == memw); 176*7d36db35SAvi Kivity 177*7d36db35SAvi Kivity memw = 7 - memw; 178*7d36db35SAvi Kivity asm volatile("mov %%rsp, %[tmp] \n\t" 179*7d36db35SAvi Kivity "mov %[stack_top], %%rsp \n\t" 180*7d36db35SAvi Kivity "pushq %[val] \n\t" 181*7d36db35SAvi Kivity "popq %[tmp2] \n\t" 182*7d36db35SAvi Kivity "mov %[tmp], %%rsp" 183*7d36db35SAvi Kivity : [tmp]"=&r"(tmp), [tmp2]"=m"(tmp2) 184*7d36db35SAvi Kivity : [val]"r"(memw), [stack_top]"r"(stack_top) 185*7d36db35SAvi Kivity : "memory"); 186*7d36db35SAvi Kivity report("pop mem (2)", tmp2 == memw); 187*7d36db35SAvi Kivity 188*7d36db35SAvi Kivity memw = 129443 - memw; 189*7d36db35SAvi Kivity asm volatile("mov %%rsp, %[tmp] \n\t" 190*7d36db35SAvi Kivity "mov %[stack_top], %%rsp \n\t" 191*7d36db35SAvi Kivity "pushq %[val] \n\t" 192*7d36db35SAvi Kivity "popq %[tmp2] \n\t" 193*7d36db35SAvi Kivity "mov %[tmp], %%rsp" 194*7d36db35SAvi Kivity : [tmp]"=&r"(tmp), [tmp2]"=r"(tmp2) 195*7d36db35SAvi Kivity : [val]"r"(memw), [stack_top]"r"(stack_top) 196*7d36db35SAvi Kivity : "memory"); 197*7d36db35SAvi Kivity report("pop reg", tmp2 == memw); 198*7d36db35SAvi Kivity 199*7d36db35SAvi Kivity asm volatile("mov %%rsp, %[tmp] \n\t" 200*7d36db35SAvi Kivity "mov %[stack_top], %%rsp \n\t" 201*7d36db35SAvi Kivity "push $1f \n\t" 202*7d36db35SAvi Kivity "ret \n\t" 203*7d36db35SAvi Kivity "2: jmp 2b \n\t" 204*7d36db35SAvi Kivity "1: mov %[tmp], %%rsp" 205*7d36db35SAvi Kivity : [tmp]"=&r"(tmp) : [stack_top]"r"(stack_top) 206*7d36db35SAvi Kivity : "memory"); 207*7d36db35SAvi Kivity report("ret", 1); 208*7d36db35SAvi Kivity } 209*7d36db35SAvi Kivity 210*7d36db35SAvi Kivity void test_ljmp(void *mem) 211*7d36db35SAvi Kivity { 212*7d36db35SAvi Kivity unsigned char *m = mem; 213*7d36db35SAvi Kivity volatile int res = 1; 214*7d36db35SAvi Kivity 215*7d36db35SAvi Kivity *(unsigned long**)m = &&jmpf; 216*7d36db35SAvi Kivity asm volatile ("data16/mov %%cs, %0":"=m"(*(m + sizeof(unsigned long)))); 217*7d36db35SAvi Kivity asm volatile ("rex64/ljmp *%0"::"m"(*m)); 218*7d36db35SAvi Kivity res = 0; 219*7d36db35SAvi Kivity jmpf: 220*7d36db35SAvi Kivity report("ljmp", res); 221*7d36db35SAvi Kivity } 222*7d36db35SAvi Kivity 223*7d36db35SAvi Kivity void test_incdecnotneg(void *mem) 224*7d36db35SAvi Kivity { 225*7d36db35SAvi Kivity unsigned long *m = mem, v = 1234; 226*7d36db35SAvi Kivity unsigned char *mb = mem, vb = 66; 227*7d36db35SAvi Kivity 228*7d36db35SAvi Kivity *m = 0; 229*7d36db35SAvi Kivity 230*7d36db35SAvi Kivity asm volatile ("incl %0":"+m"(*m)); 231*7d36db35SAvi Kivity report("incl", *m == 1); 232*7d36db35SAvi Kivity asm volatile ("decl %0":"+m"(*m)); 233*7d36db35SAvi Kivity report("decl", *m == 0); 234*7d36db35SAvi Kivity asm volatile ("incb %0":"+m"(*m)); 235*7d36db35SAvi Kivity report("incb", *m == 1); 236*7d36db35SAvi Kivity asm volatile ("decb %0":"+m"(*m)); 237*7d36db35SAvi Kivity report("decb", *m == 0); 238*7d36db35SAvi Kivity 239*7d36db35SAvi Kivity asm volatile ("lock incl %0":"+m"(*m)); 240*7d36db35SAvi Kivity report("lock incl", *m == 1); 241*7d36db35SAvi Kivity asm volatile ("lock decl %0":"+m"(*m)); 242*7d36db35SAvi Kivity report("lock decl", *m == 0); 243*7d36db35SAvi Kivity asm volatile ("lock incb %0":"+m"(*m)); 244*7d36db35SAvi Kivity report("lock incb", *m == 1); 245*7d36db35SAvi Kivity asm volatile ("lock decb %0":"+m"(*m)); 246*7d36db35SAvi Kivity report("lock decb", *m == 0); 247*7d36db35SAvi Kivity 248*7d36db35SAvi Kivity *m = v; 249*7d36db35SAvi Kivity 250*7d36db35SAvi Kivity asm ("lock negq %0" : "+m"(*m)); v = -v; 251*7d36db35SAvi Kivity report("lock negl", *m == v); 252*7d36db35SAvi Kivity asm ("lock notq %0" : "+m"(*m)); v = ~v; 253*7d36db35SAvi Kivity report("lock notl", *m == v); 254*7d36db35SAvi Kivity 255*7d36db35SAvi Kivity *mb = vb; 256*7d36db35SAvi Kivity 257*7d36db35SAvi Kivity asm ("lock negb %0" : "+m"(*mb)); vb = -vb; 258*7d36db35SAvi Kivity report("lock negb", *mb == vb); 259*7d36db35SAvi Kivity asm ("lock notb %0" : "+m"(*mb)); vb = ~vb; 260*7d36db35SAvi Kivity report("lock notb", *mb == vb); 261*7d36db35SAvi Kivity } 262*7d36db35SAvi Kivity 263*7d36db35SAvi Kivity void test_smsw(void) 264*7d36db35SAvi Kivity { 265*7d36db35SAvi Kivity char mem[16]; 266*7d36db35SAvi Kivity unsigned short msw, msw_orig, *pmsw; 267*7d36db35SAvi Kivity int i, zero; 268*7d36db35SAvi Kivity 269*7d36db35SAvi Kivity msw_orig = read_cr0(); 270*7d36db35SAvi Kivity 271*7d36db35SAvi Kivity asm("smsw %0" : "=r"(msw)); 272*7d36db35SAvi Kivity report("smsw (1)", msw == msw_orig); 273*7d36db35SAvi Kivity 274*7d36db35SAvi Kivity memset(mem, 0, 16); 275*7d36db35SAvi Kivity pmsw = (void *)mem; 276*7d36db35SAvi Kivity asm("smsw %0" : "=m"(pmsw[4])); 277*7d36db35SAvi Kivity zero = 1; 278*7d36db35SAvi Kivity for (i = 0; i < 8; ++i) 279*7d36db35SAvi Kivity if (i != 4 && pmsw[i]) 280*7d36db35SAvi Kivity zero = 0; 281*7d36db35SAvi Kivity report("smsw (2)", msw == pmsw[4] && zero); 282*7d36db35SAvi Kivity } 283*7d36db35SAvi Kivity 284*7d36db35SAvi Kivity void test_lmsw(void) 285*7d36db35SAvi Kivity { 286*7d36db35SAvi Kivity char mem[16]; 287*7d36db35SAvi Kivity unsigned short msw, *pmsw; 288*7d36db35SAvi Kivity unsigned long cr0; 289*7d36db35SAvi Kivity 290*7d36db35SAvi Kivity cr0 = read_cr0(); 291*7d36db35SAvi Kivity 292*7d36db35SAvi Kivity msw = cr0 ^ 8; 293*7d36db35SAvi Kivity asm("lmsw %0" : : "r"(msw)); 294*7d36db35SAvi Kivity printf("before %lx after %lx\n", cr0, read_cr0()); 295*7d36db35SAvi Kivity report("lmsw (1)", (cr0 ^ read_cr0()) == 8); 296*7d36db35SAvi Kivity 297*7d36db35SAvi Kivity pmsw = (void *)mem; 298*7d36db35SAvi Kivity *pmsw = cr0; 299*7d36db35SAvi Kivity asm("lmsw %0" : : "m"(*pmsw)); 300*7d36db35SAvi Kivity printf("before %lx after %lx\n", cr0, read_cr0()); 301*7d36db35SAvi Kivity report("lmsw (2)", cr0 == read_cr0()); 302*7d36db35SAvi Kivity 303*7d36db35SAvi Kivity /* lmsw can't clear cr0.pe */ 304*7d36db35SAvi Kivity msw = (cr0 & ~1ul) ^ 4; /* change EM to force trap */ 305*7d36db35SAvi Kivity asm("lmsw %0" : : "r"(msw)); 306*7d36db35SAvi Kivity report("lmsw (3)", (cr0 ^ read_cr0()) == 4 && (cr0 & 1)); 307*7d36db35SAvi Kivity 308*7d36db35SAvi Kivity /* back to normal */ 309*7d36db35SAvi Kivity msw = cr0; 310*7d36db35SAvi Kivity asm("lmsw %0" : : "r"(msw)); 311*7d36db35SAvi Kivity } 312*7d36db35SAvi Kivity 313*7d36db35SAvi Kivity void test_xchg(void *mem) 314*7d36db35SAvi Kivity { 315*7d36db35SAvi Kivity unsigned long *memq = mem; 316*7d36db35SAvi Kivity unsigned long rax; 317*7d36db35SAvi Kivity 318*7d36db35SAvi Kivity asm volatile("mov $0x123456789abcdef, %%rax\n\t" 319*7d36db35SAvi Kivity "mov %%rax, (%[memq])\n\t" 320*7d36db35SAvi Kivity "mov $0xfedcba9876543210, %%rax\n\t" 321*7d36db35SAvi Kivity "xchg %%al, (%[memq])\n\t" 322*7d36db35SAvi Kivity "mov %%rax, %[rax]\n\t" 323*7d36db35SAvi Kivity : [rax]"=r"(rax) 324*7d36db35SAvi Kivity : [memq]"r"(memq) 325*7d36db35SAvi Kivity : "memory"); 326*7d36db35SAvi Kivity report("xchg reg, r/m (1)", 327*7d36db35SAvi Kivity rax == 0xfedcba98765432ef && *memq == 0x123456789abcd10); 328*7d36db35SAvi Kivity 329*7d36db35SAvi Kivity asm volatile("mov $0x123456789abcdef, %%rax\n\t" 330*7d36db35SAvi Kivity "mov %%rax, (%[memq])\n\t" 331*7d36db35SAvi Kivity "mov $0xfedcba9876543210, %%rax\n\t" 332*7d36db35SAvi Kivity "xchg %%ax, (%[memq])\n\t" 333*7d36db35SAvi Kivity "mov %%rax, %[rax]\n\t" 334*7d36db35SAvi Kivity : [rax]"=r"(rax) 335*7d36db35SAvi Kivity : [memq]"r"(memq) 336*7d36db35SAvi Kivity : "memory"); 337*7d36db35SAvi Kivity report("xchg reg, r/m (2)", 338*7d36db35SAvi Kivity rax == 0xfedcba987654cdef && *memq == 0x123456789ab3210); 339*7d36db35SAvi Kivity 340*7d36db35SAvi Kivity asm volatile("mov $0x123456789abcdef, %%rax\n\t" 341*7d36db35SAvi Kivity "mov %%rax, (%[memq])\n\t" 342*7d36db35SAvi Kivity "mov $0xfedcba9876543210, %%rax\n\t" 343*7d36db35SAvi Kivity "xchg %%eax, (%[memq])\n\t" 344*7d36db35SAvi Kivity "mov %%rax, %[rax]\n\t" 345*7d36db35SAvi Kivity : [rax]"=r"(rax) 346*7d36db35SAvi Kivity : [memq]"r"(memq) 347*7d36db35SAvi Kivity : "memory"); 348*7d36db35SAvi Kivity report("xchg reg, r/m (3)", 349*7d36db35SAvi Kivity rax == 0x89abcdef && *memq == 0x123456776543210); 350*7d36db35SAvi Kivity 351*7d36db35SAvi Kivity asm volatile("mov $0x123456789abcdef, %%rax\n\t" 352*7d36db35SAvi Kivity "mov %%rax, (%[memq])\n\t" 353*7d36db35SAvi Kivity "mov $0xfedcba9876543210, %%rax\n\t" 354*7d36db35SAvi Kivity "xchg %%rax, (%[memq])\n\t" 355*7d36db35SAvi Kivity "mov %%rax, %[rax]\n\t" 356*7d36db35SAvi Kivity : [rax]"=r"(rax) 357*7d36db35SAvi Kivity : [memq]"r"(memq) 358*7d36db35SAvi Kivity : "memory"); 359*7d36db35SAvi Kivity report("xchg reg, r/m (4)", 360*7d36db35SAvi Kivity rax == 0x123456789abcdef && *memq == 0xfedcba9876543210); 361*7d36db35SAvi Kivity } 362*7d36db35SAvi Kivity 363*7d36db35SAvi Kivity int main() 364*7d36db35SAvi Kivity { 365*7d36db35SAvi Kivity void *mem; 366*7d36db35SAvi Kivity unsigned long t1, t2; 367*7d36db35SAvi Kivity 368*7d36db35SAvi Kivity setup_vm(); 369*7d36db35SAvi Kivity mem = vmap(IORAM_BASE_PHYS, IORAM_LEN); 370*7d36db35SAvi Kivity 371*7d36db35SAvi Kivity // test mov reg, r/m and mov r/m, reg 372*7d36db35SAvi Kivity t1 = 0x123456789abcdef; 373*7d36db35SAvi Kivity asm volatile("mov %[t1], (%[mem]) \n\t" 374*7d36db35SAvi Kivity "mov (%[mem]), %[t2]" 375*7d36db35SAvi Kivity : [t2]"=r"(t2) 376*7d36db35SAvi Kivity : [t1]"r"(t1), [mem]"r"(mem) 377*7d36db35SAvi Kivity : "memory"); 378*7d36db35SAvi Kivity report("mov reg, r/m (1)", t2 == 0x123456789abcdef); 379*7d36db35SAvi Kivity 380*7d36db35SAvi Kivity test_cmps(mem); 381*7d36db35SAvi Kivity 382*7d36db35SAvi Kivity test_push(mem); 383*7d36db35SAvi Kivity test_pop(mem); 384*7d36db35SAvi Kivity 385*7d36db35SAvi Kivity test_xchg(mem); 386*7d36db35SAvi Kivity 387*7d36db35SAvi Kivity test_cr8(); 388*7d36db35SAvi Kivity 389*7d36db35SAvi Kivity test_smsw(); 390*7d36db35SAvi Kivity test_lmsw(); 391*7d36db35SAvi Kivity test_ljmp(mem); 392*7d36db35SAvi Kivity test_stringio(); 393*7d36db35SAvi Kivity test_incdecnotneg(mem); 394*7d36db35SAvi Kivity 395*7d36db35SAvi Kivity printf("\nSUMMARY: %d tests, %d failures\n", tests, fails); 396*7d36db35SAvi Kivity return fails ? 1 : 0; 397*7d36db35SAvi Kivity } 398