//MACRO Hash.buffer Anchor, Buffer, Length, HashAddr, WReg[3] //-------------------------------------------------------------------------------------------------- // // @ CopyRight Roberti & Parau Enterprises, Inc. 2021-2023 // // This work is licensed under the Creative Commons Attribution-NoDerivatives 4.0 International License. // To view a copy of this license, visit http://creativecommons.org/licenses/by-nd/4.0/ // or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. // //-------------------------------------------------------------------------------------------------- // // // Get load/store MIs and word length // eval(DVASM.getEnv()[4]); var ld= "L" + abiWID; var st= "S" + abiWID; var wl= abiWLen; var wn= abiWID == "D" ? "double word" : "word"; var WReg0= WReg[0]; var WReg1= WReg[1]; var WReg2= WReg[2]; // // Generate code // \#Label MV #HashAddr, 0 // Set hash starting value to zero \ #ld #WReg0, #wl+#Anchor // Load prime \ ADD #Length, #Buffer // Compute end of buffer addr \ ADDI #Length, -#wl // Subtract #wn to it \ WHILE Condition= ( #Buffer <= #Length ) // Start loop to hash all #wn.s \ #ld #WReg1, 0[#Buffer] // Load next #wn for to be hashed \ ADD #HashAddr, #WReg1 // Add new word to hash \ MUL #HashAddr, #WReg0 // Multiply \ ADDI #Buffer, #wl // Load next #wn address \ ENDWHILE \ ADDI #Length, #wl // Restore end of buffer addr \ SUB #Length, #Buffer // Compute residual length \ \ IF ( #Length > 0 ), THEN // Handle residual bytes if any if (abiWID == "D") { \ ANDI #WReg1, 0b100[#Length] // Extract length == 4 bit; \ IF ( #WReg1 != 0 ), THEN // ... to check if length >= 4; \ LWU #WReg1, 0[#Buffer] // Load four bytes \ SLLI #WReg1, 32 // Shift into position \ ADD #HashAddr, #WReg1 // Add them to the existing hash; \ ADDI #Buffer, 4 // Add 4 to buffer address \ ENDIF } \ ANDI #WReg1, 0b10[#Length] // Extract length == 2 bit \ IF ( #WReg1 != 0 ), THEN // ... to check if we need to load two byte \ LHU #WReg1, 0[#Buffer] // Load two bytes \ SLLI #WReg1, 16 // Shift into position \ ADD #HashAddr, #WReg1 // Add them to the existing hash \ ADDI #Buffer, 2 // Add 2 to buffer address \ ENDIF \ ANDI #WReg1, 0b1[#Length] // Extract length == 1 bit \ IF ( #WReg1 != 0 ), THEN // ... to check if we need to load last byte \ LBU #WReg1, 0[#Buffer] // Load last byte \ ADD #HashAddr, #WReg1 // Add it to the existing hash \ ENDIF \ ENDIF // // Do the final hash on the resulted value in register HashAddr // \ \ LWU #WReg1, 2*#wl+#Anchor // Load hash shift \ SRL #WReg2, #HashAddr, #WReg1 // Shift Key right \ XOR #HashAddr, #WReg2 // XOR shifted key with original key \ MUL #HashAddr, #WReg0 // Multiply shifted and XORed key by prime number \ SRL #HashAddr, #WReg1 // Shift key right \ LWU #WReg1, 2*#wl+2+#Anchor // Load cell shift \ SLL #HashAddr, #WReg1 // Shift key left - offset in hash vector \ #ld #WReg1, #Anchor // Load hash vector addr \ ADD #HashAddr, #WReg1 // Add vector address - hash cell addr