|
|
|
@ -16,12 +16,8 @@ pub enum Instruction {
|
|
|
|
|
operand: Operand,
|
|
|
|
|
opcode: Short1OpOpcode,
|
|
|
|
|
},
|
|
|
|
|
Long2Op {
|
|
|
|
|
operands: (Operand, Operand),
|
|
|
|
|
opcode: Long2OpOpcode,
|
|
|
|
|
},
|
|
|
|
|
Variable2Op {
|
|
|
|
|
operands: (Operand, Operand),
|
|
|
|
|
operands: Vec<Operand>,
|
|
|
|
|
opcode: Variable2OpOpcode,
|
|
|
|
|
},
|
|
|
|
|
VariableVarOp {
|
|
|
|
@ -122,8 +118,6 @@ make_instruction_type!(Variable2OpOpcode {
|
|
|
|
|
28 Throw,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
type Long2OpOpcode = Variable2OpOpcode;
|
|
|
|
|
|
|
|
|
|
make_instruction_type!(VariableVarOpOpcode {
|
|
|
|
|
0 CallVs,
|
|
|
|
|
1 Storew,
|
|
|
|
@ -273,9 +267,9 @@ pub fn decode_instruction(cursor: &mut SimpleCursor) -> Result<Instruction, Inst
|
|
|
|
|
OperandType::SmallConst => Operand::make_small(cursor.read_const().unwrap()),
|
|
|
|
|
OperandType::Var => Operand::make_var(cursor.read_const().unwrap()),
|
|
|
|
|
};
|
|
|
|
|
let PotentialStoreBranchText { store, branch, text } = decode_store_branch_text::<Long2OpOpcode>(cursor, opcode_num);
|
|
|
|
|
Long2OpOpcode::from_number(opcode_num, store, branch,text)
|
|
|
|
|
.map(|opcode| Instruction::Long2Op { operands: (operand_1, operand_2), opcode })
|
|
|
|
|
let PotentialStoreBranchText { store, branch, text } = decode_store_branch_text::<Variable2OpOpcode>(cursor, opcode_num);
|
|
|
|
|
Variable2OpOpcode::from_number(opcode_num, store, branch,text)
|
|
|
|
|
.map(|opcode| Instruction::Variable2Op { operands: vec![operand_1, operand_2], opcode })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn decode_extended(cursor: &mut SimpleCursor) -> Result<Instruction, InstructionDecodeError> {
|
|
|
|
@ -328,22 +322,17 @@ pub fn decode_instruction(cursor: &mut SimpleCursor) -> Result<Instruction, Inst
|
|
|
|
|
VariableVarOpOpcode::from_number(opcode_num, store, branch, text)
|
|
|
|
|
.map(|opcode| Instruction::VariableVarOp { operands, opcode })
|
|
|
|
|
} else {
|
|
|
|
|
let mut operands = vec![];
|
|
|
|
|
let &[op_descs] = cursor.read_const().unwrap();
|
|
|
|
|
let op0 = match (op_descs >> 6) & 0b11 {
|
|
|
|
|
0b00 => Operand::make_large(cursor.read_const().unwrap()),
|
|
|
|
|
0b01 => Operand::make_small(cursor.read_const().unwrap()),
|
|
|
|
|
0b10 => Operand::make_var(cursor.read_const().unwrap()),
|
|
|
|
|
0b11 => return Err(InstructionDecodeError::InsufficientOperands),
|
|
|
|
|
_ => unreachable!()
|
|
|
|
|
};
|
|
|
|
|
let op1 = match (op_descs >> 4) & 0b11 {
|
|
|
|
|
0b00 => Operand::make_large(cursor.read_const().unwrap()),
|
|
|
|
|
0b01 => Operand::make_small(cursor.read_const().unwrap()),
|
|
|
|
|
0b10 => Operand::make_var(cursor.read_const().unwrap()),
|
|
|
|
|
0b11 => return Err(InstructionDecodeError::InsufficientOperands),
|
|
|
|
|
_ => unreachable!()
|
|
|
|
|
};
|
|
|
|
|
let operands = (op0, op1);
|
|
|
|
|
for i in 0..4 {
|
|
|
|
|
match (op_descs >> (6 - 2 * i)) & 0b11 {
|
|
|
|
|
0b00 => operands.push(Operand::make_large(cursor.read_const().unwrap())),
|
|
|
|
|
0b01 => operands.push(Operand::make_small(cursor.read_const().unwrap())),
|
|
|
|
|
0b10 => operands.push(Operand::make_var(cursor.read_const().unwrap())),
|
|
|
|
|
0b11 => (),
|
|
|
|
|
_ => unreachable!()
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
let PotentialStoreBranchText { store, branch, text } = decode_store_branch_text::<Variable2OpOpcode>(cursor, opcode_num);
|
|
|
|
|
Variable2OpOpcode::from_number(opcode_num, store, branch, text)
|
|
|
|
|
.map(|opcode| Instruction::Variable2Op { operands, opcode })
|
|
|
|
|