<commit_before>/*
 * This file is part of libbluray
 * Copyright (C) 2010  hpi1
 *
 * 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/>.
 */

#include "hdmv_vm.h"

#include "mobj_parse.h"
#include "hdmv_insn.h"
#include "../register.h"

#include "util/macro.h"
#include "util/strutl.h"
#include "util/logging.h"

#include <stdlib.h>
#include <string.h>
#include <time.h>


#define SWAP32(a,b) { uint32_t tmp = a; a = b; b = tmp; }

struct hdmv_vm_s {
    /* state */
    uint32_t       pc;            /* program counter */
    BD_REGISTERS  *regs;          /* player registers */
    MOBJ_OBJECT   *object;        /* currently running object code */

    HDMV_EVENT     event[5];      /* pending events to return */

    /* movie objects */
    MOBJ_OBJECTS  *movie_objects; /* disc movie objects */
    MOBJ_OBJECT   *ig_object;     /* current object from IG stream */

    /* suspended object */
    MOBJ_OBJECT *suspended_object;
    int          suspended_pc;
};

/*
 * registers: PSR and GPR access
 */

#define PSR_FLAG 0x80000000

static int _is_valid_reg(uint32_t reg)
{
    if (reg & PSR_FLAG) {
        if (reg & ~0x8000007f) {
            return 0;
        }
    }  else {
        if (reg & ~0x00000fff) {
            return 0;
        }
    }
    return 1;
}

static int _store_reg(HDMV_VM *p, uint32_t reg, uint32_t val)
{
    if (!_is_valid_reg(reg)) {
        DEBUG(DBG_HDMV, "_store_reg(): invalid register 0x%x\n", reg);
        return -1;
    }

    if (reg & PSR_FLAG) {
        return bd_psr_write(p->regs, reg & 0x7f, val);
    }  else {
        return bd_gpr_write(p->regs, reg, val);
    }
}

static uint32_t _read_reg(HDMV_VM *p, uint32_t reg)
{
    if (!_is_valid_reg(reg)) {
        DEBUG(DBG_HDMV, "_read_reg(): invalid register 0x%x\n", reg);
        return 0;
    }

    if (reg & PSR_FLAG) {
        return bd_psr_read(p->regs, reg & 0x7f);
    } else {
        return bd_gpr_read(p->regs, reg);
    }
}

static int _store_result(HDMV_VM *p, MOBJ_CMD *cmd, uint32_t src, uint32_t dst, uint32_t src0, uint32_t dst0)
{
    int ret = 0;

    /* store result to destination register(s) */
    if (dst != dst0) {
        if (cmd->insn.imm_op1) {
            DEBUG(DBG_HDMV|DBG_CRIT, "ERROR: storing to imm ! ");
            return -1;
        }
        ret = _store_reg(p, cmd->dst, dst);
    }

    if (src != src0) {
        if (cmd->insn.imm_op1) {
            DEBUG(DBG_HDMV|DBG_CRIT, "ERROR: storing to imm ! ");
            return -1;
        }
        ret += _store_reg(p, cmd->src, src);
    }

    return ret;
}

/*
 * event queue
 */

static int _get_event(HDMV_VM *p, HDMV_EVENT *ev)
{
    if (p->event[0].event != HDMV_EVENT_NONE) {
        *ev = p->event[0];
        memmove(p->event, p->event + 1, sizeof(p->event) - sizeof(p->event[0]));
        return 0;
    }

    return -1;
}

static int _queue_event(HDMV_VM *p, HDMV_EVENT ev)
{
    unsigned i;
    for (i = 0; i < sizeof(p->event) / sizeof(p->event[0]) - 1; i++) {
        if (p->event[i].event != HDMV_EVENT_NONE) {
            p->event[i] = ev;
            return 0;
        }
    }

    DEBUG(DBG_HDMV|DBG_CRIT, "_queue_event(%d, %d): queue overflow !\n", ev.event, ev.param);
    return -1;
}

/*
 * vm init<commit_msg>Fixed hdmv vm event queue<commit_after>/*
 * This file is part of libbluray
 * Copyright (C) 2010  hpi1
 *
 * 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/>.
 */

#include "hdmv_vm.h"

#include "mobj_parse.h"
#include "hdmv_insn.h"
#include "../register.h"

#include "util/macro.h"
#include "util/strutl.h"
#include "util/logging.h"

#include <stdlib.h>
#include <string.h>
#include <time.h>


#define SWAP32(a,b) { uint32_t tmp = a; a = b; b = tmp; }

struct hdmv_vm_s {
    /* state */
    uint32_t       pc;            /* program counter */
    BD_REGISTERS  *regs;          /* player registers */
    MOBJ_OBJECT   *object;        /* currently running object code */

    HDMV_EVENT     event[5];      /* pending events to return */

    /* movie objects */
    MOBJ_OBJECTS  *movie_objects; /* disc movie objects */
    MOBJ_OBJECT   *ig_object;     /* current object from IG stream */

    /* suspended object */
    MOBJ_OBJECT *suspended_object;
    int          suspended_pc;
};

/*
 * registers: PSR and GPR access
 */

#define PSR_FLAG 0x80000000

static int _is_valid_reg(uint32_t reg)
{
    if (reg & PSR_FLAG) {
        if (reg & ~0x8000007f) {
            return 0;
        }
    }  else {
        if (reg & ~0x00000fff) {
            return 0;
        }
    }
    return 1;
}

static int _store_reg(HDMV_VM *p, uint32_t reg, uint32_t val)
{
    if (!_is_valid_reg(reg)) {
        DEBUG(DBG_HDMV, "_store_reg(): invalid register 0x%x\n", reg);
        return -1;
    }

    if (reg & PSR_FLAG) {
        return bd_psr_write(p->regs, reg & 0x7f, val);
    }  else {
        return bd_gpr_write(p->regs, reg, val);
    }
}

static uint32_t _read_reg(HDMV_VM *p, uint32_t reg)
{
    if (!_is_valid_reg(reg)) {
        DEBUG(DBG_HDMV, "_read_reg(): invalid register 0x%x\n", reg);
        return 0;
    }

    if (reg & PSR_FLAG) {
        return bd_psr_read(p->regs, reg & 0x7f);
    } else {
        return bd_gpr_read(p->regs, reg);
    }
}

static int _store_result(HDMV_VM *p, MOBJ_CMD *cmd, uint32_t src, uint32_t dst, uint32_t src0, uint32_t dst0)
{
    int ret = 0;

    /* store result to destination register(s) */
    if (dst != dst0) {
        if (cmd->insn.imm_op1) {
            DEBUG(DBG_HDMV|DBG_CRIT, "ERROR: storing to imm ! ");
            return -1;
        }
        ret = _store_reg(p, cmd->dst, dst);
    }

    if (src != src0) {
        if (cmd->insn.imm_op1) {
            DEBUG(DBG_HDMV|DBG_CRIT, "ERROR: storing to imm ! ");
            return -1;
        }
        ret += _store_reg(p, cmd->src, src);
    }

    return ret;
}

/*
 * event queue
 */

static int _get_event(HDMV_VM *p, HDMV_EVENT *ev)
{
    if (p->event[0].event != HDMV_EVENT_NONE) {
        *ev = p->event[0];
        memmove(p->event, p->event + 1, sizeof(p->event) - sizeof(p->event[0]));
        return 0;
    }

    ev->event = HDMV_EVENT_NONE;

    return -1;
}

static int _queue_event(HDMV_VM *p, HDMV_EVENT ev)
{
    unsigned i;
    for (i = 0; i < sizeof(p->event) / sizeof(p->event[0]) - 1; i++) {
        if (p->event[i].event == HDMV_EVENT_NONE) {
            p->event[i] = ev;
            return 0;
        }
    }

    DEBUG(DBG_HDMV|DBG_CRIT, "_queue_event(%d, %d): queue overflow !\n", ev.event, ev.param);
    return -1;
}

/*
 * vm init
{'fraction_non_alphanumeric': 0.13008551438196425, 'fraction_numerical': 0.0222855662088624, 'mean_word_length': 2.330025884383089, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5189610', 'n_tokens_mistral': 2920, 'n_tokens_neox': 2792, 'n_words': 773}