mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
124 lines
4.8 KiB
Rust
124 lines
4.8 KiB
Rust
use crate::vm::Vm;
|
|
use crate::vm_trace;
|
|
use oxide_types::value::JsValue;
|
|
|
|
impl Vm {
|
|
#[inline(always)]
|
|
fn write_ushr_result(&mut self, rd: usize, result: u32) {
|
|
if result <= i32::MAX as u32 {
|
|
self.regs[rd] = JsValue::int(result as i32);
|
|
} else {
|
|
self.regs[rd] = JsValue::float(result as f64);
|
|
}
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_bit_and(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
|
vm_trace!("BIT_AND rd={} r{},r{}", rd, a, b);
|
|
self.regs[rd] =
|
|
JsValue::int(self.coerce_int32_bounded(self.regs[a])? & self.coerce_int32_bounded(self.regs[b])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_bit_or(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
|
vm_trace!("BIT_OR rd={} r{},r{}", rd, a, b);
|
|
self.regs[rd] =
|
|
JsValue::int(self.coerce_int32_bounded(self.regs[a])? | self.coerce_int32_bounded(self.regs[b])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_bit_xor(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
|
vm_trace!("BIT_XOR rd={} r{},r{}", rd, a, b);
|
|
self.regs[rd] =
|
|
JsValue::int(self.coerce_int32_bounded(self.regs[a])? ^ self.coerce_int32_bounded(self.regs[b])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_shl(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
|
vm_trace!("SHL rd={} r{},r{}", rd, a, b);
|
|
let lhs = self.coerce_int32_bounded(self.regs[a])?;
|
|
let shift = self.coerce_uint32_bounded(self.regs[b])? & 0x1F;
|
|
self.regs[rd] = JsValue::int(lhs.wrapping_shl(shift));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_shr(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
|
vm_trace!("SHR rd={} r{},r{}", rd, a, b);
|
|
let lhs = self.coerce_int32_bounded(self.regs[a])?;
|
|
let shift = self.coerce_uint32_bounded(self.regs[b])? & 0x1F;
|
|
self.regs[rd] = JsValue::int(lhs >> shift);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_ushr(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
|
vm_trace!("USHR rd={} r{},r{}", rd, a, b);
|
|
let lhs = self.coerce_uint32_bounded(self.regs[a])?;
|
|
let shift = self.coerce_uint32_bounded(self.regs[b])? & 0x1F;
|
|
self.write_ushr_result(rd, lhs >> shift);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_bit_not(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("BIT_NOT rd={} r{}", rd, a);
|
|
self.regs[rd] = JsValue::int(!self.coerce_int32_bounded(self.regs[a])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_compound_bit_and(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("COMPOUND_BIT_AND rd={} r{}", rd, a);
|
|
self.regs[rd] =
|
|
JsValue::int(self.coerce_int32_bounded(self.regs[rd])? & self.coerce_int32_bounded(self.regs[a])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_compound_bit_or(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("COMPOUND_BIT_OR rd={} r{}", rd, a);
|
|
self.regs[rd] =
|
|
JsValue::int(self.coerce_int32_bounded(self.regs[rd])? | self.coerce_int32_bounded(self.regs[a])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_compound_bit_xor(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("COMPOUND_BIT_XOR rd={} r{}", rd, a);
|
|
self.regs[rd] =
|
|
JsValue::int(self.coerce_int32_bounded(self.regs[rd])? ^ self.coerce_int32_bounded(self.regs[a])?);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_compound_shl(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("COMPOUND_SHL rd={} r{}", rd, a);
|
|
let lhs = self.coerce_int32_bounded(self.regs[rd])?;
|
|
let shift = self.coerce_uint32_bounded(self.regs[a])? & 0x1F;
|
|
self.regs[rd] = JsValue::int(lhs.wrapping_shl(shift));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_compound_shr(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("COMPOUND_SHR rd={} r{}", rd, a);
|
|
let lhs = self.coerce_int32_bounded(self.regs[rd])?;
|
|
let shift = self.coerce_uint32_bounded(self.regs[a])? & 0x1F;
|
|
self.regs[rd] = JsValue::int(lhs >> shift);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn dispatch_compound_ushr(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
|
vm_trace!("COMPOUND_USHR rd={} r{}", rd, a);
|
|
let lhs = self.coerce_uint32_bounded(self.regs[rd])?;
|
|
let shift = self.coerce_uint32_bounded(self.regs[a])? & 0x1F;
|
|
self.write_ushr_result(rd, lhs >> shift);
|
|
Ok(())
|
|
}
|
|
}
|