Added relaxed relative 16 bit instructions

pull/2/head
ondra05 2023-09-29 09:10:36 +02:00
parent bd6d795f8a
commit e6b5f8d27d
No known key found for this signature in database
GPG Key ID: 0DA6D2BB2285E881
3 changed files with 126 additions and 107 deletions

View File

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

View File

@ -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! {

View File

@ -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) {