Skip to content

Unexpected assembly output using relative offsets in inline assembler #47093

Closed as not planned
@s-ol

Description

@s-ol
Bugzilla Link 47749
Version 10.0
OS Linux
Attachments Example Program showing the unexpected behaviour

Extended Description

While porting C source (https://github.com/cpldcpu/light_ws2812/blob/master/light_ws2812_AVR/Light_WS2812/light_ws2812.c) to Zig, which uses LLVM as a backend, I noticed that the "rjmp .+0" instructions that are used as 2-cycle NOPs under avr-gcc assembled to "rjmp .-2" (infinite loops) under Zig and LLVM/Clang.

Here is some code to reproduce:

/*
$ clang -target avr-freestanding-eabi -mmcu=atmega32u2 demo_c.c -c -o demo_c.o
$ avr-gcc -mmcu=atmega32u2 demo_c.o -o demo_c.elf
$ avr-objdump --siassemble=main demo_c.elf

  demo_c.elf:     file format elf32-avr


  Disassembly of section .text:

  00000000 <main>:
     0:	fe cf       	rjmp	.-4      	; 0xfffffffe <__eeprom_end+0xff7efffe>
     2:	ff cf       	rjmp	.-2      	; 0x2 <main+0x2>
     4:	00 c0       	rjmp	.+0      	; 0x6 <main+0x6>
     6:	80 e0       	ldi	r24, 0x00	; 0
     8:	90 e0       	ldi	r25, 0x00	; 0
     a:	08 95       	ret

*/

int main() {
  asm("rjmp .-2");
  asm("rjmp .+0");
  asm("rjmp .+2");
}

(this file is also attached as demo_c.c)

Note that just inspecting the object file created using clang will confusingly show "rjmp .+0" thrice since the actual offset is set using relocation fixups at that stage.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions