/*
 * Copyright (c) 2021 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "src/common/cpuinfo/CpuModel.h"

namespace arm_compute
{
namespace cpuinfo
{
std::string cpu_model_to_string(CpuModel model)
{
    switch(model)
    {
#define X(MODEL)          \
case CpuModel::MODEL: \
    return #MODEL;
            ARM_COMPUTE_CPU_MODEL_LIST
#undef X
        default:
        {
            return std::string("GENERIC");
        }
    };
}

bool model_supports_fp16(CpuModel model)
{
    switch(model)
    {
        case CpuModel::GENERIC_FP16:
        case CpuModel::GENERIC_FP16_DOT:
        case CpuModel::A55r1:
        case CpuModel::X1:
        case CpuModel::KLEIN:
            return true;
        default:
            return false;
    }
}

bool model_supports_dot(CpuModel model)
{
    switch(model)
    {
        case CpuModel::GENERIC_FP16_DOT:
        case CpuModel::A55r1:
        case CpuModel::X1:
        case CpuModel::KLEIN:
            return true;
        default:
            return false;
    }
}

bool model_supports_sve(CpuModel model)
{
    switch(model)
    {
        case CpuModel::KLEIN:
            return true;
        default:
            return false;
    }
}

CpuModel midr_to_model(uint32_t midr)
{
    CpuModel model = CpuModel::GENERIC;

    // Unpack variant and CPU ID
    const int implementer = (midr >> 24) & 0xFF;
    const int variant     = (midr >> 20) & 0xF;
    const int cpunum      = (midr >> 4) & 0xFFF;

    if(implementer == 0x41) // Arm CPUs
    {
        // Only CPUs we have code paths for are detected.  All other CPUs can be safely classed as "GENERIC"
        switch(cpunum)
        {
            case 0xd03: // A53
            case 0xd04: // A35
                model = CpuModel::A53;
                break;
            case 0xd05: // A55
                if(variant != 0)
                {
                    model = CpuModel::A55r1;
                }
                else
                {
                    model = CpuModel::A55r0;
                }
                break;
            case 0xd09: // A73
                model = CpuModel::A73;
                break;
            case 0xd0a: // A75
                if(variant != 0)
                {
                    model = CpuModel::GENERIC_FP16_DOT;
                }
                else
                {
                    model = CpuModel::GENERIC_FP16;
                }
                break;
            case 0xd06: // A65
            case 0xd0b: // A76
            case 0xd0c: // N1
            case 0xd0d: // A77
            case 0xd0e: // A76AE
            case 0xd41: // A78
            case 0xd42: // A78AE
            case 0xd4a: // E1
                model = CpuModel::GENERIC_FP16_DOT;
                break;
            case 0xd44: // X1
                model = CpuModel::X1;
                break;
            case 0xd46:
                model = CpuModel::KLEIN;
                break;
            default:
                model = CpuModel::GENERIC;
                break;
        }
    }
    else if(implementer == 0x48)
    {
        // Only CPUs we have code paths for are detected.  All other CPUs can be safely classed as "GENERIC"
        switch(cpunum)
        {
            case 0xd40: // A76
                model = CpuModel::GENERIC_FP16_DOT;
                break;
            default:
                model = CpuModel::GENERIC;
                break;
        }
    }
    else if(implementer == 0x51)
    {
        // Only CPUs we have code paths for are detected.  All other CPUs can be safely classed as "GENERIC"
        switch(cpunum)
        {
            case 0x800: // A73
                model = CpuModel::A73;
                break;
            case 0x801: // A53
                model = CpuModel::A53;
                break;
            case 0x803: // A55r0
                model = CpuModel::A55r0;
                break;
            case 0x804: // A76
                model = CpuModel::GENERIC_FP16_DOT;
                break;
            case 0x805: // A55r1
                model = CpuModel::A55r1;
                break;
            default:
                model = CpuModel::GENERIC;
                break;
        }
    }

    return model;
}
} // namespace cpuinfo
} // namespace arm_compute