Skip to content

Commit 6227674

Browse files
authored
pulley: Implement support for symbol_value (#11576)
This commit fills out the Pulley lowerings of the `symbol_value` and `func_addr` CLIF instructions. Additionally handling of relocations on Pulley is improved to be more "formal" as opposed to just blindly using an x64 relocation and assuming it works out. The intention here is to make Pulley behave more similarly to other platforms in all these respects while also enabling usage of Wasmtime to eventually use `symbol_addr` to calculate an address relative to the current PC (similar to x64). This includes Cranelift golden tests as well as more filetests being run, but the actual integration into Wasmtime will be deferred to a future commit.
1 parent cf68886 commit 6227674

File tree

22 files changed

+578
-161
lines changed

22 files changed

+578
-161
lines changed

cranelift/codegen/src/binemit/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ pub enum Reloc {
125125
/// s390x TLS GDCall - marker to enable optimization of TLS calls
126126
S390xTlsGdCall,
127127

128+
/// Pulley - a relocation which is a pc-relative offset.
129+
PulleyPcRel,
130+
128131
/// Pulley - call a host function indirectly where the embedder resolving
129132
/// this relocation needs to fill the 8-bit immediate that's part of the
130133
/// `call_indirect_host` opcode (an opaque identifier used by the host).
@@ -164,6 +167,7 @@ impl fmt::Display for Reloc {
164167
Self::Aarch64AddAbsLo12Nc => write!(f, "Aarch64AddAbsLo12Nc"),
165168
Self::S390xTlsGd64 => write!(f, "TlsGd64"),
166169
Self::S390xTlsGdCall => write!(f, "TlsGdCall"),
170+
Self::PulleyPcRel => write!(f, "PulleyPcRel"),
167171
Self::PulleyCallIndirectHost => write!(f, "PulleyCallIndirectHost"),
168172
}
169173
}

cranelift/codegen/src/isa/pulley_shared/inst.isle

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@
4242
(reg XReg))
4343

4444
;; Load an external symbol's address into a register.
45-
(LoadExtName (dst WritableXReg)
46-
(name BoxExternalName)
47-
(offset i64))
45+
(LoadExtNameNear (dst WritableXReg) (name BoxExternalName) (offset i64))
46+
(LoadExtNameFar (dst WritableXReg) (name BoxExternalName) (offset i64))
4847

4948
;; A direct call to a known callee.
5049
(Call (info BoxCallInfo))
@@ -154,6 +153,7 @@
154153
(convert RawInst MInst raw_inst_to_inst)
155154

156155
(type U6 (primitive U6))
156+
(type PcRelOffset (primitive PcRelOffset))
157157
(type BoxCallInfo (primitive BoxCallInfo))
158158
(type BoxCallIndInfo (primitive BoxCallIndInfo))
159159
(type BoxReturnCallInfo (primitive BoxReturnCallInfo))
@@ -689,6 +689,27 @@
689689
(rule (gen_br_table idx default labels)
690690
(emit (MInst.BrTable idx default labels)))
691691

692+
;; Helper for creating `MInst.LoadExtNameNear` instructions.
693+
(decl load_ext_name_near (BoxExternalName i64) XReg)
694+
(rule (load_ext_name_near name offset)
695+
(let ((dst WritableXReg (temp_writable_xreg))
696+
(_ Unit (emit (MInst.LoadExtNameNear dst name offset))))
697+
dst))
698+
699+
;; Helper for creating `MInst.LoadExtNameFar` instructions.
700+
(decl load_ext_name_far (BoxExternalName i64) XReg)
701+
(rule (load_ext_name_far name offset)
702+
(let ((dst WritableXReg (temp_writable_xreg))
703+
(_ Unit (emit (MInst.LoadExtNameFar dst name offset))))
704+
dst))
705+
706+
;; Helper for creating `MInst.LoadExtName*` instructions.
707+
(decl load_ext_name (BoxExternalName i64 RelocDistance) XReg)
708+
(rule 1 (load_ext_name name offset (RelocDistance.Near))
709+
(load_ext_name_near name offset))
710+
(rule 0 (load_ext_name name offset (RelocDistance.Far))
711+
(load_ext_name_far name offset))
712+
692713
;;;; Helpers for Emitting Calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
693714

694715
(decl gen_call_info (Sig ExternalName CallArgList CallRetList OptionTryCallInfo) BoxCallInfo)

cranelift/codegen/src/isa/pulley_shared/inst/args.rs

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -289,103 +289,103 @@ impl Cond {
289289
///
290290
/// Note that the offset encoded to jump by is filled in as 0 and it's
291291
/// assumed `MachBuffer` will come back and clean it up.
292-
pub fn encode(&self, sink: &mut impl Extend<u8>) {
292+
pub fn encode(&self, sink: &mut impl Extend<u8>, rel: i32) {
293293
match *self {
294-
Cond::If32 { reg } => encode::br_if32(sink, reg, 0),
295-
Cond::IfNot32 { reg } => encode::br_if_not32(sink, reg, 0),
296-
Cond::IfXeq32 { src1, src2 } => encode::br_if_xeq32(sink, src1, src2, 0),
297-
Cond::IfXneq32 { src1, src2 } => encode::br_if_xneq32(sink, src1, src2, 0),
298-
Cond::IfXslt32 { src1, src2 } => encode::br_if_xslt32(sink, src1, src2, 0),
299-
Cond::IfXslteq32 { src1, src2 } => encode::br_if_xslteq32(sink, src1, src2, 0),
300-
Cond::IfXult32 { src1, src2 } => encode::br_if_xult32(sink, src1, src2, 0),
301-
Cond::IfXulteq32 { src1, src2 } => encode::br_if_xulteq32(sink, src1, src2, 0),
302-
Cond::IfXeq64 { src1, src2 } => encode::br_if_xeq64(sink, src1, src2, 0),
303-
Cond::IfXneq64 { src1, src2 } => encode::br_if_xneq64(sink, src1, src2, 0),
304-
Cond::IfXslt64 { src1, src2 } => encode::br_if_xslt64(sink, src1, src2, 0),
305-
Cond::IfXslteq64 { src1, src2 } => encode::br_if_xslteq64(sink, src1, src2, 0),
306-
Cond::IfXult64 { src1, src2 } => encode::br_if_xult64(sink, src1, src2, 0),
307-
Cond::IfXulteq64 { src1, src2 } => encode::br_if_xulteq64(sink, src1, src2, 0),
294+
Cond::If32 { reg } => encode::br_if32(sink, reg, rel),
295+
Cond::IfNot32 { reg } => encode::br_if_not32(sink, reg, rel),
296+
Cond::IfXeq32 { src1, src2 } => encode::br_if_xeq32(sink, src1, src2, rel),
297+
Cond::IfXneq32 { src1, src2 } => encode::br_if_xneq32(sink, src1, src2, rel),
298+
Cond::IfXslt32 { src1, src2 } => encode::br_if_xslt32(sink, src1, src2, rel),
299+
Cond::IfXslteq32 { src1, src2 } => encode::br_if_xslteq32(sink, src1, src2, rel),
300+
Cond::IfXult32 { src1, src2 } => encode::br_if_xult32(sink, src1, src2, rel),
301+
Cond::IfXulteq32 { src1, src2 } => encode::br_if_xulteq32(sink, src1, src2, rel),
302+
Cond::IfXeq64 { src1, src2 } => encode::br_if_xeq64(sink, src1, src2, rel),
303+
Cond::IfXneq64 { src1, src2 } => encode::br_if_xneq64(sink, src1, src2, rel),
304+
Cond::IfXslt64 { src1, src2 } => encode::br_if_xslt64(sink, src1, src2, rel),
305+
Cond::IfXslteq64 { src1, src2 } => encode::br_if_xslteq64(sink, src1, src2, rel),
306+
Cond::IfXult64 { src1, src2 } => encode::br_if_xult64(sink, src1, src2, rel),
307+
Cond::IfXulteq64 { src1, src2 } => encode::br_if_xulteq64(sink, src1, src2, rel),
308308

309309
Cond::IfXeq32I32 { src1, src2 } => match i8::try_from(src2) {
310-
Ok(src2) => encode::br_if_xeq32_i8(sink, src1, src2, 0),
311-
Err(_) => encode::br_if_xeq32_i32(sink, src1, src2, 0),
310+
Ok(src2) => encode::br_if_xeq32_i8(sink, src1, src2, rel),
311+
Err(_) => encode::br_if_xeq32_i32(sink, src1, src2, rel),
312312
},
313313
Cond::IfXneq32I32 { src1, src2 } => match i8::try_from(src2) {
314-
Ok(src2) => encode::br_if_xneq32_i8(sink, src1, src2, 0),
315-
Err(_) => encode::br_if_xneq32_i32(sink, src1, src2, 0),
314+
Ok(src2) => encode::br_if_xneq32_i8(sink, src1, src2, rel),
315+
Err(_) => encode::br_if_xneq32_i32(sink, src1, src2, rel),
316316
},
317317
Cond::IfXslt32I32 { src1, src2 } => match i8::try_from(src2) {
318-
Ok(src2) => encode::br_if_xslt32_i8(sink, src1, src2, 0),
319-
Err(_) => encode::br_if_xslt32_i32(sink, src1, src2, 0),
318+
Ok(src2) => encode::br_if_xslt32_i8(sink, src1, src2, rel),
319+
Err(_) => encode::br_if_xslt32_i32(sink, src1, src2, rel),
320320
},
321321
Cond::IfXslteq32I32 { src1, src2 } => match i8::try_from(src2) {
322-
Ok(src2) => encode::br_if_xslteq32_i8(sink, src1, src2, 0),
323-
Err(_) => encode::br_if_xslteq32_i32(sink, src1, src2, 0),
322+
Ok(src2) => encode::br_if_xslteq32_i8(sink, src1, src2, rel),
323+
Err(_) => encode::br_if_xslteq32_i32(sink, src1, src2, rel),
324324
},
325325
Cond::IfXsgt32I32 { src1, src2 } => match i8::try_from(src2) {
326-
Ok(src2) => encode::br_if_xsgt32_i8(sink, src1, src2, 0),
327-
Err(_) => encode::br_if_xsgt32_i32(sink, src1, src2, 0),
326+
Ok(src2) => encode::br_if_xsgt32_i8(sink, src1, src2, rel),
327+
Err(_) => encode::br_if_xsgt32_i32(sink, src1, src2, rel),
328328
},
329329
Cond::IfXsgteq32I32 { src1, src2 } => match i8::try_from(src2) {
330-
Ok(src2) => encode::br_if_xsgteq32_i8(sink, src1, src2, 0),
331-
Err(_) => encode::br_if_xsgteq32_i32(sink, src1, src2, 0),
330+
Ok(src2) => encode::br_if_xsgteq32_i8(sink, src1, src2, rel),
331+
Err(_) => encode::br_if_xsgteq32_i32(sink, src1, src2, rel),
332332
},
333333
Cond::IfXult32I32 { src1, src2 } => match u8::try_from(src2) {
334-
Ok(src2) => encode::br_if_xult32_u8(sink, src1, src2, 0),
335-
Err(_) => encode::br_if_xult32_u32(sink, src1, src2, 0),
334+
Ok(src2) => encode::br_if_xult32_u8(sink, src1, src2, rel),
335+
Err(_) => encode::br_if_xult32_u32(sink, src1, src2, rel),
336336
},
337337
Cond::IfXulteq32I32 { src1, src2 } => match u8::try_from(src2) {
338-
Ok(src2) => encode::br_if_xulteq32_u8(sink, src1, src2, 0),
339-
Err(_) => encode::br_if_xulteq32_u32(sink, src1, src2, 0),
338+
Ok(src2) => encode::br_if_xulteq32_u8(sink, src1, src2, rel),
339+
Err(_) => encode::br_if_xulteq32_u32(sink, src1, src2, rel),
340340
},
341341
Cond::IfXugt32I32 { src1, src2 } => match u8::try_from(src2) {
342-
Ok(src2) => encode::br_if_xugt32_u8(sink, src1, src2, 0),
343-
Err(_) => encode::br_if_xugt32_u32(sink, src1, src2, 0),
342+
Ok(src2) => encode::br_if_xugt32_u8(sink, src1, src2, rel),
343+
Err(_) => encode::br_if_xugt32_u32(sink, src1, src2, rel),
344344
},
345345
Cond::IfXugteq32I32 { src1, src2 } => match u8::try_from(src2) {
346-
Ok(src2) => encode::br_if_xugteq32_u8(sink, src1, src2, 0),
347-
Err(_) => encode::br_if_xugteq32_u32(sink, src1, src2, 0),
346+
Ok(src2) => encode::br_if_xugteq32_u8(sink, src1, src2, rel),
347+
Err(_) => encode::br_if_xugteq32_u32(sink, src1, src2, rel),
348348
},
349349

350350
Cond::IfXeq64I32 { src1, src2 } => match i8::try_from(src2) {
351-
Ok(src2) => encode::br_if_xeq64_i8(sink, src1, src2, 0),
352-
Err(_) => encode::br_if_xeq64_i32(sink, src1, src2, 0),
351+
Ok(src2) => encode::br_if_xeq64_i8(sink, src1, src2, rel),
352+
Err(_) => encode::br_if_xeq64_i32(sink, src1, src2, rel),
353353
},
354354
Cond::IfXneq64I32 { src1, src2 } => match i8::try_from(src2) {
355-
Ok(src2) => encode::br_if_xneq64_i8(sink, src1, src2, 0),
356-
Err(_) => encode::br_if_xneq64_i32(sink, src1, src2, 0),
355+
Ok(src2) => encode::br_if_xneq64_i8(sink, src1, src2, rel),
356+
Err(_) => encode::br_if_xneq64_i32(sink, src1, src2, rel),
357357
},
358358
Cond::IfXslt64I32 { src1, src2 } => match i8::try_from(src2) {
359-
Ok(src2) => encode::br_if_xslt64_i8(sink, src1, src2, 0),
360-
Err(_) => encode::br_if_xslt64_i32(sink, src1, src2, 0),
359+
Ok(src2) => encode::br_if_xslt64_i8(sink, src1, src2, rel),
360+
Err(_) => encode::br_if_xslt64_i32(sink, src1, src2, rel),
361361
},
362362
Cond::IfXslteq64I32 { src1, src2 } => match i8::try_from(src2) {
363-
Ok(src2) => encode::br_if_xslteq64_i8(sink, src1, src2, 0),
364-
Err(_) => encode::br_if_xslteq64_i32(sink, src1, src2, 0),
363+
Ok(src2) => encode::br_if_xslteq64_i8(sink, src1, src2, rel),
364+
Err(_) => encode::br_if_xslteq64_i32(sink, src1, src2, rel),
365365
},
366366
Cond::IfXsgt64I32 { src1, src2 } => match i8::try_from(src2) {
367-
Ok(src2) => encode::br_if_xsgt64_i8(sink, src1, src2, 0),
368-
Err(_) => encode::br_if_xsgt64_i32(sink, src1, src2, 0),
367+
Ok(src2) => encode::br_if_xsgt64_i8(sink, src1, src2, rel),
368+
Err(_) => encode::br_if_xsgt64_i32(sink, src1, src2, rel),
369369
},
370370
Cond::IfXsgteq64I32 { src1, src2 } => match i8::try_from(src2) {
371-
Ok(src2) => encode::br_if_xsgteq64_i8(sink, src1, src2, 0),
372-
Err(_) => encode::br_if_xsgteq64_i32(sink, src1, src2, 0),
371+
Ok(src2) => encode::br_if_xsgteq64_i8(sink, src1, src2, rel),
372+
Err(_) => encode::br_if_xsgteq64_i32(sink, src1, src2, rel),
373373
},
374374
Cond::IfXult64I32 { src1, src2 } => match u8::try_from(src2) {
375-
Ok(src2) => encode::br_if_xult64_u8(sink, src1, src2, 0),
376-
Err(_) => encode::br_if_xult64_u32(sink, src1, src2, 0),
375+
Ok(src2) => encode::br_if_xult64_u8(sink, src1, src2, rel),
376+
Err(_) => encode::br_if_xult64_u32(sink, src1, src2, rel),
377377
},
378378
Cond::IfXulteq64I32 { src1, src2 } => match u8::try_from(src2) {
379-
Ok(src2) => encode::br_if_xulteq64_u8(sink, src1, src2, 0),
380-
Err(_) => encode::br_if_xulteq64_u32(sink, src1, src2, 0),
379+
Ok(src2) => encode::br_if_xulteq64_u8(sink, src1, src2, rel),
380+
Err(_) => encode::br_if_xulteq64_u32(sink, src1, src2, rel),
381381
},
382382
Cond::IfXugt64I32 { src1, src2 } => match u8::try_from(src2) {
383-
Ok(src2) => encode::br_if_xugt64_u8(sink, src1, src2, 0),
384-
Err(_) => encode::br_if_xugt64_u32(sink, src1, src2, 0),
383+
Ok(src2) => encode::br_if_xugt64_u8(sink, src1, src2, rel),
384+
Err(_) => encode::br_if_xugt64_u32(sink, src1, src2, rel),
385385
},
386386
Cond::IfXugteq64I32 { src1, src2 } => match u8::try_from(src2) {
387-
Ok(src2) => encode::br_if_xugteq64_u8(sink, src1, src2, 0),
388-
Err(_) => encode::br_if_xugteq64_u32(sink, src1, src2, 0),
387+
Ok(src2) => encode::br_if_xugteq64_u8(sink, src1, src2, rel),
388+
Err(_) => encode::br_if_xugteq64_u32(sink, src1, src2, rel),
389389
},
390390
}
391391
}

0 commit comments

Comments
 (0)