From: Ranjeet Singh Date: Wed, 15 Jun 2016 11:32:18 +0000 (+0000) Subject: [ARM] Add mrrc/mrrc2 intrinsics and update existing mcrr/mcrr2 intrinsics. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c39587a0d1be59acd8ea9c813946e3b73f5c8887;p=clang [ARM] Add mrrc/mrrc2 intrinsics and update existing mcrr/mcrr2 intrinsics. Patch adds intrinsics for mrrc/mrrc2. The intrinsics for mrrc/mrrc2 return a single uint64_t to represent two 32 bit values. The mcrr/mcrr2 intrinsic was changed to accept a single uint64_t instead of two 32 bit values as the input for consistency. Differential Revision: http://reviews.llvm.org/D21179 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272777 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index 4174c826dd..1fa9794ca9 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -58,14 +58,16 @@ BUILTIN(__builtin_arm_stcl, "vUIiUIiv*", "") BUILTIN(__builtin_arm_stc2, "vUIiUIiv*", "") BUILTIN(__builtin_arm_stc2l, "vUIiUIiv*", "") +BUILTIN(__builtin_arm_cdp, "vUIiUIiUIiUIiUIiUIi", "") +BUILTIN(__builtin_arm_cdp2, "vUIiUIiUIiUIiUIiUIi", "") BUILTIN(__builtin_arm_mcr, "vUIiUIiUiUIiUIiUIi", "") BUILTIN(__builtin_arm_mcr2, "vUIiUIiUiUIiUIiUIi", "") BUILTIN(__builtin_arm_mrc, "UiUIiUIiUIiUIiUIi", "") BUILTIN(__builtin_arm_mrc2, "UiUIiUIiUIiUIiUIi", "") -BUILTIN(__builtin_arm_cdp, "vUIiUIiUIiUIiUIiUIi", "") -BUILTIN(__builtin_arm_cdp2, "vUIiUIiUIiUIiUIiUIi", "") -BUILTIN(__builtin_arm_mcrr, "vUIiUIiUiUiUIi", "") -BUILTIN(__builtin_arm_mcrr2, "vUIiUIiUiUiUIi", "") +BUILTIN(__builtin_arm_mcrr, "vUIiUIiLLUiUIi", "") +BUILTIN(__builtin_arm_mcrr2, "vUIiUIiLLUiUIi", "") +BUILTIN(__builtin_arm_mrrc, "LLUiUIiUIiUIi", "") +BUILTIN(__builtin_arm_mrrc2, "LLUiUIiUIiUIi", "") // CRC32 BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc") diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index fb5cdd5819..298707874f 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -3793,6 +3793,74 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); } + if (BuiltinID == ARM::BI__builtin_arm_mcrr || + BuiltinID == ARM::BI__builtin_arm_mcrr2) { + Function *F; + + switch (BuiltinID) { + default: llvm_unreachable("unexpected builtin"); + case ARM::BI__builtin_arm_mcrr: + F = CGM.getIntrinsic(Intrinsic::arm_mcrr); + break; + case ARM::BI__builtin_arm_mcrr2: + F = CGM.getIntrinsic(Intrinsic::arm_mcrr2); + break; + } + + // MCRR{2} instruction has 5 operands but + // the intrinsic has 4 because Rt and Rt2 + // are represented as a single unsigned 64 + // bit integer in the intrinsic definition + // but internally it's represented as 2 32 + // bit integers. + + Value *Coproc = EmitScalarExpr(E->getArg(0)); + Value *Opc1 = EmitScalarExpr(E->getArg(1)); + Value *RtAndRt2 = EmitScalarExpr(E->getArg(2)); + Value *CRm = EmitScalarExpr(E->getArg(3)); + + Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); + Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty); + Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1); + Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty); + + return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm}); + } + + if (BuiltinID == ARM::BI__builtin_arm_mrrc || + BuiltinID == ARM::BI__builtin_arm_mrrc2) { + Function *F; + + switch (BuiltinID) { + default: llvm_unreachable("unexpected builtin"); + case ARM::BI__builtin_arm_mrrc: + F = CGM.getIntrinsic(Intrinsic::arm_mrrc); + break; + case ARM::BI__builtin_arm_mrrc2: + F = CGM.getIntrinsic(Intrinsic::arm_mrrc2); + break; + } + + Value *Coproc = EmitScalarExpr(E->getArg(0)); + Value *Opc1 = EmitScalarExpr(E->getArg(1)); + Value *CRm = EmitScalarExpr(E->getArg(2)); + Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm}); + + // Returns an unsigned 64 bit integer, represented + // as two 32 bit integers. + + Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1); + Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0); + Rt = Builder.CreateZExt(Rt, Int64Ty); + Rt1 = Builder.CreateZExt(Rt1, Int64Ty); + + Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32); + RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true); + RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1); + + return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType())); + } + if (BuiltinID == ARM::BI__builtin_arm_ldrexd || ((BuiltinID == ARM::BI__builtin_arm_ldrex || BuiltinID == ARM::BI__builtin_arm_ldaex) && diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c index df53b9f4cf..a385bd2754 100644 --- a/test/CodeGen/builtins-arm.c +++ b/test/CodeGen/builtins-arm.c @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -Wall -Werror -triple thumbv7-eabi -target-cpu cortex-a8 -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +#include + void *f0() { return __builtin_thread_pointer(); @@ -180,16 +182,28 @@ void mcr2(unsigned a) { __builtin_arm_mcr2(15, 0, a, 13, 0, 3); } -void mcrr(unsigned a, unsigned b) { - // CHECK: define void @mcrr(i32 [[A:%.*]], i32 [[B:%.*]]) - // CHECK: call void @llvm.arm.mcrr(i32 15, i32 0, i32 [[A]], i32 [[B]], i32 0) - __builtin_arm_mcrr(15, 0, a, b, 0); +void mcrr(uint64_t a) { + // CHECK: define void @mcrr(i64 %{{.*}}) + // CHECK: call void @llvm.arm.mcrr(i32 15, i32 0, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 0) + __builtin_arm_mcrr(15, 0, a, 0); +} + +void mcrr2(uint64_t a) { + // CHECK: define void @mcrr2(i64 %{{.*}}) + // CHECK: call void @llvm.arm.mcrr2(i32 15, i32 0, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 0) + __builtin_arm_mcrr2(15, 0, a, 0); +} + +uint64_t mrrc() { + // CHECK: define i64 @mrrc() + // CHECK: call { i32, i32 } @llvm.arm.mrrc(i32 15, i32 0, i32 0) + return __builtin_arm_mrrc(15, 0, 0); } -void mcrr2(unsigned a, unsigned b) { - // CHECK: define void @mcrr2(i32 [[A:%.*]], i32 [[B:%.*]]) - // CHECK: call void @llvm.arm.mcrr2(i32 15, i32 0, i32 [[A]], i32 [[B]], i32 0) - __builtin_arm_mcrr2(15, 0, a, b, 0); +uint64_t mrrc2() { + // CHECK: define i64 @mrrc2() + // CHECK: call { i32, i32 } @llvm.arm.mrrc2(i32 15, i32 0, i32 0) + return __builtin_arm_mrrc2(15, 0, 0); } unsigned rsr() { diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c index 8a6d71773f..668b8284ff 100644 --- a/test/Sema/builtins-arm.c +++ b/test/Sema/builtins-arm.c @@ -116,11 +116,23 @@ void test6(int a, int b, int c) { __builtin_arm_mcr2(15, 0, b, 13, a, 3); // expected-error {{argument to '__builtin_arm_mcr2' must be a constant integer}} __builtin_arm_mcr2(15, 0, b, 13, 0, a); // expected-error {{argument to '__builtin_arm_mcr2' must be a constant integer}} - __builtin_arm_mcrr( a, 0, b, c, 0); // expected-error {{argument to '__builtin_arm_mcrr' must be a constant integer}} - __builtin_arm_mcrr(15, a, b, c, 0); // expected-error {{argument to '__builtin_arm_mcrr' must be a constant integer}} - __builtin_arm_mcrr(15, 0, b, c, a); // expected-error {{argument to '__builtin_arm_mcrr' must be a constant integer}} - - __builtin_arm_mcrr2( a, 0, b, c, 0); // expected-error {{argument to '__builtin_arm_mcrr2' must be a constant integer}} - __builtin_arm_mcrr2(15, a, b, c, 0); // expected-error {{argument to '__builtin_arm_mcrr2' must be a constant integer}} - __builtin_arm_mcrr2(15, 0, b, c, a); // expected-error {{argument to '__builtin_arm_mcrr2' must be a constant integer}} + __builtin_arm_mcrr(15, 0, b, 0); + __builtin_arm_mcrr( a, 0, b, 0); // expected-error {{argument to '__builtin_arm_mcrr' must be a constant integer}} + __builtin_arm_mcrr(15, a, b, 0); // expected-error {{argument to '__builtin_arm_mcrr' must be a constant integer}} + __builtin_arm_mcrr(15, 0, b, a); // expected-error {{argument to '__builtin_arm_mcrr' must be a constant integer}} + + __builtin_arm_mcrr2(15, 0, b, 0); + __builtin_arm_mcrr2( a, 0, b, 0); // expected-error {{argument to '__builtin_arm_mcrr2' must be a constant integer}} + __builtin_arm_mcrr2(15, a, b, 0); // expected-error {{argument to '__builtin_arm_mcrr2' must be a constant integer}} + __builtin_arm_mcrr2(15, 0, b, a); // expected-error {{argument to '__builtin_arm_mcrr2' must be a constant integer}} + + __builtin_arm_mrrc(15, 0, 0); + __builtin_arm_mrrc( a, 0, 0); // expected-error {{argument to '__builtin_arm_mrrc' must be a constant integer}} + __builtin_arm_mrrc(15, a, 0); // expected-error {{argument to '__builtin_arm_mrrc' must be a constant integer}} + __builtin_arm_mrrc(15, 0, a); // expected-error {{argument to '__builtin_arm_mrrc' must be a constant integer}} + + __builtin_arm_mrrc2(15, 0, 0); + __builtin_arm_mrrc2( a, 0, 0); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}} + __builtin_arm_mrrc2(15, a, 0); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}} + __builtin_arm_mrrc2(15, 0, a); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}} }