< prev index next >

src/cpu/x86/vm/macroAssembler_x86.cpp

Print this page




8450 
8451   BIND(L_tail_restore);
8452   movl(len, tmp); // restore
8453   BIND(L_tail);
8454   andl(len, 0xf);
8455   jccb(Assembler::zero, L_exit);
8456 
8457   // Fold the rest of bytes
8458   align(4);
8459   BIND(L_tail_loop);
8460   movsbl(rax, Address(buf, 0)); // load byte with sign extension
8461   update_byte_crc32(crc, rax, table);
8462   increment(buf);
8463   decrementl(len);
8464   jccb(Assembler::greater, L_tail_loop);
8465 
8466   BIND(L_exit);
8467   notl(crc); // ~c
8468 }
8469 
8470 #undef BIND
8471 #undef BLOCK_COMMENT
















































































































































































































































































































































































































































































































8472 
8473 
8474 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
8475   switch (cond) {
8476     // Note some conditions are synonyms for others
8477     case Assembler::zero:         return Assembler::notZero;
8478     case Assembler::notZero:      return Assembler::zero;
8479     case Assembler::less:         return Assembler::greaterEqual;
8480     case Assembler::lessEqual:    return Assembler::greater;
8481     case Assembler::greater:      return Assembler::lessEqual;
8482     case Assembler::greaterEqual: return Assembler::less;
8483     case Assembler::below:        return Assembler::aboveEqual;
8484     case Assembler::belowEqual:   return Assembler::above;
8485     case Assembler::above:        return Assembler::belowEqual;
8486     case Assembler::aboveEqual:   return Assembler::below;
8487     case Assembler::overflow:     return Assembler::noOverflow;
8488     case Assembler::noOverflow:   return Assembler::overflow;
8489     case Assembler::negative:     return Assembler::positive;
8490     case Assembler::positive:     return Assembler::negative;
8491     case Assembler::parity:       return Assembler::noParity;


8450 
8451   BIND(L_tail_restore);
8452   movl(len, tmp); // restore
8453   BIND(L_tail);
8454   andl(len, 0xf);
8455   jccb(Assembler::zero, L_exit);
8456 
8457   // Fold the rest of bytes
8458   align(4);
8459   BIND(L_tail_loop);
8460   movsbl(rax, Address(buf, 0)); // load byte with sign extension
8461   update_byte_crc32(crc, rax, table);
8462   increment(buf);
8463   decrementl(len);
8464   jccb(Assembler::greater, L_tail_loop);
8465 
8466   BIND(L_exit);
8467   notl(crc); // ~c
8468 }
8469 
8470 namespace CRC32C {
8471 #include "crc32c.h"
8472 
8473 #define Nehalem(x) x
8474 #define Westmere(x) x
8475 
8476 #undef IN
8477 #define IN(x) x
8478 #define INOUT(x) x
8479 #undef OUT
8480 #define OUT(x) x
8481 #define Scratch(x) x
8482 
8483 #undef D
8484 
8485 #ifdef _LP64
8486 // S. Gueron / Information Processing Letters 112 (2012) 184
8487 // Algorithm 4: Computing carry-less multiplication using a precomputed lookup table.
8488 // Input: A 32 bit value B = [byte3, byte2, byte1, byte0].
8489 // Output: the 64-bit carry-less product of B * CONST
8490   void IPL_Alg4(INOUT(Register B), uint32_t n,
8491   Scratch(Register C), Scratch(Register D), Scratch(Register Z),
8492   MacroAssembler * This) {
8493     This->lea(Z, ExternalAddress(StubRoutines::crc32c_table_addr()));
8494     if (n > 0) {
8495       This->addq(Z, n * 256 * 8);
8496     }
8497     //    Q1 = TABLEExt[n][B & 0xFF];
8498     This->movl(C, B);
8499     This->andl(C, 0x000000FF);
8500     This->shll(C, 3);
8501     This->addq(C, Z);
8502     This->movq(C, Address(C, 0));
8503 
8504     //    Q2 = TABLEExt[n][B >> 8 & 0xFF];
8505     This->movl(D, B);
8506     This->shrl(D, 8);
8507     This->andl(D, 0x000000FF);
8508     This->shll(D, 3);
8509     This->addq(D, Z);
8510     This->movq(D, Address(D, 0));
8511 
8512     This->shlq(D, 8);
8513     This->xorq(C, D);
8514 
8515     //    Q3 = TABLEExt[n][B >> 16 & 0xFF];
8516     This->movl(D, B);
8517     This->shrl(D, 16);
8518     This->andl(D, 0x000000FF);
8519     This->shll(D, 3);
8520     This->addq(D, Z);
8521     This->movq(D, Address(D, 0));
8522 
8523     This->shlq(D, 16);
8524     This->xorq(C, D);
8525 
8526     //    Q4 = TABLEExt[n][B >> 24 & 0xFF];
8527     This->shrl(B, 24);
8528     This->andl(B, 0x000000FF);
8529     This->shll(B, 3);
8530     This->addq(B, Z);
8531     This->movq(B, Address(B, 0));
8532  
8533     This->shlq(B, 24);
8534     This->xorq(B, C);
8535     //    return Q1 ^ Q2 << 8 ^ Q3 << 16 ^ Q4 << 24;
8536   }
8537 
8538   void PCLMULQDQ(Westmere(Scratch(XMMRegister crcXMM)),
8539     INOUT(Register crc),
8540     uint32_t CONSTOrPreCompConstIndex, bool IsPclmulqdqSupported,
8541     Westmere(Scratch(XMMRegister DXMM)),
8542     Scratch(Register A),
8543     Nehalem(Scratch(Register B)), Nehalem(Scratch(Register C)),
8544     MacroAssembler * This) {
8545     if (IsPclmulqdqSupported) {
8546       This->movdl(crcXMM, crc); // modified blindly
8547 
8548       This->movl(A, CONSTOrPreCompConstIndex);
8549       This->movdl(DXMM, A);
8550       This->pclmulqdq(crcXMM, DXMM, 0);
8551 
8552       This->movdq(crc, crcXMM);
8553     } else {
8554       IPL_Alg4(crc, CONSTOrPreCompConstIndex, A, B, C, This);
8555     }
8556   }
8557 
8558   // Recombination Alternative 2: No bit-reflections
8559   // T1 = (CRC_A * U1) << 1
8560   // T2 = (CRC_B * U2) << 1
8561   // C1 = T1 >> 32
8562   // C2 = T2 >> 32
8563   // T1 = T1 & 0xFFFFFFFF
8564   // T2 = T2 & 0xFFFFFFFF
8565   // T1 = CRC32(0, T1)
8566   // T2 = CRC32(0, T2)
8567   // C1 = C1 ^ T1
8568   // C2 = C2 ^ T2
8569   // CRC = C1 ^ C2 ^ CRC_C
8570   void RecAlt2(uint32_t CONSTOrPreCompConstIndexU1, uint32_t CONSTOrPreCompConstIndexU2, bool IsPclmulqdqSupported, INOUT(Register crcA), IN(Scratch(Register crcB)), IN(Register crcC),
8571     Westmere(Scratch(XMMRegister AXMM)), Westmere(Scratch(XMMRegister BXMM)), Westmere(Scratch(XMMRegister CXMM)),
8572     Scratch(Register E), Scratch(Register F),
8573     Nehalem(Scratch(Register G)),
8574     MacroAssembler * This) {
8575     PCLMULQDQ(AXMM, crcA, CONSTOrPreCompConstIndexU1, IsPclmulqdqSupported, CXMM, E, F, G, This);
8576     PCLMULQDQ(BXMM, crcB, CONSTOrPreCompConstIndexU2, IsPclmulqdqSupported, CXMM, E, F, G, This);
8577     This->shlq(crcA, 1);
8578     This->movl(E, crcA);
8579     This->shrq(crcA, 32);
8580     This->xorl(F, F);
8581     This->crc32(F, E, 4);
8582     This->xorl(crcA, F); // we don't care about upper 32 bit contents here
8583     This->shlq(crcB, 1);
8584     This->movl(E, crcB);
8585     This->shrq(crcB, 32);
8586     This->xorl(F, F);
8587     This->crc32(F, E, 4);
8588     This->xorl(crcB, F);
8589     This->xorl(crcA, crcB);
8590     This->xorl(crcA, crcC);
8591   }
8592 
8593   // Set N to predefined value
8594   // Subtract from a lenght of a buffer
8595   // execute in a loop:
8596   // CRC_A = 0xFFFFFFFF, CRC_B = 0, CRC_C = 0
8597   // for i = 1 to N do
8598   //  CRC_A = CRC32(CRC_A, A[i])
8599   //  CRC_B = CRC32(CRC_B, B[i])
8600   //  CRC_C = CRC32(CRC_C, C[i])
8601   // end for
8602   // Recombine
8603   void ProcChunk(uint32_t size, uint32_t CONSTOrPreCompConstIndexU1, uint32_t CONSTOrPreCompConstIndexU2, bool IsPclmulqdqSupported,
8604     INOUT(Register len), INOUT(Register buf), INOUT(Register crc),
8605     Scratch(Register E), Scratch(Register F), Scratch(Register end), 
8606     Westmere(Scratch(XMMRegister AXMM)), Westmere(Scratch(XMMRegister BXMM)), Westmere(Scratch(XMMRegister CXMM)),
8607     Scratch(Register G), Scratch(Register H), 
8608     Nehalem(Scratch(Register I)),
8609     MacroAssembler * This) {
8610     Label L_processPartitions;
8611     Label L_processPartition;
8612     Label L_exit;
8613     
8614     This->bind(L_processPartitions);
8615     This->cmpl(len, 3 * size);
8616     This->jcc(Assembler::less, L_exit);
8617       This->xorl(E, E);
8618       This->xorl(F, F);
8619       This->movq(end, buf);
8620       This->addq(end, size);
8621 
8622       This->bind(L_processPartition);
8623         This->crc32(crc, Address(buf, 0), 8);
8624         This->crc32(E, Address(buf, size), 8);
8625         This->crc32(F, Address(buf, size * 2), 8);
8626         This->addq(buf, 8);
8627         This->cmpq(buf, end);
8628         This->jcc(Assembler::less, L_processPartition);
8629       RecAlt2(CONSTOrPreCompConstIndexU1, CONSTOrPreCompConstIndexU2, IsPclmulqdqSupported, crc, E, F, 
8630       AXMM, BXMM, CXMM,
8631       G, H,
8632       I, 
8633       This);
8634       This->addq(buf, 2 * size);
8635       This->subl(len, 3 * size);
8636       This->jmp(L_processPartitions);
8637 
8638     This->bind(L_exit);
8639   }
8640 #else
8641 void IPL_Alg4(INOUT(Register B), uint32_t n,
8642   Scratch(Register C), Scratch(Register D), Scratch(Register Z),
8643   Scratch(XMMRegister CXMM), Scratch(XMMRegister DXMM),
8644   MacroAssembler * This) {
8645   This->lea(Z, ExternalAddress(StubRoutines::crc32c_table_addr()));
8646   if (n > 0) {
8647     This->addl(Z, n * 256 * 8);
8648   }
8649   //    Q1 = TABLEExt[n][B & 0xFF];
8650   This->movl(C, B);
8651   This->andl(C, 0x000000FF);
8652   This->shll(C, 3);
8653   This->addl(C, Z);
8654   This->movq(CXMM, Address(C, 0));
8655 
8656   //    Q2 = TABLEExt[n][B >> 8 & 0xFF];
8657   This->movl(D, B);
8658   This->shrl(D, 8);
8659   This->andl(D, 0x000000FF);
8660   This->shll(D, 3);
8661   This->addl(D, Z);
8662   This->movq(DXMM, Address(D, 0));
8663 
8664   This->psllq(DXMM, 8);
8665   This->pxor(CXMM, DXMM);
8666 
8667   //    Q3 = TABLEExt[n][B >> 16 & 0xFF];
8668   This->movl(D, B);
8669   This->shrl(D, 16);
8670   This->andl(D, 0x000000FF);
8671   This->shll(D, 3);
8672   This->addl(D, Z);
8673   This->movq(DXMM, Address(D, 0));
8674 
8675   This->psllq(DXMM, 16);
8676   This->pxor(CXMM, DXMM);
8677 
8678   //    Q4 = TABLEExt[n][B >> 24 & 0xFF];
8679   This->shrl(B, 24);
8680   This->andl(B, 0x000000FF);
8681   This->shll(B, 3);
8682   This->addl(B, Z);
8683   This->movq(DXMM, Address(B, 0));
8684 
8685   This->psllq(DXMM, 24);
8686   This->pxor(CXMM, DXMM); // Result in CXMM
8687   //    return Q1 ^ Q2 << 8 ^ Q3 << 16 ^ Q4 << 24;
8688 }
8689 
8690 void PCLMULQDQ(Westmere(Scratch(XMMRegister crcXMM)),
8691   INOUT(Register crc),
8692   uint32_t CONSTOrPreCompConstIndex, bool IsPclmulqdqSupported,
8693   Westmere(Scratch(XMMRegister DXMM)),
8694   Scratch(Register A),
8695   Nehalem(Scratch(Register B)), Nehalem(Scratch(Register C)),
8696   MacroAssembler * This) {
8697   if (IsPclmulqdqSupported) {
8698     This->movdl(crcXMM, crc);
8699 
8700     This->movl(A, CONSTOrPreCompConstIndex);
8701     This->movdl(DXMM, A);
8702     This->pclmulqdq(crcXMM, DXMM, 0);
8703     // Keep result in XMM since GPR is 32 bit in length
8704   } else {
8705     IPL_Alg4(crc, CONSTOrPreCompConstIndex, A, B, C, crcXMM, DXMM, This);
8706   }
8707 }
8708 
8709 void RecAlt2(uint32_t CONSTOrPreCompConstIndexU1, uint32_t CONSTOrPreCompConstIndexU2, bool IsPclmulqdqSupported, INOUT(Register crcA), IN(Scratch(Register crcB)), IN(Register crcC),
8710   Westmere(Scratch(XMMRegister AXMM)), Westmere(Scratch(XMMRegister BXMM)), Westmere(Scratch(XMMRegister CXMM)),
8711   Scratch(Register E), Scratch(Register F),
8712   Nehalem(Scratch(Register G)),
8713   MacroAssembler * This) {
8714   PCLMULQDQ(AXMM, crcA, CONSTOrPreCompConstIndexU1, IsPclmulqdqSupported, CXMM, E, F, G, This);
8715   PCLMULQDQ(BXMM, crcB, CONSTOrPreCompConstIndexU2, IsPclmulqdqSupported, CXMM, E, F, G, This);
8716   
8717   This->psllq(AXMM, 1);
8718   This->movdl(E, AXMM);
8719   This->psrlq(AXMM, 32);
8720   This->movdl(crcA, AXMM);
8721 
8722   This->xorl(F, F);
8723   This->crc32(F, E, 4);
8724   This->xorl(crcA, F);
8725   
8726   This->psllq(BXMM, 1);
8727   This->movdl(E, BXMM);
8728   This->psrlq(BXMM, 32);
8729   This->movdl(crcB, BXMM);
8730 
8731   This->xorl(F, F);
8732   This->crc32(F, E, 4);
8733   This->xorl(crcB, F);
8734   This->xorl(crcA, crcB);
8735   This->xorl(crcA, crcC);
8736 }
8737 
8738 void ProcChunk(uint32_t size, uint32_t CONSTOrPreCompConstIndexU1, uint32_t CONSTOrPreCompConstIndexU2, bool IsPclmulqdqSupported,
8739   INOUT(Register len), INOUT(Register buf), INOUT(Register crc),
8740   Scratch(Register E), Scratch(Register F), Scratch(Register end),
8741   Westmere(Scratch(XMMRegister AXMM)), Westmere(Scratch(XMMRegister BXMM)), Westmere(Scratch(XMMRegister CXMM)),
8742   Scratch(Register G), Scratch(Register H),
8743   Nehalem(Scratch(Register I)),
8744   MacroAssembler * This) {
8745   Label L_processPartitions;
8746   Label L_processPartition;
8747   Label L_exit;
8748 
8749   This->bind(L_processPartitions);
8750   This->cmpl(len, 3 * size);
8751   This->jcc(Assembler::less, L_exit);
8752     This->xorl(E, E);
8753     This->xorl(F, F);
8754     This->movl(end, buf);
8755     This->addl(end, size);
8756 
8757     This->bind(L_processPartition);
8758       This->crc32(crc, Address(buf, 0), 4);
8759       This->crc32(E, Address(buf, size), 4);
8760       This->crc32(F, Address(buf, size*2), 4);
8761       This->crc32(crc, Address(buf, 0+4), 4);
8762       This->crc32(E, Address(buf, size+4), 4);
8763       This->crc32(F, Address(buf, size*2+4), 4);
8764       This->addl(buf, 8);
8765       This->cmpl(buf, end);
8766       This->jcc(Assembler::less, L_processPartition);
8767 
8768         This->push(end);
8769         This->push(len);
8770         This->push(buf);
8771         G = end;
8772         H = len;
8773         I = buf;
8774 
8775     RecAlt2(CONSTOrPreCompConstIndexU1, CONSTOrPreCompConstIndexU2, IsPclmulqdqSupported, crc, E, F,
8776       AXMM, BXMM, CXMM,
8777       G, H,
8778       I,
8779       This);
8780 
8781         This->pop(buf);
8782         This->pop(len);
8783         This->pop(end);
8784 
8785     This->addl(buf, 2 * size);
8786     This->subl(len, 3 * size);
8787     This->jmp(L_processPartitions);
8788 
8789   This->bind(L_exit);
8790 }
8791 #endif //LP64
8792 }
8793 #undef D
8794 
8795 #ifdef _LP64
8796 // Algorithm 2: Pipelined usage of the CRC32 instruction.
8797 // Input: A buffer I of L bytes.
8798 // Output: the CRC32C value of the buffer.
8799 // Notations:
8800 // Write L = 24N + r, with N = floor (L/24).
8801 // r = L mod 24 (0 <= r < 24).
8802 // Consider I as the concatenation of A|B|C|R, where A, B, C, each,
8803 // N quadwords, and R consists of r bytes.
8804 // A[j] = I [8j+7:8j], j= 0, 1, ..., N-1
8805 // B[j] = I [N + 8j+7:N + 8j], j= 0, 1, ..., N-1
8806 // C[j] = I [2N + 8j+7:2N + 8j], j= 0, 1, ..., N-1
8807 // if r > 0 R[j] = I [3N +j], j= 0, 1, ...,r-1
8808 void MacroAssembler::crc32c_IPL_Alg2Alt2Fast(Register crc, Register buf, Register len,
8809   Scratch(Register A), Scratch(Register  B), Scratch(Register C),
8810   Scratch(Register D), Scratch(Register  E), Scratch(Register F),
8811   Westmere(Scratch(XMMRegister AXMM)), Westmere(Scratch(XMMRegister BXMM)), Westmere(Scratch(XMMRegister CXMM)),
8812   bool IsPclmulqdqSupported) {
8813   uint32_t CONSTOrPreCompConstIndex[CRC32C::NUM_PRECOMPUTED_CONSTANTS];
8814   Label L_wordByWord;
8815   Label L_byteByByteProlog;
8816   Label L_byteByByte;
8817   Label L_exit;
8818 
8819   if (IsPclmulqdqSupported ) {
8820     CONSTOrPreCompConstIndex[1] = *(uint32_t *)StubRoutines::_crc32c_table_addr;
8821     CONSTOrPreCompConstIndex[0] = *((uint32_t *)StubRoutines::_crc32c_table_addr+1);
8822 
8823     CONSTOrPreCompConstIndex[3] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 2);
8824     CONSTOrPreCompConstIndex[2] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 3);
8825 
8826     CONSTOrPreCompConstIndex[5] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 4);
8827     CONSTOrPreCompConstIndex[4] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 5);
8828     assert((CRC32C::NUM_PRECOMPUTED_CONSTANTS - 1 ) == 5, "Checking whether you declared all of the constants based on the number of \"chunks\"");
8829   } else {
8830     CONSTOrPreCompConstIndex[0] = 1;
8831     CONSTOrPreCompConstIndex[1] = 0;
8832 
8833     CONSTOrPreCompConstIndex[2] = 3;
8834     CONSTOrPreCompConstIndex[3] = 2;
8835 
8836     CONSTOrPreCompConstIndex[4] = 5;
8837     CONSTOrPreCompConstIndex[5] = 4;
8838    }
8839   CRC32C::ProcChunk(CRC32C::HIGH, CONSTOrPreCompConstIndex[0], CONSTOrPreCompConstIndex[1], IsPclmulqdqSupported,
8840     len, buf, crc, 
8841     A, B, C,
8842     AXMM, BXMM, CXMM,
8843     D, E, 
8844     F, 
8845     this);
8846   CRC32C::ProcChunk(CRC32C::MIDDLE, CONSTOrPreCompConstIndex[2], CONSTOrPreCompConstIndex[3], IsPclmulqdqSupported,
8847     len, buf, crc,
8848     A, B, C,
8849     AXMM, BXMM, CXMM,
8850     D, E, 
8851     F,
8852     this);
8853   CRC32C::ProcChunk(CRC32C::LOW, CONSTOrPreCompConstIndex[4], CONSTOrPreCompConstIndex[5], IsPclmulqdqSupported,
8854     len, buf, crc,
8855     A, B, C,
8856     AXMM, BXMM, CXMM,
8857     D, E, 
8858     F, 
8859     this);
8860   movl(A, len);
8861   andl(A, 0x00000007);
8862   negl(A);
8863   addl(A, len);
8864   addq(A, buf);
8865 
8866   BIND(L_wordByWord);
8867   cmpq(buf, A);
8868   jcc(Assembler::greaterEqual, L_byteByByteProlog);
8869     crc32(crc, Address(buf, 0), 4);
8870     addq(buf, 4);
8871     jmp(L_wordByWord);
8872   
8873   BIND(L_byteByByteProlog);
8874   andl(len, 0x00000007);
8875   movl(B, 1);
8876 
8877   BIND(L_byteByByte);
8878   cmpl(B, len);
8879   jccb(Assembler::greater, L_exit);
8880     crc32(crc, Address(buf, 0), 1);
8881     incq(buf);
8882     incl(B);
8883     jmp(L_byteByByte);
8884 
8885   BIND(L_exit);
8886 }
8887 #else
8888 void MacroAssembler::crc32c_IPL_Alg2Alt2Fast(Register crc, Register buf, Register len,
8889   Scratch(Register A), Scratch(Register  B), Scratch(Register C),
8890   Scratch(Register D), Scratch(Register  E), Scratch(Register F),
8891   Westmere(Scratch(XMMRegister AXMM)), Westmere(Scratch(XMMRegister BXMM)), Westmere(Scratch(XMMRegister CXMM)),
8892   bool IsPclmulqdqSupported) {
8893   uint32_t CONSTOrPreCompConstIndex[CRC32C::NUM_PRECOMPUTED_CONSTANTS];
8894   Label L_wordByWord;
8895   Label L_byteByByteProlog;
8896   Label L_byteByByte;
8897   Label L_exit;
8898 
8899   if (IsPclmulqdqSupported) {
8900     CONSTOrPreCompConstIndex[1] = *(uint32_t *)StubRoutines::_crc32c_table_addr;
8901     CONSTOrPreCompConstIndex[0] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 1);
8902 
8903     CONSTOrPreCompConstIndex[3] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 2);
8904     CONSTOrPreCompConstIndex[2] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 3);
8905 
8906     CONSTOrPreCompConstIndex[5] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 4);
8907     CONSTOrPreCompConstIndex[4] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 5);
8908   } else {
8909     CONSTOrPreCompConstIndex[0] = 1;
8910     CONSTOrPreCompConstIndex[1] = 0;
8911 
8912     CONSTOrPreCompConstIndex[2] = 3;
8913     CONSTOrPreCompConstIndex[3] = 2;
8914 
8915     CONSTOrPreCompConstIndex[4] = 5;
8916     CONSTOrPreCompConstIndex[5] = 4;
8917   }
8918   CRC32C::ProcChunk(CRC32C::HIGH, CONSTOrPreCompConstIndex[0], CONSTOrPreCompConstIndex[1], IsPclmulqdqSupported,
8919     len, buf, crc,
8920     A, B, C,
8921     AXMM, BXMM, CXMM,
8922     D, E,
8923     F,
8924     this);
8925   CRC32C::ProcChunk(CRC32C::MIDDLE, CONSTOrPreCompConstIndex[2], CONSTOrPreCompConstIndex[3], IsPclmulqdqSupported,
8926     len, buf, crc,
8927     A, B, C,
8928     AXMM, BXMM, CXMM,
8929     D, E,
8930     F,
8931     this);
8932   CRC32C::ProcChunk(CRC32C::LOW, CONSTOrPreCompConstIndex[4], CONSTOrPreCompConstIndex[5], IsPclmulqdqSupported,
8933     len, buf, crc,
8934     A, B, C,
8935     AXMM, BXMM, CXMM,
8936     D, E,
8937     F,
8938     this);
8939   movl(A, len);
8940   andl(A, 0x00000007);
8941   negl(A);
8942   addl(A, len);
8943   addl(A, buf);
8944 
8945   BIND(L_wordByWord);
8946   cmpl(buf, A);
8947   jcc(Assembler::greaterEqual, L_byteByByteProlog);
8948     crc32(crc, Address(buf,0), 4);
8949     addl(buf, 4);
8950     jmp(L_wordByWord);
8951 
8952   BIND(L_byteByByteProlog);
8953   andl(len, 0x00000007);
8954   movl(B, 1);
8955 
8956   BIND(L_byteByByte);
8957   cmpl(B, len);
8958   jccb(Assembler::greater, L_exit);
8959     movb(A, Address(buf, 0));
8960     crc32(crc, A, 1);
8961     incl(buf);
8962     incl(B);
8963     jmp(L_byteByByte);
8964 
8965   BIND(L_exit);
8966 }
8967 #endif // LP64
8968 
8969 
8970 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
8971   switch (cond) {
8972     // Note some conditions are synonyms for others
8973     case Assembler::zero:         return Assembler::notZero;
8974     case Assembler::notZero:      return Assembler::zero;
8975     case Assembler::less:         return Assembler::greaterEqual;
8976     case Assembler::lessEqual:    return Assembler::greater;
8977     case Assembler::greater:      return Assembler::lessEqual;
8978     case Assembler::greaterEqual: return Assembler::less;
8979     case Assembler::below:        return Assembler::aboveEqual;
8980     case Assembler::belowEqual:   return Assembler::above;
8981     case Assembler::above:        return Assembler::belowEqual;
8982     case Assembler::aboveEqual:   return Assembler::below;
8983     case Assembler::overflow:     return Assembler::noOverflow;
8984     case Assembler::noOverflow:   return Assembler::overflow;
8985     case Assembler::negative:     return Assembler::positive;
8986     case Assembler::positive:     return Assembler::negative;
8987     case Assembler::parity:       return Assembler::noParity;
< prev index next >