Skip to content

Commit a989acc

Browse files
committed
[RISCV] Implement Clang Builtins for XCValu Extension in CV32E40P
This commit adds the Clang Builtins, C API header and relevant tests for XCValu extension. Spec: https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md Contributor: @melonedo, @PaoloS02
1 parent ac1a1e5 commit a989acc

File tree

12 files changed

+852
-73
lines changed

12 files changed

+852
-73
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//==- BuiltinsRISCVXCV.def - RISC-V CORE-V Builtin database ----*- C++ -*-==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the CORE-V-specific builtin function database. Users of
10+
// this file must define the BUILTIN macro to make use of this information.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
15+
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
16+
#endif
17+
18+
TARGET_BUILTIN(alu_slet, "ZiZiZi", "nc", "xcvalu")
19+
TARGET_BUILTIN(alu_sletu, "ZiUZiUZi", "nc", "xcvalu")
20+
TARGET_BUILTIN(alu_min, "ZiZiZi", "nc", "xcvalu")
21+
TARGET_BUILTIN(alu_minu, "UZiUZiUZi", "nc", "xcvalu")
22+
TARGET_BUILTIN(alu_max, "ZiZiZi", "nc", "xcvalu")
23+
TARGET_BUILTIN(alu_maxu, "UZiUZiUZi", "nc", "xcvalu")
24+
TARGET_BUILTIN(alu_exths, "Zis", "nc", "xcvalu")
25+
TARGET_BUILTIN(alu_exthz, "UZiUs", "nc", "xcvalu")
26+
TARGET_BUILTIN(alu_extbs, "Zic", "nc", "xcvalu")
27+
TARGET_BUILTIN(alu_extbz, "UZiUc", "nc", "xcvalu")
28+
29+
TARGET_BUILTIN(alu_clip, "ZiZiUZi", "nc", "xcvalu")
30+
TARGET_BUILTIN(alu_clipu, "UZiUZiUZi", "nc", "xcvalu")
31+
TARGET_BUILTIN(alu_addN, "ZiZiUZiUc", "nc", "xcvalu")
32+
TARGET_BUILTIN(alu_adduN, "UZiUZiUZiUc", "nc", "xcvalu")
33+
TARGET_BUILTIN(alu_addRN, "ZiZiZiUc", "nc", "xcvalu")
34+
TARGET_BUILTIN(alu_adduRN, "UZiUZiUZiUc", "nc", "xcvalu")
35+
TARGET_BUILTIN(alu_subN, "ZiZiUZiUc", "nc", "xcvalu")
36+
TARGET_BUILTIN(alu_subuN, "UZiUZiUZiUc", "nc", "xcvalu")
37+
TARGET_BUILTIN(alu_subRN, "ZiZiZiUc", "nc", "xcvalu")
38+
TARGET_BUILTIN(alu_subuRN, "UZiUZiUZiUc", "nc", "xcvalu")
39+
40+
#undef BUILTIN
41+
#undef TARGET_BUILTIN

clang/include/clang/Basic/TargetBuiltins.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,22 @@ namespace clang {
152152
};
153153
}
154154

155+
namespace RISCVXCV {
156+
enum {
157+
LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
158+
#define BUILTIN(ID, TYPE, ATTRS) BI__builtin_riscv_cv_##ID,
159+
#include "clang/Basic/BuiltinsRISCVXCV.def"
160+
FirstTSBuiltin,
161+
};
162+
} // namespace RISCVXCV
163+
155164
/// RISCV builtins
156165
namespace RISCV {
157166
enum {
158167
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
159168
FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin,
160169
LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
170+
LastXCVBuiltin = RISCVXCV::FirstTSBuiltin - 1,
161171
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
162172
#include "clang/Basic/BuiltinsRISCV.inc"
163173
LastTSBuiltin

clang/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ module Clang_Basic {
5555
textual header "clang/Basic/BuiltinsNEON.def"
5656
textual header "clang/Basic/BuiltinsNVPTX.def"
5757
textual header "clang/Basic/BuiltinsPPC.def"
58+
textual header "Basic/BuiltinsRISCVXCV.def"
5859
textual header "clang/Basic/BuiltinsRISCVVector.def"
5960
textual header "clang/Basic/BuiltinsSME.def"
6061
textual header "clang/Basic/BuiltinsSVE.def"

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,14 @@ static constexpr Builtin::Info BuiltinInfo[] = {
231231
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
232232
#include "clang/Basic/BuiltinsRISCVVector.def"
233233
#define BUILTIN(ID, TYPE, ATTRS) \
234-
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
234+
{"__builtin_riscv_cv_" #ID, TYPE, ATTRS, nullptr, \
235+
HeaderDesc::NO_HEADER, ALL_LANGUAGES},
236+
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
237+
{"__builtin_riscv_cv_" #ID, TYPE, ATTRS, FEATURE, \
238+
HeaderDesc::NO_HEADER, ALL_LANGUAGES},
239+
#include "clang/Basic/BuiltinsRISCVXCV.def"
240+
#define BUILTIN(ID, TYPE, ATTRS) \
241+
\ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
235242
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
236243
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
237244
#include "clang/Basic/BuiltinsRISCV.inc"

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21901,6 +21901,30 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
2190121901
return nullptr;
2190221902
}
2190321903

21904+
static Value *EmitXCVIntrinsic(CodeGenFunction &CGF, unsigned BuiltinID,
21905+
unsigned IntrinsicID,
21906+
MutableArrayRef<Value *> Ops,
21907+
const CallExpr *E) {
21908+
llvm::Type *MachineType =
21909+
llvm::IntegerType::getInt32Ty(CGF.CGM.getLLVMContext());
21910+
for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
21911+
if (Ops[i]->getType() != MachineType) {
21912+
QualType type = E->getArg(i)->getType();
21913+
assert((type->isSignedIntegerType() || type->isUnsignedIntegerType() ||
21914+
type->isPointerType()) &&
21915+
"Argument of Core-V builtin must have signed or unsigned integer "
21916+
"or Pointer type");
21917+
if (type->isSignedIntegerType()) {
21918+
Ops[i] = CGF.Builder.CreateSExt(Ops[i], MachineType);
21919+
} else if ((type->isUnsignedIntegerType())) {
21920+
Ops[i] = CGF.Builder.CreateZExt(Ops[i], MachineType);
21921+
}
21922+
}
21923+
}
21924+
llvm::Function *F = CGF.CGM.getIntrinsic(IntrinsicID);
21925+
return CGF.Builder.CreateCall(F, Ops);
21926+
}
21927+
2190421928
Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
2190521929
const CallExpr *E,
2190621930
ReturnValueSlot ReturnValue) {
@@ -22126,6 +22150,13 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
2212622150
return Store;
2212722151
}
2212822152

22153+
// Core-V
22154+
#define BUILTIN(NAME, TYPE, ATTRS) \
22155+
case RISCVXCV::BI__builtin_riscv_cv_##NAME: \
22156+
ID = Intrinsic::riscv_cv_##NAME; \
22157+
return EmitXCVIntrinsic(*this, BuiltinID, ID, Ops, E);
22158+
#include "clang/Basic/BuiltinsRISCVXCV.def"
22159+
2212922160
// Vector builtins are handled from here.
2213022161
#include "clang/Basic/riscv_vector_builtin_cg.inc"
2213122162
// SiFive Vector builtins are handled from here.

clang/lib/Headers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ set(riscv_files
122122
riscv_crypto.h
123123
riscv_ntlh.h
124124
sifive_vector.h
125+
riscv_corev_alu.h
125126
)
126127

127128
set(systemz_files

clang/lib/Headers/riscv_corev_alu.h

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*===---- riscv_corev_alu.h - CORE-V ALU intrinsics ------------------------===
2+
*
3+
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
* See https://llvm.org/LICENSE.txt for license information.
5+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
*
7+
*===-----------------------------------------------------------------------===
8+
*/
9+
10+
#ifndef __RISCV_COREV_ALU_H
11+
#define __RISCV_COREV_ALU_H
12+
13+
#include <stdint.h>
14+
15+
#if defined(__cplusplus)
16+
extern "C" {
17+
#endif
18+
19+
#if defined(__riscv_xcvalu)
20+
21+
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
22+
23+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_abs(long a) {
24+
return __builtin_abs(a);
25+
}
26+
27+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_slet(long a, long b) {
28+
return __builtin_riscv_cv_alu_slet(a, b);
29+
}
30+
31+
static __inline__ long __DEFAULT_FN_ATTRS
32+
__riscv_cv_alu_sletu(unsigned long a, unsigned long b) {
33+
return __builtin_riscv_cv_alu_sletu(a, b);
34+
}
35+
36+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_min(long a, long b) {
37+
return __builtin_riscv_cv_alu_min(a, b);
38+
}
39+
40+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
41+
__riscv_cv_alu_minu(unsigned long a, unsigned long b) {
42+
return __builtin_riscv_cv_alu_minu(a, b);
43+
}
44+
45+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_max(long a, long b) {
46+
return __builtin_riscv_cv_alu_max(a, b);
47+
}
48+
49+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
50+
__riscv_cv_alu_maxu(unsigned long a, unsigned long b) {
51+
return __builtin_riscv_cv_alu_maxu(a, b);
52+
}
53+
54+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_exths(int16_t a) {
55+
return __builtin_riscv_cv_alu_exths(a);
56+
}
57+
58+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
59+
__riscv_cv_alu_exthz(uint16_t a) {
60+
return __builtin_riscv_cv_alu_exthz(a);
61+
}
62+
63+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_extbs(int8_t a) {
64+
return __builtin_riscv_cv_alu_extbs(a);
65+
}
66+
67+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
68+
__riscv_cv_alu_extbz(uint8_t a) {
69+
return __builtin_riscv_cv_alu_extbz(a);
70+
}
71+
72+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_clip(long a,
73+
unsigned long b) {
74+
return __builtin_riscv_cv_alu_clip(a, b);
75+
}
76+
77+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
78+
__riscv_cv_alu_clipu(unsigned long a, unsigned long b) {
79+
return __builtin_riscv_cv_alu_clipu(a, b);
80+
}
81+
82+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_addN(long a, long b,
83+
uint8_t shft) {
84+
return __builtin_riscv_cv_alu_addN(a, b, shft);
85+
}
86+
87+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
88+
__riscv_cv_alu_adduN(unsigned long a, unsigned long b, uint8_t shft) {
89+
return __builtin_riscv_cv_alu_adduN(a, b, shft);
90+
}
91+
92+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_addRN(long a, long b,
93+
uint8_t shft) {
94+
return __builtin_riscv_cv_alu_addRN(a, b, shft);
95+
}
96+
97+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
98+
__riscv_cv_alu_adduRN(unsigned long a, unsigned long b, uint8_t shft) {
99+
return __builtin_riscv_cv_alu_adduRN(a, b, shft);
100+
}
101+
102+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_subN(long a, long b,
103+
uint8_t shft) {
104+
return __builtin_riscv_cv_alu_subN(a, b, shft);
105+
}
106+
107+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
108+
__riscv_cv_alu_subuN(unsigned long a, unsigned long b, uint8_t shft) {
109+
return __builtin_riscv_cv_alu_subuN(a, b, shft);
110+
}
111+
112+
static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_subRN(long a, long b,
113+
uint8_t shft) {
114+
return __builtin_riscv_cv_alu_subRN(a, b, shft);
115+
}
116+
117+
static __inline__ unsigned long __DEFAULT_FN_ATTRS
118+
__riscv_cv_alu_subuRN(unsigned long a, unsigned long b, uint8_t shft) {
119+
return __builtin_riscv_cv_alu_subuRN(a, b, shft);
120+
}
121+
122+
#endif // defined(__riscv_xcvalu)
123+
124+
#if defined(__cplusplus)
125+
}
126+
#endif
127+
128+
#endif // define __RISCV_COREV_ALU_H
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple riscv32 -target-feature +xcvalu -emit-llvm %s -o - \
3+
// RUN: | FileCheck %s
4+
5+
#include <stdint.h>
6+
#include <riscv_corev_alu.h>
7+
8+
// CHECK-LABEL: @test_alu_slet
9+
// CHECK: @llvm.riscv.cv.alu.slet
10+
int test_alu_slet(int32_t a, int32_t b) {
11+
return __riscv_cv_alu_slet(a, b);
12+
}
13+
14+
// CHECK-LABEL: @test_alu_sletu
15+
// CHECK: @llvm.riscv.cv.alu.sletu
16+
int test_alu_sletu(uint32_t a, uint32_t b) {
17+
return __riscv_cv_alu_sletu(a, b);
18+
}
19+
20+
// CHECK-LABEL: @test_alu_min
21+
// CHECK: @llvm.riscv.cv.alu.min
22+
int test_alu_min(int32_t a, int32_t b) {
23+
return __riscv_cv_alu_min(a, b);
24+
}
25+
26+
// CHECK-LABEL: @test_alu_minu
27+
// CHECK: @llvm.riscv.cv.alu.minu
28+
int test_alu_minu(uint32_t a, uint32_t b) {
29+
return __riscv_cv_alu_minu(a, b);
30+
}
31+
32+
// CHECK-LABEL: @test_alu_max
33+
// CHECK: @llvm.riscv.cv.alu.max
34+
int test_alu_max(int32_t a, int32_t b) {
35+
return __riscv_cv_alu_max(a, b);
36+
}
37+
38+
// CHECK-LABEL: @test_alu_maxu
39+
// CHECK: @llvm.riscv.cv.alu.maxu
40+
int test_alu_maxu(uint32_t a, uint32_t b) {
41+
return __riscv_cv_alu_maxu(a, b);
42+
}
43+
44+
// CHECK-LABEL: @test_alu_exths
45+
// CHECK: @llvm.riscv.cv.alu.exths
46+
int test_alu_exths(int16_t a) {
47+
return __riscv_cv_alu_exths(a);
48+
}
49+
50+
// CHECK-LABEL: @test_alu_exthz
51+
// CHECK: @llvm.riscv.cv.alu.exthz
52+
int test_alu_exthz(uint16_t a) {
53+
return __riscv_cv_alu_exthz(a);
54+
}
55+
56+
// CHECK-LABEL: @test_alu_extbs
57+
// CHECK: @llvm.riscv.cv.alu.extbs
58+
int test_alu_extbs(int8_t a) {
59+
return __riscv_cv_alu_extbs(a);
60+
}
61+
62+
// CHECK-LABEL: @test_alu_extbz
63+
// CHECK: @llvm.riscv.cv.alu.extbz
64+
int test_alu_extbz(uint8_t a) {
65+
return __riscv_cv_alu_extbz(a);
66+
}
67+
68+
// CHECK-LABEL: @test_alu_clip
69+
// CHECK: @llvm.riscv.cv.alu.clip
70+
int test_alu_clip(int32_t a) {
71+
return __riscv_cv_alu_clip(a, 0);
72+
}
73+
74+
// CHECK-LABEL: @test_alu_clipu
75+
// CHECK: @llvm.riscv.cv.alu.clipu
76+
int test_alu_clipu(uint32_t a) {
77+
return __riscv_cv_alu_clipu(a, 0);
78+
}
79+
80+
// CHECK-LABEL: @test_alu_addN
81+
// CHECK: @llvm.riscv.cv.alu.addN
82+
int test_alu_addN(int32_t a, int32_t b) {
83+
return __riscv_cv_alu_addN(a, b, 0);
84+
}
85+
86+
// CHECK-LABEL: @test_alu_adduN
87+
// CHECK: @llvm.riscv.cv.alu.adduN
88+
int test_alu_adduN(uint32_t a, uint32_t b) {
89+
return __riscv_cv_alu_adduN(a, b, 0);
90+
}
91+
92+
// CHECK-LABEL: @test_alu_addRN
93+
// CHECK: @llvm.riscv.cv.alu.addRN
94+
int test_alu_addRN(int32_t a, int32_t b) {
95+
return __riscv_cv_alu_addRN(a, b, 0);
96+
}
97+
98+
// CHECK-LABEL: @test_alu_adduRN
99+
// CHECK: @llvm.riscv.cv.alu.adduRN
100+
int test_alu_adduRN(uint32_t a, uint32_t b) {
101+
return __riscv_cv_alu_adduRN(a, b, 0);
102+
}
103+
104+
// CHECK-LABEL: @test_alu_subN
105+
// CHECK: @llvm.riscv.cv.alu.subN
106+
int test_alu_subN(int32_t a, int32_t b) {
107+
return __riscv_cv_alu_subN(a, b, 0);
108+
}
109+
110+
// CHECK-LABEL: @test_alu_subuN
111+
// CHECK: @llvm.riscv.cv.alu.subuN
112+
int test_alu_subuN(uint32_t a, uint32_t b) {
113+
return __riscv_cv_alu_subuN(a, b, 0);
114+
}
115+
116+
// CHECK-LABEL: @test_alu_subRN
117+
// CHECK: @llvm.riscv.cv.alu.subRN
118+
int test_alu_subRN(int32_t a, int32_t b) {
119+
return __riscv_cv_alu_subRN(a, b, 0);
120+
}
121+
122+
// CHECK-LABEL: @test_alu_subuRN
123+
// CHECK: @llvm.riscv.cv.alu.subuRN
124+
int test_alu_subuRN(uint32_t a, uint32_t b) {
125+
return __riscv_cv_alu_subuRN(a, b, 0);
126+
}

0 commit comments

Comments
 (0)