machinst x64: implement loads/stores for v128 SIMD types;
This made it possible to enable more SIMD tests from the spec test suite too.
This commit is contained in:
4
build.rs
4
build.rs
@@ -182,6 +182,10 @@ fn experimental_x64_should_panic(testsuite: &str, testname: &str, strategy: &str
|
|||||||
match (testsuite, testname) {
|
match (testsuite, testname) {
|
||||||
("simd", "simd_address") => return false,
|
("simd", "simd_address") => return false,
|
||||||
("simd", "simd_const") => return false,
|
("simd", "simd_const") => return false,
|
||||||
|
("simd", "simd_i8x16_arith") => return false,
|
||||||
|
("simd", "simd_i16x8_arith") => return false,
|
||||||
|
("simd", "simd_i32x4_arith") => return false,
|
||||||
|
("simd", "simd_i64x2_arith") => return false,
|
||||||
("simd", "simd_f32x4_arith") => return false,
|
("simd", "simd_f32x4_arith") => return false,
|
||||||
("simd", "simd_f32x4_cmp") => return false,
|
("simd", "simd_f32x4_cmp") => return false,
|
||||||
("simd", "simd_f64x2_arith") => return false,
|
("simd", "simd_f64x2_arith") => return false,
|
||||||
|
|||||||
@@ -195,65 +195,23 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn gen_load_stack(mem: StackAMode, into_reg: Writable<Reg>, ty: Type) -> Self::I {
|
fn gen_load_stack(mem: StackAMode, into_reg: Writable<Reg>, ty: Type) -> Self::I {
|
||||||
let (is_int, ext_mode) = match ty {
|
let ext_kind = match ty {
|
||||||
types::B1 | types::B8 | types::I8 => (true, Some(ExtMode::BQ)),
|
types::B1
|
||||||
types::B16 | types::I16 => (true, Some(ExtMode::WQ)),
|
| types::B8
|
||||||
types::B32 | types::I32 => (true, Some(ExtMode::LQ)),
|
| types::I8
|
||||||
types::B64 | types::I64 | types::R64 => (true, None),
|
| types::B16
|
||||||
types::F32 | types::F64 => (false, None),
|
| types::I16
|
||||||
|
| types::B32
|
||||||
|
| types::I32 => ExtKind::SignExtend,
|
||||||
|
types::B64 | types::I64 | types::R64 | types::F32 | types::F64 => ExtKind::None,
|
||||||
|
_ if ty.bytes() == 16 => ExtKind::None,
|
||||||
_ => panic!("load_stack({})", ty),
|
_ => panic!("load_stack({})", ty),
|
||||||
};
|
};
|
||||||
|
Inst::load(ty, mem, into_reg, ext_kind, /* infallible */ None)
|
||||||
let mem = SyntheticAmode::from(mem);
|
|
||||||
|
|
||||||
if is_int {
|
|
||||||
match ext_mode {
|
|
||||||
Some(ext_mode) => Inst::movsx_rm_r(
|
|
||||||
ext_mode,
|
|
||||||
RegMem::mem(mem),
|
|
||||||
into_reg,
|
|
||||||
/* infallible load */ None,
|
|
||||||
),
|
|
||||||
None => Inst::mov64_m_r(mem, into_reg, None /* infallible */),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let sse_op = match ty {
|
|
||||||
types::F32 => SseOpcode::Movss,
|
|
||||||
types::F64 => SseOpcode::Movsd,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
Inst::xmm_mov(
|
|
||||||
sse_op,
|
|
||||||
RegMem::mem(mem),
|
|
||||||
into_reg,
|
|
||||||
None, /* infallible */
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_store_stack(mem: StackAMode, from_reg: Reg, ty: Type) -> Self::I {
|
fn gen_store_stack(mem: StackAMode, from_reg: Reg, ty: Type) -> Self::I {
|
||||||
let (is_int, size) = match ty {
|
Inst::store(ty, from_reg, mem, /* infallible */ None)
|
||||||
types::B1 | types::B8 | types::I8 => (true, 1),
|
|
||||||
types::B16 | types::I16 => (true, 2),
|
|
||||||
types::B32 | types::I32 => (true, 4),
|
|
||||||
types::B64 | types::I64 | types::R64 => (true, 8),
|
|
||||||
types::F32 => (false, 4),
|
|
||||||
types::F64 => (false, 8),
|
|
||||||
_ => unimplemented!("store_stack({})", ty),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mem = SyntheticAmode::from(mem);
|
|
||||||
|
|
||||||
if is_int {
|
|
||||||
Inst::mov_r_m(size, from_reg, mem, /* infallible store */ None)
|
|
||||||
} else {
|
|
||||||
let sse_op = match size {
|
|
||||||
4 => SseOpcode::Movss,
|
|
||||||
8 => SseOpcode::Movsd,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
Inst::xmm_mov_r_m(sse_op, from_reg, mem, /* infallible store */ None)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_move(to_reg: Writable<Reg>, from_reg: Reg, ty: Type) -> Self::I {
|
fn gen_move(to_reg: Writable<Reg>, from_reg: Reg, ty: Type) -> Self::I {
|
||||||
|
|||||||
Reference in New Issue
Block a user