Skip to content

Commit dcd0c86

Browse files
committed
Use LLVM's UEFI targets
The UEFI targets previously passed Windows targets to LLVM, because that's what they're the most similar to. That's not ideal though (part of this problem was analyzed in 21e062d), but it seems like LLVM has since the introduction of these targets gained support for UEFI in-tree, so we should just use that: https://discourse.llvm.org/t/rfc-uefi-driver-support-uefi-target/73261
1 parent 705cfe0 commit dcd0c86

File tree

3 files changed

+5
-60
lines changed

3 files changed

+5
-60
lines changed

compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
1111
base.features = "+v8a".into();
1212

1313
Target {
14-
llvm_target: "aarch64-unknown-windows".into(),
14+
llvm_target: "aarch64-unknown-uefi".into(),
1515
metadata: crate::spec::TargetMetadata {
1616
description: Some("ARM64 UEFI".into()),
1717
tier: Some(2),

compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs

+2-56
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// UEFI systems always run in protected-mode, have the interrupt-controller pre-configured and
44
// force a single-CPU execution.
55
// The cdecl ABI is used. It differs from the stdcall or fastcall ABI.
6-
// "i686-unknown-windows" is used to get the minimal subset of windows-specific features.
76

87
use crate::spec::{Target, base};
98

@@ -23,61 +22,8 @@ pub(crate) fn target() -> Target {
2322
// arguments, thus giving you access to full MMX/SSE acceleration.
2423
base.features = "-mmx,-sse,+soft-float".into();
2524

26-
// Use -GNU here, because of the reason below:
27-
// Background and Problem:
28-
// If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic
29-
// _alldiv, _aulldiv, _allrem, _aullrem, _allmul, which will cause undefined symbol.
30-
// A real issue is __aulldiv() is referred by __udivdi3() - udivmod_inner!(), from
31-
// https://github.com/rust-lang-nursery/compiler-builtins.
32-
// As result, rust-lld generates link error finally.
33-
// Root-cause:
34-
// In rust\src\llvm-project\llvm\lib\Target\X86\X86ISelLowering.cpp,
35-
// we have below code to use MSVC intrinsics. It assumes MSVC target
36-
// will link MSVC library. But that is NOT true in UEFI environment.
37-
// UEFI does not link any MSVC or GCC standard library.
38-
// if (Subtarget.isTargetKnownWindowsMSVC() ||
39-
// Subtarget.isTargetWindowsItanium()) {
40-
// // Setup Windows compiler runtime calls.
41-
// setLibcallName(RTLIB::SDIV_I64, "_alldiv");
42-
// setLibcallName(RTLIB::UDIV_I64, "_aulldiv");
43-
// setLibcallName(RTLIB::SREM_I64, "_allrem");
44-
// setLibcallName(RTLIB::UREM_I64, "_aullrem");
45-
// setLibcallName(RTLIB::MUL_I64, "_allmul");
46-
// setLibcallCallingConv(RTLIB::SDIV_I64, CallingConv::X86_StdCall);
47-
// setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::X86_StdCall);
48-
// setLibcallCallingConv(RTLIB::SREM_I64, CallingConv::X86_StdCall);
49-
// setLibcallCallingConv(RTLIB::UREM_I64, CallingConv::X86_StdCall);
50-
// setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::X86_StdCall);
51-
// }
52-
// The compiler intrinsics should be implemented by compiler-builtins.
53-
// Unfortunately, compiler-builtins has not provided those intrinsics yet. Such as:
54-
// i386/divdi3.S
55-
// i386/lshrdi3.S
56-
// i386/moddi3.S
57-
// i386/muldi3.S
58-
// i386/udivdi3.S
59-
// i386/umoddi3.S
60-
// Possible solution:
61-
// 1. Eliminate Intrinsics generation.
62-
// 1.1 Choose different target to bypass isTargetKnownWindowsMSVC().
63-
// 1.2 Remove the "Setup Windows compiler runtime calls" in LLVM
64-
// 2. Implement Intrinsics.
65-
// We evaluated all options.
66-
// #2 is hard because we need implement the intrinsics (_aulldiv) generated
67-
// from the other intrinsics (__udivdi3) implementation with the same
68-
// functionality (udivmod_inner). If we let _aulldiv() call udivmod_inner!(),
69-
// then we are in loop. We may have to find another way to implement udivmod_inner!().
70-
// #1.2 may break the existing usage.
71-
// #1.1 seems the simplest solution today.
72-
// The IA32 -gnu calling convention is same as the one defined in UEFI specification.
73-
// It uses cdecl, EAX/ECX/EDX as volatile register, and EAX/EDX as return value.
74-
// We also checked the LLVM X86TargetLowering, the differences between -gnu and -msvc
75-
// is fmodf(f32), longjmp() and TLS. None of them impacts the UEFI code.
76-
// As a result, we choose -gnu for i686 version before those intrinsics are implemented in
77-
// compiler-builtins. After compiler-builtins implements all required intrinsics, we may
78-
// remove -gnu and use the default one.
7925
Target {
80-
llvm_target: "i686-unknown-windows-gnu".into(),
26+
llvm_target: "i686-unknown-uefi".into(),
8127
metadata: crate::spec::TargetMetadata {
8228
description: Some("32-bit UEFI".into()),
8329
tier: Some(2),
@@ -86,7 +32,7 @@ pub(crate) fn target() -> Target {
8632
},
8733
pointer_width: 32,
8834
data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
89-
i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
35+
i128:128-f64:32:64-f80:32-n8:16:32-S128"
9036
.into(),
9137
arch: "x86".into(),
9238

compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
// uefi-base module for generic UEFI options. On x86_64 systems (mostly called "x64" in the spec)
33
// UEFI systems always run in long-mode, have the interrupt-controller pre-configured and force a
44
// single-CPU execution.
5-
// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
6-
// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
5+
// The win64 ABI is used. It differs from the sysv64 ABI.
76

87
use crate::abi::call::Conv;
98
use crate::spec::{Target, base};
@@ -28,7 +27,7 @@ pub(crate) fn target() -> Target {
2827
base.features = "-mmx,-sse,+soft-float".into();
2928

3029
Target {
31-
llvm_target: "x86_64-unknown-windows".into(),
30+
llvm_target: "x86_64-unknown-uefi".into(),
3231
metadata: crate::spec::TargetMetadata {
3332
description: Some("64-bit UEFI".into()),
3433
tier: Some(2),

0 commit comments

Comments
 (0)