/*
 * Copyright (C) 2015-2017 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 "MacroAssemblerPrinter.h"

#if ENABLE(MASM_PROBE)

#include "MacroAssembler.h"

namespace JSC {
namespace Printer {

using CPUState = MacroAssembler::CPUState;
using RegisterID = MacroAssembler::RegisterID;
using FPRegisterID = MacroAssembler::FPRegisterID;

void printAllRegisters(PrintStream& out, Context& context)
{
    auto& cpu = context.probeContext.cpu;
    unsigned charsToIndent = context.data.as<unsigned>();

    auto indent = [&] () {
        for (unsigned i = 0; i < charsToIndent; ++i)
            out.print(" ");
    };
#define INDENT indent()

    INDENT, out.print("cpu: {\n");

#if USE(JSVALUE32_64)
    #define INTPTR_HEX_VALUE_FORMAT "0x%08lx"
#else
    #define INTPTR_HEX_VALUE_FORMAT "0x%016lx"
#endif

    #define PRINT_GPREGISTER(_type, _regName) { \
        intptr_t value = reinterpret_cast<intptr_t>(cpu._regName); \
        INDENT, out.printf("    %6s: " INTPTR_HEX_VALUE_FORMAT "  %ld\n", #_regName, value, value) ; \
    }
    FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER)
    FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER)
    #undef PRINT_GPREGISTER
    #undef INTPTR_HEX_VALUE_FORMAT
    
    #define PRINT_FPREGISTER(_type, _regName) { \
        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
        double* d = reinterpret_cast<double*>(&cpu._regName); \
        INDENT, out.printf("    %6s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
    }
    FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER)
    #undef PRINT_FPREGISTER

    INDENT, out.print("}\n");
#undef INDENT

}

void printPCRegister(PrintStream& out, Context& context)
{
    auto cpu = context.probeContext.cpu;
    void* value;
#if CPU(X86) || CPU(X86_64)
    value = cpu.eip;
#elif CPU(ARM_TRADITIONAL) || CPU(ARM_THUMB2) || CPU(ARM64)
    value = cpu.pc;
#else
#error "Unsupported CPU"
#endif
    out.printf("pc:<%p %ld>", value, bitwise_cast<intptr_t>(value));
}

void printRegisterID(PrintStream& out, Context& context)
{
    RegisterID regID = context.data.as<RegisterID>();
    const char* name = CPUState::gprName(regID);
    void* value = context.probeContext.gpr(regID);
    out.printf("%s:<%p %ld>", name, value, bitwise_cast<intptr_t>(value));
}

void printFPRegisterID(PrintStream& out, Context& context)
{
    FPRegisterID regID = context.data.as<FPRegisterID>();
    const char* name = CPUState::fprName(regID);
    double value = context.probeContext.fpr(regID);
    out.printf("%s:<0x%016llx %.13g>", name, bitwise_cast<uint64_t>(value), value);
}

void printAddress(PrintStream& out, Context& context)
{
    MacroAssembler::Address address = context.data.as<MacroAssembler::Address>();
    RegisterID regID = address.base;
    const char* name = CPUState::gprName(regID);
    void* value = context.probeContext.gpr(regID);
    out.printf("Address{base:%s:<%p %ld>, offset:<0x%x %d>", name, value, bitwise_cast<intptr_t>(value), address.offset, address.offset);
}

void printMemory(PrintStream& out, Context& context)
{
    const Memory& memory = context.data.as<Memory>();

    uint8_t* ptr = nullptr;
    switch (memory.addressType) {
    case Memory::AddressType::Address: {
        ptr = reinterpret_cast<uint8_t*>(context.probeContext.gpr(memory.u.address.base));
        ptr += memory.u.address.offset;
        break;
    }
    case Memory::AddressType::AbsoluteAddress: {
        ptr = reinterpret_cast<uint8_t*>(const_cast<void*>(memory.u.absoluteAddress.m_ptr));
        break;
    }
    }

    if (memory.dumpStyle == Memory::SingleWordDump) {
        if (memory.numBytes == sizeof(int8_t)) {
            auto p = reinterpret_cast<int8_t*>(ptr);
            out.printf("%p:<0x%02x %d>", p, *p, *p);
            return;
        }
        if (memory.numBytes == sizeof(int16_t)) {
            auto p = reinterpret_cast<int16_t*>(ptr);
            out.printf("%p:<0x%04x %d>", p, *p, *p);
            return;
        }
        if (memory.numBytes == sizeof(int32_t)) {
            auto p = reinterpret_cast<int32_t*>(ptr);
            out.printf("%p:<0x%08x %d>", p, *p, *p);
            return;
        }
        if (memory.numBytes == sizeof(int64_t)) {
            auto p = reinterpret_cast<int64_t*>(ptr);
            out.printf("%p:<0x%016llx %lld>", p, *p, *p);
            return;
        }
        // Else, unknown word size. Fall thru and dump in the generic way.
    }

    // Generic dump: dump rows of 16 bytes in 4 byte groupings.
    size_t numBytes = memory.numBytes;
    for (size_t i = 0; i < numBytes; i++) {
        if (!(i % 16))
            out.printf("%p: ", &ptr[i]);
        else if (!(i % 4))
            out.printf(" ");

        out.printf("%02x", ptr[i]);

        if (i % 16 == 15)
            out.print("\n");
    }
    if (numBytes % 16 < 15)
        out.print("\n");
}

void printCallback(ProbeContext* probeContext)
{
    auto& out = WTF::dataFile();
    PrintRecordList& list = *reinterpret_cast<PrintRecordList*>(probeContext->arg);
    for (size_t i = 0; i < list.size(); i++) {
        auto& record = list[i];
        Context context(*probeContext, record.data);
        record.printer(out, context);
    }
}

} // namespace Printer
} // namespace JSC

#endif // ENABLE(MASM_PROBE)
