]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - ftl/FTLOutput.cpp
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / ftl / FTLOutput.cpp
diff --git a/ftl/FTLOutput.cpp b/ftl/FTLOutput.cpp
new file mode 100644 (file)
index 0000000..986d374
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLOutput.h"
+
+#if ENABLE(FTL_JIT)
+
+namespace JSC { namespace FTL {
+
+Output::Output(LContext context)
+    : IntrinsicRepository(context)
+    , m_function(0)
+    , m_heaps(0)
+    , m_builder(llvm->CreateBuilderInContext(m_context))
+    , m_block(0)
+    , m_nextBlock(0)
+{
+}
+
+Output::~Output()
+{
+    llvm->DisposeBuilder(m_builder);
+}
+
+void Output::initialize(LModule module, LValue function, AbstractHeapRepository& heaps)
+{
+    IntrinsicRepository::initialize(module);
+    m_function = function;
+    m_heaps = &heaps;
+}
+
+LBasicBlock Output::appendTo(LBasicBlock block, LBasicBlock nextBlock)
+{
+    appendTo(block);
+    return insertNewBlocksBefore(nextBlock);
+}
+
+void Output::appendTo(LBasicBlock block)
+{
+    m_block = block;
+    
+    llvm->PositionBuilderAtEnd(m_builder, block);
+}
+
+LBasicBlock Output::newBlock(const char* name)
+{
+    if (!m_nextBlock)
+        return appendBasicBlock(m_context, m_function, name);
+    return insertBasicBlock(m_context, m_nextBlock, name);
+}
+
+LValue Output::sensibleDoubleToInt(LValue value)
+{
+    RELEASE_ASSERT(isX86());
+    return call(
+        x86SSE2CvtTSD2SIIntrinsic(),
+        insertElement(
+            insertElement(getUndef(vectorType(doubleType, 2)), value, int32Zero),
+            doubleZero, int32One));
+}
+
+LValue Output::load(TypedPointer pointer, LType refType)
+{
+    LValue result = get(intToPtr(pointer.value(), refType));
+    pointer.heap().decorateInstruction(result, *m_heaps);
+    return result;
+}
+
+void Output::store(LValue value, TypedPointer pointer, LType refType)
+{
+    LValue result = set(value, intToPtr(pointer.value(), refType));
+    pointer.heap().decorateInstruction(result, *m_heaps);
+}
+
+LValue Output::baseIndex(LValue base, LValue index, Scale scale, ptrdiff_t offset)
+{
+    LValue accumulatedOffset;
+        
+    switch (scale) {
+    case ScaleOne:
+        accumulatedOffset = index;
+        break;
+    case ScaleTwo:
+        accumulatedOffset = shl(index, intPtrOne);
+        break;
+    case ScaleFour:
+        accumulatedOffset = shl(index, intPtrTwo);
+        break;
+    case ScaleEight:
+    case ScalePtr:
+        accumulatedOffset = shl(index, intPtrThree);
+        break;
+    }
+        
+    if (offset)
+        accumulatedOffset = add(accumulatedOffset, constIntPtr(offset));
+        
+    return add(base, accumulatedOffset);
+}
+
+void Output::branch(LValue condition, LBasicBlock taken, Weight takenWeight, LBasicBlock notTaken, Weight notTakenWeight)
+{
+    LValue branch = buildCondBr(m_builder, condition, taken, notTaken);
+    
+    if (!takenWeight || !notTakenWeight)
+        return;
+    
+    double total = takenWeight.value() + notTakenWeight.value();
+    
+    setMetadata(
+        branch, profKind,
+        mdNode(
+            m_context, branchWeights,
+            constInt32(takenWeight.scaleToTotal(total)),
+            constInt32(notTakenWeight.scaleToTotal(total))));
+}
+
+void Output::crashNonTerminal()
+{
+    call(intToPtr(constIntPtr(abort), pointerType(functionType(voidType))));
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+