Skip to content

Commit 1f3a15c

Browse files
committed
[x86] Adding support for some missing intrinsics: _castf32_u32, _castf64_u64, _castu32_f32, _castu64_f64
Summary: Adding support for some missing intrinsics: _castf32_u32, _castf64_u64, _castu32_f32, _castu64_f64 Reviewers: craig.topper, LuoYuanke, RKSimon, pengfei Reviewed By: RKSimon Subscribers: llvm-commits Patch by yubing (Bing Yu) Differential Revision: https://reviews.llvm.org/D67212 llvm-svn: 372802
1 parent 03f2a11 commit 1f3a15c

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

clang/lib/Headers/ia32intrin.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,74 @@ __writeeflags(unsigned int __f)
195195
}
196196
#endif /* !__x86_64__ */
197197

198+
/** Cast a 32-bit float value to a 32-bit unsigned integer value
199+
*
200+
* \headerfile <x86intrin.h>
201+
* This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction in x86_64,
202+
* and corresponds to the <c> VMOVL / MOVL </c> instruction in ia32.
203+
*
204+
* \param __A
205+
* A 32-bit float value.
206+
* \returns a 32-bit unsigned integer containing the converted value.
207+
*/
208+
static __inline__ unsigned int __attribute__((__always_inline__))
209+
_castf32_u32(float __A) {
210+
unsigned int D;
211+
__builtin_memcpy(&D, &__A, sizeof(__A));
212+
return D;
213+
}
214+
215+
/** Cast a 64-bit float value to a 64-bit unsigned integer value
216+
*
217+
* \headerfile <x86intrin.h>
218+
* This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
219+
* and corresponds to the <c> VMOVL / MOVL </c> instruction in ia32.
220+
*
221+
* \param __A
222+
* A 64-bit float value.
223+
* \returns a 64-bit unsigned integer containing the converted value.
224+
*/
225+
static __inline__ unsigned long long __attribute__((__always_inline__))
226+
_castf64_u64(double __A) {
227+
unsigned long long D;
228+
__builtin_memcpy(&D, &__A, sizeof(__A));
229+
return D;
230+
}
231+
232+
/** Cast a 32-bit unsigned integer value to a 32-bit float value
233+
*
234+
* \headerfile <x86intrin.h>
235+
* This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
236+
* and corresponds to the <c> FLDS </c> instruction in ia32.
237+
*
238+
* \param __A
239+
* A 32-bit unsigned integer value.
240+
* \returns a 32-bit float value containing the converted value.
241+
*/
242+
static __inline__ float __attribute__((__always_inline__))
243+
_castu32_f32(unsigned int __A) {
244+
float D;
245+
__builtin_memcpy(&D, &__A, sizeof(__A));
246+
return D;
247+
}
248+
249+
/** Cast a 64-bit unsigned integer value to a 64-bit float value
250+
*
251+
* \headerfile <x86intrin.h>
252+
* This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
253+
* and corresponds to the <c> FLDL </c> instruction in ia32.
254+
*
255+
* \param __A
256+
* A 64-bit unsigned integer value.
257+
* \returns a 64-bit float value containing the converted value.
258+
*/
259+
static __inline__ double __attribute__((__always_inline__))
260+
_castu64_f64(unsigned long long __A) {
261+
double D;
262+
__builtin_memcpy(&D, &__A, sizeof(__A));
263+
return D;
264+
}
265+
198266
/** Adds the unsigned integer operand to the CRC-32C checksum of the
199267
* unsigned char operand.
200268
*

clang/test/CodeGen/x86-builtins.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-unknown-unknown -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=CHECK-64
2+
// RUN: %clang_cc1 -ffreestanding %s -triple=i386-unknown-unknown -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=CHECK-32
3+
4+
#include <x86intrin.h>
5+
6+
unsigned int test_castf32_u32 (float __A){
7+
// CHECK-64-LABEL: @test_castf32_u32
8+
// CHECK-64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i64 4, i1 false)
9+
// CHECK-64: %{{.*}} = load i32, i32* %{{.*}}, align 4
10+
// CHECK-32-LABEL: @test_castf32_u32
11+
// CHECK-32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 4, i1 false)
12+
// CHECK-32: %{{.*}} = load i32, i32* %{{.*}}, align 4
13+
return _castf32_u32(__A);
14+
}
15+
16+
unsigned long long test_castf64_u64 (double __A){
17+
// CHECK-64-LABEL: @test_castf64_u64
18+
// CHECK-64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %{{.*}}, i8* align 8 %{{.*}}, i64 8, i1 false)
19+
// CHECK-64: %{{.*}} = load i64, i64* %{{.*}}, align 8
20+
// CHECK-32-LABEL: @test_castf64_u64
21+
// CHECK-32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %{{.*}}, i8* align 8 %{{.*}}, i32 8, i1 false)
22+
// CHECK-32: %{{.*}} = load i64, i64* %{{.*}}, align 8
23+
return _castf64_u64(__A);
24+
}
25+
26+
float test_castu32_f32 (unsigned int __A){
27+
// CHECK-64-LABEL: @test_castu32_f32
28+
// CHECK-64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i64 4, i1 false)
29+
// CHECK-64: %{{.*}} = load float, float* %{{.*}}, align 4
30+
// CHECK-32-LABEL: @test_castu32_f32
31+
// CHECK-32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 4, i1 false)
32+
// CHECK-32: %{{.*}} = load float, float* %{{.*}}, align 4
33+
return _castu32_f32(__A);
34+
}
35+
36+
double test_castu64_f64 (unsigned long long __A){
37+
// CHECK-64-LABEL: @test_castu64_f64
38+
// CHECK-64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %{{.*}}, i8* align 8 %{{.*}}, i64 8, i1 false)
39+
// CHECK-64: %{{.*}} = load double, double* %{{.*}}, align 8
40+
// CHECK-32-LABEL: @test_castu64_f64
41+
// CHECK-32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %{{.*}}, i8* align 8 %{{.*}}, i32 8, i1 false)
42+
// CHECK-32: %{{.*}} = load double, double* %{{.*}}, align 8
43+
return _castu64_f64(__A);
44+
}
45+

0 commit comments

Comments
 (0)