Support explicit endianness in Cranelift IR MemFlags
WebAssembly memory operations are by definition little-endian even on big-endian target platforms. However, other memory accesses will require native target endianness (e.g. to access parts of the VMContext that is also accessed by VM native code). This means on big-endian targets, the code generator will have to handle both little- and big-endian memory accesses. However, there is currently no way to encode that distinction into the Cranelift IR that describes memory accesses. This patch provides such a way by adding an (optional) explicit endianness marker to an instance of MemFlags. Since each Cranelift IR instruction that describes memory accesses already has an instance of MemFlags attached, this can now be used to provide endianness information. Note that by default, memory accesses will continue to use the native target ISA endianness. To override this to specify an explicit endianness, a MemFlags value that was built using the set_endianness routine must be used. This patch does so for accesses that implement WebAssembly memory operations. This patch addresses issue #2124.
This commit is contained in:
@@ -2056,7 +2056,9 @@ fn prepare_load<FE: FuncEnvironment + ?Sized>(
|
||||
// Note that we don't set `is_aligned` here, even if the load instruction's
|
||||
// alignment immediate says it's aligned, because WebAssembly's immediate
|
||||
// field is just a hint, while Cranelift's aligned flag needs a guarantee.
|
||||
let flags = MemFlags::new();
|
||||
// WebAssembly memory accesses are always little-endian.
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_endianness(ir::Endianness::Little);
|
||||
|
||||
Ok((flags, base, offset.into()))
|
||||
}
|
||||
@@ -2103,7 +2105,8 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
|
||||
builder,
|
||||
);
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
let flags = MemFlags::new();
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_endianness(ir::Endianness::Little);
|
||||
builder
|
||||
.ins()
|
||||
.Store(opcode, val_ty, flags, offset.into(), val, base);
|
||||
@@ -2207,7 +2210,8 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
|
||||
finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
let flags = MemFlags::new();
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_endianness(ir::Endianness::Little);
|
||||
let mut res = builder
|
||||
.ins()
|
||||
.atomic_rmw(access_ty, flags, op, final_effective_address, arg2);
|
||||
@@ -2260,7 +2264,8 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
|
||||
finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
let flags = MemFlags::new();
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_endianness(ir::Endianness::Little);
|
||||
let mut res = builder
|
||||
.ins()
|
||||
.atomic_cas(flags, final_effective_address, expected, replacement);
|
||||
@@ -2302,7 +2307,8 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
|
||||
finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
let flags = MemFlags::new();
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_endianness(ir::Endianness::Little);
|
||||
let mut res = builder
|
||||
.ins()
|
||||
.atomic_load(access_ty, flags, final_effective_address);
|
||||
@@ -2348,7 +2354,8 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
|
||||
finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
let flags = MemFlags::new();
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_endianness(ir::Endianness::Little);
|
||||
builder
|
||||
.ins()
|
||||
.atomic_store(flags, data, final_effective_address);
|
||||
|
||||
Reference in New Issue
Block a user