Added relaxed relative 16 bit instructions
This commit is contained in:
parent
3e4095da6f
commit
2f8612c6d2
|
@ -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)" ;
|
||||
|
|
|
@ -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