Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions avm-transpiler/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use crate::opcodes::AvmOpcode;
pub struct AvmInstruction {
pub opcode: AvmOpcode,

/// Any instructions with memory offset operands have the indirect flag
/// Any instructions with memory offset operands have the addressing mode
/// Each bit is a boolean: 0:direct, 1:indirect
/// The 0th bit corresponds to an instruction's 0th offset arg, 1st to 1st, etc...
pub indirect: Option<AvmOperand>,
pub addressing_mode: Option<AvmOperand>,

/// Some instructions have a tag, its usage will depend on the instruction.
/// Its usage will depend on the instruction.
Expand All @@ -33,8 +33,8 @@ pub struct AvmInstruction {
impl Display for AvmInstruction {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "opcode {}", self.opcode.name())?;
if let Some(indirect) = &self.indirect {
write!(f, ", indirect: {}", indirect)?;
if let Some(addressing_mode) = &self.addressing_mode {
write!(f, ", addressing_mode: {}", addressing_mode)?;
}
if !self.operands.is_empty() {
write!(f, ", operands: [")?;
Expand All @@ -60,12 +60,12 @@ impl Display for AvmInstruction {

impl AvmInstruction {
/// Bytes representation for generating AVM bytecode
/// Order: INDIRECT, OPERANDS, TAG, IMMEDIATES
/// Order: ADDRESSING_MODE, OPERANDS, TAG, IMMEDIATES
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(self.opcode as u8);
if let Some(indirect) = &self.indirect {
bytes.extend_from_slice(&indirect.to_be_bytes());
if let Some(addressing_mode) = &self.addressing_mode {
bytes.extend_from_slice(&addressing_mode.to_be_bytes());
}
for operand in &self.operands {
bytes.extend_from_slice(&operand.to_be_bytes());
Expand Down Expand Up @@ -95,8 +95,8 @@ impl Default for AvmInstruction {
fn default() -> Self {
AvmInstruction {
opcode: AvmOpcode::ADD_8,
// TODO(4266): default to Some(0), since all instructions have indirect flag except jumps
indirect: None,
// TODO(4266): default to Some(0), since all instructions have addressing mode except jumps
addressing_mode: None,
tag: None,
operands: vec![],
immediates: vec![],
Expand Down Expand Up @@ -158,34 +158,34 @@ impl AvmOperand {

#[derive(Debug, Default)]
pub(crate) struct AddressingModeBuilder {
indirect: Vec<bool>,
addressing_mode: Vec<bool>,
relative: Vec<bool>,
}

impl AddressingModeBuilder {
pub(crate) fn direct_operand(mut self, address: &MemoryAddress) -> Self {
self.relative.push(address.is_relative());
self.indirect.push(false);
self.addressing_mode.push(false);

self
}

pub(crate) fn indirect_operand(mut self, address: &MemoryAddress) -> Self {
self.relative.push(address.is_relative());
self.indirect.push(true);
self.addressing_mode.push(true);

self
}

pub(crate) fn build(self) -> AvmOperand {
let num_operands = self.indirect.len();
let num_operands = self.addressing_mode.len();
assert!(num_operands <= 8, "Too many operands for building addressing mode bytes");

let mut result = 0;
for (i, (indirect, relative)) in
self.indirect.into_iter().zip(self.relative.into_iter()).enumerate()
for (i, (is_indirect, relative)) in
self.addressing_mode.into_iter().zip(self.relative.into_iter()).enumerate()
{
if indirect {
if is_indirect {
// Even bits are indirect
result |= 1 << (i * 2);
}
Expand Down
24 changes: 12 additions & 12 deletions avm-transpiler/src/procedures/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: set_opcode,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: vec![make_operand(bits_needed_mem, &dest_address)],
immediates: vec![make_operand(bits_needed_opcode, &immediate_value)],
tag: collection.tag,
Expand Down Expand Up @@ -133,7 +133,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: AvmOpcode::JUMPI_32,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: vec![make_operand(16, &collection.operands[0])],
immediates: vec![make_unresolved_pc()],
..Default::default()
Expand All @@ -154,7 +154,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: if bits_needed == 8 { AvmOpcode::NOT_8 } else { AvmOpcode::NOT_16 },
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: collection
.operands
.iter()
Expand Down Expand Up @@ -183,7 +183,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: avm_opcode,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: collection
.operands
.iter()
Expand All @@ -210,7 +210,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: mov_opcode,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: collection
.operands
.iter()
Expand Down Expand Up @@ -242,7 +242,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: AvmOpcode::ECADD,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: collection
.operands
.into_iter()
Expand All @@ -265,7 +265,7 @@ fn compile_opcode(
result.add_instruction(
AvmInstruction {
opcode: AvmOpcode::TORADIXBE,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: collection
.operands
.into_iter()
Expand Down Expand Up @@ -368,7 +368,7 @@ fn compile_binary_instruction(
result.add_instruction(
AvmInstruction {
opcode: avm_opcode,
indirect: Some(build_addressing_mode(collection.indirect)),
addressing_mode: Some(build_addressing_mode(collection.addressing_mode)),
operands: collection
.operands
.iter()
Expand All @@ -381,13 +381,13 @@ fn compile_binary_instruction(
Ok(())
}

fn build_addressing_mode(indirect: Vec<bool>) -> AvmOperand {
let num_operands = indirect.len();
fn build_addressing_mode(addressing_mode: Vec<bool>) -> AvmOperand {
let num_operands = addressing_mode.len();
assert!(num_operands <= 8, "Too many operands for building addressing mode bytes");

let mut result = 0;
for (i, indirect) in indirect.into_iter().enumerate() {
if indirect {
for (i, is_indirect) in addressing_mode.into_iter().enumerate() {
if is_indirect {
// No relative, so we only operate on even bits
result |= 1 << (i * 2);
}
Expand Down
14 changes: 7 additions & 7 deletions avm-transpiler/src/procedures/compiler/operand_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Immediate {

pub(crate) struct OperandCollectionResult {
pub(crate) operands: Vec<usize>,
pub(crate) indirect: Vec<bool>,
pub(crate) addressing_mode: Vec<bool>,
pub(crate) immediates: Vec<Immediate>,
pub(crate) tag: Option<AvmTypeTag>,
}
Expand All @@ -42,7 +42,7 @@ pub(crate) struct OperandCollector {
parsed_opcode: ParsedOpcode,
extracted_operands: Vec<usize>,
extracted_immediates: Vec<Immediate>,
indirect: Vec<bool>,
addressing_mode: Vec<bool>,

operand_index: usize,
extracted_tag: bool,
Expand All @@ -54,7 +54,7 @@ impl OperandCollector {
parsed_opcode,
extracted_operands: vec![],
extracted_immediates: vec![],
indirect: vec![],
addressing_mode: vec![],
operand_index: 0,
extracted_tag: false,
}
Expand Down Expand Up @@ -82,15 +82,15 @@ impl OperandCollector {
let address = match operand {
Operand::Symbol(symbol) => match symbol {
Symbol::Direct(address) => {
self.indirect.push(false);
self.addressing_mode.push(false);
OperandCollector::convert_address(address)
}
Symbol::Indirect(address) => {
self.indirect.push(true);
self.addressing_mode.push(true);
OperandCollector::convert_address(address)
}
Symbol::Reserved(address) => {
self.indirect.push(false);
self.addressing_mode.push(false);
Ok(address)
}
Symbol::Label(_) => Err("Expected address found label".to_string()),
Expand Down Expand Up @@ -148,7 +148,7 @@ impl OperandCollector {
}
Ok(OperandCollectionResult {
operands: self.extracted_operands,
indirect: self.indirect,
addressing_mode: self.addressing_mode,
immediates: self.extracted_immediates,
tag: self.parsed_opcode.tag,
})
Expand Down
Loading
Loading