diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp index ec7f42a7fcaddc35da6b0d25a10519efb4324657..0e21a5277fd223c1425c8ca9250f1c46cff26c9c 100644 --- a/src/cpu/x86/vm/assembler_x86.cpp +++ b/src/cpu/x86/vm/assembler_x86.cpp @@ -3804,6 +3804,14 @@ void Assembler::addq(Register dst, Register src) { emit_arith(0x03, 0xC0, dst, src); } +void Assembler::andq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_byte(0x81); + emit_operand(rsp, dst, 4); + emit_long(imm32); +} + void Assembler::andq(Register dst, int32_t imm32) { (void) prefixq_and_encode(dst->encoding()); emit_arith(0x81, 0xE0, dst, imm32); diff --git a/src/cpu/x86/vm/assembler_x86.hpp b/src/cpu/x86/vm/assembler_x86.hpp index 2cd4b5c34d555b6e2b88f07994bd1b37f890ed24..f07291cd9783d6c6192bc34879ee31e87ec6d1b0 100644 --- a/src/cpu/x86/vm/assembler_x86.hpp +++ b/src/cpu/x86/vm/assembler_x86.hpp @@ -779,6 +779,7 @@ private: void andl(Register dst, Address src); void andl(Register dst, Register src); + void andq(Address dst, int32_t imm32); void andq(Register dst, int32_t imm32); void andq(Register dst, Address src); void andq(Register dst, Register src); diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad index 7c90f7c4f0be8ec13bce5e1f245a4f70ec9d3b13..9612d4f3e2f923cc5fc92042ca882f9aa9fa664a 100644 --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -830,6 +830,17 @@ void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { } } +// This could be in MacroAssembler but it's fairly C2 specific +void emit_cmpfp_fixup(MacroAssembler& _masm) { + Label exit; + __ jccb(Assembler::noParity, exit); + __ pushf(); + __ andq(Address(rsp, 0), 0xffffff2b); + __ popf(); + __ bind(exit); + __ nop(); // (target for branch to avoid branch to branch) +} + //============================================================================= const bool Matcher::constant_table_absolute_addressing = true; @@ -2173,27 +2184,9 @@ encode %{ emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); %} - enc_class cmpfp_fixup() - %{ - // jnp,s exit - emit_opcode(cbuf, 0x7B); - emit_d8(cbuf, 0x0A); - - // pushfq - emit_opcode(cbuf, 0x9C); - - // andq $0xffffff2b, (%rsp) - emit_opcode(cbuf, Assembler::REX_W); - emit_opcode(cbuf, 0x81); - emit_opcode(cbuf, 0x24); - emit_opcode(cbuf, 0x24); - emit_d32(cbuf, 0xffffff2b); - - // popfq - emit_opcode(cbuf, 0x9D); - - // nop (target for branch to avoid branch to branch) - emit_opcode(cbuf, 0x90); + enc_class cmpfp_fixup() %{ + MacroAssembler _masm(&cbuf); + emit_cmpfp_fixup(_masm); %} enc_class cmpfp3(rRegI dst) @@ -10253,14 +10246,8 @@ instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ "popfq\n" "exit: nop\t# avoid branch to branch" %} ins_encode %{ - Label L_exit; __ ucomiss($src$$XMMRegister, $constantaddress($con)); - __ jcc(Assembler::noParity, L_exit); - __ pushf(); - __ andq(rsp, 0xffffff2b); - __ popf(); - __ bind(L_exit); - __ nop(); + emit_cmpfp_fixup(_masm); %} ins_pipe(pipe_slow); %} @@ -10341,14 +10328,8 @@ instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ "popfq\n" "exit: nop\t# avoid branch to branch" %} ins_encode %{ - Label L_exit; __ ucomisd($src$$XMMRegister, $constantaddress($con)); - __ jcc(Assembler::noParity, L_exit); - __ pushf(); - __ andq(rsp, 0xffffff2b); - __ popf(); - __ bind(L_exit); - __ nop(); + emit_cmpfp_fixup(_masm); %} ins_pipe(pipe_slow); %}