Pieter Kapsenberg via llvm-dev
2020-Jan-30 02:56 UTC
[llvm-dev] RISC-V disassembly doesn't seem to know about multiply instructions
I built llvm + clang from source, a github clone from today: clang version 11.0.0 (https://github.com/llvm/llvm-project.git 91aa67bf290bc7f877b1b90128284863bc31aa43) I compiled a small program: #include <stdint.h> int main() { uint8_t a = 2; uint8_t b = 5; uint8_t c = a * b; } $ clang -c -target riscv32 -march=rv32imc -g main.c Works fine. The dumped assembly seems to not know about the multiply instruction - is that expected? See offset 1e in the listing below. Happily, the opcode value does appear to match the MUL instruction. $ llvm-objdump -S main.o main.o: file format ELF32-riscv Disassembly of section .text: 00000000 .text: /usr/local/google/home/pkapsenb/work/llvm-project/build/bin/llvm-objdump: warning: 'main.o': failed to parse debug information for main.o 0: 01 00 nop 00000002 main: ; int main() { 2: 41 11 addi sp, sp, -16 4: 06 c6 sw ra, 12(sp) 6: 22 c4 sw s0, 8(sp) 8: 00 08 addi s0, sp, 16 a: 09 45 addi a0, zero, 2 ; uint8_t a = 2; c: a3 0b a4 fe sb a0, -9(s0) 10: 15 45 addi a0, zero, 5 ; uint8_t b = 5; 12: 23 0b a4 fe sb a0, -10(s0) ; uint8_t c = a * b; 16: 03 05 74 ff lb a0, -9(s0) 1a: 83 05 64 ff lb a1, -10(s0) 1e: 33 05 b5 02 *<unknown>* 22: a3 0a a4 fe sb a0, -11(s0) 26: 01 45 mv a0, zero ; } 28: 22 44 lw s0, 8(sp) 2a: b2 40 lw ra, 12(sp) 2c: 41 01 addi sp, sp, 16 2e: 82 80 ret -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200129/bcd2734d/attachment.html>
Sam Elliott via llvm-dev
2020-Jan-30 10:56 UTC
[llvm-dev] RISC-V disassembly doesn't seem to know about multiply instructions
For your architecture (rv32imc), you’ll need to pass `-mattr=+m,+c` which allows llvm-objdump to disassemble both the M and the C RISC-V extensions. For more general background: `-mattr=` takes a comma separated list of features to enable (+feature) or disable (-feature). The RISC-V backend has one “feature” per implemented RISC-V architectural extension, each named using the lower case letter that corresponds to the extension in the RISC-V specification. LLVM chooses a default set of features based on the triple, but for `riscv32` (which expands to `riscv32-unknown-elf`) we enable the features that correspond to `rv32i` only. I hope this helps you out! It is good to know that this is somewhere the RISC-V backend could improve its documentation. Sam> On 30 Jan 2020, at 2:56 am, Pieter Kapsenberg via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > I built llvm + clang from source, a github clone from today: > clang version 11.0.0 (https://github.com/llvm/llvm-project.git 91aa67bf290bc7f877b1b90128284863bc31aa43) > > I compiled a small program: > #include <stdint.h> > > int main() { > uint8_t a = 2; > uint8_t b = 5; > uint8_t c = a * b; > } > $ clang -c -target riscv32 -march=rv32imc -g main.c > Works fine. > > The dumped assembly seems to not know about the multiply instruction - is that expected? See offset 1e in the listing below. Happily, the opcode value does appear to match the MUL instruction. > > $ llvm-objdump -S main.o > main.o: file format ELF32-riscv > > > Disassembly of section .text: > > 00000000 .text: > /usr/local/google/home/pkapsenb/work/llvm-project/build/bin/llvm-objdump: warning: 'main.o': failed to parse debug information for main.o > 0: 01 00 nop > > 00000002 main: > ; int main() { > 2: 41 11 addi sp, sp, -16 > 4: 06 c6 sw ra, 12(sp) > 6: 22 c4 sw s0, 8(sp) > 8: 00 08 addi s0, sp, 16 > a: 09 45 addi a0, zero, 2 > ; uint8_t a = 2; > c: a3 0b a4 fe sb a0, -9(s0) > 10: 15 45 addi a0, zero, 5 > ; uint8_t b = 5; > 12: 23 0b a4 fe sb a0, -10(s0) > ; uint8_t c = a * b; > 16: 03 05 74 ff lb a0, -9(s0) > 1a: 83 05 64 ff lb a1, -10(s0) > 1e: 33 05 b5 02 <unknown> > 22: a3 0a a4 fe sb a0, -11(s0) > 26: 01 45 mv a0, zero > ; } > 28: 22 44 lw s0, 8(sp) > 2a: b2 40 lw ra, 12(sp) > 2c: 41 01 addi sp, sp, 16 > 2e: 82 80 ret > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Sam Elliott Software Developer - LLVM lowRISC CIC --
Simon Cook via llvm-dev
2020-Jan-30 11:46 UTC
[llvm-dev] RISC-V disassembly doesn't seem to know about multiply instructions
Hi Sam, I'm wondering in this case whether for the disassembler we should be using a different default that explicitly enables all the standard extensions to match what it looks like GNU binutils objdump is doing (I note we already do this for extracting compressed support out of the e_flags field in ElfObjectFile.cpp)? I know there is the .riscv.attributes section that gas now adds that stores this information, which we could use at some point to autoenable the correct feature subset, but it looks like LLVM doesn't yet generate or support parsing that. Do we know if anyone has been working on or plans on adding support for that. Thanks, Simon On 30/01/2020 10:56, Sam Elliott via llvm-dev wrote:> For your architecture (rv32imc), you’ll need to pass `-mattr=+m,+c` which allows llvm-objdump to disassemble both the M and the C RISC-V extensions. > > For more general background: `-mattr=` takes a comma separated list of features to enable (+feature) or disable (-feature). The RISC-V backend has one “feature” per implemented RISC-V architectural extension, each named using the lower case letter that corresponds to the extension in the RISC-V specification. LLVM chooses a default set of features based on the triple, but for `riscv32` (which expands to `riscv32-unknown-elf`) we enable the features that correspond to `rv32i` only. > > I hope this helps you out! It is good to know that this is somewhere the RISC-V backend could improve its documentation. > > Sam > > >> On 30 Jan 2020, at 2:56 am, Pieter Kapsenberg via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> >> I built llvm + clang from source, a github clone from today: >> clang version 11.0.0 (https://github.com/llvm/llvm-project.git 91aa67bf290bc7f877b1b90128284863bc31aa43) >> >> I compiled a small program: >> #include <stdint.h> >> >> int main() { >> uint8_t a = 2; >> uint8_t b = 5; >> uint8_t c = a * b; >> } >> $ clang -c -target riscv32 -march=rv32imc -g main.c >> Works fine. >> >> The dumped assembly seems to not know about the multiply instruction - is that expected? See offset 1e in the listing below. Happily, the opcode value does appear to match the MUL instruction. >> >> $ llvm-objdump -S main.o >> main.o: file format ELF32-riscv >> >> >> Disassembly of section .text: >> >> 00000000 .text: >> /usr/local/google/home/pkapsenb/work/llvm-project/build/bin/llvm-objdump: warning: 'main.o': failed to parse debug information for main.o >> 0: 01 00 nop >> >> 00000002 main: >> ; int main() { >> 2: 41 11 addi sp, sp, -16 >> 4: 06 c6 sw ra, 12(sp) >> 6: 22 c4 sw s0, 8(sp) >> 8: 00 08 addi s0, sp, 16 >> a: 09 45 addi a0, zero, 2 >> ; uint8_t a = 2; >> c: a3 0b a4 fe sb a0, -9(s0) >> 10: 15 45 addi a0, zero, 5 >> ; uint8_t b = 5; >> 12: 23 0b a4 fe sb a0, -10(s0) >> ; uint8_t c = a * b; >> 16: 03 05 74 ff lb a0, -9(s0) >> 1a: 83 05 64 ff lb a1, -10(s0) >> 1e: 33 05 b5 02 <unknown> >> 22: a3 0a a4 fe sb a0, -11(s0) >> 26: 01 45 mv a0, zero >> ; } >> 28: 22 44 lw s0, 8(sp) >> 2a: b2 40 lw ra, 12(sp) >> 2c: 41 01 addi sp, sp, 16 >> 2e: 82 80 ret >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > -- > Sam Elliott > Software Developer - LLVM > lowRISC CIC > -- > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >