<commit_before>use std::ptr;

use baseline::fct::ExHandler;
use execstate::ExecState;
use object::{Handle, Obj};
use stacktrace::StackFrameInfo;

pub use self::param::*;
pub use self::reg::*;

pub mod asm;
pub mod param;
pub mod reg;
pub mod trap;

pub fn sfi_from_execution_state(es: &ExecState) -> StackFrameInfo {
    let ra = es.regs[REG_LR.asm() as usize];

    StackFrameInfo {
        last: ptr::null(),
        fp: es.regs[REG_FP.asm() as usize],
        sp: es.sp,
        ra: ra,
        xpc: ra - 1,
    }
}

pub fn resume_with_handler(es: &mut ExecState,
                           handler: &ExHandler,
                           fp: usize,
                           exception: Handle<Obj>,
                           stacksize: usize) {
    if let Some(offset) = handler.offset {
        let arg = (fp as isize + offset as isize) as usize;

        unsafe {
            *(arg as *mut usize) = exception.raw() as usize;
        }
    }

    es.sp = fp - stacksize;
    es.regs[REG_FP.asm() as usize] = fp;
    es.pc = handler.catch;
}

pub fn flush_icache(start: *const u8, len: usize) {
    let start = start as usize;
    let end = start + len;

    // FIXME: get real data/insn cache-line size
    let icacheline_size = 64;
    let dcacheline_size = 64;

    let istart = start & !(icacheline_size - 1);
    let dstart = start & !(dcacheline_size - 1);

    let mut ptr = dstart;

    while ptr < end {
        unsafe {
            asm!("dc civac, $0":: "r"(ptr) : "memory" : "volatile");
        }

        ptr += dcacheline_size;
    }

    unsafe {
        asm!("dsb ish" ::: "memory" : "volatile");
    }

    ptr = istart;

    while ptr < end {
        unsafe {
            asm!("ic ivau, $0":: "r"(ptr) : "memory" : "volatile");
        }

        ptr += icacheline_size;
    }

    unsafe {
        asm!("dsb ish
              isb" ::: "memory" : "volatile");
    }
}

pub fn fp_from_execstate(es: &ExecState) -> usize {
    es.regs[REG_FP.asm() as usize]
}

pub fn get_exception_object(es: &ExecState) -> Handle<Obj> {
    let obj: Handle<Obj> = es.regs[REG_RESULT.asm() as usize].into();

    obj
}

pub fn ra_from_execstate(es: &ExecState) -> usize {
    es.regs[REG_LR.asm() as usize]
}<commit_msg>arm64: get cachline sizes<commit_after>use std::ptr;

use baseline::fct::ExHandler;
use execstate::ExecState;
use object::{Handle, Obj};
use stacktrace::StackFrameInfo;

pub use self::param::*;
pub use self::reg::*;

pub mod asm;
pub mod param;
pub mod reg;
pub mod trap;

pub fn sfi_from_execution_state(es: &ExecState) -> StackFrameInfo {
    let ra = es.regs[REG_LR.asm() as usize];

    StackFrameInfo {
        last: ptr::null(),
        fp: es.regs[REG_FP.asm() as usize],
        sp: es.sp,
        ra: ra,
        xpc: ra - 1,
    }
}

pub fn resume_with_handler(es: &mut ExecState,
                           handler: &ExHandler,
                           fp: usize,
                           exception: Handle<Obj>,
                           stacksize: usize) {
    if let Some(offset) = handler.offset {
        let arg = (fp as isize + offset as isize) as usize;

        unsafe {
            *(arg as *mut usize) = exception.raw() as usize;
        }
    }

    es.sp = fp - stacksize;
    es.regs[REG_FP.asm() as usize] = fp;
    es.pc = handler.catch;
}

pub fn flush_icache(start: *const u8, len: usize) {
    let start = start as usize;
    let end = start + len;

    let (icacheline_size, dcacheline_size) = cacheline_sizes();

    let istart = start & !(icacheline_size - 1);
    let dstart = start & !(dcacheline_size - 1);

    let mut ptr = dstart;

    while ptr < end {
        unsafe {
            asm!("dc civac, $0":: "r"(ptr) : "memory" : "volatile");
        }

        ptr += dcacheline_size;
    }

    unsafe {
        asm!("dsb ish" ::: "memory" : "volatile");
    }

    ptr = istart;

    while ptr < end {
        unsafe {
            asm!("ic ivau, $0":: "r"(ptr) : "memory" : "volatile");
        }

        ptr += icacheline_size;
    }

    unsafe {
        asm!("dsb ish
              isb" ::: "memory" : "volatile");
    }
}

pub fn cacheline_sizes() -> (usize, usize) {
    let value : usize;

    unsafe {
        asm!("mrs $0, ctr_el0": "=r"(value)::: "volatile");
    }

    let insn = 4 << (value & 0xF);
    let data = 4 << ((value >> 16) & 0xF);

    (insn, data)
}

pub fn fp_from_execstate(es: &ExecState) -> usize {
    es.regs[REG_FP.asm() as usize]
}

pub fn get_exception_object(es: &ExecState) -> Handle<Obj> {
    let obj: Handle<Obj> = es.regs[REG_RESULT.asm() as usize].into();

    obj
}

pub fn ra_from_execstate(es: &ExecState) -> usize {
    es.regs[REG_LR.asm() as usize]
}
{'fraction_non_alphanumeric': 0.14570387829440754, 'fraction_numerical': 0.005571030640668524, 'mean_word_length': 2.0730743910467413, 'pattern_counts': {'":': 5, '<': 17, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '6498822', 'n_tokens_mistral': 1675, 'n_tokens_neox': 1644, 'n_words': 430}