// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string.h>

#include <hypervisor/decode.h>
#include <zircon/syscalls/hypervisor.h>
#include <zircon/syscalls/port.h>

static const uint8_t kRexRMask = 1u << 2;
static const uint8_t kRexWMask = 1u << 3;
static const uint8_t kModRMRegMask = 0b00111000;

static bool is_h66_prefix(uint8_t prefix) {
    return prefix == 0x66;
}

static bool is_rex_prefix(uint8_t prefix) {
    return (prefix >> 4) == 0b0100;
}

static bool has_sib_byte(uint8_t mod_rm) {
    return (mod_rm >> 6) != 0b11 && (mod_rm & 0b111) == 0b100;
}

static uint8_t displacement_size(uint8_t mod_rm) {
    switch (mod_rm >> 6) {
    case 0b01:
        return 1;
    case 0b10:
        return 4;
    default:
        return (mod_rm & ~kModRMRegMask) == 0b00000101 ? 4 : 0;
    }
}

static uint8_t mem_size(bool h66, bool rex_w) {
    if (rex_w) {
        return 8;
    } else if (!h66) {
        return 4;
    } else {
        return 2;
    }
}

static uint8_t register_id(uint8_t mod_rm, bool rex_r) {
    return static_cast<uint8_t>(((mod_rm >> 3) & 0b111) + (rex_r ? 0b1000 : 0));
}

static uint64_t* select_register(zx_vcpu_state_t* vcpu_state, uint8_t register_id) {
    // From Intel Volume 2, Section 2.1.
    switch (register_id) {
    // From Intel Volume 2, Section 2.1.5.
    case 0:
        return &vcpu_state->rax;
    case 1:
        return &vcpu_state->rcx;
    case 2:
        return &vcpu_state->rdx;
    case 3:
        return &vcpu_state->rbx;
    case 4:
        return &vcpu_state->rsp;
    case 5:
        return &vcpu_state->rbp;
    case 6:
        return &vcpu_state->rsi;
    case 7:
        return &vcpu_state->rdi;
    case 8:
        return &vcpu_state->r8;
    case 9:
        return &vcpu_state->r9;
    case 10:
        return &vcpu_state->r10;
    case 11:
        return &vcpu_state->r11;
    case 12:
        return &vcpu_state->r12;
    case 13:
        return &vcpu_state->r13;
    case 14:
        return &vcpu_state->r14;
    case 15:
        return &vcpu_state->r15;
    default:
        return NULL;
    }
}

zx_status_t deconstruct_instruction(const uint8_t* inst_buf, uint32_t inst_len,
                                    uint16_t* opcode, uint8_t* mod_rm) {
    if (inst_len == 0)
        return ZX_ERR_NOT_SUPPORTED;
    switch (inst_buf[0]) {
    case 0x0f:
        if (inst_len < 3)
            return ZX_ERR_NOT_SUPPORTED;
        *opcode = *(uint16_t*)inst_buf;
        *mod_rm = inst_buf[2];
        break;
    default:
        if (inst_len < 2)
            return ZX_ERR_OUT_OF_RANGE;
        *opcode = inst_buf[0];
        *mod_rm = inst_buf[1];
        break;
    }
    return ZX_OK;
}

zx_status_t inst_decode(const uint8_t* inst_buf, uint32_t inst_len, zx_vcpu_state_t* vcpu_state,
                        instruction_t* inst) {
    if (inst_len == 0)
        return ZX_ERR_BAD_STATE;
    if (inst_len > X86_MAX_INST_LEN)
        return ZX_ERR_OUT_OF_RANGE;

    // Parse 66H prefix.
    bool h66 = is_h66_prefix(inst_buf[0]);
    if (h66) {
        if (inst_len == 1)
            return ZX_ERR_BAD_STATE;
        inst_buf++;
        inst_len--;
    }
    // Parse REX prefix.
    //
    // From Intel Volume 2, Appendix 2.2.1: Only one REX prefix is allowed per
    // instruction. If used, the REX prefix byte must immediately precede the
    // opcode byte or the escape opcode byte (0FH).
    bool rex_r = false;
    bool rex_w = false;
    if (is_rex_prefix(inst_buf[0])) {
        rex_r = inst_buf[0] & kRexRMask;
        rex_w = inst_buf[0] & kRexWMask;
        inst_buf++;
        inst_len--;
    }
    // Technically this is valid, but no sane compiler should emit it.
    if (h66 && rex_w)
        return ZX_ERR_NOT_SUPPORTED;

    uint16_t opcode;
    uint8_t mod_rm;
    zx_status_t status = deconstruct_instruction(inst_buf, inst_len, &opcode, &mod_rm);
    if (status != ZX_OK)
        return status;
    if (has_sib_byte(mod_rm))
        return ZX_ERR_NOT_SUPPORTED;

    const uint8_t disp_size = displacement_size(mod_rm);
    switch (opcode) {
    // Move r to r/m.
    case 0x89:
        if (inst_len != disp_size + 2u)
            return ZX_ERR_OUT_OF_RANGE;
        inst->type = INST_MOV_WRITE;
        inst->mem = mem_size(h66, rex_w);
        inst->imm = 0;
        inst->reg = select_register(vcpu_state, register_id(mod_rm, rex_r));
        inst->flags = NULL;
        return inst->reg == NULL ? ZX_ERR_NOT_SUPPORTED : ZX_OK;
    // Move r/m to r.
    case 0x8b:
        if (inst_len != disp_size + 2u)
            return ZX_ERR_OUT_OF_RANGE;
        inst->type = INST_MOV_READ;
        inst->mem = mem_size(h66, rex_w);
        inst->imm = 0;
        inst->reg = select_register(vcpu_state, register_id(mod_rm, rex_r));
        inst->flags = NULL;
        return inst->reg == NULL ? ZX_ERR_NOT_SUPPORTED : ZX_OK;
    // Move imm to r/m.
    case 0xc7: {
        const uint8_t imm_size = h66 ? 2 : 4;
        if (inst_len != disp_size + imm_size + 2u)
            return ZX_ERR_OUT_OF_RANGE;
        if ((mod_rm & kModRMRegMask) != 0)
            return ZX_ERR_INVALID_ARGS;
        inst->type = INST_MOV_WRITE;
        inst->mem = mem_size(h66, rex_w);
        inst->imm = 0;
        inst->reg = NULL;
        inst->flags = NULL;
        memcpy(&inst->imm, inst_buf + disp_size + 2, imm_size);
        return ZX_OK;
    }
    // Move (8-bit) with zero-extend r/m to r.
    case 0xb60f:
        if (h66)
            return ZX_ERR_BAD_STATE;
        if (inst_len != disp_size + 3u)
            return ZX_ERR_OUT_OF_RANGE;
        inst->type = INST_MOV_READ;
        inst->mem = 1;
        inst->imm = 0;
        inst->reg = select_register(vcpu_state, register_id(mod_rm, rex_r));
        inst->flags = NULL;
        return inst->reg == NULL ? ZX_ERR_NOT_SUPPORTED : ZX_OK;
    // Move (16-bit) with zero-extend r/m to r.
    case 0xb70f:
        if (h66)
            return ZX_ERR_BAD_STATE;
        if (inst_len != disp_size + 3u)
            return ZX_ERR_OUT_OF_RANGE;
        inst->type = INST_MOV_READ;
        inst->mem = 2;
        inst->imm = 0;
        inst->reg = select_register(vcpu_state, register_id(mod_rm, rex_r));
        inst->flags = NULL;
        return inst->reg == NULL ? ZX_ERR_NOT_SUPPORTED : ZX_OK;
    // Logical compare (8-bit) imm with r/m.
    case 0xf6:
        if (h66)
            return ZX_ERR_BAD_STATE;
        if (inst_len != disp_size + 3u)
            return ZX_ERR_OUT_OF_RANGE;
        if ((mod_rm & kModRMRegMask) != 0)
            return ZX_ERR_INVALID_ARGS;
        inst->type = INST_TEST;
        inst->mem = 1;
        inst->imm = 0;
        inst->reg = NULL;
        inst->flags = &vcpu_state->flags;
        memcpy(&inst->imm, inst_buf + disp_size + 2, 1);
        return ZX_OK;
    default:
        return ZX_ERR_NOT_SUPPORTED;
    }
}
