FTL should use cvttsd2si directly for double-to-int32 conversions
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLAbbreviations.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef FTLAbbreviations_h
27 #define FTLAbbreviations_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(FTL_JIT)
32
33 #include "FTLAbbreviatedTypes.h"
34 #include "FTLSwitchCase.h"
35 #include "FTLValueFromBlock.h"
36 #include "LLVMAPI.h"
37 #include <cstring>
38
39 namespace JSC { namespace FTL {
40
41 // This file contains short-form calls into the LLVM C API. It is meant to
42 // save typing and make the lowering code clearer. If we ever call an LLVM C API
43 // function more than once in the FTL lowering code, we should add a shortcut for
44 // it here.
45
46 #if USE(JSVALUE32_64)
47 #error "The FTL backend assumes that pointers are 64-bit."
48 #endif
49
50 static inline LType voidType(LContext context) { return llvm->VoidTypeInContext(context); }
51 static inline LType int1Type(LContext context) { return llvm->Int1TypeInContext(context); }
52 static inline LType int8Type(LContext context) { return llvm->Int8TypeInContext(context); }
53 static inline LType int16Type(LContext context) { return llvm->Int16TypeInContext(context); }
54 static inline LType int32Type(LContext context) { return llvm->Int32TypeInContext(context); }
55 static inline LType int64Type(LContext context) { return llvm->Int64TypeInContext(context); }
56 static inline LType intPtrType(LContext context) { return llvm->Int64TypeInContext(context); }
57 static inline LType floatType(LContext context) { return llvm->FloatTypeInContext(context); }
58 static inline LType doubleType(LContext context) { return llvm->DoubleTypeInContext(context); }
59
60 static inline LType pointerType(LType type) { return llvm->PointerType(type, 0); }
61 static inline LType vectorType(LType type, unsigned count) { return llvm->VectorType(type, count); }
62
63 enum PackingMode { NotPacked, Packed };
64 static inline LType structType(LContext context, LType* elementTypes, unsigned elementCount, PackingMode packing = NotPacked)
65 {
66     return llvm->StructTypeInContext(context, elementTypes, elementCount, packing == Packed);
67 }
68 static inline LType structType(LContext context, PackingMode packing = NotPacked)
69 {
70     return structType(context, 0, 0, packing);
71 }
72 static inline LType structType(LContext context, LType element1, PackingMode packing = NotPacked)
73 {
74     return structType(context, &element1, 1, packing);
75 }
76 static inline LType structType(LContext context, LType element1, LType element2, PackingMode packing = NotPacked)
77 {
78     LType elements[] = { element1, element2 };
79     return structType(context, elements, 2, packing);
80 }
81
82 enum Variadicity { NotVariadic, Variadic };
83 static inline LType functionType(LType returnType, const LType* paramTypes, unsigned paramCount, Variadicity variadicity)
84 {
85     return llvm->FunctionType(returnType, const_cast<LType*>(paramTypes), paramCount, variadicity == Variadic);
86 }
87 template<typename VectorType>
88 inline LType functionType(LType returnType, const VectorType& vector, Variadicity variadicity = NotVariadic)
89 {
90     return functionType(returnType, vector.begin(), vector.size(), variadicity);
91 }
92 static inline LType functionType(LType returnType, Variadicity variadicity = NotVariadic)
93 {
94     return functionType(returnType, 0, 0, variadicity);
95 }
96 static inline LType functionType(LType returnType, LType param1, Variadicity variadicity = NotVariadic)
97 {
98     return functionType(returnType, &param1, 1, variadicity);
99 }
100 static inline LType functionType(LType returnType, LType param1, LType param2, Variadicity variadicity = NotVariadic)
101 {
102     LType paramTypes[] = { param1, param2 };
103     return functionType(returnType, paramTypes, 2, variadicity);
104 }
105 static inline LType functionType(LType returnType, LType param1, LType param2, LType param3, Variadicity variadicity = NotVariadic)
106 {
107     LType paramTypes[] = { param1, param2, param3 };
108     return functionType(returnType, paramTypes, 3, variadicity);
109 }
110 static inline LType functionType(LType returnType, LType param1, LType param2, LType param3, LType param4, Variadicity variadicity = NotVariadic)
111 {
112     LType paramTypes[] = { param1, param2, param3, param4 };
113     return functionType(returnType, paramTypes, 4, variadicity);
114 }
115
116 static inline LType typeOf(LValue value) { return llvm->TypeOf(value); }
117
118 static inline unsigned mdKindID(LContext context, const char* string) { return llvm->GetMDKindIDInContext(context, string, std::strlen(string)); }
119 static inline LValue mdString(LContext context, const char* string, unsigned length) { return llvm->MDStringInContext(context, string, length); }
120 static inline LValue mdString(LContext context, const char* string) { return mdString(context, string, std::strlen(string)); }
121 static inline LValue mdNode(LContext context, LValue* args, unsigned numArgs) { return llvm->MDNodeInContext(context, args, numArgs); }
122 static inline LValue mdNode(LContext context) { return mdNode(context, 0, 0); }
123 static inline LValue mdNode(LContext context, LValue arg1) { return mdNode(context, &arg1, 1); }
124 static inline LValue mdNode(LContext context, LValue arg1, LValue arg2)
125 {
126     LValue args[] = { arg1, arg2 };
127     return mdNode(context, args, 2);
128 }
129
130 static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { llvm->SetMetadata(instruction, kind, metadata); }
131
132 static inline LValue addFunction(LModule module, const char* name, LType type) { return llvm->AddFunction(module, name, type); }
133 static inline void setLinkage(LValue global, LLinkage linkage) { llvm->SetLinkage(global, linkage); }
134 static inline void setFunctionCallingConv(LValue function, LCallConv convention) { llvm->SetFunctionCallConv(function, convention); }
135
136 static inline LValue addExternFunction(LModule module, const char* name, LType type)
137 {
138     LValue result = addFunction(module, name, type);
139     setLinkage(result, LLVMExternalLinkage);
140     return result;
141 }
142
143 static inline LValue getParam(LValue function, unsigned index) { return llvm->GetParam(function, index); }
144 static inline LValue getUndef(LType type) { return llvm->GetUndef(type); }
145
146 enum BitExtension { ZeroExtend, SignExtend };
147 static inline LValue constInt(LType type, unsigned long long value, BitExtension extension = ZeroExtend) { return llvm->ConstInt(type, value, extension == SignExtend); }
148 static inline LValue constReal(LType type, double value) { return llvm->ConstReal(type, value); }
149 static inline LValue constIntToPtr(LValue value, LType type) { return llvm->ConstIntToPtr(value, type); }
150 static inline LValue constNull(LType type) { return llvm->ConstNull(type); }
151 static inline LValue constBitCast(LValue value, LType type) { return llvm->ConstBitCast(value, type); }
152
153 static inline LBasicBlock appendBasicBlock(LContext context, LValue function, const char* name = "") { return llvm->AppendBasicBlockInContext(context, function, name); }
154 static inline LBasicBlock insertBasicBlock(LContext context, LBasicBlock beforeBasicBlock, const char* name = "") { return llvm->InsertBasicBlockInContext(context, beforeBasicBlock, name); }
155
156 static inline LValue buildPhi(LBuilder builder, LType type) { return llvm->BuildPhi(builder, type, ""); }
157 static inline void addIncoming(LValue phi, const LValue* values, const LBasicBlock* blocks, unsigned numPredecessors)
158 {
159     llvm->AddIncoming(phi, const_cast<LValue*>(values), const_cast<LBasicBlock*>(blocks), numPredecessors);
160 }
161 static inline void addIncoming(LValue phi, ValueFromBlock value1)
162 {
163     LValue value = value1.value();
164     LBasicBlock block = value1.block();
165     addIncoming(phi, &value, &block, 1);
166 }
167 static inline void addIncoming(LValue phi, ValueFromBlock value1, ValueFromBlock value2)
168 {
169     LValue values[] = { value1.value(), value2.value() };
170     LBasicBlock blocks[] = { value1.block(), value2.block() };
171     addIncoming(phi, values, blocks, 2);
172 }
173 static inline LValue buildPhi(LBuilder builder, LType type, ValueFromBlock value1)
174 {
175     LValue result = buildPhi(builder, type);
176     addIncoming(result, value1);
177     return result;
178 }
179 static inline LValue buildPhi(
180     LBuilder builder, LType type, ValueFromBlock value1, ValueFromBlock value2)
181 {
182     LValue result = buildPhi(builder, type);
183     addIncoming(result, value1, value2);
184     return result;
185 }
186
187 static inline LValue buildAlloca(LBuilder builder, LType type) { return llvm->BuildAlloca(builder, type, ""); }
188 static inline LValue buildAdd(LBuilder builder, LValue left, LValue right) { return llvm->BuildAdd(builder, left, right, ""); }
189 static inline LValue buildSub(LBuilder builder, LValue left, LValue right) { return llvm->BuildSub(builder, left, right, ""); }
190 static inline LValue buildMul(LBuilder builder, LValue left, LValue right) { return llvm->BuildMul(builder, left, right, ""); }
191 static inline LValue buildDiv(LBuilder builder, LValue left, LValue right) { return llvm->BuildSDiv(builder, left, right, ""); }
192 static inline LValue buildRem(LBuilder builder, LValue left, LValue right) { return llvm->BuildSRem(builder, left, right, ""); }
193 static inline LValue buildNeg(LBuilder builder, LValue value) { return llvm->BuildNeg(builder, value, ""); }
194 static inline LValue buildFAdd(LBuilder builder, LValue left, LValue right) { return llvm->BuildFAdd(builder, left, right, ""); }
195 static inline LValue buildFSub(LBuilder builder, LValue left, LValue right) { return llvm->BuildFSub(builder, left, right, ""); }
196 static inline LValue buildFMul(LBuilder builder, LValue left, LValue right) { return llvm->BuildFMul(builder, left, right, ""); }
197 static inline LValue buildFDiv(LBuilder builder, LValue left, LValue right) { return llvm->BuildFDiv(builder, left, right, ""); }
198 static inline LValue buildFRem(LBuilder builder, LValue left, LValue right) { return llvm->BuildFRem(builder, left, right, ""); }
199 static inline LValue buildFNeg(LBuilder builder, LValue value) { return llvm->BuildFNeg(builder, value, ""); }
200 static inline LValue buildAnd(LBuilder builder, LValue left, LValue right) { return llvm->BuildAnd(builder, left, right, ""); }
201 static inline LValue buildOr(LBuilder builder, LValue left, LValue right) { return llvm->BuildOr(builder, left, right, ""); }
202 static inline LValue buildXor(LBuilder builder, LValue left, LValue right) { return llvm->BuildXor(builder, left, right, ""); }
203 static inline LValue buildShl(LBuilder builder, LValue left, LValue right) { return llvm->BuildShl(builder, left, right, ""); }
204 static inline LValue buildAShr(LBuilder builder, LValue left, LValue right) { return llvm->BuildAShr(builder, left, right, ""); }
205 static inline LValue buildLShr(LBuilder builder, LValue left, LValue right) { return llvm->BuildLShr(builder, left, right, ""); }
206 static inline LValue buildNot(LBuilder builder, LValue value) { return llvm->BuildNot(builder, value, ""); }
207 static inline LValue buildLoad(LBuilder builder, LValue pointer) { return llvm->BuildLoad(builder, pointer, ""); }
208 static inline LValue buildStore(LBuilder builder, LValue value, LValue pointer) { return llvm->BuildStore(builder, value, pointer); }
209 static inline LValue buildSExt(LBuilder builder, LValue value, LType type) { return llvm->BuildSExt(builder, value, type, ""); }
210 static inline LValue buildZExt(LBuilder builder, LValue value, LType type) { return llvm->BuildZExt(builder, value, type, ""); }
211 static inline LValue buildFPToSI(LBuilder builder, LValue value, LType type) { return llvm->BuildFPToSI(builder, value, type, ""); }
212 static inline LValue buildFPToUI(LBuilder builder, LValue value, LType type) { return llvm->BuildFPToUI(builder, value, type, ""); }
213 static inline LValue buildSIToFP(LBuilder builder, LValue value, LType type) { return llvm->BuildSIToFP(builder, value, type, ""); }
214 static inline LValue buildUIToFP(LBuilder builder, LValue value, LType type) { return llvm->BuildUIToFP(builder, value, type, ""); }
215 static inline LValue buildIntCast(LBuilder builder, LValue value, LType type) { return llvm->BuildIntCast(builder, value, type, ""); }
216 static inline LValue buildFPCast(LBuilder builder, LValue value, LType type) { return llvm->BuildFPCast(builder, value, type, ""); }
217 static inline LValue buildIntToPtr(LBuilder builder, LValue value, LType type) { return llvm->BuildIntToPtr(builder, value, type, ""); }
218 static inline LValue buildPtrToInt(LBuilder builder, LValue value, LType type) { return llvm->BuildPtrToInt(builder, value, type, ""); }
219 static inline LValue buildBitCast(LBuilder builder, LValue value, LType type) { return llvm->BuildBitCast(builder, value, type, ""); }
220 static inline LValue buildICmp(LBuilder builder, LIntPredicate cond, LValue left, LValue right) { return llvm->BuildICmp(builder, cond, left, right, ""); }
221 static inline LValue buildFCmp(LBuilder builder, LRealPredicate cond, LValue left, LValue right) { return llvm->BuildFCmp(builder, cond, left, right, ""); }
222 static inline LValue buildInsertElement(LBuilder builder, LValue vector, LValue element, LValue index) { return llvm->BuildInsertElement(builder, vector, element, index, ""); }
223
224 enum SynchronizationScope { SingleThread, CrossThread };
225 static inline LValue buildFence(LBuilder builder, LAtomicOrdering ordering, SynchronizationScope scope = CrossThread)
226 {
227     return llvm->BuildFence(builder, ordering, scope == SingleThread, "");
228 }
229
230 static inline LValue buildCall(LBuilder builder, LValue function, const LValue* args, unsigned numArgs)
231 {
232     return llvm->BuildCall(builder, function, const_cast<LValue*>(args), numArgs, "");
233 }
234 template<typename VectorType>
235 inline LValue buildCall(LBuilder builder, LValue function, const VectorType& vector)
236 {
237     return buildCall(builder, function, vector.begin(), vector.size());
238 }
239 static inline LValue buildCall(LBuilder builder, LValue function)
240 {
241     return buildCall(builder, function, 0, 0);
242 }
243 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1)
244 {
245     return buildCall(builder, function, &arg1, 1);
246 }
247 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2)
248 {
249     LValue args[] = { arg1, arg2 };
250     return buildCall(builder, function, args, 2);
251 }
252 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3)
253 {
254     LValue args[] = { arg1, arg2, arg3 };
255     return buildCall(builder, function, args, 3);
256 }
257 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4)
258 {
259     LValue args[] = { arg1, arg2, arg3, arg4 };
260     return buildCall(builder, function, args, 4);
261 }
262 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5)
263 {
264     LValue args[] = { arg1, arg2, arg3, arg4, arg5 };
265     return buildCall(builder, function, args, 5);
266 }
267 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6)
268 {
269     LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
270     return buildCall(builder, function, args, 6);
271 }
272 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7)
273 {
274     LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
275     return buildCall(builder, function, args, 7);
276 }
277 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8)
278 {
279     LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
280     return buildCall(builder, function, args, 8);
281 }
282 static inline void setInstructionCallingConvention(LValue instruction, LCallConv callingConvention) { llvm->SetInstructionCallConv(instruction, callingConvention); }
283 static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return llvm->BuildExtractValue(builder, aggVal, index, ""); }
284 static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return llvm->BuildSelect(builder, condition, taken, notTaken, ""); }
285 static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return llvm->BuildBr(builder, destination); }
286 static inline LValue buildCondBr(LBuilder builder, LValue condition, LBasicBlock taken, LBasicBlock notTaken) { return llvm->BuildCondBr(builder, condition, taken, notTaken); }
287 static inline LValue buildSwitch(LBuilder builder, LValue value, LBasicBlock fallThrough, unsigned numCases) { return llvm->BuildSwitch(builder, value, fallThrough, numCases); }
288 static inline void addCase(LValue switchInst, LValue value, LBasicBlock target) { llvm->AddCase(switchInst, value, target); }
289 template<typename VectorType>
290 static inline LValue buildSwitch(LBuilder builder, LValue value, const VectorType& cases, LBasicBlock fallThrough)
291 {
292     LValue result = buildSwitch(builder, value, fallThrough, cases.size());
293     for (unsigned i = 0; i < cases.size(); ++i)
294         addCase(result, cases[i].value(), cases[i].target());
295     return result;
296 }
297 static inline LValue buildRet(LBuilder builder, LValue value) { return llvm->BuildRet(builder, value); }
298 static inline LValue buildUnreachable(LBuilder builder) { return llvm->BuildUnreachable(builder); }
299
300 static inline void dumpModule(LModule module) { llvm->DumpModule(module); }
301 static inline void verifyModule(LModule module)
302 {
303     char* error = 0;
304     llvm->VerifyModule(module, LLVMAbortProcessAction, &error);
305     llvm->DisposeMessage(error);
306 }
307
308 } } // namespace JSC::FTL
309
310 #endif // ENABLE(FTL_JIT)
311
312 #endif // FTLAbbreviations_h
313