826 } else { |
826 } else { |
827 MacroAssembler _masm(&cbuf); |
827 MacroAssembler _masm(&cbuf); |
828 |
828 |
829 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding)); |
829 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding)); |
830 } |
830 } |
|
831 } |
|
832 |
|
833 // This could be in MacroAssembler but it's fairly C2 specific |
|
834 void emit_cmpfp_fixup(MacroAssembler& _masm) { |
|
835 Label exit; |
|
836 __ jccb(Assembler::noParity, exit); |
|
837 __ pushf(); |
|
838 __ andq(Address(rsp, 0), 0xffffff2b); |
|
839 __ popf(); |
|
840 __ bind(exit); |
|
841 __ nop(); // (target for branch to avoid branch to branch) |
831 } |
842 } |
832 |
843 |
833 |
844 |
834 //============================================================================= |
845 //============================================================================= |
835 const bool Matcher::constant_table_absolute_addressing = true; |
846 const bool Matcher::constant_table_absolute_addressing = true; |
2171 %{ |
2182 %{ |
2172 emit_opcode(cbuf, $opcode$$constant); |
2183 emit_opcode(cbuf, $opcode$$constant); |
2173 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); |
2184 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); |
2174 %} |
2185 %} |
2175 |
2186 |
2176 enc_class cmpfp_fixup() |
2187 enc_class cmpfp_fixup() %{ |
2177 %{ |
2188 MacroAssembler _masm(&cbuf); |
2178 // jnp,s exit |
2189 emit_cmpfp_fixup(_masm); |
2179 emit_opcode(cbuf, 0x7B); |
|
2180 emit_d8(cbuf, 0x0A); |
|
2181 |
|
2182 // pushfq |
|
2183 emit_opcode(cbuf, 0x9C); |
|
2184 |
|
2185 // andq $0xffffff2b, (%rsp) |
|
2186 emit_opcode(cbuf, Assembler::REX_W); |
|
2187 emit_opcode(cbuf, 0x81); |
|
2188 emit_opcode(cbuf, 0x24); |
|
2189 emit_opcode(cbuf, 0x24); |
|
2190 emit_d32(cbuf, 0xffffff2b); |
|
2191 |
|
2192 // popfq |
|
2193 emit_opcode(cbuf, 0x9D); |
|
2194 |
|
2195 // nop (target for branch to avoid branch to branch) |
|
2196 emit_opcode(cbuf, 0x90); |
|
2197 %} |
2190 %} |
2198 |
2191 |
2199 enc_class cmpfp3(rRegI dst) |
2192 enc_class cmpfp3(rRegI dst) |
2200 %{ |
2193 %{ |
2201 int dstenc = $dst$$reg; |
2194 int dstenc = $dst$$reg; |
10251 "pushfq\t# saw NaN, set CF\n\t" |
10244 "pushfq\t# saw NaN, set CF\n\t" |
10252 "andq [rsp], #0xffffff2b\n\t" |
10245 "andq [rsp], #0xffffff2b\n\t" |
10253 "popfq\n" |
10246 "popfq\n" |
10254 "exit: nop\t# avoid branch to branch" %} |
10247 "exit: nop\t# avoid branch to branch" %} |
10255 ins_encode %{ |
10248 ins_encode %{ |
10256 Label L_exit; |
|
10257 __ ucomiss($src$$XMMRegister, $constantaddress($con)); |
10249 __ ucomiss($src$$XMMRegister, $constantaddress($con)); |
10258 __ jcc(Assembler::noParity, L_exit); |
10250 emit_cmpfp_fixup(_masm); |
10259 __ pushf(); |
|
10260 __ andq(rsp, 0xffffff2b); |
|
10261 __ popf(); |
|
10262 __ bind(L_exit); |
|
10263 __ nop(); |
|
10264 %} |
10251 %} |
10265 ins_pipe(pipe_slow); |
10252 ins_pipe(pipe_slow); |
10266 %} |
10253 %} |
10267 |
10254 |
10268 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ |
10255 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ |
10339 "pushfq\t# saw NaN, set CF\n\t" |
10326 "pushfq\t# saw NaN, set CF\n\t" |
10340 "andq [rsp], #0xffffff2b\n\t" |
10327 "andq [rsp], #0xffffff2b\n\t" |
10341 "popfq\n" |
10328 "popfq\n" |
10342 "exit: nop\t# avoid branch to branch" %} |
10329 "exit: nop\t# avoid branch to branch" %} |
10343 ins_encode %{ |
10330 ins_encode %{ |
10344 Label L_exit; |
|
10345 __ ucomisd($src$$XMMRegister, $constantaddress($con)); |
10331 __ ucomisd($src$$XMMRegister, $constantaddress($con)); |
10346 __ jcc(Assembler::noParity, L_exit); |
10332 emit_cmpfp_fixup(_masm); |
10347 __ pushf(); |
|
10348 __ andq(rsp, 0xffffff2b); |
|
10349 __ popf(); |
|
10350 __ bind(L_exit); |
|
10351 __ nop(); |
|
10352 %} |
10333 %} |
10353 ins_pipe(pipe_slow); |
10334 ins_pipe(pipe_slow); |
10354 %} |
10335 %} |
10355 |
10336 |
10356 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ |
10337 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ |