Minimum version of binutils required to compile the kernel is 2.25.
This version correctly handles the "rep" prefixes, so it is possible
to remove the semicolon, which was used to support ancient versions
of GNU as.
Due to the semicolon, the compiler considers "rep; insn" (or its
alternate "rep\n\tinsn" form) as two separate instructions. Removing
the semicolon makes asm length calculations more accurate, consequently
making scheduling and inlining decisions of the compiler more accurate.
Removing the semicolon also enables assembler checks involving "rep"
prefixes. Trying to assemble e.g. "rep addl %eax, %ebx" results in:
  Error: invalid instruction `add' after `rep'
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Pavel Machek <pavel@kernel.org>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Link: https://lore.kernel.org/r/20250418071437.4144391-2-ubizjak@gmail.com
 static inline void __iowrite32_copy(void __iomem *to, const void *from,
                                    size_t count)
 {
-       asm volatile("rep ; movsl"
+       asm volatile("rep movsl"
                     : "=&c"(count), "=&D"(to), "=&S"(from)
                     : "0"(count), "1"(to), "2"(from)
                     : "memory");
                        count--;                                        \
                }                                                       \
        } else {                                                        \
-               asm volatile("rep; outs" #bwl                           \
+               asm volatile("rep outs" #bwl                            \
                             : "+S"(addr), "+c"(count)                  \
                             : "d"(port) : "memory");                   \
        }                                                               \
                        count--;                                        \
                }                                                       \
        } else {                                                        \
-               asm volatile("rep; ins" #bwl                            \
+               asm volatile("rep ins" #bwl                             \
                             : "+D"(addr), "+c"(count)                  \
                             : "d"(port) : "memory");                   \
        }                                                               \
 
 static __always_inline void *__memcpy(void *to, const void *from, size_t n)
 {
        int d0, d1, d2;
-       asm volatile("rep ; movsl\n\t"
+       asm volatile("rep movsl\n\t"
                     "movl %4,%%ecx\n\t"
                     "andl $3,%%ecx\n\t"
                     "jz 1f\n\t"
-                    "rep ; movsb\n\t"
+                    "rep movsb\n\t"
                     "1:"
                     : "=&c" (d0), "=&D" (d1), "=&S" (d2)
                     : "0" (n / 4), "g" (n), "1" ((long)to), "2" ((long)from)
        if (n >= 5 * 4) {
                /* large block: use rep prefix */
                int ecx;
-               asm volatile("rep ; movsl"
+               asm volatile("rep movsl"
                             : "=&c" (ecx), "=&D" (edi), "=&S" (esi)
                             : "0" (n / 4), "1" (edi), "2" (esi)
                             : "memory"
 static inline void *__memset_generic(void *s, char c, size_t count)
 {
        int d0, d1;
-       asm volatile("rep\n\t"
-                    "stosb"
+       asm volatile("rep stosb"
                     : "=&c" (d0), "=&D" (d1)
                     : "a" (c), "1" (s), "0" (count)
                     : "memory");
 static inline void *memset16(uint16_t *s, uint16_t v, size_t n)
 {
        int d0, d1;
-       asm volatile("rep\n\t"
-                    "stosw"
+       asm volatile("rep stosw"
                     : "=&c" (d0), "=&D" (d1)
                     : "a" (v), "1" (s), "0" (n)
                     : "memory");
 static inline void *memset32(uint32_t *s, uint32_t v, size_t n)
 {
        int d0, d1;
-       asm volatile("rep\n\t"
-                    "stosl"
+       asm volatile("rep stosl"
                     : "=&c" (d0), "=&D" (d1)
                     : "a" (v), "1" (s), "0" (n)
                     : "memory");
 
        movl $pa(__bss_stop),%ecx
        subl %edi,%ecx
        shrl $2,%ecx
-       rep ; stosl
+       rep stosl
 /*
  * Copy bootup parameters out of the way.
  * Note: %esi still has the pointer to the real-mode data.
        movl $pa(boot_params),%edi
        movl $(PARAM_SIZE/4),%ecx
        cld
-       rep
-       movsl
+       rep movsl
        movl pa(boot_params) + NEW_CL_POINTER,%esi
        andl %esi,%esi
        jz 1f                   # No command line
        movl $pa(boot_command_line),%edi
        movl $(COMMAND_LINE_SIZE/4),%ecx
-       rep
-       movsl
+       rep movsl
 1:
 
 #ifdef CONFIG_OLPC
 
 
        movl    %edx, %edi
        movl    $1024, %ecx
-       rep ; movsl
+       rep movsl
 
        movl    %ebp, %edi
        movl    %eax, %esi
        movl    $1024, %ecx
-       rep ; movsl
+       rep movsl
 
        movl    %eax, %edi
        movl    %edx, %esi
        movl    $1024, %ecx
-       rep ; movsl
+       rep movsl
 
        lea     PAGE_SIZE(%ebp), %esi
        jmp     0b
 
        /* copy source page to swap page */
        movq    kexec_pa_swap_page(%rip), %rdi
        movl    $512, %ecx
-       rep ; movsq
+       rep movsq
 
        /* copy destination page to source page */
        movq    %rax, %rdi
        movq    %rdx, %rsi
        movl    $512, %ecx
-       rep ; movsq
+       rep movsq
 
        /* copy swap page to destination page */
        movq    %rdx, %rdi
        movq    kexec_pa_swap_page(%rip), %rsi
 .Lnoswap:
        movl    $512, %ecx
-       rep ; movsq
+       rep movsq
 
        lea     PAGE_SIZE(%rax), %rsi
        jmp     .Lloop
 
 static __always_inline void rep_movs(void *to, const void *from, size_t n)
 {
        unsigned long d0, d1, d2;
-       asm volatile("rep ; movsl\n\t"
+       asm volatile("rep movsl\n\t"
                     "testb $2,%b4\n\t"
                     "je 1f\n\t"
                     "movsw\n"
 
                "stosb\n\t"
                "testb %%al,%%al\n\t"
                "jne 1b\n\t"
-               "rep\n\t"
-               "stosb\n"
+               "rep stosb\n"
                "2:"
                : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
                : "0" (src), "1" (dest), "2" (count) : "memory");
 char *strcat(char *dest, const char *src)
 {
        int d0, d1, d2, d3;
-       asm volatile("repne\n\t"
-               "scasb\n\t"
+       asm volatile("repne scasb\n\t"
                "decl %1\n"
                "1:\tlodsb\n\t"
                "stosb\n\t"
 char *strncat(char *dest, const char *src, size_t count)
 {
        int d0, d1, d2, d3;
-       asm volatile("repne\n\t"
-               "scasb\n\t"
+       asm volatile("repne scasb\n\t"
                "decl %1\n\t"
                "movl %8,%3\n"
                "1:\tdecl %3\n\t"
 {
        int d0;
        size_t res;
-       asm volatile("repne\n\t"
-               "scasb"
+       asm volatile("repne scasb"
                : "=c" (res), "=&D" (d0)
                : "1" (s), "a" (0), "0" (0xffffffffu)
                : "memory");
        void *res;
        if (!count)
                return NULL;
-       asm volatile("repne\n\t"
-               "scasb\n\t"
+       asm volatile("repne scasb\n\t"
                "je 1f\n\t"
                "movl $1,%0\n"
                "1:\tdecl %0"
 {
        if (!size)
                return addr;
-       asm volatile("repnz; scasb\n\t"
+       asm volatile("repnz scasb\n\t"
            "jnz 1f\n\t"
            "dec %%edi\n"
            "1:"
 
 register char *__res;
 __asm__ __volatile__(
        "movl %6,%%edi\n\t"
-       "repne\n\t"
-       "scasb\n\t"
+       "repne scasb\n\t"
        "notl %%ecx\n\t"
        "decl %%ecx\n\t"        /* NOTE! This also sets Z if searchstring='' */
        "movl %%ecx,%%edx\n"
        "1:\tmovl %6,%%edi\n\t"
        "movl %%esi,%%eax\n\t"
        "movl %%edx,%%ecx\n\t"
-       "repe\n\t"
-       "cmpsb\n\t"
+       "repe cmpsb\n\t"
        "je 2f\n\t"             /* also works for empty string, see above */
        "xchgl %%eax,%%esi\n\t"
        "incl %%esi\n\t"
 
        might_fault();                                                  \
        __asm__ __volatile__(                                           \
                ASM_STAC "\n"                                           \
-               "0:     rep; stosl\n"                                   \
+               "0:     rep stosl\n"                                    \
                "       movl %2,%0\n"                                   \
-               "1:     rep; stosb\n"                                   \
+               "1:     rep stosb\n"                                    \
                "2: " ASM_CLAC "\n"                                     \
                _ASM_EXTABLE_TYPE_REG(0b, 2b, EX_TYPE_UCOPY_LEN4, %2)   \
                _ASM_EXTABLE_UA(1b, 2b)                                 \
                       "       shrl  $2, %0\n"
                       "       andl  $3, %%eax\n"
                       "       cld\n"
-                      "99:    rep; movsl\n"
+                      "99:    rep movsl\n"
                       "36:    movl %%eax, %0\n"
-                      "37:    rep; movsb\n"
+                      "37:    rep movsb\n"
                       "100:\n"
                       _ASM_EXTABLE_UA(1b, 100b)
                       _ASM_EXTABLE_UA(2b, 100b)
               "        shrl  $2, %0\n"
               "        andl $3, %%eax\n"
               "        cld\n"
-              "6:      rep; movsl\n"
+              "6:      rep movsl\n"
               "        movl %%eax,%0\n"
-              "7:      rep; movsb\n"
+              "7:      rep movsb\n"
               "8:\n"
               _ASM_EXTABLE_UA(0b, 8b)
               _ASM_EXTABLE_UA(1b, 8b)
                "       negl %0\n"                                      \
                "       andl $7,%0\n"                                   \
                "       subl %0,%3\n"                                   \
-               "4:     rep; movsb\n"                                   \
+               "4:     rep movsb\n"                                    \
                "       movl %3,%0\n"                                   \
                "       shrl $2,%0\n"                                   \
                "       andl $3,%3\n"                                   \
                "       .align 2,0x90\n"                                \
-               "0:     rep; movsl\n"                                   \
+               "0:     rep movsl\n"                                    \
                "       movl %3,%0\n"                                   \
-               "1:     rep; movsb\n"                                   \
+               "1:     rep movsb\n"                                    \
                "2:\n"                                                  \
                _ASM_EXTABLE_TYPE_REG(4b, 2b, EX_TYPE_UCOPY_LEN1, %3)   \
                _ASM_EXTABLE_TYPE_REG(0b, 2b, EX_TYPE_UCOPY_LEN4, %3)   \
 
        mov %ebx, %esi
        movl rva(pvh_start_info_sz)(%ebp), %ecx
        shr $2,%ecx
-       rep
-       movsl
+       rep movsl
 
        leal rva(early_stack_end)(%ebp), %esp
 
 
        movl    pbe_orig_address(%edx), %edi
 
        movl    $(PAGE_SIZE >> 2), %ecx
-       rep
-       movsl
+       rep movsl
 
        movl    pbe_next(%edx), %edx
        jmp     copy_loop
 
        movq    pbe_address(%rdx), %rsi
        movq    pbe_orig_address(%rdx), %rdi
        movq    $(PAGE_SIZE >> 3), %rcx
-       rep
-       movsq
+       rep movsq
 
        /* progress to the next pbe */
        movq    pbe_next(%rdx), %rdx