fork download
  1. #include <stdio.h>
  2. #include <inttypes.h>
  3. #include <limits.h>
  4.  
  5. __asm__ (
  6. /* support both environments that does and doesn't add underscore before function name */
  7. "loop_asm:\n"
  8. "_loop_asm:\n"
  9. "push %ebp\n"
  10. "mov %esp, %ebp\n"
  11. "push %esi\n"
  12. "push %edi\n"
  13. "push %ebx\n"
  14.  
  15. "# x at %ebp+8, n at %ebp+12\n"
  16. "movl 8(%ebp), %esi\n"
  17. "movl 12(%ebp), %ebx\n"
  18. "movl $-1, %edi\n"
  19. "movl $1, %edx\n"
  20. ".L2_test:\n" /* rename .L2 to .L2_test to avoid collision */
  21. "movl %edx, %eax\n"
  22. "andl %esi, %eax\n"
  23. "xorl %eax, %edi\n"
  24. "movl %ebx, %ecx\n"
  25. "sall %cl, %edx\n"
  26. "testl %edx, %edx\n"
  27. "jne .L2_test\n"
  28. "movl %edi, %eax\n"
  29.  
  30. "pop %ebx\n"
  31. "pop %edi\n"
  32. "pop %esi\n"
  33. "leave\n"
  34. "ret\n"
  35. );
  36.  
  37. uint32_t loop_asm(uint32_t, uint32_t);
  38.  
  39. uint32_t loop_convert(uint32_t x, uint32_t n) {
  40. uint32_t result = -1;
  41. uint32_t mask;
  42. for (mask = 1; mask != 0; mask <<= n & 31) {
  43. result ^= mask & x;
  44. }
  45. return result;
  46. }
  47.  
  48. int mask;
  49. int loop(int x, int n){
  50.  
  51. int result = -1;
  52.  
  53. for (mask = 1; mask >= result; mask = x&1) {
  54.  
  55. result ^= n;
  56.  
  57. }
  58. return result;
  59. }
  60.  
  61. int main(void) {
  62. int x, n;
  63. uint32_t raw, test, conv;
  64. int miss_count = 0;
  65. /* search for mismatch in some range */
  66. for (n = 1; n < 32; n++) {
  67. uint32_t x_test;
  68. for (x_test = 0; x_test < UINT32_C(100000); x_test++) {
  69. if (loop_asm(x, n) != loop_convert(x, n)) {
  70. printf("mismatch at x=%"PRIu32", n=%d\n", x_test, n);
  71. if (miss_count < INT_MAX) miss_count++;
  72. }
  73. }
  74. }
  75. printf("%d mismatch(es) found.\n", miss_count);
  76. /* print some examples */
  77. x = 100;
  78. n = 5;
  79. raw = loop_asm(x, n);
  80. conv = loop_convert(x, n);
  81. printf("loop_asm(%d, %d) = %"PRIu32"\n", x, n, raw);
  82. printf("loop_convert(%d, %d) = %"PRIu32"\n", x, n, conv);
  83. fflush(stdout);
  84. test = loop(x, n);
  85. printf("loop(%d, %d) = %"PRIu32"\n", x, n, test);
  86. return 0;
  87. }
  88.  
Time limit exceeded #stdin #stdout 5s 2156KB
stdin
Standard input is empty
stdout
0 mismatch(es) found.
loop_asm(100, 5) = 4294967263
loop_convert(100, 5) = 4294967263