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.