1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <math.h> 4 5 #define xglue(x, y) x ## y 6 #define glue(x, y) xglue(x, y) 7 #define stringify(s) tostring(s) 8 #define tostring(s) #s 9 10 #define CC_C 0x0001 11 #define CC_P 0x0004 12 #define CC_A 0x0010 13 #define CC_Z 0x0040 14 #define CC_S 0x0080 15 #define CC_O 0x0800 16 17 #define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) 18 19 static void *call_start __init_call = NULL; 20 21 #define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) 22 23 #define OP add 24 #include "test-i386.h" 25 26 #define OP sub 27 #include "test-i386.h" 28 29 #define OP xor 30 #include "test-i386.h" 31 32 #define OP and 33 #include "test-i386.h" 34 35 #define OP or 36 #include "test-i386.h" 37 38 #define OP cmp 39 #include "test-i386.h" 40 41 #define OP adc 42 #define OP_CC 43 #include "test-i386.h" 44 45 #define OP sbb 46 #define OP_CC 47 #include "test-i386.h" 48 49 #define OP inc 50 #define OP_CC 51 #define OP1 52 #include "test-i386.h" 53 54 #define OP dec 55 #define OP_CC 56 #define OP1 57 #include "test-i386.h" 58 59 #define OP neg 60 #define OP_CC 61 #define OP1 62 #include "test-i386.h" 63 64 #define OP not 65 #define OP_CC 66 #define OP1 67 #include "test-i386.h" 68 69 #undef CC_MASK 70 #define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O) 71 72 #define OP shl 73 #include "test-i386-shift.h" 74 75 #define OP shr 76 #include "test-i386-shift.h" 77 78 #define OP sar 79 #include "test-i386-shift.h" 80 81 #define OP rol 82 #include "test-i386-shift.h" 83 84 #define OP ror 85 #include "test-i386-shift.h" 86 87 #define OP rcr 88 #define OP_CC 89 #include "test-i386-shift.h" 90 91 #define OP rcl 92 #define OP_CC 93 #include "test-i386-shift.h" 94 95 96 /* lea test (modrm support) */ 97 #define TEST_LEA(STR)\ 98 {\ 99 asm("leal " STR ", %0"\ 100 : "=r" (res)\ 101 : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ 102 printf("lea %s = %08x\n", STR, res);\ 103 } 104 105 #define TEST_LEA16(STR)\ 106 {\ 107 asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ 108 : "=wq" (res)\ 109 : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ 110 printf("lea %s = %08x\n", STR, res);\ 111 } 112 113 114 void test_lea(void) 115 { 116 int eax, ebx, ecx, edx, esi, edi, res; 117 eax = 0x0001; 118 ebx = 0x0002; 119 ecx = 0x0004; 120 edx = 0x0008; 121 esi = 0x0010; 122 edi = 0x0020; 123 124 TEST_LEA("0x4000"); 125 126 TEST_LEA("(%%eax)"); 127 TEST_LEA("(%%ebx)"); 128 TEST_LEA("(%%ecx)"); 129 TEST_LEA("(%%edx)"); 130 TEST_LEA("(%%esi)"); 131 TEST_LEA("(%%edi)"); 132 133 TEST_LEA("0x40(%%eax)"); 134 TEST_LEA("0x40(%%ebx)"); 135 TEST_LEA("0x40(%%ecx)"); 136 TEST_LEA("0x40(%%edx)"); 137 TEST_LEA("0x40(%%esi)"); 138 TEST_LEA("0x40(%%edi)"); 139 140 TEST_LEA("0x4000(%%eax)"); 141 TEST_LEA("0x4000(%%ebx)"); 142 TEST_LEA("0x4000(%%ecx)"); 143 TEST_LEA("0x4000(%%edx)"); 144 TEST_LEA("0x4000(%%esi)"); 145 TEST_LEA("0x4000(%%edi)"); 146 147 TEST_LEA("(%%eax, %%ecx)"); 148 TEST_LEA("(%%ebx, %%edx)"); 149 TEST_LEA("(%%ecx, %%ecx)"); 150 TEST_LEA("(%%edx, %%ecx)"); 151 TEST_LEA("(%%esi, %%ecx)"); 152 TEST_LEA("(%%edi, %%ecx)"); 153 154 TEST_LEA("0x40(%%eax, %%ecx)"); 155 TEST_LEA("0x4000(%%ebx, %%edx)"); 156 157 TEST_LEA("(%%ecx, %%ecx, 2)"); 158 TEST_LEA("(%%edx, %%ecx, 4)"); 159 TEST_LEA("(%%esi, %%ecx, 8)"); 160 161 TEST_LEA("(,%%eax, 2)"); 162 TEST_LEA("(,%%ebx, 4)"); 163 TEST_LEA("(,%%ecx, 8)"); 164 165 TEST_LEA("0x40(,%%eax, 2)"); 166 TEST_LEA("0x40(,%%ebx, 4)"); 167 TEST_LEA("0x40(,%%ecx, 8)"); 168 169 170 TEST_LEA("-10(%%ecx, %%ecx, 2)"); 171 TEST_LEA("-10(%%edx, %%ecx, 4)"); 172 TEST_LEA("-10(%%esi, %%ecx, 8)"); 173 174 TEST_LEA("0x4000(%%ecx, %%ecx, 2)"); 175 TEST_LEA("0x4000(%%edx, %%ecx, 4)"); 176 TEST_LEA("0x4000(%%esi, %%ecx, 8)"); 177 178 /* limited 16 bit addressing test */ 179 TEST_LEA16("0x4000"); 180 TEST_LEA16("(%%bx)"); 181 TEST_LEA16("(%%si)"); 182 TEST_LEA16("(%%di)"); 183 TEST_LEA16("0x40(%%bx)"); 184 TEST_LEA16("0x40(%%si)"); 185 TEST_LEA16("0x40(%%di)"); 186 TEST_LEA16("0x4000(%%bx)"); 187 TEST_LEA16("0x4000(%%si)"); 188 TEST_LEA16("(%%bx,%%si)"); 189 TEST_LEA16("(%%bx,%%di)"); 190 TEST_LEA16("0x40(%%bx,%%si)"); 191 TEST_LEA16("0x40(%%bx,%%di)"); 192 TEST_LEA16("0x4000(%%bx,%%si)"); 193 TEST_LEA16("0x4000(%%bx,%%di)"); 194 } 195 196 #define TEST_JCC(JCC, v1, v2)\ 197 {\ 198 asm("movl $1, %0\n\t"\ 199 "cmpl %2, %1\n\t"\ 200 JCC " 1f\n\t"\ 201 "movl $0, %0\n\t"\ 202 "1:\n\t"\ 203 : "=r" (res)\ 204 : "r" (v1), "r" (v2));\ 205 printf("%-10s %d\n", JCC, res);\ 206 } 207 208 /* various jump tests */ 209 void test_jcc(void) 210 { 211 int res; 212 213 TEST_JCC("jne", 1, 1); 214 TEST_JCC("jne", 1, 0); 215 216 TEST_JCC("je", 1, 1); 217 TEST_JCC("je", 1, 0); 218 219 TEST_JCC("jl", 1, 1); 220 TEST_JCC("jl", 1, 0); 221 TEST_JCC("jl", 1, -1); 222 223 TEST_JCC("jle", 1, 1); 224 TEST_JCC("jle", 1, 0); 225 TEST_JCC("jle", 1, -1); 226 227 TEST_JCC("jge", 1, 1); 228 TEST_JCC("jge", 1, 0); 229 TEST_JCC("jge", -1, 1); 230 231 TEST_JCC("jg", 1, 1); 232 TEST_JCC("jg", 1, 0); 233 TEST_JCC("jg", 1, -1); 234 235 TEST_JCC("jb", 1, 1); 236 TEST_JCC("jb", 1, 0); 237 TEST_JCC("jb", 1, -1); 238 239 TEST_JCC("jbe", 1, 1); 240 TEST_JCC("jbe", 1, 0); 241 TEST_JCC("jbe", 1, -1); 242 243 TEST_JCC("jae", 1, 1); 244 TEST_JCC("jae", 1, 0); 245 TEST_JCC("jae", 1, -1); 246 247 TEST_JCC("ja", 1, 1); 248 TEST_JCC("ja", 1, 0); 249 TEST_JCC("ja", 1, -1); 250 251 252 TEST_JCC("jp", 1, 1); 253 TEST_JCC("jp", 1, 0); 254 255 TEST_JCC("jnp", 1, 1); 256 TEST_JCC("jnp", 1, 0); 257 258 TEST_JCC("jo", 0x7fffffff, 0); 259 TEST_JCC("jo", 0x7fffffff, -1); 260 261 TEST_JCC("jno", 0x7fffffff, 0); 262 TEST_JCC("jno", 0x7fffffff, -1); 263 264 TEST_JCC("js", 0, 1); 265 TEST_JCC("js", 0, -1); 266 TEST_JCC("js", 0, 0); 267 268 TEST_JCC("jns", 0, 1); 269 TEST_JCC("jns", 0, -1); 270 TEST_JCC("jns", 0, 0); 271 } 272 273 #undef CC_MASK 274 #define CC_MASK (CC_O | CC_C) 275 276 #define OP mul 277 #include "test-i386-muldiv.h" 278 279 #define OP imul 280 #include "test-i386-muldiv.h" 281 282 #undef CC_MASK 283 #define CC_MASK (0) 284 285 #define OP div 286 #include "test-i386-muldiv.h" 287 288 #define OP idiv 289 #include "test-i386-muldiv.h" 290 291 void test_imulw2(int op0, int op1) 292 { 293 int res, s1, s0, flags; 294 s0 = op0; 295 s1 = op1; 296 res = s0; 297 flags = 0; 298 asm ("push %4\n\t" 299 "popf\n\t" 300 "imulw %w2, %w0\n\t" 301 "pushf\n\t" 302 "popl %1\n\t" 303 : "=q" (res), "=g" (flags) 304 : "q" (s1), "0" (res), "1" (flags)); 305 printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", 306 "imulw", s0, s1, res, flags & CC_MASK); 307 } 308 309 void test_imull2(int op0, int op1) 310 { 311 int res, s1, s0, flags; 312 s0 = op0; 313 s1 = op1; 314 res = s0; 315 flags = 0; 316 asm ("push %4\n\t" 317 "popf\n\t" 318 "imull %2, %0\n\t" 319 "pushf\n\t" 320 "popl %1\n\t" 321 : "=q" (res), "=g" (flags) 322 : "q" (s1), "0" (res), "1" (flags)); 323 printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", 324 "imull", s0, s1, res, flags & CC_MASK); 325 } 326 327 void test_mul(void) 328 { 329 test_imulb(0x1234561d, 4); 330 test_imulb(3, -4); 331 test_imulb(0x80, 0x80); 332 test_imulb(0x10, 0x10); 333 334 test_imulw(0, 0x1234001d, 45); 335 test_imulw(0, 23, -45); 336 test_imulw(0, 0x8000, 0x8000); 337 test_imulw(0, 0x100, 0x100); 338 339 test_imull(0, 0x1234001d, 45); 340 test_imull(0, 23, -45); 341 test_imull(0, 0x80000000, 0x80000000); 342 test_imull(0, 0x10000, 0x10000); 343 344 test_mulb(0x1234561d, 4); 345 test_mulb(3, -4); 346 test_mulb(0x80, 0x80); 347 test_mulb(0x10, 0x10); 348 349 test_mulw(0, 0x1234001d, 45); 350 test_mulw(0, 23, -45); 351 test_mulw(0, 0x8000, 0x8000); 352 test_mulw(0, 0x100, 0x100); 353 354 test_mull(0, 0x1234001d, 45); 355 test_mull(0, 23, -45); 356 test_mull(0, 0x80000000, 0x80000000); 357 test_mull(0, 0x10000, 0x10000); 358 359 test_imulw2(0x1234001d, 45); 360 test_imulw2(23, -45); 361 test_imulw2(0x8000, 0x8000); 362 test_imulw2(0x100, 0x100); 363 364 test_imull2(0x1234001d, 45); 365 test_imull2(23, -45); 366 test_imull2(0x80000000, 0x80000000); 367 test_imull2(0x10000, 0x10000); 368 369 test_idivb(0x12341678, 0x127e); 370 test_idivb(0x43210123, -5); 371 test_idivb(0x12340004, -1); 372 373 test_idivw(0, 0x12345678, 12347); 374 test_idivw(0, -23223, -45); 375 test_idivw(0, 0x12348000, -1); 376 test_idivw(0x12343, 0x12345678, 0x81238567); 377 378 test_idivl(0, 0x12345678, 12347); 379 test_idivl(0, -233223, -45); 380 test_idivl(0, 0x80000000, -1); 381 test_idivl(0x12343, 0x12345678, 0x81234567); 382 383 test_divb(0x12341678, 0x127e); 384 test_divb(0x43210123, -5); 385 test_divb(0x12340004, -1); 386 387 test_divw(0, 0x12345678, 12347); 388 test_divw(0, -23223, -45); 389 test_divw(0, 0x12348000, -1); 390 test_divw(0x12343, 0x12345678, 0x81238567); 391 392 test_divl(0, 0x12345678, 12347); 393 test_divl(0, -233223, -45); 394 test_divl(0, 0x80000000, -1); 395 test_divl(0x12343, 0x12345678, 0x81234567); 396 } 397 398 399 static void *call_end __init_call = NULL; 400 401 int main(int argc, char **argv) 402 { 403 void **ptr; 404 void (*func)(void); 405 406 test_mul(); 407 #if 0 408 ptr = &call_start + 1; 409 while (*ptr != NULL) { 410 func = *ptr++; 411 func(); 412 } 413 test_jcc(); 414 test_lea(); 415 #endif 416 return 0; 417 } 418