Added relaxed relative 16 bit instructions

This commit is contained in:
Erin 2023-09-29 09:10:36 +02:00 committed by ondra05
parent c1905062c4
commit 354aac2d2c
3 changed files with 126 additions and 107 deletions

View file

@ -1,64 +1,69 @@
// OPCODE, MNEMONIC, TYPE, DOC; // OPCODE, MNEMONIC, TYPE, DOC;
0, UN, N, "Cause an unreachable code trap" ; 0, UN, N, "Cause an unreachable code trap" ;
1, TX, N, "Termiante execution" ; 1, TX, N, "Termiante execution" ;
2, NOP, N, "Do nothing" ; 2, NOP, N, "Do nothing" ;
3, ADD, RRR, "Addition" ; 3, ADD, RRR, "Addition" ;
4, SUB, RRR, "Subtraction" ; 4, SUB, RRR, "Subtraction" ;
5, MUL, RRR, "Multiplication" ; 5, MUL, RRR, "Multiplication" ;
6, AND, RRR, "Bitand" ; 6, AND, RRR, "Bitand" ;
7, OR, RRR, "Bitor" ; 7, OR, RRR, "Bitor" ;
8, XOR, RRR, "Bitxor" ; 8, XOR, RRR, "Bitxor" ;
9, SL, RRR, "Unsigned left bitshift" ; 9, SL, RRR, "Unsigned left bitshift" ;
10, SR, RRR, "Unsigned right bitshift" ; 10, SR, RRR, "Unsigned right bitshift" ;
11, SRS, RRR, "Signed right bitshift" ; 11, SRS, RRR, "Signed right bitshift" ;
12, CMP, RRR, "Signed comparsion" ; 12, CMP, RRR, "Signed comparsion" ;
13, CMPU, RRR, "Unsigned comparsion" ; 13, CMPU, RRR, "Unsigned comparsion" ;
14, DIR, RRRR, "Merged divide-remainder" ; 14, DIR, RRRR, "Merged divide-remainder" ;
15, NOT, RR, "Logical negation" ; 15, NOT, RR, "Logical negation" ;
16, ADDI, RRD, "Addition with immediate" ; 16, ADDI, RRD, "Addition with immediate" ;
17, MULI, RRD, "Multiplication with immediate" ; 17, MULI, RRD, "Multiplication with immediate" ;
18, ANDI, RRD, "Bitand with immediate" ; 18, ANDI, RRD, "Bitand with immediate" ;
19, ORI, RRD, "Bitor with immediate" ; 19, ORI, RRD, "Bitor with immediate" ;
20, XORI, RRD, "Bitxor with immediate" ; 20, XORI, RRD, "Bitxor with immediate" ;
21, SLI, RRW, "Unsigned left bitshift with immedidate"; 21, SLI, RRW, "Unsigned left bitshift with immedidate";
22, SRI, RRW, "Unsigned right bitshift with immediate"; 22, SRI, RRW, "Unsigned right bitshift with immediate";
23, SRSI, RRW, "Signed right bitshift with immediate" ; 23, SRSI, RRW, "Signed right bitshift with immediate" ;
24, CMPI, RRD, "Signed compare with immediate" ; 24, CMPI, RRD, "Signed compare with immediate" ;
25, CMPUI, RRD, "Unsigned compare with immediate" ; 25, CMPUI, RRD, "Unsigned compare with immediate" ;
26, CP, RR, "Copy register" ; 26, CP, RR, "Copy register" ;
27, SWA, RR, "Swap registers" ; 27, SWA, RR, "Swap registers" ;
28, LI, RD, "Load immediate" ; 28, LI, RD, "Load immediate" ;
29, LRA, RRO, "Load relative address" ; 29, LRA, RRO, "Load relative address" ;
30, LD, RRAH, "Load from absolute address" ; 30, LD, RRAH, "Load from absolute address" ;
31, ST, RRAH, "Store to absolute address" ; 31, ST, RRAH, "Store to absolute address" ;
32, LDR, RROH, "Load from relative 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" ; 34, BMC, RRH, "Copy block of memory" ;
35, BRC, RRB, "Copy register block" ; 35, BRC, RRB, "Copy register block" ;
36, JMP, A, "Absolute jump" ; 36, JMP, A, "Absolute jump" ;
37, JMPR, O, "Relative jump" ; 37, JMPR, O, "Relative jump" ;
38, JAL, RRA, "Linking absolute jump" ; 38, JAL, RRA, "Linking absolute jump" ;
39, JALR, RRO, "Linking relative jump" ; 39, JALR, RRO, "Linking relative jump" ;
40, JEQ, RRP, "Branch on equal" ; 40, JEQ, RRP, "Branch on equal" ;
41, JNE, RRP, "Branch on nonequal" ; 41, JNE, RRP, "Branch on nonequal" ;
42, JLT, RRP, "Branch on lesser-than (signed)" ; 42, JLT, RRP, "Branch on lesser-than (signed)" ;
43, JGT, RRP, "Branch on greater-than (signed)" ; 43, JGT, RRP, "Branch on greater-than (signed)" ;
44, JLTU, RRP, "Branch on lesser-than (unsigned)" ; 44, JLTU, RRP, "Branch on lesser-than (unsigned)" ;
45, JGTU, RRP, "Branch on greater-than (unsigned)" ; 45, JGTU, RRP, "Branch on greater-than (unsigned)" ;
46, ECALL, N, "Issue ecall trap" ; 46, ECALL, N, "Issue ecall trap" ;
47, ADDF, RRR, "Floating addition" ; 47, ADDF, RRR, "Floating addition" ;
48, SUBF, RRR, "Floating subtraction" ; 48, SUBF, RRR, "Floating subtraction" ;
49, MULF, RRR, "Floating multiply" ; 49, MULF, RRR, "Floating multiply" ;
50, DIRF, RRRR, "Merged floating divide-remainder" ; 50, DIRF, RRRR, "Merged floating divide-remainder" ;
51, FMAF, RRRR, "Fused floating multiply-add" ; 51, FMAF, RRRR, "Fused floating multiply-add" ;
52, NEGF, RR, "Floating sign negation" ; 52, NEGF, RR, "Floating sign negation" ;
53, ITF, RR, "Int to float" ; 53, ITF, RR, "Int to float" ;
54, FTI, RR, "Float to int" ; 54, FTI, RR, "Float to int" ;
55, ADDFI, RRD, "Floating addition with immediate" ; 55, ADDFI, RRD, "Floating addition with immediate" ;
56, MULFI, RRD, "Floating multiplication 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)" ;

View file

@ -35,6 +35,7 @@ define_items! {
OpsRRD (OpR, OpR, OpD ), OpsRRD (OpR, OpR, OpD ),
OpsRRAH (OpR, OpR, OpA, OpH), OpsRRAH (OpR, OpR, OpA, OpH),
OpsRROH (OpR, OpR, OpO, OpH), OpsRROH (OpR, OpR, OpO, OpH),
OpsRRPH (OpR, OpR, OpP, OpH),
OpsRRO (OpR, OpR, OpO ), OpsRRO (OpR, OpR, OpO ),
OpsRRP (OpR, OpR, OpP ), OpsRRP (OpR, OpR, OpP ),
} }
@ -42,6 +43,7 @@ define_items! {
unsafe impl BytecodeItem for OpA {} unsafe impl BytecodeItem for OpA {}
unsafe impl BytecodeItem for OpB {} unsafe impl BytecodeItem for OpB {}
unsafe impl BytecodeItem for OpO {} unsafe impl BytecodeItem for OpO {}
unsafe impl BytecodeItem for OpP {}
unsafe impl BytecodeItem for () {} unsafe impl BytecodeItem for () {}
::with_builtin_macros::with_builtin! { ::with_builtin_macros::with_builtin! {

View file

@ -12,8 +12,8 @@ use {
crate::mem::{addr::AddressOp, Address}, crate::mem::{addr::AddressOp, Address},
core::{cmp::Ordering, mem::size_of, ops}, core::{cmp::Ordering, mem::size_of, ops},
hbbytecode::{ hbbytecode::{
BytecodeItem, OpA, OpO, OpsRD, OpsRR, OpsRRAH, OpsRRB, OpsRRD, OpsRRH, OpsRRO, OpsRROH, BytecodeItem, OpA, OpO, OpP, OpsRD, OpsRR, OpsRRAH, OpsRRB, OpsRRD, OpsRRH, OpsRRO,
OpsRRP, OpsRRR, OpsRRRR, OpsRRW, OpsRROH, OpsRRP, OpsRRPH, OpsRRR, OpsRRRR, OpsRRW,
}, },
}; };
@ -163,64 +163,20 @@ where
LD => { LD => {
// Load. If loading more than register size, continue on adjecent registers // Load. If loading more than register size, continue on adjecent registers
let OpsRRAH(dst, base, off, count) = self.decode(); let OpsRRAH(dst, base, off, count) = self.decode();
let n: u8 = match dst { self.load(dst, base, off, count)?;
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()),
)?;
} }
ST => { ST => {
// Store. Same rules apply as to LD // Store. Same rules apply as to LD
let OpsRRAH(dst, base, off, count) = self.decode(); let OpsRRAH(dst, base, off, count) = self.decode();
self.memory.store( self.store(dst, base, off, count)?;
self.ldst_addr_uber(dst, base, off, count, 0)?,
self.registers.as_ptr().add(usize::from(dst)).cast(),
count.into(),
)?;
} }
LDR => { LDR => {
let OpsRROH(dst, base, off, count) = self.decode(); let OpsRROH(dst, base, off, count) = self.decode();
let n: u8 = match dst { self.load(dst, base, u64::from(off).wrapping_add(self.pc.get()), count)?;
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()),
)?;
} }
STR => { STR => {
let OpsRROH(dst, base, off, count) = self.decode(); let OpsRROH(dst, base, off, count) = self.decode();
self.memory.store( self.store(dst, base, u64::from(off).wrapping_add(self.pc.get()), count)?;
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(),
)?;
} }
BMC => { BMC => {
const INS_SIZE: usize = size_of::<OpsRRH>() + 1; const INS_SIZE: usize = size_of::<OpsRRH>() + 1;
@ -341,6 +297,19 @@ where
} }
ADDFI => self.binary_op_imm::<f64>(ops::Add::add), ADDFI => self.binary_op_imm::<f64>(ops::Add::add),
MULFI => self.binary_op_imm::<f64>(ops::Mul::mul), 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)), op => return Err(VmRunError::InvalidOpcode(op)),
} }
} }
@ -363,6 +332,49 @@ where
data 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 /// Perform binary operating over two registers
#[inline(always)] #[inline(always)]
unsafe fn binary_op<T: ValueVariant>(&mut self, op: impl Fn(T, T) -> T) { unsafe fn binary_op<T: ValueVariant>(&mut self, op: impl Fn(T, T) -> T) {