Skip to content

Commit 0d6b5dd

Browse files
committed
Add f16 inline ASM support for RISC-V
1 parent 92af831 commit 0d6b5dd

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,13 @@ fn llvm_fixup_input<'ll, 'tcx>(
10291029
_ => value,
10301030
}
10311031
}
1032+
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s)) if s.primitive() == Primitive::Float(Float::F16) => {
1033+
// Smaller floats are always "NaN-boxed" inside larger floats on RISC-V.
1034+
let value = bx.bitcast(value, bx.type_i16());
1035+
let value = bx.zext(value, bx.type_i32());
1036+
let value = bx.or(value, bx.const_u32(0xFFFF_0000));
1037+
bx.bitcast(value, bx.type_f32())
1038+
}
10321039
_ => value,
10331040
}
10341041
}
@@ -1140,6 +1147,11 @@ fn llvm_fixup_output<'ll, 'tcx>(
11401147
_ => value,
11411148
}
11421149
}
1150+
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s)) if s.primitive() == Primitive::Float(Float::F16) => {
1151+
let value = bx.bitcast(value, bx.type_i32());
1152+
let value = bx.trunc(value, bx.type_i16());
1153+
bx.bitcast(value, bx.type_f16())
1154+
}
11431155
_ => value,
11441156
}
11451157
}
@@ -1242,6 +1254,9 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
12421254
_ => layout.llvm_type(cx),
12431255
}
12441256
}
1257+
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s)) if s.primitive() == Primitive::Float(Float::F16) => {
1258+
cx.type_f32()
1259+
}
12451260
_ => layout.llvm_type(cx),
12461261
}
12471262
}

compiler/rustc_target/src/asm/riscv.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ impl RiscVInlineAsmRegClass {
4040
match self {
4141
Self::reg => {
4242
if arch == InlineAsmArch::RiscV64 {
43-
types! { _: I8, I16, I32, I64, F32, F64; }
43+
types! { _: I8, I16, I32, I64, F16, F32, F64; }
4444
} else {
45-
types! { _: I8, I16, I32, F32; }
45+
types! { _: I8, I16, I32, F16, F32; }
4646
}
4747
}
48-
Self::freg => types! { f: F32; d: F64; },
48+
// FIXME(f16_f128): Add `q: F128;` once LLVM support the `Q` extension.
49+
Self::freg => types! { f: F16, F32; d: F64; },
4950
Self::vreg => &[],
5051
}
5152
}

tests/assembly/asm/riscv-types.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//@[riscv32] needs-llvm-components: riscv
77
//@ compile-flags: -C target-feature=+d
88

9-
#![feature(no_core, lang_items, rustc_attrs)]
9+
#![feature(no_core, lang_items, rustc_attrs, f16)]
1010
#![crate_type = "rlib"]
1111
#![no_core]
1212
#![allow(asm_sub_register)]
@@ -33,6 +33,7 @@ type ptr = *mut u8;
3333

3434
impl Copy for i8 {}
3535
impl Copy for i16 {}
36+
impl Copy for f16 {}
3637
impl Copy for i32 {}
3738
impl Copy for f32 {}
3839
impl Copy for i64 {}
@@ -103,6 +104,12 @@ macro_rules! check_reg {
103104
// CHECK: #NO_APP
104105
check!(reg_i8 i8 reg "mv");
105106

107+
// CHECK-LABEL: reg_f16:
108+
// CHECK: #APP
109+
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
110+
// CHECK: #NO_APP
111+
check!(reg_f16 f16 reg "mv");
112+
106113
// CHECK-LABEL: reg_i16:
107114
// CHECK: #APP
108115
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
@@ -141,6 +148,12 @@ check!(reg_f64 f64 reg "mv");
141148
// CHECK: #NO_APP
142149
check!(reg_ptr ptr reg "mv");
143150

151+
// CHECK-LABEL: freg_f16:
152+
// CHECK: #APP
153+
// CHECK: fmv.s f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
154+
// CHECK: #NO_APP
155+
check!(freg_f16 f16 freg "fmv.s");
156+
144157
// CHECK-LABEL: freg_f32:
145158
// CHECK: #APP
146159
// CHECK: fmv.s f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
@@ -165,6 +178,12 @@ check_reg!(a0_i8 i8 "a0" "mv");
165178
// CHECK: #NO_APP
166179
check_reg!(a0_i16 i16 "a0" "mv");
167180

181+
// CHECK-LABEL: a0_f16:
182+
// CHECK: #APP
183+
// CHECK: mv a0, a0
184+
// CHECK: #NO_APP
185+
check_reg!(a0_f16 f16 "a0" "mv");
186+
168187
// CHECK-LABEL: a0_i32:
169188
// CHECK: #APP
170189
// CHECK: mv a0, a0
@@ -197,6 +216,12 @@ check_reg!(a0_f64 f64 "a0" "mv");
197216
// CHECK: #NO_APP
198217
check_reg!(a0_ptr ptr "a0" "mv");
199218

219+
// CHECK-LABEL: fa0_f16:
220+
// CHECK: #APP
221+
// CHECK: fmv.s fa0, fa0
222+
// CHECK: #NO_APP
223+
check_reg!(fa0_f16 f16 "fa0" "fmv.s");
224+
200225
// CHECK-LABEL: fa0_f32:
201226
// CHECK: #APP
202227
// CHECK: fmv.s fa0, fa0

0 commit comments

Comments
 (0)