Mercurial > hg > graal-compiler
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) %{ |