/*
 * QEMU TILE-Gx helpers
 *
 *  Copyright (c) 2015 Chen Gang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see
 * <http://www.gnu.org/licenses/lgpl-2.1.html>
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "qemu-common.h"
#include "exec/helper-proto.h"
#include <zlib.h> /* For crc32 */
#include "syscall_defs.h"

void helper_exception(CPUTLGState *env, uint32_t excp)
{
    CPUState *cs = CPU(tilegx_env_get_cpu(env));

    cs->exception_index = excp;
    cpu_loop_exit(cs);
}

void helper_ext01_ics(CPUTLGState *env)
{
    uint64_t val = env->spregs[TILEGX_SPR_EX_CONTEXT_0_1];

    switch (val) {
    case 0:
    case 1:
        env->spregs[TILEGX_SPR_CRITICAL_SEC] = val;
        break;
    default:
#if defined(CONFIG_USER_ONLY)
        env->signo = TARGET_SIGILL;
        env->sigcode = TARGET_ILL_ILLOPC;
        helper_exception(env, TILEGX_EXCP_SIGNAL);
#else
        helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED);
#endif
        break;
    }
}

uint64_t helper_revbits(uint64_t arg)
{
    return revbit64(arg);
}

/*
 * Functional Description
 *     uint64_t a = rf[SrcA];
 *     uint64_t b = rf[SrcB];
 *     uint64_t d = rf[Dest];
 *     uint64_t output = 0;
 *     unsigned int counter;
 *     for (counter = 0; counter < (WORD_SIZE / BYTE_SIZE); counter++)
 *     {
 *         int sel = getByte (b, counter) & 0xf;
 *         uint8_t byte = (sel < 8) ? getByte (d, sel) : getByte (a, (sel - 8));
 *         output = setByte (output, counter, byte);
 *     }
 *     rf[Dest] = output;
 */
uint64_t helper_shufflebytes(uint64_t dest, uint64_t srca, uint64_t srcb)
{
    uint64_t vdst = 0;
    int count;

    for (count = 0; count < 64; count += 8) {
        uint64_t sel = srcb >> count;
        uint64_t src = (sel & 8) ? srca : dest;
        vdst |= extract64(src, (sel & 7) * 8, 8) << count;
    }

    return vdst;
}

uint64_t helper_crc32_8(uint64_t accum, uint64_t input)
{
    uint8_t buf = input;

    /* zlib crc32 converts the accumulator and output to one's complement.  */
    return crc32(accum ^ 0xffffffff, &buf, 1) ^ 0xffffffff;
}

uint64_t helper_crc32_32(uint64_t accum, uint64_t input)
{
    uint8_t buf[4];

    stl_le_p(buf, input);

    /* zlib crc32 converts the accumulator and output to one's complement.  */
    return crc32(accum ^ 0xffffffff, buf, 4) ^ 0xffffffff;
}

uint64_t helper_cmula(uint64_t srcd, uint64_t srca, uint64_t srcb)
{
    uint32_t reala = (int16_t)srca;
    uint32_t imaga = (int16_t)(srca >> 16);
    uint32_t realb = (int16_t)srcb;
    uint32_t imagb = (int16_t)(srcb >> 16);
    uint32_t reald = srcd;
    uint32_t imagd = srcd >> 32;
    uint32_t realr = reala * realb - imaga * imagb + reald;
    uint32_t imagr = reala * imagb + imaga * realb + imagd;

    return deposit64(realr, 32, 32, imagr);
}

uint64_t helper_cmulaf(uint64_t srcd, uint64_t srca, uint64_t srcb)
{
    uint32_t reala = (int16_t)srca;
    uint32_t imaga = (int16_t)(srca >> 16);
    uint32_t realb = (int16_t)srcb;
    uint32_t imagb = (int16_t)(srcb >> 16);
    uint32_t reald = (int16_t)srcd;
    uint32_t imagd = (int16_t)(srcd >> 16);
    int32_t realr = reala * realb - imaga * imagb;
    int32_t imagr = reala * imagb + imaga * realb;

    return deposit32((realr >> 15) + reald, 16, 16, (imagr >> 15) + imagd);
}

uint64_t helper_cmul2(uint64_t srca, uint64_t srcb, int shift, int round)
{
    uint32_t reala = (int16_t)srca;
    uint32_t imaga = (int16_t)(srca >> 16);
    uint32_t realb = (int16_t)srcb;
    uint32_t imagb = (int16_t)(srcb >> 16);
    int32_t realr = reala * realb - imaga * imagb + round;
    int32_t imagr = reala * imagb + imaga * realb + round;

    return deposit32(realr >> shift, 16, 16, imagr >> shift);
}
