From c0c1f9c2d51c8a56512913070899464d22a7c150 Mon Sep 17 00:00:00 2001 From: fractasy Date: Mon, 15 Jun 2026 09:28:22 +0200 Subject: [PATCH 1/2] Optimize assembly dynamic jump --- core/src/riscv2zisk_context.rs | 14 ++++++++++++ core/src/zisk_rom_2_asm.rs | 40 +++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/core/src/riscv2zisk_context.rs b/core/src/riscv2zisk_context.rs index c25afb47e..efaf92c21 100644 --- a/core/src/riscv2zisk_context.rs +++ b/core/src/riscv2zisk_context.rs @@ -75,6 +75,8 @@ const FLOAT_HANDLER_RETURN_ADDR: u64 = FLOAT_HANDLER_ADDR + 4 * 34; // 31 regs + /// Mask to apply to the target address of JALR instructions, to ensure the least significant bit is 0 const JALR_MASK: u64 = 0xfffffffffffffffe; +const NO_FLOAT_ECALL_ADDR: u64 = ROM_EXIT + 0x58; + /// Context to store the list of converted ZisK instructions, including their program address and a /// map to store the instructions pub struct Riscv2ZiskContext<'a> { @@ -1261,7 +1263,15 @@ impl Riscv2ZiskContext<'_> { pub fn ecall(&mut self, i: &RiscvInstruction) { let mut zib = ZiskInstBuilder::new_from_riscv(i.rom_address, i.inst.clone()); zib.src_a("imm", 0, false); + // If the float feature is enabled, we use the MTVEC register as the address to jump to for + // the ecall. If not, we use a fixed address (NO_FLOAT_ECALL_ADDR) for the ecall. This + // allows us to handle system calls differently based on whether floating-point operations + // are supported or not. When float is disabled, this avoids the only dynamic jump to the + // lower addresses space, improving the performance of dynamic jumps in general. + #[cfg(feature = "float")] zib.src_b("mem", MTVEC, false); + #[cfg(not(feature = "float"))] + zib.src_b("imm", NO_FLOAT_ECALL_ADDR, false); zib.op("copyb").unwrap(); zib.store_pc("reg", 1, false); zib.set_pc(); @@ -2432,7 +2442,11 @@ pub fn add_entry_exit_jmp(rom: &mut ZiskRom, addr: u64) { // Calculate the trap handler rom pc address as an offset from the current instruction address // to the beginning of the ecall section + #[cfg(not(feature = "float"))] + assert!(rom.next_init_inst_addr == ROM_EXIT + 4); let trap_handler: u64 = rom.next_init_inst_addr + 0x54; + #[cfg(not(feature = "float"))] + assert!(trap_handler == NO_FLOAT_ECALL_ADDR); // :0000 we note the rom pc address offset from the first address for each instruction // Store the Zisk architecture ID into memory diff --git a/core/src/zisk_rom_2_asm.rs b/core/src/zisk_rom_2_asm.rs index 67287ea79..39f093b07 100644 --- a/core/src/zisk_rom_2_asm.rs +++ b/core/src/zisk_rom_2_asm.rs @@ -7907,8 +7907,11 @@ impl ZiskRom2Asm { high_address, ctx.comment_str("is pc a low address?") ); - *code += &format!("\tcmp {REG_PC}, {REG_ADDRESS}\n"); - *code += &format!("\tjb pc_{:x}_jump_to_low_address\n", ctx.pc); + #[cfg(feature = "float")] + { + *code += &format!("\tcmp {REG_PC}, {REG_ADDRESS}\n"); + *code += &format!("\tjb pc_{:x}_jump_to_low_address\n", ctx.pc); + } *code += &format!("\tsub {}, {} {}\n", REG_PC, REG_ADDRESS, ctx.comment_str("pc -= ROM_ADDR")); *code += &format!( @@ -7925,21 +7928,24 @@ impl ZiskRom2Asm { ctx.comment_str("address = map[pc]") ); *code += &format!("\tjmp {} {}\n", REG_ADDRESS, ctx.comment_str("jump to address")); - *code += &format!("pc_{:x}_jump_to_low_address:\n", ctx.pc); - *code += &format!("\tsub {}, 0x1000 {}\n", REG_PC, ctx.comment_str("pc -= ROM_ENTRY")); - *code += &format!( - "\tlea {}, [map_pc_1000] {}\n", - REG_ADDRESS, - ctx.comment_str("address = map[ROM_ENTRY]") - ); - *code += &format!( - "\tmov {}, [{} + {}*2] {}\n", - REG_ADDRESS, - REG_ADDRESS, - REG_PC, - ctx.comment_str("address = map[pc]") - ); - *code += &format!("\tjmp {} {}\n", REG_ADDRESS, ctx.comment_str("jump to address")); + #[cfg(feature = "float")] + { + *code += &format!("pc_{:x}_jump_to_low_address:\n", ctx.pc); + *code += &format!("\tsub {}, 0x1000 {}\n", REG_PC, ctx.comment_str("pc -= ROM_ENTRY")); + *code += &format!( + "\tlea {}, [map_pc_1000] {}\n", + REG_ADDRESS, + ctx.comment_str("address = map[ROM_ENTRY]") + ); + *code += &format!( + "\tmov {}, [{} + {}*2] {}\n", + REG_ADDRESS, + REG_ADDRESS, + REG_PC, + ctx.comment_str("address = map[pc]") + ); + *code += &format!("\tjmp {} {}\n", REG_ADDRESS, ctx.comment_str("jump to address")); + } } /*************/ From 3fc20284b73d707a22fcc183c5c319eaf15fceda Mon Sep 17 00:00:00 2001 From: fractasy Date: Mon, 15 Jun 2026 14:09:48 +0200 Subject: [PATCH 2/2] Fix cargo clippy --- core/src/riscv2zisk_context.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/riscv2zisk_context.rs b/core/src/riscv2zisk_context.rs index efaf92c21..d3cf369e9 100644 --- a/core/src/riscv2zisk_context.rs +++ b/core/src/riscv2zisk_context.rs @@ -75,6 +75,7 @@ const FLOAT_HANDLER_RETURN_ADDR: u64 = FLOAT_HANDLER_ADDR + 4 * 34; // 31 regs + /// Mask to apply to the target address of JALR instructions, to ensure the least significant bit is 0 const JALR_MASK: u64 = 0xfffffffffffffffe; +#[cfg(not(feature = "float"))] const NO_FLOAT_ECALL_ADDR: u64 = ROM_EXIT + 0x58; /// Context to store the list of converted ZisK instructions, including their program address and a