Skip to content

Commit 24c6573

Browse files
committed
Fix bytecode immediates
1 parent 31f8104 commit 24c6573

2 files changed

Lines changed: 62 additions & 7 deletions

File tree

fidget-bytecode/src/lib.rs

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ impl Bytecode {
197197
let mut data = vec![u32::MAX, 0u32];
198198
let mut reg_count = 0u8;
199199
let mut mem_count = 0u32;
200+
let mem_offset = u32::try_from(N).unwrap();
200201
for op in t.iter_asm() {
201202
let mut word = [0xFF; 4];
202203
let mut imm = None;
@@ -217,15 +218,15 @@ impl Bytecode {
217218

218219
RegOp::Load(reg, slot) => {
219220
store_reg(1, reg)?;
220-
store_reg(2, u8::MAX)?;
221-
mem_count = mem_count.max(slot);
222-
imm = Some(slot);
221+
word[2] = u8::MAX;
222+
mem_count = mem_count.max(slot - mem_offset);
223+
imm = Some(slot - mem_offset);
223224
}
224225
RegOp::Store(reg, slot) => {
225-
store_reg(1, u8::MAX)?;
226226
store_reg(2, reg)?;
227-
mem_count = mem_count.max(slot);
228-
imm = Some(slot);
227+
word[1] = u8::MAX;
228+
mem_count = mem_count.max(slot - mem_offset);
229+
imm = Some(slot - mem_offset);
229230
}
230231

231232
RegOp::CopyImm(out, imm_f32) => {
@@ -361,6 +362,7 @@ mod test {
361362

362363
#[test]
363364
fn load_store() {
365+
// Build a bytecode tape with only 2 registers to test load and store
364366
let mut ctx = fidget_core::Context::new();
365367
let x = ctx.x();
366368
let y = ctx.y();
@@ -373,9 +375,59 @@ mod test {
373375
let mut next = || *iter.next().unwrap();
374376
assert_eq!(next(), 0xFFFFFFFF); // start marker
375377
assert_eq!(next(), 0);
378+
379+
// Input(1, Z)
380+
assert_eq!(
381+
next().to_le_bytes(),
382+
[BytecodeOp::Input as u8, 1, 0xFF, 0xFF]
383+
);
384+
assert_eq!(next(), 2); // Z
385+
386+
// Copy from reg[1] -> mem[0]
387+
assert_eq!(
388+
next().to_le_bytes(),
389+
[BytecodeOp::Mem as u8, 0xFF, 1, 0xFF]
390+
);
391+
assert_eq!(next(), 0);
392+
393+
// Input(1, Y)
376394
assert_eq!(
377395
next().to_le_bytes(),
378-
[BytecodeOp::Copy as u8, 0, 0xFF, 0xFF]
396+
[BytecodeOp::Input as u8, 1, 0xFF, 0xFF]
397+
);
398+
assert_eq!(next(), 1); // Y
399+
400+
// Input(0, X)
401+
assert_eq!(
402+
next().to_le_bytes(),
403+
[BytecodeOp::Input as u8, 0, 0xFF, 0xFF]
379404
);
405+
assert_eq!(next(), 0); // X
406+
407+
// r1 = max(1, 0)
408+
assert_eq!(next().to_le_bytes(), [BytecodeOp::Max as u8, 1, 1, 0]);
409+
assert_eq!(next(), 0xFF000000);
410+
411+
// Copy from mem[0] -> reg[0]
412+
assert_eq!(
413+
next().to_le_bytes(),
414+
[BytecodeOp::Mem as u8, 0, 0xFF, 0xFF]
415+
);
416+
assert_eq!(next(), 0);
417+
418+
// r1 = max(1, 0)
419+
assert_eq!(next().to_le_bytes(), [BytecodeOp::Max as u8, 0, 0, 1]);
420+
assert_eq!(next(), 0xFF000000);
421+
422+
// output(0) = r0
423+
assert_eq!(
424+
next().to_le_bytes(),
425+
[BytecodeOp::Output as u8, 0, 0xFF, 0xFF]
426+
);
427+
assert_eq!(next(), 0);
428+
429+
assert_eq!(next(), 0xFFFFFFFF); // end marker
430+
assert_eq!(next(), 0xFFFFFFFF);
431+
assert!(iter.next().is_none());
380432
}
381433
}

fidget-core/src/compiler/op.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ opcodes!(
275275
///
276276
/// We have a maximum of 256 registers, though some tapes (e.g. ones
277277
/// targeting physical hardware) may choose to use fewer.
278+
///
279+
/// Note that memory slots are not zero-indexed; they start at `N` (where
280+
/// `N` is the register count).
278281
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
279282
pub enum RegOp<u8> {
280283
// default variants

0 commit comments

Comments
 (0)