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

            Bug ID: 77570
           Summary: [msp430-elf] Wrong assembly in delay_cycles_32x insn
                    declaration
           Product: gcc
           Version: 6.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: oarias at knights dot ucf.edu
  Target Milestone: ---

Created attachment 39607
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39607&action=edit
Patch which fixes the assembly issued by the delay_cycles_32x insn.

Greetings,

We ran into a bug this weekend and traced it back to the following. The delay
loop insn for loops with 32bit constants currently does the following:

(define_insn "delay_cycles_32x"
  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
                     (match_operand 1 "immediate_operand" "i")
                     ] UNS_DELAY_32X)]
  ""
  "PUSHM.A      #2,r13
        MOV.W   %A0, r13
        MOV.W   %B0, r14
1:      SUB.W   #1, r13
        SUBC.W  #0, r14
        JNE     1b
        TST.W   r13
        JNE     1b
        POPM.A  #2,r13"
  )

The assembly issued by this insn is not correct. According to the CPUX
description of the pushm and popm instructions, the list of registers saved is
from n-1 to the listed register in the instruction. As such,

pushm.a #2, r13 ; saves r12 and r13 in the stack, and
popm.a #2, r13 ; restores r12 and r13 from the stack

However, in this loop, the compiler uses r13 and r14 as temporaries. However,
it does not save r14 into the stack, corrupting its value. The attached patch
fixes the insn. I have not checked whether a similar situation happens
somewhere else in the msp430-elf backend. Thank you.

Cheers,
Orlando.

Reply via email to