fork download
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. // A helper function, which is performed very very rare.
  6. void SaveCode (const uint8_t length, const uint64_t code);
  7.  
  8.  
  9. int main (int argc, char * argv [])
  10. {
  11. const uint8_t sideLobeLimit= 1;
  12. const uint8_t length = 13;
  13. const uint64_t beginCode = 1ull << (length - 1);
  14. const uint64_t endCode = (1ull << length) - 1;
  15. const uint64_t mask = (1ull << (length - 1) ) - 1ull;
  16.  
  17. __asm__ __volatile__ (
  18. "INIT: \n\t" // Prepare for computation.
  19. " xorq %%r8, %%r8 \n\t"
  20. " movb %[length], %%r8b \n\t" // Load length of sequences into CPU register.
  21. " movq %[code], %%r9 \n\t" // Load first sequence of the range into CPU register.
  22. " movq %[maxcode], %%r10 \n\t" // Load last sequence of the range into CPU register.
  23. " movb %[limit], %%r11b \n\t" // Load maximum allowed level of sidelobes into CPU register.
  24. " movq %[mask], %%r12 \n\t" // Load mask for extracting significant bits into CPU register.
  25. "CHECK_CODE: \n\t" // Body of loop through sequence (like the "do-while" loop).
  26. " mov $1, %%cx \n\t" // Set the offset value.
  27. " movq %%r12, %%r13 \n\t" // Set mask into mutable variable.
  28. "NEXT_SHIFT: \n\t" // Beginning of loop through shift of sequence (like the "do-while" loop).
  29. " movq %%r9, %%rdi \n\t" // Shifting sequence.
  30. " shrq %%cl, %%rdi \n\t" // Shift.
  31. " xorq %%r9, %%rdi \n\t" // Counting level of sidelobes.
  32. " andq %%r13, %%rdi \n\t" // Remove extra bits.
  33. " popcntq %%rdi, %%rax \n\t" // al = n (number of the different bits).
  34. " shl $1, %%ax \n\t" // al = 2 * n.
  35. " sub %%r8w, %%ax \n\t" // al = 2 * n - l (l - length of the sequence).
  36. " add %%cx, %%ax \n\t" // al = o + 2 * n - l (o - current offset).
  37. " cwd \n\t" // .
  38. " add %%dx, %%ax \n\t" // .
  39. " xor %%dx, %%ax \n\t" // al =|o + 2 * n - l| (now al contain the sidelobe level).
  40. " cmpb %%r11b, %%al \n\t" // Check if the sidelobe level acceptable?
  41. " jg NEXT_CODE \n\t" // If it is not, then go to the next sequence.
  42. " incb %%cl \n\t" // Increment the offset for creating next shifted sequence.
  43. " cmpb %%cl, %%r8b \n\t" // Check if is it the lass offset.
  44. " jbe SAVE_CODE \n\t" // If it is, then save cureent sequence.
  45. " shrq $1, %%r13 \n\t" // Shift mask for next shifted sequence.
  46. " jmp NEXT_SHIFT \n\t" // End of loop through shift of sequence.
  47. "NEXT_CODE: \n\t" // Control of loop through sequence.
  48. " incq %%r9 \n\t" // Set next sequence.
  49. " cmpq %%r10, %%r9 \n\t" // Check if the sequence inside the range.
  50. " jbe CHECK_CODE \n\t" // If it is, then go to the begining of the loops body.
  51. " jmp QUIT \n\t" // If it is not, then go to the end of procedure.
  52. "SAVE_CODE: \n\t" // Saving sequence with accepted level of sidelobes.
  53. " pushq %%r8 \n\t" // Store registers.
  54. " pushq %%r9 \n\t" // .
  55. " pushq %%r10 \n\t" // .
  56. " pushq %%r11 \n\t" // .
  57. " pushq %%r12 \n\t" // .
  58. " movl %%r8d, %%edi \n\t" // .
  59. " movq %%r9, %%rsi \n\t" // .
  60. " call SaveCode \n\t" // Calling external function for saving the sequence.
  61. " popq %%r12 \n\t" // Restore registers.
  62. " popq %%r11 \n\t" // .
  63. " popq %%r10 \n\t" // .
  64. " popq %%r9 \n\t" // .
  65. " popq %%r8 \n\t" // .
  66. " jmp NEXT_CODE \n\t" // Continue test sequences.
  67. "QUIT: \n\t" // Exit of procedure.
  68. " nop \n\t" // .
  69. :
  70. : [length ] "m" (length),
  71. [code ] "m" (beginCode),
  72. [maxcode] "m" (endCode),
  73. [limit ] "m" (sideLobeLimit),
  74. [mask ] "m" (mask)
  75. : "%rax", "%rcx", "%rdx", "%rdi", "%rsi",
  76. "%r8", "%r9", "%r10", "%r11", "%r12", "%r13"
  77. );
  78.  
  79. return EXIT_SUCCESS;
  80. }
  81.  
  82.  
  83. void SaveCode (const uint8_t length, const uint64_t code)
  84. {
  85. uint8_t i = 0;
  86. for (i = 0; i < length; ++i) {
  87. (code >> i) & 0x01 ? printf ("+") : printf ("-");
  88. }
  89. printf ("\n");
  90. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:77:6: error: unknown register name ‘%r13’ in ‘asm’
     );
      ^
prog.cpp:77:6: error: unknown register name ‘%r12’ in ‘asm’
prog.cpp:77:6: error: unknown register name ‘%r11’ in ‘asm’
prog.cpp:77:6: error: unknown register name ‘%r10’ in ‘asm’
prog.cpp:77:6: error: unknown register name ‘%r9’ in ‘asm’
prog.cpp:77:6: error: unknown register name ‘%r8’ in ‘asm’
stdout
Standard output is empty