1
2 #include <stdio.h>
3
4 typedef unsigned long long int ULong;
5
6 ULong data;
7 ULong xtra;
8 ULong amt;
9 ULong flags_in;
10 ULong result;
11 ULong flags_out;
12
13 #define AMD64G_CC_SHIFT_O 11
14 #define AMD64G_CC_SHIFT_S 7
15 #define AMD64G_CC_SHIFT_Z 6
16 #define AMD64G_CC_SHIFT_A 4
17 #define AMD64G_CC_SHIFT_C 0
18 #define AMD64G_CC_SHIFT_P 2
19
20 #define AMD64G_CC_MASK_O (1 << AMD64G_CC_SHIFT_O)
21 #define AMD64G_CC_MASK_S (1 << AMD64G_CC_SHIFT_S)
22 #define AMD64G_CC_MASK_Z (1 << AMD64G_CC_SHIFT_Z)
23 #define AMD64G_CC_MASK_A (1 << AMD64G_CC_SHIFT_A)
24 #define AMD64G_CC_MASK_C (1 << AMD64G_CC_SHIFT_C)
25 #define AMD64G_CC_MASK_P (1 << AMD64G_CC_SHIFT_P)
26
27 #define MASK_OSZACP \
28 (AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z \
29 | AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P)
30
31 extern void shld64 ( void );
32 asm("\n"
33 "shld64:\n"
34 "\tpushq %rsi\n"
35 "\tpushq %r11\n"
36 "\tpushq %rcx\n"
37 "\tmovq data, %rsi\n"
38 "\tmovq xtra, %r11\n"
39 "\tmovq amt, %rcx\n"
40 "\tpushq flags_in\n"
41 "\tpopfq\n"
42 "\tshldq %cl, %r11, %rsi\n"
43 "\tmovq %rsi, result\n"
44 "\tpushfq\n"
45 "\tpopq flags_out\n"
46 "\tpopq %rcx\n"
47 "\tpopq %r11\n"
48 "\tpopq %rsi\n"
49 "\tret\n"
50 );
51
52 extern void shld32 ( void );
53 asm("\n"
54 "shld32:\n"
55 "\tpushq %rsi\n"
56 "\tpushq %r11\n"
57 "\tpushq %rcx\n"
58 "\tmovq data, %rsi\n"
59 "\tmovq xtra, %r11\n"
60 "\tmovq amt, %rcx\n"
61 "\tpushq flags_in\n"
62 "\tpopfq\n"
63 "\tshldl %cl, %r11d, %esi\n"
64 "\tmovq %rsi, result\n"
65 "\tpushfq\n"
66 "\tpopq flags_out\n"
67 "\tpopq %rcx\n"
68 "\tpopq %r11\n"
69 "\tpopq %rsi\n"
70 "\tret\n"
71 );
72
73 extern void shld16 ( void );
74 asm("\n"
75 "shld16:\n"
76 "\tpushq %rsi\n"
77 "\tpushq %r11\n"
78 "\tpushq %rcx\n"
79 "\tmovq data, %rsi\n"
80 "\tmovq xtra, %r11\n"
81 "\tmovq amt, %rcx\n"
82 "\tpushq flags_in\n"
83 "\tpopfq\n"
84 "\tshldw %cl, %r11w, %si\n"
85 "\tmovq %rsi, result\n"
86 "\tpushfq\n"
87 "\tpopq flags_out\n"
88 "\tpopq %rcx\n"
89 "\tpopq %r11\n"
90 "\tpopq %rsi\n"
91 "\tret\n"
92 );
93
94
95 extern void shrd64 ( void );
96 asm("\n"
97 "shrd64:\n"
98 "\tpushq %rsi\n"
99 "\tpushq %r11\n"
100 "\tpushq %rcx\n"
101 "\tmovq data, %rsi\n"
102 "\tmovq xtra, %r11\n"
103 "\tmovq amt, %rcx\n"
104 "\tpushq flags_in\n"
105 "\tpopfq\n"
106 "\tshrdq %cl, %r11, %rsi\n"
107 "\tmovq %rsi, result\n"
108 "\tpushfq\n"
109 "\tpopq flags_out\n"
110 "\tpopq %rcx\n"
111 "\tpopq %r11\n"
112 "\tpopq %rsi\n"
113 "\tret\n"
114 );
115
116 extern void shrd32 ( void );
117 asm("\n"
118 "shrd32:\n"
119 "\tpushq %rsi\n"
120 "\tpushq %r11\n"
121 "\tpushq %rcx\n"
122 "\tmovq data, %rsi\n"
123 "\tmovq xtra, %r11\n"
124 "\tmovq amt, %rcx\n"
125 "\tpushq flags_in\n"
126 "\tpopfq\n"
127 "\tshrdl %cl, %r11d, %esi\n"
128 "\tmovq %rsi, result\n"
129 "\tpushfq\n"
130 "\tpopq flags_out\n"
131 "\tpopq %rcx\n"
132 "\tpopq %r11\n"
133 "\tpopq %rsi\n"
134 "\tret\n"
135 );
136
137 extern void shrd16 ( void );
138 asm("\n"
139 "shrd16:\n"
140 "\tpushq %rsi\n"
141 "\tpushq %r11\n"
142 "\tpushq %rcx\n"
143 "\tmovq data, %rsi\n"
144 "\tmovq xtra, %r11\n"
145 "\tmovq amt, %rcx\n"
146 "\tpushq flags_in\n"
147 "\tpopfq\n"
148 "\tshrdw %cl, %r11w, %si\n"
149 "\tmovq %rsi, result\n"
150 "\tpushfq\n"
151 "\tpopq flags_out\n"
152 "\tpopq %rcx\n"
153 "\tpopq %r11\n"
154 "\tpopq %rsi\n"
155 "\tret\n"
156 );
157
158
main(void)159 int main ( void )
160 {
161 int i;
162 ULong mask;
163
164 printf("\nleft 64\n");
165 for (i = 0; i < 260; i++) {
166 mask = MASK_OSZACP;
167 if (i > 1) mask &= ~AMD64G_CC_MASK_O;
168 if (i > 0) mask &= ~AMD64G_CC_MASK_A;
169 data = 0x1122334455667788ULL;
170 xtra = 0x3141592727182818ULL;
171 flags_in = 0ULL;
172 amt = (ULong)i;
173 shld64();
174 printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
175 }
176
177 printf("\nleft 32\n");
178 for (i = 0; i < 260; i++) {
179 mask = MASK_OSZACP;
180 if (i > 1) mask &= ~AMD64G_CC_MASK_O;
181 if (i > 0) mask &= ~AMD64G_CC_MASK_A;
182 data = 0x1122334455667788ULL;
183 xtra = 0x3141592727182818ULL;
184 flags_in = 0ULL;
185 amt = (ULong)i;
186 shld32();
187 printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
188 }
189 printf("\n");
190
191 printf("\nleft 16\n");
192 for (i = 0; i < 260; i++) {
193 mask = MASK_OSZACP;
194 if (i > 1) mask &= ~AMD64G_CC_MASK_O;
195 if (i > 0) mask &= ~AMD64G_CC_MASK_A;
196 data = 0x1122334455667788ULL;
197 xtra = 0x987654321987abcdULL;
198 flags_in = 0ULL;
199 amt = (ULong)i;
200 shld16();
201 printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
202 }
203 printf("\n");
204
205 printf("\nright 64\n");
206 for (i = 0; i < 260; i++) {
207 mask = MASK_OSZACP;
208 if (i > 1) mask &= ~AMD64G_CC_MASK_O;
209 if (i > 0) mask &= ~AMD64G_CC_MASK_A;
210 data = 0x1122334455667788ULL;
211 xtra = 0x3141592727182818ULL;
212 flags_in = 0ULL;
213 amt = (ULong)i;
214 shrd64();
215 printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
216 }
217
218 printf("\nright 32\n");
219 for (i = 0; i < 260; i++) {
220 mask = MASK_OSZACP;
221 if (i > 1) mask &= ~AMD64G_CC_MASK_O;
222 if (i > 0) mask &= ~AMD64G_CC_MASK_A;
223 data = 0x1122334455667788ULL;
224 xtra = 0x3141592727182818ULL;
225 flags_in = 0ULL;
226 amt = (ULong)i;
227 shrd32();
228 printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
229 }
230 printf("\n");
231
232 printf("\nright 16\n");
233 for (i = 0; i < 260; i++) {
234 mask = MASK_OSZACP;
235 if (i > 1) mask &= ~AMD64G_CC_MASK_O;
236 if (i > 0) mask &= ~AMD64G_CC_MASK_A;
237 data = 0x1122334455667788ULL;
238 xtra = 0x987654321987abcdULL;
239 flags_in = 0ULL;
240 amt = (ULong)i;
241 shrd16();
242 printf("%3d 0x%016llx 0x%llx\n", i, result, flags_out & mask);
243 }
244 printf("\n");
245
246 return 0;
247 }
248