From 23ad8d18481d86048c6291541514ab425bd6fecf Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 2 Aug 2009 18:28:11 +0000 Subject: [PATCH] Add some basic blackfin intrinsics. llvm-svn: 77903 --- include/llvm/Intrinsics.td | 1 + include/llvm/IntrinsicsBlackfin.td | 51 ++++++++++++++++++++++++ lib/Target/Blackfin/BlackfinInstrInfo.td | 43 +++++++++++++++++++- test/CodeGen/Blackfin/load-intr.ll | 16 ++++++++ test/CodeGen/Blackfin/sync-intr.ll | 13 ++++++ 5 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 include/llvm/IntrinsicsBlackfin.td create mode 100644 test/CodeGen/Blackfin/load-intr.ll create mode 100644 test/CodeGen/Blackfin/sync-intr.ll diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 6d0a563b3e0..fa21dc0682b 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -458,3 +458,4 @@ include "llvm/IntrinsicsARM.td" include "llvm/IntrinsicsCellSPU.td" include "llvm/IntrinsicsAlpha.td" include "llvm/IntrinsicsXCore.td" +include "llvm/IntrinsicsBlackfin.td" diff --git a/include/llvm/IntrinsicsBlackfin.td b/include/llvm/IntrinsicsBlackfin.td new file mode 100644 index 00000000000..3a4052b6b85 --- /dev/null +++ b/include/llvm/IntrinsicsBlackfin.td @@ -0,0 +1,51 @@ +//===- IntrinsicsBlackfin.td - Defines Blackfin intrinsics -*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines all of the blackfin-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Core synchronisation etc. +// +// These intrinsics have sideeffects. Each represent a single instruction, but +// workarounds are sometimes required depending on the cpu. + +let TargetPrefix = "bfin" in { + + // Execute csync instruction with workarounds + def int_bfin_csync : GCCBuiltin<"__builtin_bfin_csync">, + Intrinsic<[llvm_void_ty]>; + + // Execute ssync instruction with workarounds + def int_bfin_ssync : GCCBuiltin<"__builtin_bfin_ssync">, + Intrinsic<[llvm_void_ty]>; + + // Execute idle instruction with workarounds + def int_bfin_idle : GCCBuiltin<"__builtin_bfin_idle">, + Intrinsic<[llvm_void_ty]>; + +} + +//===----------------------------------------------------------------------===// +// Miscellaneous GCC-compatible builtins. +// + +let TargetPrefix = "bfin" in { + + // Almost identical to ctpop except for the type signature + def int_bfin_ones : GCCBuiltin<"__builtin_bfin_ones">, + Intrinsic<[llvm_i16_ty], [llvm_i32_ty], [IntrNoMem]>; + + // Load unaligned pointer, ignoring the low bits. Like *(p&~3). + // This uses the disalignexcpt instruction + def int_bfin_loadbytes : GCCBuiltin<"__builtin_bfin_loadbytes">, + Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; + +} diff --git a/lib/Target/Blackfin/BlackfinInstrInfo.td b/lib/Target/Blackfin/BlackfinInstrInfo.td index a6653517c9d..6faec271439 100644 --- a/lib/Target/Blackfin/BlackfinInstrInfo.td +++ b/lib/Target/Blackfin/BlackfinInstrInfo.td @@ -672,8 +672,9 @@ def NBITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2), def ONES: F2<(outs D16L:$dst), (ins D:$src), "$dst = ones $src;", - [(set D16L:$dst, (trunc (ctpop D:$src)))]>; + [(set D16L:$dst, (int_bfin_ones D:$src))]>; +def : Pat<(i16 (trunc (ctpop D:$src))), (ONES D:$src)>; def : Pat<(ctpop D:$src), (MOVEzext (ONES D:$src))>; //===----------------------------------------------------------------------===// @@ -810,11 +811,51 @@ def MUL32: F1<(outs D:$dst), (ins D:$src1, D:$src2), // Table C-18. External Exent Management Instructions //===----------------------------------------------------------------------===// +def IDLE : F1<(outs), (ins), "idle;", [(int_bfin_idle)]>; +def CSYNC : F1<(outs), (ins), "csync;", [(int_bfin_csync)]>; +def SSYNC : F1<(outs), (ins), "ssync;", [(int_bfin_ssync)]>; +def EMUEXCPT : F1<(outs), (ins), "emuexcpt;", []>; +def CLI : F1<(outs D:$mask), (ins), "cli $mask;", []>; +def STI : F1<(outs), (ins D:$mask), "sti $mask;", []>; +def RAISE : F1<(outs), (ins i32imm:$itr), "raise $itr;", []>; +def EXCPT : F1<(outs), (ins i32imm:$exc), "excpt $exc;", []>; +def NOP : F1<(outs), (ins), "nop;", []>; +def MNOP : F2<(outs), (ins), "mnop;", []>; +def ABORT : F1<(outs), (ins), "abort;", []>; + //===----------------------------------------------------------------------===// // Table C-19. Cache Control Instructions //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Table C-20. Video Pixel Operations Instructions +//===----------------------------------------------------------------------===// + +def ALIGN8 : F2<(outs D:$dst), (ins D:$src1, D:$src2), + "$dst = align8($src1, $src2);", + [(set D:$dst, (or (shl D:$src1, (i32 24)), + (srl D:$src2, (i32 8))))]>; + +def ALIGN16 : F2<(outs D:$dst), (ins D:$src1, D:$src2), + "$dst = align16($src1, $src2);", + [(set D:$dst, (or (shl D:$src1, (i32 16)), + (srl D:$src2, (i32 16))))]>; + +def ALIGN24 : F2<(outs D:$dst), (ins D:$src1, D:$src2), + "$dst = align16($src1, $src2);", + [(set D:$dst, (or (shl D:$src1, (i32 8)), + (srl D:$src2, (i32 24))))]>; + +def DISALGNEXCPT : F2<(outs), (ins), "disalignexcpt;", []>; + +// This is really two instructions in parallel, but we don't support vliw yet +def DISALGNEXCPT_LOAD : F2<(outs D:$dst), (ins I:$ptr), + "disalignexcpt \\|\\| $dst = [$ptr];", + [(set D:$dst, (int_bfin_loadbytes I:$ptr))]>; + +// TODO: BYTEOP3P, BYTEOP16P, BYTEOP1P, BYTEOP2P, BYTEOP16M, SAA, +// BYTEPACK, BYTEUNPACK + // Table C-21. Vector Operations Instructions // Patterns diff --git a/test/CodeGen/Blackfin/load-intr.ll b/test/CodeGen/Blackfin/load-intr.ll new file mode 100644 index 00000000000..9d742370228 --- /dev/null +++ b/test/CodeGen/Blackfin/load-intr.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=bfin -verify-machineinstrs | FileCheck %s +; XFAIL: * +; Assertion failed: (isUsed(Reg) && "Using an undefined register!"), +; function forward, file lib/CodeGen/RegisterScavenging.cpp, line 221. + +define i16 @f(i32* %p) nounwind { +entry: + ; CHECK: disalignexcpt || r0 = [i0]; + %b = call i32 @llvm.bfin.loadbytes(i32* %p) + ; CHECK: r0.l = ones r0; + %c = call i16 @llvm.bfin.ones(i32 %b) + ret i16 %c +} + +declare void @llvm.bfin.ones() nounwind +declare void @llvm.bfin.loadbytes() nounwind diff --git a/test/CodeGen/Blackfin/sync-intr.ll b/test/CodeGen/Blackfin/sync-intr.ll new file mode 100644 index 00000000000..8fa5c5f9e88 --- /dev/null +++ b/test/CodeGen/Blackfin/sync-intr.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -march=bfin -verify-machineinstrs | FileCheck %s + +define void @f() nounwind { +entry: + ; CHECK: csync; + call void @llvm.bfin.csync() + ; CHECK: ssync; + call void @llvm.bfin.ssync() + ret void +} + +declare void @llvm.bfin.csync() nounwind +declare void @llvm.bfin.ssync() nounwind