Legalize load.i128 and store.i128
This commit is contained in:
@@ -14,7 +14,7 @@ use crate::cdsl::type_inference::Constraint;
|
||||
use crate::cdsl::types::{LaneType, ReferenceType, ValueType, VectorType};
|
||||
use crate::cdsl::typevar::TypeVar;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct OpcodeNumber(u32);
|
||||
entity_impl!(OpcodeNumber);
|
||||
|
||||
|
||||
@@ -247,16 +247,16 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
|
||||
def!((xl, xh) = isplit(x)),
|
||||
def!(
|
||||
a = icmp_imm(
|
||||
Literal::enumerator_for(intcc, "eq"),
|
||||
Literal::enumerator_for(&imm.intcc, "eq"),
|
||||
xl,
|
||||
Literal::constant(imm64, 0)
|
||||
Literal::constant(&imm.imm64, 0)
|
||||
)
|
||||
),
|
||||
def!(
|
||||
b = icmp_imm(
|
||||
Literal::enumerator_for(intcc, "eq"),
|
||||
Literal::enumerator_for(&imm.intcc, "eq"),
|
||||
xh,
|
||||
Literal::constant(imm64, 0)
|
||||
Literal::constant(&imm.imm64, 0)
|
||||
)
|
||||
),
|
||||
def!(c = band(a, b)),
|
||||
@@ -273,6 +273,30 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
|
||||
],
|
||||
);
|
||||
|
||||
// FIXME generalize to any offset once offset+8 can be represented
|
||||
narrow.legalize(
|
||||
def!(a = load.I128(flags, ptr, Literal::constant(&imm.offset32, 0))),
|
||||
vec![
|
||||
def!(al = load.I64(flags, ptr, Literal::constant(&imm.offset32, 0))),
|
||||
def!(ah = load.I64(flags, ptr, Literal::constant(&imm.offset32, 8))),
|
||||
// `iconcat` expects the same byte order as stored in memory,
|
||||
// so no need to swap depending on endianness.
|
||||
def!(a = iconcat(al, ah)),
|
||||
],
|
||||
);
|
||||
|
||||
// FIXME generalize to any offset once offset+8 can be represented
|
||||
narrow.legalize(
|
||||
def!(store.I128(flags, a, ptr, Literal::constant(&imm.offset32, 0))),
|
||||
vec![
|
||||
// `isplit` gives the same byte order as stored in memory,
|
||||
// so no need to swap depending on endianness.
|
||||
def!((al, ah) = isplit(a)),
|
||||
def!(store.I64(flags, al, ptr, Literal::constant(&imm.offset32, 0))),
|
||||
def!(store.I64(flags, ah, ptr, Literal::constant(&imm.offset32, 8))),
|
||||
],
|
||||
);
|
||||
|
||||
// Widen instructions with one input operand.
|
||||
for &op in &[bnot, popcnt] {
|
||||
for &int_ty in &[I8, I16] {
|
||||
|
||||
@@ -26,3 +26,21 @@ ebb0(v0: i128):
|
||||
; check: v6 = x86_pop.i64
|
||||
; check: return v3, v4, v6
|
||||
}
|
||||
|
||||
function u0:1(i64, i128) fast {
|
||||
; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v4: i64 [%rbp]):
|
||||
ebb0(v0: i64, v1: i128):
|
||||
; check: store v2, v0
|
||||
; check: store v3, v0+8
|
||||
store v1, v0
|
||||
return
|
||||
}
|
||||
|
||||
function u0:1(i64) -> i128 fast {
|
||||
ebb0(v0: i64):
|
||||
; check: v2 = load.i64 v0
|
||||
; check: v3 = load.i64 v0+8
|
||||
v1 = load.i128 v0
|
||||
; check: return v2, v3, v5
|
||||
return v1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user