Skip to content

Commit fccc8a9

Browse files
authored
ECAL opcode support (#6947)
## 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 <zees-dev@users.noreply.github.com>
1 parent b07d0ca commit fccc8a9

File tree

9 files changed

+67
-0
lines changed

9 files changed

+67
-0
lines changed

sway-ast/src/expr/op_code.rs

+1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ define_op_codes!(
340340
(ECOP, ECOPOpcode, "ecop", (dst_addr: reg, curve: reg, operation: reg, src_addr: reg)),
341341
(EPAR, EPAROpcode, "epar", (ret: reg, curve: reg, groups_of_points: reg, addr: reg)),
342342
/* Other Instructions */
343+
(Ecal, EcalOpcode, "ecal", (reg_a: reg, reg_b: reg, reg_c: reg, reg_d: reg)),
343344
(Flag, FlagOpcode, "flag", (value: reg)),
344345
(Gm, GmOpcode, "gm", (ret: reg, op: imm)),
345346
(

sway-core/src/asm_lang/allocated_ops.rs

+11
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ pub(crate) enum AllocatedOpcode {
281281
),
282282

283283
/* Other Instructions */
284+
ECAL(
285+
AllocatedRegister,
286+
AllocatedRegister,
287+
AllocatedRegister,
288+
AllocatedRegister,
289+
),
284290
FLAG(AllocatedRegister),
285291
GM(AllocatedRegister, VirtualImmediate18),
286292
GTF(AllocatedRegister, AllocatedRegister, VirtualImmediate12),
@@ -408,6 +414,7 @@ impl AllocatedOpcode {
408414
EPAR(r1, _r2, _r3, _r4) => vec![r1],
409415

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

541548
/* Other Instructions */
549+
ECAL(a, b, c, d) => write!(fmtr, "ecal {a} {b} {c} {d}"),
542550
FLAG(a) => write!(fmtr, "flag {a}"),
543551
GM(a, b) => write!(fmtr, "gm {a} {b}"),
544552
GTF(a, b, c) => write!(fmtr, "gtf {a} {b} {c}"),
@@ -775,6 +783,9 @@ impl AllocatedOp {
775783
}
776784

777785
/* Other Instructions */
786+
ECAL(a, b, c, d) => {
787+
op::ECAL::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.to_reg_id()).into()
788+
}
778789
FLAG(a) => op::FLAG::new(a.to_reg_id()).into(),
779790
GM(a, b) => op::GM::new(a.to_reg_id(), b.value().into()).into(),
780791
GTF(a, b, c) => op::GTF::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(),

sway-core/src/asm_lang/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,10 @@ impl Op {
684684
}
685685

686686
/* Other Instructions */
687+
"ecal" => {
688+
let (r1, r2, r3, r4) = four_regs(handler, args, immediate, whole_op_span)?;
689+
VirtualOp::ECAL(r1, r2, r3, r4)
690+
}
687691
"flag" => {
688692
let r1 = single_reg(handler, args, immediate, whole_op_span)?;
689693
VirtualOp::FLAG(r1)
@@ -1240,6 +1244,7 @@ impl fmt::Display for VirtualOp {
12401244
EPAR(a, b, c, d) => write!(fmtr, "epar {a} {b} {c} {d}"),
12411245

12421246
/* Other Instructions */
1247+
ECAL(a, b, c, d) => write!(fmtr, "ecal {a} {b} {c} {d}"),
12431248
FLAG(a) => write!(fmtr, "flag {a}"),
12441249
GM(a, b) => write!(fmtr, "gm {a} {b}"),
12451250
GTF(a, b, c) => write!(fmtr, "gtf {a} {b} {c}"),

sway-core/src/asm_lang/virtual_ops.rs

+24
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ pub(crate) enum VirtualOp {
232232
),
233233

234234
/* Other Instructions */
235+
ECAL(
236+
VirtualRegister,
237+
VirtualRegister,
238+
VirtualRegister,
239+
VirtualRegister,
240+
),
235241
FLAG(VirtualRegister),
236242
GM(VirtualRegister, VirtualImmediate18),
237243
GTF(VirtualRegister, VirtualRegister, VirtualImmediate12),
@@ -355,6 +361,7 @@ impl VirtualOp {
355361
EPAR(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
356362

357363
/* Other Instructions */
364+
ECAL(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
358365
FLAG(r1) => vec![r1],
359366
GM(r1, _imm) => vec![r1],
360367
GTF(r1, r2, _i) => vec![r1, r2],
@@ -479,6 +486,8 @@ impl VirtualOp {
479486
| K256(_, _, _)
480487
| S256(_, _, _)
481488
| ECOP(_, _, _, _)
489+
// Other instructions
490+
| ECAL(_, _, _, _)
482491
| FLAG(_)
483492
// Virtual OPs
484493
| BLOB(_)
@@ -588,6 +597,7 @@ impl VirtualOp {
588597
| S256(_, _, _)
589598
| ECOP(_, _, _, _)
590599
| EPAR(_, _, _, _)
600+
| ECAL(_, _, _, _)
591601
| GM(_, _)
592602
| GTF(_, _, _)
593603
| BLOB(_)
@@ -709,6 +719,7 @@ impl VirtualOp {
709719
EPAR(_r1, r2, r3, r4) => vec![r2, r3, r4],
710720

711721
/* Other Instructions */
722+
ECAL(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
712723
FLAG(r1) => vec![r1],
713724
GM(_r1, _imm) => vec![],
714725
GTF(_r1, r2, _i) => vec![r2],
@@ -833,6 +844,7 @@ impl VirtualOp {
833844
EPAR(r1, _r2, _r3, _r4) => vec![r1],
834845

835846
/* Other Instructions */
847+
ECAL(_r1, _r2, _r3, _r4) => vec![],
836848
FLAG(_r1) => vec![],
837849
GM(r1, _imm) => vec![r1],
838850
GTF(r1, _r2, _i) => vec![r1],
@@ -1292,6 +1304,12 @@ impl VirtualOp {
12921304
),
12931305

12941306
/* Other Instructions */
1307+
ECAL(r1, r2, r3, r4) => Self::ECAL(
1308+
update_reg(reg_to_reg_map, r1),
1309+
update_reg(reg_to_reg_map, r2),
1310+
update_reg(reg_to_reg_map, r3),
1311+
update_reg(reg_to_reg_map, r4),
1312+
),
12951313
FLAG(r1) => Self::FLAG(update_reg(reg_to_reg_map, r1)),
12961314
GM(r1, i) => Self::GM(update_reg(reg_to_reg_map, r1), i.clone()),
12971315
GTF(r1, r2, i) => Self::GTF(
@@ -1785,6 +1803,12 @@ impl VirtualOp {
17851803
),
17861804

17871805
/* Other Instructions */
1806+
ECAL(reg1, reg2, reg3, reg4) => AllocatedOpcode::ECAL(
1807+
map_reg(&mapping, reg1),
1808+
map_reg(&mapping, reg2),
1809+
map_reg(&mapping, reg3),
1810+
map_reg(&mapping, reg4),
1811+
),
17881812
FLAG(reg) => AllocatedOpcode::FLAG(map_reg(&mapping, reg)),
17891813
GM(reg, imm) => AllocatedOpcode::GM(map_reg(&mapping, reg), imm.clone()),
17901814
GTF(reg1, reg2, imm) => AllocatedOpcode::GTF(

sway-parse/src/expr/op_code.rs

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ define_op_codes!(
137137
(ret, curve, groups_of_points, addr)
138138
),
139139
/* Other Instructions */
140+
(Ecal, EcalOpcode, "ecal", (reg_a, reg_b, reg_c, reg_d)),
140141
(Flag, FlagOpcode, "flag", (value)),
141142
(Gm, GmOpcode, "gm", (ret, op)),
142143
(Gtf, GtfOpcode, "gtf", (ret, index, tx_field_id)),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[package]]
2+
name = "core"
3+
source = "path+from-root-02C557D3012ABF18"
4+
5+
[[package]]
6+
name = "ecall_basic"
7+
source = "member"
8+
dependencies = ["core"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "ecall_basic"
3+
authors = ["Fuel Labs <contact@fuel.sh>"]
4+
entry = "main.sw"
5+
implicit-std = false
6+
license = "Apache-2.0"
7+
8+
[dependencies]
9+
core = { path = "../../../../../../../sway-lib-core" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
script;
2+
3+
fn main() {
4+
asm(r1: 1u64, r2: 2u32, r3: 3u32, r4: 4u32) {
5+
ecal r1 r2 r3 r4;
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
category = "unit_tests_pass"

0 commit comments

Comments
 (0)