enable the MSP430 LLVM backend #37672

Merged
merged 8 commits into from Nov 15, 2016

Projects

None yet

7 participants

@japaric
Member
japaric commented Nov 9, 2016 edited

to let people experiment with this target out of tree.

The MSP430 architecture is used in 16-bit microcontrollers commonly used
in Digital Signal Processing applications.


How this was tested:

Declaring a custom target with the following specification:

{
  "arch": "msp430",
  "data-layout": "e-m:e-p:16:16-i32:16:32-a:16-n8:16",
  "executables": true,
  "linker": "msp430-elf-gcc",
  "llvm-target": "msp430",
  "max-atomic-width": 0,
  "no-integrated-as": true,
  "os": "none",
  "panic-strategy": "abort",
  "relocation-model": "static",
  "target-endian": "little",
  "target-pointer-width": "16"
}

And this minimal file:

#![feature(lang_items)]
#![feature(no_core)]
#![no_core]
#![no_main]

#[export_name = "start"]
pub fn start() -> ! {
    loop {}
}

#[lang = "copy"]
trait Copy {}

#[lang = "sized"]
trait Sized {}

Produces the following object files:

$ rustc --target=msp430 --emit=obj foo.rs

$ msp430-objdump -Cd foo.o

foo.o:     file format elf32-msp430


Disassembly of section .text.start:

00000000 <start>:
   0:   21 83           decd    r1
   2:   00 3c           jmp     $+2             ;abs 0x4
   4:   00 3c           jmp     $+2             ;abs 0x6
   6:   ff 3f           jmp     $+0             ;abs 0x6

$ rustc --target=msp430 --emit=obj foo.rs -O

$ msp430-objdump -Cd foo.o

foo.o:     file format elf32-msp430


Disassembly of section .text.start:

00000000 <start>:
   0:   ff 3f           jmp     $+0             ;abs 0x0

r? @alexcrichton
TODO get this working with Makefiles so nightly releases include this backend
TODO measure the increase in binary size +187KiB (+0.47%)
FIXME --emit=obj produces empty object files

@rust-highfive
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

src/librustc_llvm/build.rs
@@ -134,8 +134,9 @@ fn main() {
version_cmd.arg("--version");
let version_output = output(&mut version_cmd);
let mut parts = version_output.split('.');
- if let (Some(major), Some(minor)) = (parts.next().and_then(|s| s.parse::<u32>().ok()),
- parts.next().and_then(|s| s.parse::<u32>().ok())) {
+ if let (Some(major), Some(minor)) =
@japaric
japaric Nov 9, 2016 Member

Sorry for the churn. My editor automatically rustfmts files on save ๐Ÿ˜„.

@brson brson added the relnotes label Nov 9, 2016
@brson
Contributor
brson commented Nov 9, 2016

@bors r+

@bors
Contributor
bors commented Nov 9, 2016

๐Ÿ“Œ Commit 1a0ee74 has been approved by brson

@brson
Contributor
brson commented Nov 9, 2016

@bors r+

@bors
Contributor
bors commented Nov 9, 2016

๐Ÿ“Œ Commit 46b3951 has been approved by brson

@japaric
Member
japaric commented Nov 9, 2016

@bors r-

Hold your horses @brson. I just found a bug. LLVM is happily eating the IR rustc passes to it but it's sending back empty object files. I wonder if I need to add some annotation to the functions in the llvm-ir.

@japaric
Member
japaric commented Nov 9, 2016

Update

  • I can cross compile libcore to a custom msp430 target. (Cheating a little. I haven't implemented the cabi stuff yet so I just "removed" some extern "C" stuff from libcore to make this happen)
  • LLVM can actually emit MSP430 assembly so I'm not sure why I'm getting empty object files. Perhaps the problem is somewhere further in the pipeline.
@japaric
Member
japaric commented Nov 9, 2016

TODO measure the increase in binary size

stage1 rustc_llvm went from 40766544 bytes to 40958376. An increase of 187KiB (+0.47%)

@pftbest
Contributor
pftbest commented Nov 9, 2016 edited

@japaric
LLVM does not support object files for MSP430 target (yet). Bitcode and Asm only.
Also you would like to have my patch that was accepted in LLVM trunk yesterday. It fixes issue with wrong branch instructions which sometimes get generated for large functions.

@japaric
Member
japaric commented Nov 9, 2016

TODO get this working with Makefiles so nightly releases include this backend

Done.

@pftbest

Hmm, then how come clang 3.8 can produce object files? It's the object emission logic in clang instead of in llvm?

Bitcode and Asm only.

Can we funnel the bitcode throught some tool (clang?) to get object files?

@japaric
Member
japaric commented Nov 9, 2016

Also you would like to have my patch that was accepted in LLVM trunk yesterday.

If it applies cleanly on 3.9.1, you can send it to rust-lang/llvm then we can update the submodule.

@pftbest
Contributor
pftbest commented Nov 9, 2016

@japaric

how come clang 3.8 can produce object files?

Are you sure that it was object file and not bitcode? For example if you try to do this:

clang --target=msp430 -c main.c

It will produce main.o but in fact it will have bitcode inside, not the actual object.
And if you try to create an object file using llc you will get:

llc -filetype=obj main.o
llc: target does not support generation of this file type!

If it applies cleanly on 3.9.1,

Well, I can apply it to 3.9 but it will need some work, because some APIs have changed since then.

@pftbest
Contributor
pftbest commented Nov 9, 2016

Has anyone tried to update rust to llvm 4?

@japaric
Member
japaric commented Nov 9, 2016

@pftbest

Ubuntu's clang can produce executables though:

$ clang -v
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)

$ cat foo.c
int main() {
  while (1) {}
}

$ clang --target=msp430 foo.c

$ msp430-readelf -h a.out
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 ff 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            Standalone App
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Texas Instruments msp430 microcontroller
  Version:                           0x1
  Entry point address:               0xf800
  Start of program headers:          52 (bytes into file)
  Start of section headers:          2576 (bytes into file)
  Flags:                             0x10000000
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         3
  Size of section headers:           40 (bytes)
  Number of section headers:         12
  Section header string table index: 9

$ msp430-objdump -Cd a.out

a.out:     file format elf32-msp430


Disassembly of section .text:

0000f800 <__watchdog_support>:
    f800:       55 42 20 01     mov.b   &0x0120,r5
    f804:       35 d0 08 5a     bis     #23048, r5      ;#0x5a08
    f808:       82 45 00 02     mov     r5,     &0x0200

0000f80c <__init_stack>:
    f80c:       31 40 00 03     mov     #768,   r1      ;#0x0300

0000f810 <__do_copy_data>:
    f810:       3f 40 00 00     mov     #0,     r15     ;#0x0000
    f814:       0f 93           tst     r15
    f816:       08 24           jz      $+18            ;abs 0xf828
    f818:       92 42 00 02     mov     &0x0200,&0x0120
    f81c:       20 01
    f81e:       2f 83           decd    r15
    f820:       9f 4f 5a f8     mov     -1958(r15),512(r15);0xf85a(r15), 0x0200(r15)
    f824:       00 02
    f826:       f8 23           jnz     $-14            ;abs 0xf818

0000f828 <__do_clear_bss>:
    f828:       3f 40 00 00     mov     #0,     r15     ;#0x0000
    f82c:       0f 93           tst     r15
    f82e:       07 24           jz      $+16            ;abs 0xf83e
    f830:       92 42 00 02     mov     &0x0200,&0x0120
    f834:       20 01
    f836:       1f 83           dec     r15
    f838:       cf 43 00 02     mov.b   #0,     512(r15);r3 As==00, 0x0200(r15)
    f83c:       f9 23           jnz     $-12            ;abs 0xf830

0000f83e <__stop_progExec__>:
    f83e:       32 d0 f0 00     bis     #240,   r2      ;#0x00f0
    f842:       fd 3f           jmp     $-4             ;abs 0xf83e

0000f844 <__ctors_end>:
    f844:       30 40 58 f8     br      #0xf858

0000f848 <main>:
    f848:       04 12           push    r4
    f84a:       04 41           mov     r1,     r4
    f84c:       21 83           decd    r1
    f84e:       84 43 fe ff     mov     #0,     -2(r4)  ;r3 As==00, 0xfffe(r4)
    f852:       00 3c           jmp     $+2             ;abs 0xf854
    f854:       ff 3f           jmp     $+0             ;abs 0xf854
        ...

0000f858 <_unexpected_>:
    f858:       00 13           reti

Disassembly of section .vectors:

0000ffe0 <__ivtbl_16>:
    ffe0:       44 f8 44 f8 44 f8 44 f8 44 f8 44 f8 44 f8 44 f8     D.D.D.D.D.D.D.D.
    fff0:       44 f8 44 f8 44 f8 44 f8 44 f8 44 f8 44 f8 00 f8     D.D.D.D.D.D.D...

And executables are object files.

@japaric
Member
japaric commented Nov 9, 2016 edited

-c works too:

$ clang --target=msp430 -c foo.c -o foo.o

$ file foo.o
foo.o: ELF 32-bit LSB executable, TI msp430, version 1, statically linked, stripped

$ msp430-objdump -Cd foo.o

foo.o:     file format elf32-msp430


Disassembly of section .text:

0000f800 <.text>:
    f800:       55 42 20 01     mov.b   &0x0120,r5
    f804:       35 d0 08 5a     bis     #23048, r5      ;#0x5a08
    f808:       82 45 00 02     mov     r5,     &0x0200
    f80c:       31 40 00 03     mov     #768,   r1      ;#0x0300
    f810:       3f 40 00 00     mov     #0,     r15     ;#0x0000
    f814:       0f 93           tst     r15
    f816:       08 24           jz      $+18            ;abs 0xf828
    f818:       92 42 00 02     mov     &0x0200,&0x0120
    f81c:       20 01
    f81e:       2f 83           decd    r15
    f820:       9f 4f 5a f8     mov     -1958(r15),512(r15);0xf85a(r15), 0x0200(r15)
    f824:       00 02
    f826:       f8 23           jnz     $-14            ;abs 0xf818
    f828:       3f 40 00 00     mov     #0,     r15     ;#0x0000
    f82c:       0f 93           tst     r15
    f82e:       07 24           jz      $+16            ;abs 0xf83e
    f830:       92 42 00 02     mov     &0x0200,&0x0120
    f834:       20 01
    f836:       1f 83           dec     r15
    f838:       cf 43 00 02     mov.b   #0,     512(r15);r3 As==00, 0x0200(r15)
    f83c:       f9 23           jnz     $-12            ;abs 0xf830
    f83e:       32 d0 f0 00     bis     #240,   r2      ;#0x00f0
    f842:       fd 3f           jmp     $-4             ;abs 0xf83e
    f844:       30 40 58 f8     br      #0xf858
    f848:       04 12           push    r4
    f84a:       04 41           mov     r1,     r4
    f84c:       21 83           decd    r1
    f84e:       84 43 fe ff     mov     #0,     -2(r4)  ;r3 As==00, 0xfffe(r4)
    f852:       00 3c           jmp     $+2             ;abs 0xf854
    f854:       ff 3f           jmp     $+0             ;abs 0xf854
    f856:       00 00           .word   0x0000; ????
    f858:       00 13           reti

Disassembly of section .vectors:

0000ffe0 <.vectors>:
    ffe0:       44 f8           and.b   r8,     r4
    ffe2:       44 f8           and.b   r8,     r4
    ffe4:       44 f8           and.b   r8,     r4
    ffe6:       44 f8           and.b   r8,     r4
    ffe8:       44 f8           and.b   r8,     r4
    ffea:       44 f8           and.b   r8,     r4
    ffec:       44 f8           and.b   r8,     r4
    ffee:       44 f8           and.b   r8,     r4
    fff0:       44 f8           and.b   r8,     r4
    fff2:       44 f8           and.b   r8,     r4
    fff4:       44 f8           and.b   r8,     r4
    fff6:       44 f8           and.b   r8,     r4
    fff8:       44 f8           and.b   r8,     r4
    fffa:       44 f8           and.b   r8,     r4
    fffc:       44 f8           and.b   r8,     r4
    fffe:       00 f8           and     r8,     r0

EDIT: typo -s -> -c

@japaric
Member
japaric commented Nov 9, 2016

@pftbest

Has anyone tried to update rust to llvm 4?

See #37609

@japaric
Member
japaric commented Nov 9, 2016

Well, I can apply it to 3.9 but it will need some work, because some APIs have changed since then.

If it's not trivial to do, you can just wait for an llvm-up

@japaric
Member
japaric commented Nov 9, 2016

I know what's going on now. clang is making LLVM produce assembly and then it's calling msp430-as (GCC assembler) to produce an object file from that assembly:

$ clang --target=msp430 -c foo.c -o foo.o -v
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: msp430
Thread model: posix
InstalledDir: /usr/bin
 "/usr/lib/llvm-3.8/bin/clang" -cc1 -triple msp430 -S -disable-free -disable-llvm-verifier -main-file-name foo.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -no-integrated-as -mconstructor-aliases -v -dwarf-column-info -debugger-tuning=gdb -coverage-file /home/japaric/foo.o -resource-dir /usr/lib/llvm-3.8/bin/../lib/clang/3.8.0 -fno-dwarf-directory-asm -fdebug-compilation-dir /home/japaric -ferror-limit 19 -fmessage-length 174 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/foo-35f3f8.s -x c foo.c
clang -cc1 version 3.8.0 based upon LLVM 3.8.0 default target x86_64-pc-linux-gnu
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/llvm-3.8/bin/../lib/clang/3.8.0/include
 /usr/include
End of search list.
 "/usr/bin/msp430-as" -o foo.o /tmp/foo-35f3f8.s <--

I think there is some machinery inside rustc to handle this type of scenario. Let's see if I can get rustc to generate object files using this approach.

@pftbest
Contributor
pftbest commented Nov 9, 2016

Well, this explains why it never worked for me. I don't have a msp430-as I have msp430-elf-as instead.

@pftbest
Contributor
pftbest commented Nov 9, 2016

If it's not trivial to do, you can just wait for an llvm-up

I don't have a MSP430 board anymore, so I don't need this fix. But if you are going to test the code on a real hardware be warned that this bug can cause some random crashes.

@japaric
Member
japaric commented Nov 9, 2016

But if you are going to test the code on a real hardware be warned that this bug can cause some random crashes.

I can't because I don't have hardware either. But noted.

@japaric
Member
japaric commented Nov 10, 2016

OK. rustc can now emit object files and produce executables using the following pipeline:

rustc -(.ll)-> LLVM -(.s)-> msp430-as -(.o)-> msp430-gcc --> executable

The logic to do this was shoehorned and it's missing important stuff like proper error reporting but, hey, it sort of works.

I've added some notes to the PR description that explain how I tested this (the target specification used, the Rust source file used and how the object files that rustc generated look like)

And executables don't look quite right though ...

AFAICT, msp430-gcc is dropping all the Rust functions so they don't make it to the final executable. This is caused by the --gc-sections flag we use with the linker and me not understanding the linker script / startup objects involved as in I don't know what symbol name to use in the Rust side to properly glue it to the C startup stuff.

What's pending to do:

  • Test that .rlib are working properly. i.e. test this as a Cargo project that has at least one dependency.
  • Do the cabi stuff so extern "C" actually works.
  • Figure out how to produce a correct, flashable executable
  • Try that executable in a real microcontroller and see if it "works" (i.e. it doesn't brick the device and it at least makes the device boot properly)

I'm going to punt the last two points to someone that actually has the hardware and that has proper knowledge about these microcontrollers.

@japaric
Member
japaric commented Nov 10, 2016

Do the cabi stuff so extern "C" actually works.

BTW, this is required to be able to compile core for this target.

@bors
Contributor
bors commented Nov 10, 2016

โ˜”๏ธ The latest upstream changes (presumably #37678) made this pull request unmergeable. Please resolve the merge conflicts.

@alexcrichton

Nice! Onwards to porting to everything!

src/librustc_back/target/mod.rs
@@ -358,6 +358,10 @@ pub struct TargetOptions {
// will 'just work'.
pub obj_is_bitcode: bool,
+ // LLVM can't produce object files for MSP430. Instead, we'll make LLVM emit
+ // assembly and then use `msp430-as` to turn that assembly into an object file
+ pub obj_needs_as: bool,
@alexcrichton
alexcrichton Nov 10, 2016 Member

It looks like we still have the vestigal option -C no_integrated_as, perhaps that could be hooked up to the target specs as well? I believe manually running the assembler is implemented in write::run_assembler

src/librustc_trans/back/write.rs
@@ -557,10 +565,13 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
// machine code, instead copy the .o file from the .bc
let write_bc = config.emit_bc || config.obj_is_bitcode;
let rm_bc = !config.emit_bc && config.obj_is_bitcode;
+ let write_asm = config.emit_asm || config.obj_needs_as;
@alexcrichton
alexcrichton Nov 10, 2016 Member

I think if we call write::run_assembler or hook into no_integrated_as these changes may not be necessary.

That being said, I'm not sure whether the code path with no_integrated_as still works, I can't imagine anyone's used that in forever...

src/librustc_trans/back/write.rs
+ // TODO don't hardcode, maybe expose as a `as` field in the target
+ // specification
+ // TODO how to properly access `sess` here?
+ let mut cmd = Command::new("msp430-as");
@alexcrichton
alexcrichton Nov 10, 2016 Member

Could this get pushed into custom target specs?

@alexcrichton
alexcrichton Nov 10, 2016 Member

(note that this block of additions I think can be subsumed by write::run_assembler)

@japaric japaric referenced this pull request in rust-embedded/rfcs Nov 11, 2016
Open

MSP430 support #20

3 of 9 tasks complete
@jck
jck commented Nov 12, 2016

I'm not too familiar with how rust targets work, but I am familiar with MSP430s. A few comments:

  • msp430-gcc is deprecated. The msp430 is now a part of upstream gcc, so msp430-elf-gcc would be the correct toolchain to use.
  • There are a lot of MSP430 families. The -mmcu= option needs to be specified to build for any particular family. I'm not sure how this would be integrated into rust.
@japaric
Member
japaric commented Nov 12, 2016

msp430-gcc is deprecated. The msp430 is now a part of upstream gcc, so msp430-elf-gcc would be the correct toolchain to use.

Interesting. Ubuntu seems to only ship with gcc-msp430 version 4.6.3. Whereas Arch Linux provides (via the AUR) a msp430-elf-gcc package with version 6.2.0. This is not a problem for this PR as we are not adding a built-in target yet. But by the time we do add a built-in target we can leave the linker field empty so it's up to the user to pick the right toolchain.

The -mmcu= option needs to be specified to build for any particular family.

Do you know if this affects codegen at all? llc says CPU selection doesn't affect codegen, apparently:

$ ./build/x86_64-unknown-linux-gnu/llvm/bin/llc -mcpu=help -march=msp430
Available CPUs for this target:

  generic - Select the generic processor.

Available features for this target:

  ext - Enable MSP430-X extensions.

Use +feature to enable a feature, or -feature to disable it.
For example, llc -mcpu=mycpu -mattr=+feature1,-feature2
Available CPUs for this target:

  generic - Select the generic processor.

Available features for this target:

  ext - Enable MSP430-X extensions.

I'm wondering if that's just used to pick the right linker scripts (memory.x and periph.x)? The msp430-gcc package installs a bunch of linker scripts in /usr/msp430/lib/ldscripts.

Do you get an error if you omit the -mmcu= flag? If yes, what kind of error do you get?

@pftbest
Contributor
pftbest commented Nov 12, 2016

@japaric

Do you know if this affects codegen at all?

It does not, AFAIK, except for maybe this MSP430X extension.

Do you get an error if you omit the -mmcu= flag?

No, you don't get any error, but you need to manually specify the linker script.

if that's just used to pick the right linker scripts

Yes, and I think it also checks the assembly for some hardware errata, but I'm not sure if it's still relevant.

@pftbest
Contributor
pftbest commented Nov 12, 2016

I've looked into the gcc source code:
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/msp430/msp430.c#L99
And I see that this table only specifies 2 things:

  1. Do we have MSP430X instruction set (MSP430Xv2 and MSP430X are binary identical, the only difference is a cycle time during execution [link])
  2. What hardware multiplier do we have. This is used to generate right calls to runtime library
  /* If we have been given a specific MCU name then we may be
     able to make use of its hardware multiply capabilities.  */
  if (msp430_hwmult_type != NONE)
    {
      if (strcmp ("__mspabi_mpyi", name) == 0)
    {
      if (msp430_use_f5_series_hwmult ())
        name = "__mulhi2_f5";
      else if (! msp430_no_hwmult ())
        name = "__mulhi2";
    }
      else if (strcmp ("__mspabi_mpyl", name) == 0)
    {
      if (msp430_use_f5_series_hwmult ())
        name = "__mulsi2_f5";
      else if (use_32bit_hwmult ())
        name = "__mulsi2_hw32";
      else if (! msp430_no_hwmult ())
        name = "__mulsi2";
    }
    }

I think llvm always generates __mulqi3hw call, but I don't know if gcc or compiler-rt has implementation for it, the only thing I found is some code from llvm-dev mailing list:
http://lists.llvm.org/pipermail/llvm-dev/2012-October/054236.html
So I bet you'll have to manually code this function in assembly.

@japaric
Member
japaric commented Nov 12, 2016

@alexcrichton Updated the code to use write::run_assembler. The diff is smaller now but I had to add a hack to get compiling executables to work. The thing is that write::run_assembler produces a foo.o artifact but when building an executable, the linker expects the object file to be named foo.0.o (*). So my hack is to rename the file.

(*) Why the .0 though? Is this related to codegen units where each codegen worker generates a different object file: foo.0.o, foo.1.o, etc. and then the linker merges them?

+ // LLVM can't produce object files for this target. Instead, we'll make LLVM
+ // emit assembly and then use `gcc` to turn that assembly into an object
+ // file
+ pub no_integrated_as: bool,
@japaric
japaric Nov 12, 2016 Member

This ... could have a more descriptive name I supposed. I just use the same name as the -C no-integrated-as flag.

@japaric
Member
japaric commented Nov 12, 2016

The cabi stuff is still missing but this is useable already. I'd be nice to have this in a nightly before novemb.rs ๐Ÿ˜„.

@pftbest
Contributor
pftbest commented Nov 13, 2016

@japaric
Can you please update xargo, so it will allow custom compilers (not just nightly)? Then I will be able to test this PR on msp430g2553 and cc430f5137 boards.

@japaric
Member
japaric commented Nov 13, 2016

Added the cabi stuff but I'd like someone familiar with the LLVM API to review it (@eddyb? ๐Ÿ™‡). I added a link to the MSP430 ABI documentation.

With this I can turn the core crate into assembly. But msp430-gcc (v4.6.3) fails to turn that into an object file:

$ rustc --target msp430 /shared/rust/checkouts/msp430/src/libcore/lib.rs --emit=obj
error: linking with `msp430-gcc` failed: exit code: 1
  |
  = note: "msp430-gcc" "-c" "-o" "core.o" "core.s"
  = note: core.s: Assembler messages:
core.s:86017: Error: odd operand: 7
core.s:88969: Error: odd operand: 5

Using msp430-elf-gcc (v6.2.0) as the linker/assembler does works though.

@pftbest Until this hits nightly you can explicitly depend on the standard crates to make Cargo build them:

# Cargo.toml
[dependencies]
core = { path = "/path/to/rust/repo/src/libcore }
@pftbest
Contributor
pftbest commented Nov 13, 2016

When I do

rustc --target=msp430g2553 ../rust/src/libcore/lib.rs --emit=asm

or --emit=llvm-ir, it always gives me object file in return. And this object file has it's Tag_ISA set to MSP430X, event though I have added -ext to my msp430g2553.json

{
  "arch": "msp430",
  "data-layout": "e-m:e-p:16:16-i32:16:32-a:16-n8:16",
  "features": "-ext",
  "executables": true,
  "linker": "msp430-elf-gcc",
  "llvm-target": "msp430",
  "max-atomic-width": 0,
  "no-integrated-as": true,
  "os": "none",
  "relocation-model": "static",
  "target-endian": "little",
  "target-pointer-width": "16"
}
@japaric
Member
japaric commented Nov 13, 2016

it always gives me object file in return.

Huh? Are you sure you are not looking at an old, previously generated object file? I don't see such thing.

And this object file has it's Tag_ISA set to MSP430X, event though I have added -ext to my msp430g2553.json

This is msp430-elf-gcc "fault"; it's probably defaulting to generating MSP430X objects. msp430-gcc produces MSP430 objects (withouth the X).

You could use a "shim" linker to disable the "extension" stuff on the gcc side:

$ cat my-msp430-elf-gcc
#!/bin/bash

msp430-elf-gcc --some-flag-to-disable-ext-stuff "${@}"

and change the linker field in msp430.json to my-msp430-elf-gcc (and update your PATH, etc.).

@japaric
Member
japaric commented Nov 13, 2016

(Also you should add "panic-strategy": "abort" to your .json file).

@pftbest
Contributor
pftbest commented Nov 13, 2016

So, I've added "panic-strategy": "abort" to json file but nothing changed:

vadzim ~/Downloads/rustmsp $ 
vadzim ~/Downloads/rustmsp $ ls -l
total 64
-rw-r--r--  1 vadzim  staff    371 Nov 13 20:51 msp430g2553.json
-rw-r--r--  1 vadzim  staff  12506 Dec 17  2015 msp430g2553.ld
-rw-r--r--  1 vadzim  staff   9070 Dec 17  2015 msp430g2553_symbols.ld
vadzim ~/Downloads/rustmsp $ rustc --target=msp430g2553 ../rust/src/libcore/lib.rs --emit=llvm-ir
vadzim ~/Downloads/rustmsp $ ls -l
total 3200
-rw-r--r--  1 vadzim  staff        0 Nov 13 20:51 core.metadata.o
-rw-r--r--  1 vadzim  staff  1604652 Nov 13 20:51 core.o
-rw-r--r--  1 vadzim  staff      371 Nov 13 20:51 msp430g2553.json
-rw-r--r--  1 vadzim  staff    12506 Dec 17  2015 msp430g2553.ld
-rw-r--r--  1 vadzim  staff     9070 Dec 17  2015 msp430g2553_symbols.ld
vadzim ~/Downloads/rustmsp $ file core.o
core.o: ELF 32-bit LSB relocatable, version 1, not stripped
vadzim ~/Downloads/rustmsp $ rustc --version --verbose
rustc 1.15.0-dev (e7cae415e 2016-11-13)
binary: rustc
commit-hash: e7cae415ea207732a199dbdd23fb2baee1946d63
commit-date: 2016-11-13
host: x86_64-apple-darwin
release: 1.15.0-dev
LLVM version: 3.9
vadzim ~/Downloads/rustmsp $

I will try to use "shim" linker later.

@japaric japaric don't build an object file for emit=asm,llvm-ir
80ca1e1
@japaric
Member
japaric commented Nov 14, 2016

When I do ... or --emit=llvm-ir, it always gives me object file in return

Fixed this, btw.

@pftbest
Contributor
pftbest commented Nov 14, 2016

@japaric

Fixed this, btw.

Thank you, I saw the commit, but I don't have time to test it.

@alexcrichton
Member

@bors: r+

Looks good to me, thanks @japaric!

@bors
Contributor
bors commented Nov 15, 2016

๐Ÿ“Œ Commit 80ca1e1 has been approved by alexcrichton

@bors
Contributor
bors commented Nov 15, 2016

โŒ›๏ธ Testing commit 80ca1e1 with merge c8867f8...

@bors bors added a commit that referenced this pull request Nov 15, 2016
@bors bors Auto merge of #37672 - japaric:msp430, r=alexcrichton
enable the MSP430 LLVM backend

to let people experiment with this target out of tree.

The MSP430 architecture is used in 16-bit microcontrollers commonly used
in Digital Signal Processing applications.

---

How this was tested:

Declaring a custom target with the following specification:

``` json
{
  "arch": "msp430",
  "data-layout": "e-m:e-p:16:16-i32:16:32-a:16-n8:16",
  "executables": true,
  "linker": "msp430-gcc",
  "llvm-target": "msp430",
  "max-atomic-width": 0,
  "no-integrated-as": true,
  "os": "none",
  "panic-strategy": "abort",
  "relocation-model": "static",
  "target-endian": "little",
  "target-pointer-width": "16"
}
```

And this minimal file:

``` rust

pub fn start() -> ! {
    loop {}
}

trait Copy {}

trait Sized {}
```

Produces the following object files:

```
$ rustc --target=msp430 --emit=obj foo.rs

$ msp430-objdump -Cd foo.o

foo.o:     file format elf32-msp430

Disassembly of section .text.start:

00000000 <start>:
   0:   21 83           decd    r1
   2:   00 3c           jmp     $+2             ;abs 0x4
   4:   00 3c           jmp     $+2             ;abs 0x6
   6:   ff 3f           jmp     $+0             ;abs 0x6

$ rustc --target=msp430 --emit=obj foo.rs -O

$ msp430-objdump -Cd foo.o

foo.o:     file format elf32-msp430

Disassembly of section .text.start:

00000000 <start>:
   0:   ff 3f           jmp     $+0             ;abs 0x0
```

---

r? @alexcrichton
~~TODO get this working with Makefiles so nightly releases include this backend~~
~~TODO measure the increase in binary size~~ +187KiB (+0.47%)
~~FIXME --emit=obj produces empty object files~~
c8867f8
@bors bors merged commit 80ca1e1 into rust-lang:master Nov 15, 2016

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@japaric japaric deleted the japaric:msp430 branch Dec 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment