I'm using cross to compile a program for a Raspberry Pi Zero W (arm-unknown-linux-gnueabihf).
The program crashes with an “Illegal Instruction” error however, when I try rounding an f64.
fn main() {
let v: f64 = 0.0;
println!("works: {:?}", v);
println!("fails: {:?}", (v * 10.0).round());
}
The weird thing is, this doesn't fail:
fn main() {
let v: f64 = 0.0;
println!("works: {:?}", v.round());
println!("works: {:?}", (v * 10.0).round());
}
Neither does this:
fn main() {
let v: f64 = 0.0;
println!("works: {:?}", v);
println!("works: {:?}", (v * 1.0).round());
}
I have no idea what is going on, any help is appreciated.
Note: I have also tried compiling with arm-unknown-linux-gnueabi, which shows the same behaviour, except instead of crashing with an “Illegal Instruction” it produces NaN.
If you haven't already, I'd suggest creating an issue on the rust issue tracker.
It sounds like arm-unknown-linux-gnuabihf may not be the right target to use for your platform. Or maybe the target definition itself is incorrect, so rustc tells LLVM to generate the wrong instructions.
@reitermarkus The last part of your triple, hf, indicates the ARM target supports hardware floats.
It sounds like your Raspberry PI W doesn't supports hardware floats, and thus hardware instructions operating on floats fail. I'm guessing the code that works only works because the compiler decided to perform the rounding operations at compile time, rather than runtime, and that optimization can be pretty fickle.
I would recommend setting your target to arm-unknown-linux-gnueabi instead. Note the lack of hf on the end means that hardware floating point operations ("Hard Float" operations) won't be generated, and software emulation of floating point ops will be done instead.
The people are correct here.
According to Raspberry Pi - Wikipedia the Zero has no NEON FPU, therefore gnueabihf is the wrong target. (I also can't find anything FPU related in the datasheet).