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; |