[PATCH] D82184: [MSP430] Update register names

Anatoly Trosinenko via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 19 06:59:38 PDT 2020


atrosinenko created this revision.
atrosinenko added reviewers: echristo, rjmccall, krisb, mskvortsov, pftbest.
Herald added a subscriber: hiraditya.
Herald added projects: clang, LLVM.

When writing a unit test on replacing standard epilogue sequences with `BR __mspabi_func_epilog_<N>`, by manually asm-clobbering `rN` - `r10` for N = 4..10, everything worked well except for seeming inability to clobber r4.

The problem was that MSP430 code generator of LLVM used an obsolete name FP for that register. Things were worse because when `llc` read an unknown register name, it silently ignored it.

Example: take the following source:

name=test-regs.c
  void f(void)
  {
    asm volatile ("" : : : "r0");
    asm volatile ("" : : : "r1");
    asm volatile ("" : : : "r2");
    asm volatile ("" : : : "r3");
    asm volatile ("" : : : "r4");
    asm volatile ("" : : : "r5");
  }
  
  void g(void)
  {
    asm volatile ("" : : : "pc");
    asm volatile ("" : : : "sp");
    asm volatile ("" : : : "sr");
    asm volatile ("" : : : "cg");
    asm volatile ("" : : : "fp");
    asm volatile ("" : : : "r5");
  }

and execute:

  $ $sysroot/bin/msp430-elf-gcc --version
  msp430-elf-gcc (Mitto Systems Limited - msp430-gcc 8.3.1.25) 8.3.1
  Copyright (C) 2018 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  
  $ $sysroot/bin/msp430-elf-gcc -c test-regs.c
  test-regs.c: In function 'g':
  test-regs.c:14:3: error: unknown register name 'pc' in 'asm'
     asm volatile ("" : : : "pc");
     ^~~
  test-regs.c:15:3: error: unknown register name 'sp' in 'asm'
     asm volatile ("" : : : "sp");
     ^~~
  test-regs.c:16:3: error: unknown register name 'sr' in 'asm'
     asm volatile ("" : : : "sr");
     ^~~
  test-regs.c:17:3: error: unknown register name 'cg' in 'asm'
     asm volatile ("" : : : "cg");
     ^~~
  test-regs.c:18:3: error: unknown register name 'fp' in 'asm'
     asm volatile ("" : : : "fp");
     ^~~
  $ clang --version
  clang version 10.0.0-4ubuntu1 
  Target: x86_64-pc-linux-gnu
  Thread model: posix
  InstalledDir: /usr/bin
  $ clang -target msp430 -c test-regs.c 
  test-regs.c:14:26: error: unknown register name 'pc' in asm
    asm volatile ("" : : : "pc");
                           ^
  test-regs.c:15:26: error: unknown register name 'sp' in asm
    asm volatile ("" : : : "sp");
                           ^
  test-regs.c:16:26: error: unknown register name 'sr' in asm
    asm volatile ("" : : : "sr");
                           ^
  test-regs.c:17:26: error: unknown register name 'cg' in asm
    asm volatile ("" : : : "cg");
                           ^
  test-regs.c:18:26: error: unknown register name 'fp' in asm
    asm volatile ("" : : : "fp");
                           ^
  5 errors generated.

No differences at all. Now, let's drop `g()` function, to make it valid source.

  $ clang -target msp430 test-regs.c -S -emit-llvm -o-
  ...
  ; Function Attrs: noinline nounwind optnone
  define dso_local void @f() #0 {
    call void asm sideeffect "", "~{r0}"() #1, !srcloc !2
    call void asm sideeffect "", "~{r1}"() #1, !srcloc !3
    call void asm sideeffect "", "~{r2}"() #1, !srcloc !4
    call void asm sideeffect "", "~{r3}"() #1, !srcloc !5
    call void asm sideeffect "", "~{r4}"() #1, !srcloc !6
    call void asm sideeffect "", "~{r5}"() #1, !srcloc !7
    ret void
  }
  ...

Everything looks good, again.

  $ clang -target msp430 test-regs.c -S -mllvm -stop-after=finalize-isel -o-
  ...
  body:             |
    bb.0 (%ir-block.0):
      INLINEASM &"", 1, !2
      INLINEASM &"", 1, !3
      INLINEASM &"", 1, !4
      INLINEASM &"", 1, !5
      INLINEASM &"", 1, !6
      INLINEASM &"", 1, 12, implicit-def early-clobber $r5, !7
      RET

That is, I cannot use `fp` register name from the C code because Clang does not accept it (exactly like GCC). But the accepted name `r4` is not recognised by `llc` (it can be used in listings passed to `llvm-mc` and even `fp` is replace to `r4` by `llvm-mc`). So I can specify any of `fp` or `r4` for the string literal of `asm(...)` but nothing in the clobber list.

This patch replaces `MSP430::FP` with `MSP430::R4` in the backend code (even [MSP430 EABI](doesn't mention FP as a register name)). The R0 - R3 <https://reviews.llvm.org/source/clang/> registers, on the other hand, are left as is in the backend code (after all, they have some special meaning on the ISA level). It is just ensured clang is renaming them as expected by the downstream tools. There is probably not much sense in **marking them clobbered** but rename them //just in case// for use at potentially different contexts.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82184

Files:
  clang/lib/Basic/Targets/MSP430.h
  clang/test/CodeGen/msp430-register-names.c
  llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
  llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
  llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
  llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
  llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
  llvm/lib/Target/MSP430/MSP430RegisterInfo.td
  llvm/test/CodeGen/MSP430/asm-clobbers.ll
  llvm/test/CodeGen/MSP430/inline-asm-register-names.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82184.272055.patch
Type: text/x-patch
Size: 15032 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200619/f4237f94/attachment-0001.bin>


More information about the cfe-commits mailing list