Add a few ARM coprocessor intrinsics. Testcases included

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130763 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2011-05-03 17:29:22 +00:00
parent 6e97eced2f
commit 54ad87ab78
6 changed files with 147 additions and 0 deletions

View File

@ -49,6 +49,43 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
[IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
// Coprocessor
let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
// Move to coprocessor
def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
// Move from coprocessor
def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty], []>;
// Coprocessor data processing
def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
// Move from two registers to coprocessor
def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty], []>;
}
//===----------------------------------------------------------------------===//
// Advanced SIMD (NEON)

View File

@ -860,6 +860,9 @@ class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsARM];
}
class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsARM, HasV5T];
}
class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsARM, HasV5TE];
}
@ -1208,6 +1211,11 @@ class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsThumb, IsThumb1Only];
}
// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsThumb2, HasV6T2];
}
// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsThumb2];

View File

@ -3415,6 +3415,10 @@ def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
let Inst{23-20} = opc1;
}
def : ARMPat<(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
imm:$CRm, imm:$opc2),
(CDP imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, imm:$CRm,imm:$opc2)>;
def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
@ -3436,6 +3440,11 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
let Inst{23-20} = opc1;
}
def : ARMPat<(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
imm:$CRm, imm:$opc2),
(CDP2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, imm:$CRm,
imm:$opc2)>;
class ACI<dag oops, dag iops, string opc, string asm,
IndexMode im = IndexModeNone>
: InoP<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
@ -3572,6 +3581,12 @@ def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */,
(outs GPR:$Rt), (ins p_imm:$cop, i32imm:$opc1,
c_imm:$CRn, c_imm:$CRm, i32imm:$opc2)>;
def : ARMPat<(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2),
(MCR imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, imm:$CRm, imm:$opc2)>;
def : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
(MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
class MovRCopro2<string opc, bit direction, dag oops, dag iops>
: ABXI<0b1110, oops, iops, NoItinerary,
!strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
@ -3604,6 +3619,14 @@ def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */,
c_imm:$CRn, c_imm:$CRm,
i32imm:$opc2)>;
def : ARMV5TPat<(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2),
(MCR2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2)>;
def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn,
imm:$CRm, imm:$opc2),
(MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
class MovRRCopro<string opc, bit direction>
: ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
@ -3628,6 +3651,10 @@ class MovRRCopro<string opc, bit direction>
def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
def : ARMV5TEPat<(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2,
imm:$CRm),
(MCRR imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm)>;
class MovRRCopro2<string opc, bit direction>
: ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1,
GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
@ -3653,6 +3680,9 @@ class MovRRCopro2<string opc, bit direction>
def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */>;
def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
def : ARMV6Pat<(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm),
(MCRR2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm)>;
//===----------------------------------------------------------------------===//
// Move between special register and ARM core register -- for disassembly only
//

View File

@ -1381,6 +1381,14 @@ def tMRC : tMovRCopro<"mrc", 1 /* from coprocessor to ARM core register */,
(outs GPR:$Rt), (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn,
c_imm:$CRm, i32imm:$opc2)>;
def : Pat<(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2),
(tMCR imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2)>, Requires<[IsThumb, HasV6T2]>;
def : Pat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
(tMRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>,
Requires<[IsThumb, HasV6T2]>;
class tMovRRCopro<string opc, bit direction>
: T1Cop<(outs), (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
!strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
@ -1405,6 +1413,10 @@ class tMovRRCopro<string opc, bit direction>
def tMCRR : tMovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */>;
def tMRRC : tMovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>;
def : Pat<(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm),
(tMCRR imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm)>,
Requires<[IsThumb, HasV6T2]>;
//===----------------------------------------------------------------------===//
// Other Coprocessor Instructions. For disassembly only.
//
@ -1430,6 +1442,11 @@ def tCDP : T1Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
let Inst{23-20} = opc1;
}
def : Pat<(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
imm:$CRm, imm:$opc2),
(tCDP imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
imm:$CRm, imm:$opc2)>, Requires<[IsThumb, HasV6T2]>;
//===----------------------------------------------------------------------===//
// TLS Instructions
//

View File

@ -3376,6 +3376,14 @@ def t2MRC2 : t2MovRCopro<"mrc2", 1 /* from coprocessor to ARM core register */,
(outs GPR:$Rt), (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn,
c_imm:$CRm, i32imm:$opc2)>;
def : T2v6Pat<(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2),
(t2MCR2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
imm:$CRm, imm:$opc2)>;
def : T2v6Pat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn,
imm:$CRm, imm:$opc2),
(t2MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
class t2MovRRCopro<string opc, bit direction>
: T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
!strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"),
@ -3402,6 +3410,9 @@ def t2MCRR2 : t2MovRRCopro<"mcrr2",
def t2MRRC2 : t2MovRRCopro<"mrrc2",
1 /* from coprocessor to ARM core register */>;
def : T2v6Pat<(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm),
(t2MCRR2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm)>;
//===----------------------------------------------------------------------===//
// Other Coprocessor Instructions. For disassembly only.
//
@ -3427,3 +3438,8 @@ def t2CDP2 : T2Cop<(outs), (ins p_imm:$cop, i32imm:$opc1,
let Inst{19-16} = CRn;
let Inst{23-20} = opc1;
}
def : T2v6Pat<(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
imm:$CRm, imm:$opc2),
(t2CDP2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
imm:$CRm, imm:$opc2)>;

View File

@ -0,0 +1,39 @@
; RUN: llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 | FileCheck %s
; RUN: llc < %s -march=thumb -mtriple=thumbv7-eabi -mcpu=cortex-a8 | FileCheck %s
define void @coproc() nounwind {
entry:
; CHECK: mrc
%0 = tail call i32 @llvm.arm.mrc(i32 7, i32 1, i32 1, i32 1, i32 4) nounwind
; CHECK: mcr
tail call void @llvm.arm.mcr(i32 7, i32 1, i32 %0, i32 1, i32 1, i32 4) nounwind
; CHECK: mrc2
%1 = tail call i32 @llvm.arm.mrc2(i32 7, i32 1, i32 1, i32 1, i32 4) nounwind
; CHECK: mcr2
tail call void @llvm.arm.mcr2(i32 7, i32 1, i32 %1, i32 1, i32 1, i32 4) nounwind
; CHECK: mcrr
tail call void @llvm.arm.mcrr(i32 7, i32 1, i32 %0, i32 %1, i32 1) nounwind
; CHECK: mcrr2
tail call void @llvm.arm.mcrr2(i32 7, i32 1, i32 %0, i32 %1, i32 1) nounwind
; CHECK: cdp
tail call void @llvm.arm.cdp(i32 7, i32 3, i32 1, i32 1, i32 1, i32 5) nounwind
; CHECK: cdp2
tail call void @llvm.arm.cdp2(i32 7, i32 3, i32 1, i32 1, i32 1, i32 5) nounwind
ret void
}
declare void @llvm.arm.cdp2(i32, i32, i32, i32, i32, i32) nounwind
declare void @llvm.arm.cdp(i32, i32, i32, i32, i32, i32) nounwind
declare void @llvm.arm.mcrr2(i32, i32, i32, i32, i32) nounwind
declare void @llvm.arm.mcrr(i32, i32, i32, i32, i32) nounwind
declare void @llvm.arm.mcr2(i32, i32, i32, i32, i32, i32) nounwind
declare i32 @llvm.arm.mrc2(i32, i32, i32, i32, i32) nounwind
declare void @llvm.arm.mcr(i32, i32, i32, i32, i32, i32) nounwind
declare i32 @llvm.arm.mrc(i32, i32, i32, i32, i32) nounwind