[llvm-dev] RISC-V disassembly doesn't seem to know about multiply instructions

460 views
Skip to first unread message

Pieter Kapsenberg via llvm-dev

unread,
Jan 29, 2020, 9:57:18 PM1/29/20
to llvm...@lists.llvm.org
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

Sam Elliott via llvm-dev

unread,
Jan 30, 2020, 5:57:14 AM1/30/20
to Pieter Kapsenberg, llvm...@lists.llvm.org
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

> _______________________________________________
> LLVM Developers mailing list
> llvm...@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...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Simon Cook via llvm-dev

unread,
Jan 30, 2020, 6:46:34 AM1/30/20
to llvm...@lists.llvm.org
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

Pieter Kapsenberg via llvm-dev

unread,
Jan 30, 2020, 12:31:01 PM1/30/20
to Simon Cook, llvm...@lists.llvm.org
Thanks for the explanation.  Why not just always enable all of them during objdump? If the binary wasn't compiled with the M instruction it won't be present in the machine code right?
Reply all
Reply to author
Forward
0 new messages