From 354aac2d2c5e1aba9e89207f171f5221ded2ad23 Mon Sep 17 00:00:00 2001 From: Erin Date: Fri, 29 Sep 2023 09:10:36 +0200 Subject: [PATCH] Added relaxed relative 16 bit instructions --- hbbytecode/instructions.in | 119 +++++++++++++++++++------------------ hbbytecode/src/lib.rs | 2 + hbvm/src/vmrun.rs | 112 ++++++++++++++++++---------------- 3 files changed, 126 insertions(+), 107 deletions(-) diff --git a/hbbytecode/instructions.in b/hbbytecode/instructions.in index f9edb07..6bf97e0 100644 --- a/hbbytecode/instructions.in +++ b/hbbytecode/instructions.in @@ -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)" ; diff --git a/hbbytecode/src/lib.rs b/hbbytecode/src/lib.rs index 06414f8..45ed510 100644 --- a/hbbytecode/src/lib.rs +++ b/hbbytecode/src/lib.rs @@ -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! { diff --git a/hbvm/src/vmrun.rs b/hbvm/src/vmrun.rs index 76c2bb4..da69627 100644 --- a/hbvm/src/vmrun.rs +++ b/hbvm/src/vmrun.rs @@ -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::() + 1; @@ -341,6 +297,19 @@ where } ADDFI => self.binary_op_imm::(ops::Add::add), MULFI => self.binary_op_imm::(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::()), 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(&mut self, op: impl Fn(T, T) -> T) {