/*
 * 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 "exec/helper-proto.h"
#include <zlib.h> /* For crc32 */
#include "syscall_defs.h"

void helper_exception(CPUTLGState *env, uint32_t excp)
{
    CPUState *cs = env_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);
}
