llvm.org GIT mirror llvm / 6fb3bd6
Add bswap intrinsics as documented in the Language Reference git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25309 91177308-0d34-0410-b5e6-96231b3b80d8 Nate Begeman 13 years ago
8 changed file(s) with 114 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
5757 dbg_func_start, // Start of a function
5858 dbg_declare, // Declare a local object
5959
60
61 // Standard libc functions.
60 // Standard C library intrinsics.
6261 memcpy, // Copy non-overlapping memory blocks
6362 memmove, // Copy potentially overlapping memory blocks
6463 memset, // Fill memory with a byte value
64 isunordered, // Return true if either argument is a NaN
65 sqrt, // Square root
6566
66 // libm related functions.
67 isunordered, // Return true if either argument is a NaN
68 ctpop, //count population
69 ctlz, //count leading zeros
70 cttz, //count trailing zeros
71 sqrt, //square root
72
67 // Bit manipulation instrinsics.
68 bswap_i16, // Byteswap 16 bits
69 bswap_i32, // Byteswap 32 bits
70 bswap_i64, // Byteswap 64 bits
71 ctpop, // Count population
72 ctlz, // Count leading zeros
73 cttz, // Count trailing zeros
74
7375 // Input/Output intrinsics.
7476 readport,
7577 writeport,
7676 // > 0 (64 bit edition.)
7777 inline bool isPowerOf2_64(uint64_t Value) {
7878 return Value && !(Value & (Value - 1LL));
79 }
80
81 // ByteSwap_16 - This function returns a byte-swapped representation of the
82 // 16-bit argument, Value.
83 inline unsigned short ByteSwap_16(unsigned short Value) {
84 unsigned short Hi = Value << 8;
85 unsigned short Lo = Value >> 8;
86 return Hi | Lo;
87 }
88
89 // ByteSwap_32 - This function returns a byte-swapped representation of the
90 // 32-bit argument, Value.
91 inline unsigned ByteSwap_32(unsigned Value) {
92 unsigned Byte0 = Value & 0x000000FF;
93 unsigned Byte1 = Value & 0x0000FF00;
94 unsigned Byte2 = Value & 0x00FF0000;
95 unsigned Byte3 = Value & 0xFF000000;
96 return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
97 }
98
99 // ByteSwap_64 - This function returns a byte-swapped representation of the
100 // 64-bit argument, Value.
101 inline uint64_t ByteSwap_64(uint64_t Value) {
102 uint64_t Hi = ByteSwap_32(Value);
103 uint64_t Lo = ByteSwap_32(Value >> 32);
104 return (Hi << 32) | Lo;
79105 }
80106
81107 // CountLeadingZeros_32 - this function performs the platform optimal form of
707707 static const char *DoesntAccessMemoryTable[] = {
708708 // LLVM intrinsics:
709709 "llvm.frameaddress", "llvm.returnaddress", "llvm.readport",
710 "llvm.isunordered", "llvm.sqrt", "llvm.ctpop", "llvm.ctlz", "llvm.cttz",
710 "llvm.isunordered", "llvm.sqrt", "llvm.bswap.i16", "llvm.bswap.i32",
711 "llvm.bswap.i64", "llvm.ctpop", "llvm.ctlz", "llvm.cttz",
711712
712713 "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl",
713714 "trunc", "truncf", "truncl", "ldexp",
3636 switch (F->getIntrinsicID()) {
3737 case Intrinsic::isunordered:
3838 case Intrinsic::sqrt:
39 case Intrinsic::bswap_i16:
40 case Intrinsic::bswap_i32:
41 case Intrinsic::bswap_i64:
42 // FIXME: these should be constant folded as well
43 //case Intrinsic::ctpop:
44 //case Intrinsic::ctlz:
45 //case Intrinsic::cttz:
3946 return true;
4047 default: break;
4148 }
141148 default:
142149 break;
143150 }
151 } else if (ConstantUInt *Op = dyn_cast(Operands[0])) {
152 uint64_t V = Op->getValue();
153 if (Name == "llvm.bswap.i16")
154 return ConstantUInt::get(Ty, ByteSwap_16(V));
155 else if (Name == "llvm.bswap.i32")
156 return ConstantUInt::get(Ty, ByteSwap_32(V));
157 else if (Name == "llvm.bswap.i64")
158 return ConstantUInt::get(Ty, ByteSwap_64(V));
144159 }
145160 } else if (Operands.size() == 2) {
146161 if (ConstantFP *Op1 = dyn_cast(Operands[0])) {
297297 case Intrinsic::frameaddress:
298298 case Intrinsic::stacksave:
299299 case Intrinsic::isunordered:
300 case Intrinsic::bswap_i16:
301 case Intrinsic::bswap_i32:
302 case Intrinsic::bswap_i64:
300303 case Intrinsic::ctpop:
301304 case Intrinsic::ctlz:
302305 case Intrinsic::cttz:
206206 assert(getName().size() != 5 && "'llvm.' is an invalid intrinsic name!");
207207
208208 switch (getName()[5]) {
209 case 'b':
210 if (getName() == "llvm.bswap.i16") return Intrinsic::bswap_i16;
211 if (getName() == "llvm.bswap.i32") return Intrinsic::bswap_i32;
212 if (getName() == "llvm.bswap.i64") return Intrinsic::bswap_i64;
213 break;
209214 case 'c':
210215 if (getName() == "llvm.ctpop") return Intrinsic::ctpop;
211216 if (getName() == "llvm.cttz") return Intrinsic::cttz;
748748 NumArgs = 0;
749749 break;
750750
751 case Intrinsic::bswap_i16:
752 Assert1(FT->getNumParams() == 1,
753 "Illegal # arguments for intrinsic function!", IF);
754 Assert1(FT->getReturnType() == FT->getParamType(0),
755 "Return type does not match source type", IF);
756 Assert1(FT->getReturnType() == Type::UShortTy,
757 "Return type is not ushort!", IF);
758 NumArgs = 1;
759 break;
760
761 case Intrinsic::bswap_i32:
762 Assert1(FT->getNumParams() == 1,
763 "Illegal # arguments for intrinsic function!", IF);
764 Assert1(FT->getReturnType() == FT->getParamType(0),
765 "Return type does not match source type", IF);
766 Assert1(FT->getReturnType() == Type::UIntTy,
767 "Return type is not uint!", IF);
768 NumArgs = 1;
769 break;
770
771 case Intrinsic::bswap_i64:
772 Assert1(FT->getNumParams() == 1,
773 "Illegal # arguments for intrinsic function!", IF);
774 Assert1(FT->getReturnType() == FT->getParamType(0),
775 "Return type does not match source type", IF);
776 Assert1(FT->getReturnType() == Type::ULongTy,
777 "Return type is not ulong!", IF);
778 NumArgs = 1;
779 break;
780
751781 case Intrinsic::ctpop:
752782 case Intrinsic::ctlz:
753783 case Intrinsic::cttz:
0 ; bswap should be constant folded when it is passed a constant argument
1
2 ; RUN: llvm-as < %s | opt -constprop | llvm-dis | not grep call
3
4 declare ushort %llvm.bswap.i16(ushort)
5 declare uint %llvm.bswap.i32(uint)
6 declare ulong %llvm.bswap.i64(ulong)
7
8 ushort %W() {
9 %Z = call ushort %llvm.bswap.i16(ushort 1)
10 ret ushort %Z
11 }
12
13 uint %X() {
14 %Z = call uint %llvm.bswap.i32(uint 1)
15 ret uint %Z
16 }
17
18 ulong %Y() {
19 %Z = call ulong %llvm.bswap.i64(ulong 1)
20 ret ulong %Z
21 }