Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

u256 more operations #4904

Merged
merged 13 commits into from
Aug 7, 2023
Merged
92 changes: 90 additions & 2 deletions sway-core/src/asm_generation/fuel/fuel_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
},
asm_lang::{
virtual_register::*, Label, Op, VirtualImmediate06, VirtualImmediate12, VirtualImmediate18,
VirtualOp,
VirtualOp, WideCmp,
},
decl_engine::DeclRefFunction,
metadata::MetadataManager,
Expand Down Expand Up @@ -250,10 +250,20 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
}
FuelVmInstruction::WideBinaryOp {
op,
result,
arg1,
arg2,
result,
} => self.compile_wide_binary_op(instr_val, op, arg1, arg2, result),
FuelVmInstruction::WideCmpOp { op, arg1, arg2 } => {
self.compile_wide_cmp_op(instr_val, op, arg1, arg2)
}
FuelVmInstruction::WideModularOp {
op,
result,
arg1,
arg2,
arg3,
} => self.compile_wide_modular_op(instr_val, op, result, arg1, arg2, arg3),
},
Instruction::GetElemPtr {
base,
Expand Down Expand Up @@ -503,6 +513,82 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
val2_reg,
VirtualImmediate06::wide_op(crate::asm_lang::WideOperations::Add, true),
),
BinaryOpKind::Sub => VirtualOp::WQOP(
result_reg,
val1_reg,
val2_reg,
VirtualImmediate06::wide_op(crate::asm_lang::WideOperations::Sub, true),
),
BinaryOpKind::Mul => VirtualOp::WQML(
result_reg,
val1_reg,
val2_reg,
VirtualImmediate06::wide_mul(true, true),
),
BinaryOpKind::Div => VirtualOp::WQDV(
result_reg,
val1_reg,
val2_reg,
VirtualImmediate06::wide_div(true),
),
_ => todo!(),
};

self.cur_bytecode.push(Op {
opcode: Either::Left(opcode),
comment: String::new(),
owning_span: self.md_mgr.val_to_span(self.context, *instr_val),
});

Ok(())
}

fn compile_wide_modular_op(
&mut self,
instr_val: &Value,
op: &BinaryOpKind,
result: &Value,
arg1: &Value,
arg2: &Value,
arg3: &Value,
) -> Result<(), CompileError> {
let result_reg = self.value_to_register(result)?;
let val1_reg = self.value_to_register(arg1)?;
let val2_reg = self.value_to_register(arg2)?;
let val3_reg = self.value_to_register(arg3)?;

let opcode = match op {
BinaryOpKind::Mod => VirtualOp::WQAM(result_reg, val1_reg, val2_reg, val3_reg),
_ => todo!(),
};

self.cur_bytecode.push(Op {
opcode: Either::Left(opcode),
comment: String::new(),
owning_span: self.md_mgr.val_to_span(self.context, *instr_val),
});

Ok(())
}

fn compile_wide_cmp_op(
&mut self,
instr_val: &Value,
op: &Predicate,
arg1: &Value,
arg2: &Value,
) -> Result<(), CompileError> {
let res_reg = self.reg_seqr.next();
let val1_reg = self.value_to_register(arg1)?;
let val2_reg = self.value_to_register(arg2)?;

let opcode = match op {
Predicate::Equal => VirtualOp::WQCM(
res_reg.clone(),
val1_reg,
val2_reg,
VirtualImmediate06::wide_cmp(WideCmp::Equality, true),
),
_ => todo!(),
};

Expand All @@ -512,6 +598,8 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
owning_span: self.md_mgr.val_to_span(self.context, *instr_val),
});

self.reg_map.insert(*instr_val, res_reg);

Ok(())
}

Expand Down
44 changes: 44 additions & 0 deletions sway-core/src/asm_lang/allocated_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,30 @@ pub(crate) enum AllocatedOpcode {
AllocatedRegister,
VirtualImmediate06,
),
WQML(
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
VirtualImmediate06,
),
WQDV(
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
VirtualImmediate06,
),
WQCM(
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
VirtualImmediate06,
),
WQAM(
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
),

/* Conrol Flow Instructions */
JMP(AllocatedRegister),
Expand Down Expand Up @@ -250,6 +274,10 @@ impl AllocatedOpcode {
XOR(r1, _r2, _r3) => vec![r1],
XORI(r1, _r2, _i) => vec![r1],
WQOP(_, _, _, _) => vec![],
WQML(_, _, _, _) => vec![],
WQDV(_, _, _, _) => vec![],
WQCM(r1, _, _, _) => vec![r1],
WQAM(_, _, _, _) => vec![],

/* Control Flow Instructions */
JMP(_r1) => vec![],
Expand Down Expand Up @@ -364,6 +392,10 @@ impl fmt::Display for AllocatedOpcode {
XOR(a, b, c) => write!(fmtr, "xor {a} {b} {c}"),
XORI(a, b, c) => write!(fmtr, "xori {a} {b} {c}"),
WQOP(a, b, c, d) => write!(fmtr, "wqop {a} {b} {c} {d}"),
WQML(a, b, c, d) => write!(fmtr, "wqml {a} {b} {c} {d}"),
WQDV(a, b, c, d) => write!(fmtr, "wqdv {a} {b} {c} {d}"),
WQCM(a, b, c, d) => write!(fmtr, "wqcm {a} {b} {c} {d}"),
WQAM(a, b, c, d) => write!(fmtr, "wqam {a} {b} {c} {d}"),

/* Control Flow Instructions */
JMP(a) => write!(fmtr, "jmp {a}"),
Expand Down Expand Up @@ -511,6 +543,18 @@ impl AllocatedOp {
WQOP(a, b, c, d) => {
op::WQOP::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.value.into()).into()
}
WQML(a, b, c, d) => {
op::WQML::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.value.into()).into()
}
WQDV(a, b, c, d) => {
op::WQDV::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.value.into()).into()
}
WQCM(a, b, c, d) => {
op::WQCM::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.value.into()).into()
}
WQAM(a, b, c, d) => {
op::WQAM::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.to_reg_id()).into()
}

/* Control Flow Instructions */
JMP(a) => op::JMP::new(a.to_reg_id()).into(),
Expand Down
4 changes: 4 additions & 0 deletions sway-core/src/asm_lang/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,10 @@ impl fmt::Display for VirtualOp {
XOR(a, b, c) => write!(fmtr, "xor {a} {b} {c}"),
XORI(a, b, c) => write!(fmtr, "xori {a} {b} {c}"),
WQOP(a, b, c, d) => write!(fmtr, "wqop {a} {b} {c} {d}"),
WQML(a, b, c, d) => write!(fmtr, "wqml {a} {b} {c} {d}"),
WQDV(a, b, c, d) => write!(fmtr, "wqdv {a} {b} {c} {d}"),
WQCM(a, b, c, d) => write!(fmtr, "wqcm {a} {b} {c} {d}"),
WQAM(a, b, c, d) => write!(fmtr, "wqam {a} {b} {c} {d}"),

/* Control Flow Instructions */
JMP(a) => write!(fmtr, "jmp {a}"),
Expand Down
23 changes: 23 additions & 0 deletions sway-core/src/asm_lang/virtual_immediate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ use std::fmt;
#[repr(u8)]
pub enum WideOperations {
Add = 0,
Sub = 1,
}

#[repr(u8)]
pub enum WideCmp {
Equality = 0,
}

/// 6-bit immediate value type
Expand Down Expand Up @@ -47,6 +53,23 @@ impl VirtualImmediate06 {
value: (op as u8) | if rhs_indirect { 32u8 } else { 0 },
}
}

pub fn wide_cmp(op: WideCmp, rhs_indirect: bool) -> VirtualImmediate06 {
VirtualImmediate06 {
value: (op as u8) | if rhs_indirect { 32u8 } else { 0 },
}
}

pub fn wide_mul(lhs_indirect: bool, rhs_indirect: bool) -> VirtualImmediate06 {
let lhs = if lhs_indirect { 16u8 } else { 0 };
let rhs = if rhs_indirect { 32u8 } else { 0 };
VirtualImmediate06 { value: lhs | rhs }
}

pub fn wide_div(rhs_indirect: bool) -> VirtualImmediate06 {
let rhs = if rhs_indirect { 32u8 } else { 0 };
VirtualImmediate06 { value: rhs }
}
}

impl fmt::Display for VirtualImmediate06 {
Expand Down
84 changes: 84 additions & 0 deletions sway-core/src/asm_lang/virtual_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,30 @@ pub(crate) enum VirtualOp {
VirtualRegister,
VirtualImmediate06,
),
WQML(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualImmediate06,
),
WQDV(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualImmediate06,
),
WQCM(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualImmediate06,
),
WQAM(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),

/* Control Flow Instructions */
JMP(VirtualRegister),
Expand Down Expand Up @@ -214,6 +238,10 @@ impl VirtualOp {
XOR(r1, r2, r3) => vec![r1, r2, r3],
XORI(r1, r2, _i) => vec![r1, r2],
WQOP(r1, r2, r3, _) => vec![r1, r2, r3],
WQML(r1, r2, r3, _) => vec![r1, r2, r3],
WQDV(r1, r2, r3, _) => vec![r1, r2, r3],
WQCM(r1, r2, r3, _) => vec![r1, r2, r3],
WQAM(r1, r2, r3, r4) => vec![r1, r2, r3, r4],

/* Control Flow Instructions */
JMP(r1) => vec![r1],
Expand Down Expand Up @@ -324,6 +352,10 @@ impl VirtualOp {
XOR(_r1, r2, r3) => vec![r2, r3],
XORI(_r1, r2, _i) => vec![r2],
WQOP(r1, r2, r3, _) => vec![r1, r2, r3],
WQML(r1, r2, r3, _) => vec![r1, r2, r3],
WQDV(r1, r2, r3, _) => vec![r1, r2, r3],
WQCM(_, r2, r3, _) => vec![r2, r3],
WQAM(_, r2, r3, r4) => vec![r2, r3, r4],

/* Control Flow Instructions */
JMP(r1) => vec![r1],
Expand Down Expand Up @@ -434,6 +466,10 @@ impl VirtualOp {
XOR(r1, _r2, _r3) => vec![r1],
XORI(r1, _r2, _i) => vec![r1],
WQOP(_, _, _, _) => vec![],
WQML(_, _, _, _) => vec![],
WQDV(_, _, _, _) => vec![],
WQCM(r1, _, _, _) => vec![r1],
WQAM(r1, _, _, _) => vec![r1],

/* Control Flow Instructions */
JMP(_r1) => vec![],
Expand Down Expand Up @@ -685,6 +721,30 @@ impl VirtualOp {
update_reg(reg_to_reg_map, r3),
i.clone(),
),
WQML(r1, r2, r3, i) => Self::WQML(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
i.clone(),
),
WQDV(r1, r2, r3, i) => Self::WQDV(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
i.clone(),
),
WQCM(r1, r2, r3, i) => Self::WQCM(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
i.clone(),
),
WQAM(r1, r2, r3, r4) => Self::WQAM(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),

/* Control Flow Instructions */
JMP(r1) => Self::JMP(update_reg(reg_to_reg_map, r1)),
Expand Down Expand Up @@ -1109,6 +1169,30 @@ impl VirtualOp {
map_reg(&mapping, reg3),
imm.clone(),
),
WQML(reg1, reg2, reg3, imm) => AllocatedOpcode::WQML(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
imm.clone(),
),
WQDV(reg1, reg2, reg3, imm) => AllocatedOpcode::WQDV(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
imm.clone(),
),
WQCM(reg1, reg2, reg3, imm) => AllocatedOpcode::WQCM(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
imm.clone(),
),
WQAM(reg1, reg2, reg3, reg4) => AllocatedOpcode::WQAM(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),

/* Control Flow Instructions */
JMP(reg1) => AllocatedOpcode::JMP(map_reg(&mapping, reg1)),
Expand Down
Loading