https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118934

--- Comment #6 from liu mirko <lw297073896 at gmail dot com> ---
(In reply to liu mirko from comment #5)
> (In reply to Jeffrey A. Law from comment #4)
> > This should be fixed on the trunk.
> 
> int foo(int x)
> {
>   if (x)
>     goto out;
> 
>   // > 1MB of code
>   INSNS_524288
> 
> out:
>   return x;
> }
> 
> if "INSNS_524288" is replaced with "asm volatile("nop;nop;....Repeat A
> multiple times");" and the assembly code of nop exceeds 1MB, the problem may
> still persist.

sorry, the above case does not encounter linking issues with "nop;", but
problems arise when using the pseudo-instruction "li t5,0x180000000;" in "asm
volatile" (which actually maps to two instructions with a length of 6 bytes).
In the md file:
```
;; Length of instruction in bytes.
(define_attr "length" ""
   (cond [
          ;; Branches further than +/- 1 MiB require three instructions.
          ;; Branches further than +/- 4 KiB require two instructions.
          (eq_attr "type" "branch")
          (if_then_else (and (le (minus (match_dup 0) (pc))
                                 (const_int 4088))
                             (le (minus (pc) (match_dup 0))
                                 (const_int 4092)))
                        (const_int 4)
                        (if_then_else (and (le (minus (match_dup 0) (pc))
                                               (const_int 1048568))
                                           (le (minus (pc) (match_dup 0))
                                               (const_int 1048572)))
                                      (const_int 8)
                                      (const_int 12)))

          ;; Jumps further than +/- 1 MiB require two instructions.
          (eq_attr "type" "jump")
          (if_then_else (and (le (minus (match_dup 0) (pc))
                                 (const_int 1048568))
                             (le (minus (pc) (match_dup 0))
                                 (const_int 1048572)))
                        (const_int 4)
                        (const_int 8))

          ;; Conservatively assume calls take two instructions (AUIPC + JALR).
          ;; The linker will opportunistically relax the sequence to JAL.
          (eq_attr "type" "call") (const_int 8)

          ;; "Ghost" instructions occupy no space.
          (eq_attr "type" "ghost") (const_int 0)

          (eq_attr "got" "load") (const_int 8)

          ;; SHIFT_SHIFTs are decomposed into two separate instructions.
          (eq_attr "move_type" "shift_shift")
                (const_int 8)

          ;; Check for doubleword moves that are decomposed into two
          ;; instructions.
          (and (eq_attr "move_type" "mtc,mfc,move")
               (eq_attr "dword_mode" "yes"))
          (const_int 8)

          ;; Doubleword CONST{,N} moves are split into two word
          ;; CONST{,N} moves.
          (and (eq_attr "move_type" "const")
               (eq_attr "dword_mode" "yes"))
          (symbol_ref "riscv_split_const_insns (operands[1]) * 4")

          ;; Otherwise, constants, loads and stores are handled by external
          ;; routines.
          (eq_attr "move_type" "load,fpload")
          (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
          (eq_attr "move_type" "store,fpstore")
          (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
          ] (const_int 4)))
```

the "length" of an assembly instruction is 4, leading to incorrect judgment of
the instruction length in "asm volatile".

Reply via email to