X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/4be4e30906bcb8ee30b4d189205cb70bad6707ce..81345200c95645a1b0d2635520f96ad55dfde63f:/ftl/FTLOutput.cpp diff --git a/ftl/FTLOutput.cpp b/ftl/FTLOutput.cpp new file mode 100644 index 0000000..986d374 --- /dev/null +++ b/ftl/FTLOutput.cpp @@ -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) +