Skip to content

Commit

Permalink
ECAL opcode support (#6947)
Browse files Browse the repository at this point in the history
## Description
The ECAL opcode is supported in `fuel-vm` to extend the capabilities of
the VM.
Users can implement rust code to interop with the VM using the ECAL
opcode.
This PR introduces support for the opcode in the sway repo - such that
sway assembly can be successfully compiled with the ECAL opcode.

Examples of how to utilize the `ECAL` opcode can be seen here:
https://github.com/FuelLabs/fuel-vm/blob/9478991db1ea8799fab47ebe1c195946a2698a7f/fuel-vm/examples/external.rs#L51

- Closes #5239
- Added an e2e test to validate compilation of ecall opcode in sway
assembly.

## Checklist

- [x] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: z <[email protected]>
  • Loading branch information
zees-dev and zees-dev authored Feb 22, 2025
1 parent b07d0ca commit fccc8a9
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 0 deletions.
1 change: 1 addition & 0 deletions sway-ast/src/expr/op_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ define_op_codes!(
(ECOP, ECOPOpcode, "ecop", (dst_addr: reg, curve: reg, operation: reg, src_addr: reg)),
(EPAR, EPAROpcode, "epar", (ret: reg, curve: reg, groups_of_points: reg, addr: reg)),
/* Other Instructions */
(Ecal, EcalOpcode, "ecal", (reg_a: reg, reg_b: reg, reg_c: reg, reg_d: reg)),
(Flag, FlagOpcode, "flag", (value: reg)),
(Gm, GmOpcode, "gm", (ret: reg, op: imm)),
(
Expand Down
11 changes: 11 additions & 0 deletions sway-core/src/asm_lang/allocated_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ pub(crate) enum AllocatedOpcode {
),

/* Other Instructions */
ECAL(
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
AllocatedRegister,
),
FLAG(AllocatedRegister),
GM(AllocatedRegister, VirtualImmediate18),
GTF(AllocatedRegister, AllocatedRegister, VirtualImmediate12),
Expand Down Expand Up @@ -408,6 +414,7 @@ impl AllocatedOpcode {
EPAR(r1, _r2, _r3, _r4) => vec![r1],

/* Other Instructions */
ECAL(_r1, _r2, _r3, _r4) => vec![],
FLAG(_r1) => vec![],
GM(r1, _imm) => vec![r1],
GTF(r1, _r2, _i) => vec![r1],
Expand Down Expand Up @@ -539,6 +546,7 @@ impl fmt::Display for AllocatedOpcode {
EPAR(a, b, c, d) => write!(fmtr, "epar {a} {b} {c} {d}"),

/* Other Instructions */
ECAL(a, b, c, d) => write!(fmtr, "ecal {a} {b} {c} {d}"),
FLAG(a) => write!(fmtr, "flag {a}"),
GM(a, b) => write!(fmtr, "gm {a} {b}"),
GTF(a, b, c) => write!(fmtr, "gtf {a} {b} {c}"),
Expand Down Expand Up @@ -775,6 +783,9 @@ impl AllocatedOp {
}

/* Other Instructions */
ECAL(a, b, c, d) => {
op::ECAL::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.to_reg_id()).into()
}
FLAG(a) => op::FLAG::new(a.to_reg_id()).into(),
GM(a, b) => op::GM::new(a.to_reg_id(), b.value().into()).into(),
GTF(a, b, c) => op::GTF::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(),
Expand Down
5 changes: 5 additions & 0 deletions sway-core/src/asm_lang/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,10 @@ impl Op {
}

/* Other Instructions */
"ecal" => {
let (r1, r2, r3, r4) = four_regs(handler, args, immediate, whole_op_span)?;
VirtualOp::ECAL(r1, r2, r3, r4)
}
"flag" => {
let r1 = single_reg(handler, args, immediate, whole_op_span)?;
VirtualOp::FLAG(r1)
Expand Down Expand Up @@ -1240,6 +1244,7 @@ impl fmt::Display for VirtualOp {
EPAR(a, b, c, d) => write!(fmtr, "epar {a} {b} {c} {d}"),

/* Other Instructions */
ECAL(a, b, c, d) => write!(fmtr, "ecal {a} {b} {c} {d}"),
FLAG(a) => write!(fmtr, "flag {a}"),
GM(a, b) => write!(fmtr, "gm {a} {b}"),
GTF(a, b, c) => write!(fmtr, "gtf {a} {b} {c}"),
Expand Down
24 changes: 24 additions & 0 deletions sway-core/src/asm_lang/virtual_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ pub(crate) enum VirtualOp {
),

/* Other Instructions */
ECAL(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
FLAG(VirtualRegister),
GM(VirtualRegister, VirtualImmediate18),
GTF(VirtualRegister, VirtualRegister, VirtualImmediate12),
Expand Down Expand Up @@ -355,6 +361,7 @@ impl VirtualOp {
EPAR(r1, r2, r3, r4) => vec![r1, r2, r3, r4],

/* Other Instructions */
ECAL(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
FLAG(r1) => vec![r1],
GM(r1, _imm) => vec![r1],
GTF(r1, r2, _i) => vec![r1, r2],
Expand Down Expand Up @@ -479,6 +486,8 @@ impl VirtualOp {
| K256(_, _, _)
| S256(_, _, _)
| ECOP(_, _, _, _)
// Other instructions
| ECAL(_, _, _, _)
| FLAG(_)
// Virtual OPs
| BLOB(_)
Expand Down Expand Up @@ -588,6 +597,7 @@ impl VirtualOp {
| S256(_, _, _)
| ECOP(_, _, _, _)
| EPAR(_, _, _, _)
| ECAL(_, _, _, _)
| GM(_, _)
| GTF(_, _, _)
| BLOB(_)
Expand Down Expand Up @@ -709,6 +719,7 @@ impl VirtualOp {
EPAR(_r1, r2, r3, r4) => vec![r2, r3, r4],

/* Other Instructions */
ECAL(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
FLAG(r1) => vec![r1],
GM(_r1, _imm) => vec![],
GTF(_r1, r2, _i) => vec![r2],
Expand Down Expand Up @@ -833,6 +844,7 @@ impl VirtualOp {
EPAR(r1, _r2, _r3, _r4) => vec![r1],

/* Other Instructions */
ECAL(_r1, _r2, _r3, _r4) => vec![],
FLAG(_r1) => vec![],
GM(r1, _imm) => vec![r1],
GTF(r1, _r2, _i) => vec![r1],
Expand Down Expand Up @@ -1292,6 +1304,12 @@ impl VirtualOp {
),

/* Other Instructions */
ECAL(r1, r2, r3, r4) => Self::ECAL(
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),
),
FLAG(r1) => Self::FLAG(update_reg(reg_to_reg_map, r1)),
GM(r1, i) => Self::GM(update_reg(reg_to_reg_map, r1), i.clone()),
GTF(r1, r2, i) => Self::GTF(
Expand Down Expand Up @@ -1785,6 +1803,12 @@ impl VirtualOp {
),

/* Other Instructions */
ECAL(reg1, reg2, reg3, reg4) => AllocatedOpcode::ECAL(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
FLAG(reg) => AllocatedOpcode::FLAG(map_reg(&mapping, reg)),
GM(reg, imm) => AllocatedOpcode::GM(map_reg(&mapping, reg), imm.clone()),
GTF(reg1, reg2, imm) => AllocatedOpcode::GTF(
Expand Down
1 change: 1 addition & 0 deletions sway-parse/src/expr/op_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ define_op_codes!(
(ret, curve, groups_of_points, addr)
),
/* Other Instructions */
(Ecal, EcalOpcode, "ecal", (reg_a, reg_b, reg_c, reg_d)),
(Flag, FlagOpcode, "flag", (value)),
(Gm, GmOpcode, "gm", (ret, op)),
(Gtf, GtfOpcode, "gtf", (ret, index, tx_field_id)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[[package]]
name = "core"
source = "path+from-root-02C557D3012ABF18"

[[package]]
name = "ecall_basic"
source = "member"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
name = "ecall_basic"
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
implicit-std = false
license = "Apache-2.0"

[dependencies]
core = { path = "../../../../../../../sway-lib-core" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
script;

fn main() {
asm(r1: 1u64, r2: 2u32, r3: 3u32, r4: 4u32) {
ecal r1 r2 r3 r4;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
category = "unit_tests_pass"

0 comments on commit fccc8a9

Please sign in to comment.