diff options
author | iximeow <me@iximeow.net> | 2025-04-13 01:54:24 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2025-04-13 01:54:24 -0700 |
commit | c785240f7593abd3fc5b9c8c5da9e05bade61012 (patch) | |
tree | 32509de1efb396a8905546259fc2808b0c410f5c | |
parent | fba052bca5783a315dbf9f0d539a27bbe1901c39 (diff) |
the rest of the extenders
-rw-r--r-- | src/lib.rs | 170 | ||||
-rw-r--r-- | tests/from_brain.rs | 294 |
2 files changed, 378 insertions, 86 deletions
@@ -1164,7 +1164,7 @@ pub enum Operand { RegMemIndexedBrev { base: u8, mu: u8 }, - Absolute { addr: i8 }, + Absolute { addr: u32 }, GpOffset { offset: u32 }, } @@ -1919,7 +1919,8 @@ fn decode_instruction< JumpEq, JumpNeq, JumpGt, JumpLe, JumpGtu, JumpLeu ]; - handler.on_source_decoded(Operand::imm_u32(lllll as u8 as u32))?; + + handler.on_source_decoded(Operand::immext(lllll as u32, extender, |i| Ok(Operand::imm_u32(i)))?)?; handler.on_opcode_decoded(OPS[op as usize - 0b10000])?; } else if op < 0b11000 { let opc = if op == 0b10110 { @@ -2034,7 +2035,7 @@ fn decode_instruction< let vv = ((inst >> 5) & 0b11) as u8; let iiiiii = (inst >> 7) & 0b11_1111; let l_hi = (((inst >> 13) & 0b1) << 5) as u8; - let llllll = (l_lo | l_hi) as u8; + let llllll = (l_lo | l_hi) as u32; let op = (inst >> 21) & 0b11; let negated = nn & 1 == 1; @@ -2042,27 +2043,38 @@ fn decode_instruction< handler.inst_predicated(vv, negated, pred_new)?; + let offset = iiiiii; + handler.on_dest_decoded(Operand::RegOffset { base: sssss, offset })?; + match op { 0b00 => { handler.on_opcode_decoded(Opcode::StoreMemb)?; - let offset = iiiiii; - let imm = (llllll as i8) << 2 >> 2; - handler.on_dest_decoded(Operand::RegOffset { base: sssss, offset })?; - handler.on_source_decoded(Operand::imm_i8(imm))?; + + let imm = Operand::with_extension(llllll, extender, + |imm| Ok(Operand::imm_u32(imm)), + |imm| Ok(Operand::imm_i8((imm as i8) << 2 >> 2)), + )?; + handler.on_source_decoded(imm)?; } 0b01 => { handler.on_opcode_decoded(Opcode::StoreMemh)?; - let offset = iiiiii << 1; - let imm = (llllll as i16) << 10 >> 10; - handler.on_dest_decoded(Operand::RegOffset { base: sssss, offset })?; - handler.on_source_decoded(Operand::imm_i16(imm))?; + + let imm = Operand::with_extension(llllll, extender, + |imm| Ok(Operand::imm_u32(imm)), + |imm| Ok(Operand::imm_i16((imm as i16) << 10 >> 10)), + )?; + handler.on_source_decoded(imm)?; } 0b10 => { handler.on_opcode_decoded(Opcode::StoreMemw)?; - let offset = iiiiii << 2; let imm = (llllll as i32) << 26 >> 26; - handler.on_dest_decoded(Operand::RegOffset { base: sssss, offset })?; handler.on_source_decoded(Operand::imm_i32(imm))?; + + let imm = Operand::with_extension(llllll, extender, + |imm| Ok(Operand::imm_u32(imm)), + |imm| Ok(Operand::imm_i32((imm as i32) << 26 >> 26)), + )?; + handler.on_source_decoded(imm)?; } _ => { return Err(DecodeError::InvalidOpcode); @@ -2454,8 +2466,13 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Jump)?; let imm = ((inst >> 1) & 0x1fff) | ((inst >> 3) & 0xffe000); let imm = ((imm as i32) << 10) >> 10; - // TODO: extend - handler.on_dest_decoded(Operand::PCRel32 { rel: imm << 2 })?; + handler.on_dest_decoded( + Operand::with_extension( + (imm << 2) as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; }, 0b101 => { // V73 Call to address @@ -2467,7 +2484,13 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Call)?; let imm = ((inst >> 1) & 0x1fff) | ((inst >> 3) & 0xffe000); let imm = ((imm as i32) << 10) >> 10; - handler.on_dest_decoded(Operand::PCRel32 { rel: imm << 2 })?; + handler.on_dest_decoded( + Operand::with_extension( + (imm << 2) as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; }, 0b110 => { // V73 Predicated jump/call relative @@ -2491,12 +2514,19 @@ fn decode_instruction< handler.inst_predicated(uu as u8, negated, false)?; opcode_check!(!dotnew); } else { - // ... not shown as extended in the manual? + // ... not shown as extended in the manual? does have an + // `apply_extension()` though handler.on_opcode_decoded(Opcode::Jump)?; handler.inst_predicated(uu as u8, negated, dotnew)?; handler.branch_hint(hint_taken)?; } - handler.on_dest_decoded(Operand::PCRel32 { rel: i15 << 2 })?; + handler.on_dest_decoded( + Operand::with_extension( + (i15 << 2) as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; } 0b111 => { return Err(DecodeError::InvalidOpcode); @@ -2518,7 +2548,13 @@ fn decode_instruction< let rel = ((i7 << 1) as i8 as i32) << 1; handler.on_opcode_decoded(Opcode::Loop0)?; - handler.on_source_decoded(Operand::PCRel32 { rel })?; + handler.on_source_decoded( + Operand::with_extension( + rel as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; } 0b0000001 => { @@ -2529,7 +2565,13 @@ fn decode_instruction< let rel = ((i7 << 1) as i8 as i32) << 1; handler.on_opcode_decoded(Opcode::Loop1)?; - handler.on_source_decoded(Operand::PCRel32 { rel })?; + handler.on_source_decoded( + Operand::with_extension( + rel as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; } 0b0000010 | 0b0000011 => { @@ -2543,7 +2585,13 @@ fn decode_instruction< let rel = ((i7 << 1) as i8 as i32) << 1; handler.on_opcode_decoded(Opcode::Sp1Loop0)?; - handler.on_source_decoded(Operand::PCRel32 { rel })?; + handler.on_source_decoded( + Operand::with_extension( + rel as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_dest_decoded(Operand::pred(3))?; } @@ -2555,7 +2603,13 @@ fn decode_instruction< let rel = ((i7 << 1) as i8 as i32) << 1; handler.on_opcode_decoded(Opcode::Sp2Loop0)?; - handler.on_source_decoded(Operand::PCRel32 { rel })?; + handler.on_source_decoded( + Operand::with_extension( + rel as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_dest_decoded(Operand::pred(3))?; } @@ -2567,7 +2621,13 @@ fn decode_instruction< let rel = ((i7 << 1) as i8 as i32) << 1; handler.on_opcode_decoded(Opcode::Sp3Loop0)?; - handler.on_source_decoded(Operand::PCRel32 { rel })?; + handler.on_source_decoded( + Operand::with_extension( + rel as u32, extender, + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + |rel| Ok(Operand::PCRel32 { rel: rel as i32 }), + )? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_dest_decoded(Operand::pred(3))?; } @@ -2893,7 +2953,9 @@ fn decode_instruction< let ddddd = reg_b0(inst); handler.on_opcode_decoded(Opcode::Add)?; handler.on_source_decoded(Operand::cr(9))?; - handler.on_source_decoded(Operand::imm_u8(iiiiii as u8))?; + handler.on_source_decoded( + Operand::immext(iiiiii, extender, |i| Ok(Operand::imm_u8(i as u8)) )? + )?; handler.on_dest_decoded(Operand::gpr(ddddd))?; } o if o & 0b1111000 == 0b1011000 => { @@ -3197,9 +3259,9 @@ fn decode_instruction< if reg_first { handler.on_source_decoded(Operand::gpr(sssss))?; - handler.on_source_decoded(Operand::imm_i8(i))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?; } else { - handler.on_source_decoded(Operand::imm_i8(i))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?; handler.on_source_decoded(Operand::gpr(sssss))?; } } @@ -3218,7 +3280,7 @@ fn decode_instruction< handler.inst_predicated(pred_number as u8, negated, dotnew)?; handler.on_dest_decoded(Operand::gpr(ddddd))?; handler.on_source_decoded(Operand::gpr(sssss))?; - handler.on_source_decoded(Operand::imm_i8(i))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?; } 0b0101 => { let sssss = reg_b16(inst); @@ -3249,9 +3311,9 @@ fn decode_instruction< handler.on_source_decoded(Operand::gpr(sssss))?; if opcode == Opcode::CmpGtu { operand_check!(i >= 0); - handler.on_source_decoded(Operand::imm_u16(i as u16))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_u16(i as u16)))?)?; } else { - handler.on_source_decoded(Operand::imm_i16(i))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i16(i as i16)))?)?; } } 0b0110 => { @@ -3324,7 +3386,7 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Mux)?; handler.on_dest_decoded(Operand::gpr(ddddd))?; handler.on_source_decoded(Operand::pred(uu as u8))?; - handler.on_source_decoded(Operand::imm_i8(i))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?; handler.on_source_decoded(Operand::imm_i8(l))?; } 0b1100 => { @@ -3337,15 +3399,16 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Combine)?; handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; - handler.on_source_decoded(Operand::imm_i8(i))?; if min_op & 0b100 == 0 { + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?; handler.on_source_decoded(Operand::imm_i8(l))?; } else { + handler.on_source_decoded(Operand::imm_i8(i))?; // TODO: technically more restrictive than the manual - these bits are // dontcare, not 0 let l = l as u8; operand_check!(l & 0xc0 == 0); - handler.on_source_decoded(Operand::imm_u8(l))?; + handler.on_source_decoded(Operand::immext(l as u32, extender, |l| Ok(Operand::imm_u8(l as u8)))?)?; } } 0b1101 => { @@ -3369,7 +3432,7 @@ fn decode_instruction< handler.inst_predicated(pred_number as u8, negated, dotnew)?; handler.on_dest_decoded(Operand::gpr(ddddd))?; - handler.on_source_decoded(Operand::imm_i16(i))?; + handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i16(i as i16)))?)?; } 0b1111 => { // 0b0111_1111_... @@ -4694,7 +4757,10 @@ fn decode_instruction< let i6 = ((ii_high << 4) | iiii) as i8; let dotnew = (inst >> 13) & 1 == 1; decode_store_ops(handler, minbits, ttttt, |_shamt| { - Ok(Operand::Absolute { addr: i6 }) + Operand::with_extension(i6 as u32, extender, + |addr| Ok(Operand::Absolute { addr }), + |addr| Ok(Operand::Absolute { addr }), + ) })?; handler.inst_predicated(vv as u8, negated, dotnew)?; } @@ -4714,7 +4780,7 @@ fn decode_instruction< handler.on_dest_decoded(Operand::gpr(ddddd))?; handler.on_source_decoded(Operand::gpr(sssss))?; - handler.on_source_decoded(Operand::imm_i16(i as i16))?; + handler.on_source_decoded(Operand::immext(i, extender, |i| Ok(Operand::imm_i16(i as i16)))?)?; } 0b1100 => { let ddddd = reg_b0(inst); @@ -5663,7 +5729,9 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::AddMpyi)?; handler.on_dest_decoded(Operand::gpr(ddddd))?; - handler.on_source_decoded(Operand::imm_u8(i as u8))?; + handler.on_source_decoded( + Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_source_decoded(Operand::gpr(ttttt))?; } @@ -5683,7 +5751,9 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::AddMpyi)?; handler.on_dest_decoded(Operand::gpr(ddddd))?; - handler.on_source_decoded(Operand::imm_u8(i as u8))?; + handler.on_source_decoded( + Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))? + )?; handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_source_decoded(Operand::imm_u8(l as u8))?; } @@ -5732,12 +5802,13 @@ fn decode_instruction< let i9 = (inst >> 5) & 0b1_1111_1111; let i_hi = (inst >> 21) & 1; let i10 = i9 | (i_hi << 9); - let i = (i10 as i16) << 6 >> 6; handler.on_opcode_decoded(Opcode::OrAnd)?; handler.on_dest_decoded(Operand::gpr(reg_b16(inst)))?; handler.on_source_decoded(Operand::gpr(reg_b0(inst)))?; handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?; - handler.on_source_decoded(Operand::imm_i16(i))?; + handler.on_source_decoded( + Operand::immext(i10, extender, |i| Ok(Operand::imm_i16((i as i16) << 6 >> 6)))? + )?; } 0b10 => { let i9 = (inst >> 5) & 0b1_1111_1111; @@ -5765,7 +5836,6 @@ fn decode_instruction< let i_mid = (inst >> 13) & 0b1; let i_hi = (inst >> 21) & 0b11; let i = i_lo | (i_mid << 3) | (i_hi << 4); - let s6 = (i as i8) << 2 >> 2; let op = (inst >> 23) & 1; @@ -5774,10 +5844,14 @@ fn decode_instruction< if op == 0 { handler.on_opcode_decoded(Opcode::AddAdd)?; handler.on_source_decoded(Operand::gpr(uuuuu))?; - handler.on_source_decoded(Operand::imm_i8(s6))?; + handler.on_source_decoded( + Operand::immext(i, extender, |i| Ok(Operand::imm_i8((i as i8) << 2 >> 2)))? + )?; } else { handler.on_opcode_decoded(Opcode::AddSub)?; - handler.on_source_decoded(Operand::imm_i8(s6))?; + handler.on_source_decoded( + Operand::immext(i, extender, |i| Ok(Operand::imm_i8((i as i8) << 2 >> 2)))? + )?; handler.on_source_decoded(Operand::gpr(uuuuu))?; } } @@ -5836,7 +5910,9 @@ fn decode_instruction< if opc & 0b10_00 != 0 { operand_check!(imm < 0b1000_0000); } - handler.on_source_decoded(Operand::imm_u8(imm as u8))?; + handler.on_source_decoded( + Operand::immext(imm, extender, |imm| Ok(Operand::imm_u8(imm as u8)))? + )?; } 0b1110 => { let xxxxx = reg_b16(inst); @@ -5851,7 +5927,9 @@ fn decode_instruction< let u5 = reg_b8(inst); handler.on_dest_decoded(Operand::gpr(xxxxx))?; - handler.on_source_decoded(Operand::imm_u8(i as u8))?; + handler.on_source_decoded( + Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))? + )?; handler.on_source_decoded(Operand::gpr(xxxxx))?; handler.on_source_decoded(Operand::imm_u8(u5))?; @@ -5922,7 +6000,7 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Mpyi)?; handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?; handler.on_source_decoded(Operand::gpr(sssss))?; - handler.on_source_decoded(Operand::imm_u8(i as u8))?; + handler.on_source_decoded(Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))?)?; if op_hi < 0b100 { handler.assign_mode(AssignMode::AddAssign)?; } else { @@ -5935,7 +6013,7 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Add)?; handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?; handler.on_source_decoded(Operand::gpr(sssss))?; - handler.on_source_decoded(Operand::imm_i8(i as i8))?; + handler.on_source_decoded(Operand::immext(i, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?; if op_hi < 0b100 { handler.assign_mode(AssignMode::AddAssign)?; } else { diff --git a/tests/from_brain.rs b/tests/from_brain.rs index 334dc82..5eec602 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -26,62 +26,65 @@ fn extenders() { * // it turns out these are encoded by applying an extender to the `mem{b,ub,...}(gp+#u16)` forms * [x]: Rd = mem{b,ub,h,uh,w,d}(##U32) * // predicated loads - * [ ]: if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (Rs + ##U32) + * [x]: if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (Rs + ##U32) * [x]: Rd = mem{b,ub,h,uh,w,d} (Rs + ##U32) * [x]: Rd = mem{b,ub,h,uh,w,d} (Re=##U32) * [x]: Rd = mem{b,ub,h,uh,w,d} (Rt<<#u2 + ##U32) - * [ ]: if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (##U32) + * [x]: if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (##U32) * // it turns out these are encoded by applying an extender to the `mem{b,ub,...}(gp+#u16)` forms * [x]: mem{b,h,w,d}(##U32) = Rs[.new] * // predicated stores - * [ ]: if ([!]Pt[.new]) mem{b,h,w,d}(Rs + ##U32) = Rt[.new] + * [x]: if ([!]Pt[.new]) mem{b,h,w,d}(Rs + ##U32) = Rt[.new] * [x]: mem{b,h,w,d}(Rs + ##U32) = Rt[.new] * [x]: mem{b,h,w,d}(Rd=##U32) = Rt[.new] * [x]: mem{b,h,w,d}(Ru<<#u2 + ##U32) = Rt[.new] - * [ ]: if ([!]Pt[.new]) mem{b,h,w,d}(##U32) = Rt[.new] - * [ ]: [if [!]Ps] memw(Rs + #u6) = ##U32 // constant store - * [ ]: memw(Rs + Rt<<#u2) = ##U32 // constant store - * [ ]: if (cmp.xx(Rs.new,##U32)) jump:hint target + * [x]: if ([!]Pt[.new]) mem{b,h,w,d}(##U32) = Rt[.new] + * [x]: [if [!]Ps] memw(Rs + #u6) = ##U32 // constant store + * // this just does not exist?! + * [!]: memw(Rs + Rt<<#u2) = ##U32 // constant store + * [x]: if (cmp.xx(Rs.new,##U32)) jump:hint target * [x]: Rd = ##u32 - * [ ]: Rdd = combine(Rs,##u32) - * [ ]: Rdd = combine(##u32,Rs) - * [ ]: Rdd = combine(##u32,#s8) - * [ ]: Rdd = combine(#s8,##u32) - * [ ]: Rd = mux(Pu, Rs,##u32) - * [ ]: Rd = mux(Pu, ##u32, Rs) - * [ ]: Rd = mux(Pu,##u32,#s8) - * [ ]: if ([!]Pu[.new]) Rd = add(Rs,##u32) - * [ ]: if ([!]Pu[.new]) Rd = ##u32 - * [ ]: Pd = [!]cmp.eq (Rs,##u32) - * [ ]: Pd = [!]cmp.gt (Rs,##u32) - * [ ]: Pd = [!]cmp.gtu (Rs,##u32) - * [ ]: Rd = [!]cmp.eq(Rs,##u32) + * [x]: Rdd = combine(Rs,##u32) + * [x]: Rdd = combine(##u32,Rs) + * [x]: Rdd = combine(##u32,#s8) + * [x]: Rdd = combine(#s8,##u32) + * [x]: Rd = mux(Pu, Rs,##u32) + * [x]: Rd = mux(Pu, ##u32, Rs) + * [x]: Rd = mux(Pu,##u32,#s8) + * [x]: if ([!]Pu[.new]) Rd = add(Rs,##u32) + * [x]: if ([!]Pu[.new]) Rd = ##u32 + * [x]: Pd = [!]cmp.eq (Rs,##u32) + * [x]: Pd = [!]cmp.gt (Rs,##u32) + * [x]: Pd = [!]cmp.gtu (Rs,##u32) * [x]: Rd = and(Rs,##u32) * [x]: Rd = or(Rs,##u32) * [x]: Rd = sub(##u32,Rs) - * [ ]: Rd = add(Rs,##s32) - * [ ]: Rd = mpyi(Rs,##u32) - * [ ]: Rd += mpyi(Rs,##u32) - * [ ]: Rd -= mpyi(Rs,##u32) - * [ ]: Rx += add(Rs,##u32) - * [ ]: Rx -= add(Rs,##u32) + * [x]: Rd = add(Rs,##s32) + * // this does not exist... + * [!]: Rd = mpyi(Rs,##u32) + * [x]: Rd += mpyi(Rs,##u32) + * [x]: Rd -= mpyi(Rs,##u32) + * [x]: Rx += add(Rs,##u32) + * [x]: Rx -= add(Rs,##u32) * [x]: Rd = ##u32 - * [ ]: Rd = add(Rs,##s32) - * [ ]: jump (PC + ##s32) - * [ ]: call (PC + ##s32) - * [ ]: if ([!]Pu) call (PC + ##s32) - * [ ]: Pd = spNloop0(PC+##s32,Rs/#U10) - * [ ]: loop0/1 (PC+##s32,#Rs/#U10) - * [ ]: Rd = add(pc,##s32) - * [ ]: Rd = add(##u32,mpyi(Rs,#u6)) - * [ ]: Rd = add(##u32,mpyi(Rs,Rt)) - * [ ]: Rd = add(Rs,add(Rt,##u32)) + * [x]: Rd = add(Rs,##s32) + * [x]: jump (PC + ##s32) + * [x]: call (PC + ##s32) + * [x]: if ([!]Pu) call (PC + ##s32) + * [x]: Pd = spNloop0(PC+##s32,Rs/#U10) + * [x]: loop0/1 (PC+##s32,#Rs/#U10) + * [x]: Rd = add(pc,##s32) + * [x]: Rd = add(##u32,mpyi(Rs,#u6)) + * [x]: Rd = add(##u32,mpyi(Rs,Rt)) + * [x]: Rd = add(Rs,add(Rt,##u32)) * [x]: Rd = add(Rs,sub(##u32,Rt)) - * [x]: Rd = sub(##u32,add(Rs,Rt)) + * // doesn't exist? + * [!]: Rd = sub(##u32,add(Rs,Rt)) * [x]: Rd = or(Rs,and(Rt,##u32)) - * [ ]: Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,#U5)) - * [ ]: Rx = add/sub/and/or (##u32,asl/asr/lsr(Rs,Rx)) - * [ ]: Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,Rs)) + * [x]: Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,#U5)) + * // neither of these exist? + * [!]: Rx = add/sub/and/or (##u32,asl/asr/lsr(Rs,Rx)) + * [!]: Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,Rs)) * [ ]: Pd = cmpb/h.{eq,gt,gtu} (Rs,##u32) */ @@ -339,6 +342,215 @@ fn extenders() { 0xc7, 0xc6, 0xc4, 0xad, ], "{ memd(r4<<1 + 0x207) = r7:6 }"); + // not writing out permutations for all predicated instructions come on now + // if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (Rs + ##U32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xa8, 0xf0, 0x6a, 0x47, + ], "{ if (!p2.new) r8 = memuh(r10+#522) }"); + // if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (##U32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x90, 0xf5, 0x62, 0x9f, + ], "{ if (p2.new) r16 = memuh(##0x205) }"); + // if ([!]Pt[.new]) mem{b,h,w,d}(Rs + ##U32) = Rt[.new] + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x2a, 0xc7, 0x4a, 0x40, + ], "{ if (p2) memh(r10+#522) = r7 }"); + // if ([!]Pt[.new]) mem{b,h,w,d}(##U32) = Rt[.new] + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xc9, 0xe6, 0x80, 0xaf, + ], "{ if (p1.new) memw(#0x209) = r6 }"); + // [if [!]Ps] memw(Rs + #u6) = ##U32 // constant store + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xbf, 0xe2, 0x84, 0x38, + ], "{ if (!p1) memb(r4+#5) = #575 }"); + // if (cmp.xx(Rs.new,##U32)) jump:hint target + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xe3, 0xd4, 0x24, + ], "{ if (!cmp.gt(r4.new, ##0x203)) jump:t $+0x32c }"); + + test_display(&[ + 0x02, 0x40, 0x00, 0x00, + 0x01, 0xd6, 0x49, 0x6a, + ], "{ r1 = add(pc, ##0xac) }"); + + test_display(&[ + 0x0c, 0x42, 0xf8, 0x03, + 0x17, 0xc2, 0x19, 0xb0, + ], "{ r23 = add(r25, ##0x3f808310) }"); + + // Rdd = combine(##u32,#s8) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf0, 0xe0, 0x40, 0x7c, + ], "{ r17:16 = combine(##0x207, #-127) }"); + + // Rdd = combine(#s8,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf0, 0xc0, 0x84, 0x7c, + ], "{ r17:16 = combine(#7, ##0x208) }"); + + // Rd = mux(Pu, Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf0, 0xc0, 0x26, 0x73, + ], "{ r16 = mux(p1, r6, ##0x207) }"); + // Rd = mux(Pu, ##u32, Rs) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf0, 0xc0, 0xa6, 0x73, + ], "{ r16 = mux(p1, ##0x207, r6) }"); + // Rd = mux(Pu,##u32,#s8) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf1, 0xe0, 0xa7, 0x7a, + ], "{ r17 = mux(p1, ##0x207, #79) }"); + + // if ([!]Pu[.new]) Rd = add(Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf0, 0xe0, 0xc6, 0x74, + ], "{ if (!p2.new) r16 = add(r6, ##0x207) }"); + + // if ([!]Pu[.new]) Rd = ##u32 + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf0, 0xe0, 0xc0, 0x7e, + ], "{ if (!p2.new) r16 = ##0x207 }"); + + // Pd = [!]cmp.eq (Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf1, 0xc0, 0x06, 0x75, + ], "{ p1 = !cmp.eq(r6, ##0x207) }"); + // Pd = [!]cmp.gt (Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf1, 0xc0, 0x46, 0x75, + ], "{ p1 = !cmp.gt(r6, ##0x207) }"); + // Pd = [!]cmp.gtu (Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0xf1, 0xc0, 0x86, 0x75, + ], "{ p1 = !cmp.gtu(r6, ##0x207) }"); + + // Rd = mpyi(Rs,##u32) + + // Rd += mpyi(Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xc6, 0x14, 0xe1, + ], "{ r22 += mpyi(r20, ##0x234) }"); + // Rd -= mpyi(Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xc6, 0x94, 0xe1, + ], "{ r22 -= mpyi(r20, ##0x234) }"); + // Rx += add(Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xc6, 0x14, 0xe2, + ], "{ r22 += add(r20, ##0x234) }"); + // Rx -= add(Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xc6, 0x94, 0xe2, + ], "{ r22 -= add(r20, ##0x234) }"); + // Rd = add(Rs,##s32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0x58, + ], "{ jump $+0x204 }"); + // jump (PC + ##s32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0x5a, + ], "{ call $+0x204 }"); + // call (PC + ##s32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x02, 0xc1, 0x00, 0x5c, + ], "{ if (p1) jump:nt $+0x204 }"); + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x02, 0xc9, 0x20, 0x5c, + ], "{ if (!p1.new) jump:nt $+0x204 }"); + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x02, 0xc1, 0x20, 0x5d, + ], "{ if (!p1) call $+0x204 }"); + // if ([!]Pu) call (PC + ##s32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x08, 0xc2, 0xa6, 0x60, + ], "{ p3 = sp1loop0($+0x224, r6) }"); + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x08, 0xc2, 0xc6, 0x60, + ], "{ p3 = sp2loop0($+0x224, r6) }"); + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x08, 0xc2, 0xe6, 0x60, + ], "{ p3 = sp3loop0($+0x224, r6) }"); + // Pd = spNloop0(PC+##s32,Rs/#U10) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x08, 0xc2, 0x06, 0x60, + ], "{ loop0($+0x224, r6) }"); + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x08, 0xc2, 0x26, 0x60, + ], "{ loop1($+0x224, r6) }"); + // loop0/1 (PC+##s32,#Rs/#U10) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xe6, 0xd4, 0xd8, + ], "{ r6 = add(##0x22c, mpyi(r20, #0x36)) }"); + // Rd = add(##u32,mpyi(Rs,#u6)) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xe6, 0x54, 0xd7, + ], "{ r22 = add(##0x22c, mpyi(r20, r6)) }"); + // Rd = add(##u32,mpyi(Rs,Rt)) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xe6, 0x34, 0xdb, + ], "{ r6 = add(r20, add(r22, ##0x21c)) }"); + // Rd = add(Rs,add(Rt,##u32)) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xe6, 0xb4, 0xdb, + ], "{ r6 = add(r20, sub(##0x21c, r22)) }"); + // Rd = add(Rs,sub(##u32,Rt)) + + // Rd = sub(##u32,add(Rs,Rt)) + + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x96, 0xc3, 0x54, 0xda, + ], "{ r20 = or(r22, and(r20, ##0x21c)) }"); + // Rd = or(Rs,and(Rt,##u32)) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x84, 0xe6, 0x14, 0xde, + ], "{ r20 = add(##0x218, asl(r20, #0x6)) }"); + // Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,#U5)) + + // neither of these exist? + // Rx = add/sub/and/or (##u32,asl/asr/lsr(Rs,Rx)) + // Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,Rs)) + + // Pd = cmpb/h.{eq,gt,gtu} (Rs,##u32) + test_display(&[ + 0x08, 0x40, 0x00, 0x00, + 0x87, 0xe6, 0x14, 0xdd, + ], "{ p3 = cmpb.gt(r20, ##0x234) }"); test_display(&[ 0x08, 0x40, 0x00, 0x00, @@ -770,6 +982,8 @@ fn inst_0111() { test_display(&0b0111_1000110_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ r17 = #-15929 }"); + test_display(&0b0111_101_01_0100111_11_1_00000111_10001u32.to_le_bytes(), "{ r17 = mux(p1, #7, #79) }"); + test_display(&0b0111_1100010_00000_11_1_0_0000_111_10000u32.to_le_bytes(), "{ r17:16 = combine(#7, #-127) }"); test_display(&0b0111_1100100_10000_11_1_0_0000_111_10000u32.to_le_bytes(), "{ r17:16 = combine(#7, #0x21) }"); |