Skip to content

armhf code generation is broken #10482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ibukanov opened this issue Nov 14, 2013 · 34 comments
Closed

armhf code generation is broken #10482

ibukanov opened this issue Nov 14, 2013 · 34 comments
Labels
O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state P-medium Medium priority

Comments

@ibukanov
Copy link
Contributor

I am using armhf build from http://luqman.ca/rust-builds/rust-0.9-pre-3b0d486-arm-unknown-linux-gnueabihf.zip released 2013-11-12. That generates broken code with the following program:

enum Test {
    A(f64),
    B
}

impl Test {
    fn draw(&self) {
        match *self {
            A(x) => println!("A {}", x),
            B => println!("B")
        }
    }
}

fn main() {
    let s = A(0.1);
    s.draw();
}

When running on armhf (Samsung ARM Chromebook) the program just goes into infinite loop instead of printing A 0.1.

@ibukanov
Copy link
Contributor Author

http://pastebin.mozilla.org/3601836 is the asm output of compiling the above file with rustc -S source.rs

@ibukanov
Copy link
Contributor Author

Apparently it is the call to println with a floating point to blame. The following test case is enough to show the problem:

fn main() {
   println!("a={}", 1);
   println!("b={}", 1.1);
}

It inters oo loop after printing a=1

@alexcrichton
Copy link
Member

Are you able to get a stack trace when the program is infinite looping? Printing is actually a very large amount of machinery, so it may be helpful to reduce this down even further.

@ibukanov
Copy link
Contributor Author

Given the program:

fn main() {
   format!("{}", 1.1);
}

The stack trace of the looping thread looks like oo recursion:

#0  0x76aba534 in __divdf3 ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#1  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#2  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#3  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#4  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#5  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#6  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#7  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#8  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#9  0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#10 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#11 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#12 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#13 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#14 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#15 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#16 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#17 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#18 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so
#19 0x769c7aec in num::strconv::float_to_str_common::h6babd82e453a2ffeaw::v0.9$x2dpre ()
   from /home/user/a/dev/rust/../../../opt/rust/lib/rustc/arm-unknown-linux-gnueabihf/lib/libstd-6425b930ca146ae9-0.9-pre.so

@ibukanov
Copy link
Contributor Author

A variation of the example without format:

fn main() {
   (1.1_f64).to_str();
}

also leads to oo recursion:

bt
#0  0x00013e2c in __divdf3 ()
#1  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#2  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#3  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#4  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#5  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#6  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#7  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#8  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#9  0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#10 0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()
#11 0x00010d08 in f64::Div$f64::div::h22c34fa84d77518naU::v0.0 ()

It is

@ibukanov
Copy link
Contributor Author

More direct test case:

use std::num::strconv;

fn main() {
   strconv::float_to_str_common(
        1.1_f64, 10u, true, strconv::SignNeg, strconv::DigAll);
}

So something breaks code in the float_to_str_common implementation.

@chris-morgan
Copy link
Member

I ran into this this very issue this evening (when rust-http tests were inexplicably not completing), and pinpointed the cause of failure more accurately. (I may say that after that, I was a little disappointed to find it had already been filed!)

  1. Only gnueabihf is affected (my tablet used to run an armel OS and gnueabi build and at that time the aforementioned tests ran successfully)
  2. f32 is not affected.
  3. The string formatting fails because the loop for the integral part of the number never reaches the terminating condition where it is zero. This is because
  4. std::num::cmath::c_double_utils::trunc, which provides f64.trunc(), is unsound: 0f64.trunc() != 0f64. A little transmutation (unsafe { std::cast::transmute::<f64, u64>(0f64) }.to_str_radix(2)) consistently shows it is yielding the bits 1111111111111111111111000000000100000000000000000000000000000000 (the last 32 bits are zero) rather than 0, the expected value. (I'm not certain of the f64 layout on this architecture, but sign, exponent and mantissa should certainly all be zero.)

This is as far as I have gone at present.

I suggest that this be escalated to (at the least!) high priority. It also needs more tags added.

Could someone please update this issue's title and main body to reflect the underlying problem?

@emberian
Copy link
Member

Nominating for 1.0.

@chris-morgan
Copy link
Member

@ibukanov: BTW, the stack traces showing recursion is actually bogus; I've experienced it myself on armel also, that it simply doesn't work. The backtraces are broken. But that's a separate issue (#5934, I think).

@itdaniher
Copy link
Contributor

fn i2f(i: u8) -> f64 {(i as f64)/127f64 - 1f64}
println!("{:?}", i2f(125u8));

Hangs indefinitely, as expected.

fn i2f(i: u8) -> f64 {(i as f32)/127f32 - 1f32}
println!("{:?}", i2f(125u8));

Prints -00000000000000000000000000000000000000000000f32.

Any operations upon the result of 'i2f' are printed as NaN.

This is using:

rustc 0.9-pre (d5d5c50 2013-12-20 12:41:33 -0800)
host: arm-unknown-linux-gnueabihf

Any idea if this issue is related? @chris-morgan suggested f32 to not be impacted, but something's definitely wonky here.

@itdaniher
Copy link
Contributor

I got bored and wrote an implementation of ftoa in rust. It works fine on x86, fails miserably on armhf.

use std::num::{pow, log10};

fn main() {
    let mut out = ~"";
    let mut n: f32 = -0.1231;
    if (n < 0.0) { n *= -1.0; out.push_char('-');}
    let mut m: f32 = log10(n).floor();
    if (m < 1.0) { m = 0.0 }
    loop {
        if (n > 0.000001f32) || (m >= 0.0) {
            let w: f32 = pow(10.0, m);
            let d = (n / w).floor();
            n -= d*w;
            out.push_str((d as uint).to_str_radix(10u));
            if (m == 0.0) { out.push_char('.') }
            m -= 1.0;
        }
        else {
            break
        }
    }
    println!("{}", out);
}

Prints -0.123099 on x86, -0. on ARMHF. Some combination of 'pow', 'floor', or 'log10' are seriously mucked up. (edit: to_str_radix isn't culpable)

@itdaniher
Copy link
Contributor

This seems as if it ought to be high priority, with even fairly simple code failing to behave as expected.

@luqmana - have you encountered any related floating point weirdness on ARM? Any insights?

@itdaniher
Copy link
Contributor

It looks like the call to the llvm intrinsics for log10 are at least partially culpable.

use std::num::log10;

fn main() {
        let x = log10(100f32);
        let y = x as u8;
        println!("{}", y);
}

prints 0.

fn main() {
        let x = 100f32;
        let y = x as u8;
        println!("{}", y);
}

prints 100.

@itdaniher
Copy link
Contributor

Minimal test case:

use std::unstable::intrinsics::log10f32;
use std::cast::transmute;

fn main() {
        let x = unsafe { log10f32(100f32)};
        let y = unsafe { transmute::<f32,u32>(x)}.to_str_radix(2);
        println(y);
}

With optimizations on, it prints 1000000000000000000000000000000 aka 2.0, as expected, as an intrinsic function of a constant is optimized to a constant. Without optimizations, it prints 0 (wrong) as expected.

@pnkfelix
Copy link
Member

pnkfelix commented Jan 6, 2014

cc me

@itdaniher
Copy link
Contributor

Not knowing anything about LLVM, I've been embarking on a pretty thorough exploration of the IR for the simple test case above. It looks surprisingly OK - I've been copying possibly suspect pieces into the IR for a working C / clang analogue.

I'm going to keep at the grind here, and will report back as soon as I have more information.

@itdaniher
Copy link
Contributor

One roadblock I've been fighting is going from rust LLVM bitcode to an executable. With a pointer from IRC, I have the following:

clang test.bc -lm -lstd-04ff901e-0.9-pre -lgreen-3b3a1962-0.9-pre -lrustuv-7945354c-0.9-pre -L /usr/local/lib -Wl,-rpath=/usr/local/lib

Unfortunately, this returns

clang version 3.3 (tags/RELEASE_33/final)
Target: armv7l-unknown-linux-gnueabihf
Thread model: posix
 "/usr/local/bin/clang" -cc1 -triple armv7-unknown-linux-gnueabihf -S -disable-free -disable-llvm-verifier -main-file-name test.bc -mrelocation-model static -mdisable-fp-elim -fmath-errno -mconstructor-aliases -fuse-init-array -target-abi aapcs-linux -target-cpu cortex-a8 -mfloat-abi hard -target-linker-version 2.22.90.20120924 -v -resource-dir /usr/local/bin/../lib/clang/3.3 -fno-dwarf-directory-asm -fdebug-compilation-dir /home/picuntu/projects/rust-float/rs -ferror-limit 19 -fmessage-length 194 -mstackrealign -fno-signed-char -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/test-wzfuLc.s -x ir test.bc
clang -cc1 version 3.3 based upon LLVM 3.3 default target armv7l-unknown-linux-gnueabihf
 "/usr/bin/as" -mfloat-abi=hard -o /tmp/test-Exwdqf.o /tmp/test-wzfuLc.s
 "/usr/bin/ld" -z relro -X --hash-style=gnu --build-id --eh-frame-hdr -m armelf_linux_eabi -dynamic-linker /lib/ld-linux-armhf.so.3 -o a.out /usr/lib/gcc/arm-linux-gnueabihf/4.7/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/4.7/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/4.7/crtbegin.o -L/usr/local/lib -L/usr/lib/gcc/arm-linux-gnueabihf/4.7 -L/usr/lib/gcc/arm-linux-gnueabihf/4.7/../../../arm-linux-gnueabihf -L/lib/arm-linux-gnueabihf -L/usr/lib/arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.7/../../.. -L/lib -L/usr/lib /tmp/test-Exwdqf.o -lm -lstd-04ff901e-0.9-pre -lgreen-3b3a1962-0.9-pre -lrustuv-7945354c-0.9-pre -rpath=/usr/local/lib -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/arm-linux-gnueabihf/4.7/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/4.7/../../../arm-linux-gnueabihf/crtn.o
/usr/bin/ld: /tmp/test-Exwdqf.o(.text+0x11dc): unresolvable R_ARM_TLS_LE32 relocation against symbol `_ZN2rt9local_ptr8compiled10RT_TLS_PTR19ha35df66a83b7e2ffaP8v0.9.preE'
/usr/bin/ld: final link failed: Nonrepresentable section on output
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Suggestions welcome!

@itdaniher
Copy link
Contributor

Few more observations.

use std::unstable::intrinsics::log10f64;
use std::cast::transmute;

fn main() {
        let x = unsafe { log10f64(100f64)};
        let z = unsafe { transmute::<f64,u64>(x)}.to_str_radix(2);
        println(z);
}

returns 10001000000000000000000000000000000000 on ARMHF. This decodes as 7e-313, or approximately 0.

On x86, this same code returns 100000000000000000000000000000000000000000000000000000000000000, which decodes as 2.


On ARMHF, in C, printf of a float value is always prefaced by an extension to double. Without this extension, the number is printed as 0.

@itdaniher
Copy link
Contributor

All calls to f64 intrinsics (tested log, log2, log10) seem to return 0x2200000000 / 0b10001000000000000000000000000000000000, regardless of input value (tested 1, 100, 1e16, few others.)

Any idea from where this constant could be originating?

@itdaniher
Copy link
Contributor

This is decimal 146028888064 - I checked OEIS, n_2^(2_n-1) looked possible, but didn't find anything especially compelling.

@pnkfelix
Copy link
Member

pnkfelix commented Jan 9, 2014

Important, but we are not sure that armhf support need block 1.0 (and we are not sure how much of the android ecosystem we need to support for 1.0). Accepted for P-high.

@itdaniher
Copy link
Contributor

Spent eight days beating on this problem only to discover the following (partial) fix.

rustc --target-feature +vfp3 test.rs

Freaking kidding me. LLVM IR looked fine because it was, llc just wasn't getting the right flag.

I'll send a few bitcents to anyone who can explain why f64 intrinsics were returning 0x2200000000.

@itdaniher
Copy link
Contributor

I'll also send money to whoever writes the documentation for exactly what happens when you call rustc foo.rs.

@itdaniher
Copy link
Contributor

Adding --target-feature +vfp3 causes println!("{}", num::log10(100f64)); to print 000000000000 immediately. Still wrong, but not an infinite hang.

@itdaniher
Copy link
Contributor

In a similar vein, println!("{}", num::log10(100f32)); prints 00000000 immediately.

It looks like the println! macro is in need of some TLC, but the bit layout of the results from intrinsics is correct and the version of ftoa above prints the same string on x86-64 and ARMHF, and the same string when the input is f32 or f64.

@itdaniher
Copy link
Contributor

Huzzah!

diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index aa3ab80..36da12a 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -779,7 +779,13 @@ pub fn build_session_options(binary: ~str,
     let sysroot_opt = matches.opt_str("sysroot").map(|m| @Path::new(m));
     let target = matches.opt_str("target").unwrap_or(host_triple());
     let target_cpu = matches.opt_str("target-cpu").unwrap_or(~"generic");
-    let target_feature = matches.opt_str("target-feature").unwrap_or(~"");
+    let mut target_feature = matches.opt_str("target-feature").unwrap_or(~"");
+    if (target == ~"arm-unknown-linux-gnueabihf") {
+        if (target_feature != ~"") {
+            target_feature.push_char(',');
+       }
+       target_feature.push_str("+vfp3");
+    }
     let save_temps = matches.opt_present("save-temps");
     let opt_level = {
         if (debugging_opts & session::no_opt) != 0 {

Seems to resolve the problem completely. println! works for both f32 and f64 arguments, as does building via rustpkg.

That said, this is not necessarily the most elegant of solutions. Comparing against target is probably unnecessarily verbose.

I also considered modifying librustc/back/link.rs, but that would require a little bit more hacking as target_feature is used through a few levels of dereferencing. librustc/driver/session.rs was another possibility, namely having the output of basic_options be populated with vfp3 on gnueabihf, but I decided against this as it didn't seem to actually be used for rustc, merely rustpkg.

@itdaniher
Copy link
Contributor

Tested on BeagleBone Black, Raspberry Pi, Allwinner A20, Allwinner A10, and RK3188 hardware and modern kernels.

@itdaniher
Copy link
Contributor

@alexcrichton looks like you fixed this in practice at 071ee96?

@alexcrichton
Copy link
Member

I did? I was just shuffling things around in that commit, so I'm not sure that anything would have been fixed as part of that, but I could be wrong? Is the issue here just having some more target_feature flags?

@itdaniher
Copy link
Contributor

Yeah, rustc previously didn't(?) have a viable way to add target_feature flags, and without a manual specification of vfp3, floating point ops failed on ARM. My patch automatically adds the flag on the right architectures, but yours is merged and ought to work.

@alexcrichton
Copy link
Member

From what you discovered, should we be enabling vfp3 by default on some arm platforms?

@itdaniher
Copy link
Contributor

Yes, we should. "Hardfloat" is pretty broken without it.

@alexcrichton
Copy link
Member

Sounds good to me, would you like to submit a PR? I think you probably know more about it than I do!

@itdaniher
Copy link
Contributor

Latest from the frontlines:

../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S: Assembler messages:

.../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S:18: Error: unknown pseudo-op: `.syntax'

.../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S:21: Error: no such instruction: `vmov d6,r0,r1'

../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S:22: Error: no such instruction: `vmov d7,r2,r3'

.../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S:23: Error: no such instruction: `vadd.f64 d6,d6,d7'

.../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S:24: Error: no such instruction: `vmov r0,r1,d6'

.../rust/src/compiler-rt/lib/builtins/arm/adddf3vfp.S:25: Error: no such instruction: `bx lr'

make[1]: *** [.../rust/arm-unknown-linux-gnueabihf/rt/compiler-rt/triple/runtime/armv7/SubDir.lib__builtins__arm/adddf3vfp.o] Error 1

Not entirely sure what's up here. I have a cross-compiler (x86_64 -> arm-unknown-linux-gnueabihf) working, but even -C target-feature=+vfp3 outputs an executable that hang ad nauseam. Guessing there's something broken with my toolchain? Related: ade-ma/A20Notes#5

@alexcrichton - on a similar note, target_feature=+v7 doesn't seem to disable __kernel_cmpxchg64.

bors added a commit that referenced this issue Mar 13, 2014
This enables the lowering of llvm 64b intrinsics to hardware ops, resolving issues around `__kernel_cmpxchg64` on older kernels on ARM devices, and also enables use of the hardware floating point unit, resolving #10482.
@bors bors closed this as completed in f568720 Mar 13, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue Mar 24, 2023
Do not propose to remove `async move` if variables are captured by ref

Fixes rust-lang#10482

changelog: FP [`redundant_async_block`] Do not propose to remove `async move` if variables are captured by ref
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state P-medium Medium priority
Projects
None yet
Development

No branches or pull requests

6 participants