Skip to content

Commit 1122f42

Browse files
committed
Support cross-compiling to Windows using MinGW
1 parent c825bc8 commit 1122f42

File tree

7 files changed

+82
-22
lines changed

7 files changed

+82
-22
lines changed

example/mini_core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ struct PanicLocation {
621621
}
622622

623623
#[no_mangle]
624+
#[cfg(not(windows))]
624625
pub fn get_tls() -> u8 {
625626
#[thread_local]
626627
static A: u8 = 42;

example/mini_core_hello_world.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ fn main() {
239239

240240
assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
241241

242-
#[cfg(not(jit))]
242+
#[cfg(not(any(jit, windows)))]
243243
{
244244
extern {
245245
#[linkage = "extern_weak"]
@@ -292,7 +292,7 @@ fn main() {
292292

293293
from_decimal_string();
294294

295-
#[cfg(not(jit))]
295+
#[cfg(not(any(jit, windows)))]
296296
test_tls();
297297

298298
#[cfg(all(not(jit), target_os = "linux"))]

example/std_example.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ fn main() {
1616
let mut stderr = stderr.lock();
1717

1818
// FIXME support lazy jit when multi threading
19-
#[cfg(not(lazy_jit))]
19+
// FIXME support TLS on windows
20+
#[cfg(not(any(lazy_jit, windows)))]
2021
std::thread::spawn(move || {
2122
println!("Hello from another thread!");
2223
});

prepare.sh

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
set -e
33

44
rustup component add rust-src rustc-dev llvm-tools-preview
5+
rustup target add x86_64-pc-windows-gnu
56
./build_sysroot/prepare_sysroot_src.sh
67
cargo install hyperfine || echo "Skipping hyperfine install"
78

src/codegen_i128.rs

+70-19
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,56 @@ pub(crate) fn maybe_codegen<'tcx>(
3232
BinOp::Add | BinOp::Sub if !checked => None,
3333
BinOp::Mul if !checked => {
3434
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
35-
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
35+
if fx.tcx.sess.target.is_like_windows {
36+
let ret_place = CPlace::new_stack_slot(fx, lhs.layout());
37+
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
38+
let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
39+
assert!(lhs_extra.is_none());
40+
assert!(rhs_extra.is_none());
41+
let args =
42+
[ret_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)];
43+
fx.lib_call(
44+
"__multi3",
45+
vec![
46+
AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn),
47+
AbiParam::new(pointer_ty(fx.tcx)),
48+
AbiParam::new(pointer_ty(fx.tcx)),
49+
],
50+
vec![],
51+
&args,
52+
);
53+
Some(ret_place.to_cvalue(fx))
54+
} else {
55+
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
56+
}
3657
}
3758
BinOp::Add | BinOp::Sub | BinOp::Mul => {
3859
assert!(checked);
3960
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
4061
let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
41-
let param_types = vec![
42-
AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn),
43-
AbiParam::new(types::I128),
44-
AbiParam::new(types::I128),
45-
];
46-
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
62+
let (param_types, args) = if fx.tcx.sess.target.is_like_windows {
63+
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
64+
let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
65+
assert!(lhs_extra.is_none());
66+
assert!(rhs_extra.is_none());
67+
(
68+
vec![
69+
AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn),
70+
AbiParam::new(pointer_ty(fx.tcx)),
71+
AbiParam::new(pointer_ty(fx.tcx)),
72+
],
73+
[out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)],
74+
)
75+
} else {
76+
(
77+
vec![
78+
AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn),
79+
AbiParam::new(types::I128),
80+
AbiParam::new(types::I128),
81+
],
82+
[out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)],
83+
)
84+
};
4785
let name = match (bin_op, is_signed) {
4886
(BinOp::Add, false) => "__rust_u128_addo",
4987
(BinOp::Add, true) => "__rust_i128_addo",
@@ -57,20 +95,33 @@ pub(crate) fn maybe_codegen<'tcx>(
5795
Some(out_place.to_cvalue(fx))
5896
}
5997
BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"),
60-
BinOp::Div => {
98+
BinOp::Div | BinOp::Rem => {
6199
assert!(!checked);
62-
if is_signed {
63-
Some(fx.easy_call("__divti3", &[lhs, rhs], fx.tcx.types.i128))
64-
} else {
65-
Some(fx.easy_call("__udivti3", &[lhs, rhs], fx.tcx.types.u128))
66-
}
67-
}
68-
BinOp::Rem => {
69-
assert!(!checked);
70-
if is_signed {
71-
Some(fx.easy_call("__modti3", &[lhs, rhs], fx.tcx.types.i128))
100+
let name = match (bin_op, is_signed) {
101+
(BinOp::Div, false) => "__udivti3",
102+
(BinOp::Div, true) => "__divti3",
103+
(BinOp::Rem, false) => "__umodti3",
104+
(BinOp::Rem, true) => "__modti3",
105+
_ => unreachable!(),
106+
};
107+
if fx.tcx.sess.target.is_like_windows {
108+
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
109+
let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
110+
assert!(lhs_extra.is_none());
111+
assert!(rhs_extra.is_none());
112+
let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)];
113+
let ret = fx.lib_call(
114+
name,
115+
vec![AbiParam::new(pointer_ty(fx.tcx)), AbiParam::new(pointer_ty(fx.tcx))],
116+
vec![AbiParam::new(types::I64X2)],
117+
&args,
118+
)[0];
119+
// FIXME use bitcast instead of store to get from i64x2 to i128
120+
let ret_place = CPlace::new_stack_slot(fx, lhs.layout());
121+
ret_place.to_ptr().store(fx, ret, MemFlags::trusted());
122+
Some(ret_place.to_cvalue(fx))
72123
} else {
73-
Some(fx.easy_call("__umodti3", &[lhs, rhs], fx.tcx.types.u128))
124+
Some(fx.easy_call(name, &[lhs, rhs], lhs.layout().ty))
74125
}
75126
}
76127
BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => {

src/inline_asm.rs

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ pub(crate) fn codegen_inline_asm<'tcx>(
2020
if template.is_empty() {
2121
// Black box
2222
return;
23+
} else if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
24+
let true_ = fx.bcx.ins().iconst(types::I32, 1);
25+
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
26+
return;
2327
}
2428

2529
let mut slot_size = Size::from_bytes(0);

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
313313

314314
flags_builder.set("enable_simd", "true").unwrap();
315315

316+
flags_builder.set("enable_llvm_abi_extensions", "true").unwrap();
317+
316318
use rustc_session::config::OptLevel;
317319
match sess.opts.optimize {
318320
OptLevel::No => {

0 commit comments

Comments
 (0)