comparison src/cpu/x86/vm/x86_32.ad @ 1209:e8443c7be117

6921969: optimize 64 long multiply for case with high bits zero Reviewed-by: never, twisti, kvn, rasbold Contributed-by: Hiroshi Yamauchi <yamauchi@google.com>
author never
date Wed, 03 Feb 2010 15:56:37 -0800
parents 97125851f396
children 2883969d09e7
comparison
equal deleted inserted replaced
1207:74c848d437ab 1209:e8443c7be117
233 233
234 234
235 //----------SOURCE BLOCK------------------------------------------------------- 235 //----------SOURCE BLOCK-------------------------------------------------------
236 // This is a block of C++ code which provides values, functions, and 236 // This is a block of C++ code which provides values, functions, and
237 // definitions necessary in the rest of the architecture description 237 // definitions necessary in the rest of the architecture description
238 source_hpp %{
239 // Must be visible to the DFA in dfa_x86_32.cpp
240 extern bool is_operand_hi32_zero(Node* n);
241 %}
242
238 source %{ 243 source %{
239 #define RELOC_IMM32 Assembler::imm_operand 244 #define RELOC_IMM32 Assembler::imm_operand
240 #define RELOC_DISP32 Assembler::disp32_operand 245 #define RELOC_DISP32 Assembler::disp32_operand
241 246
242 #define __ _masm. 247 #define __ _masm.
1481 return RegMask(); 1486 return RegMask();
1482 } 1487 }
1483 1488
1484 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1489 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1485 return EBP_REG_mask; 1490 return EBP_REG_mask;
1491 }
1492
1493 // Returns true if the high 32 bits of the value is known to be zero.
1494 bool is_operand_hi32_zero(Node* n) {
1495 int opc = n->Opcode();
1496 if (opc == Op_LoadUI2L) {
1497 return true;
1498 }
1499 if (opc == Op_AndL) {
1500 Node* o2 = n->in(2);
1501 if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) {
1502 return true;
1503 }
1504 }
1505 return false;
1486 } 1506 }
1487 1507
1488 %} 1508 %}
1489 1509
1490 //----------ENCODING BLOCK----------------------------------------------------- 1510 //----------ENCODING BLOCK-----------------------------------------------------
8594 "IMUL EDX,EAX\n\t" 8614 "IMUL EDX,EAX\n\t"
8595 "ADD $tmp,EDX\n\t" 8615 "ADD $tmp,EDX\n\t"
8596 "MUL EDX:EAX,$src.lo\n\t" 8616 "MUL EDX:EAX,$src.lo\n\t"
8597 "ADD EDX,$tmp" %} 8617 "ADD EDX,$tmp" %}
8598 ins_encode( long_multiply( dst, src, tmp ) ); 8618 ins_encode( long_multiply( dst, src, tmp ) );
8619 ins_pipe( pipe_slow );
8620 %}
8621
8622 // Multiply Register Long where the left operand's high 32 bits are zero
8623 instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8624 predicate(is_operand_hi32_zero(n->in(1)));
8625 match(Set dst (MulL dst src));
8626 effect(KILL cr, TEMP tmp);
8627 ins_cost(2*100+2*400);
8628 // Basic idea: lo(result) = lo(x_lo * y_lo)
8629 // hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0
8630 format %{ "MOV $tmp,$src.hi\n\t"
8631 "IMUL $tmp,EAX\n\t"
8632 "MUL EDX:EAX,$src.lo\n\t"
8633 "ADD EDX,$tmp" %}
8634 ins_encode %{
8635 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
8636 __ imull($tmp$$Register, rax);
8637 __ mull($src$$Register);
8638 __ addl(rdx, $tmp$$Register);
8639 %}
8640 ins_pipe( pipe_slow );
8641 %}
8642
8643 // Multiply Register Long where the right operand's high 32 bits are zero
8644 instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8645 predicate(is_operand_hi32_zero(n->in(2)));
8646 match(Set dst (MulL dst src));
8647 effect(KILL cr, TEMP tmp);
8648 ins_cost(2*100+2*400);
8649 // Basic idea: lo(result) = lo(x_lo * y_lo)
8650 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0
8651 format %{ "MOV $tmp,$src.lo\n\t"
8652 "IMUL $tmp,EDX\n\t"
8653 "MUL EDX:EAX,$src.lo\n\t"
8654 "ADD EDX,$tmp" %}
8655 ins_encode %{
8656 __ movl($tmp$$Register, $src$$Register);
8657 __ imull($tmp$$Register, rdx);
8658 __ mull($src$$Register);
8659 __ addl(rdx, $tmp$$Register);
8660 %}
8661 ins_pipe( pipe_slow );
8662 %}
8663
8664 // Multiply Register Long where the left and the right operands' high 32 bits are zero
8665 instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{
8666 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2)));
8667 match(Set dst (MulL dst src));
8668 effect(KILL cr);
8669 ins_cost(1*400);
8670 // Basic idea: lo(result) = lo(x_lo * y_lo)
8671 // hi(result) = hi(x_lo * y_lo) where lo(x_hi * y_lo) = 0 and lo(x_lo * y_hi) = 0 because x_hi = 0 and y_hi = 0
8672 format %{ "MUL EDX:EAX,$src.lo\n\t" %}
8673 ins_encode %{
8674 __ mull($src$$Register);
8675 %}
8599 ins_pipe( pipe_slow ); 8676 ins_pipe( pipe_slow );
8600 %} 8677 %}
8601 8678
8602 // Multiply Register Long by small constant 8679 // Multiply Register Long by small constant
8603 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{ 8680 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{