This is an archive of the discontinued LLVM Phabricator instance.

[AVR] Fix incorrect decoding of RJMP and RCALL
ClosedPublic

Authored by benshi001 on Dec 31 2022, 10:48 PM.

Details

Summary

This patch fixes the inaccurate decoding of the offset operand of
the RCALL & RJMP instructions.

Diff Detail

Event Timeline

benshi001 created this revision.Dec 31 2022, 10:48 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 31 2022, 10:48 PM
benshi001 requested review of this revision.Dec 31 2022, 10:48 PM
benshi001 retitled this revision from [AVR] Fix incorrect decoding of RJMP and RCALL. to [AVR] Fix incorrect decoding of RJMP and RCALL.Jan 1 2023, 12:45 AM
benshi001 added a reviewer: MaskRay.
aykevl added a comment.Jan 1 2023, 7:02 AM

Shouldn't this also affect llvm/test/MC/AVR/inst-rjmp.s?
In any case, I think it's better to (also) have tests in llvm/test/MC/AVR for this.

benshi001 added a comment.EditedJan 1 2023, 5:11 PM

Shouldn't this also affect llvm/test/MC/AVR/inst-rjmp.s?
In any case, I think it's better to (also) have tests in llvm/test/MC/AVR for this.

Actually this bug does not affect llvm/test/MC/AVR/inst-rjmp.s, so I can not add any test in llvm/test/MC/AVR.

Since llvm-objdump decodes all address offsets of rjmp/rcall (before linking) to 0, so you can see those zeros in llvm/test/MC/AVR/inst-rjmp.s, which are not affected.

llvm-objdump only affects address offsets of rjmp/rcall that are after linking, so we have to test them in the lld tests.

benshi001 added inline comments.Jan 1 2023, 5:13 PM
llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
300

This is modified by clang-format .

aykevl added a comment.Jan 6 2023, 1:05 PM

Since llvm-objdump decodes all address offsets of rjmp/rcall (before linking) to 0, so you can see those zeros in llvm/test/MC/AVR/inst-rjmp.s, which are not affected.

llvm-objdump only affects address offsets of rjmp/rcall that are after linking, so we have to test them in the lld tests.

Hmm, yeah that's a problem.
@MaskRay do you have an idea how to properly test this? I don't like moving these tests into lld (it's a separate subproject), but the alternative seems to be to use a binary file to test against which isn't great either.

benshi001 added a comment.EditedJan 6 2023, 6:54 PM

Since llvm-objdump decodes all address offsets of rjmp/rcall (before linking) to 0, so you can see those zeros in llvm/test/MC/AVR/inst-rjmp.s, which are not affected.

llvm-objdump only affects address offsets of rjmp/rcall that are after linking, so we have to test them in the lld tests.

Hmm, yeah that's a problem.
@MaskRay do you have an idea how to properly test this? I don't like moving these tests into lld (it's a separate subproject), but the alternative seems to be to use a binary file to test against which isn't great either.

I do see many .o files in clang/test/, but none in llvm/test/MC/ . Do we need to create such a precedent ?

MaskRay added a comment.EditedJan 6 2023, 7:22 PM

llvm-objdump only affects address offsets of rjmp/rcall that are after linking, so we have to test them in the lld tests.

It's not appropriate to add a lld test to test an assembly issue (https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-at-the-wrong-layer). Such tests live in llvm/test/MC/

If you want to disassembly an arbitrary instruction, you may use directives like .word: after disassembly, an instruction isn't differentiable with a .word xxx.
If you want to craft an ET_EXEC or ET_DYN file, use yaml2obj. See llvm/test/tools/llvm-{objcopy,readobj} for some examples.

You can use llvm-readelf -x ... to dump the content of a section.

benshi001 updated this revision to Diff 487051.EditedJan 6 2023, 10:39 PM

llvm-objdump only affects address offsets of rjmp/rcall that are after linking, so we have to test them in the lld tests.

It's not appropriate to add a lld test to test an assembly issue (https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-at-the-wrong-layer). Such tests live in llvm/test/MC/

If you want to disassembly an arbitrary instruction, you may use directives like .word: after disassembly, an instruction isn't differentiable with a .word xxx.
If you want to craft an ET_EXEC or ET_DYN file, use yaml2obj. See llvm/test/tools/llvm-{objcopy,readobj} for some examples.

You can use llvm-readelf -x ... to dump the content of a section.

Thanks. Using the .short directive seems the most clear way !

benshi001 edited the summary of this revision. (Show Details)Jan 6 2023, 11:29 PM
benshi001 added inline comments.Jan 6 2023, 11:35 PM
llvm/test/MC/AVR/inst-rjmp.s
49

The positive offset is tested here and the negative offset is tested in inst-rcall.s.

aykevl accepted this revision.Jan 7 2023, 7:23 AM

That's indeed a nice solution, didn't think of that!

llvm/test/MC/AVR/inst-rcall.s
13

It may be useful for the reader to add what this means: .short 0xdfea ; rcall .-44

This revision is now accepted and ready to land.Jan 7 2023, 7:23 AM
This revision was landed with ongoing or failed builds.Jan 7 2023, 7:32 AM
This revision was automatically updated to reflect the committed changes.