mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1657062: vendor Cranelift to rev fc88898e9ad7766feadfa0954c4594fcccd86b92 to fix fuzzbug. r=jseward
This patch vendors in the latest version of Cranelift, including the following PR, which fixes this fuzzbug: https://github.com/bytecodealliance/wasmtime/pull/2097 Differential Revision: https://phabricator.services.mozilla.com/D86044
This commit is contained in:
parent
002102679d
commit
534b2e3e86
@ -60,7 +60,7 @@ rev = "3224e2dee65c0726c448484d4c3c43956b9330ec"
|
||||
[source."https://github.com/bytecodealliance/wasmtime"]
|
||||
git = "https://github.com/bytecodealliance/wasmtime"
|
||||
replace-with = "vendored-sources"
|
||||
rev = "25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
rev = "fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
|
||||
[source."https://github.com/badboy/failure"]
|
||||
git = "https://github.com/badboy/failure"
|
||||
|
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -753,7 +753,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
dependencies = [
|
||||
"cranelift-entity 0.66.0",
|
||||
]
|
||||
@ -761,7 +761,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"cranelift-bforest",
|
||||
@ -778,7 +778,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity 0.66.0",
|
||||
@ -787,7 +787,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
@ -797,12 +797,12 @@ source = "git+https://github.com/PLSysSec/lucet_sandbox_compiler?rev=6594bb9dfab
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
@ -813,7 +813,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cranelift-wasm"
|
||||
version = "0.66.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=25e31739a63b7a33a4a34c961b88606c76670e46#25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime?rev=fc88898e9ad7766feadfa0954c4594fcccd86b92#fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"cranelift-entity 0.66.0",
|
||||
|
@ -75,8 +75,8 @@ failure_derive = { git = "https://github.com/badboy/failure", rev = "64af847bc5f
|
||||
|
||||
[patch.crates-io.cranelift-codegen]
|
||||
git = "https://github.com/bytecodealliance/wasmtime"
|
||||
rev = "25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
rev = "fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
|
||||
[patch.crates-io.cranelift-wasm]
|
||||
git = "https://github.com/bytecodealliance/wasmtime"
|
||||
rev = "25e31739a63b7a33a4a34c961b88606c76670e46"
|
||||
rev = "fc88898e9ad7766feadfa0954c4594fcccd86b92"
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,20 +1,17 @@
|
||||
//! Implementation of the standard x64 ABI.
|
||||
|
||||
use log::trace;
|
||||
use regalloc::{RealReg, Reg, RegClass, Set, SpillSlot, Writable};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use std::mem;
|
||||
|
||||
use crate::binemit::Stackmap;
|
||||
use crate::ir::{self, types, types::*, ArgumentExtension, StackSlot, Type};
|
||||
use crate::isa::{x64::inst::*, CallConv};
|
||||
use crate::machinst::*;
|
||||
use crate::settings;
|
||||
use crate::{CodegenError, CodegenResult};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use args::*;
|
||||
use log::trace;
|
||||
use regalloc::{RealReg, Reg, RegClass, Set, SpillSlot, Writable};
|
||||
use std::mem;
|
||||
|
||||
/// This is the limit for the size of argument and return-value areas on the
|
||||
/// stack. We place a reasonable limit here to avoid integer overflow issues
|
||||
|
@ -1,18 +1,13 @@
|
||||
//! Instruction operand sub-components (aka "parts"): definitions and printing.
|
||||
|
||||
use std::fmt;
|
||||
use std::string::{String, ToString};
|
||||
|
||||
use regalloc::{RealRegUniverse, Reg, RegClass, RegUsageCollector, RegUsageMapper};
|
||||
|
||||
use super::regs::{self, show_ireg_sized};
|
||||
use super::EmitState;
|
||||
use crate::ir::condcodes::{FloatCC, IntCC};
|
||||
use crate::machinst::*;
|
||||
|
||||
use super::{
|
||||
regs::{self, show_ireg_sized},
|
||||
EmitState,
|
||||
};
|
||||
use core::fmt::Debug;
|
||||
use regalloc::{RealRegUniverse, Reg, RegClass, RegUsageCollector, RegUsageMapper};
|
||||
use std::fmt;
|
||||
use std::string::{String, ToString};
|
||||
|
||||
/// A possible addressing mode (amode) that can be used in instructions.
|
||||
/// These denote a 64-bit value only.
|
||||
|
@ -1767,8 +1767,8 @@ pub(crate) fn emit(
|
||||
|
||||
Inst::XmmRmRImm { op, src, dst, imm } => {
|
||||
let prefix = match op {
|
||||
SseOpcode::Cmpps => LegacyPrefix::_66,
|
||||
SseOpcode::Cmppd => LegacyPrefix::None,
|
||||
SseOpcode::Cmpps => LegacyPrefix::None,
|
||||
SseOpcode::Cmppd => LegacyPrefix::_66,
|
||||
SseOpcode::Cmpss => LegacyPrefix::_F3,
|
||||
SseOpcode::Cmpsd => LegacyPrefix::_F2,
|
||||
_ => unimplemented!("Opcode {:?} not implemented", op),
|
||||
@ -1949,9 +1949,9 @@ pub(crate) fn emit(
|
||||
//
|
||||
// done:
|
||||
|
||||
assert!(src != tmp_gpr1);
|
||||
assert!(src != tmp_gpr2);
|
||||
assert!(tmp_gpr1 != tmp_gpr2);
|
||||
assert_ne!(src, tmp_gpr1);
|
||||
assert_ne!(src, tmp_gpr2);
|
||||
assert_ne!(tmp_gpr1, tmp_gpr2);
|
||||
|
||||
let handle_negative = sink.get_label();
|
||||
let done = sink.get_label();
|
||||
@ -2251,7 +2251,7 @@ pub(crate) fn emit(
|
||||
//
|
||||
// done:
|
||||
|
||||
assert!(tmp_xmm != src, "tmp_xmm clobbers src!");
|
||||
assert_ne!(tmp_xmm, src, "tmp_xmm clobbers src!");
|
||||
|
||||
let (sub_op, cast_op, cmp_op, trunc_op) = if *src_size == OperandSize::Size64 {
|
||||
(
|
||||
|
@ -9,10 +9,9 @@
|
||||
//! (cd cranelift/codegen && \
|
||||
//! RUST_BACKTRACE=1 cargo test isa::x64::inst::test_x64_insn_encoding_and_printing -- --nocapture)
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use super::*;
|
||||
use crate::isa::test_utils;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[test]
|
||||
fn test_x64_emit() {
|
||||
@ -3191,6 +3190,19 @@ fn test_x64_emit() {
|
||||
"psrlq $1, %xmm3",
|
||||
));
|
||||
|
||||
// ========================================================
|
||||
// XmmRmRImm
|
||||
insns.push((
|
||||
Inst::xmm_rm_r_imm(SseOpcode::Cmppd, RegMem::reg(xmm5), w_xmm1, 2),
|
||||
"660FC2CD02",
|
||||
"cmppd $2, %xmm5, %xmm1",
|
||||
));
|
||||
insns.push((
|
||||
Inst::xmm_rm_r_imm(SseOpcode::Cmpps, RegMem::reg(xmm15), w_xmm7, 0),
|
||||
"410FC2FF00",
|
||||
"cmpps $0, %xmm15, %xmm7",
|
||||
));
|
||||
|
||||
// ========================================================
|
||||
// Misc instructions.
|
||||
|
||||
|
@ -4,21 +4,20 @@
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use std::fmt;
|
||||
use std::string::{String, ToString};
|
||||
|
||||
use regalloc::RegUsageCollector;
|
||||
use regalloc::{RealRegUniverse, Reg, RegClass, RegUsageMapper, SpillSlot, VirtualReg, Writable};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::binemit::{CodeOffset, Stackmap};
|
||||
use crate::ir::types::*;
|
||||
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode, Type};
|
||||
use crate::machinst::*;
|
||||
use crate::settings::Flags;
|
||||
use crate::{settings, CodegenError, CodegenResult};
|
||||
use crate::{settings, settings::Flags, CodegenError, CodegenResult};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use regalloc::{
|
||||
RealRegUniverse, Reg, RegClass, RegUsageCollector, RegUsageMapper, SpillSlot, VirtualReg,
|
||||
Writable,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::fmt;
|
||||
use std::string::{String, ToString};
|
||||
|
||||
pub mod args;
|
||||
mod emit;
|
||||
|
@ -10,13 +10,10 @@
|
||||
//! Also, they will have to be ABI dependent. Need to find a way to avoid constructing a universe
|
||||
//! for each function we compile.
|
||||
|
||||
use crate::{machinst::pretty_print::ShowWithRRU, settings};
|
||||
use alloc::vec::Vec;
|
||||
use std::string::String;
|
||||
|
||||
use regalloc::{RealReg, RealRegUniverse, Reg, RegClass, RegClassInfo, NUM_REG_CLASSES};
|
||||
|
||||
use crate::machinst::pretty_print::ShowWithRRU;
|
||||
use crate::settings;
|
||||
use std::string::String;
|
||||
|
||||
// Hardware encodings for a few registers.
|
||||
|
||||
|
@ -2,31 +2,26 @@
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use log::trace;
|
||||
use regalloc::{Reg, RegClass, Writable};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::ir::types;
|
||||
use crate::ir::types::*;
|
||||
use crate::ir::Inst as IRInst;
|
||||
use crate::ir::{
|
||||
condcodes::FloatCC, condcodes::IntCC, AbiParam, ArgumentPurpose, ExternalName, InstructionData,
|
||||
LibCall, Opcode, Signature, TrapCode, Type,
|
||||
condcodes::FloatCC, condcodes::IntCC, types, AbiParam, ArgumentPurpose, ExternalName,
|
||||
Inst as IRInst, InstructionData, LibCall, Opcode, Signature, TrapCode, Type,
|
||||
};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use cranelift_codegen_shared::condcodes::CondCode;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use crate::machinst::lower::*;
|
||||
use crate::machinst::*;
|
||||
use crate::result::CodegenResult;
|
||||
use crate::settings::Flags;
|
||||
|
||||
use crate::isa::x64::abi::*;
|
||||
use crate::isa::x64::inst::args::*;
|
||||
use crate::isa::x64::inst::*;
|
||||
use crate::isa::{x64::X64Backend, CallConv};
|
||||
use crate::machinst::lower::*;
|
||||
use crate::machinst::*;
|
||||
use crate::result::CodegenResult;
|
||||
use crate::settings::Flags;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use cranelift_codegen_shared::condcodes::CondCode;
|
||||
use log::trace;
|
||||
use regalloc::{Reg, RegClass, Writable};
|
||||
use smallvec::SmallVec;
|
||||
use std::convert::TryFrom;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
/// Context passed to all lowering functions.
|
||||
@ -282,7 +277,7 @@ fn emit_vm_call<C: LowerCtx<I = Inst>>(
|
||||
abi.emit_stack_pre_adjust(ctx);
|
||||
|
||||
let vm_context = if call_conv.extends_baldrdash() { 1 } else { 0 };
|
||||
assert!(inputs.len() + vm_context == abi.num_args());
|
||||
assert_eq!(inputs.len() + vm_context, abi.num_args());
|
||||
|
||||
for (i, input) in inputs.iter().enumerate() {
|
||||
let arg_reg = input_to_reg(ctx, *input);
|
||||
@ -860,92 +855,137 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
Opcode::Fcmp => {
|
||||
let condcode = inst_fp_condcode(ctx.data(insn)).unwrap();
|
||||
let input_ty = ctx.input_ty(insn, 0);
|
||||
let op = match input_ty {
|
||||
F32 => SseOpcode::Ucomiss,
|
||||
F64 => SseOpcode::Ucomisd,
|
||||
_ => panic!("Bad input type to Fcmp"),
|
||||
};
|
||||
if !input_ty.is_vector() {
|
||||
let op = match input_ty {
|
||||
F32 => SseOpcode::Ucomiss,
|
||||
F64 => SseOpcode::Ucomisd,
|
||||
_ => panic!("Bad input type to fcmp: {}", input_ty),
|
||||
};
|
||||
|
||||
// Unordered is returned by setting ZF, PF, CF <- 111
|
||||
// Greater than by ZF, PF, CF <- 000
|
||||
// Less than by ZF, PF, CF <- 001
|
||||
// Equal by ZF, PF, CF <- 100
|
||||
//
|
||||
// Checking the result of comiss is somewhat annoying because you don't have setcc
|
||||
// instructions that explicitly check simultaneously for the condition (i.e. eq, le,
|
||||
// gt, etc) *and* orderedness.
|
||||
//
|
||||
// So that might mean we need more than one setcc check and then a logical "and" or
|
||||
// "or" to determine both, in some cases. However knowing that if the parity bit is
|
||||
// set, then the result was considered unordered and knowing that if the parity bit is
|
||||
// set, then both the ZF and CF flag bits must also be set we can get away with using
|
||||
// one setcc for most condition codes.
|
||||
// Unordered is returned by setting ZF, PF, CF <- 111
|
||||
// Greater than by ZF, PF, CF <- 000
|
||||
// Less than by ZF, PF, CF <- 001
|
||||
// Equal by ZF, PF, CF <- 100
|
||||
//
|
||||
// Checking the result of comiss is somewhat annoying because you don't have setcc
|
||||
// instructions that explicitly check simultaneously for the condition (i.e. eq, le,
|
||||
// gt, etc) *and* orderedness.
|
||||
//
|
||||
// So that might mean we need more than one setcc check and then a logical "and" or
|
||||
// "or" to determine both, in some cases. However knowing that if the parity bit is
|
||||
// set, then the result was considered unordered and knowing that if the parity bit is
|
||||
// set, then both the ZF and CF flag bits must also be set we can get away with using
|
||||
// one setcc for most condition codes.
|
||||
|
||||
match condcode {
|
||||
FloatCC::LessThan
|
||||
| FloatCC::LessThanOrEqual
|
||||
| FloatCC::UnorderedOrGreaterThan
|
||||
| FloatCC::UnorderedOrGreaterThanOrEqual => {
|
||||
// setb and setbe for ordered LessThan and LessThanOrEqual check if CF = 1
|
||||
// which doesn't exclude unorderdness. To get around this we can reverse the
|
||||
// operands and the cc test to instead check if CF and ZF are 0 which would
|
||||
// also excludes unorderedness. Using similiar logic we also reverse
|
||||
// UnorderedOrGreaterThan and UnorderedOrGreaterThanOrEqual and assure that ZF
|
||||
// or CF is 1 to exclude orderedness.
|
||||
let lhs = input_to_reg_mem(ctx, inputs[0]);
|
||||
let rhs = input_to_reg(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, lhs, rhs));
|
||||
let condcode = condcode.reverse();
|
||||
let cc = CC::from_floatcc(condcode);
|
||||
ctx.emit(Inst::setcc(cc, dst));
|
||||
match condcode {
|
||||
FloatCC::LessThan
|
||||
| FloatCC::LessThanOrEqual
|
||||
| FloatCC::UnorderedOrGreaterThan
|
||||
| FloatCC::UnorderedOrGreaterThanOrEqual => {
|
||||
// setb and setbe for ordered LessThan and LessThanOrEqual check if CF = 1
|
||||
// which doesn't exclude unorderdness. To get around this we can reverse the
|
||||
// operands and the cc test to instead check if CF and ZF are 0 which would
|
||||
// also excludes unorderedness. Using similiar logic we also reverse
|
||||
// UnorderedOrGreaterThan and UnorderedOrGreaterThanOrEqual and assure that ZF
|
||||
// or CF is 1 to exclude orderedness.
|
||||
let lhs = input_to_reg_mem(ctx, inputs[0]);
|
||||
let rhs = input_to_reg(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, lhs, rhs));
|
||||
let condcode = condcode.reverse();
|
||||
let cc = CC::from_floatcc(condcode);
|
||||
ctx.emit(Inst::setcc(cc, dst));
|
||||
}
|
||||
|
||||
FloatCC::Equal => {
|
||||
// Outlier case: equal means both the operands are ordered and equal; we cannot
|
||||
// get around checking the parity bit to determine if the result was ordered.
|
||||
let lhs = input_to_reg(ctx, inputs[0]);
|
||||
let rhs = input_to_reg_mem(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
let tmp_gpr1 = ctx.alloc_tmp(RegClass::I64, I32);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, rhs, lhs));
|
||||
ctx.emit(Inst::setcc(CC::NP, tmp_gpr1));
|
||||
ctx.emit(Inst::setcc(CC::Z, dst));
|
||||
ctx.emit(Inst::alu_rmi_r(
|
||||
false,
|
||||
AluRmiROpcode::And,
|
||||
RegMemImm::reg(tmp_gpr1.to_reg()),
|
||||
dst,
|
||||
));
|
||||
}
|
||||
|
||||
FloatCC::NotEqual => {
|
||||
// Outlier case: not equal means either the operands are unordered, or they're
|
||||
// not the same value.
|
||||
let lhs = input_to_reg(ctx, inputs[0]);
|
||||
let rhs = input_to_reg_mem(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
let tmp_gpr1 = ctx.alloc_tmp(RegClass::I64, I32);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, rhs, lhs));
|
||||
ctx.emit(Inst::setcc(CC::P, tmp_gpr1));
|
||||
ctx.emit(Inst::setcc(CC::NZ, dst));
|
||||
ctx.emit(Inst::alu_rmi_r(
|
||||
false,
|
||||
AluRmiROpcode::Or,
|
||||
RegMemImm::reg(tmp_gpr1.to_reg()),
|
||||
dst,
|
||||
));
|
||||
}
|
||||
|
||||
_ => {
|
||||
// For all remaining condition codes we can handle things with one check.
|
||||
let lhs = input_to_reg(ctx, inputs[0]);
|
||||
let rhs = input_to_reg_mem(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
let cc = CC::from_floatcc(condcode);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, rhs, lhs));
|
||||
ctx.emit(Inst::setcc(cc, dst));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let op = match input_ty {
|
||||
types::F32X4 => SseOpcode::Cmpps,
|
||||
types::F64X2 => SseOpcode::Cmppd,
|
||||
_ => panic!("Bad input type to fcmp: {}", input_ty),
|
||||
};
|
||||
|
||||
FloatCC::Equal => {
|
||||
// Outlier case: equal means both the operands are ordered and equal; we cannot
|
||||
// get around checking the parity bit to determine if the result was ordered.
|
||||
let lhs = input_to_reg(ctx, inputs[0]);
|
||||
let rhs = input_to_reg_mem(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
let tmp_gpr1 = ctx.alloc_tmp(RegClass::I64, I32);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, rhs, lhs));
|
||||
ctx.emit(Inst::setcc(CC::NP, tmp_gpr1));
|
||||
ctx.emit(Inst::setcc(CC::Z, dst));
|
||||
ctx.emit(Inst::alu_rmi_r(
|
||||
false,
|
||||
AluRmiROpcode::And,
|
||||
RegMemImm::reg(tmp_gpr1.to_reg()),
|
||||
dst,
|
||||
));
|
||||
}
|
||||
// Since some packed comparisons are not available, some of the condition codes
|
||||
// must be inverted, with a corresponding `flip` of the operands.
|
||||
let (imm, flip) = match condcode {
|
||||
FloatCC::GreaterThan => (FcmpImm::LessThan, true),
|
||||
FloatCC::GreaterThanOrEqual => (FcmpImm::LessThanOrEqual, true),
|
||||
FloatCC::UnorderedOrLessThan => (FcmpImm::UnorderedOrGreaterThan, true),
|
||||
FloatCC::UnorderedOrLessThanOrEqual => {
|
||||
(FcmpImm::UnorderedOrGreaterThanOrEqual, true)
|
||||
}
|
||||
FloatCC::OrderedNotEqual | FloatCC::UnorderedOrEqual => {
|
||||
panic!("unsupported float condition code: {}", condcode)
|
||||
}
|
||||
_ => (FcmpImm::from(condcode), false),
|
||||
};
|
||||
|
||||
FloatCC::NotEqual => {
|
||||
// Outlier case: not equal means either the operands are unordered, or they're
|
||||
// not the same value.
|
||||
let lhs = input_to_reg(ctx, inputs[0]);
|
||||
let rhs = input_to_reg_mem(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
let tmp_gpr1 = ctx.alloc_tmp(RegClass::I64, I32);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, rhs, lhs));
|
||||
ctx.emit(Inst::setcc(CC::P, tmp_gpr1));
|
||||
ctx.emit(Inst::setcc(CC::NZ, dst));
|
||||
ctx.emit(Inst::alu_rmi_r(
|
||||
false,
|
||||
AluRmiROpcode::Or,
|
||||
RegMemImm::reg(tmp_gpr1.to_reg()),
|
||||
dst,
|
||||
));
|
||||
}
|
||||
// Determine the operands of the comparison, possibly by flipping them.
|
||||
let (lhs, rhs) = if flip {
|
||||
(
|
||||
input_to_reg(ctx, inputs[1]),
|
||||
input_to_reg_mem(ctx, inputs[0]),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
input_to_reg(ctx, inputs[0]),
|
||||
input_to_reg_mem(ctx, inputs[1]),
|
||||
)
|
||||
};
|
||||
|
||||
_ => {
|
||||
// For all remaining condition codes we can handle things with one check.
|
||||
let lhs = input_to_reg(ctx, inputs[0]);
|
||||
let rhs = input_to_reg_mem(ctx, inputs[1]);
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
let cc = CC::from_floatcc(condcode);
|
||||
ctx.emit(Inst::xmm_cmp_rm_r(op, rhs, lhs));
|
||||
ctx.emit(Inst::setcc(cc, dst));
|
||||
}
|
||||
// Move the `lhs` to the same register as `dst`; this may not emit an actual move
|
||||
// but ensures that the registers are the same to match x86's read-write operand
|
||||
// encoding.
|
||||
let dst = output_to_reg(ctx, outputs[0]);
|
||||
ctx.emit(Inst::gen_move(dst, lhs, input_ty));
|
||||
|
||||
// Emit the comparison.
|
||||
ctx.emit(Inst::xmm_rm_r_imm(op, rhs, dst, imm.encode()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -965,8 +1005,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
Opcode::Call => {
|
||||
let (extname, dist) = ctx.call_target(insn).unwrap();
|
||||
let sig = ctx.call_sig(insn).unwrap();
|
||||
assert!(inputs.len() == sig.params.len());
|
||||
assert!(outputs.len() == sig.returns.len());
|
||||
assert_eq!(inputs.len(), sig.params.len());
|
||||
assert_eq!(outputs.len(), sig.returns.len());
|
||||
(
|
||||
X64ABICall::from_func(sig, &extname, dist, loc)?,
|
||||
&inputs[..],
|
||||
@ -976,8 +1016,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
Opcode::CallIndirect => {
|
||||
let ptr = input_to_reg(ctx, inputs[0]);
|
||||
let sig = ctx.call_sig(insn).unwrap();
|
||||
assert!(inputs.len() - 1 == sig.params.len());
|
||||
assert!(outputs.len() == sig.returns.len());
|
||||
assert_eq!(inputs.len() - 1, sig.params.len());
|
||||
assert_eq!(outputs.len(), sig.returns.len());
|
||||
(X64ABICall::from_ptr(sig, ptr, loc, op)?, &inputs[1..])
|
||||
}
|
||||
|
||||
@ -985,7 +1025,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
};
|
||||
|
||||
abi.emit_stack_pre_adjust(ctx);
|
||||
assert!(inputs.len() == abi.num_args());
|
||||
assert_eq!(inputs.len(), abi.num_args());
|
||||
for (i, input) in inputs.iter().enumerate() {
|
||||
let arg_reg = input_to_reg(ctx, *input);
|
||||
abi.emit_copy_reg_to_arg(ctx, i, arg_reg);
|
||||
@ -1536,7 +1576,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| Opcode::Sload16
|
||||
| Opcode::Uload32
|
||||
| Opcode::Sload32 => {
|
||||
assert!(inputs.len() == 1, "only one input for load operands");
|
||||
assert_eq!(inputs.len(), 1, "only one input for load operands");
|
||||
let base = input_to_reg(ctx, inputs[0]);
|
||||
Amode::imm_reg(offset as u32, base)
|
||||
}
|
||||
@ -1548,8 +1588,9 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| Opcode::Sload16Complex
|
||||
| Opcode::Uload32Complex
|
||||
| Opcode::Sload32Complex => {
|
||||
assert!(
|
||||
inputs.len() == 2,
|
||||
assert_eq!(
|
||||
inputs.len(),
|
||||
2,
|
||||
"can't handle more than two inputs in complex load"
|
||||
);
|
||||
let base = input_to_reg(ctx, inputs[0]);
|
||||
@ -1623,10 +1664,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
|
||||
let addr = match op {
|
||||
Opcode::Store | Opcode::Istore8 | Opcode::Istore16 | Opcode::Istore32 => {
|
||||
assert!(
|
||||
inputs.len() == 2,
|
||||
"only one input for store memory operands"
|
||||
);
|
||||
assert_eq!(inputs.len(), 2, "only one input for store memory operands");
|
||||
let base = input_to_reg(ctx, inputs[1]);
|
||||
// TODO sign?
|
||||
Amode::imm_reg(offset as u32, base)
|
||||
@ -1636,8 +1674,9 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| Opcode::Istore8Complex
|
||||
| Opcode::Istore16Complex
|
||||
| Opcode::Istore32Complex => {
|
||||
assert!(
|
||||
inputs.len() == 3,
|
||||
assert_eq!(
|
||||
inputs.len(),
|
||||
3,
|
||||
"can't handle more than two inputs in complex store"
|
||||
);
|
||||
let base = input_to_reg(ctx, inputs[1]);
|
||||
@ -2028,7 +2067,7 @@ impl LowerBackend for X64Backend {
|
||||
_ => unimplemented!("branch opcode"),
|
||||
}
|
||||
} else {
|
||||
assert!(branches.len() == 1);
|
||||
assert_eq!(branches.len(), 1);
|
||||
|
||||
// Must be an unconditional branch or trap.
|
||||
let op = ctx.data(branches[0]).opcode();
|
||||
|
@ -1,21 +1,17 @@
|
||||
//! X86_64-bit Instruction Set Architecture.
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use regalloc::RealRegUniverse;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
use crate::ir::condcodes::IntCC;
|
||||
use crate::ir::Function;
|
||||
use super::TargetIsa;
|
||||
use crate::ir::{condcodes::IntCC, Function};
|
||||
use crate::isa::x64::{inst::regs::create_reg_universe_systemv, settings as x64_settings};
|
||||
use crate::isa::Builder as IsaBuilder;
|
||||
use crate::machinst::pretty_print::ShowWithRRU;
|
||||
use crate::machinst::{compile, MachBackend, MachCompileResult, TargetIsaAdapter, VCode};
|
||||
use crate::machinst::{
|
||||
compile, pretty_print::ShowWithRRU, MachBackend, MachCompileResult, TargetIsaAdapter, VCode,
|
||||
};
|
||||
use crate::result::CodegenResult;
|
||||
use crate::settings::{self as shared_settings, Flags};
|
||||
|
||||
use crate::isa::x64::{inst::regs::create_reg_universe_systemv, settings as x64_settings};
|
||||
|
||||
use super::TargetIsa;
|
||||
use alloc::boxed::Box;
|
||||
use regalloc::RealRegUniverse;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
mod abi;
|
||||
mod inst;
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"34ad61b3a40b5bfee68d575e749314cf8395484c0484fd40d39a9bd1f46d3e14","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c82c252fbeeaa101a0eef042b9a925eb1fa3d2b51d19481b9c22e593e6a8d772","src/code_translator.rs":"18348a7d922566727c7f49b6ed6b7999713928022bc4706d070e485e23af2726","src/environ/dummy.rs":"0c05a77ab37a305c799f1b0e99c9debe1b8f59a3e3aa764e2fe39a923716b2ee","src/environ/mod.rs":"692f35d75f125f9c071f7166252f427e4bac29401356f73307c6c36e23c667fb","src/environ/spec.rs":"0f97fff3cc545772a1959f7d0439713fd7dc8d8adf43a2636f8174126dc1393c","src/func_translator.rs":"48ee25da11063743459f9e9407512413075265e67713c6f5ab733798be2bf19d","src/lib.rs":"7bdbcf638fa30fb05e8320439881f7536824f7f60a7db4f0c1b51ab369edf895","src/module_translator.rs":"1374fa56ca18a782083fa0f25f2ad675044a92bbf1a0a1cc44fcaf695807e044","src/sections_translator.rs":"11d65fd2e595e41f976e5c7d0df823f70449f79a9d2facbed61263616f8cfec1","src/state/func_state.rs":"023e3eb4f69590167baecb3fa8e7b335d69a631fff68fa0ee249075699f71a30","src/state/mod.rs":"20014cb93615467b4d20321b52f67f66040417efcaa739a4804093bb559eed19","src/state/module_state.rs":"7ca3cb06b4481bc3ae74697fbcd437aea1d851eaa3cfe18cc013a4af43728957","src/translation_utils.rs":"69f20c47ea22f0badd21a6187b5f9764252a00d19643a7e3e691797a9fe34f1b","tests/wasm_testsuite.rs":"da8dedfd11918946e9cf6af68fd4826f020ef90a4e22742b1a30e61a3fb4aedd"},"package":null}
|
||||
{"files":{"Cargo.toml":"34ad61b3a40b5bfee68d575e749314cf8395484c0484fd40d39a9bd1f46d3e14","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c82c252fbeeaa101a0eef042b9a925eb1fa3d2b51d19481b9c22e593e6a8d772","src/code_translator.rs":"ee3e63141ca7c060a39428e75be9ae61bdb5b6a1f22bc04ecbbd3865007607e8","src/environ/dummy.rs":"0c05a77ab37a305c799f1b0e99c9debe1b8f59a3e3aa764e2fe39a923716b2ee","src/environ/mod.rs":"692f35d75f125f9c071f7166252f427e4bac29401356f73307c6c36e23c667fb","src/environ/spec.rs":"0f97fff3cc545772a1959f7d0439713fd7dc8d8adf43a2636f8174126dc1393c","src/func_translator.rs":"48ee25da11063743459f9e9407512413075265e67713c6f5ab733798be2bf19d","src/lib.rs":"7bdbcf638fa30fb05e8320439881f7536824f7f60a7db4f0c1b51ab369edf895","src/module_translator.rs":"1374fa56ca18a782083fa0f25f2ad675044a92bbf1a0a1cc44fcaf695807e044","src/sections_translator.rs":"11d65fd2e595e41f976e5c7d0df823f70449f79a9d2facbed61263616f8cfec1","src/state/func_state.rs":"023e3eb4f69590167baecb3fa8e7b335d69a631fff68fa0ee249075699f71a30","src/state/mod.rs":"20014cb93615467b4d20321b52f67f66040417efcaa739a4804093bb559eed19","src/state/module_state.rs":"7ca3cb06b4481bc3ae74697fbcd437aea1d851eaa3cfe18cc013a4af43728957","src/translation_utils.rs":"69f20c47ea22f0badd21a6187b5f9764252a00d19643a7e3e691797a9fe34f1b","tests/wasm_testsuite.rs":"da8dedfd11918946e9cf6af68fd4826f020ef90a4e22742b1a30e61a3fb4aedd"},"package":null}
|
@ -395,7 +395,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let i = state.control_stack.len() - 1 - (min_depth as usize);
|
||||
let min_depth_frame = &state.control_stack[i];
|
||||
if min_depth_frame.is_loop() {
|
||||
0
|
||||
min_depth_frame.num_param_values()
|
||||
} else {
|
||||
min_depth_frame.num_return_values()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user