Mercurial > hg > truffle
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 |