summaryrefslogtreecommitdiffstats
path: root/third_party/rust/cranelift-codegen/src/legalizer/call.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/cranelift-codegen/src/legalizer/call.rs
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/cranelift-codegen/src/legalizer/call.rs')
-rw-r--r--third_party/rust/cranelift-codegen/src/legalizer/call.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/third_party/rust/cranelift-codegen/src/legalizer/call.rs b/third_party/rust/cranelift-codegen/src/legalizer/call.rs
new file mode 100644
index 0000000000..4321dbb90b
--- /dev/null
+++ b/third_party/rust/cranelift-codegen/src/legalizer/call.rs
@@ -0,0 +1,54 @@
+//! Legalization of calls.
+//!
+//! This module exports the `expand_call` function which transforms a `call`
+//! instruction into `func_addr` and `call_indirect` instructions.
+
+use crate::cursor::{Cursor, FuncCursor};
+use crate::flowgraph::ControlFlowGraph;
+use crate::ir::{self, InstBuilder};
+use crate::isa::TargetIsa;
+
+/// Expand a `call` instruction. This lowers it to a `call_indirect`, which
+/// is only done if the ABI doesn't support direct calls.
+pub fn expand_call(
+ inst: ir::Inst,
+ func: &mut ir::Function,
+ _cfg: &mut ControlFlowGraph,
+ isa: &dyn TargetIsa,
+) {
+ // Unpack the instruction.
+ let (func_ref, old_args) = match func.dfg[inst] {
+ ir::InstructionData::Call {
+ opcode,
+ ref args,
+ func_ref,
+ } => {
+ debug_assert_eq!(opcode, ir::Opcode::Call);
+ (func_ref, args.clone())
+ }
+ _ => panic!("Wanted call: {}", func.dfg.display_inst(inst, None)),
+ };
+
+ let ptr_ty = isa.pointer_type();
+
+ let sig = func.dfg.ext_funcs[func_ref].signature;
+
+ let callee = {
+ let mut pos = FuncCursor::new(func).at_inst(inst);
+ pos.use_srcloc(inst);
+ pos.ins().func_addr(ptr_ty, func_ref)
+ };
+
+ let mut new_args = ir::ValueList::default();
+ new_args.push(callee, &mut func.dfg.value_lists);
+ for i in 0..old_args.len(&func.dfg.value_lists) {
+ new_args.push(
+ old_args.as_slice(&func.dfg.value_lists)[i],
+ &mut func.dfg.value_lists,
+ );
+ }
+
+ func.dfg
+ .replace(inst)
+ .CallIndirect(ir::Opcode::CallIndirect, ptr_ty, sig, new_args);
+}