1515 */
1616module std.internal.digest.sha_SSSE3 ;
1717
18- version (D_PIC )
18+ version (D_InlineAsm_X86 )
1919{
20- // Do not use (Bug9378).
21- }
22- else version ( D_InlineAsm_X86 )
23- {
24- private version = USE_SSSE3 ;
25- private version = _32Bit;
20+ version ( D_PIC ) {} // Bugzilla 9378
21+ else
22+ {
23+ private version = USE_SSSE3 ;
24+ private version = _32Bit ;
25+ }
2626}
2727else version (D_InlineAsm_X86_64 )
2828{
@@ -108,6 +108,7 @@ version(USE_SSSE3)
108108 private immutable string SP = " RSP" ;
109109 private immutable string BUFFER_PTR = " R9" ;
110110 private immutable string STATE_PTR = " R8" ;
111+ private immutable string CONSTANTS_PTR = " R10" ;
111112
112113 // Registers for temporary results (XMM10 and XMM11 are also used temporary)
113114 private immutable string W_TMP = " XMM8" ;
@@ -120,15 +121,11 @@ version(USE_SSSE3)
120121 private immutable string X_CONSTANT = " XMM13" ;
121122 }
122123
123- /* The control words for the byte shuffle instruction. */
124- align (16 ) private immutable uint [4 ] bswap_shufb_ctl =
125- [
126- 0x0001_0203, 0x0405_0607, 0x0809_0a0b, 0x0c0d_0e0f
127- ];
128-
129- /* The round constants. */
130- align (16 ) private immutable uint [16 ] constants =
124+ /* The control words for the byte shuffle instruction and the round constants. */
125+ align (16 ) public immutable uint [20 ] constants =
131126 [
127+ // The control words for the byte shuffle instruction.
128+ 0x0001_0203, 0x0405_0607, 0x0809_0a0b, 0x0c0d_0e0f,
132129 // Constants for round 0-19
133130 0x5a827999 , 0x5a827999 , 0x5a827999 , 0x5a827999 ,
134131 // Constants for round 20-39
@@ -152,10 +149,22 @@ version(USE_SSSE3)
152149 return s.idup;
153150 }
154151
152+ /* * Returns the reference to the byte shuffle control word. */
153+ private nothrow pure string bswap_shufb_ctl()
154+ {
155+ version (_64Bit)
156+ return " [" ~ CONSTANTS_PTR ~ " ]" ;
157+ else
158+ return " [constants]" ;
159+ }
160+
155161 /* * Returns the reference to constant used in round i. */
156162 private nothrow pure string constant(uint i)
157163 {
158- return " [constants + 16*" ~ to_string(i/ 20 )~ " ]" ;
164+ version (_64Bit)
165+ return " 16 + 16*" ~ to_string(i/ 20 )~ " [" ~ CONSTANTS_PTR ~ " ]" ;
166+ else
167+ return " [constants + 16 + 16*" ~ to_string(i/ 20 )~ " ]" ;
159168 }
160169
161170 /* * Returns the XMM register number used in round i */
@@ -304,9 +313,9 @@ version(USE_SSSE3)
304313 {
305314 if (i == 0 )
306315 {
307- return swt3264 ([" movdqa " ~ X_SHUFFLECTL ~ " ,[bswap_shufb_ctl] " ,
316+ return swt3264 ([" movdqa " ~ X_SHUFFLECTL ~ " ," ~ bswap_shufb_ctl() ,
308317 " movdqa " ~ X_CONSTANT ~ " ," ~ constant(i)],
309- [" movdqa " ~ X_SHUFFLECTL ~ " ,[bswap_shufb_ctl] " ,
318+ [" movdqa " ~ X_SHUFFLECTL ~ " ," ~ bswap_shufb_ctl() ,
310319 " movdqa " ~ X_CONSTANT ~ " ," ~ constant(i)]);
311320 }
312321 version (_64Bit)
@@ -589,8 +598,9 @@ version(USE_SSSE3)
589598 {
590599 /*
591600 * Parameters:
592- * RSI contains pointer to state
593- * RDI contains pointer to input buffer
601+ * RDX contains pointer to state
602+ * RSI contains pointer to input buffer
603+ * RDI contains pointer to constants
594604 *
595605 * Stack layout as follows:
596606 * +----------------+
@@ -610,8 +620,9 @@ version(USE_SSSE3)
610620 " push RBP" ,
611621 " push RBX" ,
612622 // Save parameters
613- " mov " ~ STATE_PTR ~ " , RSI" , // pointer to state
614- " mov " ~ BUFFER_PTR ~ " , RDI" , // pointer to buffer
623+ " mov " ~ STATE_PTR ~ " , RDX" , // pointer to state
624+ " mov " ~ BUFFER_PTR ~ " , RSI" , // pointer to buffer
625+ " mov " ~ CONSTANTS_PTR ~ " , RDI" , // pointer to constants to avoid absolute addressing
615626 // Align stack
616627 " sub RSP, 4*16+8" ,
617628 ];
@@ -643,10 +654,17 @@ version(USE_SSSE3)
643654 }
644655 }
645656
657+ // constants as extra argument for PIC, see Bugzilla 9378
658+ import std.meta : AliasSeq;
659+ version (_64Bit)
660+ alias ExtraArgs = AliasSeq! (typeof (&constants));
661+ else
662+ alias ExtraArgs = AliasSeq! ();
663+
646664 /**
647665 *
648666 */
649- public void transformSSSE3 (uint [5 ]* state, const (ubyte [64 ])* buffer) pure nothrow @nogc
667+ public void transformSSSE3 (uint [5 ]* state, const (ubyte [64 ])* buffer, ExtraArgs ) pure nothrow @nogc
650668 {
651669 mixin (wrap([" naked;" ] ~ prologue()));
652670 // Precalc first 4*16=64 bytes
0 commit comments