Struct cranelift_codegen::ir::immediates::Offset32
source · pub struct Offset32(_);Expand description
32-bit signed immediate offset.
This is used to encode an immediate offset for load/store instructions. All supported ISAs have
a maximum load/store offset that fits in an i32.
Implementations§
source§impl Offset32
impl Offset32
sourcepub fn new(x: i32) -> Self
pub fn new(x: i32) -> Self
Create a new Offset32 representing the signed number x.
Examples found in repository?
More examples
src/ir/immediates.rs (line 401)
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
pub fn try_from_i64(x: i64) -> Option<Self> {
let x = i32::try_from(x).ok()?;
Some(Self::new(x))
}
/// Add in the signed number `x` if possible.
pub fn try_add_i64(self, x: i64) -> Option<Self> {
let x = i32::try_from(x).ok()?;
let ret = self.0.checked_add(x)?;
Some(Self::new(ret))
}
}
impl From<Offset32> for i32 {
fn from(val: Offset32) -> i32 {
val.0
}
}
impl From<Offset32> for i64 {
fn from(val: Offset32) -> i64 {
i64::from(val.0)
}
}
impl From<i32> for Offset32 {
fn from(x: i32) -> Self {
Self(x)
}
}
impl From<u8> for Offset32 {
fn from(val: u8) -> Offset32 {
Self(val.into())
}
}
impl Display for Offset32 {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
// 0 displays as an empty offset.
if self.0 == 0 {
return Ok(());
}
// Always include a sign.
write!(f, "{}", if self.0 < 0 { '-' } else { '+' })?;
let val = i64::from(self.0).abs();
if val < 10_000 {
write!(f, "{}", val)
} else {
write_hex(val as u64, f)
}
}
}
impl FromStr for Offset32 {
type Err = &'static str;
// Parse a decimal or hexadecimal `Offset32`, formatted as above.
fn from_str(s: &str) -> Result<Self, &'static str> {
if !(s.starts_with('-') || s.starts_with('+')) {
return Err("Offset must begin with sign");
}
parse_i64(s).and_then(|x| {
if i64::from(i32::MIN) <= x && x <= i64::from(i32::MAX) {
Ok(Self::new(x as i32))
} else {
Err("Offset out of range")
}
})
}src/legalizer/heap.rs (line 42)
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
pub fn expand_heap_load(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
isa: &dyn TargetIsa,
heap_imm: ir::HeapImm,
index: ir::Value,
) {
let HeapImmData {
flags,
heap,
offset,
} = func.dfg.heap_imms[heap_imm];
let result_ty = func.dfg.ctrl_typevar(inst);
let access_size = result_ty.bytes();
let access_size = u8::try_from(access_size).unwrap();
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let addr =
bounds_check_and_compute_addr(&mut pos, cfg, isa, heap, index, offset.into(), access_size);
pos.func
.dfg
.replace(inst)
.load(result_ty, flags, addr, Offset32::new(0));
}
/// Expand a `heap_store` instruction according to the definition of the heap.
pub fn expand_heap_store(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
isa: &dyn TargetIsa,
heap_imm: ir::HeapImm,
index: ir::Value,
value: ir::Value,
) {
let HeapImmData {
flags,
heap,
offset,
} = func.dfg.heap_imms[heap_imm];
let store_ty = func.dfg.value_type(value);
let access_size = u8::try_from(store_ty.bytes()).unwrap();
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let addr =
bounds_check_and_compute_addr(&mut pos, cfg, isa, heap, index, offset.into(), access_size);
pos.func
.dfg
.replace(inst)
.store(flags, value, addr, Offset32::new(0));
}src/legalizer/table.rs (line 93)
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
fn compute_addr(
inst: ir::Inst,
table: ir::Table,
addr_ty: ir::Type,
mut index: ir::Value,
index_ty: ir::Type,
element_offset: Offset32,
func: &mut ir::Function,
spectre_oob_cmp: Option<(ir::Value, ir::Value)>,
) {
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
// Convert `index` to `addr_ty`.
if index_ty != addr_ty {
index = pos.ins().uextend(addr_ty, index);
}
// Add the table base address base
let base_gv = pos.func.tables[table].base_gv;
let base = pos.ins().global_value(addr_ty, base_gv);
let element_size = pos.func.tables[table].element_size;
let mut offset;
let element_size: u64 = element_size.into();
if element_size == 1 {
offset = index;
} else if element_size.is_power_of_two() {
offset = pos
.ins()
.ishl_imm(index, i64::from(element_size.trailing_zeros()));
} else {
offset = pos.ins().imul_imm(index, element_size as i64);
}
let element_addr = if element_offset == Offset32::new(0) {
pos.ins().iadd(base, offset)
} else {
let imm: i64 = element_offset.into();
offset = pos.ins().iadd(base, offset);
pos.ins().iadd_imm(offset, imm)
};
let element_addr = if let Some((index, bound)) = spectre_oob_cmp {
let cond = pos
.ins()
.icmp(IntCC::UnsignedGreaterThanOrEqual, index, bound);
// If out-of-bounds, choose the table base on the misspeculation path.
pos.ins().select_spectre_guard(cond, base, element_addr)
} else {
element_addr
};
let new_inst = pos.func.dfg.value_def(element_addr).inst().unwrap();
pos.func.dfg.replace_with_aliases(inst, new_inst);
pos.remove_inst();
}sourcepub fn try_from_i64(x: i64) -> Option<Self>
pub fn try_from_i64(x: i64) -> Option<Self>
Create a new Offset32 representing the signed number x if possible.
sourcepub fn try_add_i64(self, x: i64) -> Option<Self>
pub fn try_add_i64(self, x: i64) -> Option<Self>
Add in the signed number x if possible.
Trait Implementations§
source§impl PartialEq<Offset32> for Offset32
impl PartialEq<Offset32> for Offset32
impl Copy for Offset32
impl Eq for Offset32
impl StructuralEq for Offset32
impl StructuralPartialEq for Offset32
Auto Trait Implementations§
impl RefUnwindSafe for Offset32
impl Send for Offset32
impl Sync for Offset32
impl Unpin for Offset32
impl UnwindSafe for Offset32
Blanket Implementations§
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key and return true if they are equal.