Added relaxed relative 16 bit instructions
This commit is contained in:
parent
3e4095da6f
commit
2f8612c6d2
|
@ -35,7 +35,7 @@
|
|||
30, LD, RRAH, "Load from absolute address" ;
|
||||
31, ST, RRAH, "Store to absolute address" ;
|
||||
32, LDR, RROH, "Load from relative address" ;
|
||||
33, STR, RROH, "Store to absolute address" ;
|
||||
33, STR, RROH, "Store to relative address" ;
|
||||
34, BMC, RRH, "Copy block of memory" ;
|
||||
35, BRC, RRB, "Copy register block" ;
|
||||
|
||||
|
@ -62,3 +62,8 @@
|
|||
|
||||
55, ADDFI, RRD, "Floating addition with immediate" ;
|
||||
56, MULFI, RRD, "Floating multiplication with immediate";
|
||||
|
||||
57, LRA16 , RRP, "Load relative immediate (16 bit)" ;
|
||||
58, LDR16 , RRPH, "Load from relative address (16 bit)" ;
|
||||
59, STR16 , RRPH, "Store to relative address (16 bit)" ;
|
||||
60, JMPR16, P, "Relative jump (16 bit)" ;
|
||||
|
|
|
@ -35,6 +35,7 @@ define_items! {
|
|||
OpsRRD (OpR, OpR, OpD ),
|
||||
OpsRRAH (OpR, OpR, OpA, OpH),
|
||||
OpsRROH (OpR, OpR, OpO, OpH),
|
||||
OpsRRPH (OpR, OpR, OpP, OpH),
|
||||
OpsRRO (OpR, OpR, OpO ),
|
||||
OpsRRP (OpR, OpR, OpP ),
|
||||
}
|
||||
|
@ -42,6 +43,7 @@ define_items! {
|
|||
unsafe impl BytecodeItem for OpA {}
|
||||
unsafe impl BytecodeItem for OpB {}
|
||||
unsafe impl BytecodeItem for OpO {}
|
||||
unsafe impl BytecodeItem for OpP {}
|
||||
unsafe impl BytecodeItem for () {}
|
||||
|
||||
::with_builtin_macros::with_builtin! {
|
||||
|
|
|
@ -12,8 +12,8 @@ use {
|
|||
crate::mem::{addr::AddressOp, Address},
|
||||
core::{cmp::Ordering, mem::size_of, ops},
|
||||
hbbytecode::{
|
||||
BytecodeItem, OpA, OpO, OpsRD, OpsRR, OpsRRAH, OpsRRB, OpsRRD, OpsRRH, OpsRRO, OpsRROH,
|
||||
OpsRRP, OpsRRR, OpsRRRR, OpsRRW,
|
||||
BytecodeItem, OpA, OpO, OpP, OpsRD, OpsRR, OpsRRAH, OpsRRB, OpsRRD, OpsRRH, OpsRRO,
|
||||
OpsRROH, OpsRRP, OpsRRPH, OpsRRR, OpsRRRR, OpsRRW,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -163,64 +163,20 @@ where
|
|||
LD => {
|
||||
// Load. If loading more than register size, continue on adjecent registers
|
||||
let OpsRRAH(dst, base, off, count) = self.decode();
|
||||
let n: u8 = match dst {
|
||||
0 => 1,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
self.memory.load(
|
||||
self.ldst_addr_uber(dst, base, off, count, n)?,
|
||||
self.registers
|
||||
.as_mut_ptr()
|
||||
.add(usize::from(dst) + usize::from(n))
|
||||
.cast(),
|
||||
usize::from(count).wrapping_sub(n.into()),
|
||||
)?;
|
||||
self.load(dst, base, off, count)?;
|
||||
}
|
||||
ST => {
|
||||
// Store. Same rules apply as to LD
|
||||
let OpsRRAH(dst, base, off, count) = self.decode();
|
||||
self.memory.store(
|
||||
self.ldst_addr_uber(dst, base, off, count, 0)?,
|
||||
self.registers.as_ptr().add(usize::from(dst)).cast(),
|
||||
count.into(),
|
||||
)?;
|
||||
self.store(dst, base, off, count)?;
|
||||
}
|
||||
LDR => {
|
||||
let OpsRROH(dst, base, off, count) = self.decode();
|
||||
let n: u8 = match dst {
|
||||
0 => 1,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
self.memory.load(
|
||||
self.ldst_addr_uber(
|
||||
dst,
|
||||
base,
|
||||
u64::from(off).wrapping_add(self.pc.get()),
|
||||
count,
|
||||
n,
|
||||
)?,
|
||||
self.registers
|
||||
.as_mut_ptr()
|
||||
.add(usize::from(dst) + usize::from(n))
|
||||
.cast(),
|
||||
usize::from(count).wrapping_sub(n.into()),
|
||||
)?;
|
||||
self.load(dst, base, u64::from(off).wrapping_add(self.pc.get()), count)?;
|
||||
}
|
||||
STR => {
|
||||
let OpsRROH(dst, base, off, count) = self.decode();
|
||||
self.memory.store(
|
||||
self.ldst_addr_uber(
|
||||
dst,
|
||||
base,
|
||||
u64::from(off).wrapping_add(self.pc.get()),
|
||||
count,
|
||||
0,
|
||||
)?,
|
||||
self.registers.as_ptr().add(usize::from(dst)).cast(),
|
||||
count.into(),
|
||||
)?;
|
||||
self.store(dst, base, u64::from(off).wrapping_add(self.pc.get()), count)?;
|
||||
}
|
||||
BMC => {
|
||||
const INS_SIZE: usize = size_of::<OpsRRH>() + 1;
|
||||
|
@ -341,6 +297,19 @@ where
|
|||
}
|
||||
ADDFI => self.binary_op_imm::<f64>(ops::Add::add),
|
||||
MULFI => self.binary_op_imm::<f64>(ops::Mul::mul),
|
||||
LRA16 => {
|
||||
let OpsRRP(tg, reg, imm) = self.decode();
|
||||
self.write_reg(tg, self.rel_addr(reg, imm).get());
|
||||
}
|
||||
LDR16 => {
|
||||
let OpsRRPH(dst, base, off, count) = self.decode();
|
||||
self.load(dst, base, u64::from(off).wrapping_add(self.pc.get()), count)?;
|
||||
}
|
||||
STR16 => {
|
||||
let OpsRRPH(dst, base, off, count) = self.decode();
|
||||
self.store(dst, base, u64::from(off).wrapping_add(self.pc.get()), count)?;
|
||||
}
|
||||
JMPR16 => self.pc = self.pc.wrapping_add(self.decode::<OpP>()),
|
||||
op => return Err(VmRunError::InvalidOpcode(op)),
|
||||
}
|
||||
}
|
||||
|
@ -363,6 +332,49 @@ where
|
|||
data
|
||||
}
|
||||
|
||||
/// Load
|
||||
#[inline(always)]
|
||||
unsafe fn load(
|
||||
&mut self,
|
||||
dst: u8,
|
||||
base: u8,
|
||||
offset: u64,
|
||||
count: u16,
|
||||
) -> Result<(), VmRunError> {
|
||||
let n: u8 = match dst {
|
||||
0 => 1,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
self.memory.load(
|
||||
self.ldst_addr_uber(dst, base, offset, count, n)?,
|
||||
self.registers
|
||||
.as_mut_ptr()
|
||||
.add(usize::from(dst) + usize::from(n))
|
||||
.cast(),
|
||||
usize::from(count).wrapping_sub(n.into()),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Store
|
||||
#[inline(always)]
|
||||
unsafe fn store(
|
||||
&mut self,
|
||||
dst: u8,
|
||||
base: u8,
|
||||
offset: u64,
|
||||
count: u16,
|
||||
) -> Result<(), VmRunError> {
|
||||
self.memory.store(
|
||||
self.ldst_addr_uber(dst, base, offset, count, 0)?,
|
||||
self.registers.as_ptr().add(usize::from(dst)).cast(),
|
||||
count.into(),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Perform binary operating over two registers
|
||||
#[inline(always)]
|
||||
unsafe fn binary_op<T: ValueVariant>(&mut self, op: impl Fn(T, T) -> T) {
|
||||
|
|
Loading…
Reference in a new issue