src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6921969 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/x86_32.ad

Print this page




 218 reg_class dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
 219                    FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
 220                    FPR7L,FPR7H );
 221 
 222 reg_class flt_reg0( FPR1L );
 223 reg_class dbl_reg0( FPR1L,FPR1H );
 224 reg_class dbl_reg1( FPR2L,FPR2H );
 225 reg_class dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
 226                        FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
 227 
 228 // XMM6 and XMM7 could be used as temporary registers for long, float and
 229 // double values for SSE2.
 230 reg_class xdb_reg6( XMM6a,XMM6b );
 231 reg_class xdb_reg7( XMM7a,XMM7b );
 232 %}
 233 
 234 
 235 //----------SOURCE BLOCK-------------------------------------------------------
 236 // This is a block of C++ code which provides values, functions, and
 237 // definitions necessary in the rest of the architecture description





 238 source %{
 239 #define   RELOC_IMM32    Assembler::imm_operand
 240 #define   RELOC_DISP32   Assembler::disp32_operand
 241 
 242 #define __ _masm.
 243 
 244 // How to find the high register of a Long pair, given the low register
 245 #define   HIGH_FROM_LOW(x) ((x)+2)
 246 
 247 // These masks are used to provide 128-bit aligned bitmasks to the XMM
 248 // instructions, to allow sign-masking or sign-bit flipping.  They allow
 249 // fast versions of NegF/NegD and AbsF/AbsD.
 250 
 251 // Note: 'double' and 'long long' have 32-bits alignment on x86.
 252 static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {
 253   // Use the expression (adr)&(~0xF) to provide 128-bits aligned address
 254   // of 128-bits operands for SSE instructions.
 255   jlong *operand = (jlong*)(((uintptr_t)adr)&((uintptr_t)(~0xF)));
 256   // Store the value to a 128-bits operand.
 257   operand[0] = lo;


1468 RegMask Matcher::modI_proj_mask() {
1469   return EDX_REG_mask;
1470 }
1471 
1472 // Register for DIVL projection of divmodL
1473 RegMask Matcher::divL_proj_mask() {
1474   ShouldNotReachHere();
1475   return RegMask();
1476 }
1477 
1478 // Register for MODL projection of divmodL
1479 RegMask Matcher::modL_proj_mask() {
1480   ShouldNotReachHere();
1481   return RegMask();
1482 }
1483 
1484 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1485   return EBP_REG_mask;
1486 }
1487 















1488 %}
1489 
1490 //----------ENCODING BLOCK-----------------------------------------------------
1491 // This block specifies the encoding classes used by the compiler to output
1492 // byte streams.  Encoding classes generate functions which are called by
1493 // Machine Instruction Nodes in order to generate the bit encoding of the
1494 // instruction.  Operands specify their base encoding interface with the
1495 // interface keyword.  There are currently supported four interfaces,
1496 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
1497 // operand to generate a function which returns its register number when
1498 // queried.   CONST_INTER causes an operand to generate a function which
1499 // returns the value of the constant when queried.  MEMORY_INTER causes an
1500 // operand to generate four functions which return the Base Register, the
1501 // Index Register, the Scale Value, and the Offset Value of the operand when
1502 // queried.  COND_INTER causes an operand to generate six functions which
1503 // return the encoding code (ie - encoding bits for the instruction)
1504 // associated with each basic boolean condition for a conditional instruction.
1505 // Instructions specify two basic values for encoding.  They use the
1506 // ins_encode keyword to specify their encoding class (which must be one of
1507 // the class names specified in the encoding block), and they use the


8581   ins_pipe( ialu_reg_reg_alu0 );
8582 %}
8583 
8584 // Multiply Register Long
8585 instruct mulL_eReg(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8586   match(Set dst (MulL dst src));
8587   effect(KILL cr, TEMP tmp);
8588   ins_cost(4*100+3*400);
8589 // Basic idea: lo(result) = lo(x_lo * y_lo)
8590 //             hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
8591   format %{ "MOV    $tmp,$src.lo\n\t"
8592             "IMUL   $tmp,EDX\n\t"
8593             "MOV    EDX,$src.hi\n\t"
8594             "IMUL   EDX,EAX\n\t"
8595             "ADD    $tmp,EDX\n\t"
8596             "MUL    EDX:EAX,$src.lo\n\t"
8597             "ADD    EDX,$tmp" %}
8598   ins_encode( long_multiply( dst, src, tmp ) );
8599   ins_pipe( pipe_slow );
8600 %}

























































8601 
8602 // Multiply Register Long by small constant
8603 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{
8604   match(Set dst (MulL dst src));
8605   effect(KILL cr, TEMP tmp);
8606   ins_cost(2*100+2*400);
8607   size(12);
8608 // Basic idea: lo(result) = lo(src * EAX)
8609 //             hi(result) = hi(src * EAX) + lo(src * EDX)
8610   format %{ "IMUL   $tmp,EDX,$src\n\t"
8611             "MOV    EDX,$src\n\t"
8612             "MUL    EDX\t# EDX*EAX -> EDX:EAX\n\t"
8613             "ADD    EDX,$tmp" %}
8614   ins_encode( long_multiply_con( dst, src, tmp ) );
8615   ins_pipe( pipe_slow );
8616 %}
8617 
8618 // Integer DIV with Register
8619 instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
8620   match(Set rax (DivI rax div));




 218 reg_class dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
 219                    FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
 220                    FPR7L,FPR7H );
 221 
 222 reg_class flt_reg0( FPR1L );
 223 reg_class dbl_reg0( FPR1L,FPR1H );
 224 reg_class dbl_reg1( FPR2L,FPR2H );
 225 reg_class dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
 226                        FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
 227 
 228 // XMM6 and XMM7 could be used as temporary registers for long, float and
 229 // double values for SSE2.
 230 reg_class xdb_reg6( XMM6a,XMM6b );
 231 reg_class xdb_reg7( XMM7a,XMM7b );
 232 %}
 233 
 234 
 235 //----------SOURCE BLOCK-------------------------------------------------------
 236 // This is a block of C++ code which provides values, functions, and
 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 
 243 source %{
 244 #define   RELOC_IMM32    Assembler::imm_operand
 245 #define   RELOC_DISP32   Assembler::disp32_operand
 246 
 247 #define __ _masm.
 248 
 249 // How to find the high register of a Long pair, given the low register
 250 #define   HIGH_FROM_LOW(x) ((x)+2)
 251 
 252 // These masks are used to provide 128-bit aligned bitmasks to the XMM
 253 // instructions, to allow sign-masking or sign-bit flipping.  They allow
 254 // fast versions of NegF/NegD and AbsF/AbsD.
 255 
 256 // Note: 'double' and 'long long' have 32-bits alignment on x86.
 257 static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {
 258   // Use the expression (adr)&(~0xF) to provide 128-bits aligned address
 259   // of 128-bits operands for SSE instructions.
 260   jlong *operand = (jlong*)(((uintptr_t)adr)&((uintptr_t)(~0xF)));
 261   // Store the value to a 128-bits operand.
 262   operand[0] = lo;


1473 RegMask Matcher::modI_proj_mask() {
1474   return EDX_REG_mask;
1475 }
1476 
1477 // Register for DIVL projection of divmodL
1478 RegMask Matcher::divL_proj_mask() {
1479   ShouldNotReachHere();
1480   return RegMask();
1481 }
1482 
1483 // Register for MODL projection of divmodL
1484 RegMask Matcher::modL_proj_mask() {
1485   ShouldNotReachHere();
1486   return RegMask();
1487 }
1488 
1489 const RegMask Matcher::method_handle_invoke_SP_save_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;
1506 }
1507 
1508 %}
1509 
1510 //----------ENCODING BLOCK-----------------------------------------------------
1511 // This block specifies the encoding classes used by the compiler to output
1512 // byte streams.  Encoding classes generate functions which are called by
1513 // Machine Instruction Nodes in order to generate the bit encoding of the
1514 // instruction.  Operands specify their base encoding interface with the
1515 // interface keyword.  There are currently supported four interfaces,
1516 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
1517 // operand to generate a function which returns its register number when
1518 // queried.   CONST_INTER causes an operand to generate a function which
1519 // returns the value of the constant when queried.  MEMORY_INTER causes an
1520 // operand to generate four functions which return the Base Register, the
1521 // Index Register, the Scale Value, and the Offset Value of the operand when
1522 // queried.  COND_INTER causes an operand to generate six functions which
1523 // return the encoding code (ie - encoding bits for the instruction)
1524 // associated with each basic boolean condition for a conditional instruction.
1525 // Instructions specify two basic values for encoding.  They use the
1526 // ins_encode keyword to specify their encoding class (which must be one of
1527 // the class names specified in the encoding block), and they use the


8601   ins_pipe( ialu_reg_reg_alu0 );
8602 %}
8603 
8604 // Multiply Register Long
8605 instruct mulL_eReg(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8606   match(Set dst (MulL dst src));
8607   effect(KILL cr, TEMP tmp);
8608   ins_cost(4*100+3*400);
8609 // Basic idea: lo(result) = lo(x_lo * y_lo)
8610 //             hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
8611   format %{ "MOV    $tmp,$src.lo\n\t"
8612             "IMUL   $tmp,EDX\n\t"
8613             "MOV    EDX,$src.hi\n\t"
8614             "IMUL   EDX,EAX\n\t"
8615             "ADD    $tmp,EDX\n\t"
8616             "MUL    EDX:EAX,$src.lo\n\t"
8617             "ADD    EDX,$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   %}
8676   ins_pipe( pipe_slow );
8677 %}
8678 
8679 // Multiply Register Long by small constant
8680 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{
8681   match(Set dst (MulL dst src));
8682   effect(KILL cr, TEMP tmp);
8683   ins_cost(2*100+2*400);
8684   size(12);
8685 // Basic idea: lo(result) = lo(src * EAX)
8686 //             hi(result) = hi(src * EAX) + lo(src * EDX)
8687   format %{ "IMUL   $tmp,EDX,$src\n\t"
8688             "MOV    EDX,$src\n\t"
8689             "MUL    EDX\t# EDX*EAX -> EDX:EAX\n\t"
8690             "ADD    EDX,$tmp" %}
8691   ins_encode( long_multiply_con( dst, src, tmp ) );
8692   ins_pipe( pipe_slow );
8693 %}
8694 
8695 // Integer DIV with Register
8696 instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
8697   match(Set rax (DivI rax div));


src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File