--- /dev/null
+/*
+ * Copyright (C) 2013, 2014 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 "FTLLocation.h"
+
+#if ENABLE(FTL_JIT)
+
+#include "FTLSaveRestore.h"
+#include "RegisterSet.h"
+#include <wtf/CommaPrinter.h>
+#include <wtf/DataLog.h>
+#include <wtf/ListDump.h>
+
+namespace JSC { namespace FTL {
+
+Location Location::forStackmaps(const StackMaps* stackmaps, const StackMaps::Location& location)
+{
+ switch (location.kind) {
+ case StackMaps::Location::Unprocessed:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
+ case StackMaps::Location::Register:
+ case StackMaps::Location::Direct:
+ return forRegister(location.dwarfReg, location.offset);
+
+ case StackMaps::Location::Indirect:
+ return forIndirect(location.dwarfReg, location.offset);
+
+ case StackMaps::Location::Constant:
+ return forConstant(location.offset);
+
+ case StackMaps::Location::ConstantIndex:
+ ASSERT(stackmaps);
+ return forConstant(stackmaps->constants[location.offset].integer);
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+
+ return Location();
+}
+
+void Location::dump(PrintStream& out) const
+{
+ out.print("(", kind());
+ if (hasDwarfReg())
+ out.print(", ", dwarfReg());
+ if (hasOffset())
+ out.print(", ", offset());
+ if (hasAddend())
+ out.print(", ", addend());
+ if (hasConstant())
+ out.print(", ", constant());
+ out.print(")");
+}
+
+bool Location::involvesGPR() const
+{
+ return isGPR() || kind() == Indirect;
+}
+
+bool Location::isGPR() const
+{
+ return kind() == Register && dwarfReg().reg().isGPR();
+}
+
+GPRReg Location::gpr() const
+{
+ return dwarfReg().reg().gpr();
+}
+
+bool Location::isFPR() const
+{
+ return kind() == Register && dwarfReg().reg().isFPR();
+}
+
+FPRReg Location::fpr() const
+{
+ return dwarfReg().reg().fpr();
+}
+
+void Location::restoreInto(MacroAssembler& jit, char* savedRegisters, GPRReg result, unsigned numFramesToPop) const
+{
+ if (involvesGPR() && RegisterSet::stackRegisters().get(gpr())) {
+ // Make the result GPR contain the appropriate stack register.
+ if (numFramesToPop) {
+ jit.move(MacroAssembler::framePointerRegister, result);
+
+ for (unsigned i = numFramesToPop - 1; i--;)
+ jit.loadPtr(result, result);
+
+ if (gpr() == MacroAssembler::framePointerRegister)
+ jit.loadPtr(result, result);
+ else
+ jit.addPtr(MacroAssembler::TrustedImmPtr(sizeof(void*) * 2), result);
+ } else
+ jit.move(gpr(), result);
+ }
+
+ if (isGPR()) {
+ if (RegisterSet::stackRegisters().get(gpr())) {
+ // Already restored into result.
+ } else
+ jit.load64(savedRegisters + offsetOfGPR(gpr()), result);
+
+ if (addend())
+ jit.add64(MacroAssembler::TrustedImm32(addend()), result);
+ return;
+ }
+
+ if (isFPR()) {
+ jit.load64(savedRegisters + offsetOfFPR(fpr()), result);
+ ASSERT(!addend());
+ return;
+ }
+
+ switch (kind()) {
+ case Register:
+ // LLVM used some register that we don't know about!
+ dataLog("Unrecognized location: ", *this, "\n");
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+
+ case Indirect:
+ if (RegisterSet::stackRegisters().get(gpr())) {
+ // The stack register is already recovered into result.
+ jit.load64(MacroAssembler::Address(result, offset()), result);
+ return;
+ }
+
+ jit.load64(savedRegisters + offsetOfGPR(gpr()), result);
+ jit.load64(MacroAssembler::Address(result, offset()), result);
+ return;
+
+ case Constant:
+ jit.move(MacroAssembler::TrustedImm64(constant()), result);
+ return;
+
+ case Unprocessed:
+ // Should never see this - it's an enumeration entry on LLVM's side that means that
+ // it hasn't processed this location.
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+GPRReg Location::directGPR() const
+{
+ RELEASE_ASSERT(!addend());
+ return gpr();
+}
+
+} } // namespace JSC::FTL
+
+namespace WTF {
+
+using namespace JSC::FTL;
+
+void printInternal(PrintStream& out, JSC::FTL::Location::Kind kind)
+{
+ switch (kind) {
+ case Location::Unprocessed:
+ out.print("Unprocessed");
+ return;
+ case Location::Register:
+ out.print("Register");
+ return;
+ case Location::Indirect:
+ out.print("Indirect");
+ return;
+ case Location::Constant:
+ out.print("Constant");
+ return;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(FTL_JIT)
+