comparison src/cpu/x86/vm/x86_64.ad @ 415:4d9884b01ba6

6754519: don't emit flag fixup for NaN when condition being tested doesn't need it Reviewed-by: kvn, rasbold
author never
date Tue, 28 Oct 2008 09:31:30 -0700
parents b744678d4d71
children a1980da045cc
comparison
equal deleted inserted replaced
407:ebfd4ae89bf6 415:4d9884b01ba6
2002 2002
2003 // Is this branch offset short enough that a short branch can be used? 2003 // Is this branch offset short enough that a short branch can be used?
2004 // 2004 //
2005 // NOTE: If the platform does not provide any short branch variants, then 2005 // NOTE: If the platform does not provide any short branch variants, then
2006 // this method should return false for offset 0. 2006 // this method should return false for offset 0.
2007 bool Matcher::is_short_branch_offset(int offset) 2007 bool Matcher::is_short_branch_offset(int rule, int offset) {
2008 { 2008 // the short version of jmpConUCF2 contains multiple branches,
2009 return -0x80 <= offset && offset < 0x80; 2009 // making the reach slightly less
2010 if (rule == jmpConUCF2_rule)
2011 return (-126 <= offset && offset <= 125);
2012 return (-128 <= offset && offset <= 127);
2010 } 2013 }
2011 2014
2012 const bool Matcher::isSimpleConstant64(jlong value) { 2015 const bool Matcher::isSimpleConstant64(jlong value) {
2013 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2016 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
2014 //return value == (int) value; // Cf. storeImmL and immL32. 2017 //return value == (int) value; // Cf. storeImmL and immL32.
5132 5135
5133 format %{ "RFLAGS_U" %} 5136 format %{ "RFLAGS_U" %}
5134 interface(REG_INTER); 5137 interface(REG_INTER);
5135 %} 5138 %}
5136 5139
5140 operand rFlagsRegUCF() %{
5141 constraint(ALLOC_IN_RC(int_flags));
5142 match(RegFlags);
5143 predicate(false);
5144
5145 format %{ "RFLAGS_U_CF" %}
5146 interface(REG_INTER);
5147 %}
5148
5137 // Float register operands 5149 // Float register operands
5138 operand regF() 5150 operand regF()
5139 %{ 5151 %{
5140 constraint(ALLOC_IN_RC(float_reg)); 5152 constraint(ALLOC_IN_RC(float_reg));
5141 match(RegF); 5153 match(RegF);
5403 %{ 5415 %{
5404 match(Bool); 5416 match(Bool);
5405 5417
5406 format %{ "" %} 5418 format %{ "" %}
5407 interface(COND_INTER) %{ 5419 interface(COND_INTER) %{
5408 equal(0x4); 5420 equal(0x4, "e");
5409 not_equal(0x5); 5421 not_equal(0x5, "ne");
5410 less(0xC); 5422 less(0xC, "l");
5411 greater_equal(0xD); 5423 greater_equal(0xD, "ge");
5412 less_equal(0xE); 5424 less_equal(0xE, "le");
5413 greater(0xF); 5425 greater(0xF, "g");
5414 %} 5426 %}
5415 %} 5427 %}
5416 5428
5417 // Comparison Code, unsigned compare. Used by FP also, with 5429 // Comparison Code, unsigned compare. Used by FP also, with
5418 // C2 (unordered) turned into GT or LT already. The other bits 5430 // C2 (unordered) turned into GT or LT already. The other bits
5421 %{ 5433 %{
5422 match(Bool); 5434 match(Bool);
5423 5435
5424 format %{ "" %} 5436 format %{ "" %}
5425 interface(COND_INTER) %{ 5437 interface(COND_INTER) %{
5426 equal(0x4); 5438 equal(0x4, "e");
5427 not_equal(0x5); 5439 not_equal(0x5, "ne");
5428 less(0x2); 5440 less(0x2, "b");
5429 greater_equal(0x3); 5441 greater_equal(0x3, "nb");
5430 less_equal(0x6); 5442 less_equal(0x6, "be");
5431 greater(0x7); 5443 greater(0x7, "nbe");
5444 %}
5445 %}
5446
5447
5448 // Floating comparisons that don't require any fixup for the unordered case
5449 operand cmpOpUCF() %{
5450 match(Bool);
5451 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
5452 n->as_Bool()->_test._test == BoolTest::ge ||
5453 n->as_Bool()->_test._test == BoolTest::le ||
5454 n->as_Bool()->_test._test == BoolTest::gt);
5455 format %{ "" %}
5456 interface(COND_INTER) %{
5457 equal(0x4, "e");
5458 not_equal(0x5, "ne");
5459 less(0x2, "b");
5460 greater_equal(0x3, "nb");
5461 less_equal(0x6, "be");
5462 greater(0x7, "nbe");
5463 %}
5464 %}
5465
5466
5467 // Floating comparisons that can be fixed up with extra conditional jumps
5468 operand cmpOpUCF2() %{
5469 match(Bool);
5470 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
5471 n->as_Bool()->_test._test == BoolTest::eq);
5472 format %{ "" %}
5473 interface(COND_INTER) %{
5474 equal(0x4, "e");
5475 not_equal(0x5, "ne");
5476 less(0x2, "b");
5477 greater_equal(0x3, "nb");
5478 less_equal(0x6, "be");
5479 greater(0x7, "nbe");
5432 %} 5480 %}
5433 %} 5481 %}
5434 5482
5435 5483
5436 //----------OPERAND CLASSES---------------------------------------------------- 5484 //----------OPERAND CLASSES----------------------------------------------------
7174 opcode(0x0F, 0x40); 7222 opcode(0x0F, 0x40);
7175 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7223 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7176 ins_pipe(pipe_cmov_reg); 7224 ins_pipe(pipe_cmov_reg);
7177 %} 7225 %}
7178 7226
7179 instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop) 7227 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
7180 %{
7181 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7228 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7182 7229
7183 ins_cost(200); // XXX 7230 ins_cost(200); // XXX
7184 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7231 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7185 opcode(0x0F, 0x40); 7232 opcode(0x0F, 0x40);
7186 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7233 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7187 ins_pipe(pipe_cmov_reg); 7234 ins_pipe(pipe_cmov_reg);
7188 %} 7235 %}
7189 7236
7237 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
7238 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7239 ins_cost(200);
7240 expand %{
7241 cmovI_regU(cop, cr, dst, src);
7242 %}
7243 %}
7244
7190 // Conditional move 7245 // Conditional move
7191 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) 7246 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
7192 %{
7193 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7247 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7194 7248
7195 ins_cost(250); // XXX 7249 ins_cost(250); // XXX
7196 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7250 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7197 opcode(0x0F, 0x40); 7251 opcode(0x0F, 0x40);
7209 opcode(0x0F, 0x40); 7263 opcode(0x0F, 0x40);
7210 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7264 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
7211 ins_pipe(pipe_cmov_mem); 7265 ins_pipe(pipe_cmov_mem);
7212 %} 7266 %}
7213 7267
7268 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
7269 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7270 ins_cost(250);
7271 expand %{
7272 cmovI_memU(cop, cr, dst, src);
7273 %}
7274 %}
7275
7214 // Conditional move 7276 // Conditional move
7215 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7277 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
7216 %{ 7278 %{
7217 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7279 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7218 7280
7222 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7284 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7223 ins_pipe(pipe_cmov_reg); 7285 ins_pipe(pipe_cmov_reg);
7224 %} 7286 %}
7225 7287
7226 // Conditional move 7288 // Conditional move
7227 instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop) 7289 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
7228 %{ 7290 %{
7229 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7291 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7230 7292
7231 ins_cost(200); // XXX 7293 ins_cost(200); // XXX
7232 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7294 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
7233 opcode(0x0F, 0x40); 7295 opcode(0x0F, 0x40);
7234 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7296 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7235 ins_pipe(pipe_cmov_reg); 7297 ins_pipe(pipe_cmov_reg);
7236 %} 7298 %}
7237 7299
7300 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
7301 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7302 ins_cost(200);
7303 expand %{
7304 cmovN_regU(cop, cr, dst, src);
7305 %}
7306 %}
7307
7238 // Conditional move 7308 // Conditional move
7239 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7309 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
7240 %{ 7310 %{
7241 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7311 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7242 7312
7246 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7316 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7247 ins_pipe(pipe_cmov_reg); // XXX 7317 ins_pipe(pipe_cmov_reg); // XXX
7248 %} 7318 %}
7249 7319
7250 // Conditional move 7320 // Conditional move
7251 instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop) 7321 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
7252 %{ 7322 %{
7253 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7323 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7254 7324
7255 ins_cost(200); // XXX 7325 ins_cost(200); // XXX
7256 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7326 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
7257 opcode(0x0F, 0x40); 7327 opcode(0x0F, 0x40);
7258 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7328 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7259 ins_pipe(pipe_cmov_reg); // XXX 7329 ins_pipe(pipe_cmov_reg); // XXX
7330 %}
7331
7332 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
7333 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7334 ins_cost(200);
7335 expand %{
7336 cmovP_regU(cop, cr, dst, src);
7337 %}
7260 %} 7338 %}
7261 7339
7262 // DISABLED: Requires the ADLC to emit a bottom_type call that 7340 // DISABLED: Requires the ADLC to emit a bottom_type call that
7263 // correctly meets the two pointer arguments; one is an incoming 7341 // correctly meets the two pointer arguments; one is an incoming
7264 // register but the other is a memory operand. ALSO appears to 7342 // register but the other is a memory operand. ALSO appears to
7317 opcode(0x0F, 0x40); 7395 opcode(0x0F, 0x40);
7318 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7396 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7319 ins_pipe(pipe_cmov_reg); // XXX 7397 ins_pipe(pipe_cmov_reg); // XXX
7320 %} 7398 %}
7321 7399
7400 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
7401 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7402 ins_cost(200);
7403 expand %{
7404 cmovL_regU(cop, cr, dst, src);
7405 %}
7406 %}
7407
7322 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7408 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
7323 %{ 7409 %{
7324 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7410 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7325 7411
7326 ins_cost(200); // XXX 7412 ins_cost(200); // XXX
7327 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7413 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7328 opcode(0x0F, 0x40); 7414 opcode(0x0F, 0x40);
7329 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7415 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7330 ins_pipe(pipe_cmov_mem); // XXX 7416 ins_pipe(pipe_cmov_mem); // XXX
7417 %}
7418
7419 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7420 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7421 ins_cost(200);
7422 expand %{
7423 cmovL_memU(cop, cr, dst, src);
7424 %}
7331 %} 7425 %}
7332 7426
7333 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7427 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7334 %{ 7428 %{
7335 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7429 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7364 "skip:" %} 7458 "skip:" %}
7365 ins_encode(enc_cmovf_branch(cop, dst, src)); 7459 ins_encode(enc_cmovf_branch(cop, dst, src));
7366 ins_pipe(pipe_slow); 7460 ins_pipe(pipe_slow);
7367 %} 7461 %}
7368 7462
7463 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7464 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7465 ins_cost(200);
7466 expand %{
7467 cmovF_regU(cop, cr, dst, src);
7468 %}
7469 %}
7470
7369 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7471 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7370 %{ 7472 %{
7371 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7473 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7372 7474
7373 ins_cost(200); // XXX 7475 ins_cost(200); // XXX
7386 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7488 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7387 "movsd $dst, $src\n" 7489 "movsd $dst, $src\n"
7388 "skip:" %} 7490 "skip:" %}
7389 ins_encode(enc_cmovd_branch(cop, dst, src)); 7491 ins_encode(enc_cmovd_branch(cop, dst, src));
7390 ins_pipe(pipe_slow); 7492 ins_pipe(pipe_slow);
7493 %}
7494
7495 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7496 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7497 ins_cost(200);
7498 expand %{
7499 cmovD_regU(cop, cr, dst, src);
7500 %}
7391 %} 7501 %}
7392 7502
7393 //----------Arithmetic Instructions-------------------------------------------- 7503 //----------Arithmetic Instructions--------------------------------------------
7394 //----------Addition Instructions---------------------------------------------- 7504 //----------Addition Instructions----------------------------------------------
7395 7505
9714 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 9824 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
9715 cmpfp_fixup); 9825 cmpfp_fixup);
9716 ins_pipe(pipe_slow); 9826 ins_pipe(pipe_slow);
9717 %} 9827 %}
9718 9828
9829 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
9830 match(Set cr (CmpF src1 src2));
9831
9832 ins_cost(145);
9833 format %{ "ucomiss $src1, $src2" %}
9834 ins_encode %{
9835 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9836 %}
9837 ins_pipe(pipe_slow);
9838 %}
9839
9719 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9840 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
9720 %{ 9841 %{
9721 match(Set cr (CmpF src1 (LoadF src2))); 9842 match(Set cr (CmpF src1 (LoadF src2)));
9722 9843
9723 ins_cost(145); 9844 ins_cost(145);
9731 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 9852 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
9732 cmpfp_fixup); 9853 cmpfp_fixup);
9733 ins_pipe(pipe_slow); 9854 ins_pipe(pipe_slow);
9734 %} 9855 %}
9735 9856
9857 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
9858 match(Set cr (CmpF src1 (LoadF src2)));
9859
9860 ins_cost(100);
9861 format %{ "ucomiss $src1, $src2" %}
9862 opcode(0x0F, 0x2E);
9863 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
9864 ins_pipe(pipe_slow);
9865 %}
9866
9736 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2) 9867 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
9737 %{ 9868 %{
9738 match(Set cr (CmpF src1 src2)); 9869 match(Set cr (CmpF src1 src2));
9739 9870
9740 ins_cost(145); 9871 ins_cost(145);
9748 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 9879 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
9749 cmpfp_fixup); 9880 cmpfp_fixup);
9750 ins_pipe(pipe_slow); 9881 ins_pipe(pipe_slow);
9751 %} 9882 %}
9752 9883
9884 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
9885 match(Set cr (CmpF src1 src2));
9886
9887 ins_cost(100);
9888 format %{ "ucomiss $src1, $src2" %}
9889 opcode(0x0F, 0x2E);
9890 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
9891 ins_pipe(pipe_slow);
9892 %}
9893
9753 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9894 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
9754 %{ 9895 %{
9755 match(Set cr (CmpD src1 src2)); 9896 match(Set cr (CmpD src1 src2));
9756 9897
9757 ins_cost(145); 9898 ins_cost(145);
9765 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 9906 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
9766 cmpfp_fixup); 9907 cmpfp_fixup);
9767 ins_pipe(pipe_slow); 9908 ins_pipe(pipe_slow);
9768 %} 9909 %}
9769 9910
9911 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
9912 match(Set cr (CmpD src1 src2));
9913
9914 ins_cost(100);
9915 format %{ "ucomisd $src1, $src2 test" %}
9916 ins_encode %{
9917 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9918 %}
9919 ins_pipe(pipe_slow);
9920 %}
9921
9770 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9922 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
9771 %{ 9923 %{
9772 match(Set cr (CmpD src1 (LoadD src2))); 9924 match(Set cr (CmpD src1 (LoadD src2)));
9773 9925
9774 ins_cost(145); 9926 ins_cost(145);
9782 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 9934 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
9783 cmpfp_fixup); 9935 cmpfp_fixup);
9784 ins_pipe(pipe_slow); 9936 ins_pipe(pipe_slow);
9785 %} 9937 %}
9786 9938
9939 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
9940 match(Set cr (CmpD src1 (LoadD src2)));
9941
9942 ins_cost(100);
9943 format %{ "ucomisd $src1, $src2" %}
9944 opcode(0x66, 0x0F, 0x2E);
9945 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
9946 ins_pipe(pipe_slow);
9947 %}
9948
9787 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2) 9949 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
9788 %{ 9950 %{
9789 match(Set cr (CmpD src1 src2)); 9951 match(Set cr (CmpD src1 src2));
9790 9952
9791 ins_cost(145); 9953 ins_cost(145);
9796 "popfq\n" 9958 "popfq\n"
9797 "exit: nop\t# avoid branch to branch" %} 9959 "exit: nop\t# avoid branch to branch" %}
9798 opcode(0x66, 0x0F, 0x2E); 9960 opcode(0x66, 0x0F, 0x2E);
9799 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 9961 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
9800 cmpfp_fixup); 9962 cmpfp_fixup);
9963 ins_pipe(pipe_slow);
9964 %}
9965
9966 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
9967 match(Set cr (CmpD src1 src2));
9968
9969 ins_cost(100);
9970 format %{ "ucomisd $src1, [$src2]" %}
9971 opcode(0x66, 0x0F, 0x2E);
9972 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
9801 ins_pipe(pipe_slow); 9973 ins_pipe(pipe_slow);
9802 %} 9974 %}
9803 9975
9804 // Compare into -1,0,1 9976 // Compare into -1,0,1
9805 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9977 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
11404 ins_pipe(pipe_jcc); 11576 ins_pipe(pipe_jcc);
11405 ins_pc_relative(1); 11577 ins_pc_relative(1);
11406 %} 11578 %}
11407 11579
11408 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11580 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11409 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) 11581 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11410 %{
11411 match(CountedLoopEnd cop cmp); 11582 match(CountedLoopEnd cop cmp);
11412 effect(USE labl); 11583 effect(USE labl);
11413 11584
11414 ins_cost(300); 11585 ins_cost(300);
11415 format %{ "j$cop,u $labl\t# loop end" %} 11586 format %{ "j$cop,u $labl\t# loop end" %}
11418 ins_encode(Jcc(cop, labl)); 11589 ins_encode(Jcc(cop, labl));
11419 ins_pipe(pipe_jcc); 11590 ins_pipe(pipe_jcc);
11420 ins_pc_relative(1); 11591 ins_pc_relative(1);
11421 %} 11592 %}
11422 11593
11423 // Jump Direct Conditional - using unsigned comparison 11594 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11424 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) 11595 match(CountedLoopEnd cop cmp);
11425 %{
11426 match(If cop cmp);
11427 effect(USE labl); 11596 effect(USE labl);
11428 11597
11429 ins_cost(300); 11598 ins_cost(200);
11430 format %{ "j$cop,u $labl" %} 11599 format %{ "j$cop,u $labl\t# loop end" %}
11431 size(6); 11600 size(6);
11432 opcode(0x0F, 0x80); 11601 opcode(0x0F, 0x80);
11433 ins_encode(Jcc(cop, labl)); 11602 ins_encode(Jcc(cop, labl));
11603 ins_pipe(pipe_jcc);
11604 ins_pc_relative(1);
11605 %}
11606
11607 // Jump Direct Conditional - using unsigned comparison
11608 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11609 match(If cop cmp);
11610 effect(USE labl);
11611
11612 ins_cost(300);
11613 format %{ "j$cop,u $labl" %}
11614 size(6);
11615 opcode(0x0F, 0x80);
11616 ins_encode(Jcc(cop, labl));
11617 ins_pipe(pipe_jcc);
11618 ins_pc_relative(1);
11619 %}
11620
11621 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11622 match(If cop cmp);
11623 effect(USE labl);
11624
11625 ins_cost(200);
11626 format %{ "j$cop,u $labl" %}
11627 size(6);
11628 opcode(0x0F, 0x80);
11629 ins_encode(Jcc(cop, labl));
11630 ins_pipe(pipe_jcc);
11631 ins_pc_relative(1);
11632 %}
11633
11634 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11635 match(If cop cmp);
11636 effect(USE labl);
11637
11638 ins_cost(200);
11639 format %{ $$template
11640 if ($cop$$cmpcode == Assembler::notEqual) {
11641 $$emit$$"jp,u $labl\n\t"
11642 $$emit$$"j$cop,u $labl"
11643 } else {
11644 $$emit$$"jp,u done\n\t"
11645 $$emit$$"j$cop,u $labl\n\t"
11646 $$emit$$"done:"
11647 }
11648 %}
11649 size(12);
11650 opcode(0x0F, 0x80);
11651 ins_encode %{
11652 Label* l = $labl$$label;
11653 $$$emit8$primary;
11654 emit_cc(cbuf, $secondary, Assembler::parity);
11655 int parity_disp = -1;
11656 if ($cop$$cmpcode == Assembler::notEqual) {
11657 // the two jumps 6 bytes apart so the jump distances are too
11658 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
11659 } else if ($cop$$cmpcode == Assembler::equal) {
11660 parity_disp = 6;
11661 } else {
11662 ShouldNotReachHere();
11663 }
11664 emit_d32(cbuf, parity_disp);
11665 $$$emit8$primary;
11666 emit_cc(cbuf, $secondary, $cop$$cmpcode);
11667 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
11668 emit_d32(cbuf, disp);
11669 %}
11434 ins_pipe(pipe_jcc); 11670 ins_pipe(pipe_jcc);
11435 ins_pc_relative(1); 11671 ins_pc_relative(1);
11436 %} 11672 %}
11437 11673
11438 // ============================================================================ 11674 // ============================================================================
11503 // long variant with the shorter variant. The compiler will determine if a 11739 // long variant with the shorter variant. The compiler will determine if a
11504 // branch can be taken by the is_short_branch_offset() predicate in the machine 11740 // branch can be taken by the is_short_branch_offset() predicate in the machine
11505 // specific code section of the file. 11741 // specific code section of the file.
11506 11742
11507 // Jump Direct - Label defines a relative address from JMP+1 11743 // Jump Direct - Label defines a relative address from JMP+1
11508 instruct jmpDir_short(label labl) 11744 instruct jmpDir_short(label labl) %{
11509 %{
11510 match(Goto); 11745 match(Goto);
11511 effect(USE labl); 11746 effect(USE labl);
11512 11747
11513 ins_cost(300); 11748 ins_cost(300);
11514 format %{ "jmp,s $labl" %} 11749 format %{ "jmp,s $labl" %}
11519 ins_pc_relative(1); 11754 ins_pc_relative(1);
11520 ins_short_branch(1); 11755 ins_short_branch(1);
11521 %} 11756 %}
11522 11757
11523 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11758 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11524 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) 11759 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
11525 %{
11526 match(If cop cr); 11760 match(If cop cr);
11527 effect(USE labl); 11761 effect(USE labl);
11528 11762
11529 ins_cost(300); 11763 ins_cost(300);
11530 format %{ "j$cop,s $labl" %} 11764 format %{ "j$cop,s $labl" %}
11535 ins_pc_relative(1); 11769 ins_pc_relative(1);
11536 ins_short_branch(1); 11770 ins_short_branch(1);
11537 %} 11771 %}
11538 11772
11539 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11773 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11540 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) 11774 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
11541 %{
11542 match(CountedLoopEnd cop cr); 11775 match(CountedLoopEnd cop cr);
11543 effect(USE labl); 11776 effect(USE labl);
11544 11777
11545 ins_cost(300); 11778 ins_cost(300);
11546 format %{ "j$cop,s $labl" %} 11779 format %{ "j$cop,s $labl\t# loop end" %}
11547 size(2); 11780 size(2);
11548 opcode(0x70); 11781 opcode(0x70);
11549 ins_encode(JccShort(cop, labl)); 11782 ins_encode(JccShort(cop, labl));
11550 ins_pipe(pipe_jcc); 11783 ins_pipe(pipe_jcc);
11551 ins_pc_relative(1); 11784 ins_pc_relative(1);
11552 ins_short_branch(1); 11785 ins_short_branch(1);
11553 %} 11786 %}
11554 11787
11555 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11788 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11556 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) 11789 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11557 %{
11558 match(CountedLoopEnd cop cmp); 11790 match(CountedLoopEnd cop cmp);
11791 effect(USE labl);
11792
11793 ins_cost(300);
11794 format %{ "j$cop,us $labl\t# loop end" %}
11795 size(2);
11796 opcode(0x70);
11797 ins_encode(JccShort(cop, labl));
11798 ins_pipe(pipe_jcc);
11799 ins_pc_relative(1);
11800 ins_short_branch(1);
11801 %}
11802
11803 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11804 match(CountedLoopEnd cop cmp);
11805 effect(USE labl);
11806
11807 ins_cost(300);
11808 format %{ "j$cop,us $labl\t# loop end" %}
11809 size(2);
11810 opcode(0x70);
11811 ins_encode(JccShort(cop, labl));
11812 ins_pipe(pipe_jcc);
11813 ins_pc_relative(1);
11814 ins_short_branch(1);
11815 %}
11816
11817 // Jump Direct Conditional - using unsigned comparison
11818 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11819 match(If cop cmp);
11559 effect(USE labl); 11820 effect(USE labl);
11560 11821
11561 ins_cost(300); 11822 ins_cost(300);
11562 format %{ "j$cop,us $labl" %} 11823 format %{ "j$cop,us $labl" %}
11563 size(2); 11824 size(2);
11566 ins_pipe(pipe_jcc); 11827 ins_pipe(pipe_jcc);
11567 ins_pc_relative(1); 11828 ins_pc_relative(1);
11568 ins_short_branch(1); 11829 ins_short_branch(1);
11569 %} 11830 %}
11570 11831
11571 // Jump Direct Conditional - using unsigned comparison 11832 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11572 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
11573 %{
11574 match(If cop cmp); 11833 match(If cop cmp);
11575 effect(USE labl); 11834 effect(USE labl);
11576 11835
11577 ins_cost(300); 11836 ins_cost(300);
11578 format %{ "j$cop,us $labl" %} 11837 format %{ "j$cop,us $labl" %}
11579 size(2); 11838 size(2);
11580 opcode(0x70); 11839 opcode(0x70);
11581 ins_encode(JccShort(cop, labl)); 11840 ins_encode(JccShort(cop, labl));
11841 ins_pipe(pipe_jcc);
11842 ins_pc_relative(1);
11843 ins_short_branch(1);
11844 %}
11845
11846 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11847 match(If cop cmp);
11848 effect(USE labl);
11849
11850 ins_cost(300);
11851 format %{ $$template
11852 if ($cop$$cmpcode == Assembler::notEqual) {
11853 $$emit$$"jp,u,s $labl\n\t"
11854 $$emit$$"j$cop,u,s $labl"
11855 } else {
11856 $$emit$$"jp,u,s done\n\t"
11857 $$emit$$"j$cop,u,s $labl\n\t"
11858 $$emit$$"done:"
11859 }
11860 %}
11861 size(4);
11862 opcode(0x70);
11863 ins_encode %{
11864 Label* l = $labl$$label;
11865 emit_cc(cbuf, $primary, Assembler::parity);
11866 int parity_disp = -1;
11867 if ($cop$$cmpcode == Assembler::notEqual) {
11868 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
11869 } else if ($cop$$cmpcode == Assembler::equal) {
11870 parity_disp = 2;
11871 } else {
11872 ShouldNotReachHere();
11873 }
11874 emit_d8(cbuf, parity_disp);
11875 emit_cc(cbuf, $primary, $cop$$cmpcode);
11876 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
11877 emit_d8(cbuf, disp);
11878 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
11879 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
11880 %}
11582 ins_pipe(pipe_jcc); 11881 ins_pipe(pipe_jcc);
11583 ins_pc_relative(1); 11882 ins_pc_relative(1);
11584 ins_short_branch(1); 11883 ins_short_branch(1);
11585 %} 11884 %}
11586 11885