Skip to content

Commit 3ec8d7a

Browse files
committed
Implement _mm_cmpestri and _mm_cmpestrm using inline asm
1 parent 9c95819 commit 3ec8d7a

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

src/intrinsics/llvm_x86.rs

+98
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,104 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
720720
}
721721
}
722722

723+
"llvm.x86.sse42.pcmpestri128" => {
724+
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpestri&ig_expand=939
725+
intrinsic_args!(fx, args => (a, la, b, lb, _imm8); intrinsic);
726+
727+
let a = a.load_scalar(fx);
728+
let la = la.load_scalar(fx);
729+
let b = b.load_scalar(fx);
730+
let lb = lb.load_scalar(fx);
731+
732+
let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[4])
733+
{
734+
imm8
735+
} else {
736+
fx.tcx.sess.span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant");
737+
};
738+
739+
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
740+
741+
codegen_inline_asm_inner(
742+
fx,
743+
&[InlineAsmTemplatePiece::String(format!("pcmpestri xmm0, xmm1, {imm8}"))],
744+
&[
745+
CInlineAsmOperand::In {
746+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
747+
value: a,
748+
},
749+
CInlineAsmOperand::In {
750+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
751+
value: b,
752+
},
753+
// Implicit argument to the pcmpestri intrinsic
754+
CInlineAsmOperand::In {
755+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
756+
value: la,
757+
},
758+
// Implicit argument to the pcmpestri intrinsic
759+
CInlineAsmOperand::In {
760+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
761+
value: lb,
762+
},
763+
// Implicit result of the pcmpestri intrinsic
764+
CInlineAsmOperand::Out {
765+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
766+
late: true,
767+
place: Some(ret),
768+
},
769+
],
770+
InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
771+
);
772+
}
773+
774+
"llvm.x86.sse42.pcmpestrm128" => {
775+
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpestrm&ig_expand=940
776+
intrinsic_args!(fx, args => (a, la, b, lb, _imm8); intrinsic);
777+
778+
let a = a.load_scalar(fx);
779+
let la = la.load_scalar(fx);
780+
let b = b.load_scalar(fx);
781+
let lb = lb.load_scalar(fx);
782+
783+
let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[4])
784+
{
785+
imm8
786+
} else {
787+
fx.tcx.sess.span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant");
788+
};
789+
790+
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
791+
792+
codegen_inline_asm_inner(
793+
fx,
794+
&[InlineAsmTemplatePiece::String(format!("pcmpestrm xmm0, xmm1, {imm8}"))],
795+
&[
796+
CInlineAsmOperand::InOut {
797+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
798+
_late: true,
799+
in_value: a,
800+
out_place: Some(ret),
801+
},
802+
CInlineAsmOperand::In {
803+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
804+
value: b,
805+
},
806+
// Implicit argument to the pcmpestri intrinsic
807+
CInlineAsmOperand::In {
808+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
809+
value: la,
810+
},
811+
// Implicit argument to the pcmpestri intrinsic
812+
CInlineAsmOperand::In {
813+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
814+
value: lb,
815+
},
816+
],
817+
InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
818+
);
819+
}
820+
723821
"llvm.x86.pclmulqdq" => {
724822
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_clmulepi64_si128&ig_expand=772
725823
intrinsic_args!(fx, args => (a, b, _imm8); intrinsic);

0 commit comments

Comments
 (0)